Define bloques

Las definiciones de bloques describen cómo se ve y se comporta un bloque, incluido el texto, el color, la forma y a qué otros bloques se puede conectar.

Comparación entre el formato JSON y la API de JavaScript

Blockly tiene dos formas de definir bloques: objetos JSON y funciones de JavaScript. El formato JSON está diseñado para simplificar el proceso de localización cuando se desarrolla para idiomas con diferente orden de palabras. El formato JSON es el método preferido para definir bloques.

Sin embargo, el formato JSON no puede definir directamente funciones avanzadas como mutadores o validadores. Se deben escribir en JavaScript, generalmente como extensiones.

Las apps que usan la implementación original de Blockly en JavaScript también pueden escribir definiciones de bloques directamente en las llamadas a la función de la API de Blockly de nivel inferior, como se muestra en los siguientes ejemplos de JavaScript.

JSON

Blockly.defineBlocksWithJsonArray([{
  "type": "string_length",
  "message0": 'length of %1',
  "args0": [
    {
      "type": "input_value",
      "name": "VALUE",
      "check": "String"
    }
  ],
  "output": "Number",
  "colour": 160,
  "tooltip": "Returns number of letters in the provided text.",
  "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
}]);

JavaScript

Blockly.Blocks['string_length'] = {
  init: function() {
    this.appendValueInput('VALUE')
        .setCheck('String')
        .appendField('length of');
    this.setOutput(true, 'Number');
    this.setColour(160);
    this.setTooltip('Returns number of letters in the provided text.');
    this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp');
  }
};

La función init crea la forma del bloque. En el contexto de esta función, la palabra clave this es el bloque real que se creará.

Ambos ejemplos cargan el mismo bloque 'string_length'.

En la Web, el formato JSON se carga con la función initJson. Esto también permite combinar los dos formatos en las páginas web de Blockly. Te recomendamos que definas tu bloque con JSON siempre que sea posible y que uses JavaScript solo para las partes de las definiciones de bloque que JSON no admite.

A continuación, se muestra un ejemplo de un bloque definido principalmente con JSON, pero que se extiende con la API de JavaScript para mostrar información dinámica sobre la herramienta.

JavaScript

var mathChangeJson = {
  "message0": "change %1 by %2",
  "args0": [
    {"type": "field_variable", "name": "VAR", "variable": "item", "variableTypes": [""]},
    {"type": "input_value", "name": "DELTA", "check": "Number"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 230
};

Blockly.Blocks['math_change'] = {
  init: function() {
    this.jsonInit(mathChangeJson);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return 'Add a number to variable "%1".'.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  }
};

Color del bloque

El color principal de un bloque se define mediante la propiedad colour de JSON, la función block.setColour(..) o el uso de temas y la definición de un estilo de bloque.

JSON

{
  // ...,
  "colour": 160,
}

JavaScript

init: function() {
  // ...
  this.setColour(160);
}

Consulta la guía de colores de bloques para obtener más detalles.

Conexiones de instrucciones

Los usuarios pueden crear secuencias de bloques mediante los conectores nextStatement y previousStatement. En el diseño estándar de Blockly, estas conexiones están en la parte superior e inferior, con los bloques apilados verticalmente.

Un bloque con un conector anterior no puede tener un conector de salida y viceversa. El término bloque de instrucciones se refiere a un bloque sin salida de valor. Un bloque de sentencias generalmente tendrá una conexión anterior y una conexión siguiente.

Las conexiones nextStatement y previousStatement se pueden escribir, pero los bloques estándar no usan esta función.

Próxima conexión

Crea un punto en la parte inferior del bloque de modo que otras declaraciones se puedan apilar debajo de él. Por lo general, un bloque con una conexión siguiente, pero sin conexión anterior, representa un evento y se puede configurar para que se renderice con un sombrero.

JSON

Sin escribir:

{
  ...,
  "nextStatement": null,
}

Escrito (poco frecuente):

{
  "nextStatement": "Action",
  ...
}

JavaScript

Sin escribir:

this.setNextStatement(true);  // false implies no next connector, the default

Escrito (poco frecuente):

this.setNextStatement(true, 'Action');

Conexión anterior

Crea una muesca en la parte superior del bloque para que se pueda conectar como una pila de declaraciones.

Los bloques con una conexión anterior no pueden tener una conexión de salida.

JSON

Sin escribir:

{
  ...,
  "previousStatement": null,
}

Escrito (poco frecuente):

{
  "previousStatement": "Action",
  ...
}

JavaScript

Sin escribir:

this.setPreviousStatement(true);  // false implies no previous connector, the default

Escrito (poco frecuente):

this.setPreviousStatement(true, 'Action');

Salida de bloque

Un bloque puede tener una sola salida, representada como un conector de rompecabezas masculino en el borde inicial. Las salidas se conectan con las entradas de valores. Los bloques con una salida generalmente se denominan bloques de valor.

JSON

Sin escribir:

{
  // ...,
  "output": null,
}

Escrito:

{
  // ...,
  "output": "Number",
}

JavaScript

Sin escribir:

init: function() {
  // ...
  this.setOutput(true);
}

Escrito:

init: function() {
  // ...
  this.setOutput(true, 'Number');
}

Los bloques con un conector de salida tampoco pueden tener un recorte de sentencia anterior.

Bloquear entradas

Un bloque tiene una o más entradas, y cada una tiene una secuencia de campos y puede terminar en una conexión. Hay varios tipos de entradas integradas.

  • Entrada de valor: Se conecta a una conexión de salida de un bloque de valor. Un bloque math_arithmetic (suma, resta) es un ejemplo de un bloque con dos entradas de valores.
  • Entrada de enunciado: se conecta a una conexión anterior de un bloque de declaraciones. La sección anidada de un bucle while es un ejemplo de una entrada de instrucción.
  • Entrada ficticia: No tiene una conexión de bloque. Actúa como un salto de línea cuando el bloque está configurado para usar entradas de valores externos.
  • Entrada de la fila de finalización: No tiene una conexión de bloque y siempre actúa como una línea nueva.

También puedes crear una entrada personalizada para admitir la renderización personalizada.

El formato JSON y la API de JavaScript usan modelos ligeramente diferentes para describir sus entradas.

Entradas y campos en JSON

Los bloques definidos de JSON se estructuran como una secuencia de cadenas de mensajes interpoladas ( message0, message1, ...), en la que cada token de interpolación (%1, %2, ...) es un campo o un extremo de entrada (por lo tanto, donde el conector de entrada se renderiza, dentro del mensaje) en el array JSON argsN coincidente. Este formato está diseñado para facilitar la internacionalización.

JSON

{
  "message0": "set %1 to %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

Los tokens de interpolación deben coincidir por completo con el array args0: sin duplicados ni omisiones. Los tokens pueden estar presentes en cualquier orden, lo que permite que diferentes idiomas cambien el diseño del bloque.

El texto a ambos lados de un token de interpolación tiene espacios en blanco. En el texto que usa el carácter % (p.ej., cuando se hace referencia a un porcentaje), se debe usar %% para que no se interprete como un token de interpolación.

El orden de los argumentos y los tipos de argumentos definen la forma del bloque. Cambiar una de estas cadenas puede cambiar por completo el diseño del bloque. Esto es particularmente importante en idiomas con un orden diferente al inglés. Considera un lenguaje hipotético en el que "set %1 to %2" (como se usa en el ejemplo anterior) debe invertirse para que diga "put %2 in %1". Cuando se cambia esta string (y se deja el resto del JSON intacto) se genera el siguiente bloque:

Blockly cambió automáticamente el orden de los campos, creó una entrada ficticia y cambió las entradas externas a internas.

Blockly también reemplaza automáticamente cualquier carácter de salto de línea (\n) en la string del mensaje por una entrada de fila final.

JSON

{
  "message0": "set %1\nto %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

Args

Cada cadena de mensaje está vinculada con un array args del mismo número. Por ejemplo, message0 va con args0. Los tokens de interpolación (%1, %2, ...) hacen referencia a los elementos del array args. Cada objeto tiene una cadena type. El resto de los parámetros varían según el tipo:

También puedes definir tus propios campos personalizados y entradas personalizadas, y pasarlos como argumentos.

Cada objeto también puede tener un campo alt. En caso de que Blockly no reconozca el type del objeto, se usará el objeto alt en su lugar. Por ejemplo, si se agrega un campo nuevo llamado field_time a Blockly, los bloques que usan este campo podrían usar alt para definir un resguardo de field_input para versiones anteriores de Blockly:

JSON

{
  "message0": "sound alarm at %1",
  "args0": [
    {
      "type": "field_time",
      "name": "TEMPO",
      "hour": 9,
      "minutes": 0,
      "alt":
        {
          "type": "field_input",
          "name": "TEMPOTEXT",
          "text": "9:00"
        }
    }
  ]
}

Un objeto alt puede tener su propio objeto alt, lo que permite el encadenamiento. En última instancia, si Blockly no puede crear un objeto en el array args0 (después de intentar con cualquier objeto alt), ese objeto simplemente se omite.

Se agregará automáticamente una entrada ficticia al final del bloque si la string message termina con texto o campos que no contiene una entrada. Por lo tanto, si la última entrada de un bloque es ficticia, puede omitirse en el array args y no es necesario interpolar en message. La adición automática de una entrada de prueba final permite a los traductores cambiar message sin necesidad de modificar el resto del JSON. Consulta el ejemplo de "set %1 to %2" (sin entrada ficticia) y "put %2 in %1" (entrada ficticia agregada) que se encuentra más arriba en esta página.

implicitAlign0

En casos excepcionales, la entrada ficticia final creada automáticamente debe alinearse con "RIGHT" o "CENTRE". Si no se especifica, el valor predeterminado es "LEFT".

En el siguiente ejemplo, message0 es "send email to %1 subject %2 secure %3" y Blockly agrega automáticamente una entrada ficticia para la tercera fila. Establecer implicitAlign0 en "RIGHT" fuerza esta fila para que se alinee a la derecha. Esta alineación se aplica a todas las entradas que no se definen de forma explícita en la definición del bloque JSON, incluidas las entradas de la fila final que reemplazan los caracteres de salto de línea ('\n') en el mensaje. También está la propiedad obsoleta lastDummyAlign0, que tiene el mismo comportamiento que implicitAlign0.

Cuando se diseñan bloques para escritura de derecha a izquierda (árabe y hebreo), se invierte la izquierda y la derecha. Por lo tanto, "RIGHT" alinearía los campos a la izquierda.

message1, args1 y implicitAlign1

Algunos bloques se dividen naturalmente en dos o más partes separadas. Considera este bloque "repetir" que tiene dos filas:

Si este bloque se describiera con un solo mensaje, la propiedad message0 sería "repeat %1 times %2 do %3". Esta string es incómoda para un traductor, es difícil explicar qué significa la sustitución %2. Es posible que la entrada ficticia %2 tampoco se desee en algunos idiomas. Y puede haber varios bloques que quieran compartir el texto de la segunda fila. Un mejor enfoque es que JSON use más de un mensaje y propiedades de args:

JSON

{
  "type": "controls_repeat_ext",
  "message0": "repeat %1 times",
  "args0": [
    {"type": "input_value", "name": "TIMES", "check": "Number"}
  ],
  "message1": "do %1",
  "args1": [
    {"type": "input_statement", "name": "DO"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 120
}

Cualquier cantidad de propiedades de message, args y implicitAlign se puede definir en el formato JSON, a partir de 0 y el aumento secuencial. Ten en cuenta que Block Factory no puede dividir mensajes en varias partes, pero hacerlo de forma manual es sencillo.

Entradas y campos en JavaScript

La API de JavaScript incluye un método append para cada tipo de entrada:

JavaScript

this.appendEndRowInput()
    .appendField('for each')
    .appendField('item')
    .appendField(new Blockly.FieldVariable());
this.appendValueInput('LIST')
    .setCheck('Array')
    .setAlign(Blockly.inputs.Align.RIGHT)
    .appendField('in list');
this.appendStatementInput('DO')
    .appendField('do');
this.appendDummyInput()
    .appendField('end');

Cada método de anexo puede tomar una cadena identificadora, que usan los generadores de código. Las entradas ficticias y de fila final rara vez necesitan referencia y, por lo general, el identificador no se configura.

La API de JavaScript también incluye un método appendInput genérico para agregar entradas personalizadas. Ten en cuenta que, en este caso, el identificador se debe pasar directamente al constructor de tu entrada personalizada.

JavaScript

this.appendInput(new MyCustomInput('INPUT_NAME'))
    .appendField('an example label')

Todos los métodos appendInput (genéricos y no genéricos) muestran el objeto de entrada para que puedan configurarse mediante el encadenamiento de métodos. Hay tres métodos integrados que se usan para configurar las entradas.

setCheck

JavaScript

input.setCheck('Number');

Esta función opcional se usa para la comprobación de tipo de entradas conectadas. Si se le da un argumento nulo, el valor predeterminado, entonces, esta entrada se puede conectar a cualquier bloque. Consulta Verificaciones de tipos para obtener más detalles.

setAlign

JavaScript

input.setAlign(Blockly.inputs.Align.RIGHT);

Esta función opcional se usa para alinear los campos (consulta a continuación). Existen tres valores autodescriptivos que se pueden pasar como argumento a esta función: Blockly.inputs.Align.LEFT, Blockly.inputs.Align.RIGHT y Blockly.inputs.Align.CENTER.

Cuando se diseñan bloques para escritura de derecha a izquierda (árabe y hebreo), se invierte la izquierda y la derecha. Por lo tanto, Blockly.inputs.Align.RIGHT alinearía los campos a la izquierda.

appendField

Una vez que se crea una entrada y se agrega a un bloque con appendInput, tienes la opción de agregar cualquier cantidad de campos a la entrada. Estos campos se suelen usar como etiquetas a fin de describir para qué sirve cada entrada.

JavaScript

input.appendField('hello');

El elemento de campo más simple es el texto. La convención de Blockly es usar todo el texto en minúsculas, a excepción de los nombres propios (p.ej., Google o SQL).

Una fila de entrada puede contener cualquier cantidad de elementos de campo. Se pueden encadenar varias llamadas a appendField para agregar de manera eficiente varios campos a la misma fila de entrada.

JavaScript

input.appendField('hello')
     .appendField(new Blockly.FieldLabel('Neil', 'person'));

En realidad, la llamada a appendField('hello') es un acceso directo para usar un constructor FieldLabel explícito: appendField(new Blockly.FieldLabel('hello')). El único momento en el que se recomienda usar el constructor es cuando se especifica un nombre de clase, de modo que se pueda diseñar el texto con una regla de CSS.

Intercalado o externa

Las entradas de bloque se pueden renderizar como externas o internas.

La definición del bloque puede especificar un booleano opcional que controle si las entradas están intercaladas o no. Si es false, cualquier entrada de valor será externa (como el bloque de la izquierda). Si es true, cualquier entrada de valor estará intercalada (como el bloque de la derecha).

JSON

{
  // ...,
  "inputsInline": true
}

JavaScript

init: function() {
  // ...
  this.setInputsInline(true);
}

Si no está definido, Blockly usará una heurística para adivinar qué modo es el mejor. Suponiendo que Blockly toma la decisión correcta, es preferible dejar este campo sin definir, ya que las traducciones a diferentes idiomas pueden tener automáticamente modos diferentes. Consulta el ejemplo de JSON de "set %1 to %2" (entradas externas) y "put %2 in %1" (entradas intercaladas) que se ve antes en esta página.

Usa entradas intercaladas cuando es probable que un bloque tenga entradas pequeñas, como números. El usuario puede activar o desactivar esta opción desde el menú contextual si está habilitada la configuración de collapse (el valor predeterminado es verdadero si la caja de herramientas tiene categorías).

Campos

Los campos definen la mayoría de los elementos de la IU dentro de un bloque. Esto incluye las etiquetas de strings, las imágenes y las entradas para datos literales, como strings y números. El ejemplo más simple es el bloque math_number, que usa un field_input para permitir que el usuario escriba un número.

Los campos se agregan al bloque con appendField.

Blockly proporciona una serie de campos integrados, como entradas de texto, imágenes y selectores de color. También puedes crear tus propios campos.

→ Obtén más información sobre los campos integrados.

→ Obtén más información sobre la creación de campos personalizados.

Íconos

Los íconos definen elementos de la IU en un bloque que muestran información "meta" sobre el bloque.

Los íconos se agregan al bloque con addIcon.

Blockly proporciona una serie de íconos integrados, incluidos los de comentarios y los de advertencia. También puedes crear tus propios íconos.

→ Obtén más información sobre la creación de íconos personalizados.

Cuadros de información

La información sobre la herramienta ofrece ayuda instantánea cuando el usuario coloca el cursor sobre el bloque. Si el texto es largo, se ajustará automáticamente.

JSON

{
  // ...,
  "tooltip": "Tooltip text."
}

JavaScript

init: function() {
  this.setTooltip("Tooltip text.");
}

En la API de JavaScript, la información sobre la herramienta también se puede definir como una función en lugar de una cadena estática. Esto permite obtener ayuda dinámica. Consulta math_arithmetic para ver un ejemplo de información sobre la herramienta que cambia según la opción del menú desplegable que se haya elegido.

JavaScript

Blockly.Blocks['math_arithmetic'] = {
  init: function() {
    // ...

    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      var mode = thisBlock.getFieldValue('OP');
      var TOOLTIPS = {
        'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
        'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
        'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
        'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
        'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
      };
      return TOOLTIPS[mode];
    });
  }
};

Con la API de JavaScript, los bloques pueden especificar una función, en lugar de una string estática, que muestra una string con información sobre la herramienta. Esto permite obtener información dinámica sobre la herramienta. Consulta math_arithmetic para ver un ejemplo.

Personalización

También puedes personalizar el aspecto de la información sobre la herramienta si proporcionas una función de renderización personalizada. Crea una función que acepte dos parámetros:

  • Primero, un elemento <div> en el que renderizarás el contenido.
  • el elemento real sobre el que se pasa el mouse y el cuadro de información sobre la herramienta

En el cuerpo de la función, puedes renderizar el contenido que quieras en el elemento div. Para obtener la string de información sobre la herramienta definida en el bloque sobre el que se desplaza el mouse, puedes llamar a Blockly.Tooltip.getTooltipOfObject(element);, donde element es el segundo parámetro anterior.

Por último, registra esta función para que Blockly pueda llamarla en el momento adecuado:

Blockly.Tooltip.setCustomTooltip(yourFnHere);

Para ver un ejemplo, consulta la demostración de información sobre herramientas personalizadas.

URL de ayuda

Los bloqueos pueden tener asociada una página de ayuda. Esta opción está disponible para los usuarios de Blockly para la Web. Para ello, deben hacer clic con el botón derecho en el bloque y seleccionar "Help" en el menú contextual. Si este valor es null, el menú estará inhabilitado.

JSON

{
  // ...,
  "helpUrl": "https://en.wikipedia.org/wiki/For_loop"
}

JavaScript

init: function() {
  // ...
  this.setHelpUrl('https://en.wikipedia.org/wiki/For_loop');
}

Con la API de JavaScript, los bloques pueden especificar una función, en lugar de una string estática, que muestra una string de URL, lo que permite una ayuda dinámica.

Cambia objetos de escucha y validadores

Los bloques pueden tener funciones de objetos de escucha cambiantes a las que se llama ante cualquier cambio en el lugar de trabajo (incluidas las no relacionadas con el bloque). Se usan principalmente para configurar el texto de advertencia del bloque o una notificación de usuario similar fuera del lugar de trabajo.

Para agregar la función, se llama a setOnChange con una función y se puede hacer durante la inicialización o a través de una extensión de JSON si planeas usarla en todas las plataformas.

JSON

{
  // ...,
  "extensions":["warning_on_change"],
}

Blockly.Extensions.register('warning_on_change', function() {
  // Example validation upon block change:
  this.setOnChange(function(changeEvent) {
    if (this.getInput('NUM').connection.targetBlock()) {
      this.setWarningText(null);
    } else {
      this.setWarningText('Must have an input block.');
    }
  });
});

JavaScript

Blockly.Blocks['block_type'] = {
  init: function() {
    // Example validation upon block change:
    this.setOnChange(function(changeEvent) {
      if (this.getInput('NUM').connection.targetBlock()) {
        this.setWarningText(null);
      } else {
        this.setWarningText('Must have an input block.');
      }
    });
  }
}

El sistema llama a la función y pasa el evento de cambio. Dentro de la función, this hace referencia a la instancia de bloque.

Dado que se llama a la función ante cualquier cambio, si se usa, los desarrolladores deben asegurarse de que el objeto de escucha se ejecute rápidamente. También se deben tener cuidado con los cambios en el lugar de trabajo que pueden ocurrir en cascada o se repiten en el objeto de escucha.

Consulta los bloques controls_flow_statements, logic_compare y procedures_ifreturn para ver ejemplos.

Ten en cuenta que los campos editables tienen sus propios objetos de escucha de eventos para la validación de entrada y causar efectos secundarios.

Mutador

Los mutadores permiten que los bloques avanzados cambien de forma, sobre todo cuando los usuarios abren un diálogo para agregar, quitar o reorganizar componentes. Los mutadores se pueden agregar a través de JSON con la clave mutator.

JSON

{
  // ...,
  "mutator":"if_else_mutator"
}

Configuración por bloque

Las instancias de bloqueo tienen varias propiedades que configuran su comportamiento para el usuario. Se pueden usar para restringir el lugar de trabajo a fin de reflejar ciertas propiedades del dominio (p.ej., hay exactamente un evento de “inicio”) o centrar el esfuerzo del usuario (p.ej., un instructivo).

Estado que se puede borrar

block.setDeletable(false);

Si se establece como falsa, el usuario no podrá borrar el bloque. De forma predeterminada, los bloques se pueden borrar en un lugar de trabajo editable.

Cualquier bloque, incluso los que no se pueden borrar, puede borrarse de manera programática:

block.dispose();

Estado editable

block.setEditable(false);

Si se configura como falsa, el usuario no podrá cambiar los campos del bloque (p.ej., menús desplegables y entradas de texto). De forma predeterminada, los bloques se pueden editar en un lugar de trabajo editable.

Estado móvil

block.setMovable(false);

Si se establece como false, el usuario no podrá mover el bloque directamente. Un bloque inamovible que es secundario de otro no puede desconectarse de ese bloque, aunque se moverá con su elemento superior si este se mueve. De forma predeterminada, el bloqueo se puede mover en un lugar de trabajo editable.

Cualquier bloque (incluso los inamovibles) se puede mover de manera programática una vez que está en un lugar de trabajo.

block.moveBy(dx, dy)

El valor predeterminado de la posición inicial para un bloque en un lugar de trabajo es (0, 0).

Bloquear datos

this.data = '16dcb3a4-bd39-11e4-8dfc-aa07a5b093db';

Los datos son una cadena opcional y arbitraria que se adjunta al bloque. Cuando se serializa el bloque, la string de datos se serializa con él. Esto incluye los casos en que se duplica o se copia y pega el bloque.

A menudo, se usa para asociar un bloque con un recurso externo.

Cuando se serializan a JSON, los datos se almacenan como una propiedad de nivel superior en el bloque:

{
  "type": "my_block",
  "data": "16dcb3a4-bd39-11e4-8dfc-aa07a5b093db",
  // etc..
}

Cuando se serializa en XML (el antiguo sistema de serialización congelado), la string de datos se almacena en una etiqueta <data></data> dentro del bloque:

<block type="my_block">
  <data>16dcb3a4-bd39-11e4-8dfc-aa07a5b093db</data>
  <!-- etc... -->
</block>

Destrucción

Los bloques tienen un hook destroy, al que se llama cuando se borran del lugar de trabajo. Esto se puede usar para destruir los modelos de datos de copia de seguridad o los recursos externos asociados con el bloque que ya no sean necesarios.

JSON

{
  // ...,
  "extensions":["destroy"],
}

Blockly.Extensions.registerMixin('destroy', {
  destroy: function() {
    this.myResource.dispose();
  }
});

JavaScript

Blockly.Blocks['block_type'] = {
  destroy: function() {
    this.myResource.dispose();
  }
}

Se llama al método destroy después de que se haya eliminado el elemento superior del bloque, pero antes de que se elimine cualquiera de sus elementos secundarios o campos.

Menús contextuales

De forma predeterminada, los bloques tienen un menú contextual de clic derecho que permite a los usuarios realizar acciones como agregar comentarios o duplicar bloques.

Puedes inhabilitar el menú contextual de un bloque en particular de la siguiente manera:

block.contextMenu = false;

También puedes personalizar las opciones que se muestran en el menú. Para personalizar el menú de todos los bloques, consulta la documentación sobre menús contextuales. Para personalizar el menú de un bloque individual, puedes implementar customContextMenu. Esta función toma un array de opciones de menú y lo modifica en su lugar, lo que significa que puedes agregar y quitar elementos.

Cada opción de menú es un objeto con tres propiedades:

  • text es el texto visible.
  • enabled es un valor booleano. Cuando se inhabilita, la opción se muestra, pero con texto gris.
  • callback es la función a la que se llamará cuando se haga clic en la opción.