From 0686762a12bbfa87afafe9ac5c6bb95ae6ebea1b Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Fri, 18 Mar 2016 17:59:52 -0700 Subject: [PATCH 01/13] Move options to their own file; clean up initialization code. --- core/inject.js | 275 +++++++++++++----------------------------------- core/options.js | 214 +++++++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+), 204 deletions(-) create mode 100644 core/options.js diff --git a/core/inject.js b/core/inject.js index 15010a4cb..75501def7 100644 --- a/core/inject.js +++ b/core/inject.js @@ -26,6 +26,7 @@ goog.provide('Blockly.inject'); +goog.require('Blockly.Options'); goog.require('Blockly.Css'); goog.require('Blockly.WorkspaceSvg'); goog.require('goog.dom'); @@ -49,7 +50,7 @@ Blockly.inject = function(container, opt_options) { if (!goog.dom.contains(document, container)) { throw 'Error: container is not in current document.'; } - var options = Blockly.parseOptions_(opt_options || {}); + var options = new Blockly.Options(opt_options || {}); var svg = Blockly.createDom_(container, options); var workspace = Blockly.createMainWorkspace_(svg, options); Blockly.init_(workspace); @@ -58,159 +59,6 @@ Blockly.inject = function(container, opt_options) { return workspace; }; -/** - * Parse the provided toolbox tree into a consistent DOM format. - * @param {Node|string} tree DOM tree of blocks, or text representation of same. - * @return {Node} DOM tree of blocks, or null. - * @private - */ -Blockly.parseToolboxTree_ = function(tree) { - if (tree) { - if (typeof tree != 'string') { - if (typeof XSLTProcessor == 'undefined' && tree.outerHTML) { - // In this case the tree will not have been properly built by the - // browser. The HTML will be contained in the element, but it will - // not have the proper DOM structure since the browser doesn't support - // XSLTProcessor (XML -> HTML). This is the case in IE 9+. - tree = tree.outerHTML; - } else if (!(tree instanceof Element)) { - tree = null; - } - } - if (typeof tree == 'string') { - tree = Blockly.Xml.textToDom(tree); - } - } else { - tree = null; - } - return tree; -}; - -/** - * Configure Blockly to behave according to a set of options. - * @param {!Object} options Dictionary of options. Specification: - * https://developers.google.com/blockly/installation/overview#configuration - * @return {!Object} Dictionary of normalized options. - * @private - */ -Blockly.parseOptions_ = function(options) { - var readOnly = !!options['readOnly']; - if (readOnly) { - var languageTree = null; - var hasCategories = false; - var hasTrashcan = false; - var hasCollapse = false; - var hasComments = false; - var hasDisable = false; - var hasSounds = false; - } else { - var languageTree = Blockly.parseToolboxTree_(options['toolbox']); - var hasCategories = Boolean(languageTree && - languageTree.getElementsByTagName('category').length); - var hasTrashcan = options['trashcan']; - if (hasTrashcan === undefined) { - hasTrashcan = hasCategories; - } - var hasCollapse = options['collapse']; - if (hasCollapse === undefined) { - hasCollapse = hasCategories; - } - var hasComments = options['comments']; - if (hasComments === undefined) { - hasComments = hasCategories; - } - var hasDisable = options['disable']; - if (hasDisable === undefined) { - hasDisable = hasCategories; - } - var hasSounds = options['sounds']; - if (hasSounds === undefined) { - hasSounds = true; - } - } - var hasScrollbars = options['scrollbars']; - if (hasScrollbars === undefined) { - hasScrollbars = hasCategories; - } - var hasCss = options['css']; - if (hasCss === undefined) { - hasCss = true; - } - // See grid documentation at: - // https://developers.google.com/blockly/installation/grid - var grid = options['grid'] || {}; - var gridOptions = {}; - gridOptions.spacing = parseFloat(grid['spacing']) || 0; - gridOptions.colour = grid['colour'] || '#888'; - gridOptions.length = parseFloat(grid['length']) || 1; - gridOptions.snap = gridOptions.spacing > 0 && !!grid['snap']; - var pathToMedia = 'https://blockly-demo.appspot.com/static/media/'; - if (options['media']) { - pathToMedia = options['media']; - } else if (options['path']) { - // 'path' is a deprecated option which has been replaced by 'media'. - pathToMedia = options['path'] + 'media/'; - } - - // See zoom documentation at: - // https://developers.google.com/blockly/installation/zoom - var zoom = options['zoom'] || {}; - var zoomOptions = {}; - if (zoom['controls'] === undefined) { - zoomOptions.controls = false; - } else { - zoomOptions.controls = !!zoom['controls']; - } - if (zoom['wheel'] === undefined) { - zoomOptions.wheel = false; - } else { - zoomOptions.wheel = !!zoom['wheel']; - } - if (zoom['startScale'] === undefined) { - zoomOptions.startScale = 1; - } else { - zoomOptions.startScale = parseFloat(zoom['startScale']); - } - if (zoom['maxScale'] === undefined) { - zoomOptions.maxScale = 3; - } else { - zoomOptions.maxScale = parseFloat(zoom['maxScale']); - } - if (zoom['minScale'] === undefined) { - zoomOptions.minScale = 0.3; - } else { - zoomOptions.minScale = parseFloat(zoom['minScale']); - } - if (zoom['scaleSpeed'] === undefined) { - zoomOptions.scaleSpeed = 1.2; - } else { - zoomOptions.scaleSpeed = parseFloat(zoom['scaleSpeed']); - } - - var enableRealtime = !!options['realtime']; - var realtimeOptions = enableRealtime ? options['realtimeOptions'] : undefined; - - return { - RTL: !!options['rtl'], - collapse: hasCollapse, - comments: hasComments, - disable: hasDisable, - readOnly: readOnly, - maxBlocks: options['maxBlocks'] || Infinity, - pathToMedia: pathToMedia, - hasCategories: hasCategories, - hasScrollbars: hasScrollbars, - hasTrashcan: hasTrashcan, - hasSounds: hasSounds, - hasCss: hasCss, - languageTree: languageTree, - gridOptions: gridOptions, - zoomOptions: zoomOptions, - enableRealtime: enableRealtime, - realtimeOptions: realtimeOptions - }; -}; - /** * Create the SVG image. * @param {!Element} container Containing element. @@ -405,6 +253,7 @@ Blockly.createMainWorkspace_ = function(svg, options) { Blockly.init_ = function(mainWorkspace) { var options = mainWorkspace.options; var svg = mainWorkspace.getParentSvg(); + // Supress the browser's context menu. Blockly.bindEvent_(svg, 'contextmenu', null, function(e) { @@ -412,34 +261,11 @@ Blockly.init_ = function(mainWorkspace) { e.preventDefault(); } }); - // Bind events for scrolling the workspace. - // Most of these events should be bound to the SVG's surface. - // However, 'mouseup' has to be on the whole document so that a block dragged - // out of bounds and released will know that it has been released. - // Also, 'keydown' has to be on the whole document since the browser doesn't - // understand a concept of focus on the SVG image. Blockly.bindEvent_(window, 'resize', null, function() {Blockly.svgResize(mainWorkspace);}); - if (!Blockly.documentEventsBound_) { - // Only bind the window/document events once. - // Destroying and reinjecting Blockly should not bind again. - Blockly.bindEvent_(document, 'keydown', null, Blockly.onKeyDown_); - Blockly.bindEvent_(document, 'touchend', null, Blockly.longStop_); - Blockly.bindEvent_(document, 'touchcancel', null, Blockly.longStop_); - // Don't use bindEvent_ for document's mouseup since that would create a - // corresponding touch handler that would squeltch the ability to interact - // with non-Blockly elements. - document.addEventListener('mouseup', Blockly.onMouseUp_, false); - // Some iPad versions don't fire resize after portrait to landscape change. - if (goog.userAgent.IPAD) { - Blockly.bindEvent_(window, 'orientationchange', document, function() { - Blockly.fireUiEvent(window, 'resize'); - }); - } - Blockly.documentEventsBound_ = true; - } + Blockly.inject.bindDocumentEvents_(); if (options.languageTree) { if (mainWorkspace.toolbox_) { @@ -456,6 +282,7 @@ Blockly.init_ = function(mainWorkspace) { mainWorkspace.translate(mainWorkspace.scrollX, 0); } } + if (options.hasScrollbars) { mainWorkspace.scrollbar = new Blockly.ScrollbarPair(mainWorkspace); mainWorkspace.scrollbar.resize(); @@ -463,35 +290,75 @@ Blockly.init_ = function(mainWorkspace) { // Load the sounds. if (options.hasSounds) { - mainWorkspace.loadAudio_( - [options.pathToMedia + 'click.mp3', - options.pathToMedia + 'click.wav', - options.pathToMedia + 'click.ogg'], 'click'); - mainWorkspace.loadAudio_( - [options.pathToMedia + 'disconnect.wav', - options.pathToMedia + 'disconnect.mp3', - options.pathToMedia + 'disconnect.ogg'], 'disconnect'); - mainWorkspace.loadAudio_( - [options.pathToMedia + 'delete.mp3', - options.pathToMedia + 'delete.ogg', - options.pathToMedia + 'delete.wav'], 'delete'); - - // Bind temporary hooks that preload the sounds. - var soundBinds = []; - var unbindSounds = function() { - while (soundBinds.length) { - Blockly.unbindEvent_(soundBinds.pop()); - } - mainWorkspace.preloadAudio_(); - }; - // Android ignores any sound not loaded as a result of a user action. - soundBinds.push( - Blockly.bindEvent_(document, 'mousemove', null, unbindSounds)); - soundBinds.push( - Blockly.bindEvent_(document, 'touchstart', null, unbindSounds)); + Blockly.inject.loadSounds_(options.pathToMedia, mainWorkspace); } }; +/** + * Bind document events, but only once. Destroying and reinjecting Blockly + * should not bind again. + * Bind events for scrolling the workspace. + * Most of these events should be bound to the SVG's surface. + * However, 'mouseup' has to be on the whole document so that a block dragged + * out of bounds and released will know that it has been released. + * Also, 'keydown' has to be on the whole document since the browser doesn't + * understand a concept of focus on the SVG image. + * @private + */ +Blockly.inject.bindDocumentEvents_ = function() { + if (!Blockly.documentEventsBound_) { + Blockly.bindEvent_(document, 'keydown', null, Blockly.onKeyDown_); + Blockly.bindEvent_(document, 'touchend', null, Blockly.longStop_); + Blockly.bindEvent_(document, 'touchcancel', null, Blockly.longStop_); + // Don't use bindEvent_ for document's mouseup since that would create a + // corresponding touch handler that would squeltch the ability to interact + // with non-Blockly elements. + document.addEventListener('mouseup', Blockly.onMouseUp_, false); + // Some iPad versions don't fire resize after portrait to landscape change. + if (goog.userAgent.IPAD) { + Blockly.bindEvent_(window, 'orientationchange', document, function() { + Blockly.fireUiEvent(window, 'resize'); + }); + } + } + Blockly.documentEventsBound_ = true; +}; + +/** + * Load sounds for the given workspace. + * @param options {string} The path to the media directory. + * @param workspace {!Blockly.Workspace} The workspace to load sounds for. + * @private + */ +Blockly.inject.loadSounds_ = function(pathToMedia, workspace) { + workspace.loadAudio_( + [pathToMedia + 'click.mp3', + pathToMedia + 'click.wav', + pathToMedia + 'click.ogg'], 'click'); + workspace.loadAudio_( + [pathToMedia + 'disconnect.wav', + pathToMedia + 'disconnect.mp3', + pathToMedia + 'disconnect.ogg'], 'disconnect'); + workspace.loadAudio_( + [pathToMedia + 'delete.mp3', + pathToMedia + 'delete.ogg', + pathToMedia + 'delete.wav'], 'delete'); + + // Bind temporary hooks that preload the sounds. + var soundBinds = []; + var unbindSounds = function() { + while (soundBinds.length) { + Blockly.unbindEvent_(soundBinds.pop()); + } + workspace.preloadAudio_(); + }; + // Android ignores any sound not loaded as a result of a user action. + soundBinds.push( + Blockly.bindEvent_(document, 'mousemove', null, unbindSounds)); + soundBinds.push( + Blockly.bindEvent_(document, 'touchstart', null, unbindSounds)); +}; + /** * Modify the block tree on the existing toolbox. * @param {Node|string} tree DOM tree of blocks, or text representation of same. diff --git a/core/options.js b/core/options.js new file mode 100644 index 000000000..19a848105 --- /dev/null +++ b/core/options.js @@ -0,0 +1,214 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2016 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 Object that controls settings for the workspace. + * @author fenichel@google.com (Rachel Fenichel) + */ +'use strict'; + +goog.provide('Blockly.Options'); + + +/** + * Parse the user-specified options, using reasonable defaults where behaviour + * is unspecified. + * @param {!Object} options Dictionary of options. Specification: + * https://developers.google.com/blockly/installation/overview#configuration + * @return {!Blockly.Options} Object containing a dicitonary of normalized + * options. + */ +Blockly.Options = function(options) { + var readOnly = !!options['readOnly']; + if (readOnly) { + var languageTree = null; + var hasCategories = false; + var hasTrashcan = false; + var hasCollapse = false; + var hasComments = false; + var hasDisable = false; + var hasSounds = false; + } else { + var languageTree = Blockly.Options.parseToolboxTree_(options['toolbox']); + var hasCategories = Boolean(languageTree && + languageTree.getElementsByTagName('category').length); + var hasTrashcan = options['trashcan']; + if (hasTrashcan === undefined) { + hasTrashcan = hasCategories; + } + var hasCollapse = options['collapse']; + if (hasCollapse === undefined) { + hasCollapse = hasCategories; + } + var hasComments = options['comments']; + if (hasComments === undefined) { + hasComments = hasCategories; + } + var hasDisable = options['disable']; + if (hasDisable === undefined) { + hasDisable = hasCategories; + } + var hasSounds = options['sounds']; + if (hasSounds === undefined) { + hasSounds = true; + } + } + var hasScrollbars = options['scrollbars']; + if (hasScrollbars === undefined) { + hasScrollbars = hasCategories; + } + var hasCss = options['css']; + if (hasCss === undefined) { + hasCss = true; + } + var pathToMedia = 'https://blockly-demo.appspot.com/static/media/'; + if (options['media']) { + pathToMedia = options['media']; + } else if (options['path']) { + // 'path' is a deprecated option which has been replaced by 'media'. + pathToMedia = options['path'] + 'media/'; + } + + var enableRealtime = !!options['realtime']; + var realtimeOptions = enableRealtime ? options['realtimeOptions'] : undefined; + + this.RTL = !!options['rtl']; + this.collapse = hasCollapse; + this.comments = hasComments; + this.disable = hasDisable; + this.readOnly = readOnly; + this.maxBlocks = options['maxBlocks'] || Infinity; + this.pathToMedia = pathToMedia; + this.hasCategories = hasCategories; + this.hasScrollbars = hasScrollbars; + this.hasTrashcan = hasTrashcan; + this.hasSounds = hasSounds; + this.hasCss = hasCss; + this.languageTree = languageTree; + this.gridOptions = Blockly.Options.parseGridOptions_(options); + this.zoomOptions = Blockly.Options.parseZoomOptions_(options); + this.enableRealtime = enableRealtime; + this.realtimeOptions = realtimeOptions; +}; + +Blockly.Options.prototype.parentWorkspace = null; + +/** + * If set, sets the translation of the workspace to match the scrollbars. + * No-op if unset. + */ +Blockly.Options.prototype.setMetrics = function(translation) { return; }; + +/** + * Return an object with the metrics required to size the workspace, or null + * if unset. + * @return {Object} Contains size an position metrics, or null. + */ +Blockly.Options.prototype.getMetrics = function() { return null; }; + +/** + * Parse the user-specified zoom options, using reasonable defaults where + * behaviour is unspecified. See zoom documentation: + * https://developers.google.com/blockly/installation/zoom + * @param {!Object} options Dictionary of options options. + * @return {!Object} A dictionary of normalized options. + * @private + */ +Blockly.Options.parseZoomOptions_ = function(options) { + var zoom = options['zoom'] || {}; + var zoomOptions = {}; + if (zoom['controls'] === undefined) { + zoomOptions.controls = false; + } else { + zoomOptions.controls = !!zoom['controls']; + } + if (zoom['wheel'] === undefined) { + zoomOptions.wheel = false; + } else { + zoomOptions.wheel = !!zoom['wheel']; + } + if (zoom['startScale'] === undefined) { + zoomOptions.startScale = 1; + } else { + zoomOptions.startScale = parseFloat(zoom['startScale']); + } + if (zoom['maxScale'] === undefined) { + zoomOptions.maxScale = 3; + } else { + zoomOptions.maxScale = parseFloat(zoom['maxScale']); + } + if (zoom['minScale'] === undefined) { + zoomOptions.minScale = 0.3; + } else { + zoomOptions.minScale = parseFloat(zoom['minScale']); + } + if (zoom['scaleSpeed'] === undefined) { + zoomOptions.scaleSpeed = 1.2; + } else { + zoomOptions.scaleSpeed = parseFloat(zoom['scaleSpeed']); + } + return zoomOptions; +}; + +/** + * Parse the user-specified grid options, using reasonable defaults where + * behaviour is unspecified. See grid documentation: + * https://developers.google.com/blockly/installation/grid + * @param {!Object} options Dictionary of options. + * @return {!Object} A dictionary of normalized options. + * @private + */ +Blockly.Options.parseGridOptions_ = function(options) { + var grid = options['grid'] || {}; + var gridOptions = {}; + gridOptions.spacing = parseFloat(grid['spacing']) || 0; + gridOptions.colour = grid['colour'] || '#888'; + gridOptions.length = parseFloat(grid['length']) || 1; + gridOptions.snap = gridOptions.spacing > 0 && !!grid['snap']; + return gridOptions; +}; + +/** + * Parse the provided toolbox tree into a consistent DOM format. + * @param {Node|string} tree DOM tree of blocks, or text representation of same. + * @return {Node} DOM tree of blocks, or null. + * @private + */ +Blockly.Options.parseToolboxTree_ = function(tree) { + if (tree) { + if (typeof tree != 'string') { + if (typeof XSLTProcessor == 'undefined' && tree.outerHTML) { + // In this case the tree will not have been properly built by the + // browser. The HTML will be contained in the element, but it will + // not have the proper DOM structure since the browser doesn't support + // XSLTProcessor (XML -> HTML). This is the case in IE 9+. + tree = tree.outerHTML; + } else if (!(tree instanceof Element)) { + tree = null; + } + } + if (typeof tree == 'string') { + tree = Blockly.Xml.textToDom(tree); + } + } else { + tree = null; + } + return tree; +}; From e2f1a6c8431270e1ddd57700ada40ca82fc0b019 Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Tue, 29 Mar 2016 14:26:56 -0700 Subject: [PATCH 02/13] Fix annotations --- core/inject.js | 4 ++-- core/workspace.js | 4 ++-- core/workspace_svg.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/inject.js b/core/inject.js index 75501def7..e105b6b50 100644 --- a/core/inject.js +++ b/core/inject.js @@ -62,7 +62,7 @@ Blockly.inject = function(container, opt_options) { /** * Create the SVG image. * @param {!Element} container Containing element. - * @param {Object} options Dictionary of options. + * @param {!Blockly.Options} options Dictionary of options. * @return {!Element} Newly created SVG image. * @private */ @@ -176,7 +176,7 @@ Blockly.createDom_ = function(container, options) { /** * Create a main workspace and add it to the SVG. * @param {!Element} svg SVG element with pattern defined. - * @param {Object} options Dictionary of options. + * @param {!Blockly.Options} options Dictionary of options. * @return {!Blockly.Workspace} Newly created main workspace. * @private */ diff --git a/core/workspace.js b/core/workspace.js index f8cf8d4bc..7d39f0261 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -32,14 +32,14 @@ goog.require('goog.math'); /** * Class for a workspace. This is a data structure that contains blocks. * There is no UI, and can be created headlessly. - * @param {Object=} opt_options Dictionary of options. + * @param {Blockly.Options} opt_options Dictionary of options. * @constructor */ Blockly.Workspace = function(opt_options) { /** @type {string} */ this.id = Blockly.genUid(); Blockly.Workspace.WorkspaceDB_[this.id] = this; - /** @type {!Object} */ + /** @type {!Blockly.Options} */ this.options = opt_options || {}; /** @type {boolean} */ this.RTL = !!this.options.RTL; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 7d42e6597..aa4261185 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -43,7 +43,7 @@ goog.require('goog.userAgent'); /** * Class for a workspace. This is an onscreen area with optional trashcan, * scrollbars, bubbles, and dragging. - * @param {!Object} options Dictionary of options. + * @param {!Blockly.Options} options Dictionary of options. * @extends {Blockly.Workspace} * @constructor */ From be3c761fc0407a4892f6e44a112baa61543ecf09 Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Tue, 29 Mar 2016 15:22:45 -0700 Subject: [PATCH 03/13] lint --- core/inject.js | 2 +- core/options.js | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/core/inject.js b/core/inject.js index e105b6b50..2e8d93a5d 100644 --- a/core/inject.js +++ b/core/inject.js @@ -26,8 +26,8 @@ goog.provide('Blockly.inject'); -goog.require('Blockly.Options'); goog.require('Blockly.Css'); +goog.require('Blockly.Options'); goog.require('Blockly.WorkspaceSvg'); goog.require('goog.dom'); goog.require('goog.ui.Component'); diff --git a/core/options.js b/core/options.js index 19a848105..83c084511 100644 --- a/core/options.js +++ b/core/options.js @@ -32,8 +32,7 @@ goog.provide('Blockly.Options'); * is unspecified. * @param {!Object} options Dictionary of options. Specification: * https://developers.google.com/blockly/installation/overview#configuration - * @return {!Blockly.Options} Object containing a dicitonary of normalized - * options. + * @constructor */ Blockly.Options = function(options) { var readOnly = !!options['readOnly']; @@ -108,6 +107,10 @@ Blockly.Options = function(options) { this.realtimeOptions = realtimeOptions; }; +/** + * @type {Blockly.Workspace} the parent of the current workspace, or null if + * there is no parent workspace. + **/ Blockly.Options.prototype.parentWorkspace = null; /** @@ -127,7 +130,7 @@ Blockly.Options.prototype.getMetrics = function() { return null; }; * Parse the user-specified zoom options, using reasonable defaults where * behaviour is unspecified. See zoom documentation: * https://developers.google.com/blockly/installation/zoom - * @param {!Object} options Dictionary of options options. + * @param {!Object} options Dictionary of options. * @return {!Object} A dictionary of normalized options. * @private */ From 766506656503c88280e906de53f76d7dca720bb0 Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Tue, 29 Mar 2016 17:30:39 -0700 Subject: [PATCH 04/13] Move Blockly.Block rendered into Blockly.BlockSvg --- core/block.js | 68 ++++--------------- core/block_svg.js | 166 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 55 deletions(-) diff --git a/core/block.js b/core/block.js index 5abefe053..e93de408d 100644 --- a/core/block.js +++ b/core/block.js @@ -66,8 +66,6 @@ Blockly.Block = function(workspace, prototypeName, opt_id) { /** @type {boolean|undefined} */ this.inputsInline = undefined; /** @type {boolean} */ - this.rendered = false; - /** @type {boolean} */ this.disabled = false; /** @type {string|!Function} */ this.tooltip = ''; @@ -246,29 +244,23 @@ Blockly.Block.prototype.unplug = function(opt_healStack) { /** * Returns all connections originating from this block. - * @param {boolean} all If true, return all connections even hidden ones. - * Otherwise return those that are visible. * @return {!Array.} Array of connections. * @private */ -Blockly.Block.prototype.getConnections_ = function(all) { +Blockly.Block.prototype.getConnections_ = function() { var myConnections = []; - if (all || this.rendered) { - if (this.outputConnection) { - myConnections.push(this.outputConnection); - } - if (this.previousConnection) { - myConnections.push(this.previousConnection); - } - if (this.nextConnection) { - myConnections.push(this.nextConnection); - } - if (all || !this.collapsed_) { - for (var i = 0, input; input = this.inputList[i]; i++) { - if (input.connection) { - myConnections.push(input.connection); - } - } + if (this.outputConnection) { + myConnections.push(this.outputConnection); + } + if (this.previousConnection) { + myConnections.push(this.previousConnection); + } + if (this.nextConnection) { + myConnections.push(this.nextConnection); + } + for (var i = 0, input; input = this.inputList[i]; i++) { + if (input.connection) { + myConnections.push(input.connection); } } return myConnections; @@ -613,9 +605,6 @@ Blockly.Block.prototype.setColour = function(colour) { } else { throw 'Invalid colour: ' + colour; } - if (this.rendered) { - this.updateColour(); - } }; /** @@ -736,10 +725,6 @@ Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) { new Blockly.Connection(this, Blockly.PREVIOUS_STATEMENT); this.previousConnection.setCheck(opt_check); } - if (this.rendered) { - this.render(); - this.bumpNeighbours_(); - } }; /** @@ -763,10 +748,6 @@ Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) { new Blockly.Connection(this, Blockly.NEXT_STATEMENT); this.nextConnection.setCheck(opt_check); } - if (this.rendered) { - this.render(); - this.bumpNeighbours_(); - } }; /** @@ -793,10 +774,6 @@ Blockly.Block.prototype.setOutput = function(newBoolean, opt_check) { new Blockly.Connection(this, Blockly.OUTPUT_VALUE); this.outputConnection.setCheck(opt_check); } - if (this.rendered) { - this.render(); - this.bumpNeighbours_(); - } }; /** @@ -808,10 +785,6 @@ Blockly.Block.prototype.setInputsInline = function(newBoolean) { Blockly.Events.fire(new Blockly.Events.Change( this, 'inline', null, this.inputsInline, newBoolean)); this.inputsInline = newBoolean; - if (this.rendered) { - this.render(); - this.bumpNeighbours_(); - } } }; @@ -1149,11 +1122,6 @@ Blockly.Block.prototype.appendInput_ = function(type, name) { var input = new Blockly.Input(type, name, this, connection); // Append input to list. this.inputList.push(input); - if (this.rendered) { - this.render(); - // Adding an input will cause the block to change shape. - this.bumpNeighbours_(); - } return input; }; @@ -1210,11 +1178,6 @@ Blockly.Block.prototype.moveNumberedInputBefore = function( } // Reinsert input. this.inputList.splice(refIndex, 0, input); - if (this.rendered) { - this.render(); - // Moving an input will cause the block to change shape. - this.bumpNeighbours_(); - } }; /** @@ -1240,11 +1203,6 @@ Blockly.Block.prototype.removeInput = function(name, opt_quiet) { } input.dispose(); this.inputList.splice(i, 1); - if (this.rendered) { - this.render(); - // Removing an input will cause the block to change shape. - this.bumpNeighbours_(); - } return; } } diff --git a/core/block_svg.js b/core/block_svg.js index f31bbf035..9069ba2ad 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -61,6 +61,10 @@ Blockly.BlockSvg = function(workspace, prototypeName, opt_id) { this.svgPathLight_ = Blockly.createSvgElement('path', {'class': 'blocklyPathLight'}, this.svgGroup_); this.svgPath_.tooltip = this; + + /** @type {boolean} */ + this.rendered = false; + Blockly.Tooltip.bindMouseEvents(this.svgPath_); Blockly.BlockSvg.superClass_.constructor.call(this, workspace, prototypeName, opt_id); @@ -1402,3 +1406,165 @@ Blockly.BlockSvg.prototype.removeDragging = function() { Blockly.removeClass_(/** @type {!Element} */ (this.svgGroup_), 'blocklyDragging'); }; + +// Overrides of functions on Blockly.Block that take into account whether the +// block has been rendered. + +/** + * Change the colour of a block. + * @param {number|string} colour HSV hue value, or #RRGGBB string. + */ +Blockly.BlockSvg.prototype.setColour = function(colour) { + Blockly.BlockSvg.superClass_.setColour.call(this, colour); + + if (this.rendered) { + this.updateColour(); + } +}; + +/** + * Set whether this block can chain onto the bottom of another block. + * @param {boolean} newBoolean True if there can be a previous statement. + * @param {string|Array.|null|undefined} opt_check Statement type or + * list of statement types. Null/undefined if any type could be connected. + */ +Blockly.BlockSvg.prototype.setPreviousStatement = + function(newBoolean, opt_check) { + Blockly.BlockSvg.superClass_.setPreviousStatement.call(this, newBoolean, + opt_check); + + if (this.rendered) { + this.render(); + this.bumpNeighbours_(); + } +}; + +/** + * Set whether another block can chain onto the bottom of this block. + * @param {boolean} newBoolean True if there can be a next statement. + * @param {string|Array.|null|undefined} opt_check Statement type or + * list of statement types. Null/undefined if any type could be connected. + */ +Blockly.BlockSvg.prototype.setNextStatement = function(newBoolean, opt_check) { + Blockly.BlockSvg.superClass_.setNextStatement.call(this, newBoolean, + opt_check); + + if (this.rendered) { + this.render(); + this.bumpNeighbours_(); + } +}; + +/** + * Set whether this block returns a value. + * @param {boolean} newBoolean True if there is an output. + * @param {string|Array.|null|undefined} opt_check Returned type or list + * of returned types. Null or undefined if any type could be returned + * (e.g. variable get). + */ +Blockly.BlockSvg.prototype.setOutput = function(newBoolean, opt_check) { + Blockly.BlockSvg.superClass_.setOutput.call(this, newBoolean, opt_check); + + if (this.rendered) { + this.render(); + this.bumpNeighbours_(); + } +}; + +/** + * Set whether value inputs are arranged horizontally or vertically. + * @param {boolean} newBoolean True if inputs are horizontal. + */ +Blockly.BlockSvg.prototype.setInputsInline = function(newBoolean) { + Blockly.BlockSvg.superClass_.setInputsInline.call(this, newBoolean); + + if (this.rendered) { + this.render(); + this.bumpNeighbours_(); + } +}; + +/** + * Remove an input from this block. + * @param {string} name The name of the input. + * @param {boolean=} opt_quiet True to prevent error if input is not present. + * @throws {goog.asserts.AssertionError} if the input is not present and + * opt_quiet is not true. + */ +Blockly.BlockSvg.prototype.removeInput = function(name, opt_quiet) { + Blockly.BlockSvg.superClass_.removeInput.call(this, name, opt_quiet); + + if (this.rendered) { + this.render(); + // Removing an input will cause the block to change shape. + this.bumpNeighbours_(); + } +}; + +/** + * Move a numbered input to a different location on this block. + * @param {number} inputIndex Index of the input to move. + * @param {number} refIndex Index of input that should be after the moved input. + */ +Blockly.BlockSvg.prototype.moveNumberedInputBefore = function( + inputIndex, refIndex) { + Blockly.BlockSvg.superClass_.moveNumberedInputBefore.call(this, inputIndex, + refIndex); + + if (this.rendered) { + this.render(); + // Moving an input will cause the block to change shape. + this.bumpNeighbours_(); + } +}; + +/** + * Add a value input, statement input or local variable to this block. + * @param {number} type Either Blockly.INPUT_VALUE or Blockly.NEXT_STATEMENT or + * Blockly.DUMMY_INPUT. + * @param {string} name Language-neutral identifier which may used to find this + * input again. Should be unique to this block. + * @return {!Blockly.Input} The input object created. + * @private + */ +Blockly.BlockSvg.prototype.appendInput_ = function(type, name) { + var input = Blockly.BlockSvg.superClass_.appendInput_.call(this, type, name); + + if (this.rendered) { + this.render(); + // Adding an input will cause the block to change shape. + this.bumpNeighbours_(); + } + return input; +}; + +/** + * Returns connections originating from this block. + * @param {boolean} all If true, return all connections even hidden ones. + * Otherwise, for a non-rendered block return an empty list, and for a + * collapsed block don't return inputs connections. + * @return {!Array.} Array of connections. + * @private + */ +Blockly.BlockSvg.prototype.getConnections_ = function(all) { + var myConnections = []; + if (all || this.rendered) { + if (this.outputConnection) { + myConnections.push(this.outputConnection); + } + if (this.previousConnection) { + myConnections.push(this.previousConnection); + } + if (this.nextConnection) { + myConnections.push(this.nextConnection); + } + if (all || !this.collapsed_) { + for (var i = 0, input; input = this.inputList[i]; i++) { + if (input.connection) { + myConnections.push(input.connection); + } + } + } + } + return myConnections; +}; From ae1a0aab8ac02bd38fb22491633568b39e771c18 Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Wed, 30 Mar 2016 15:09:42 -0700 Subject: [PATCH 05/13] add isConnected() to connections. --- core/block.js | 22 +++++++++++----------- core/block_render_svg.js | 10 +++++----- core/connection.js | 28 ++++++++++++++++++---------- core/mutator.js | 2 +- core/xml.js | 2 +- 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/core/block.js b/core/block.js index 5abefe053..8b0ed2b1f 100644 --- a/core/block.js +++ b/core/block.js @@ -201,7 +201,7 @@ Blockly.Block.prototype.dispose = function(healStack) { var connections = this.getConnections_(true); for (var i = 0; i < connections.length; i++) { var connection = connections[i]; - if (connection.targetConnection) { + if (connection.isConnected()) { connection.disconnect(); } connections[i].dispose(); @@ -219,13 +219,13 @@ Blockly.Block.prototype.dispose = function(healStack) { */ Blockly.Block.prototype.unplug = function(opt_healStack) { if (this.outputConnection) { - if (this.outputConnection.targetConnection) { + if (this.outputConnection.isConnected()) { // Disconnect from any superior block. this.outputConnection.disconnect(); } } else if (this.previousConnection) { var previousTarget = null; - if (this.previousConnection.targetConnection) { + if (this.previousConnection.isConnected()) { // Remember the connection that any next statements need to connect to. previousTarget = this.previousConnection.targetConnection; // Detach this block from the parent's tree. @@ -313,7 +313,7 @@ Blockly.Block.prototype.bumpNeighbours_ = function() { var myConnections = this.getConnections_(false); for (var i = 0, connection; connection = myConnections[i]; i++) { // Spider down from this block bumping all sub-blocks. - if (connection.targetConnection && connection.isSuperior()) { + if (connection.isConnected() && connection.isSuperior()) { connection.targetBlock().bumpNeighbours_(); } @@ -321,7 +321,7 @@ Blockly.Block.prototype.bumpNeighbours_ = function() { for (var j = 0, otherConnection; otherConnection = neighbours[j]; j++) { // If both connections are connected, that's probably fine. But if // either one of them is unconnected, then there could be confusion. - if (!connection.targetConnection || !otherConnection.targetConnection) { + if (!connection.isConnected() || !otherConnection.isConnected()) { // Only bump blocks if they are from different tree structures. if (otherConnection.getSourceBlock().getRootBlock() != rootBlock) { // Always bump the inferior block. @@ -431,10 +431,10 @@ Blockly.Block.prototype.setParent = function(newParent) { } // Disconnect from superior blocks. - if (this.previousConnection && this.previousConnection.targetConnection) { + if (this.previousConnection && this.previousConnection.isConnected()) { throw 'Still connected to previous block.'; } - if (this.outputConnection && this.outputConnection.targetConnection) { + if (this.outputConnection && this.outputConnection.isConnected()) { throw 'Still connected to parent block.'; } this.parentBlock_ = null; @@ -721,7 +721,7 @@ Blockly.Block.prototype.setTitleValue = function(newValue, name) { */ Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) { if (this.previousConnection) { - goog.asserts.assert(!this.previousConnection.targetConnection, + goog.asserts.assert(!this.previousConnection.isConnected(), 'Must disconnect previous statement before removing connection.'); this.previousConnection.dispose(); this.previousConnection = null; @@ -750,7 +750,7 @@ Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) { */ Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) { if (this.nextConnection) { - goog.asserts.assert(!this.nextConnection.targetConnection, + goog.asserts.assert(!this.nextConnection.isConnected(), 'Must disconnect next statement before removing connection.'); this.nextConnection.dispose(); this.nextConnection = null; @@ -778,7 +778,7 @@ Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) { */ Blockly.Block.prototype.setOutput = function(newBoolean, opt_check) { if (this.outputConnection) { - goog.asserts.assert(!this.outputConnection.targetConnection, + goog.asserts.assert(!this.outputConnection.isConnected(), 'Must disconnect output value before removing connection.'); this.outputConnection.dispose(); this.outputConnection = null; @@ -1227,7 +1227,7 @@ Blockly.Block.prototype.moveNumberedInputBefore = function( Blockly.Block.prototype.removeInput = function(name, opt_quiet) { for (var i = 0, input; input = this.inputList[i]; i++) { if (input.name == name) { - if (input.connection && input.connection.targetConnection) { + if (input.connection && input.connection.isConnected()) { input.connection.setShadowDom(null); var block = input.connection.targetBlock(); if (block.isShadow()) { diff --git a/core/block_render_svg.js b/core/block_render_svg.js index c4d503370..92ba5270f 100644 --- a/core/block_render_svg.js +++ b/core/block_render_svg.js @@ -379,7 +379,7 @@ Blockly.BlockSvg.prototype.renderCompute_ = function(iconWidth) { input.renderWidth = 0; } // Expand input size if there is a connection. - if (input.connection && input.connection.targetConnection) { + if (input.connection && input.connection.isConnected()) { var linkedBlock = input.connection.targetBlock(); var bBox = linkedBlock.getHeightWidth(); input.renderHeight = Math.max(input.renderHeight, bBox.height); @@ -692,7 +692,7 @@ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps, connectionY = connectionsXY.y + cursorY + Blockly.BlockSvg.INLINE_PADDING_Y + 1; input.connection.moveTo(connectionX, connectionY); - if (input.connection.targetConnection) { + if (input.connection.isConnected()) { input.connection.tighten_(); } } @@ -740,7 +740,7 @@ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps, (this.RTL ? -inputRows.rightEdge - 1 : inputRows.rightEdge + 1); connectionY = connectionsXY.y + cursorY; input.connection.moveTo(connectionX, connectionY); - if (input.connection.targetConnection) { + if (input.connection.isConnected()) { input.connection.tighten_(); this.width = Math.max(this.width, inputRows.rightEdge + input.connection.targetBlock().getHeightWidth().width - @@ -822,7 +822,7 @@ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps, connectionX = connectionsXY.x + (this.RTL ? -cursorX : cursorX + 1); connectionY = connectionsXY.y + cursorY + 1; input.connection.moveTo(connectionX, connectionY); - if (input.connection.targetConnection) { + if (input.connection.isConnected()) { input.connection.tighten_(); this.width = Math.max(this.width, inputRows.statementEdge + input.connection.targetBlock().getHeightWidth().width); @@ -873,7 +873,7 @@ Blockly.BlockSvg.prototype.renderDrawBottom_ = } var connectionY = connectionsXY.y + cursorY + 1; this.nextConnection.moveTo(connectionX, connectionY); - if (this.nextConnection.targetConnection) { + if (this.nextConnection.isConnected()) { this.nextConnection.tighten_(); } this.height += 4; // Height of tab. diff --git a/core/connection.js b/core/connection.js index 70ce2ba05..beef7699a 100644 --- a/core/connection.js +++ b/core/connection.js @@ -69,10 +69,10 @@ Blockly.Connection.connect_ = function(parentConnection, childConnection) { var parentBlock = parentConnection.getSourceBlock(); var childBlock = childConnection.getSourceBlock(); // Disconnect any existing parent on the child connection. - if (childConnection.targetConnection) { + if (childConnection.isConnected()) { childConnection.disconnect(); } - if (parentConnection.targetConnection) { + if (parentConnection.isConnected()) { // Other connection is already connected to something. // Disconnect it and reattach it or bump it as needed. var orphanBlock = parentConnection.targetBlock(); @@ -111,7 +111,7 @@ Blockly.Connection.connect_ = function(parentConnection, childConnection) { // block. Since this block may be a stack, walk down to the end. var newBlock = childBlock; while (newBlock.nextConnection) { - if (newBlock.nextConnection.targetConnection) { + if (newBlock.nextConnection.isConnected()) { newBlock = newBlock.getNextBlock(); } else { if (orphanBlock.previousConnection.checkType_( @@ -247,7 +247,7 @@ Blockly.Connection.prototype.hidden_ = null; * Sever all links to this connection (not including from the source object). */ Blockly.Connection.prototype.dispose = function() { - if (this.targetConnection) { + if (this.isConnected()) { throw 'Disconnect connection before disposing of it.'; } if (this.inDB_) { @@ -280,6 +280,14 @@ Blockly.Connection.prototype.isSuperior = function() { this.type == Blockly.NEXT_STATEMENT; }; +/** + * Is the connection connected? + * @return {boolean} True if connection is connected to another connection. + */ +Blockly.Connection.prototype.isConnected = function() { + return !!this.targetConnection; +}; + /** * Returns the distance between this connection and another connection. * @param {!Blockly.Connection} otherConnection The other connection to measure @@ -368,7 +376,7 @@ Blockly.Connection.prototype.isConnectionAllowed = function(candidate, // bottom of a statement block to one that's already connected. if (candidate.type == Blockly.OUTPUT_VALUE || candidate.type == Blockly.PREVIOUS_STATEMENT) { - if (candidate.targetConnection || this.targetConnection) { + if (candidate.isConnected() || this.isConnected()) { return false; } } @@ -376,7 +384,7 @@ Blockly.Connection.prototype.isConnectionAllowed = function(candidate, // Offering to connect the left (male) of a value block to an already // connected value pair is ok, we'll splice it in. // However, don't offer to splice into an immovable block. - if (candidate.type == Blockly.INPUT_VALUE && candidate.targetConnection && + if (candidate.type == Blockly.INPUT_VALUE && candidate.isConnected() && !candidate.targetBlock().isMovable() && !candidate.targetBlock().isShadow()) { return false; @@ -385,7 +393,7 @@ Blockly.Connection.prototype.isConnectionAllowed = function(candidate, // Don't let a block with no next connection bump other blocks out of the // stack. if (this.type == Blockly.PREVIOUS_STATEMENT && - candidate.targetConnection && + candidate.isConnected() && !this.sourceBlock_.nextConnection) { return false; } @@ -553,7 +561,7 @@ Blockly.Connection.prototype.disconnect = function() { * @return {Blockly.Block} The connected block or null if none is connected. */ Blockly.Connection.prototype.targetBlock = function() { - if (this.targetConnection) { + if (this.isConnected()) { return this.targetConnection.getSourceBlock(); } return null; @@ -702,7 +710,7 @@ Blockly.Connection.prototype.setCheck = function(check) { } this.check_ = check; // The new value type may not be compatible with the existing connection. - if (this.targetConnection && !this.checkType_(this.targetConnection)) { + if (this.isConnected() && !this.checkType_(this.targetConnection)) { var child = this.isSuperior() ? this.targetBlock() : this.sourceBlock_; child.unplug(); // Bump away. @@ -763,7 +771,7 @@ Blockly.Connection.prototype.setHidden = function(hidden) { */ Blockly.Connection.prototype.hideAll = function() { this.setHidden(true); - if (this.targetConnection) { + if (this.isConnected()) { var blocks = this.targetBlock().getDescendants(); for (var b = 0; b < blocks.length; b++) { var block = blocks[b]; diff --git a/core/mutator.js b/core/mutator.js index 095f957f5..ba7c5c27a 100644 --- a/core/mutator.js +++ b/core/mutator.js @@ -359,7 +359,7 @@ Blockly.Mutator.reconnect = function(connectionChild, block, inputName) { var currentParent = connectionChild.targetBlock(); if ((!currentParent || currentParent == block) && connectionParent.targetConnection != connectionChild) { - if (connectionParent.targetConnection) { + if (connectionParent.isConnected()) { // There's already something connected here. Get rid of it. connectionParent.disconnect(); } diff --git a/core/xml.js b/core/xml.js index e61a22280..3cfe3663c 100644 --- a/core/xml.js +++ b/core/xml.js @@ -465,7 +465,7 @@ Blockly.Xml.domToBlockHeadless_ = function(workspace, xmlBlock) { if (childBlockNode) { if (!block.nextConnection) { throw 'Next statement does not exist.'; - } else if (block.nextConnection.targetConnection) { + } else if (block.nextConnection.isConnected()) { // This could happen if there is more than one XML 'next' tag. throw 'Next statement is already connected.'; } From 39f7e6660e6bf4ab13a06931f25ff0bc0b197b79 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Thu, 31 Mar 2016 02:04:23 -0700 Subject: [PATCH 06/13] Add category UI event. Issue #306. --- core/events.js | 4 ++-- core/toolbox.js | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/core/events.js b/core/events.js index 8e90f6583..7570fb8e9 100644 --- a/core/events.js +++ b/core/events.js @@ -651,8 +651,8 @@ Blockly.Events.Ui.prototype.type = Blockly.Events.UI; * Encode the event as JSON. * @return {!Object} JSON representation. */ -Blockly.Events.Change.prototype.toJson = function() { - var json = Blockly.Events.Change.superClass_.toJson.call(this); +Blockly.Events.Ui.prototype.toJson = function() { + var json = Blockly.Events.Ui.superClass_.toJson.call(this); json['element'] = this.element; if (this.newValue !== undefined) { json['newValue'] = this.newValue; diff --git a/core/toolbox.js b/core/toolbox.js index c8818be1c..3951c107d 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -404,6 +404,7 @@ Blockly.Toolbox.TreeControl.prototype.setSelectedItem = function(node) { // not rendered. toolbox.addColour_(node); } + var oldNode = this.getSelectedItem(); goog.ui.tree.TreeControl.prototype.setSelectedItem.call(this, node); if (node && node.blocks && node.blocks.length) { toolbox.flyout_.show(node.blocks); @@ -415,6 +416,12 @@ Blockly.Toolbox.TreeControl.prototype.setSelectedItem = function(node) { // Hide the flyout. toolbox.flyout_.hide(); } + if (oldNode != node && oldNode != this) { + var event = new Blockly.Events.Ui(null, 'category', + oldNode && oldNode.getHtml(), node && node.getHtml()); + event.workspaceId = toolbox.workspace_.id; + Blockly.Events.fire(event); + } if (node) { toolbox.lastCategory_ = node; } From b7f73d60bb3fc1cb63c517908bdaf9ef01831001 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Thu, 31 Mar 2016 14:19:34 -0700 Subject: [PATCH 07/13] Routine recompile. --- blockly_compressed.js | 107 +++++++++++++++++++++------------------- blockly_uncompressed.js | 4 +- msg/js/ba.js | 22 ++++----- msg/js/he.js | 10 ++-- msg/js/pl.js | 4 +- msg/js/zh-hant.js | 4 +- 6 files changed, 78 insertions(+), 73 deletions(-) diff --git a/blockly_compressed.js b/blockly_compressed.js index 1b94ef1c0..418052233 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -898,28 +898,28 @@ Blockly.Comment.prototype.setVisible=function(a){if(a!=this.isVisible())if(Block this.updateColour()):(this.bubble_.dispose(),this.foreignObject_=this.textarea_=this.bubble_=null);this.setText(b);this.setBubbleSize(c.width,c.height)}};Blockly.Comment.prototype.textareaFocus_=function(a){this.bubble_.promote_();this.textarea_.focus()};Blockly.Comment.prototype.getBubbleSize=function(){return this.isVisible()?this.bubble_.getBubbleSize():{width:this.width_,height:this.height_}}; Blockly.Comment.prototype.setBubbleSize=function(a,b){this.textarea_?this.bubble_.setBubbleSize(a,b):(this.width_=a,this.height_=b)};Blockly.Comment.prototype.getText=function(){return this.textarea_?this.textarea_.value:this.text_};Blockly.Comment.prototype.setText=function(a){this.text_!=a&&(Blockly.Events.fire(new Blockly.Events.Change(this.block_,"comment",null,this.text_,a)),this.text_=a);this.textarea_&&(this.textarea_.value=a)}; Blockly.Comment.prototype.dispose=function(){Blockly.Events.isEnabled()&&this.setText("");this.block_.comment=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Connection=function(a,b){this.sourceBlock_=a;this.type=b;a.workspace.connectionDBList&&(this.db_=a.workspace.connectionDBList[b],this.dbOpposite_=a.workspace.connectionDBList[Blockly.OPPOSITE_TYPE[b]],this.hidden_=!this.db_)};Blockly.Connection.CAN_CONNECT=0;Blockly.Connection.REASON_SELF_CONNECTION=1;Blockly.Connection.REASON_WRONG_TYPE=2;Blockly.Connection.REASON_TARGET_NULL=3;Blockly.Connection.REASON_CHECKS_FAILED=4;Blockly.Connection.REASON_DIFFERENT_WORKSPACES=5; -Blockly.Connection.connect_=function(a,b){var c=a.getSourceBlock(),d=b.getSourceBlock();b.targetConnection&&b.disconnect();if(a.targetConnection){var e=a.targetBlock(),f=a.getShadowDom();a.setShadowDom(null);if(e.isShadow())f=Blockly.Xml.blockToDom(e),e.dispose(),e=null;else if(a.type==Blockly.INPUT_VALUE){if(!e.outputConnection)throw"Orphan block does not have an output connection.";var g=Blockly.Connection.lastConnectionInRow_(d,e);g&&(e.outputConnection.connect(g),e=null)}else if(a.type==Blockly.NEXT_STATEMENT){if(!e.previousConnection)throw"Orphan block does not have a previous connection."; -for(g=d;g.nextConnection;)if(g.nextConnection.targetConnection)g=g.getNextBlock();else{e.previousConnection.checkType_(g.nextConnection)&&(g.nextConnection.connect(e.previousConnection),e=null);break}}if(e&&(a.disconnect(),Blockly.Events.recordUndo)){var h=Blockly.Events.getGroup();setTimeout(function(){e.workspace&&!e.getParent()&&(Blockly.Events.setGroup(h),e.outputConnection?e.outputConnection.bumpAwayFrom_(a):e.previousConnection&&e.previousConnection.bumpAwayFrom_(a),Blockly.Events.setGroup(!1))}, +Blockly.Connection.connect_=function(a,b){var c=a.getSourceBlock(),d=b.getSourceBlock();b.isConnected()&&b.disconnect();if(a.isConnected()){var e=a.targetBlock(),f=a.getShadowDom();a.setShadowDom(null);if(e.isShadow())f=Blockly.Xml.blockToDom(e),e.dispose(),e=null;else if(a.type==Blockly.INPUT_VALUE){if(!e.outputConnection)throw"Orphan block does not have an output connection.";var g=Blockly.Connection.lastConnectionInRow_(d,e);g&&(e.outputConnection.connect(g),e=null)}else if(a.type==Blockly.NEXT_STATEMENT){if(!e.previousConnection)throw"Orphan block does not have a previous connection."; +for(g=d;g.nextConnection;)if(g.nextConnection.isConnected())g=g.getNextBlock();else{e.previousConnection.checkType_(g.nextConnection)&&(g.nextConnection.connect(e.previousConnection),e=null);break}}if(e&&(a.disconnect(),Blockly.Events.recordUndo)){var h=Blockly.Events.getGroup();setTimeout(function(){e.workspace&&!e.getParent()&&(Blockly.Events.setGroup(h),e.outputConnection?e.outputConnection.bumpAwayFrom_(a):e.previousConnection&&e.previousConnection.bumpAwayFrom_(a),Blockly.Events.setGroup(!1))}, Blockly.BUMP_DELAY)}a.setShadowDom(f)}var k;Blockly.Events.isEnabled()&&(k=new Blockly.Events.Move(d));Blockly.Connection.connectReciprocally_(a,b);d.setParent(c);k&&(k.recordNew(),Blockly.Events.fire(k));c.rendered&&c.updateDisabled();d.rendered&&d.updateDisabled();c.rendered&&d.rendered&&(a.type==Blockly.NEXT_STATEMENT||a.type==Blockly.PREVIOUS_STATEMENT?d.render():c.render())};Blockly.Connection.prototype.targetConnection=null;Blockly.Connection.prototype.check_=null; Blockly.Connection.prototype.shadowDom_=null;Blockly.Connection.prototype.x_=0;Blockly.Connection.prototype.y_=0;Blockly.Connection.prototype.inDB_=!1;Blockly.Connection.prototype.db_=null;Blockly.Connection.prototype.dbOpposite_=null;Blockly.Connection.prototype.hidden_=null; -Blockly.Connection.prototype.dispose=function(){if(this.targetConnection)throw"Disconnect connection before disposing of it.";this.inDB_&&this.db_.removeConnection_(this);Blockly.highlightedConnection_==this&&(Blockly.highlightedConnection_=null);Blockly.localConnection_==this&&(Blockly.localConnection_=null);this.dbOpposite_=this.db_=null};Blockly.Connection.prototype.getSourceBlock=function(){return this.sourceBlock_}; -Blockly.Connection.prototype.isSuperior=function(){return this.type==Blockly.INPUT_VALUE||this.type==Blockly.NEXT_STATEMENT};Blockly.Connection.prototype.distanceFrom=function(a){var b=this.x_-a.x_;a=this.y_-a.y_;return Math.sqrt(b*b+a*a)}; +Blockly.Connection.prototype.dispose=function(){if(this.isConnected())throw"Disconnect connection before disposing of it.";this.inDB_&&this.db_.removeConnection_(this);Blockly.highlightedConnection_==this&&(Blockly.highlightedConnection_=null);Blockly.localConnection_==this&&(Blockly.localConnection_=null);this.dbOpposite_=this.db_=null};Blockly.Connection.prototype.getSourceBlock=function(){return this.sourceBlock_}; +Blockly.Connection.prototype.isSuperior=function(){return this.type==Blockly.INPUT_VALUE||this.type==Blockly.NEXT_STATEMENT};Blockly.Connection.prototype.isConnected=function(){return!!this.targetConnection};Blockly.Connection.prototype.distanceFrom=function(a){var b=this.x_-a.x_;a=this.y_-a.y_;return Math.sqrt(b*b+a*a)}; Blockly.Connection.prototype.canConnectWithReason_=function(a){if(a){if(this.sourceBlock_&&a.getSourceBlock()==this.sourceBlock_)return Blockly.Connection.REASON_SELF_CONNECTION;if(a.type!=Blockly.OPPOSITE_TYPE[this.type])return Blockly.Connection.REASON_WRONG_TYPE;if(this.sourceBlock_&&a.getSourceBlock()&&this.sourceBlock_.workspace!==a.getSourceBlock().workspace)return Blockly.Connection.REASON_DIFFERENT_WORKSPACES;if(!this.checkType_(a))return Blockly.Connection.REASON_CHECKS_FAILED}else return Blockly.Connection.REASON_TARGET_NULL; return Blockly.Connection.CAN_CONNECT}; Blockly.Connection.prototype.checkConnection_=function(a){switch(this.canConnectWithReason_(a)){case Blockly.Connection.CAN_CONNECT:break;case Blockly.Connection.REASON_SELF_CONNECTION:throw"Attempted to connect a block to itself.";case Blockly.Connection.REASON_DIFFERENT_WORKSPACES:throw"Blocks not on same workspace.";case Blockly.Connection.REASON_WRONG_TYPE:throw"Attempt to connect incompatible types.";case Blockly.Connection.REASON_TARGET_NULL:throw"Target connection is null.";case Blockly.Connection.REASON_CHECKS_FAILED:throw"Connection checks failed."; default:throw"Unknown connection failure: this should never happen!";}}; -Blockly.Connection.prototype.isConnectionAllowed=function(a,b){if(this.distanceFrom(a)>b)return!1;var c=this.canConnectWithReason_(a);if(c!=Blockly.Connection.CAN_CONNECT&&c!=Blockly.Connection.REASON_MUST_DISCONNECT)return!1;if(a.type==Blockly.OUTPUT_VALUE||a.type==Blockly.PREVIOUS_STATEMENT)if(a.targetConnection||this.targetConnection)return!1;if(a.type==Blockly.INPUT_VALUE&&a.targetConnection&&!a.targetBlock().isMovable()&&!a.targetBlock().isShadow()||this.type==Blockly.PREVIOUS_STATEMENT&&a.targetConnection&& +Blockly.Connection.prototype.isConnectionAllowed=function(a,b){if(this.distanceFrom(a)>b)return!1;var c=this.canConnectWithReason_(a);if(c!=Blockly.Connection.CAN_CONNECT&&c!=Blockly.Connection.REASON_MUST_DISCONNECT)return!1;if(a.type==Blockly.OUTPUT_VALUE||a.type==Blockly.PREVIOUS_STATEMENT)if(a.isConnected()||this.isConnected())return!1;if(a.type==Blockly.INPUT_VALUE&&a.isConnected()&&!a.targetBlock().isMovable()&&!a.targetBlock().isShadow()||this.type==Blockly.PREVIOUS_STATEMENT&&a.isConnected()&& !this.sourceBlock_.nextConnection)return!1;var c=a.getSourceBlock(),d=this.sourceBlock_;if(c&&d){do{if(d==c)return!1;c=c.getParent()}while(c)}return!0};Blockly.Connection.prototype.connect=function(a){this.targetConnection!=a&&(this.checkConnection_(a),this.isSuperior()?Blockly.Connection.connect_(this,a):Blockly.Connection.connect_(a,this))};Blockly.Connection.connectReciprocally_=function(a,b){goog.asserts.assert(a&&b,"Cannot connect null connections.");a.targetConnection=b;b.targetConnection=a}; Blockly.Connection.singleConnection_=function(a,b){for(var c=!1,d=0;dd.y+e.height&&c.moveBy(0,20-e.height-d.y)}if(this.rootBlock_.workspace==this.workspace_){Blockly.Events.setGroup(!0);c=this.block_;a=(a=c.mutationToDom())&&Blockly.Xml.domToText(a);b=c.rendered;c.rendered=!1;c.compose(this.rootBlock_);c.rendered=b;c.initSvg();b=(b=c.mutationToDom())&&Blockly.Xml.domToText(b); if(a!=b){Blockly.Events.fire(new Blockly.Events.Change(c,"mutation",null,a,b));var f=Blockly.Events.getGroup();setTimeout(function(){Blockly.Events.setGroup(f);c.bumpNeighbours_();Blockly.Events.setGroup(!1)},Blockly.BUMP_DELAY)}c.rendered&&c.render();this.resizeBubble_();Blockly.Events.setGroup(!1)}};Blockly.Mutator.prototype.getFlyoutMetrics_=function(){return{viewHeight:this.workspaceHeight_,viewWidth:this.workspaceWidth_,absoluteTop:0,absoluteLeft:0}}; -Blockly.Mutator.prototype.dispose=function(){this.block_.mutator=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Mutator.reconnect=function(a,b,c){if(!a||!a.getSourceBlock().workspace)return!1;c=b.getInput(c).connection;var d=a.targetBlock();return d&&d!=b||c.targetConnection==a?!1:(c.targetConnection&&c.disconnect(),c.connect(a),!0)};goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.Mutator||(goog.global.Blockly.Mutator={});goog.global.Blockly.Mutator.reconnect=Blockly.Mutator.reconnect;Blockly.Warning=function(a){Blockly.Warning.superClass_.constructor.call(this,a);this.createIcon();this.text_={}};goog.inherits(Blockly.Warning,Blockly.Icon);Blockly.Warning.prototype.collapseHidden=!1; +Blockly.Mutator.prototype.dispose=function(){this.block_.mutator=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Mutator.reconnect=function(a,b,c){if(!a||!a.getSourceBlock().workspace)return!1;c=b.getInput(c).connection;var d=a.targetBlock();return d&&d!=b||c.targetConnection==a?!1:(c.isConnected()&&c.disconnect(),c.connect(a),!0)};goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.Mutator||(goog.global.Blockly.Mutator={});goog.global.Blockly.Mutator.reconnect=Blockly.Mutator.reconnect;Blockly.Warning=function(a){Blockly.Warning.superClass_.constructor.call(this,a);this.createIcon();this.text_={}};goog.inherits(Blockly.Warning,Blockly.Icon);Blockly.Warning.prototype.collapseHidden=!1; Blockly.Warning.prototype.drawIcon_=function(a){Blockly.createSvgElement("path",{"class":"blocklyIconShape",d:"M2,15Q-1,15 0.5,12L6.5,1.7Q8,-1 9.5,1.7L15.5,12Q17,15 14,15z"},a);Blockly.createSvgElement("path",{"class":"blocklyIconSymbol",d:"m7,4.8v3.16l0.27,2.27h1.46l0.27,-2.27v-3.16z"},a);Blockly.createSvgElement("rect",{"class":"blocklyIconSymbol",x:"7",y:"11",height:"2",width:"2"},a)}; Blockly.Warning.textToDom_=function(a){var b=Blockly.createSvgElement("text",{"class":"blocklyText blocklyBubbleText",y:Blockly.Bubble.BORDER_WIDTH},null);a=a.split("\n");for(var c=0;c=b.height&&(k-=g.height);c?g.width>=a.clientX&&(e+=g.width):a.clientX+g.width>=b.width&&(e-=g.width);Blockly.WidgetDiv.position(e,k,b,f,c);d.setAllowAutoFocus(!0);setTimeout(function(){h.focus()},1);Blockly.ContextMenu.currentBlock=null}else Blockly.ContextMenu.hide()}; Blockly.ContextMenu.hide=function(){Blockly.WidgetDiv.hideIfOwner(Blockly.ContextMenu);Blockly.ContextMenu.currentBlock=null}; -Blockly.ContextMenu.callbackFactory=function(a,b){return function(){Blockly.Events.disable();var c=Blockly.Xml.domToBlock(a.workspace,b),d=a.getRelativeToSurfaceXY();d.x=a.RTL?d.x-Blockly.SNAP_RADIUS:d.x+Blockly.SNAP_RADIUS;d.y+=2*Blockly.SNAP_RADIUS;c.moveBy(d.x,d.y);Blockly.Events.enable();Blockly.Events.isEnabled()&&!c.isShadow()&&Blockly.Events.fire(new Blockly.Events.Create(c));c.select()}};Blockly.BlockSvg=function(a,b,c){this.svgGroup_=Blockly.createSvgElement("g",{},null);this.svgPathDark_=Blockly.createSvgElement("path",{"class":"blocklyPathDark",transform:"translate(1,1)"},this.svgGroup_);this.svgPath_=Blockly.createSvgElement("path",{"class":"blocklyPath"},this.svgGroup_);this.svgPathLight_=Blockly.createSvgElement("path",{"class":"blocklyPathLight"},this.svgGroup_);this.svgPath_.tooltip=this;Blockly.Tooltip.bindMouseEvents(this.svgPath_);Blockly.BlockSvg.superClass_.constructor.call(this, +Blockly.ContextMenu.callbackFactory=function(a,b){return function(){Blockly.Events.disable();var c=Blockly.Xml.domToBlock(a.workspace,b),d=a.getRelativeToSurfaceXY();d.x=a.RTL?d.x-Blockly.SNAP_RADIUS:d.x+Blockly.SNAP_RADIUS;d.y+=2*Blockly.SNAP_RADIUS;c.moveBy(d.x,d.y);Blockly.Events.enable();Blockly.Events.isEnabled()&&!c.isShadow()&&Blockly.Events.fire(new Blockly.Events.Create(c));c.select()}};Blockly.BlockSvg=function(a,b,c){this.svgGroup_=Blockly.createSvgElement("g",{},null);this.svgPathDark_=Blockly.createSvgElement("path",{"class":"blocklyPathDark",transform:"translate(1,1)"},this.svgGroup_);this.svgPath_=Blockly.createSvgElement("path",{"class":"blocklyPath"},this.svgGroup_);this.svgPathLight_=Blockly.createSvgElement("path",{"class":"blocklyPathLight"},this.svgGroup_);this.svgPath_.tooltip=this;this.rendered=!1;Blockly.Tooltip.bindMouseEvents(this.svgPath_);Blockly.BlockSvg.superClass_.constructor.call(this, a,b,c)};goog.inherits(Blockly.BlockSvg,Blockly.Block);Blockly.BlockSvg.prototype.height=0;Blockly.BlockSvg.prototype.width=0;Blockly.BlockSvg.prototype.dragStartXY_=null;Blockly.BlockSvg.INLINE=-1; Blockly.BlockSvg.prototype.initSvg=function(){goog.asserts.assert(this.workspace.rendered,"Workspace is headless.");for(var a=0,b;b=this.inputList[a];a++)b.init();b=this.getIcons();for(a=0;a>>/g,Blockly.Css.mediaPath_),d=document.createElement("style");document.head.appendChild(d);c=document.createTextNode(c);d.appendChild(c);Blockly.Css.styleSheet_=d.sheet;Blockly.Css.setCursor(Blockly.Css.Cursor.OPEN)}}; Blockly.Css.setCursor=function(a){if(Blockly.Css.currentCursor_!=a){Blockly.Css.currentCursor_=a;var b="url("+Blockly.Css.mediaPath_+"/"+a+".cur), auto",c=".blocklyDraggable {\n cursor: "+b+";\n}\n";Blockly.Css.styleSheet_.deleteRule(0);Blockly.Css.styleSheet_.insertRule(c,0);for(var c=document.getElementsByClassName("blocklyToolboxDiv"),d=0,e;e=c[d];d++)e.style.cursor=a==Blockly.Css.Cursor.DELETE?b:"";document.body.parentNode.style.cursor=a==Blockly.Css.Cursor.OPEN?"":b}}; Blockly.Css.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;","overflow: hidden;","}",".blocklyWidgetDiv {","display: none;","position: absolute;","z-index: 999;","}",".blocklyNonSelectable {","user-select: none;","-moz-user-select: none;","-webkit-user-select: none;","-ms-user-select: none;","}",".blocklyTooltipDiv {","background-color: #ffffc7;","border: 1px solid #ddc;","box-shadow: 4px 4px 20px 1px rgba(0,0,0,.15);","color: #000;","display: none;","font-family: sans-serif;", @@ -1331,11 +1333,11 @@ Blockly.Css.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;", Blockly.WidgetDiv.show=function(a,b,c){Blockly.WidgetDiv.hide();Blockly.WidgetDiv.owner_=a;Blockly.WidgetDiv.dispose_=c;a=goog.style.getViewportPageOffset(document);Blockly.WidgetDiv.DIV.style.top=a.y+"px";Blockly.WidgetDiv.DIV.style.direction=b?"rtl":"ltr";Blockly.WidgetDiv.DIV.style.display="block";Blockly.Events.setGroup(!0)}; Blockly.WidgetDiv.hide=function(){Blockly.WidgetDiv.owner_&&(Blockly.WidgetDiv.owner_=null,Blockly.WidgetDiv.DIV.style.display="none",Blockly.WidgetDiv.DIV.style.left="",Blockly.WidgetDiv.DIV.style.top="",Blockly.WidgetDiv.DIV.style.height="",Blockly.WidgetDiv.dispose_&&Blockly.WidgetDiv.dispose_(),Blockly.WidgetDiv.dispose_=null,goog.dom.removeChildren(Blockly.WidgetDiv.DIV),Blockly.Events.setGroup(!1))};Blockly.WidgetDiv.isVisible=function(){return!!Blockly.WidgetDiv.owner_}; Blockly.WidgetDiv.hideIfOwner=function(a){Blockly.WidgetDiv.owner_==a&&Blockly.WidgetDiv.hide()};Blockly.WidgetDiv.position=function(a,b,c,d,e){bc.width+d.x&&(a=c.width+d.x):aa.viewHeight+f||a.contentLeft<(b.RTL?a.viewLeft:e)||a.contentLeft+a.contentWidth>(b.RTL?a.viewWidth:a.viewWidth+e))for(var g=c.getTopBlocks(!1),h=0,k;k=g[h];h++){var l=k.getRelativeToSurfaceXY(),q=k.getHeightWidth(),m=f+25-q.height-l.y;0m&&k.moveBy(0,m);m=25+e-l.x-(b.RTL?0:q.width);0m&&k.moveBy(m,0)}}});Blockly.svgResize(c);Blockly.WidgetDiv.createDom();Blockly.Tooltip.createDom(); return c}; -Blockly.init_=function(a){var b=a.options,c=a.getParentSvg();Blockly.bindEvent_(c,"contextmenu",null,function(a){Blockly.isTargetInput_(a)||a.preventDefault()});Blockly.bindEvent_(window,"resize",null,function(){Blockly.svgResize(a)});Blockly.documentEventsBound_||(Blockly.bindEvent_(document,"keydown",null,Blockly.onKeyDown_),Blockly.bindEvent_(document,"touchend",null,Blockly.longStop_),Blockly.bindEvent_(document,"touchcancel",null,Blockly.longStop_),document.addEventListener("mouseup",Blockly.onMouseUp_, -!1),goog.userAgent.IPAD&&Blockly.bindEvent_(window,"orientationchange",document,function(){Blockly.fireUiEvent(window,"resize")}),Blockly.documentEventsBound_=!0);b.languageTree&&(a.toolbox_?a.toolbox_.init(a):a.flyout_&&(a.flyout_.init(a),a.flyout_.show(b.languageTree.childNodes),a.scrollX=a.flyout_.width_,b.RTL&&(a.scrollX*=-1),a.translate(a.scrollX,0)));b.hasScrollbars&&(a.scrollbar=new Blockly.ScrollbarPair(a),a.scrollbar.resize());if(b.hasSounds){a.loadAudio_([b.pathToMedia+"click.mp3",b.pathToMedia+ -"click.wav",b.pathToMedia+"click.ogg"],"click");a.loadAudio_([b.pathToMedia+"disconnect.wav",b.pathToMedia+"disconnect.mp3",b.pathToMedia+"disconnect.ogg"],"disconnect");a.loadAudio_([b.pathToMedia+"delete.mp3",b.pathToMedia+"delete.ogg",b.pathToMedia+"delete.wav"],"delete");var d=[],b=function(){for(;d.length;)Blockly.unbindEvent_(d.pop());a.preloadAudio_()};d.push(Blockly.bindEvent_(document,"mousemove",null,b));d.push(Blockly.bindEvent_(document,"touchstart",null,b))}}; +Blockly.init_=function(a){var b=a.options,c=a.getParentSvg();Blockly.bindEvent_(c,"contextmenu",null,function(a){Blockly.isTargetInput_(a)||a.preventDefault()});Blockly.bindEvent_(window,"resize",null,function(){Blockly.svgResize(a)});Blockly.inject.bindDocumentEvents_();b.languageTree&&(a.toolbox_?a.toolbox_.init(a):a.flyout_&&(a.flyout_.init(a),a.flyout_.show(b.languageTree.childNodes),a.scrollX=a.flyout_.width_,b.RTL&&(a.scrollX*=-1),a.translate(a.scrollX,0)));b.hasScrollbars&&(a.scrollbar=new Blockly.ScrollbarPair(a), +a.scrollbar.resize());b.hasSounds&&Blockly.inject.loadSounds_(b.pathToMedia,a)}; +Blockly.inject.bindDocumentEvents_=function(){Blockly.documentEventsBound_||(Blockly.bindEvent_(document,"keydown",null,Blockly.onKeyDown_),Blockly.bindEvent_(document,"touchend",null,Blockly.longStop_),Blockly.bindEvent_(document,"touchcancel",null,Blockly.longStop_),document.addEventListener("mouseup",Blockly.onMouseUp_,!1),goog.userAgent.IPAD&&Blockly.bindEvent_(window,"orientationchange",document,function(){Blockly.fireUiEvent(window,"resize")}));Blockly.documentEventsBound_=!0}; +Blockly.inject.loadSounds_=function(a,b){b.loadAudio_([a+"click.mp3",a+"click.wav",a+"click.ogg"],"click");b.loadAudio_([a+"disconnect.wav",a+"disconnect.mp3",a+"disconnect.ogg"],"disconnect");b.loadAudio_([a+"delete.mp3",a+"delete.ogg",a+"delete.wav"],"delete");var c=[],d=function(){for(;c.length;)Blockly.unbindEvent_(c.pop());b.preloadAudio_()};c.push(Blockly.bindEvent_(document,"mousemove",null,d));c.push(Blockly.bindEvent_(document,"touchstart",null,d))}; Blockly.updateToolbox=function(a){console.warn("Deprecated call to Blockly.updateToolbox, use workspace.updateToolbox instead.");Blockly.getMainWorkspace().updateToolbox(a)};Blockly.utils={};Blockly.addClass_=function(a,b){var c=a.getAttribute("class")||"";-1==(" "+c+" ").indexOf(" "+b+" ")&&(c&&(c+=" "),a.setAttribute("class",c+b))};Blockly.removeClass_=function(a,b){var c=a.getAttribute("class");if(-1!=(" "+c+" ").indexOf(" "+b+" ")){for(var c=c.split(/\s+/),d=0;d Date: Sat, 2 Apr 2016 04:52:24 -0700 Subject: [PATCH 08/13] Fix issue #309, unneeded names for dummy inputs in Block Factory. --- demos/blockfactory/blocks.js | 125 +++++++++++++++++------------------ 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/demos/blockfactory/blocks.js b/demos/blockfactory/blocks.js index 5a9752625..c6c142395 100644 --- a/demos/blockfactory/blocks.js +++ b/demos/blockfactory/blocks.js @@ -196,17 +196,7 @@ Blockly.Blocks['input_dummy'] = { // Dummy input. init: function() { this.jsonInit({ - "message0": "dummy input %1 %2", - "args0": [ - { - "type": "field_input", - "name": "INPUTNAME", - "text": "NAME" - }, - { - "type": "input_dummy" - }, - ], + "message0": "dummy input", "message1": FIELD_MESSAGE, "args1": FIELD_ARGS, "previousStatement": "Input", @@ -599,27 +589,30 @@ Blockly.Blocks['type_group'] = { Blockly.Blocks['type_group_container'] = { // Container. init: function() { - this.setColour(230); - this.appendDummyInput() - .appendField('add types'); - this.appendStatementInput('STACK'); - this.setTooltip('Add, or remove allowed type.'); - this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677'); - this.contextMenu = false; + this.jsonInit({ + "message0": "add types %1 %2", + "args0": [ + {"type": "input_dummy"}, + {"type": "input_statement", "name": "STACK"} + ], + "colour": 230, + "tooltip": "Add, or remove allowed type.", + "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677" + }); } }; Blockly.Blocks['type_group_item'] = { // Add type. init: function() { - this.setColour(230); - this.appendDummyInput() - .appendField('type'); - this.setPreviousStatement(true); - this.setNextStatement(true); - this.setTooltip('Add a new allowed type.'); - this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677'); - this.contextMenu = false; + this.jsonInit({ + "message0": "type", + "previousStatement": null, + "nextStatement": null, + "colour": 230, + "tooltip": "Add a new allowed type.", + "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677" + }); } }; @@ -627,12 +620,13 @@ Blockly.Blocks['type_null'] = { // Null type. valueType: null, init: function() { - this.setColour(230); - this.appendDummyInput() - .appendField('any'); - this.setOutput(true, 'Type'); - this.setTooltip('Any type is allowed.'); - this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602'); + this.jsonInit({ + "message0": "any", + "output": "Type", + "colour": 230, + "tooltip": "Any type is allowed.", + "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602" + }); } }; @@ -640,12 +634,13 @@ Blockly.Blocks['type_boolean'] = { // Boolean type. valueType: 'Boolean', init: function() { - this.setColour(230); - this.appendDummyInput() - .appendField('Boolean'); - this.setOutput(true, 'Type'); - this.setTooltip('Booleans (true/false) are allowed.'); - this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602'); + this.jsonInit({ + "message0": "Boolean", + "output": "Type", + "colour": 230, + "tooltip": "Booleans (true/false) are allowed.", + "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602" + }); } }; @@ -653,12 +648,13 @@ Blockly.Blocks['type_number'] = { // Number type. valueType: 'Number', init: function() { - this.setColour(230); - this.appendDummyInput() - .appendField('Number'); - this.setOutput(true, 'Type'); - this.setTooltip('Numbers (int/float) are allowed.'); - this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602'); + this.jsonInit({ + "message0": "Number", + "output": "Type", + "colour": 230, + "tooltip": "Numbers (int/float) are allowed.", + "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602" + }); } }; @@ -666,12 +662,13 @@ Blockly.Blocks['type_string'] = { // String type. valueType: 'String', init: function() { - this.setColour(230); - this.appendDummyInput() - .appendField('String'); - this.setOutput(true, 'Type'); - this.setTooltip('Strings (text) are allowed.'); - this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602'); + this.jsonInit({ + "message0": "String", + "output": "Type", + "colour": 230, + "tooltip": "Strings (text) are allowed.", + "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602" + }); } }; @@ -679,25 +676,27 @@ Blockly.Blocks['type_list'] = { // List type. valueType: 'Array', init: function() { - this.setColour(230); - this.appendDummyInput() - .appendField('Array'); - this.setOutput(true, 'Type'); - this.setTooltip('Arrays (lists) are allowed.'); - this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602'); + this.jsonInit({ + "message0": "Array", + "output": "Type", + "colour": 230, + "tooltip": "Arrays (lists) are allowed.", + "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602" + }); } }; Blockly.Blocks['type_other'] = { // Other type. init: function() { - this.setColour(230); - this.appendDummyInput() - .appendField('other') - .appendField(new Blockly.FieldTextInput(''), 'TYPE'); - this.setOutput(true, 'Type'); - this.setTooltip('Custom type to allow.'); - this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=702'); + this.jsonInit({ + "message0": "other %1", + "args0": [{"type": "field_input", "name": "TYPE", "text": ""}], + "output": "Type", + "colour": 230, + "tooltip": "Custom type to allow.", + "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=702" + }); } }; From 2ce0a25f926105ffcc881bea3e3e40f1553481eb Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Sat, 2 Apr 2016 04:53:04 -0700 Subject: [PATCH 09/13] Fix error thrown when disconnecting blocks that have never been dragged. --- core/block_svg.js | 2 ++ core/connection.js | 1 + 2 files changed, 3 insertions(+) diff --git a/core/block_svg.js b/core/block_svg.js index 9069ba2ad..6db02bc8c 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -828,6 +828,8 @@ Blockly.BlockSvg.prototype.onMouseMove_ = function(e) { if (this.parentBlock_) { // Push this block to the very top of the stack. this.unplug(); + var group = this.getSvgRoot(); + group.translate_ = 'translate(' + newXY.x + ',' + newXY.y + ')'; this.disconnectUiEffect(); } this.setDragging_(true); diff --git a/core/connection.js b/core/connection.js index beef7699a..434061be0 100644 --- a/core/connection.js +++ b/core/connection.js @@ -64,6 +64,7 @@ Blockly.Connection.REASON_DIFFERENT_WORKSPACES = 5; * Connect two connections together. * @param {!Blockly.Connection} parentConnection Connection on superior block. * @param {!Blockly.Connection} childConnection Connection on inferior block. + * @private */ Blockly.Connection.connect_ = function(parentConnection, childConnection) { var parentBlock = parentConnection.getSourceBlock(); From 960b07daab34abc72d47c1150e222a395d60a728 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Sun, 3 Apr 2016 15:45:19 -0700 Subject: [PATCH 10/13] Fix grouping of disconnect and delete. --- core/block_svg.js | 2 ++ core/blockly.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/core/block_svg.js b/core/block_svg.js index 6db02bc8c..0faa7c2cb 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -726,7 +726,9 @@ Blockly.BlockSvg.prototype.showContextMenu_ = function(e) { Blockly.Msg.DELETE_X_BLOCKS.replace('%1', String(descendantCount)), enabled: true, callback: function() { + Blockly.Events.setGroup(true); block.dispose(true, true); + Blockly.Events.setGroup(false); } }; menuOptions.push(deleteOption); diff --git a/core/blockly.js b/core/blockly.js index 608909d90..85d311e6d 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -268,6 +268,7 @@ Blockly.onKeyDown_ = function(e) { } if (deleteBlock) { // Common code for delete and cut. + Blockly.Events.setGroup(true); Blockly.hideChaff(); var heal = Blockly.dragMode_ != Blockly.DRAG_FREE; Blockly.selected.dispose(heal, true); @@ -275,6 +276,7 @@ Blockly.onKeyDown_ = function(e) { Blockly.highlightedConnection_.unhighlight(); Blockly.highlightedConnection_ = null; } + Blockly.Events.setGroup(false); } }; From f527c20c90e7e9a2d06c537d4bd987e86bd95522 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Sun, 3 Apr 2016 15:45:38 -0700 Subject: [PATCH 11/13] Add missing Klingon messages. --- msg/js/tlh.js | 18 +++++++++--------- msg/json/tlh.json | 9 +++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/msg/js/tlh.js b/msg/js/tlh.js index a996d2a6d..ab934dda9 100644 --- a/msg/js/tlh.js +++ b/msg/js/tlh.js @@ -10,7 +10,7 @@ Blockly.Msg.ADD_COMMENT = "QInHom chel"; Blockly.Msg.AUTH = "ngogh nablIj DapollaHmeH qoj latlhvaD DangeHlaHmeH chaw' yInob."; Blockly.Msg.CHANGE_VALUE_TITLE = "choH:"; Blockly.Msg.CHAT = "beqpu'lI'vaD bIjawmeH naDev yIrI'!"; -Blockly.Msg.CLEAN_UP = "Clean up Blocks"; // untranslated +Blockly.Msg.CLEAN_UP = "ngoghmey Say'"; Blockly.Msg.COLLAPSE_ALL = "ngoghmey DejmoH"; Blockly.Msg.COLLAPSE_BLOCK = "ngogh DejmoH"; Blockly.Msg.COLOUR_BLEND_COLOUR1 = "rItlh wa'"; @@ -144,11 +144,11 @@ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM_START = "Sets the item at the speci Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST = "Sets the last item in a list."; // untranslated Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM = "Sets a random item in a list."; // untranslated Blockly.Msg.LISTS_SPLIT_HELPURL = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists"; // untranslated -Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT = "make list from text"; // untranslated -Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST = "make text from list"; // untranslated +Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT = "make list from text"; +Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST = "make text from list"; Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN = "Join a list of texts into one text, separated by a delimiter."; // untranslated Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT = "Split text into a list of texts, breaking at each delimiter."; // untranslated -Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER = "with delimiter"; // untranslated +Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER = "with delimiter"; Blockly.Msg.LOGIC_BOOLEAN_FALSE = "teHbe'"; Blockly.Msg.LOGIC_BOOLEAN_HELPURL = "https://github.com/google/blockly/wiki/Logic#values"; // untranslated Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP = "Returns either true or false."; // untranslated @@ -263,7 +263,7 @@ Blockly.Msg.ME = "Me"; // untranslated Blockly.Msg.NEW_VARIABLE = "lIw chu'..."; Blockly.Msg.NEW_VARIABLE_TITLE = "lIw chu' pong:"; Blockly.Msg.ORDINAL_NUMBER_SUFFIX = ""; -Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS = "allow statements"; // untranslated +Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS = "mu'tlhegh chaw'"; Blockly.Msg.PROCEDURES_BEFORE_PARAMS = "qel:"; Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29"; // untranslated Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP = "Run the user-defined function '%1'."; // untranslated @@ -271,7 +271,7 @@ Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL = "https://en.wikipedia.org/wiki/Proce Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP = "Run the user-defined function '%1' and use its output."; // untranslated Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS = "qel:"; Blockly.Msg.PROCEDURES_CREATE_DO = "chel '%1'"; -Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT = "Describe this function..."; // untranslated +Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT = "mIwQInHom yIchel..."; Blockly.Msg.PROCEDURES_DEFNORETURN_DO = ""; Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29"; // untranslated Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE = "mIw"; @@ -289,7 +289,7 @@ Blockly.Msg.PROCEDURES_MUTATORARG_TITLE = "pong:"; Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP = "Add an input to the function."; // untranslated Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE = "qelwI'mey"; Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP = "Add, remove, or reorder inputs to this function."; // untranslated -Blockly.Msg.REDO = "Redo"; // untranslated +Blockly.Msg.REDO = "wumqa'"; Blockly.Msg.REMOVE_COMMENT = "QInHom chelHa'"; Blockly.Msg.RENAME_VARIABLE = "lIw pong choH..."; Blockly.Msg.RENAME_VARIABLE_TITLE = "Hoch \"%1\" lIwmey pongmey choH:"; @@ -354,8 +354,8 @@ Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH = "poSnIHlogh pei"; Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT = "poSlogh pei"; Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT = "nIHlogh pei"; Blockly.Msg.TEXT_TRIM_TOOLTIP = "Return a copy of the text with spaces removed from one or both ends."; // untranslated -Blockly.Msg.TODAY = "Today"; // untranslated -Blockly.Msg.UNDO = "Undo"; // untranslated +Blockly.Msg.TODAY = "jajvam"; +Blockly.Msg.UNDO = "wumHa'"; Blockly.Msg.VARIABLES_DEFAULT_NAME = "Doch"; Blockly.Msg.VARIABLES_GET_CREATE_SET = "chel 'choH %1'"; Blockly.Msg.VARIABLES_GET_HELPURL = "https://github.com/google/blockly/wiki/Variables#get"; // untranslated diff --git a/msg/json/tlh.json b/msg/json/tlh.json index eac917e92..c6ea8824b 100644 --- a/msg/json/tlh.json +++ b/msg/json/tlh.json @@ -6,6 +6,7 @@ "messagedocumentation" : "qqq" }, "VARIABLES_DEFAULT_NAME": "Doch", + "TODAY": "jajvam", "DUPLICATE_BLOCK": "velqa' chenmoH", "ADD_COMMENT": "QInHom chel", "REMOVE_COMMENT": "QInHom chelHa'", @@ -14,6 +15,7 @@ "DELETE_BLOCK": "ngogh Qaw'", "DELETE_X_BLOCKS": "%1 ngoghmey Qaw'", "DELETE_ALL_BLOCKS": "Hoch %1 ngoghmey Qaw'?", + "CLEAN_UP": "ngoghmey Say'", "COLLAPSE_BLOCK": "ngogh DejmoH", "COLLAPSE_ALL": "ngoghmey DejmoH", "EXPAND_BLOCK": "ngogh DejHa'moH", @@ -21,6 +23,8 @@ "DISABLE_BLOCK": "ngogh Qotlh", "ENABLE_BLOCK": "ngogh QotlhHa'", "HELP": "QaH", + "UNDO": "wumHa'", + "REDO": "wumqa'", "CHAT": "beqpu'lI'vaD bIjawmeH naDev yIrI'!", "AUTH": "ngogh nablIj DapollaHmeH qoj latlhvaD DangeHlaHmeH chaw' yInob.", "CHANGE_VALUE_TITLE": "choH:", @@ -156,6 +160,9 @@ "LISTS_GET_SUBLIST_END_FROM_END": "mojaQ # Qav", "LISTS_GET_SUBLIST_END_LAST": "mojaQ Qav", "LISTS_GET_SUBLIST_TAIL": "Suq", + "LISTS_SPLIT_LIST_FROM_TEXT": "tetlh ghom ghItlhmey", + "LISTS_SPLIT_TEXT_FROM_LIST": "ghItlhmey ghom tetlh", + "LISTS_SPLIT_WITH_DELIMITER": "rarwI'Hom", "ORDINAL_NUMBER_SUFFIX": "", "VARIABLES_GET_CREATE_SET": "chel 'choH %1'", "VARIABLES_SET": "choH %1 %2", @@ -165,7 +172,9 @@ "PROCEDURES_BEFORE_PARAMS": "qel:", "PROCEDURES_CALL_BEFORE_PARAMS": "qel:", "PROCEDURES_DEFNORETURN_DO": "", + "PROCEDURES_DEFNORETURN_COMMENT": "mIwQInHom yIchel...", "PROCEDURES_DEFRETURN_RETURN": "chegh", + "PROCEDURES_ALLOW_STATEMENTS": "mu'tlhegh chaw'", "PROCEDURES_DEF_DUPLICATE_WARNING": "ghuHmoHna': qelwI' cha'logh chen.", "PROCEDURES_MUTATORCONTAINER_TITLE": "qelwI'mey", "PROCEDURES_MUTATORARG_TITLE": "pong:", From 05f5af3df180d25f4c4022360a6035a75a62efea Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Mon, 4 Apr 2016 14:56:00 -0700 Subject: [PATCH 12/13] JSON some math block. --- blocks/math.js | 203 +++++++++++++++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 72 deletions(-) diff --git a/blocks/math.js b/blocks/math.js index 4e87d5a7a..0350048c8 100644 --- a/blocks/math.js +++ b/blocks/math.js @@ -62,21 +62,35 @@ Blockly.Blocks['math_arithmetic'] = { * @this Blockly.Block */ init: function() { - var OPERATORS = - [[Blockly.Msg.MATH_ADDITION_SYMBOL, 'ADD'], - [Blockly.Msg.MATH_SUBTRACTION_SYMBOL, 'MINUS'], - [Blockly.Msg.MATH_MULTIPLICATION_SYMBOL, 'MULTIPLY'], - [Blockly.Msg.MATH_DIVISION_SYMBOL, 'DIVIDE'], - [Blockly.Msg.MATH_POWER_SYMBOL, 'POWER']]; - this.setHelpUrl(Blockly.Msg.MATH_ARITHMETIC_HELPURL); - this.setColour(Blockly.Blocks.math.HUE); - this.setOutput(true, 'Number'); - this.appendValueInput('A') - .setCheck('Number'); - this.appendValueInput('B') - .setCheck('Number') - .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP'); - this.setInputsInline(true); + this.jsonInit({ + "message0": "%1 %2 %3", + "args0": [ + { + "type": "input_value", + "name": "A", + "check": "Number" + }, + { + "type": "field_dropdown", + "name": "OP", + "options": + [[Blockly.Msg.MATH_ADDITION_SYMBOL, 'ADD'], + [Blockly.Msg.MATH_SUBTRACTION_SYMBOL, 'MINUS'], + [Blockly.Msg.MATH_MULTIPLICATION_SYMBOL, 'MULTIPLY'], + [Blockly.Msg.MATH_DIVISION_SYMBOL, 'DIVIDE'], + [Blockly.Msg.MATH_POWER_SYMBOL, 'POWER']] + }, + { + "type": "input_value", + "name": "B", + "check": "Number" + } + ], + "inputsInline": true, + "output": "Number", + "colour": Blockly.Blocks.math.HUE, + "helpUrl": Blockly.Msg.MATH_ARITHMETIC_HELPURL + }); // Assign 'this' to a variable for use in the tooltip closure below. var thisBlock = this; this.setTooltip(function() { @@ -99,20 +113,32 @@ Blockly.Blocks['math_single'] = { * @this Blockly.Block */ init: function() { - var OPERATORS = - [[Blockly.Msg.MATH_SINGLE_OP_ROOT, 'ROOT'], - [Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE, 'ABS'], - ['-', 'NEG'], - ['ln', 'LN'], - ['log10', 'LOG10'], - ['e^', 'EXP'], - ['10^', 'POW10']]; - this.setHelpUrl(Blockly.Msg.MATH_SINGLE_HELPURL); - this.setColour(Blockly.Blocks.math.HUE); - this.setOutput(true, 'Number'); - this.appendValueInput('NUM') - .setCheck('Number') - .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP'); + this.jsonInit({ + "message0": "%1 %2", + "args0": [ + { + "type": "field_dropdown", + "name": "OP", + "options": [ + [Blockly.Msg.MATH_SINGLE_OP_ROOT, 'ROOT'], + [Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE, 'ABS'], + ['-', 'NEG'], + ['ln', 'LN'], + ['log10', 'LOG10'], + ['e^', 'EXP'], + ['10^', 'POW10'] + ] + }, + { + "type": "input_value", + "name": "NUM", + "check": "Number" + } + ], + "output": "Number", + "colour": Blockly.Blocks.math.HUE, + "helpUrl": Blockly.Msg.MATH_SINGLE_HELPURL + }); // Assign 'this' to a variable for use in the tooltip closure below. var thisBlock = this; this.setTooltip(function() { @@ -137,19 +163,31 @@ Blockly.Blocks['math_trig'] = { * @this Blockly.Block */ init: function() { - var OPERATORS = - [[Blockly.Msg.MATH_TRIG_SIN, 'SIN'], - [Blockly.Msg.MATH_TRIG_COS, 'COS'], - [Blockly.Msg.MATH_TRIG_TAN, 'TAN'], - [Blockly.Msg.MATH_TRIG_ASIN, 'ASIN'], - [Blockly.Msg.MATH_TRIG_ACOS, 'ACOS'], - [Blockly.Msg.MATH_TRIG_ATAN, 'ATAN']]; - this.setHelpUrl(Blockly.Msg.MATH_TRIG_HELPURL); - this.setColour(Blockly.Blocks.math.HUE); - this.setOutput(true, 'Number'); - this.appendValueInput('NUM') - .setCheck('Number') - .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP'); + this.jsonInit({ + "message0": "%1 %2", + "args0": [ + { + "type": "field_dropdown", + "name": "OP", + "options": [ + [Blockly.Msg.MATH_TRIG_SIN, 'SIN'], + [Blockly.Msg.MATH_TRIG_COS, 'COS'], + [Blockly.Msg.MATH_TRIG_TAN, 'TAN'], + [Blockly.Msg.MATH_TRIG_ASIN, 'ASIN'], + [Blockly.Msg.MATH_TRIG_ACOS, 'ACOS'], + [Blockly.Msg.MATH_TRIG_ATAN, 'ATAN'] + ] + }, + { + "type": "input_value", + "name": "NUM", + "check": "Number" + } + ], + "output": "Number", + "colour": Blockly.Blocks.math.HUE, + "helpUrl": Blockly.Msg.MATH_TRIG_HELPURL + }); // Assign 'this' to a variable for use in the tooltip closure below. var thisBlock = this; this.setTooltip(function() { @@ -173,19 +211,27 @@ Blockly.Blocks['math_constant'] = { * @this Blockly.Block */ init: function() { - var CONSTANTS = - [['\u03c0', 'PI'], - ['e', 'E'], - ['\u03c6', 'GOLDEN_RATIO'], - ['sqrt(2)', 'SQRT2'], - ['sqrt(\u00bd)', 'SQRT1_2'], - ['\u221e', 'INFINITY']]; - this.setHelpUrl(Blockly.Msg.MATH_CONSTANT_HELPURL); - this.setColour(Blockly.Blocks.math.HUE); - this.setOutput(true, 'Number'); - this.appendDummyInput() - .appendField(new Blockly.FieldDropdown(CONSTANTS), 'CONSTANT'); - this.setTooltip(Blockly.Msg.MATH_CONSTANT_TOOLTIP); + this.jsonInit({ + "message0": "%1", + "args0": [ + { + "type": "field_dropdown", + "name": "CONSTANT", + "options": [ + ['\u03c0', 'PI'], + ['e', 'E'], + ['\u03c6', 'GOLDEN_RATIO'], + ['sqrt(2)', 'SQRT2'], + ['sqrt(\u00bd)', 'SQRT1_2'], + ['\u221e', 'INFINITY'] + ] + } + ], + "output": "Number", + "colour": Blockly.Blocks.math.HUE, + "tooltip": Blockly.Msg.MATH_CONSTANT_TOOLTIP, + "helpUrl": Blockly.Msg.MATH_CONSTANT_HELPURL + }); } }; @@ -297,17 +343,29 @@ Blockly.Blocks['math_round'] = { * @this Blockly.Block */ init: function() { - var OPERATORS = - [[Blockly.Msg.MATH_ROUND_OPERATOR_ROUND, 'ROUND'], - [Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP, 'ROUNDUP'], - [Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN, 'ROUNDDOWN']]; - this.setHelpUrl(Blockly.Msg.MATH_ROUND_HELPURL); - this.setColour(Blockly.Blocks.math.HUE); - this.setOutput(true, 'Number'); - this.appendValueInput('NUM') - .setCheck('Number') - .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP'); - this.setTooltip(Blockly.Msg.MATH_ROUND_TOOLTIP); + this.jsonInit({ + "message0": "%1 %2", + "args0": [ + { + "type": "field_dropdown", + "name": "OP", + "options": [ + [Blockly.Msg.MATH_ROUND_OPERATOR_ROUND, 'ROUND'], + [Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP, 'ROUNDUP'], + [Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN, 'ROUNDDOWN'] + ] + }, + { + "type": "input_value", + "name": "NUM", + "check": "Number" + } + ], + "output": "Number", + "colour": Blockly.Blocks.math.HUE, + "tooltip": Blockly.Msg.MATH_ROUND_TOOLTIP, + "helpUrl": Blockly.Msg.MATH_ROUND_HELPURL + }); } }; @@ -484,11 +542,12 @@ Blockly.Blocks['math_random_float'] = { * @this Blockly.Block */ init: function() { - this.setHelpUrl(Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL); - this.setColour(Blockly.Blocks.math.HUE); - this.setOutput(true, 'Number'); - this.appendDummyInput() - .appendField(Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM); - this.setTooltip(Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP); + this.jsonInit({ + "message0": Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM, + "output": "Number", + "colour": Blockly.Blocks.math.HUE, + "tooltip": Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP, + "helpUrl": Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL + }); } }; From 77f0936b085815e652a749818461256a9e0ced8d Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Mon, 4 Apr 2016 14:56:11 -0700 Subject: [PATCH 13/13] Routine recompile. --- blockly_compressed.js | 14 +++++++------- blockly_uncompressed.js | 12 ++++++------ blocks_compressed.js | 18 +++++++++--------- msg/js/pt.js | 2 +- msg/js/tlh.js | 6 +++--- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/blockly_compressed.js b/blockly_compressed.js index 418052233..bb3ffa92c 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -1128,12 +1128,12 @@ Blockly.BlockSvg.prototype.showHelp_=function(){var a=goog.isFunction(this.helpU Blockly.BlockSvg.prototype.showContextMenu_=function(a){if(!this.workspace.options.readOnly&&this.contextMenu){var b=this,c=[];if(this.isDeletable()&&this.isMovable()&&!b.isInFlyout){var d={text:Blockly.Msg.DUPLICATE_BLOCK,enabled:!0,callback:function(){Blockly.duplicate_(b)}};this.getDescendants().length>this.workspace.remainingCapacity()&&(d.enabled=!1);c.push(d);this.isEditable()&&!this.collapsed_&&this.workspace.options.comments&&(d={enabled:!goog.userAgent.IE},this.comment?(d.text=Blockly.Msg.REMOVE_COMMENT, d.callback=function(){b.setCommentText(null)}):(d.text=Blockly.Msg.ADD_COMMENT,d.callback=function(){b.setCommentText("")}),c.push(d));if(!this.collapsed_)for(d=1;d=a.clientX&&0==a.clientY&&0==a.button)){var b=this.getRelativeToSurfaceXY(),c=this.workspace.moveDrag(a);Blockly.dragMode_==Blockly.DRAG_STICKY&&goog.math.Coordinate.distance(b,c)*this.workspace.scale>Blockly.DRAG_RADIUS&&(Blockly.dragMode_=Blockly.DRAG_FREE,Blockly.longStop_(),this.parentBlock_&&(this.unplug(),this.disconnectUiEffect()),this.setDragging_(!0));if(Blockly.dragMode_==Blockly.DRAG_FREE){var d=b.x-this.dragStartXY_.x, -b=b.y-this.dragStartXY_.y,e=this.getSvgRoot();e.translate_="translate("+c.x+","+c.y+")";e.setAttribute("transform",e.translate_+e.skew_);for(c=0;c=a.clientX&&0==a.clientY&&0==a.button)){var b=this.getRelativeToSurfaceXY(),c=this.workspace.moveDrag(a);if(Blockly.dragMode_==Blockly.DRAG_STICKY&&goog.math.Coordinate.distance(b,c)*this.workspace.scale>Blockly.DRAG_RADIUS){Blockly.dragMode_=Blockly.DRAG_FREE;Blockly.longStop_();if(this.parentBlock_){this.unplug();var d=this.getSvgRoot();d.translate_="translate("+c.x+","+c.y+")";this.disconnectUiEffect()}this.setDragging_(!0)}if(Blockly.dragMode_== +Blockly.DRAG_FREE){var e=b.x-this.dragStartXY_.x,b=b.y-this.dragStartXY_.y,d=this.getSvgRoot();d.translate_="translate("+c.x+","+c.y+")";d.setAttribute("transform",d.translate_+d.skew_);for(c=0;cBlockly.DRAG_RADIUS&& Blockly.longStop_();a.stopPropagation()}}}; Blockly.onKeyDown_=function(a){if(!Blockly.isTargetInput_(a)){var b=!1;if(27==a.keyCode)Blockly.hideChaff();else if(8==a.keyCode||46==a.keyCode)try{Blockly.selected&&Blockly.selected.isDeletable()&&(b=!0)}finally{a.preventDefault()}else if(a.altKey||a.ctrlKey||a.metaKey)Blockly.selected&&Blockly.selected.isDeletable()&&Blockly.selected.isMovable()&&(67==a.keyCode?(Blockly.hideChaff(),Blockly.copy_(Blockly.selected)):88==a.keyCode&&(Blockly.copy_(Blockly.selected),b=!0)),86==a.keyCode?Blockly.clipboardXml_&& -Blockly.clipboardSource_.paste(Blockly.clipboardXml_):90==a.keyCode&&(Blockly.hideChaff(),Blockly.mainWorkspace.undo(a.shiftKey));b&&(Blockly.hideChaff(),Blockly.selected.dispose(Blockly.dragMode_!=Blockly.DRAG_FREE,!0),Blockly.highlightedConnection_&&(Blockly.highlightedConnection_.unhighlight(),Blockly.highlightedConnection_=null))}};Blockly.terminateDrag_=function(){Blockly.BlockSvg.terminateDrag_();Blockly.Flyout.terminateDrag_()};Blockly.longPid_=0; -Blockly.longStart_=function(a,b){Blockly.longStop_();Blockly.longPid_=setTimeout(function(){a.button=2;b.onMouseDown_(a)},Blockly.LONGPRESS)};Blockly.longStop_=function(){Blockly.longPid_&&(clearTimeout(Blockly.longPid_),Blockly.longPid_=0)}; +Blockly.clipboardSource_.paste(Blockly.clipboardXml_):90==a.keyCode&&(Blockly.hideChaff(),Blockly.mainWorkspace.undo(a.shiftKey));b&&(Blockly.Events.setGroup(!0),Blockly.hideChaff(),Blockly.selected.dispose(Blockly.dragMode_!=Blockly.DRAG_FREE,!0),Blockly.highlightedConnection_&&(Blockly.highlightedConnection_.unhighlight(),Blockly.highlightedConnection_=null),Blockly.Events.setGroup(!1))}};Blockly.terminateDrag_=function(){Blockly.BlockSvg.terminateDrag_();Blockly.Flyout.terminateDrag_()}; +Blockly.longPid_=0;Blockly.longStart_=function(a,b){Blockly.longStop_();Blockly.longPid_=setTimeout(function(){a.button=2;b.onMouseDown_(a)},Blockly.LONGPRESS)};Blockly.longStop_=function(){Blockly.longPid_&&(clearTimeout(Blockly.longPid_),Blockly.longPid_=0)}; Blockly.copy_=function(a){var b=Blockly.Xml.blockToDom(a);Blockly.dragMode_!=Blockly.DRAG_FREE&&Blockly.Xml.deleteNext(b);var c=a.getRelativeToSurfaceXY();b.setAttribute("x",a.RTL?-c.x:c.x);b.setAttribute("y",c.y);Blockly.clipboardXml_=b;Blockly.clipboardSource_=a.workspace};Blockly.duplicate_=function(a){var b=Blockly.clipboardXml_,c=Blockly.clipboardSource_;Blockly.copy_(a);a.workspace.paste(Blockly.clipboardXml_);Blockly.clipboardXml_=b;Blockly.clipboardSource_=c}; Blockly.onContextMenu_=function(a){Blockly.isTargetInput_(a)||a.preventDefault()};Blockly.hideChaff=function(a){Blockly.Tooltip.hide();Blockly.WidgetDiv.hide();a||(a=Blockly.getMainWorkspace(),a.toolbox_&&a.toolbox_.flyout_&&a.toolbox_.flyout_.autoClose&&a.toolbox_.clearSelection())}; Blockly.getMainWorkspaceMetrics_=function(){var a=Blockly.svgSize(this.getParentSvg());this.toolbox_&&(a.width-=this.toolbox_.width);var b=Blockly.Flyout.prototype.CORNER_RADIUS-1,c=a.width-b,d=a.height-b,e=this.getBlocksBoundingBox(),f=e.width*this.scale,g=e.height*this.scale,h=e.x*this.scale,k=e.y*this.scale;this.scrollbar?(b=Math.min(h-c/2,h+f-c),c=Math.max(h+f+c/2,h+c),f=Math.min(k-d/2,k+g-d),d=Math.max(k+g+d/2,k+d)):(b=e.x,c=b+e.width,f=e.y,d=f+e.height);e=0;!this.RTL&&this.toolbox_&&(e=this.toolbox_.width); diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index 64f35f7ba..fc3a55af8 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -183,7 +183,7 @@ goog.addDependency("datasource/fastdatanode.js", ['goog.ds.AbstractFastDataNode' goog.addDependency("datasource/fastdatanode_test.js", ['goog.ds.FastDataNodeTest'], ['goog.array', 'goog.ds.DataManager', 'goog.ds.Expr', 'goog.ds.FastDataNode', 'goog.testing.jsunit']); goog.addDependency("datasource/jsdatasource.js", ['goog.ds.JsDataSource', 'goog.ds.JsPropertyDataSource'], ['goog.ds.BaseDataNode', 'goog.ds.BasicNodeList', 'goog.ds.DataManager', 'goog.ds.DataNode', 'goog.ds.EmptyNodeList', 'goog.ds.LoadState']); goog.addDependency("datasource/jsondatasource.js", ['goog.ds.JsonDataSource'], ['goog.Uri', 'goog.dom', 'goog.dom.TagName', 'goog.ds.DataManager', 'goog.ds.JsDataSource', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.log']); -goog.addDependency("datasource/jsxmlhttpdatasource.js", ['goog.ds.JsXmlHttpDataSource'], ['goog.Uri', 'goog.ds.DataManager', 'goog.ds.FastDataNode', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.events', 'goog.log', 'goog.net.EventType', 'goog.net.XhrIo']); +goog.addDependency("datasource/jsxmlhttpdatasource.js", ['goog.ds.JsXmlHttpDataSource'], ['goog.Uri', 'goog.ds.DataManager', 'goog.ds.FastDataNode', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.events', 'goog.json', 'goog.log', 'goog.net.EventType', 'goog.net.XhrIo']); goog.addDependency("datasource/jsxmlhttpdatasource_test.js", ['goog.ds.JsXmlHttpDataSourceTest'], ['goog.ds.JsXmlHttpDataSource', 'goog.testing.TestQueue', 'goog.testing.jsunit', 'goog.testing.net.XhrIo']); goog.addDependency("datasource/xmldatasource.js", ['goog.ds.XmlDataSource', 'goog.ds.XmlHttpDataSource'], ['goog.Uri', 'goog.dom.NodeType', 'goog.dom.xml', 'goog.ds.BasicNodeList', 'goog.ds.DataManager', 'goog.ds.DataNode', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.log', 'goog.net.XhrIo', 'goog.string']); goog.addDependency("date/date.js", ['goog.date', 'goog.date.Date', 'goog.date.DateTime', 'goog.date.Interval', 'goog.date.month', 'goog.date.weekDay'], ['goog.asserts', 'goog.date.DateLike', 'goog.i18n.DateTimeSymbols', 'goog.string']); @@ -273,7 +273,7 @@ goog.addDependency("dom/controlrange.js", ['goog.dom.ControlRange', 'goog.dom.Co goog.addDependency("dom/controlrange_test.js", ['goog.dom.ControlRangeTest'], ['goog.dom', 'goog.dom.ControlRange', 'goog.dom.RangeType', 'goog.dom.TagName', 'goog.dom.TextRange', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']); goog.addDependency("dom/dataset.js", ['goog.dom.dataset'], ['goog.string', 'goog.userAgent.product']); goog.addDependency("dom/dataset_test.js", ['goog.dom.datasetTest'], ['goog.dom', 'goog.dom.dataset', 'goog.testing.jsunit']); -goog.addDependency("dom/dom.js", ['goog.dom', 'goog.dom.Appendable', 'goog.dom.DomHelper'], ['goog.array', 'goog.asserts', 'goog.dom.BrowserFeature', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.legacyconversions', 'goog.math.Coordinate', 'goog.math.Size', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.userAgent']); +goog.addDependency("dom/dom.js", ['goog.dom', 'goog.dom.Appendable', 'goog.dom.DomHelper'], ['goog.array', 'goog.asserts', 'goog.dom.BrowserFeature', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.math.Coordinate', 'goog.math.Size', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.userAgent']); goog.addDependency("dom/dom_test.js", ['goog.dom.dom_test'], ['goog.dom', 'goog.dom.BrowserFeature', 'goog.dom.DomHelper', 'goog.dom.InputType', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.functions', 'goog.html.testing', 'goog.object', 'goog.string.Unicode', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']); goog.addDependency("dom/fontsizemonitor.js", ['goog.dom.FontSizeMonitor', 'goog.dom.FontSizeMonitor.EventType'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.userAgent']); goog.addDependency("dom/fontsizemonitor_test.js", ['goog.dom.FontSizeMonitorTest'], ['goog.dom', 'goog.dom.FontSizeMonitor', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']); @@ -287,7 +287,7 @@ goog.addDependency("dom/inputtype.js", ['goog.dom.InputType'], []); goog.addDependency("dom/inputtype_test.js", ['goog.dom.InputTypeTest'], ['goog.dom.InputType', 'goog.object']); goog.addDependency("dom/iter.js", ['goog.dom.iter.AncestorIterator', 'goog.dom.iter.ChildIterator', 'goog.dom.iter.SiblingIterator'], ['goog.iter.Iterator', 'goog.iter.StopIteration']); goog.addDependency("dom/iter_test.js", ['goog.dom.iterTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.iter.AncestorIterator', 'goog.dom.iter.ChildIterator', 'goog.dom.iter.SiblingIterator', 'goog.testing.dom', 'goog.testing.jsunit']); -goog.addDependency("dom/multirange.js", ['goog.dom.MultiRange', 'goog.dom.MultiRangeIterator'], ['goog.array', 'goog.dom.AbstractMultiRange', 'goog.dom.AbstractRange', 'goog.dom.RangeIterator', 'goog.dom.RangeType', 'goog.dom.SavedRange', 'goog.dom.TextRange', 'goog.iter', 'goog.iter.StopIteration', 'goog.log']); +goog.addDependency("dom/multirange.js", ['goog.dom.MultiRange', 'goog.dom.MultiRangeIterator'], ['goog.array', 'goog.dom', 'goog.dom.AbstractMultiRange', 'goog.dom.AbstractRange', 'goog.dom.RangeIterator', 'goog.dom.RangeType', 'goog.dom.SavedRange', 'goog.dom.TextRange', 'goog.iter', 'goog.iter.StopIteration', 'goog.log']); goog.addDependency("dom/multirange_test.js", ['goog.dom.MultiRangeTest'], ['goog.dom', 'goog.dom.MultiRange', 'goog.dom.Range', 'goog.iter', 'goog.testing.jsunit']); goog.addDependency("dom/nodeiterator.js", ['goog.dom.NodeIterator'], ['goog.dom.TagIterator']); goog.addDependency("dom/nodeiterator_test.js", ['goog.dom.NodeIteratorTest'], ['goog.dom', 'goog.dom.NodeIterator', 'goog.testing.dom', 'goog.testing.jsunit']); @@ -350,7 +350,7 @@ goog.addDependency("dom/pattern/text.js", ['goog.dom.pattern.Text'], ['goog.dom. goog.addDependency("dom/pattern/callback/callback.js", ['goog.dom.pattern.callback'], ['goog.dom', 'goog.dom.TagWalkType', 'goog.iter']); goog.addDependency("dom/pattern/callback/counter.js", ['goog.dom.pattern.callback.Counter'], []); goog.addDependency("dom/pattern/callback/test.js", ['goog.dom.pattern.callback.Test'], ['goog.iter.StopIteration']); -goog.addDependency("editor/browserfeature.js", ['goog.editor.BrowserFeature'], ['goog.editor.defines', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']); +goog.addDependency("editor/browserfeature.js", ['goog.editor.BrowserFeature'], ['goog.editor.defines', 'goog.labs.userAgent.browser', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']); goog.addDependency("editor/browserfeature_test.js", ['goog.editor.BrowserFeatureTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit']); goog.addDependency("editor/clicktoeditwrapper.js", ['goog.editor.ClickToEditWrapper'], ['goog.Disposable', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.range', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventType']); goog.addDependency("editor/clicktoeditwrapper_test.js", ['goog.editor.ClickToEditWrapperTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.ClickToEditWrapper', 'goog.editor.SeamlessField', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']); @@ -990,7 +990,7 @@ goog.addDependency("result/resultutil.js", ['goog.result'], ['goog.array', 'goog goog.addDependency("result/simpleresult.js", ['goog.result.SimpleResult', 'goog.result.SimpleResult.StateError'], ['goog.Promise', 'goog.Thenable', 'goog.debug.Error', 'goog.result.Result']); goog.addDependency("soy/data.js", ['goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.soy.data.SanitizedCss', 'goog.soy.data.UnsanitizedText'], ['goog.html.SafeHtml', 'goog.html.uncheckedconversions', 'goog.string.Const']); goog.addDependency("soy/data_test.js", ['goog.soy.dataTest'], ['goog.html.SafeHtml', 'goog.soy.testHelper', 'goog.testing.jsunit']); -goog.addDependency("soy/renderer.js", ['goog.soy.InjectedDataSupplier', 'goog.soy.Renderer'], ['goog.asserts', 'goog.dom', 'goog.html.uncheckedconversions', 'goog.soy', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind']); +goog.addDependency("soy/renderer.js", ['goog.soy.InjectedDataSupplier', 'goog.soy.Renderer'], ['goog.asserts', 'goog.dom', 'goog.html.uncheckedconversions', 'goog.soy', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.string.Const']); goog.addDependency("soy/renderer_test.js", ['goog.soy.RendererTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.html.SafeHtml', 'goog.i18n.bidi.Dir', 'goog.soy.Renderer', 'goog.soy.data.SanitizedContentKind', 'goog.soy.testHelper', 'goog.testing.jsunit', 'goog.testing.recordFunction']); goog.addDependency("soy/soy.js", ['goog.soy'], ['goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.html.legacyconversions', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.string']); goog.addDependency("soy/soy_test.js", ['goog.soyTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.functions', 'goog.soy', 'goog.soy.testHelper', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']); @@ -1023,7 +1023,7 @@ goog.addDependency("storage/mechanism/html5webstorage_test.js", ['goog.storage.m goog.addDependency("storage/mechanism/ieuserdata.js", ['goog.storage.mechanism.IEUserData'], ['goog.asserts', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.storage.mechanism.ErrorCode', 'goog.storage.mechanism.IterableMechanism', 'goog.structs.Map', 'goog.userAgent']); goog.addDependency("storage/mechanism/ieuserdata_test.js", ['goog.storage.mechanism.IEUserDataTest'], ['goog.storage.mechanism.IEUserData', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.jsunit', 'goog.userAgent']); goog.addDependency("storage/mechanism/iterablemechanism.js", ['goog.storage.mechanism.IterableMechanism'], ['goog.array', 'goog.asserts', 'goog.iter', 'goog.storage.mechanism.Mechanism']); -goog.addDependency("storage/mechanism/iterablemechanismtester.js", ['goog.storage.mechanism.iterableMechanismTester'], ['goog.testing.asserts']); +goog.addDependency("storage/mechanism/iterablemechanismtester.js", ['goog.storage.mechanism.iterableMechanismTester'], ['goog.iter', 'goog.iter.StopIteration', 'goog.testing.asserts']); goog.addDependency("storage/mechanism/mechanism.js", ['goog.storage.mechanism.Mechanism'], []); goog.addDependency("storage/mechanism/mechanismfactory.js", ['goog.storage.mechanism.mechanismfactory'], ['goog.storage.mechanism.HTML5LocalStorage', 'goog.storage.mechanism.HTML5SessionStorage', 'goog.storage.mechanism.IEUserData', 'goog.storage.mechanism.PrefixedMechanism']); goog.addDependency("storage/mechanism/mechanismfactory_test.js", ['goog.storage.mechanism.mechanismfactoryTest'], ['goog.storage.mechanism.mechanismfactory', 'goog.testing.jsunit']); diff --git a/blocks_compressed.js b/blocks_compressed.js index d292873ec..8edc23d0a 100644 --- a/blocks_compressed.js +++ b/blocks_compressed.js @@ -62,24 +62,24 @@ Blockly.Blocks.controls_forEach={init:function(){this.jsonInit({message0:Blockly a.getFieldValue("VAR"))})},customContextMenu:Blockly.Blocks.controls_for.customContextMenu}; Blockly.Blocks.controls_flow_statements={init:function(){var a=[[Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK,"BREAK"],[Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE,"CONTINUE"]];this.setHelpUrl(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL);this.setColour(Blockly.Blocks.loops.HUE);this.appendDummyInput().appendField(new Blockly.FieldDropdown(a),"FLOW");this.setPreviousStatement(!0);var b=this;this.setTooltip(function(){var a=b.getFieldValue("FLOW");return{BREAK:Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK, CONTINUE:Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}[a]})},onchange:function(a){a=!1;var b=this;do{if(-1!=this.LOOP_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);a?this.setWarningText(null):this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING)},LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"]};Blockly.Blocks.math={};Blockly.Blocks.math.HUE=230;Blockly.Blocks.math_number={init:function(){this.setHelpUrl(Blockly.Msg.MATH_NUMBER_HELPURL);this.setColour(Blockly.Blocks.math.HUE);this.appendDummyInput().appendField(new Blockly.FieldTextInput("0",Blockly.FieldTextInput.numberValidator),"NUM");this.setOutput(!0,"Number");var a=this;this.setTooltip(function(){var b=a.getParent();return b&&b.tooltip||Blockly.Msg.MATH_NUMBER_TOOLTIP})}}; -Blockly.Blocks.math_arithmetic={init:function(){var a=[[Blockly.Msg.MATH_ADDITION_SYMBOL,"ADD"],[Blockly.Msg.MATH_SUBTRACTION_SYMBOL,"MINUS"],[Blockly.Msg.MATH_MULTIPLICATION_SYMBOL,"MULTIPLY"],[Blockly.Msg.MATH_DIVISION_SYMBOL,"DIVIDE"],[Blockly.Msg.MATH_POWER_SYMBOL,"POWER"]];this.setHelpUrl(Blockly.Msg.MATH_ARITHMETIC_HELPURL);this.setColour(Blockly.Blocks.math.HUE);this.setOutput(!0,"Number");this.appendValueInput("A").setCheck("Number");this.appendValueInput("B").setCheck("Number").appendField(new Blockly.FieldDropdown(a), -"OP");this.setInputsInline(!0);var b=this;this.setTooltip(function(){var a=b.getFieldValue("OP");return{ADD:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,MINUS:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,MULTIPLY:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,DIVIDE:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,POWER:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER}[a]})}}; -Blockly.Blocks.math_single={init:function(){var a=[[Blockly.Msg.MATH_SINGLE_OP_ROOT,"ROOT"],[Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE,"ABS"],["-","NEG"],["ln","LN"],["log10","LOG10"],["e^","EXP"],["10^","POW10"]];this.setHelpUrl(Blockly.Msg.MATH_SINGLE_HELPURL);this.setColour(Blockly.Blocks.math.HUE);this.setOutput(!0,"Number");this.appendValueInput("NUM").setCheck("Number").appendField(new Blockly.FieldDropdown(a),"OP");var b=this;this.setTooltip(function(){var a=b.getFieldValue("OP");return{ROOT:Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT, -ABS:Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS,NEG:Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG,LN:Blockly.Msg.MATH_SINGLE_TOOLTIP_LN,LOG10:Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10,EXP:Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP,POW10:Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10}[a]})}}; -Blockly.Blocks.math_trig={init:function(){var a=[[Blockly.Msg.MATH_TRIG_SIN,"SIN"],[Blockly.Msg.MATH_TRIG_COS,"COS"],[Blockly.Msg.MATH_TRIG_TAN,"TAN"],[Blockly.Msg.MATH_TRIG_ASIN,"ASIN"],[Blockly.Msg.MATH_TRIG_ACOS,"ACOS"],[Blockly.Msg.MATH_TRIG_ATAN,"ATAN"]];this.setHelpUrl(Blockly.Msg.MATH_TRIG_HELPURL);this.setColour(Blockly.Blocks.math.HUE);this.setOutput(!0,"Number");this.appendValueInput("NUM").setCheck("Number").appendField(new Blockly.FieldDropdown(a),"OP");var b=this;this.setTooltip(function(){var a= -b.getFieldValue("OP");return{SIN:Blockly.Msg.MATH_TRIG_TOOLTIP_SIN,COS:Blockly.Msg.MATH_TRIG_TOOLTIP_COS,TAN:Blockly.Msg.MATH_TRIG_TOOLTIP_TAN,ASIN:Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN,ACOS:Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS,ATAN:Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN}[a]})}}; -Blockly.Blocks.math_constant={init:function(){this.setHelpUrl(Blockly.Msg.MATH_CONSTANT_HELPURL);this.setColour(Blockly.Blocks.math.HUE);this.setOutput(!0,"Number");this.appendDummyInput().appendField(new Blockly.FieldDropdown([["\u03c0","PI"],["e","E"],["\u03c6","GOLDEN_RATIO"],["sqrt(2)","SQRT2"],["sqrt(\u00bd)","SQRT1_2"],["\u221e","INFINITY"]]),"CONSTANT");this.setTooltip(Blockly.Msg.MATH_CONSTANT_TOOLTIP)}}; +Blockly.Blocks.math_arithmetic={init:function(){this.jsonInit({message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Number"},{type:"field_dropdown",name:"OP",options:[[Blockly.Msg.MATH_ADDITION_SYMBOL,"ADD"],[Blockly.Msg.MATH_SUBTRACTION_SYMBOL,"MINUS"],[Blockly.Msg.MATH_MULTIPLICATION_SYMBOL,"MULTIPLY"],[Blockly.Msg.MATH_DIVISION_SYMBOL,"DIVIDE"],[Blockly.Msg.MATH_POWER_SYMBOL,"POWER"]]},{type:"input_value",name:"B",check:"Number"}],inputsInline:!0,output:"Number",colour:Blockly.Blocks.math.HUE, +helpUrl:Blockly.Msg.MATH_ARITHMETIC_HELPURL});var a=this;this.setTooltip(function(){var b=a.getFieldValue("OP");return{ADD:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,MINUS:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,MULTIPLY:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,DIVIDE:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,POWER:Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER}[b]})}}; +Blockly.Blocks.math_single={init:function(){this.jsonInit({message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[[Blockly.Msg.MATH_SINGLE_OP_ROOT,"ROOT"],[Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE,"ABS"],["-","NEG"],["ln","LN"],["log10","LOG10"],["e^","EXP"],["10^","POW10"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:Blockly.Blocks.math.HUE,helpUrl:Blockly.Msg.MATH_SINGLE_HELPURL});var a=this;this.setTooltip(function(){var b=a.getFieldValue("OP");return{ROOT:Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT, +ABS:Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS,NEG:Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG,LN:Blockly.Msg.MATH_SINGLE_TOOLTIP_LN,LOG10:Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10,EXP:Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP,POW10:Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10}[b]})}}; +Blockly.Blocks.math_trig={init:function(){this.jsonInit({message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[[Blockly.Msg.MATH_TRIG_SIN,"SIN"],[Blockly.Msg.MATH_TRIG_COS,"COS"],[Blockly.Msg.MATH_TRIG_TAN,"TAN"],[Blockly.Msg.MATH_TRIG_ASIN,"ASIN"],[Blockly.Msg.MATH_TRIG_ACOS,"ACOS"],[Blockly.Msg.MATH_TRIG_ATAN,"ATAN"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:Blockly.Blocks.math.HUE,helpUrl:Blockly.Msg.MATH_TRIG_HELPURL});var a=this;this.setTooltip(function(){var b= +a.getFieldValue("OP");return{SIN:Blockly.Msg.MATH_TRIG_TOOLTIP_SIN,COS:Blockly.Msg.MATH_TRIG_TOOLTIP_COS,TAN:Blockly.Msg.MATH_TRIG_TOOLTIP_TAN,ASIN:Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN,ACOS:Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS,ATAN:Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN}[b]})}}; +Blockly.Blocks.math_constant={init:function(){this.jsonInit({message0:"%1",args0:[{type:"field_dropdown",name:"CONSTANT",options:[["\u03c0","PI"],["e","E"],["\u03c6","GOLDEN_RATIO"],["sqrt(2)","SQRT2"],["sqrt(\u00bd)","SQRT1_2"],["\u221e","INFINITY"]]}],output:"Number",colour:Blockly.Blocks.math.HUE,tooltip:Blockly.Msg.MATH_CONSTANT_TOOLTIP,helpUrl:Blockly.Msg.MATH_CONSTANT_HELPURL})}}; Blockly.Blocks.math_number_property={init:function(){var a=[[Blockly.Msg.MATH_IS_EVEN,"EVEN"],[Blockly.Msg.MATH_IS_ODD,"ODD"],[Blockly.Msg.MATH_IS_PRIME,"PRIME"],[Blockly.Msg.MATH_IS_WHOLE,"WHOLE"],[Blockly.Msg.MATH_IS_POSITIVE,"POSITIVE"],[Blockly.Msg.MATH_IS_NEGATIVE,"NEGATIVE"],[Blockly.Msg.MATH_IS_DIVISIBLE_BY,"DIVISIBLE_BY"]];this.setColour(Blockly.Blocks.math.HUE);this.appendValueInput("NUMBER_TO_CHECK").setCheck("Number");a=new Blockly.FieldDropdown(a,function(a){this.sourceBlock_.updateShape_("DIVISIBLE_BY"== a)});this.appendDummyInput().appendField(a,"PROPERTY");this.setInputsInline(!0);this.setOutput(!0,"Boolean");this.setTooltip(Blockly.Msg.MATH_IS_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),b="DIVISIBLE_BY"==this.getFieldValue("PROPERTY");a.setAttribute("divisor_input",b);return a},domToMutation:function(a){a="true"==a.getAttribute("divisor_input");this.updateShape_(a)},updateShape_:function(a){var b=this.getInput("DIVISOR");a?b||this.appendValueInput("DIVISOR").setCheck("Number"): b&&this.removeInput("DIVISOR")}};Blockly.Blocks.math_change={init:function(){this.jsonInit({message0:Blockly.Msg.MATH_CHANGE_TITLE,args0:[{type:"field_variable",name:"VAR",variable:Blockly.Msg.MATH_CHANGE_TITLE_ITEM},{type:"input_value",name:"DELTA",check:"Number"}],previousStatement:null,nextStatement:null,colour:Blockly.Blocks.math.HUE,helpUrl:Blockly.Msg.MATH_CHANGE_HELPURL});var a=this;this.setTooltip(function(){return Blockly.Msg.MATH_CHANGE_TOOLTIP.replace("%1",a.getFieldValue("VAR"))})}}; -Blockly.Blocks.math_round={init:function(){var a=[[Blockly.Msg.MATH_ROUND_OPERATOR_ROUND,"ROUND"],[Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP,"ROUNDUP"],[Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN,"ROUNDDOWN"]];this.setHelpUrl(Blockly.Msg.MATH_ROUND_HELPURL);this.setColour(Blockly.Blocks.math.HUE);this.setOutput(!0,"Number");this.appendValueInput("NUM").setCheck("Number").appendField(new Blockly.FieldDropdown(a),"OP");this.setTooltip(Blockly.Msg.MATH_ROUND_TOOLTIP)}}; +Blockly.Blocks.math_round={init:function(){this.jsonInit({message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[[Blockly.Msg.MATH_ROUND_OPERATOR_ROUND,"ROUND"],[Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP,"ROUNDUP"],[Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN,"ROUNDDOWN"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:Blockly.Blocks.math.HUE,tooltip:Blockly.Msg.MATH_ROUND_TOOLTIP,helpUrl:Blockly.Msg.MATH_ROUND_HELPURL})}}; Blockly.Blocks.math_on_list={init:function(){var a=[[Blockly.Msg.MATH_ONLIST_OPERATOR_SUM,"SUM"],[Blockly.Msg.MATH_ONLIST_OPERATOR_MIN,"MIN"],[Blockly.Msg.MATH_ONLIST_OPERATOR_MAX,"MAX"],[Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE,"AVERAGE"],[Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN,"MEDIAN"],[Blockly.Msg.MATH_ONLIST_OPERATOR_MODE,"MODE"],[Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV,"STD_DEV"],[Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM,"RANDOM"]],b=this;this.setHelpUrl(Blockly.Msg.MATH_ONLIST_HELPURL);this.setColour(Blockly.Blocks.math.HUE); this.setOutput(!0,"Number");a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendValueInput("LIST").setCheck("Array").appendField(a,"OP");this.setTooltip(function(){var a=b.getFieldValue("OP");return{SUM:Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM,MIN:Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN,MAX:Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX,AVERAGE:Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE,MEDIAN:Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN,MODE:Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE,STD_DEV:Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV, RANDOM:Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM}[a]})},updateType_:function(a){"MODE"==a?this.outputConnection.setCheck("Array"):this.outputConnection.setCheck("Number")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("op",this.getFieldValue("OP"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("op"))}}; Blockly.Blocks.math_modulo={init:function(){this.jsonInit({message0:Blockly.Msg.MATH_MODULO_TITLE,args0:[{type:"input_value",name:"DIVIDEND",check:"Number"},{type:"input_value",name:"DIVISOR",check:"Number"}],inputsInline:!0,output:"Number",colour:Blockly.Blocks.math.HUE,tooltip:Blockly.Msg.MATH_MODULO_TOOLTIP,helpUrl:Blockly.Msg.MATH_MODULO_HELPURL})}}; Blockly.Blocks.math_constrain={init:function(){this.jsonInit({message0:Blockly.Msg.MATH_CONSTRAIN_TITLE,args0:[{type:"input_value",name:"VALUE",check:"Number"},{type:"input_value",name:"LOW",check:"Number"},{type:"input_value",name:"HIGH",check:"Number"}],inputsInline:!0,output:"Number",colour:Blockly.Blocks.math.HUE,tooltip:Blockly.Msg.MATH_CONSTRAIN_TOOLTIP,helpUrl:Blockly.Msg.MATH_CONSTRAIN_HELPURL})}}; Blockly.Blocks.math_random_int={init:function(){this.jsonInit({message0:Blockly.Msg.MATH_RANDOM_INT_TITLE,args0:[{type:"input_value",name:"FROM",check:"Number"},{type:"input_value",name:"TO",check:"Number"}],inputsInline:!0,output:"Number",colour:Blockly.Blocks.math.HUE,tooltip:Blockly.Msg.MATH_RANDOM_INT_TOOLTIP,helpUrl:Blockly.Msg.MATH_RANDOM_INT_HELPURL})}}; -Blockly.Blocks.math_random_float={init:function(){this.setHelpUrl(Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL);this.setColour(Blockly.Blocks.math.HUE);this.setOutput(!0,"Number");this.appendDummyInput().appendField(Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM);this.setTooltip(Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP)}};Blockly.Blocks.procedures={};Blockly.Blocks.procedures.HUE=290; +Blockly.Blocks.math_random_float={init:function(){this.jsonInit({message0:Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM,output:"Number",colour:Blockly.Blocks.math.HUE,tooltip:Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP,helpUrl:Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL})}};Blockly.Blocks.procedures={};Blockly.Blocks.procedures.HUE=290; Blockly.Blocks.procedures_defnoreturn={init:function(){var a=new Blockly.FieldTextInput(Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE,Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);this.setColour(Blockly.Blocks.procedures.HUE); this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.arguments_=[];this.setStatements_(!0);this.statementConnection_=null},validate:function(){var a=Blockly.Procedures.findLegalName(this.getFieldValue("NAME"),this);this.setFieldValue(a,"NAME")},setStatements_:function(a){this.hasStatements_!==a&&(a?(this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO),this.getInput("RETURN")&&this.moveInputBefore("STACK", "RETURN")):this.removeInput("STACK",!0),this.hasStatements_=a)},updateParams_:function(){for(var a=!1,b={},c=0;c