/**
* @license
* Visual Blocks Editor
*
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Data Flyout components including variable and list blocks.
* @author marisaleung@google.com (Marisa Leung)
*/
'use strict';
/**
* @name Blockly.DataCategory
* @namespace
**/
goog.provide('Blockly.DataCategory');
goog.require('Blockly.Blocks');
goog.require('Blockly.VariableModel');
goog.require('Blockly.Variables');
goog.require('Blockly.Workspace');
/**
* Construct the blocks required by the flyout for the variable category.
* @param {!Blockly.Workspace} workspace The workspace containing variables.
* @return {!Array.} Array of XML block elements.
*/
Blockly.DataCategory = function(workspace) {
var variableModelList = workspace.getVariablesOfType('');
variableModelList.sort(Blockly.VariableModel.compareByName);
var xmlList = [];
Blockly.DataCategory.addCreateButton(xmlList, workspace, 'VARIABLE');
for (var i = 0; i < variableModelList.length; i++) {
Blockly.DataCategory.addDataVariable(xmlList, variableModelList[i]);
}
if (variableModelList.length > 0) {
xmlList[xmlList.length - 1].setAttribute('gap', 24);
var firstVariable = variableModelList[0];
Blockly.DataCategory.addSetVariableTo(xmlList, firstVariable);
Blockly.DataCategory.addChangeVariableBy(xmlList, firstVariable);
Blockly.DataCategory.addShowVariable(xmlList, firstVariable);
Blockly.DataCategory.addHideVariable(xmlList, firstVariable);
}
// Now add list variables to the flyout
Blockly.DataCategory.addCreateButton(xmlList, workspace, 'LIST');
variableModelList = workspace.getVariablesOfType(Blockly.LIST_VARIABLE_TYPE);
variableModelList.sort(Blockly.VariableModel.compareByName);
for (var i = 0; i < variableModelList.length; i++) {
Blockly.DataCategory.addDataList(xmlList, variableModelList[i]);
}
if (variableModelList.length > 0) {
xmlList[xmlList.length - 1].setAttribute('gap', 24);
var firstVariable = variableModelList[0];
Blockly.DataCategory.addAddToList(xmlList, firstVariable);
Blockly.DataCategory.addDeleteOfList(xmlList, firstVariable);
Blockly.DataCategory.addDeleteAllOfList(xmlList, firstVariable);
Blockly.DataCategory.addInsertAtList(xmlList, firstVariable);
Blockly.DataCategory.addReplaceItemOfList(xmlList, firstVariable);
Blockly.DataCategory.addItemOfList(xmlList, firstVariable);
Blockly.DataCategory.addItemNumberOfList(xmlList, firstVariable);
Blockly.DataCategory.addLengthOfList(xmlList, firstVariable);
Blockly.DataCategory.addListContainsItem(xmlList, firstVariable);
Blockly.DataCategory.addShowList(xmlList, firstVariable);
Blockly.DataCategory.addHideList(xmlList, firstVariable);
}
return xmlList;
};
/**
* Construct and add a data_variable block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addDataVariable = function(xmlList, variable) {
//
// variablename
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_variable', 'VARIABLE');
// In the flyout, this ID must match variable ID for monitor syncing reasons
xmlList[xmlList.length - 1].setAttribute('id', variable.getId());
};
/**
* Construct and add a data_setvariableto block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addSetVariableTo = function(xmlList, variable) {
//
//
//
//
//
//
// 0
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_setvariableto',
'VARIABLE', ['VALUE', 'text', 0]);
};
/**
* Construct and add a data_changevariableby block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addChangeVariableBy = function(xmlList, variable) {
//
//
//
//
//
//
// 1
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_changevariableby',
'VARIABLE', ['VALUE', 'math_number', 1]);
};
/**
* Construct and add a data_showVariable block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addShowVariable = function(xmlList, variable) {
//
//
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_showvariable',
'VARIABLE');
};
/**
* Construct and add a data_hideVariable block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addHideVariable = function(xmlList, variable) {
//
//
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_hidevariable',
'VARIABLE');
};
/**
* Construct and add a data_listcontents block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addDataList = function(xmlList, variable) {
//
// variablename
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_listcontents', 'LIST');
// In the flyout, this ID must match variable ID for monitor syncing reasons
xmlList[xmlList.length - 1].setAttribute('id', variable.getId());
};
/**
* Construct and add a data_addtolist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addAddToList = function(xmlList, variable) {
//
// variablename
//
//
// thing
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_addtolist', 'LIST',
['ITEM', 'text', 'thing']);
};
/**
* Construct and add a data_deleteoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addDeleteOfList = function(xmlList, variable) {
//
// variablename
//
//
// 1
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_deleteoflist', 'LIST',
['INDEX', 'math_integer', 1]);
};
/**
* Construct and add a data_deleteoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addDeleteAllOfList = function(xmlList, variable) {
//
// variablename
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_deletealloflist',
'LIST');
};
/**
* Construct and add a data_insertatlist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addInsertAtList = function(xmlList, variable) {
//
// variablename
//
//
// 1
//
//
//
//
// thing
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_insertatlist', 'LIST',
['INDEX', 'math_integer', 1], ['ITEM', 'text', 'thing']);
};
/**
* Construct and add a data_replaceitemoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addReplaceItemOfList = function(xmlList, variable) {
//
// variablename
//
//
// 1
//
//
//
//
// thing
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_replaceitemoflist',
'LIST', ['INDEX', 'math_integer', 1], ['ITEM', 'text', 'thing']);
};
/**
* Construct and add a data_itemoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addItemOfList = function(xmlList, variable) {
//
// variablename
//
//
// 1
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_itemoflist', 'LIST',
['INDEX', 'math_integer', 1]);
};
/** Construct and add a data_itemnumoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addItemNumberOfList = function(xmlList, variable) {
//
//
//
// thing
//
//
// variablename
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_itemnumoflist',
'LIST', ['ITEM', 'text', 'thing']);
};
/**
* Construct and add a data_lengthoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addLengthOfList = function(xmlList, variable) {
//
// variablename
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_lengthoflist', 'LIST');
};
/**
* Construct and add a data_listcontainsitem block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addListContainsItem = function(xmlList, variable) {
//
// variablename
//
//
// thing
//
//
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_listcontainsitem',
'LIST', ['ITEM', 'text', 'thing']);
};
/**
* Construct and add a data_showlist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addShowList = function(xmlList, variable) {
//
// variablename
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_showlist', 'LIST');
};
/**
* Construct and add a data_hidelist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addHideList = function(xmlList, variable) {
//
// variablename
//
Blockly.DataCategory.addBlock(xmlList, variable, 'data_hidelist', 'LIST');
};
/**
* Construct a create variable button and push it to the xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {Blockly.Workspace} workspace Workspace to register callback to.
* @param {string} type Type of variable this is for. For example, 'LIST' or
* 'VARIABLE'.
*/
Blockly.DataCategory.addCreateButton = function(xmlList, workspace, type) {
var button = goog.dom.createDom('button');
// Set default msg, callbackKey, and callback values for type 'VARIABLE'
var msg = Blockly.Msg.NEW_VARIABLE;
var callbackKey = 'CREATE_VARIABLE';
var callback = function(button) {
Blockly.Variables.createVariable(button.getTargetWorkspace(), null, '');};
if (type === 'LIST') {
msg = Blockly.Msg.NEW_LIST;
callbackKey = 'CREATE_LIST';
callback = function(button) {
Blockly.Variables.createVariable(button.getTargetWorkspace(), null,
Blockly.LIST_VARIABLE_TYPE);};
}
button.setAttribute('text', msg);
button.setAttribute('callbackKey', callbackKey);
workspace.registerButtonCallback(callbackKey, callback);
xmlList.push(button);
};
/**
* Construct a variable block with the given variable, blockType, and optional
* value tags. Add the variable block to the given xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
* @param {string} blockType Type of block. For example, 'data_hidelist' or
* data_showlist'.
* @param {string} fieldName Name of field in block. For example: 'VARIABLE' or
* 'LIST'.
* @param {?Array.} opt_value Optional array containing the value name
* and shadow type of value tags.
* @param {?Array.} opt_secondValue Optional array containing the value
* name and shadow type of a second pair of value tags.
*/
Blockly.DataCategory.addBlock = function(xmlList, variable, blockType,
fieldName, opt_value, opt_secondValue) {
if (Blockly.Blocks[blockType]) {
var firstValueField;
var secondValueField;
if (opt_value) {
firstValueField = Blockly.DataCategory.createValue(opt_value[0],
opt_value[1], opt_value[2]);
}
if (opt_secondValue) {
secondValueField = Blockly.DataCategory.createValue(opt_secondValue[0],
opt_secondValue[1], opt_value[2]);
}
var gap = 8;
var blockText = '' +
'' +
Blockly.Variables.generateVariableFieldXml_(variable, fieldName) +
firstValueField + secondValueField +
'' +
'';
var block = Blockly.Xml.textToDom(blockText).firstChild;
xmlList.push(block);
}
};
/**
* Create the text representation of a value dom element with a shadow of the
* indicated type inside.
* @param {string} valueName Name of the value tags.
* @param {string} type The type of the shadow tags.
* @param {string|number} value The default shadow value.
* @return {string} The generated dom element in text.
*/
Blockly.DataCategory.createValue = function(valueName, type, value) {
var fieldName;
switch (valueName) {
case 'ITEM':
fieldName = 'TEXT';
break;
case 'INDEX':
fieldName = 'NUM';
break;
case 'VALUE':
if (type === 'math_number') {
fieldName = 'NUM';
} else {
fieldName = 'TEXT';
}
break;
}
var valueField =
'' +
'' +
'' + value + '' +
'' +
'';
return valueField;
};