File "block_definition_extractor.js"
Full path: /usr/home/mndrn/domains/mndrn.ru/public_html/block-hill/blockly/demos/blockfactory/block_definition_extractor.js
File size: 25.57 KiB (26186 bytes)
MIME-type: text/plain
Charset: utf-8
/**
* Copyright 2017 Juan Carlos Orozco Arena
* Apache License Version 2.0
*/
/**
* @fileoverview
* The BlockDefinitionExtractor is a class that generates a workspace DOM
* suitable for the BlockFactory's block editor, derived from an example
* Blockly.Block.
*
* <code>
* var workspaceDom = new BlockDefinitionExtractor()
* .buildBlockFactoryWorkspace(exampleBlocklyBlock);
* Blockly.Xml.domToWorkspace(workspaceDom, BlockFactory.mainWorkspace);
* </code>
*
* The <code>exampleBlocklyBlock</code> is usually the block loaded into the
* preview workspace after manually entering the block definition.
*
* @author JC-Orozco (Juan Carlos Orozco), AnmAtAnm (Andrew n marshall)
*/
'use strict';
/**
* Namespace to contain all functions needed to extract block definition from
* the block preview data structure.
* @namespace
*/
var BlockDefinitionExtractor = BlockDefinitionExtractor || Object.create(null);
/**
* Builds a BlockFactory workspace that reflects the block structure of the
* example block.
*
* @param {!Blockly.Block} block The reference block from which the definition
* will be extracted.
* @return {!Element} Returns the root workspace DOM <xml> for the block editor
* workspace.
*/
BlockDefinitionExtractor.buildBlockFactoryWorkspace = function(block) {
var workspaceXml = Blockly.utils.xml.createElement('xml');
workspaceXml.append(BlockDefinitionExtractor.factoryBase_(block, block.type));
return workspaceXml;
};
/**
* Helper function to create a new Element with the provided attributes and
* inner text.
*
* @param {string} name New element tag name.
* @param {!Object.<string, string>=} opt_attrs Optional list of attributes.
* @param {string=} opt_text Optional inner text.
* @return {!Element} The newly created element.
* @private
*/
BlockDefinitionExtractor.newDomElement_ = function(name, opt_attrs, opt_text) {
// Avoid createDom(..)'s attributes argument for being too HTML specific.
var elem = Blockly.utils.xml.createElement(name);
if (opt_attrs) {
for (var key in opt_attrs) {
elem.setAttribute(key, opt_attrs[key]);
}
}
if (opt_text) {
elem.append(opt_text);
}
return elem;
};
/**
* Creates an connection type constraint <block> Element representing the
* requested type.
*
* @param {string} type Type name of desired connection constraint.
* @return {!Element} The <block> representing the the constraint type.
* @private
*/
BlockDefinitionExtractor.buildBlockForType_ = function(type) {
switch (type) {
case 'Null':
return BlockDefinitionExtractor.typeNull_();
case 'Boolean':
return BlockDefinitionExtractor.typeBoolean_();
case 'Number':
return BlockDefinitionExtractor.typeNumber_();
case 'String':
return BlockDefinitionExtractor.typeString_();
case 'Array':
return BlockDefinitionExtractor.typeList_();
default:
return BlockDefinitionExtractor.typeOther_(type);
}
};
/**
* Constructs a <block> element representing the type constraints of the
* provided connection.
*
* @param {!Blockly.Connection} connection The connection with desired
* connection constraints.
* @return {!Element} The root <block> element of the constraint definition.
* @private
*/
BlockDefinitionExtractor.buildTypeConstraintBlockForConnection_ =
function(connection)
{
var typeBlock;
if (connection.check_) {
if (connection.check_.length < 1) {
typeBlock = BlockDefinitionExtractor.typeNullShadow_();
} else if (connection.check_.length === 1) {
typeBlock = BlockDefinitionExtractor.buildBlockForType_(
connection.check_[0]);
} else if (connection.check_.length > 1 ) {
typeBlock = BlockDefinitionExtractor.typeGroup_(connection.check_);
}
} else {
typeBlock = BlockDefinitionExtractor.typeNullShadow_();
}
return typeBlock;
};
/**
* Creates the root "factory_base" <block> element for the block definition.
*
* @param {!Blockly.Block} block The example block from which to extract the
* definition.
* @param {string} name Block name.
* @return {!Element} The factory_base block element.
* @private
*/
BlockDefinitionExtractor.factoryBase_ = function(block, name) {
BlockDefinitionExtractor.src = {root: block, current: block};
var factoryBaseEl =
BlockDefinitionExtractor.newDomElement_('block', {type: 'factory_base'});
factoryBaseEl.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'NAME'}, name));
factoryBaseEl.append(BlockDefinitionExtractor.buildInlineField_(block));
BlockDefinitionExtractor.buildConnections_(block, factoryBaseEl);
var inputsStatement = BlockDefinitionExtractor.newDomElement_(
'statement', {name: 'INPUTS'});
inputsStatement.append(BlockDefinitionExtractor.parseInputs_(block));
factoryBaseEl.append(inputsStatement);
var tooltipValue =
BlockDefinitionExtractor.newDomElement_('value', {name: 'TOOLTIP'});
tooltipValue.append(BlockDefinitionExtractor.text_(block.tooltip));
factoryBaseEl.append(tooltipValue);
var helpUrlValue =
BlockDefinitionExtractor.newDomElement_('value', {name: 'HELPURL'});
helpUrlValue.append(BlockDefinitionExtractor.text_(block.helpUrl));
factoryBaseEl.append(helpUrlValue);
// Convert colour_ to hue value 0-360 degrees
var colour_hue = block.getHue(); // May be null if not set via hue.
if (colour_hue) {
var colourBlock = BlockDefinitionExtractor.colourBlockFromHue_(colour_hue);
var colourInputValue =
BlockDefinitionExtractor.newDomElement_('value', {name: 'COLOUR'});
colourInputValue.append(colourBlock);
factoryBaseEl.append(colourInputValue);
} else {
// Editor will not have a colour block and preview will render black.
// TODO: Support RGB colours in the block editor.
}
return factoryBaseEl;
};
/**
* Generates the appropriate <field> element for the block definition's
* CONNECTIONS field, which determines the next, previous, and output
* connections.
*
* @param {!Blockly.Block} block The example block from which to extract the
* definition.
* @param {!Element} factoryBaseEl The root of the block definition.
* @private
*/
BlockDefinitionExtractor.buildConnections_ = function(block, factoryBaseEl) {
var connections = 'NONE';
if (block.outputConnection) {
connections = 'LEFT';
} else {
if (block.previousConnection) {
if (block.nextConnection) {
connections = 'BOTH';
} else {
connections = 'TOP';
}
} else if (block.nextConnection) {
connections = 'BOTTOM';
}
}
factoryBaseEl.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'CONNECTIONS'}, connections));
if (connections === 'LEFT') {
var inputValue =
BlockDefinitionExtractor.newDomElement_('value', {name: 'OUTPUTTYPE'});
inputValue.append(
BlockDefinitionExtractor.buildTypeConstraintBlockForConnection_(
block.outputConnection));
factoryBaseEl.append(inputValue);
} else {
if (connections === 'UP' || connections === 'BOTH') {
var inputValue =
BlockDefinitionExtractor.newDomElement_('value', {name: 'TOPTYPE'});
inputValue.append(
BlockDefinitionExtractor.buildTypeConstraintBlockForConnection_(
block.previousConnection));
factoryBaseEl.append(inputValue);
}
if (connections === 'DOWN' || connections === 'BOTH') {
var inputValue = BlockDefinitionExtractor.newDomElement_(
'value', {name: 'BOTTOMTYPE'});
inputValue.append(
BlockDefinitionExtractor.buildTypeConstraintBlockForConnection_(
block.nextConnection));
factoryBaseEl.append(inputValue);
}
}
};
/**
* Generates the appropriate <field> element for the block definition's INLINE
* field.
*
* @param {!Blockly.Block} block The example block from which to extract the
* definition.
* @return {Element} The INLINE <field> with value 'AUTO', 'INT' (internal) or
* 'EXT' (external).
* @private
*/
BlockDefinitionExtractor.buildInlineField_ = function(block) {
var inline = 'AUTO'; // When block.inputsInlineDefault === undefined
if (block.inputsInlineDefault === true) {
inline = 'INT';
} else if (block.inputsInlineDefault === false) {
inline = 'EXT';
}
return BlockDefinitionExtractor.newDomElement_(
'field', {name: 'INLINE'}, inline);
};
/**
* Constructs a sequence of <block> elements that represent the inputs of the
* provided block.
*
* @param {!Blockly.Block} block The source block to copy the inputs of.
* @return {Element} The fist <block> element of the sequence
* (and the root of the constructed DOM).
* @private
*/
BlockDefinitionExtractor.parseInputs_ = function(block) {
var firstInputDefElement = null;
var lastInputDefElement = null;
for (var i = 0; i < block.inputList.length; i++) {
var input = block.inputList[i];
var align = 'LEFT'; // Left alignment is the default.
if (input.align === Blockly.ALIGN_CENTRE) {
align = 'CENTRE';
} else if (input.align === Blockly.ALIGN_RIGHT) {
align = 'RIGHT';
}
var inputDefElement = BlockDefinitionExtractor.input_(input, align);
if (lastInputDefElement) {
var next = BlockDefinitionExtractor.newDomElement_('next');
next.append(inputDefElement);
lastInputDefElement.append(next);
} else {
firstInputDefElement = inputDefElement;
}
lastInputDefElement = inputDefElement;
}
return firstInputDefElement;
};
/**
* Creates a <block> element representing a block input.
*
* @param {!Blockly.Input} input The input object.
* @param {string} align Can be left, right or centre.
* @return {!Element} The <block> element that defines the input.
* @private
*/
BlockDefinitionExtractor.input_ = function(input, align) {
var isDummy = (input.type === Blockly.DUMMY_INPUT);
var inputTypeAttr =
isDummy ? 'input_dummy' :
(input.type === Blockly.INPUT_VALUE) ? 'input_value' : 'input_statement';
var inputDefBlock =
BlockDefinitionExtractor.newDomElement_('block', {type: inputTypeAttr});
if (!isDummy) {
inputDefBlock.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'INPUTNAME'}, input.name));
}
inputDefBlock.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'ALIGN'}, align));
var fieldsDef = BlockDefinitionExtractor.newDomElement_(
'statement', {name: 'FIELDS'});
var fieldsXml = BlockDefinitionExtractor.buildFields_(input.fieldRow);
fieldsDef.append(fieldsXml);
inputDefBlock.append(fieldsDef);
if (!isDummy) {
var typeValue = BlockDefinitionExtractor.newDomElement_(
'value', {name: 'TYPE'});
typeValue.append(
BlockDefinitionExtractor.buildTypeConstraintBlockForConnection_(
input.connection));
inputDefBlock.append(typeValue);
}
return inputDefBlock;
};
/**
* Constructs a sequence <block> elements representing the field definition.
* @param {Array.<Blockly.Field>} fieldRow A list of fields in a Blockly.Input.
* @return {Element} The fist <block> element of the sequence
* (and the root of the constructed DOM).
* @private
*/
BlockDefinitionExtractor.buildFields_ = function(fieldRow) {
var firstFieldDefElement = null;
var lastFieldDefElement = null;
for (var i = 0; i < fieldRow.length; i++) {
var field = fieldRow[i];
var fieldDefElement = BlockDefinitionExtractor.buildFieldElement_(field);
if (lastFieldDefElement) {
var next = BlockDefinitionExtractor.newDomElement_('next');
next.append(fieldDefElement);
lastFieldDefElement.append(next);
} else {
firstFieldDefElement = fieldDefElement;
}
lastFieldDefElement = fieldDefElement;
}
return firstFieldDefElement;
};
/**
* Constructs a <field> element that describes the provided Blockly.Field.
* @param {!Blockly.Field} field The field from which the definition is copied.
* @param {!Element} A <field> for the Field definition.
* @private
*/
BlockDefinitionExtractor.buildFieldElement_ = function(field) {
if (field instanceof Blockly.FieldLabel) {
return BlockDefinitionExtractor.buildFieldLabel_(field.text_);
} else if (field instanceof Blockly.FieldTextInput) {
return BlockDefinitionExtractor.buildFieldInput_(field.name, field.text_);
} else if (field instanceof Blockly.FieldNumber) {
return BlockDefinitionExtractor.buildFieldNumber_(
field.name, field.text_, field.min_, field.max_, field.presicion_);
} else if (field instanceof Blockly.FieldAngle) {
return BlockDefinitionExtractor.buildFieldAngle_(field.name, field.text_);
} else if (field instanceof Blockly.FieldCheckbox) {
return BlockDefinitionExtractor.buildFieldCheckbox_(field.name, field.state_);
} else if (field instanceof Blockly.FieldColour) {
return BlockDefinitionExtractor.buildFieldColour_(field.name, field.colour_);
} else if (field instanceof Blockly.FieldImage) {
return BlockDefinitionExtractor.buildFieldImage_(
field.src_, field.width_, field.height_, field.text_);
} else if (field instanceof Blockly.FieldVariable) {
// FieldVariable must be before FieldDropdown, because FieldVariable is a
// subclass.
return BlockDefinitionExtractor.buildFieldVariable_(field.name, field.text_);
} else if (field instanceof Blockly.FieldDropdown) {
return BlockDefinitionExtractor.buildFieldDropdown_(field);
}
throw Error('Unrecognized field class: ' + field.constructor.name);
};
/**
* Creates a <block> element representing a FieldLabel definition.
* @param {string} text
* @return {Element} The XML for FieldLabel definition.
* @private
*/
BlockDefinitionExtractor.buildFieldLabel_ = function(text) {
var fieldBlock =
BlockDefinitionExtractor.newDomElement_('block', {type: 'field_static'});
fieldBlock.append(
BlockDefinitionExtractor.newDomElement_('field', {name: 'TEXT'}, text));
return fieldBlock;
};
/**
* Creates a <block> element representing a FieldInput (text input) definition.
*
* @param {string} fieldName The identifying name of the field.
* @param {string} text The default text string.
* @return {Element} The XML for FieldInput definition.
* @private
*/
BlockDefinitionExtractor.buildFieldInput_ = function(fieldName, text) {
var fieldInput =
BlockDefinitionExtractor.newDomElement_('block', {type: 'field_input'});
fieldInput.append(
BlockDefinitionExtractor.newDomElement_('field', {name: 'TEXT'}, text));
fieldInput.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'FIELDNAME'}, fieldName));
return fieldInput;
};
/**
* Creates a <block> element representing a FieldNumber definition.
*
* @param {string} fieldName The identifying name of the field.
* @param {number} value The field's default value.
* @param {number} min The minimum allowed value, or negative infinity.
* @param {number} max The maximum allowed value, or positive infinity.
* @param {number} precision The precision allowed for the number.
* @return {Element} The XML for FieldNumber definition.
* @private
*/
BlockDefinitionExtractor.buildFieldNumber_ =
function(fieldName, value, min, max, precision)
{
var fieldNumber =
BlockDefinitionExtractor.newDomElement_('block', {type: 'field_number'});
fieldNumber.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'VALUE'}, value));
fieldNumber.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'FIELDNAME'}, fieldName));
fieldNumber.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'MIN'}, min));
fieldNumber.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'MAX'}, max));
fieldNumber.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'PRECISION'}, precision));
return fieldNumber;
};
/**
* Creates a <block> element representing a FieldAngle definition.
*
* @param {string} fieldName The identifying name of the field.
* @param {number} angle The field's default value.
* @return {Element} The XML for FieldAngle definition.
* @private
*/
BlockDefinitionExtractor.buildFieldAngle_ = function(angle, fieldName) {
var fieldAngle =
BlockDefinitionExtractor.newDomElement_('block', {type: 'field_angle'});
fieldAngle.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'ANGLE'}, angle));
fieldAngle.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'FIELDNAME'}, fieldName));
return fieldAngle;
};
/**
* Creates a <block> element representing a FieldDropdown definition.
*
* @param {Blockly.FieldDropdown} dropdown
* @return {Element} The <block> element representing a similar FieldDropdown.
* @private
*/
BlockDefinitionExtractor.buildFieldDropdown_ = function(dropdown) {
var menuGenerator = dropdown.menuGenerator_;
if (typeof menuGenerator === 'function') {
var options = menuGenerator();
} else if (Array.isArray(menuGenerator)) {
var options = menuGenerator;
} else {
throw Error('Unrecognized type of menuGenerator: ' + menuGenerator);
}
var fieldDropdown = BlockDefinitionExtractor.newDomElement_(
'block', {type: 'field_dropdown'});
var optionsStr = '[';
var mutation = BlockDefinitionExtractor.newDomElement_('mutation');
fieldDropdown.append(mutation);
fieldDropdown.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'FIELDNAME'}, dropdown.name));
for (var i=0; i<options.length; i++) {
var option = options[i];
if (typeof option[0] === "string") {
optionsStr += '"text",'
fieldDropdown.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'USER'+i}, option[0]));
} else {
optionsStr += '"image",';
fieldDropdown.append(
BlockDefinitionExtractor.newDomElement_(
'field', {name: 'SRC'+i}, option[0].src));
fieldDropdown.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'WIDTH'+i}, option[0].width));
fieldDropdown.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'HEIGHT'+i}, option[0].height));
fieldDropdown.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'ALT'+i}, option[0].alt));
}
fieldDropdown.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'CPU'+i}, option[1]));
}
optionsStr = optionsStr.slice(0,-1); // Drop last comma
optionsStr += ']';
mutation.setAttribute('options', optionsStr);
return fieldDropdown;
};
/**
* Creates a <block> element representing a FieldCheckbox definition.
*
* @param {string} fieldName The identifying name of the field.
* @param {string} checked The field's default value, true or false.
* @return {Element} The XML for FieldCheckbox definition.
* @private
*/
BlockDefinitionExtractor.buildFieldCheckbox_ =
function(fieldName, checked)
{
var fieldCheckbox = BlockDefinitionExtractor.newDomElement_(
'block', {type: 'field_checkbox'});
fieldCheckbox.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'CHECKED'}, checked));
fieldCheckbox.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'FIELDNAME'}, fieldName));
return fieldCheckbox;
};
/**
* Creates a <block> element representing a FieldColour definition.
*
* @param {string} fieldName The identifying name of the field.
* @param {string} colour The field's default value as a string.
* @return {Element} The XML for FieldColour definition.
* @private
*/
BlockDefinitionExtractor.buildFieldColour_ =
function(fieldName, colour)
{
var fieldColour = BlockDefinitionExtractor.newDomElement_(
'block', {type: 'field_colour'});
fieldColour.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'COLOUR'}, colour));
fieldColour.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'FIELDNAME'}, fieldName));
return fieldColour;
};
/**
* Creates a <block> element representing a FieldVariable definition.
*
* @param {string} fieldName The identifying name of the field.
* @param {string} varName The variables
* @return {Element} The <block> element representing the FieldVariable.
* @private
*/
BlockDefinitionExtractor.buildFieldVariable_ = function(fieldName, varName) {
var fieldVar = BlockDefinitionExtractor.newDomElement_(
'block', {type: 'field_variable'});
fieldVar.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'FIELDNAME'}, fieldName));
fieldVar.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'TEXT'}, varName));
return fieldVar;
};
/**
* Creates a <block> element representing a FieldImage definition.
*
* @param {string} src The URL of the field image.
* @param {number} width The pixel width of the source image
* @param {number} height The pixel height of the source image.
* @param {string} alt Alternate text to describe image.
* @private
*/
BlockDefinitionExtractor.buildFieldImage_ =
function(src, width, height, alt)
{
var block1 = BlockDefinitionExtractor.newDomElement_(
'block', {type: 'field_image'});
block1.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'SRC'}, src));
block1.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'WIDTH'}, width));
block1.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'HEIGHT'}, height));
block1.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'ALT'}, alt));
};
/**
* Creates a <block> element a group of allowed connection constraint types.
*
* @param {Array.<string>} types List of type names in this group.
* @return {Element} The <block> element representing the group, with child
* types attached.
* @private
*/
BlockDefinitionExtractor.typeGroup_ = function(types) {
var typeGroupBlock = BlockDefinitionExtractor.newDomElement_(
'block', {type: 'type_group'});
typeGroupBlock.append(BlockDefinitionExtractor.newDomElement_(
'mutation', {types:types.length}));
for (var i=0; i<types.length; i++) {
var typeBlock = BlockDefinitionExtractor.buildBlockForType_(types[i]);
var valueBlock = BlockDefinitionExtractor.newDomElement_(
'value', {name:'TYPE'+i});
valueBlock.append(typeBlock);
typeGroupBlock.append(valueBlock);
}
return typeGroupBlock;
};
/**
* Creates a <shadow> block element representing the default null connection
* constraint.
* @return {Element} The <block> element representing the "null" type
* constraint.
* @private
*/
BlockDefinitionExtractor.typeNullShadow_ = function() {
return BlockDefinitionExtractor.newDomElement_(
'shadow', {type: 'type_null'});
};
/**
* Creates a <block> element representing null in a connection constraint.
* @return {Element} The <block> element representing the "null" type
* constraint.
* @private
*/
BlockDefinitionExtractor.typeNull_ = function() {
return BlockDefinitionExtractor.newDomElement_('block', {type: 'type_null'});
};
/**
* Creates a <block> element representing the a boolean in a connection
* constraint.
* @return {Element} The <block> element representing the "boolean" type
* constraint.
* @private
*/
BlockDefinitionExtractor.typeBoolean_ = function() {
return BlockDefinitionExtractor.newDomElement_(
'block', {type: 'type_boolean'});
};
/**
* Creates a <block> element representing the a number in a connection
* constraint.
* @return {Element} The <block> element representing the "number" type
* constraint.
* @private
*/
BlockDefinitionExtractor.typeNumber_ = function() {
return BlockDefinitionExtractor.newDomElement_(
'block', {type: 'type_number'});
};
/**
* Creates a <block> element representing the a string in a connection
* constraint.
* @return {Element} The <block> element representing the "string" type
* constraint.
* @private
*/
BlockDefinitionExtractor.typeString_ = function() {
return BlockDefinitionExtractor.newDomElement_(
'block', {type: 'type_string'});
};
/**
* Creates a <block> element representing the a list in a connection
* constraint.
* @return {Element} The <block> element representing the "list" type
* constraint.
* @private
*/
BlockDefinitionExtractor.typeList_ = function() {
return BlockDefinitionExtractor.newDomElement_('block', {type: 'type_list'});
};
/**
* Creates a <block> element representing the given custom connection
* constraint type name.
*
* @param {string} type The connection constraint type name.
* @return {Element} The <block> element representing a custom input type
* constraint.
* @private
*/
BlockDefinitionExtractor.typeOther_ = function(type) {
var block = BlockDefinitionExtractor.newDomElement_(
'block', {type: 'type_other'});
block.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'TYPE'}, type));
return block;
};
/**
* Creates a block Element for the color_hue block, with the given hue.
* @param hue {number} The hue value, from 0 to 360.
* @return {Element} The <block> Element representing a colour_hue block
* with the given hue.
* @private
*/
BlockDefinitionExtractor.colourBlockFromHue_ = function(hue) {
var colourBlock = BlockDefinitionExtractor.newDomElement_(
'block', {type: 'colour_hue'});
colourBlock.append(BlockDefinitionExtractor.newDomElement_('mutation', {
colour: Blockly.hueToRgb(hue)
}));
colourBlock.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'HUE'}, hue.toString()));
return colourBlock;
};
/**
* Creates a block Element for a text block with the given text.
*
* @param text {string} The text value of the block.
* @return {Element} The <block> element representing a "text" block.
* @private
*/
BlockDefinitionExtractor.text_ = function(text) {
var textBlock =
BlockDefinitionExtractor.newDomElement_('block', {type: 'text'});
if (text) {
textBlock.append(BlockDefinitionExtractor.newDomElement_(
'field', {name: 'TEXT'}, text));
} // Else, use empty string default.
return textBlock;
};