mirror of
https://github.com/google/blockly.git
synced 2026-01-06 16:40:07 +01:00
1645 lines
55 KiB
HTML
1645 lines
55 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Blockly Playground</title>
|
|
<script src="../blockly_uncompressed.js"></script>
|
|
<script src="../generators/javascript.js"></script>
|
|
<script src="../generators/javascript/logic.js"></script>
|
|
<script src="../generators/javascript/loops.js"></script>
|
|
<script src="../generators/javascript/math.js"></script>
|
|
<script src="../generators/javascript/text.js"></script>
|
|
<script src="../generators/javascript/lists.js"></script>
|
|
<script src="../generators/javascript/colour.js"></script>
|
|
<script src="../generators/javascript/variables.js"></script>
|
|
<script src="../generators/javascript/variables_dynamic.js"></script>
|
|
<script src="../generators/javascript/procedures.js"></script>
|
|
<script src="../generators/python.js"></script>
|
|
<script src="../generators/python/logic.js"></script>
|
|
<script src="../generators/python/loops.js"></script>
|
|
<script src="../generators/python/math.js"></script>
|
|
<script src="../generators/python/text.js"></script>
|
|
<script src="../generators/python/lists.js"></script>
|
|
<script src="../generators/python/colour.js"></script>
|
|
<script src="../generators/python/variables.js"></script>
|
|
<script src="../generators/python/variables_dynamic.js"></script>
|
|
<script src="../generators/python/procedures.js"></script>
|
|
<script src="../generators/php.js"></script>
|
|
<script src="../generators/php/logic.js"></script>
|
|
<script src="../generators/php/loops.js"></script>
|
|
<script src="../generators/php/math.js"></script>
|
|
<script src="../generators/php/text.js"></script>
|
|
<script src="../generators/php/lists.js"></script>
|
|
<script src="../generators/php/colour.js"></script>
|
|
<script src="../generators/php/variables.js"></script>
|
|
<script src="../generators/php/variables_dynamic.js"></script>
|
|
<script src="../generators/php/procedures.js"></script>
|
|
<script src="../generators/lua.js"></script>
|
|
<script src="../generators/lua/logic.js"></script>
|
|
<script src="../generators/lua/loops.js"></script>
|
|
<script src="../generators/lua/math.js"></script>
|
|
<script src="../generators/lua/text.js"></script>
|
|
<script src="../generators/lua/lists.js"></script>
|
|
<script src="../generators/lua/colour.js"></script>
|
|
<script src="../generators/lua/variables.js"></script>
|
|
<script src="../generators/lua/variables_dynamic.js"></script>
|
|
<script src="../generators/lua/procedures.js"></script>
|
|
<script src="../generators/dart.js"></script>
|
|
<script src="../generators/dart/logic.js"></script>
|
|
<script src="../generators/dart/loops.js"></script>
|
|
<script src="../generators/dart/math.js"></script>
|
|
<script src="../generators/dart/text.js"></script>
|
|
<script src="../generators/dart/lists.js"></script>
|
|
<script src="../generators/dart/colour.js"></script>
|
|
<script src="../generators/dart/variables.js"></script>
|
|
<script src="../generators/dart/variables_dynamic.js"></script>
|
|
<script src="../generators/dart/procedures.js"></script>
|
|
<script src="../msg/messages.js"></script>
|
|
<script src="../blocks/logic.js"></script>
|
|
<script src="../blocks/loops.js"></script>
|
|
<script src="../blocks/math.js"></script>
|
|
<script src="../blocks/text.js"></script>
|
|
<script src="../blocks/lists.js"></script>
|
|
<script src="../blocks/colour.js"></script>
|
|
<script src="../blocks/variables.js"></script>
|
|
<script src="../blocks/variables_dynamic.js"></script>
|
|
<script src="../blocks/procedures.js"></script>
|
|
<script src="blocks/test_blocks.js"></script>
|
|
<script src="./playgrounds/screenshot.js"></script>
|
|
|
|
<script>
|
|
// Custom requires for the playground.
|
|
goog.require('Blockly.blockRendering.Debug');
|
|
goog.require('Blockly.minimalist.Renderer');
|
|
goog.require('Blockly.Themes.Modern');
|
|
goog.require('Blockly.Themes.Zelos');
|
|
goog.require('Blockly.thrasos.Renderer');
|
|
goog.require('Blockly.zelos.Renderer');
|
|
</script>
|
|
<script>
|
|
'use strict';
|
|
var workspace = null;
|
|
|
|
function start() {
|
|
setBackgroundColour();
|
|
|
|
// Parse the URL arguments.
|
|
var match = location.search.match(/dir=([^&]+)/);
|
|
var rtl = match && match[1] == 'rtl';
|
|
document.forms.options.elements.dir.selectedIndex = Number(rtl);
|
|
var toolbox = getToolboxElement();
|
|
var toolboxNames = [
|
|
'toolbox-categories',
|
|
'toolbox-categories-typed-variables',
|
|
'toolbox-simple',
|
|
'toolbox-test-blocks'
|
|
];
|
|
document.forms.options.elements.toolbox.selectedIndex =
|
|
toolboxNames.indexOf(toolbox.id);
|
|
match = location.search.match(/side=([^&]+)/);
|
|
var side = match ? match[1] : 'start';
|
|
document.forms.options.elements.side.value = side;
|
|
var autoimport = !!location.search.match(/autoimport=([^&]+)/);
|
|
match = location.search.match(/renderer=([^&]+)/);
|
|
var renderer = match ? match[1] : 'geras';
|
|
document.forms.options.elements.renderer.value = renderer;
|
|
// Create main workspace.
|
|
workspace = Blockly.inject('blocklyDiv',
|
|
{
|
|
comments: true,
|
|
collapse: true,
|
|
disable: true,
|
|
grid:
|
|
{
|
|
spacing: 25,
|
|
length: 3,
|
|
colour: '#ccc',
|
|
snap: true
|
|
},
|
|
horizontalLayout: side == 'top' || side == 'bottom',
|
|
maxBlocks: Infinity,
|
|
maxInstances: {'test_basic_limit_instances': 3},
|
|
maxTrashcanContents: 256,
|
|
media: '../media/',
|
|
oneBasedIndex: true,
|
|
readOnly: false,
|
|
rtl: rtl,
|
|
move: {
|
|
scrollbars: true,
|
|
drag: true,
|
|
wheel: false,
|
|
},
|
|
toolbox: toolbox,
|
|
toolboxPosition: side == 'top' || side == 'start' ? 'start' : 'end',
|
|
renderer: renderer,
|
|
zoom:
|
|
{
|
|
controls: true,
|
|
wheel: true,
|
|
startScale: 1.0,
|
|
maxScale: 4,
|
|
minScale: 0.25,
|
|
scaleSpeed: 1.1
|
|
}
|
|
});
|
|
workspace.configureContextMenu = configureContextMenu;
|
|
addToolboxButtonCallbacks();
|
|
addRenderDebugOptionsCheckboxes();
|
|
// Restore previously displayed text.
|
|
if (sessionStorage) {
|
|
var text = sessionStorage.getItem('textarea');
|
|
if (text) {
|
|
document.getElementById('importExport').value = text;
|
|
}
|
|
// Restore event logging state.
|
|
var state = sessionStorage.getItem('logEvents');
|
|
logEvents(Boolean(Number(state)));
|
|
// Restore render debug state.
|
|
var renderDebugState = sessionStorage.getItem('blockRenderDebug');
|
|
toggleRenderingDebug(Boolean(Number(renderDebugState)));
|
|
// Restore render debug options state.
|
|
var renderDebugOptionsState =
|
|
JSON.parse(sessionStorage.getItem('blockRenderDebugOptions'));
|
|
setRenderDebugOptionCheckboxState(renderDebugOptionsState);
|
|
} else {
|
|
// MSIE 11 does not support sessionStorage on file:// URLs.
|
|
logEvents(false);
|
|
}
|
|
taChange();
|
|
if (autoimport) {
|
|
fromXml();
|
|
}
|
|
}
|
|
|
|
function addToolboxButtonCallbacks() {
|
|
var addAllBlocksToWorkspace = function(button) {
|
|
var workspace = button.getTargetWorkspace();
|
|
var blocks = button.workspace_.getTopBlocks();
|
|
for(var i = 0, block; block = blocks[i]; i++) {
|
|
var xml = Blockly.utils.xml.createElement('xml');
|
|
xml.appendChild(Blockly.Xml.blockToDom(block));
|
|
Blockly.Xml.appendDomToWorkspace(xml, workspace);
|
|
}
|
|
};
|
|
var randomizeLabelText = function(button) {
|
|
var blocks = button.targetWorkspace_
|
|
.getBlocksByType('test_fields_label_serializable');
|
|
var possible = 'AB';
|
|
for (var i = 0, block; block = blocks[i]; i++) {
|
|
var text = '';
|
|
for (var j = 0; j < 4; j++) {
|
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
}
|
|
block.setFieldValue(text, 'LABEL');
|
|
}
|
|
};
|
|
var setRandomStyle = function(button) {
|
|
var blocks = button.workspace_.getAllBlocks(false);
|
|
var styles =
|
|
Object.keys(workspace.getRenderer().getConstants().blockStyles);
|
|
styles.splice(styles.indexOf(blocks[0].getStyleName()), 1);
|
|
var style = styles[Math.floor(Math.random() * styles.length)];
|
|
for(var i = 0, block; block = blocks[i]; i++) {
|
|
block.setStyle(style);
|
|
}
|
|
};
|
|
var toggleEnabled = function(button) {
|
|
var blocks = button.workspace_.getAllBlocks(false);
|
|
for(var i = 0, block; block = blocks[i]; i++) {
|
|
block.setEnabled(!block.isEnabled());
|
|
}
|
|
};
|
|
var toggleShadow = function(button) {
|
|
var blocks = button.workspace_.getAllBlocks(false);
|
|
for(var i = 0, block; block = blocks[i]; i++) {
|
|
block.setShadow(!block.isShadow());
|
|
}
|
|
};
|
|
var toggleCollapsed = function(button) {
|
|
var blocks = button.workspace_.getAllBlocks(false);
|
|
for(var i = 0, block; block = blocks[i]; i++) {
|
|
block.setCollapsed(!block.isCollapsed());
|
|
}
|
|
};
|
|
var setInput = function(button) {
|
|
Blockly.prompt('Input text to set.', 'ab', function(input) {
|
|
var blocks = button.getTargetWorkspace().getAllBlocks(false);
|
|
for(var i = 0, block; block = blocks[i]; i++) {
|
|
if (block.getField('INPUT')) {
|
|
block.setFieldValue(input, 'INPUT');
|
|
}
|
|
}
|
|
})
|
|
};
|
|
var changeImage = function(button) {
|
|
var blocks = button.workspace_.getBlocksByType('test_fields_image');
|
|
var possible = 'abcdefghijklm';
|
|
var image = possible.charAt(Math.floor(Math.random() * possible.length));
|
|
var src = 'https://blockly-demo.appspot.com/static/tests/media/'
|
|
+ image + '.png';
|
|
for (var i = 0, block; block = blocks[i]; i++) {
|
|
var imageField = block.getField('IMAGE');
|
|
imageField.setValue(src);
|
|
}
|
|
};
|
|
var addVariables = function(button) {
|
|
workspace.createVariable('1b', '', '1B');
|
|
workspace.createVariable('1c', '', '1C');
|
|
workspace.createVariable('2a', '', '2A');
|
|
workspace.createVariable('2b', '', '2B');
|
|
workspace.createVariable('2c', '', '2C');
|
|
};
|
|
|
|
workspace.registerButtonCallback(
|
|
'addVariables', addVariables);
|
|
workspace.registerButtonCallback(
|
|
'changeImage', changeImage);
|
|
workspace.registerButtonCallback(
|
|
'addAllBlocksToWorkspace', addAllBlocksToWorkspace);
|
|
workspace.registerButtonCallback(
|
|
'setInput', setInput);
|
|
workspace.registerButtonCallback(
|
|
'setRandomStyle', setRandomStyle);
|
|
workspace.registerButtonCallback(
|
|
'toggleEnabled', toggleEnabled);
|
|
workspace.registerButtonCallback(
|
|
'toggleShadow', toggleShadow);
|
|
workspace.registerButtonCallback(
|
|
'toggleCollapsed', toggleCollapsed);
|
|
workspace.registerButtonCallback(
|
|
'randomizeLabelText', randomizeLabelText);
|
|
workspace.registerButtonCallback(
|
|
'addDynamicOption', Blockly.TestBlocks.addDynamicDropdownOption_);
|
|
workspace.registerButtonCallback(
|
|
'removeDynamicOption', Blockly.TestBlocks.removeDynamicDropdownOption_);
|
|
}
|
|
|
|
function setRenderDebugOptionCheckboxState(overrideOptions) {
|
|
Blockly.blockRendering.Debug.config = overrideOptions || {};
|
|
if (!overrideOptions) {
|
|
return;
|
|
}
|
|
var renderDebugOptionsListEl = document.getElementById('renderDebugOptions');
|
|
var renderDebugOptionInputs =
|
|
renderDebugOptionsListEl.getElementsByTagName('input');
|
|
for (var i = 0, optionInput;
|
|
(optionInput = renderDebugOptionInputs[i]); i++) {
|
|
var optionName = optionInput.getAttribute('data-optionName');
|
|
optionInput.checked = !!overrideOptions[optionName];
|
|
}
|
|
}
|
|
|
|
function updateRenderDebugOptions(e) {
|
|
var target = e.target;
|
|
var optionName = target.getAttribute('data-optionName');
|
|
var config = Blockly.blockRendering.Debug.config;
|
|
config[optionName] = !!target.checked;
|
|
sessionStorage.setItem(
|
|
'blockRenderDebugOptions', JSON.stringify(config));
|
|
workspace.render();
|
|
}
|
|
|
|
function addRenderDebugOptionsCheckboxes() {
|
|
var renderDebugConfig = Blockly.blockRendering.Debug.config;
|
|
var renderDebugOptionsListEl = document.getElementById('renderDebugOptions');
|
|
var optionNames = Object.keys(renderDebugConfig);
|
|
for (var i = 0, optionName; (optionName = optionNames[i]); i++) {
|
|
var optionCheckId = 'RenderDebug' + optionName + 'Check';
|
|
var optionLabel = document.createElement('label');
|
|
optionLabel.setAttribute('for', optionCheckId);
|
|
optionLabel.textContent = optionName;
|
|
var optionCheck = document.createElement('input');
|
|
optionCheck.setAttribute('type', 'checkbox');
|
|
optionCheck.setAttribute('id', optionCheckId);
|
|
optionCheck.setAttribute('data-optionName', optionName);
|
|
optionCheck.onclick = updateRenderDebugOptions;
|
|
var optionLi = document.createElement('li');
|
|
optionLi.appendChild(optionLabel);
|
|
optionLi.appendChild(optionCheck);
|
|
renderDebugOptionsListEl.appendChild(optionLi);
|
|
}
|
|
}
|
|
|
|
function changeTheme() {
|
|
var theme = document.getElementById('themeChanger');
|
|
|
|
if (theme.value === "dark") {
|
|
Blockly.getMainWorkspace().setTheme(Blockly.Themes.Dark);
|
|
} else if (theme.value === "high_contrast") {
|
|
Blockly.getMainWorkspace().setTheme(Blockly.Themes.HighContrast);
|
|
} else if (theme.value === "deuteranopia") {
|
|
Blockly.getMainWorkspace().setTheme(Blockly.Themes.Deuteranopia);
|
|
} else if (theme.value === "tritanopia") {
|
|
Blockly.getMainWorkspace().setTheme(Blockly.Themes.Tritanopia);
|
|
} else if (theme.value === "modern") {
|
|
Blockly.getMainWorkspace().setTheme(Blockly.Themes.Modern);
|
|
} else if (theme.value === "zelos") {
|
|
Blockly.getMainWorkspace().setTheme(Blockly.Themes.Zelos);
|
|
} else {
|
|
Blockly.getMainWorkspace().setTheme(Blockly.Themes.Classic);
|
|
}
|
|
}
|
|
|
|
function setBackgroundColour() {
|
|
// Set background colour to differentiate server vs local copy.
|
|
if (location.protocol == 'file:') {
|
|
var lilac = '#d6d6ff';
|
|
document.body.style.backgroundColor = lilac;
|
|
}
|
|
}
|
|
|
|
function getToolboxElement() {
|
|
var match = location.search.match(/toolbox=([^&]+)/);
|
|
// Default to the basic toolbox with categories and untyped variables,
|
|
// but override that if the toolbox type is set in the URL.
|
|
var toolboxSuffix = (match ? match[1] : 'categories');
|
|
// The three possible values are: "simple", "categories",
|
|
// "categories-typed-variables".
|
|
return document.getElementById('toolbox-' + toolboxSuffix);
|
|
}
|
|
|
|
function toXml() {
|
|
var output = document.getElementById('importExport');
|
|
var xml = Blockly.Xml.workspaceToDom(workspace);
|
|
output.value = Blockly.Xml.domToPrettyText(xml);
|
|
output.focus();
|
|
output.select();
|
|
taChange();
|
|
}
|
|
|
|
function fromXml() {
|
|
var input = document.getElementById('importExport');
|
|
if (!input.value) {
|
|
return;
|
|
}
|
|
var xml = Blockly.Xml.textToDom(input.value);
|
|
Blockly.Xml.domToWorkspace(xml, workspace);
|
|
taChange();
|
|
}
|
|
|
|
function toCode(lang) {
|
|
var output = document.getElementById('importExport');
|
|
output.value = Blockly[lang].workspaceToCode(workspace);
|
|
taChange();
|
|
}
|
|
|
|
// Disable the "Import from XML" button if the XML is invalid.
|
|
// Preserve text between page reloads.
|
|
function taChange() {
|
|
var textarea = document.getElementById('importExport');
|
|
if (sessionStorage) {
|
|
sessionStorage.setItem('textarea', textarea.value);
|
|
}
|
|
var valid = true;
|
|
try {
|
|
Blockly.Xml.textToDom(textarea.value);
|
|
} catch (e) {
|
|
valid = false;
|
|
}
|
|
document.getElementById('import').disabled = !valid;
|
|
}
|
|
|
|
function logEvents(state) {
|
|
var checkbox = document.getElementById('logCheck');
|
|
checkbox.checked = state;
|
|
if (sessionStorage) {
|
|
sessionStorage.setItem('logEvents', Number(state));
|
|
}
|
|
if (state) {
|
|
workspace.addChangeListener(logger);
|
|
} else {
|
|
workspace.removeChangeListener(logger);
|
|
}
|
|
}
|
|
|
|
function toggleRenderingDebug(state) {
|
|
var checkbox = document.getElementById('blockRenderDebugCheck');
|
|
checkbox.checked = state;
|
|
if (sessionStorage) {
|
|
sessionStorage.setItem('blockRenderDebug', Number(state));
|
|
}
|
|
if (state) {
|
|
document.getElementById('blocklyDiv').className = 'renderingDebug';
|
|
Blockly.blockRendering.startDebugger();
|
|
document.getElementById('renderDebugOptions').style.display = 'block';
|
|
} else {
|
|
document.getElementById('blocklyDiv').className = '';
|
|
Blockly.blockRendering.stopDebugger();
|
|
document.getElementById('renderDebugOptions').style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function toggleAccessibilityMode(state) {
|
|
if (state) {
|
|
Blockly.navigation.enableKeyboardAccessibility();
|
|
} else {
|
|
Blockly.navigation.disableKeyboardAccessibility();
|
|
}
|
|
}
|
|
|
|
function configureContextMenu(menuOptions) {
|
|
var screenshotOption = {
|
|
text: 'Download Screenshot',
|
|
enabled: workspace.getTopBlocks().length,
|
|
callback: function() {
|
|
Blockly.downloadScreenshot(workspace);
|
|
}
|
|
};
|
|
menuOptions.push(screenshotOption);
|
|
}
|
|
|
|
function logger(e) {
|
|
console.log(e);
|
|
}
|
|
|
|
function airstrike(n) {
|
|
var prototypes = [];
|
|
var toolbox = getToolboxElement();
|
|
var blocks = toolbox.getElementsByTagName('block');
|
|
for (var i = 0, block; block = blocks[i]; i++) {
|
|
prototypes.push(block.getAttribute('type'));
|
|
}
|
|
for (var i = 0; i < n; i++) {
|
|
var prototype = prototypes[Math.floor(Math.random() * prototypes.length)];
|
|
var block = workspace.newBlock(prototype);
|
|
block.initSvg();
|
|
block.getSvgRoot().setAttribute('transform', 'translate(' +
|
|
Math.round(Math.random() * 450 + 40) + ', ' +
|
|
Math.round(Math.random() * 600 + 40) + ')');
|
|
block.render();
|
|
}
|
|
}
|
|
|
|
function spaghetti(n) {
|
|
var xml = spaghettiXml;
|
|
for(var i = 0; i < n; i++) {
|
|
xml = xml.replace(/(<(statement|next)( name="DO0")?>)<\//g,
|
|
'$1' + spaghettiXml + '</');
|
|
}
|
|
xml = '<xml xmlns="https://developers.google.com/blockly/xml">' + xml + '</xml>';
|
|
var dom = Blockly.Xml.textToDom(xml);
|
|
console.time('Spaghetti domToWorkspace');
|
|
Blockly.Xml.domToWorkspace(dom, workspace);
|
|
console.timeEnd('Spaghetti domToWorkspace');
|
|
}
|
|
var spaghettiXml = [
|
|
' <block type="controls_if">',
|
|
' <value name="IF0">',
|
|
' <block type="logic_compare">',
|
|
' <field name="OP">EQ</field>',
|
|
' <value name="A">',
|
|
' <block type="math_arithmetic">',
|
|
' <field name="OP">MULTIPLY</field>',
|
|
' <value name="A">',
|
|
' <block type="math_number">',
|
|
' <field name="NUM">6</field>',
|
|
' </block>',
|
|
' </value>',
|
|
' <value name="B">',
|
|
' <block type="math_number">',
|
|
' <field name="NUM">7</field>',
|
|
' </block>',
|
|
' </value>',
|
|
' </block>',
|
|
' </value>',
|
|
' <value name="B">',
|
|
' <block type="math_number">',
|
|
' <field name="NUM">42</field>',
|
|
' </block>',
|
|
' </value>',
|
|
' </block>',
|
|
' </value>',
|
|
' <statement name="DO0"></statement>',
|
|
' <next></next>',
|
|
' </block>'].join('\n');
|
|
|
|
</script>
|
|
|
|
<style>
|
|
html, body {
|
|
height: 100%;
|
|
}
|
|
body {
|
|
background-color: #fff;
|
|
font-family: sans-serif;
|
|
overflow: hidden;
|
|
}
|
|
h1 {
|
|
font-weight: normal;
|
|
font-size: 140%;
|
|
}
|
|
#blocklyDiv {
|
|
float: right;
|
|
height: 95%;
|
|
width: 70%;
|
|
}
|
|
#importExport {
|
|
font-family: monospace;
|
|
}
|
|
|
|
.ioLabel>.blocklyFlyoutLabelText {
|
|
font-style: italic;
|
|
}
|
|
|
|
#blocklyDiv.renderingDebug .blockRenderDebug {
|
|
display: block;
|
|
}
|
|
|
|
.playgroundToggleOptions {
|
|
list-style: none;
|
|
padding: 0;
|
|
}
|
|
.playgroundToggleOptions li {
|
|
margin-top: 1em;
|
|
}
|
|
|
|
.blockRenderDebug {
|
|
display: none;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body onload="start()">
|
|
|
|
<div id="blocklyDiv"></div>
|
|
|
|
<h1>Blockly Playground</h1>
|
|
|
|
<p><a href="javascript:void(workspace.setVisible(true))">Show</a>
|
|
- <a href="javascript:void(workspace.setVisible(false))">Hide</a></p>
|
|
|
|
<form id="options">
|
|
<select name="dir" onchange="document.forms.options.submit()">
|
|
<option value="ltr">LTR</option>
|
|
<option value="rtl">RTL</option>
|
|
</select>
|
|
<select name="toolbox" onchange="document.forms.options.submit()">
|
|
<option value="categories">Categories (untyped variables)</option>
|
|
<option value="categories-typed-variables">Categories (typed variables)</option>
|
|
<option value="simple">Simple</option>
|
|
<option value="test-blocks">Test Blocks</option>
|
|
</select>
|
|
<select name="side" onchange="document.forms.options.submit()">
|
|
<option value="start">Start</option>
|
|
<option value="end">End</option>
|
|
<option value="top">Top</option>
|
|
<option value="bottom">Bottom</option>
|
|
</select>
|
|
<select name="renderer" onchange="document.forms.options.submit()">
|
|
<option value="geras">Geras</option>
|
|
<option value="thrasos">Thrasos</option>
|
|
<option value="zelos">Zelos</option>
|
|
<option value="minimalist">Minimalist</option>
|
|
</select>
|
|
</form>
|
|
<select id="themeChanger" name="theme" onchange="changeTheme()">
|
|
<option value="classic">Classic</option>
|
|
<option value="modern">Modern</option>
|
|
<option value="dark">Dark</option>
|
|
<option value="high_contrast">High Contrast</option>
|
|
<option value="deuteranopia">Deuteranopia/Protanopia</option>
|
|
<option value="tritanopia">Tritanopia</option>
|
|
<option value="zelos">Zelos</option>
|
|
</select>
|
|
<p>
|
|
<input type="button" value="Export to XML" onclick="toXml()">
|
|
|
|
<input type="button" value="Import from XML" onclick="fromXml()" id="import">
|
|
<br>
|
|
<input type="button" value="To JavaScript" onclick="toCode('JavaScript')">
|
|
|
|
<input type="button" value="To Python" onclick="toCode('Python')">
|
|
|
|
<input type="button" value="To PHP" onclick="toCode('PHP')">
|
|
|
|
<input type="button" value="To Lua" onclick="toCode('Lua')">
|
|
|
|
<input type="button" value="To Dart" onclick="toCode('Dart')">
|
|
<br>
|
|
<textarea id="importExport" style="width: 26%; height: 12em"
|
|
onchange="taChange();" onkeyup="taChange()"></textarea>
|
|
</p>
|
|
|
|
<p>
|
|
Stress test:
|
|
<input type="button" value="Airstrike!" onclick="airstrike(100)">
|
|
<input type="button" value="Spaghetti!" onclick="spaghetti(8)">
|
|
</p>
|
|
<ul class="playgroundToggleOptions">
|
|
<li>
|
|
<label for="logCheck">Log events:</label>
|
|
<input type="checkbox" onclick="logEvents(this.checked)" id="logCheck">
|
|
</li>
|
|
<li>
|
|
<label for="blockRenderDebugCheck">Enable block rendering debug:</label>
|
|
<input type="checkbox" onclick="toggleRenderingDebug(this.checked)" id="blockRenderDebugCheck">
|
|
<ul id="renderDebugOptions"></ul>
|
|
</li>
|
|
<li>
|
|
<label for="accessibilityModeCheck">Enable Accessibility Mode:</label>
|
|
<input type="checkbox" onclick="toggleAccessibilityMode(this.checked)" id="accessibilityModeCheck">
|
|
</li>
|
|
</ul>
|
|
|
|
|
|
<!-- The next three blocks of XML are sample toolboxes for testing basic
|
|
configurations. For more information on building toolboxes, see https://developers.google.com/blockly/guides/configure/web/toolbox -->
|
|
|
|
<!-- toolbox-simple is an always-open flyout with no category menu.
|
|
Always-open flyouts are a good idea if you have a small number of blocks. -->
|
|
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox-simple" style="display: none">
|
|
<block type="controls_ifelse"></block>
|
|
<block type="logic_compare"></block>
|
|
<!-- <block type="control_repeat"></block> -->
|
|
<block type="logic_operation"></block>
|
|
<block type="controls_repeat_ext">
|
|
<value name="TIMES">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="logic_operation"></block>
|
|
<block type="logic_negate"></block>
|
|
<block type="logic_boolean"></block>
|
|
<block type="logic_null" disabled="true"></block>
|
|
<block type="logic_ternary"></block>
|
|
<block type="text_charAt">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">text</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
</xml>
|
|
|
|
<!-- toolbox-categories has a category menu and an auto-closing flyout. The
|
|
Variables category uses untyped variable blocks.
|
|
See https://developers.google.com/blockly/guides/create-custom-blocks/variables#untyped_variable_blocks for more information. -->
|
|
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox-categories" style="display: none">
|
|
<category name="Logic" categorystyle="logic_category">
|
|
<block type="controls_if"></block>
|
|
<block type="logic_compare"></block>
|
|
<block type="logic_operation"></block>
|
|
<block type="logic_negate"></block>
|
|
<block type="logic_boolean"></block>
|
|
<block type="logic_null" disabled="true"></block>
|
|
<block type="logic_ternary"></block>
|
|
</category>
|
|
<category name="Loops" categorystyle="loop_category">
|
|
<block type="controls_repeat_ext">
|
|
<value name="TIMES">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="controls_repeat" disabled="true"></block>
|
|
<block type="controls_whileUntil"></block>
|
|
<block type="controls_for">
|
|
<value name="FROM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="TO">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="BY">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="controls_forEach"></block>
|
|
<block type="controls_flow_statements"></block>
|
|
</category>
|
|
<category name="Math" categorystyle="math_category">
|
|
<block type="math_number" gap="32">
|
|
<field name="NUM">123</field>
|
|
</block>
|
|
<block type="math_arithmetic">
|
|
<value name="A">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="B">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_single">
|
|
<value name="NUM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">9</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_trig">
|
|
<value name="NUM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">45</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_constant"></block>
|
|
<block type="math_number_property">
|
|
<value name="NUMBER_TO_CHECK">
|
|
<shadow type="math_number">
|
|
<field name="NUM">0</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_round">
|
|
<value name="NUM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">3.1</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_on_list"></block>
|
|
<block type="math_modulo">
|
|
<value name="DIVIDEND">
|
|
<shadow type="math_number">
|
|
<field name="NUM">64</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="DIVISOR">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_constrain">
|
|
<value name="VALUE">
|
|
<shadow type="math_number">
|
|
<field name="NUM">50</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="LOW">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="HIGH">
|
|
<shadow type="math_number">
|
|
<field name="NUM">100</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_random_int">
|
|
<value name="FROM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="TO">
|
|
<shadow type="math_number">
|
|
<field name="NUM">100</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_random_float"></block>
|
|
<block type="math_atan2">
|
|
<value name="X">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="Y">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
</category>
|
|
<category name="Text" categorystyle="text_category">
|
|
<block type="text"></block>
|
|
<block type="text_multiline"></block>
|
|
<block type="text_join"></block>
|
|
<block type="text_append">
|
|
<value name="TEXT">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_length">
|
|
<value name="VALUE">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_isEmpty">
|
|
<value name="VALUE">
|
|
<shadow type="text">
|
|
<field name="TEXT"></field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_indexOf">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">text</field>
|
|
</block>
|
|
</value>
|
|
<value name="FIND">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_charAt">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">text</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="text_getSubstring">
|
|
<value name="STRING">
|
|
<block type="variables_get">
|
|
<field name="VAR">text</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="text_changeCase">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_trim">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_count">
|
|
<value name="SUB">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
<value name="TEXT">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_replace">
|
|
<value name="FROM">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
<value name="TO">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
<value name="TEXT">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_reverse">
|
|
<value name="TEXT">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
</block>
|
|
<label text="Input/Output:" web-class="ioLabel"></label>
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_prompt_ext">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
</category>
|
|
<category name="Lists" categorystyle="list_category">
|
|
<block type="lists_create_with">
|
|
<mutation items="0"></mutation>
|
|
</block>
|
|
<block type="lists_create_with"></block>
|
|
<block type="lists_repeat">
|
|
<value name="NUM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">5</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="lists_length"></block>
|
|
<block type="lists_isEmpty"></block>
|
|
<block type="lists_indexOf">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">list</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="lists_getIndex">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">list</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="lists_setIndex">
|
|
<value name="LIST">
|
|
<block type="variables_get">
|
|
<field name="VAR">list</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="lists_getSublist">
|
|
<value name="LIST">
|
|
<block type="variables_get">
|
|
<field name="VAR">list</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="lists_split">
|
|
<value name="DELIM">
|
|
<shadow type="text">
|
|
<field name="TEXT">,</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="lists_sort"></block>
|
|
<block type="lists_reverse"></block>
|
|
</category>
|
|
<category name="Colour" categorystyle="colour_category">
|
|
<block type="colour_picker"></block>
|
|
<block type="colour_random"></block>
|
|
<block type="colour_rgb">
|
|
<value name="RED">
|
|
<shadow type="math_number">
|
|
<field name="NUM">100</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="GREEN">
|
|
<shadow type="math_number">
|
|
<field name="NUM">50</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="BLUE">
|
|
<shadow type="math_number">
|
|
<field name="NUM">0</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="colour_blend">
|
|
<value name="COLOUR1">
|
|
<shadow type="colour_picker">
|
|
<field name="COLOUR">#ff0000</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="COLOUR2">
|
|
<shadow type="colour_picker">
|
|
<field name="COLOUR">#3333ff</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="RATIO">
|
|
<shadow type="math_number">
|
|
<field name="NUM">0.5</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
</category>
|
|
<sep></sep>
|
|
<category name="Variables" categorystyle="variable_category" custom="VARIABLE"></category>
|
|
<category name="Functions" categorystyle="procedure_category" custom="PROCEDURE"></category>
|
|
</xml>
|
|
|
|
<!-- toolbox-categories-typed-variables has a category menu and an
|
|
auto-closing flyout. The Variables category uses typed variable blocks.
|
|
See https://developers.google.com/blockly/guides/create-custom-blocks/variables#typed_variable_blocks for more information. -->
|
|
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox-categories-typed-variables" style="display: none">
|
|
<category name="Logic" categorystyle="logic_category">
|
|
<block type="controls_if"></block>
|
|
<block type="logic_compare"></block>
|
|
<block type="logic_operation"></block>
|
|
<block type="logic_negate"></block>
|
|
<block type="logic_boolean"></block>
|
|
<block type="logic_null" disabled="true"></block>
|
|
<block type="logic_ternary"></block>
|
|
</category>
|
|
<category name="Loops" categorystyle="loop_category">
|
|
<block type="controls_repeat_ext">
|
|
<value name="TIMES">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="controls_repeat" disabled="true"></block>
|
|
<block type="controls_whileUntil"></block>
|
|
<block type="controls_for">
|
|
<value name="FROM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="TO">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="BY">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="controls_forEach"></block>
|
|
<block type="controls_flow_statements"></block>
|
|
</category>
|
|
<category name="Math" categorystyle="math_category">
|
|
<block type="math_number" gap="32">
|
|
<field name="NUM">123</field>
|
|
</block>
|
|
<block type="math_arithmetic">
|
|
<value name="A">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="B">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_single">
|
|
<value name="NUM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">9</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_trig">
|
|
<value name="NUM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">45</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_constant"></block>
|
|
<block type="math_number_property">
|
|
<value name="NUMBER_TO_CHECK">
|
|
<shadow type="math_number">
|
|
<field name="NUM">0</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_round">
|
|
<value name="NUM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">3.1</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_on_list"></block>
|
|
<block type="math_modulo">
|
|
<value name="DIVIDEND">
|
|
<shadow type="math_number">
|
|
<field name="NUM">64</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="DIVISOR">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_constrain">
|
|
<value name="VALUE">
|
|
<shadow type="math_number">
|
|
<field name="NUM">50</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="LOW">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="HIGH">
|
|
<shadow type="math_number">
|
|
<field name="NUM">100</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_random_int">
|
|
<value name="FROM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="TO">
|
|
<shadow type="math_number">
|
|
<field name="NUM">100</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="math_random_float"></block>
|
|
<block type="math_atan2">
|
|
<value name="X">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="Y">
|
|
<shadow type="math_number">
|
|
<field name="NUM">1</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
</category>
|
|
<category name="Text" categorystyle="text_category">
|
|
<block type="text"></block>
|
|
<block type="text_multiline"></block>
|
|
<block type="text_join"></block>
|
|
<block type="text_append">
|
|
<value name="TEXT">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_length">
|
|
<value name="VALUE">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_isEmpty">
|
|
<value name="VALUE">
|
|
<shadow type="text">
|
|
<field name="TEXT"></field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_indexOf">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">text</field>
|
|
</block>
|
|
</value>
|
|
<value name="FIND">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_charAt">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">text</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="text_getSubstring">
|
|
<value name="STRING">
|
|
<block type="variables_get">
|
|
<field name="VAR">text</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="text_changeCase">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_trim">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_count">
|
|
<value name="SUB">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
<value name="TEXT">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_replace">
|
|
<value name="FROM">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
<value name="TO">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
<value name="TEXT">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_reverse">
|
|
<value name="TEXT">
|
|
<shadow type="text"></shadow>
|
|
</value>
|
|
</block>
|
|
<label text="Input/Output:" web-class="ioLabel"></label>
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_prompt_ext">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">abc</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
</category>
|
|
<category name="Lists" categorystyle="list_category">
|
|
<block type="lists_create_with">
|
|
<mutation items="0"></mutation>
|
|
</block>
|
|
<block type="lists_create_with"></block>
|
|
<block type="lists_repeat">
|
|
<value name="NUM">
|
|
<shadow type="math_number">
|
|
<field name="NUM">5</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="lists_length"></block>
|
|
<block type="lists_isEmpty"></block>
|
|
<block type="lists_indexOf">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">list</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="lists_getIndex">
|
|
<value name="VALUE">
|
|
<block type="variables_get">
|
|
<field name="VAR">list</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="lists_setIndex">
|
|
<value name="LIST">
|
|
<block type="variables_get">
|
|
<field name="VAR">list</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="lists_getSublist">
|
|
<value name="LIST">
|
|
<block type="variables_get">
|
|
<field name="VAR">list</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="lists_split">
|
|
<value name="DELIM">
|
|
<shadow type="text">
|
|
<field name="TEXT">,</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="lists_sort"></block>
|
|
<block type="lists_reverse"></block>
|
|
</category>
|
|
<category name="Colour" categorystyle="colour_category">
|
|
<block type="colour_picker"></block>
|
|
<block type="colour_random"></block>
|
|
<block type="colour_rgb">
|
|
<value name="RED">
|
|
<shadow type="math_number">
|
|
<field name="NUM">100</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="GREEN">
|
|
<shadow type="math_number">
|
|
<field name="NUM">50</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="BLUE">
|
|
<shadow type="math_number">
|
|
<field name="NUM">0</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="colour_blend">
|
|
<value name="COLOUR1">
|
|
<shadow type="colour_picker">
|
|
<field name="COLOUR">#ff0000</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="COLOUR2">
|
|
<shadow type="colour_picker">
|
|
<field name="COLOUR">#3333ff</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="RATIO">
|
|
<shadow type="math_number">
|
|
<field name="NUM">0.5</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
</category>
|
|
<sep></sep>
|
|
<category name="Variables" categorystyle="variable_category" custom="VARIABLE_DYNAMIC"></category>
|
|
<category name="Functions" categorystyle="procedure_category" custom="PROCEDURE"></category>
|
|
</xml>
|
|
|
|
<!-- toolbox-test-blocks has a category menu and an auto-closing flyout.
|
|
The blocks in this toolbox reflect block configurations not used by
|
|
the standard predefined blocks, and so test alternative block rendering
|
|
code paths. -->
|
|
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox-test-blocks" style="display: none">
|
|
<category name="Basic">
|
|
<block type="test_basic_empty"></block>
|
|
<block type="test_basic_empty_with_mutator"></block>
|
|
<block type="test_basic_dummy"></block>
|
|
<block type="test_basic_multiple_dummy"></block>
|
|
<block type="test_basic_stack"></block>
|
|
<block type="test_basic_row"></block>
|
|
<block type="test_basic_value_to_stack"></block>
|
|
<block type="test_basic_value_to_statement"></block>
|
|
<block type="test_basic_limit_instances"></block>
|
|
<block type="test_basic_tooltips"></block>
|
|
<block type="test_basic_javascript"></block>
|
|
</category>
|
|
<category name="Align">
|
|
<block type="test_align_dummy_right"></block>
|
|
<block type="test_align_all"></block>
|
|
<block type="test_align_with_external_input"></block>
|
|
</category>
|
|
<category name="Drag">
|
|
<label text="Drag each to the workspace"></label>
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<block type="text">
|
|
<field name="TEXT">Drag me by this child</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">Drag me by this shadow</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">Shadow value</field>
|
|
</shadow>
|
|
</value>
|
|
<next>
|
|
<shadow type="text_print">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">Shadow statement</field>
|
|
</shadow>
|
|
</value>
|
|
</shadow>
|
|
</next>
|
|
</block>
|
|
<label text="Multiple Variable Refs"></label>
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<block type="variables_get">
|
|
<field name="VAR" id="item">item</field>
|
|
</block>
|
|
</value>
|
|
<next>
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<block type="variables_get">
|
|
<field name="VAR" id="item">item</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
</next>
|
|
</block>
|
|
<label text="Procedure Definitions"></label>
|
|
<block type="procedures_defnoreturn">
|
|
<field name="NAME">without arguments</field>
|
|
<statement name="STACK">
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">No argument reference.</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
</statement>
|
|
</block>
|
|
<block type="procedures_defnoreturn">
|
|
<mutation>
|
|
<arg name="fnArgument"></arg>
|
|
</mutation>
|
|
<field name="NAME">with one argument</field>
|
|
<statement name="STACK">
|
|
<block type="text_print">
|
|
<value name="TEXT">
|
|
<shadow type="text">
|
|
<field name="TEXT">Expected an argument reference here.</field>
|
|
</shadow>
|
|
<block type="variables_get">
|
|
<field name="VAR">fnArgument</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
</statement>
|
|
</block>
|
|
</category>
|
|
<category name="Fields" expanded="true">
|
|
<category name="Defaults">
|
|
<button text="add blocks to workspace" callbackKey="addAllBlocksToWorkspace"></button>
|
|
<sep gap="8"></sep>
|
|
<button text="set random style" callbackKey="setRandomStyle"></button>
|
|
<sep gap="8"></sep>
|
|
<button text="toggle enabled" callbackKey="toggleEnabled"></button>
|
|
<sep gap="8"></sep>
|
|
<button text="toggle shadow" callbackKey="toggleShadow"></button>
|
|
<sep gap="8"></sep>
|
|
<button text="toggle collapsed" callbackKey="toggleCollapsed"></button>
|
|
<block type="test_fields_angle"></block>
|
|
<block type="test_fields_checkbox"></block>
|
|
<block type="test_fields_colour"></block>
|
|
<block type="test_fields_colour_options"></block>
|
|
<block type="test_fields_text_input"></block>
|
|
<block type="test_fields_only_text_input"></block>
|
|
<block type="test_fields_multilinetext"></block>
|
|
<block type="test_fields_variable"></block>
|
|
<button text="randomize label text" callbackKey="randomizeLabelText"></button>
|
|
<sep gap="12"></sep>
|
|
<block type="test_fields_label_serializable"></block>
|
|
<button text="change image" callbackKey="changeImage"></button>
|
|
<sep gap="12"></sep>
|
|
<block type="test_fields_image"></block>
|
|
</category>
|
|
<category name="Numbers">
|
|
<block type="test_numbers_float">
|
|
<field name="NUM">123.456</field>
|
|
</block>
|
|
<block type="test_numbers_hundredths">
|
|
<field name="NUM">123.456</field>
|
|
</block>
|
|
<block type="test_numbers_halves">
|
|
<field name="NUM">123.456</field>
|
|
</block>
|
|
<block type="test_numbers_whole">
|
|
<field name="NUM">123.456</field>
|
|
</block>
|
|
<block type="test_numbers_three_halves">
|
|
<field name="NUM">123.456</field>
|
|
</block>
|
|
<block type="test_numbers_whole_bounded">
|
|
<field name="NOTE">60</field>
|
|
</block>
|
|
</category>
|
|
<category name="Angles">
|
|
<block type="test_angles_clockwise"></block>
|
|
<block type="test_angles_offset"></block>
|
|
<block type="test_angles_wrap"></block>
|
|
<block type="test_angles_round_30"></block>
|
|
<block type="test_angles_round_0"></block>
|
|
<block type="test_angles_protractor"></block>
|
|
<block type="test_angles_compass"></block>
|
|
</category>
|
|
<category name="Drop-downs">
|
|
<label text="Dynamic"></label>
|
|
<block type="test_dropdowns_dynamic"></block>
|
|
<button text="Add option" callbackKey="addDynamicOption"></button>
|
|
<button text="Remove option" callbackKey="removeDynamicOption"></button>
|
|
<block type="test_dropdowns_dynamic_random"></block>
|
|
<label text="Other"></label>
|
|
<block type="test_dropdowns_long"></block>
|
|
<block type="test_dropdowns_images"></block>
|
|
<block type="test_dropdowns_images_and_text"></block>
|
|
</category>
|
|
<category name="Images">
|
|
<block type="test_images_datauri"></block>
|
|
<block type="test_images_small"></block>
|
|
<block type="test_images_large"></block>
|
|
<block type="test_images_fliprtl"></block>
|
|
<block type="test_images_missing"></block>
|
|
<block type="test_images_many_icons"></block>
|
|
</category>
|
|
<category name="Emoji! o((*^ᴗ^*))o">
|
|
<label text="Unicode & Emojis"></label>
|
|
<block type="test_style_emoji"></block>
|
|
<block type="text">
|
|
<field name="TEXT">Robot face in text field: 🤖</field>
|
|
</block>
|
|
<block type="text">
|
|
<field name="TEXT">Zalgo in text field: B̛̻̦̬̘̰͎̥̈̔͊͞ͅl̡͖̫̺̬̖̣̳̃̀́͑͑̕͟͠͝o̢̹͙̮̫͔͋̉̊̑̿̽̚c̸̹̹̜͙̹̠͋̒͑̊̇͝k̡͉̫͇̖̳͖̊͒́̆̄̎̂̔̕͜͞l̰̙̞̳̩̠͖̯̀̆̈́̿̈̓͗y̨̡̟͇̮͈̬̙̲̏̅̀͘͠</field>
|
|
</block>
|
|
</category>
|
|
<category name="Validators">
|
|
<button text="add blocks to workspace" callbackKey="addAllBlocksToWorkspace"></button>
|
|
<sep gap="8"></sep>
|
|
<button text="set input" callbackKey="setInput"></button>
|
|
<label text="Angles"></label>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_angle_null"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_angle_mult30_force"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_angle_mult30_null"></block>
|
|
<label text="Checkboxes"></label>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_checkbox_null"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_checkbox_match"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_checkbox_not_match_null"></block>
|
|
<label text="Colours"></label>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_colour_null"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_colour_force_red"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_colour_red_null"></block>
|
|
<label text="Dropdowns"></label>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_dropdown_null"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_dropdown_force_1s"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_dropdown_1s_null"></block>
|
|
<label text="Numbers"></label>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_number_null"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_number_mult10_force"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_number_mult10_null"></block>
|
|
<label text="Text"></label>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_text_null"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_text_A"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_text_B"></block>
|
|
<label text="Variables"></label>
|
|
<sep gap="8"></sep>
|
|
<button text="add test variables" callbackKey="addVariables" web-class="modifiesWorkspace"></button>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_variable_null"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_variable_force_1s"></block>
|
|
<sep gap="12"></sep>
|
|
<block type="test_validators_variable_1s_null"></block>
|
|
</category>
|
|
</category>
|
|
<category name="Mutators">
|
|
<label text="logic_compare"></label>
|
|
<block type="logic_compare">
|
|
<value name="A">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
<value name="B">
|
|
<shadow type="math_number">
|
|
<field name="NUM">10</field>
|
|
</shadow>
|
|
</value>
|
|
</block>
|
|
<block type="logic_compare">
|
|
<value name="A">
|
|
<block type="math_number">
|
|
<field name="NUM">10</field>
|
|
</block>
|
|
</value>
|
|
<value name="B">
|
|
<block type="math_number">
|
|
<field name="NUM">10</field>
|
|
</block>
|
|
</value>
|
|
</block>
|
|
</category>
|
|
<category name="Style">
|
|
<label text="Hats"></label>
|
|
<block type="test_style_hat"></block>
|
|
<label text="Colour"></label>
|
|
<block type="test_style_hex1"></block>
|
|
<block type="test_style_hex2"></block>
|
|
<block type="test_style_hex3"></block>
|
|
<block type="test_style_no_colour"></block>
|
|
<block type="test_style_hex4"></block>
|
|
<block type="test_style_hex5"></block>
|
|
</category>
|
|
</xml>
|
|
</body>
|
|
</html>
|