Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate a custom Blockly block from a user-provided string without eval

I am converting a string into a Google Blockly block using JavaScript.

The input string is something like "Hello %s World" - where %s defines a string input. I need to turn that into:

Blockly.Blocks['blockname'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("Hello ")
        .appendField(new Blockly.FieldTextInput("input1"), "")
        .appendField(" World");
  }
};

But I'm not sure how to achieve this without using eval(), and as the input string is from the user, I understand that using eval() would not be a good idea.

My current code is:

currentLine = blockText[x].split(/(%s)/);
for( var y = 0; y < currentLine.length; y++ )
{
  if( currentLine[y] == "" )
  {
    //do nothing
  }
  else if( currentLine[y] == "%s" )
  {
    //create a input
  }
  else
  {
    //create a label
  }
}

But I'm not quite sure how to create the Blockly code that I need, without building up the JavaScript in a string and then using eval() at the end.

Could someone please assist me with this?

like image 620
user2370460 Avatar asked Oct 31 '22 08:10

user2370460


1 Answers

You can create a custom generic block without any inputs like below -

  Blockly.Blocks['generic_block'] = {
    init: function() {
      this.jsonInit({
        message0: '',
        colour: '230'
      });
    }
  };

Now you can create a new instance of this block though the code. Based on your JS string parsing, you can create the inputs and the fields inside this block as below -

var lineBlock=yourBlocklyWorkspace.newBlock('generic_block');         // create new instance of generic block
var input=lineBlock.appendDummyInput();                               // create a dummy input
var blockText="Hello %s World";                                       // one line of the JS code
var currentLine = blockText.split(/(%s)/);                            // split every word
for( var y = 0; y < currentLine.length; y++ ) {                       // loop through each word
  if(currentLine[y]==='%s') {                                         // if the word is %s, then append input field
    input.appendField(new Blockly.FieldTextInput('input'+y));         // input+y is the name of the field
  } else {                                                                         // else just append label field
    var labelField=new Blockly.FieldLabel('label'+y);                         // label+y is the name of the field
    labelField.setValue(currentLine[y]);                                          // set the label value to the word
    input.appendField(labelField)
  }
}
like image 154
Nithin Kumar Biliya Avatar answered Nov 14 '22 10:11

Nithin Kumar Biliya