Skip to content

Multiple Mixins for custom blocks #4767

@shane-lab

Description

@shane-lab

At the moment you can not assign multiple mixins to a custom block.

In my solution I have a particular behaviour that I want some blocks to have. Mixins are a great way to add those behaviours to these blocks, however there are some cases where I would like other blocks to have additional behaviours too.

It would be great if the extensions property could accept multiple Mixins.

spoiler
Blockly.Extensions.registerMixin('a', mixinA);
Blockly.Extensions.registerMixin('b', mixinB);

Blockly.Blocks["blockA"] = {
  init: function () {
    this.jsonInit({
      extensions: ['a'],
    });
  }
};

Blockly.Blocks["blockB"] = {
  init: function () {
    this.jsonInit({
      extensions: ['a', 'b'],
    });
  }
};

Then it would be great if it is possible to run the events of the mixin in serial. Right now I have to create said mixin combinations manually e.g.:

const combineMixins = mixins => {
  const suppressPrefixSuffix = mixins.reduce((acc, mixin) => acc || mixin.suppressPrefixSuffix, false);
  const changeHandlers = mixins.reduce((acc, mixin) => {
    if (typeof mixin.onchange === 'function') {
      acc.push(mixin.onchange);
    }
    return acc;
  }, []);
  const onchange = function(...args) {
    changeHandlers.forEach(handler => handler.bind(this)(...args));
  };
  
  return { suppressPrefixSuffix, onchange };
};

Blockly.Extensions.registerMixin('a', mixinA);
Blockly.Extensions.registerMixin('b', mixinB);
Blockly.Extensions.registerMixin('c', mixinC);
Blockly.Extensions.registerMixin('a+b', combineMixins(mixinA, mixinB));
Blockly.Extensions.registerMixin('a+c', combineMixins(mixinA, mixinC));
Blockly.Extensions.registerMixin('a+b+c', combineMixins(mixinA, mixinB, mixinC));
Blockly.Extensions.registerMixin('b+c', combineMixin(mixinB, mixinC));
...etc

I think a Block will benefit of the possibility of having multiple mixins, e.g. support multiple "inheritance". What are your opinions on this proposal? Or is there an existing solution to the above that I have not discovered yet?

Thanks for reading!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions