mirror of
https://github.com/google/blockly.git
synced 2026-01-07 09:00:11 +01:00
Allowing manual code editing in Block Factory.
This commit is contained in:
@@ -23,11 +23,6 @@
|
|||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of the generated block.
|
|
||||||
*/
|
|
||||||
var blockType = '';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workspace for user to build block.
|
* Workspace for user to build block.
|
||||||
* @type Blockly.Workspace
|
* @type Blockly.Workspace
|
||||||
@@ -41,47 +36,67 @@ var mainWorkspace = null;
|
|||||||
var previewWorkspace = null;
|
var previewWorkspace = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the workspace changes, update the three other displays.
|
* Name of block if not named.
|
||||||
*/
|
*/
|
||||||
function onchange() {
|
var UNNAMED = 'unnamed';
|
||||||
var name = '';
|
|
||||||
|
/**
|
||||||
|
* Change the language code format.
|
||||||
|
*/
|
||||||
|
function formatChange() {
|
||||||
|
var mask = document.getElementById('blocklyMask');
|
||||||
|
var languagePre = document.getElementById('languagePre');
|
||||||
|
var languageTA = document.getElementById('languageTA');
|
||||||
|
if (document.getElementById('format').value == 'Manual') {
|
||||||
|
mask.style.display = 'block';
|
||||||
|
languagePre.style.display = 'none';
|
||||||
|
languageTA.style.display = 'block';
|
||||||
|
var code = languagePre.textContent.trim();
|
||||||
|
languageTA.value = code;
|
||||||
|
languageTA.focus();
|
||||||
|
updatePreview();
|
||||||
|
} else {
|
||||||
|
mask.style.display = 'none';
|
||||||
|
languageTA.style.display = 'none';
|
||||||
|
languagePre.style.display = 'block';
|
||||||
|
updateLanguage();
|
||||||
|
}
|
||||||
|
disableEnableLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the language code based on constructs made in Blockly.
|
||||||
|
*/
|
||||||
|
function updateLanguage() {
|
||||||
var rootBlock = getRootBlock();
|
var rootBlock = getRootBlock();
|
||||||
if (rootBlock) {
|
if (!rootBlock) {
|
||||||
name = rootBlock.getFieldValue('NAME');
|
return;
|
||||||
}
|
}
|
||||||
blockType = name.replace(/\W/g, '_').replace(/^(\d)/, '_\\1').toLowerCase();
|
var blockType = rootBlock.getFieldValue('NAME').trim().toLowerCase();
|
||||||
if (!blockType) {
|
if (!blockType) {
|
||||||
blockType = 'unnamed';
|
blockType = UNNAMED;
|
||||||
}
|
}
|
||||||
updateLanguage();
|
blockType = blockType.replace(/\W/g, '_').replace(/^(\d)/, '_\\1');
|
||||||
updateGenerator();
|
switch (document.getElementById('format').value) {
|
||||||
|
case 'JSON':
|
||||||
|
var code = formatJson_(blockType, rootBlock);
|
||||||
|
break;
|
||||||
|
case 'JavaScript':
|
||||||
|
var code = formatJavaScript_(blockType, rootBlock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
injectCode(code, 'languagePre');
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the language code.
|
|
||||||
*/
|
|
||||||
function updateLanguage() {
|
|
||||||
Blockly.removeAllRanges();
|
|
||||||
var code = [];
|
|
||||||
var rootBlock = getRootBlock();
|
|
||||||
if (rootBlock) {
|
|
||||||
switch (document.getElementById('format').value) {
|
|
||||||
case 'JSON':
|
|
||||||
formatJson(code, rootBlock);
|
|
||||||
break;
|
|
||||||
case 'JavaScript':
|
|
||||||
formatJavaScript(code, rootBlock);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
injectCode(code, 'languagePre');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the language code as JSON.
|
* Update the language code as JSON.
|
||||||
|
* @param {string} blockType Name of block.
|
||||||
|
* @param {!Blockly.Block} rootBlock Factory_base block.
|
||||||
|
* @return {string} Generanted language code.
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
function formatJson(code, rootBlock) {
|
function formatJson_(blockType, rootBlock) {
|
||||||
var JS = {};
|
var JS = {};
|
||||||
// ID is not used by Blockly, but may be used by a loader.
|
// ID is not used by Blockly, but may be used by a loader.
|
||||||
JS.id = blockType;
|
JS.id = blockType;
|
||||||
@@ -171,13 +186,18 @@ function formatJson(code, rootBlock) {
|
|||||||
}
|
}
|
||||||
JS.tooltip = '';
|
JS.tooltip = '';
|
||||||
JS.helpUrl = 'http://www.example.com/';
|
JS.helpUrl = 'http://www.example.com/';
|
||||||
code.push(JSON.stringify(JS, null, ' '));
|
return JSON.stringify(JS, null, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the language code as JavaScript.
|
* Update the language code as JavaScript.
|
||||||
|
* @param {string} blockType Name of block.
|
||||||
|
* @param {!Blockly.Block} rootBlock Factory_base block.
|
||||||
|
* @return {string} Generanted language code.
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
function formatJavaScript(code, rootBlock) {
|
function formatJavaScript_(blockType, rootBlock) {
|
||||||
|
var code = [];
|
||||||
code.push("Blockly.Blocks['" + blockType + "'] = {");
|
code.push("Blockly.Blocks['" + blockType + "'] = {");
|
||||||
code.push(" init: function() {");
|
code.push(" init: function() {");
|
||||||
// Generate inputs.
|
// Generate inputs.
|
||||||
@@ -241,8 +261,9 @@ function formatJavaScript(code, rootBlock) {
|
|||||||
}
|
}
|
||||||
code.push(" this.setTooltip('');");
|
code.push(" this.setTooltip('');");
|
||||||
code.push(" this.setHelpUrl('http://www.example.com/');");
|
code.push(" this.setHelpUrl('http://www.example.com/');");
|
||||||
code.push(" }");
|
code.push(' }');
|
||||||
code.push("};");
|
code.push('};');
|
||||||
|
return code.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -494,89 +515,77 @@ function getTypesFrom_(block, name) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the generator code.
|
* Update the generator code.
|
||||||
|
* @param {!Blockly.Block} block Rendered block in preview workspace.
|
||||||
*/
|
*/
|
||||||
function updateGenerator() {
|
function updateGenerator(block) {
|
||||||
Blockly.removeAllRanges();
|
|
||||||
function makeVar(root, name) {
|
function makeVar(root, name) {
|
||||||
name = name.toLowerCase().replace(/\W/g, '_');
|
name = name.toLowerCase().replace(/\W/g, '_');
|
||||||
return ' var ' + root + '_' + name;
|
return ' var ' + root + '_' + name;
|
||||||
}
|
}
|
||||||
var language = document.getElementById('language').value;
|
var language = document.getElementById('language').value;
|
||||||
var code = [];
|
var code = [];
|
||||||
code.push("Blockly." + language + "['" + blockType +
|
code.push("Blockly." + language + "['" + block.type +
|
||||||
"'] = function(block) {");
|
"'] = function(block) {");
|
||||||
var rootBlock = getRootBlock();
|
|
||||||
if (rootBlock) {
|
// Generate getters for any fields or inputs.
|
||||||
// Loop through every block, and generate getters for any fields or inputs.
|
for (var i = 0, input; input = block.inputList[i]; i++) {
|
||||||
var blocks = rootBlock.getDescendants();
|
for (var j = 0, field; field = input.fieldRow[j]; j++) {
|
||||||
for (var x = 0, block; block = blocks[x]; x++) {
|
var name = field.name;
|
||||||
if (block.disabled || block.getInheritedDisabled()) {
|
if (!name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (block.type) {
|
if (field instanceof Blockly.FieldVariable) {
|
||||||
case 'field_input':
|
// Subclass of Blockly.FieldDropdown, must test first.
|
||||||
var name = block.getFieldValue('FIELDNAME');
|
code.push(makeVar('variable', name) +
|
||||||
code.push(makeVar('text', name) +
|
" = Blockly." + language +
|
||||||
" = block.getFieldValue('" + name + "');");
|
".variableDB_.getName(block.getFieldValue('" + name +
|
||||||
break;
|
"'), Blockly.Variables.NAME_TYPE);");
|
||||||
case 'field_angle':
|
} else if (field instanceof Blockly.FieldAngle) {
|
||||||
var name = block.getFieldValue('FIELDNAME');
|
// Subclass of Blockly.FieldTextInput, must test first.
|
||||||
code.push(makeVar('angle', name) +
|
code.push(makeVar('angle', name) +
|
||||||
" = block.getFieldValue('" + name + "');");
|
" = block.getFieldValue('" + name + "');");
|
||||||
break;
|
} else if (Blockly.FieldDate && field instanceof Blockly.FieldDate) {
|
||||||
case 'field_dropdown':
|
// Blockly.FieldDate may not be compiled into Blockly.
|
||||||
var name = block.getFieldValue('FIELDNAME');
|
code.push(makeVar('date', name) +
|
||||||
code.push(makeVar('dropdown', name) +
|
" = block.getFieldValue('" + name + "');");
|
||||||
" = block.getFieldValue('" + name + "');");
|
} else if (field instanceof Blockly.FieldColour) {
|
||||||
break;
|
code.push(makeVar('colour', name) +
|
||||||
case 'field_checkbox':
|
" = block.getFieldValue('" + name + "');");
|
||||||
var name = block.getFieldValue('FIELDNAME');
|
} else if (field instanceof Blockly.FieldCheckbox) {
|
||||||
code.push(makeVar('checkbox', name) +
|
code.push(makeVar('checkbox', name) +
|
||||||
" = block.getFieldValue('" + name + "') == 'TRUE';");
|
" = block.getFieldValue('" + name + "') == 'TRUE';");
|
||||||
break;
|
} else if (field instanceof Blockly.FieldDropdown) {
|
||||||
case 'field_colour':
|
code.push(makeVar('dropdown', name) +
|
||||||
var name = block.getFieldValue('FIELDNAME');
|
" = block.getFieldValue('" + name + "');");
|
||||||
code.push(makeVar('colour', name) +
|
} else if (field instanceof Blockly.FieldTextInput) {
|
||||||
" = block.getFieldValue('" + name + "');");
|
code.push(makeVar('text', name) +
|
||||||
break;
|
" = block.getFieldValue('" + name + "');");
|
||||||
case 'field_date':
|
|
||||||
var name = block.getFieldValue('FIELDNAME');
|
|
||||||
code.push(makeVar('date', name) +
|
|
||||||
" = block.getFieldValue('" + name + "');");
|
|
||||||
break;
|
|
||||||
case 'field_variable':
|
|
||||||
var name = block.getFieldValue('FIELDNAME');
|
|
||||||
code.push(makeVar('variable', name) +
|
|
||||||
" = Blockly." + language +
|
|
||||||
".variableDB_.getName(block.getFieldValue('" + name +
|
|
||||||
"'), Blockly.Variables.NAME_TYPE);");
|
|
||||||
break;
|
|
||||||
case 'input_value':
|
|
||||||
var name = block.getFieldValue('INPUTNAME');
|
|
||||||
code.push(makeVar('value', name) +
|
|
||||||
" = Blockly." + language + ".valueToCode(block, '" + name +
|
|
||||||
"', Blockly." + language + ".ORDER_ATOMIC);");
|
|
||||||
break;
|
|
||||||
case 'input_statement':
|
|
||||||
var name = block.getFieldValue('INPUTNAME');
|
|
||||||
code.push(makeVar('statements', name) +
|
|
||||||
" = Blockly." + language + ".statementToCode(block, '" +
|
|
||||||
name + "');");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
code.push(" // TODO: Assemble " + language + " into code variable.");
|
var name = input.name;
|
||||||
code.push(" var code = \'...\';");
|
if (name) {
|
||||||
if (rootBlock.getFieldValue('CONNECTIONS') == 'LEFT') {
|
if (input.type == Blockly.INPUT_VALUE) {
|
||||||
code.push(" // TODO: Change ORDER_NONE to the correct strength.");
|
code.push(makeVar('value', name) +
|
||||||
code.push(" return [code, Blockly." + language + ".ORDER_NONE];");
|
" = Blockly." + language + ".valueToCode(block, '" + name +
|
||||||
} else {
|
"', Blockly." + language + ".ORDER_ATOMIC);");
|
||||||
code.push(" return code;");
|
} else if (input.type == Blockly.NEXT_STATEMENT) {
|
||||||
|
code.push(makeVar('statements', name) +
|
||||||
|
" = Blockly." + language + ".statementToCode(block, '" +
|
||||||
|
name + "');");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
code.push(" // TODO: Assemble " + language + " into code variable.");
|
||||||
|
code.push(" var code = \'...\';");
|
||||||
|
if (block.outputConnection) {
|
||||||
|
code.push(" // TODO: Change ORDER_NONE to the correct strength.");
|
||||||
|
code.push(" return [code, Blockly." + language + ".ORDER_NONE];");
|
||||||
|
} else {
|
||||||
|
code.push(" return code;");
|
||||||
|
}
|
||||||
code.push("};");
|
code.push("};");
|
||||||
|
|
||||||
injectCode(code, 'generatorPre');
|
injectCode(code.join('\n'), 'generatorPre');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -588,6 +597,7 @@ var oldDir = null;
|
|||||||
* Update the preview display.
|
* Update the preview display.
|
||||||
*/
|
*/
|
||||||
function updatePreview() {
|
function updatePreview() {
|
||||||
|
// Toggle between LTR/RTL if needed (also used in first display).
|
||||||
var newDir = document.getElementById('direction').value;
|
var newDir = document.getElementById('direction').value;
|
||||||
if (oldDir != newDir) {
|
if (oldDir != newDir) {
|
||||||
if (previewWorkspace) {
|
if (previewWorkspace) {
|
||||||
@@ -601,45 +611,86 @@ function updatePreview() {
|
|||||||
oldDir = newDir;
|
oldDir = newDir;
|
||||||
}
|
}
|
||||||
previewWorkspace.clear();
|
previewWorkspace.clear();
|
||||||
if (Blockly.Blocks[blockType]) {
|
|
||||||
throw 'Block name collides with existing property: ' + blockType;
|
// Fetch the code and determine its format (JSON or JavaScript).
|
||||||
|
var format = document.getElementById('format').value;
|
||||||
|
if (format == 'Manual') {
|
||||||
|
var code = document.getElementById('languageTA').value;
|
||||||
|
// If the code is JSON, it will parse, otherwise treat as JS.
|
||||||
|
try {
|
||||||
|
JSON.parse(code);
|
||||||
|
format = 'JSON';
|
||||||
|
} catch (e) {
|
||||||
|
format = 'JavaScript';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var code = document.getElementById('languagePre').textContent;
|
||||||
}
|
}
|
||||||
var code = document.getElementById('languagePre').textContent.trim();
|
if (!code.trim()) {
|
||||||
if (!code) {
|
|
||||||
// Nothing to render. Happens while cloud storage is loading.
|
// Nothing to render. Happens while cloud storage is loading.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var format = document.getElementById('format').value;
|
|
||||||
if (format == 'JSON') {
|
// Backup Blockly.Blocks object so that main workspace and preview don't
|
||||||
Blockly.Blocks[blockType] = {
|
// collide if user creates a 'factory_base' block, for instance.
|
||||||
init: function() {
|
var backupBlocks = Blockly.Blocks;
|
||||||
this.jsonInit(JSON.parse(code));
|
try {
|
||||||
|
// Make a shallow copy.
|
||||||
|
Blockly.Blocks = {};
|
||||||
|
for (var prop in backupBlocks) {
|
||||||
|
Blockly.Blocks[prop] = backupBlocks[prop];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == 'JSON') {
|
||||||
|
var json = JSON.parse(code);
|
||||||
|
Blockly.Blocks[json.id || UNNAMED] = {
|
||||||
|
init: function() {
|
||||||
|
this.jsonInit(json);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if (format == 'JavaScript') {
|
||||||
|
eval(code);
|
||||||
|
} else {
|
||||||
|
throw 'Unknown format: ' + format;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a block on Blockly.Blocks that does not match the backup.
|
||||||
|
var blockType = null;
|
||||||
|
for (var type in Blockly.Blocks) {
|
||||||
|
if (typeof Blockly.Blocks[type].init == 'function' &&
|
||||||
|
Blockly.Blocks[type] != backupBlocks[type]) {
|
||||||
|
blockType = type;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
} else if (format == 'JavaScript') {
|
if (!blockType) {
|
||||||
eval(code);
|
return;
|
||||||
} else {
|
}
|
||||||
throw 'Unknown format: ' + format;
|
|
||||||
|
// Create the preview block.
|
||||||
|
var previewBlock = Blockly.Block.obtain(previewWorkspace, blockType);
|
||||||
|
previewBlock.initSvg();
|
||||||
|
previewBlock.render();
|
||||||
|
previewBlock.setMovable(false);
|
||||||
|
previewBlock.setDeletable(false);
|
||||||
|
previewBlock.moveBy(15, 10);
|
||||||
|
|
||||||
|
updateGenerator(previewBlock);
|
||||||
|
} finally {
|
||||||
|
Blockly.Blocks = backupBlocks;
|
||||||
}
|
}
|
||||||
// Create the preview block.
|
|
||||||
var previewBlock = Blockly.Block.obtain(previewWorkspace, blockType);
|
|
||||||
delete Blockly.Blocks[blockType];
|
|
||||||
previewBlock.initSvg();
|
|
||||||
previewBlock.render();
|
|
||||||
previewBlock.setMovable(false);
|
|
||||||
previewBlock.setDeletable(false);
|
|
||||||
previewBlock.moveBy(15, 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject code into a pre tag, with syntax highlighting.
|
* Inject code into a pre tag, with syntax highlighting.
|
||||||
* Safe from HTML/script injection.
|
* Safe from HTML/script injection.
|
||||||
* @param {!Array.<string>} code Array of lines of code.
|
* @param {string} code Lines of code.
|
||||||
* @param {string} id ID of <pre> element to inject into.
|
* @param {string} id ID of <pre> element to inject into.
|
||||||
*/
|
*/
|
||||||
function injectCode(code, id) {
|
function injectCode(code, id) {
|
||||||
|
Blockly.removeAllRanges();
|
||||||
var pre = document.getElementById(id);
|
var pre = document.getElementById(id);
|
||||||
pre.textContent = code.join('\n');
|
pre.textContent = code;
|
||||||
code = pre.innerHTML;
|
code = pre.innerHTML;
|
||||||
code = prettyPrintOne(code, 'js');
|
code = prettyPrintOne(code, 'js');
|
||||||
pre.innerHTML = code;
|
pre.innerHTML = code;
|
||||||
@@ -659,6 +710,14 @@ function getRootBlock() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the link button if the format is 'Manual', enable otherwise.
|
||||||
|
*/
|
||||||
|
function disableEnableLink() {
|
||||||
|
var linkButton = document.getElementById('linkButton');
|
||||||
|
linkButton.disabled = document.getElementById('format').value == 'Manual';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize Blockly and layout. Called on page load.
|
* Initialize Blockly and layout. Called on page load.
|
||||||
*/
|
*/
|
||||||
@@ -676,17 +735,21 @@ function init() {
|
|||||||
linkButton.style.display = 'inline-block';
|
linkButton.style.display = 'inline-block';
|
||||||
linkButton.addEventListener('click',
|
linkButton.addEventListener('click',
|
||||||
function() {BlocklyStorage.link(mainWorkspace);});
|
function() {BlocklyStorage.link(mainWorkspace);});
|
||||||
|
disableEnableLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('helpButton').addEventListener('click', function() {
|
document.getElementById('helpButton').addEventListener('click',
|
||||||
|
function() {
|
||||||
open('https://developers.google.com/blockly/custom-blocks/block-factory',
|
open('https://developers.google.com/blockly/custom-blocks/block-factory',
|
||||||
'BlockFactoryHelp');
|
'BlockFactoryHelp');
|
||||||
});
|
});
|
||||||
|
|
||||||
var expandList = [
|
var expandList = [
|
||||||
document.getElementById('blockly'),
|
document.getElementById('blockly'),
|
||||||
|
document.getElementById('blocklyMask'),
|
||||||
document.getElementById('preview'),
|
document.getElementById('preview'),
|
||||||
document.getElementById('languagePre'),
|
document.getElementById('languagePre'),
|
||||||
|
document.getElementById('languageTA'),
|
||||||
document.getElementById('generatorPre')
|
document.getElementById('generatorPre')
|
||||||
];
|
];
|
||||||
var onresize = function(e) {
|
var onresize = function(e) {
|
||||||
@@ -714,12 +777,16 @@ function init() {
|
|||||||
rootBlock.setDeletable(false);
|
rootBlock.setDeletable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
mainWorkspace.addChangeListener(onchange);
|
mainWorkspace.addChangeListener(updateLanguage);
|
||||||
document.getElementById('direction')
|
document.getElementById('direction')
|
||||||
.addEventListener('change', updatePreview);
|
.addEventListener('change', updatePreview);
|
||||||
document.getElementById('format').addEventListener('change',
|
document.getElementById('languageTA')
|
||||||
function() {updateLanguage(); updatePreview();});
|
.addEventListener('change', updatePreview);
|
||||||
|
document.getElementById('languageTA')
|
||||||
|
.addEventListener('keyup', updatePreview);
|
||||||
|
document.getElementById('format')
|
||||||
|
.addEventListener('change', formatChange);
|
||||||
document.getElementById('language')
|
document.getElementById('language')
|
||||||
.addEventListener('change', updateGenerator);
|
.addEventListener('change', updatePreview);
|
||||||
}
|
}
|
||||||
window.addEventListener('load', init);
|
window.addEventListener('load', init);
|
||||||
|
|||||||
@@ -38,15 +38,29 @@
|
|||||||
#blockly {
|
#blockly {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
#blocklyMask {
|
||||||
|
background-color: #000;
|
||||||
|
cursor: not-allowed;
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
opacity: 0.2;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
#preview {
|
#preview {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
pre {
|
pre,
|
||||||
|
#languageTA {
|
||||||
|
border: #ddd 1px solid;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: #ddd 1px solid;
|
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
#languageTA {
|
||||||
|
display: none;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -57,14 +71,17 @@
|
|||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
font-size: large;
|
font-size: large;
|
||||||
}
|
}
|
||||||
button:hover {
|
button:hover:not(:disabled) {
|
||||||
box-shadow: 2px 2px 5px #888;
|
box-shadow: 2px 2px 5px #888;
|
||||||
}
|
}
|
||||||
|
button:disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
button>* {
|
button>* {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
vertical-align: text-bottom;
|
vertical-align: text-bottom;
|
||||||
}
|
}
|
||||||
button:hover>* {
|
button:hover:not(:disabled)>* {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
#linkButton {
|
#linkButton {
|
||||||
@@ -110,6 +127,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td width="50%" height="95%" style="padding: 2px;">
|
<td width="50%" height="95%" style="padding: 2px;">
|
||||||
<div id="blockly"></div>
|
<div id="blockly"></div>
|
||||||
|
<div id="blocklyMask"></div>
|
||||||
</td>
|
</td>
|
||||||
<td width="50%" height="95%">
|
<td width="50%" height="95%">
|
||||||
<table>
|
<table>
|
||||||
@@ -124,6 +142,7 @@
|
|||||||
<select id="format">
|
<select id="format">
|
||||||
<option value="JavaScript">JavaScript</option>
|
<option value="JavaScript">JavaScript</option>
|
||||||
<option value="JSON">JSON</option>
|
<option value="JSON">JSON</option>
|
||||||
|
<option value="Manual">Manual edit...</option>
|
||||||
</select>
|
</select>
|
||||||
</h3>
|
</h3>
|
||||||
</td>
|
</td>
|
||||||
@@ -131,6 +150,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td height="30%">
|
<td height="30%">
|
||||||
<pre id="languagePre"></pre>
|
<pre id="languagePre"></pre>
|
||||||
|
<textarea id="languageTA"></textarea>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user