As ferramentas para desenvolvedores do Blockly permitem criar blocos personalizados usando blocos. Ele tem suporte para campos publicados como plug-ins, além dos campos que vêm com o Blockly principal. Se você criou um campo personalizado, siga este guia para adicionar suporte a ele na Block Factory. O campo personalizado precisa ser publicado no npm antes de você adicionar suporte a ele. Você também precisa se comprometer a atualizar o campo para acompanhar as mudanças no Blockly. Caso contrário, talvez seja necessário removê-lo da Fábrica de blocos no futuro.
Desenvolvimento na Block Factory
O código-fonte da Block Factory está no repositório
blockly-samples no diretório
examples/developer-tools
.
Para enviar uma mudança nas ferramentas para desenvolvedores em blockly-samples, siga as etapas típicas de desenvolvimento em blockly-samples. Ao contrário do trabalho com plug-ins, você precisa executar npm
install
diretamente do diretório examples/developer-tools
, em vez de no nível raiz de blockly-samples.
Instalar o plug-in
Para que a Block Factory mostre seu campo personalizado na prévia, é necessário instalar o campo. Adicione seu campo como uma dependência npm de
developer-tools. Em seguida, registre ou faça qualquer outro trabalho de configuração necessário em
developer-tools/src/blocks/index.ts
.
Criar um bloco para o campo
Como a Block Factory usa blocos para criar blocos personalizados, você precisa de um bloco que represente seu campo personalizado.
Criar a definição do bloco
Você precisa criar o bloco para seu campo. Se quiser ir além, crie-o usando a Block Factory. O bloco precisa permitir que o usuário configure
a configuração exigida pelo campo, como valores padrão e um nome. Adicione essa
definição de bloco a
developer-tools/src/blocks/fields.ts
e importe-a em
developer-tools/src/blocks/index.ts
.
Adicionar bloco à caixa de ferramentas
Em seguida, adicione esse bloco à definição da caixa de ferramentas para que ele fique acessível
aos usuários. A definição da caixa de ferramentas está localizada em
developer-tools/src/toolbox.ts
. Seu bloco será adicionado à categoria "Campos".
Geradores de código
A Block Factory usa o sistema Code Generator que você já conhece do Blockly. Cada bloco tem um gerador de código para cada tipo de saída gerada pela Block Factory, e os blocos principais montam o código dos blocos filhos na saída correta. Para adicionar suporte a um campo personalizado, é necessário adicionar funções geradoras de código de bloco para cada uma das classes do gerador de código.
Crie um arquivo para o bloco de campo no diretório
output-generators/fields
. Você vai adicionar os
geradores de código de bloco para cada um dos seguintes geradores a esse arquivo. Importe
esse arquivo no arquivo blocks/index.ts
para que as
funções do gerador de código de bloco sejam carregadas no aplicativo.
Definição de JavaScript
O javascriptDefinitionGenerator
cria o código que será incluído na
definição JavaScript de um bloco que inclui seu campo personalizado. Normalmente, isso significa que o gerador de código em bloco precisa retornar uma linha de código semelhante a .appendField(new YourFieldConstructor(arg1, arg2), 'userSpecifiedName')
. Observe que essa linha de código não inclui um ponto e vírgula, porque uma entrada que contém vários campos terá várias chamadas para appendField
encadeadas. Os argumentos no construtor são extraídos dos valores que o usuário
definiu no bloco de campo. Confira um exemplo desse gerador de código de bloco para
FieldAngle
:
javascriptDefinitionGenerator.forBlock['field_angle'] = function (
block: Blockly.Block,
generator: JavascriptDefinitionGenerator,
): string {
const name = generator.quote_(block.getFieldValue('FIELDNAME'));
const angle = block.getFieldValue('ANGLE');
return `.appendField(new FieldAngle(${angle}), ${name})`;
};
O bloco de ângulo que o usuário arrastou da categoria "Campos" da caixa de ferramentas da Block Factory tem dois campos:
FIELDNAME
: o usuário pode definir o nome do campo no bloco personalizadoANGLE
: o usuário pode definir o valor de ângulo padrão.
Neste gerador de código em blocos, recebemos o valor de ângulo padrão e o transmitimos como o
único argumento para o construtor FieldAngle
. O nome do campo é sempre transmitido
como o segundo argumento para appendField
.
Definição de JSON
O jsonDefinitionGenerator
é semelhante, mas gera a parte da definição do bloco JSON que corresponde ao seu campo. Normalmente, esse código é um objeto JSON que inclui:
type
: corresponde ao nome do campo no registro de campos do Blockly.name
: o usuário pode definir o nome do campo no bloco personalizado- qualquer outra propriedade personalizada necessária pelo método de inicialização JSON do campo.
Confira outro exemplo de FieldAngle
:
jsonDefinitionGenerator.forBlock['field_angle'] = function (
block: Blockly.Block,
generator: JsonDefinitionGenerator,
): string {
const code = {
type: 'field_angle',
name: block.getFieldValue('FIELDNAME'),
angle: block.getFieldValue('ANGLE'),
};
return JSON.stringify(code);
};
Cabeçalhos de código
O gerador de cabeçalho de código cria a saída de cabeçalhos de código mostrada na Block
Factory. Essa saída pode ser alternada entre importações de esmodule e tags de script,
dependendo de como o usuário quer carregar o código. Portanto, há duas
instâncias de gerador diferentes: uma para cada caso. Você precisa adicionar um gerador de código de bloco para cada um deles. Confira um exemplo para FieldAngle
:
importHeaderGenerator.forBlock['field_angle'] = function (
block: Blockly.Block,
generator: CodeHeaderGenerator,
): string {
generator.addHeaderLine(
`import {registerFieldAngle, FieldAngle} from '@blockly/field-angle';`,
);
generator.addHeaderLine(`registerFieldAngle();`);
return '';
};
scriptHeaderGenerator.forBlock['field_angle'] = function (
block: Blockly.Block,
generator: CodeHeaderGenerator,
): string {
generator.addHeaderLine(
`<script src="https://unpkg.com/@blockly/field-angle"></script>`,
);
generator.addHeaderLine(`registerFieldAngle();`);
return '';
};
Esses geradores têm um método chamado addHeaderLine
que permite especificar uma
linha de código que deve ser chamada antes que o campo seja usado no código. Normalmente,
isso inclui trabalho como importar o campo ou carregá-lo por uma tag
de script e talvez chamar uma função que registre o campo no registro de
campos do Blockly.
Para esses dois geradores de código em bloco, todo o código precisa ser adicionado por chamadas
para addHeaderLine
. Essa função garante que cada linha de cabeçalho seja mostrada apenas uma vez, mesmo que o bloco de campo personalizado seja usado várias vezes em um bloco personalizado. O gerador de código de bloco precisa retornar a string vazia.
Stub do gerador
Por fim, temos o gerador que cria o stub do gerador para o campo. Neste gerador de código em blocos, você vai escrever um código que gera um código que ajuda o usuário a escrever um código que gera um código. Ainda não entendeu? É mais fácil do que parece!
O stub do gerador para um bloco personalizado inclui uma variável predefinida
que representa todos os campos do bloco. Em seguida, há um TODO
que o usuário precisa
concluir para reunir todas essas variáveis na string de código final que o
bloco personalizado vai retornar. Isso significa que, normalmente, tudo o que o gerador de código em blocos precisa fazer é retornar a linha que cria essa variável personalizada. Digamos que o usuário esteja criando um bloco personalizado que vai adicionar raios de sol à tela. Eles adicionam um campo de ângulo ao bloco e o chamam de "SUN_DIRECTION"
. O stub
do gerador para esse bloco incluiria a linha const angle_sun_direction =
block.getFieldValue("SUN_DIRECTION");
. Essa é a linha de código que nosso gerador de código de bloco
para o campo de ângulo precisa retornar:
generatorStubGenerator.forBlock['field_angle'] = function (
block: Blockly.Block,
generator: GeneratorStubGenerator,
): string {
const name = block.getFieldValue('FIELDNAME');
const fieldVar = generator.createVariableName('angle', name);
return `const ${fieldVar} = block.getFieldValue(${generator.quote_(
name,
)});\n`;
};
Para receber um nome padronizado para a variável, chame
generator.createVariableName
e transmita o tipo do campo (como
angle
, number
etc.) junto com o nome que o usuário deu ao campo.
Realizar o teste
Depois de escrever todas essas partes, você poderá iniciar a Block
Factory executando npm start
no diretório blockly-samples/examples/developer-tools
. Arraste o bloco da categoria de campo, adicione-o a uma entrada em um bloco e observe a mudança na saída. Verifique se a prévia do bloco está correta e se o código de cada uma das seções de saída também está.