Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

@blockly/field-colour causes "CSS already injected" and "Invalid block definition" errors after upgrading Blockly to v11

44 views
Skip to first unread message

Subin Kim

unread,
Feb 7, 2025, 11:35:19 AMFeb 7
to Blockly
Issue Title:

@blockly/field-colour causes "CSS already injected" and "Invalid block definition" errors after upgrading Blockly to v11

Description:

My project was originally using Blockly v6, but after upgrading to Blockly v11, we encountered issues when adding the now separately packaged @blockly/field-colour library.

Main Issues:

  1. CSS Injection Error

    • This error occurs when initializing Blockly with @blockly/field-colour.
    • It suggests that the CSS for this module is being injected multiple times, leading to conflicts.
  2. "Invalid block definition" Error
    When importing registerFieldColour from @blockly/field-colour:

    import { registerFieldColour } from '@blockly/field-colour';

    • The following error occurs for all blocks when the Blockly toolbox loads:
    Uncaught TypeError: Invalid block definition for type: example_type              at new Block$$module$build$src$core$block (blockly_compressed.js:11432:1) at new BlockSvg$$module$build$src$core$block_svg (blockly_compressed.js:15073:1) at WorkspaceSvg$$module$build$src$core$workspace_svg.newBlock (blockly_compressed.js:20917:1) at domToBlockHeadless$$module$build$src$core$xml (blockly_compressed.js:2509:1) at domToBlockInternal$$module$build$src$core$xml (blockly_compressed.js:2355:1) at VerticalFlyout$$module$build$src$core$flyout_vertical.createFlyoutBlock (blockly_compressed.js:18033:1) at VerticalFlyout$$module$build$src$core$flyout_vertical.createFlyoutInfo (blockly_compressed.js:17993:1) at VerticalFlyout$$module$build$src$core$flyout_vertical.show (blockly_compressed.js:17961:1) at Toolbox$$module$build$src$core$toolbox$toolbox.updateFlyout_ (blockly_compressed.js:20838:1) at Toolbox$$module$build$src$core$toolbox$toolbox.setSelectedItem (blockly_compressed.js:20814:1)
    • This breaks all block definitions, including our custom blocks.

Steps to Reproduce:

  1. Upgrade Blockly from v6 to v11.
  2. Install @blockly/field-...@5.0.12.
  3. Import and register field-colour:
    import { registerFieldColour } from '@blockly/field-colour'; registerFieldColour();
  4. Initialize Blockly with a toolbox containing a block with a colour field.
  5. Observe the "CSS already injected" error in the console.
  6. Open the Blockly toolbox and observe "Invalid block definition" errors for all blocks.

Expected Behavior:

  • Blockly should initialize without CSS injection errors.
  • Blocks should render properly without "Invalid block definition" errors.

Actual Behavior:

  • Registering @blockly/field-colour causes CSS conflicts.
  • Importing registerFieldColour breaks all blocks in the toolbox.

Environment:

  • Blockly Version: 11.2.1
  • @blockly/field-colour Version: 5.0.12
  • React Version: 18.3.1
  • Browser: Chrome
  • Operating System: Windows 

Additional Notes:

  • This issue did not occur in Blockly v6, as colour fields were part of the core package.
  • Other Blockly modules (@blockly/workspace-backpack, @blockly/workspace-minimap) work fine.
  • The issue seems to be related to how @blockly/field-colour handles registration in module-based environments (React, Webpack, etc.)

    I have done my best to modify the existing code to be compatible with Blockly v11. However, our project has been stalled for a week due to this issue.
    If anyone can provide assistance, it would be greatly appreciated.  

    Block Definition:
    Blockly.Blocks["example_type"] = {
      init: function() {
        this.jsonInit({
          message0: "%{BKY_EXAMPLE_TYPE}",
          args0: [
            {
              type: "field_image",
              src: matchBaseUrl + "/images/icons/led.svg",
              width: 25,
              height: 25,
              alt: "*"
            },
            {
              type: "field_colour",
              name: "colour",
              colour: "#ff0000",
              colourOptions:
                ["#FF0000", "#ff8c00", "#FFFF00", "#00FF00", "#ACE5EE",
                 "#1974d2", "#5D3FD3", "#ff00ff", "#FFFFFF", "#000000"]
            },
            {
              type: "input_value",
              name: "brightness"
            },
            {
              type: "input_dummy",
              name: "PLACEHOLDER"
            }
          ],
          previousStatement: null,
          nextStatement: null,
          colour: HUE_Violet,
          tooltip: "",
          helpUrl: ""
        });
      }
    };

    Python Generator:
    pythonGenerator.forBlock['example_type'] = function(block) {
      var arg0 = block.getFieldValue("colour");  
      var r = parseInt("0x" + arg0.substring(1, 3), 16);
      var g = parseInt("0x" + arg0.substring(3, 5), 16);
      var b = parseInt("0x" + arg0.substring(5, 7), 16);
      if (r === "0x00" && g === "0x00" && b === "0x00") {
        return "example_code()\n";
      }

      var brightness = pythonGenerator.valueToCode(block, 'brightness', Order.ATOMIC) || '0';
      return "example_code(" + r + ", " +  g + ", " + b +", " + brightness + ")\n";
    }

feni...@google.com

unread,
Feb 12, 2025, 2:56:42 PMFeb 12
to Blockly
Thanks for reporting this. The issue is that Blockly.Css.register is really for internal modules to use in order to add to Blockly's CSS just before injection. Since this plugin is separate, it should instead provide its own stylesheet. We also see this with other plugins that use Blockly.CSS.register, indicating that we need to fix this across the board.

The issue you filed (https://github.com/google/blockly-samples/issues/2486) will track work here.

feni...@google.com

unread,
Feb 12, 2025, 4:04:51 PMFeb 12
to Blockly
As a workaround, can you adjust your imports so that field colour is only imported once?
Reply all
Reply to author
Forward
0 new messages