diff --git a/blockly_compressed.js b/blockly_compressed.js index 377b0ac67..40fc0798f 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -861,10 +861,12 @@ goog.ui.tree.TreeControl.prototype.createNode=function(a){return new goog.ui.tre // Copyright 2013 Google Inc. Apache License 2.0 var Blockly={Blocks:{}}; // Copyright 2012 Google Inc. Apache License 2.0 -Blockly.Workspace=function(a){this.id=Blockly.genUid();Blockly.Workspace.WorkspaceDB_[this.id]=this;this.options=a||{};this.RTL=!!this.options.RTL;this.horizontalLayout=!!this.options.horizontalLayout;this.toolboxPosition=this.options.toolboxPosition;this.topBlocks_=[];this.listeners_=[];this.undoStack_=[];this.redoStack_=[];this.blockDB_=Object.create(null)};Blockly.Workspace.prototype.rendered=!1;Blockly.Workspace.prototype.MAX_UNDO=1024; -Blockly.Workspace.prototype.dispose=function(){this.listeners_.length=0;this.clear();delete Blockly.Workspace.WorkspaceDB_[this.id]};Blockly.Workspace.SCAN_ANGLE=3;Blockly.Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a)};Blockly.Workspace.prototype.removeTopBlock=function(a){for(var b=!1,c,d=0;c=this.topBlocks_[d];d++)if(c==a){this.topBlocks_.splice(d,1);b=!0;break}if(!b)throw"Block not present in workspace's list of top-most blocks.";}; +Blockly.Workspace=function(a){this.id=Blockly.genUid();Blockly.Workspace.WorkspaceDB_[this.id]=this;this.options=a||{};this.RTL=!!this.options.RTL;this.horizontalLayout=!!this.options.horizontalLayout;this.toolboxPosition=this.options.toolboxPosition;this.topBlocks_=[];this.listeners_=[];this.undoStack_=[];this.redoStack_=[];this.blockDB_=Object.create(null);this.variableList=[]};Blockly.Workspace.prototype.rendered=!1;Blockly.Workspace.prototype.MAX_UNDO=1024; +Blockly.Workspace.prototype.dispose=function(){this.listeners_.length=0;this.clear();delete Blockly.Workspace.WorkspaceDB_[this.id]};Blockly.Workspace.SCAN_ANGLE=3;Blockly.Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a);if(this.isFlyout){a=Blockly.Variables.allVariables(a);for(var b=0;bthis.MAX_UNDO&&this.undoStack_.unshift());for(var b=0,c;c=this.listeners_[b];b++)c(a)}; Blockly.Workspace.prototype.getBlockById=function(a){return this.blockDB_[a]||null};Blockly.Workspace.WorkspaceDB_=Object.create(null);Blockly.Workspace.getById=function(a){return Blockly.Workspace.WorkspaceDB_[a]||null};Blockly.Workspace.prototype.clear=Blockly.Workspace.prototype.clear;Blockly.Workspace.prototype.clearUndo=Blockly.Workspace.prototype.clearUndo;Blockly.Workspace.prototype.addChangeListener=Blockly.Workspace.prototype.addChangeListener; @@ -997,7 +999,7 @@ Blockly.Xml.cloneShadow_=function(a){for(var b=a=a.cloneNode(!0),c;b;)if(b.first Blockly.Xml.domToPrettyText=function(a){a=Blockly.Xml.domToText(a).split("<");for(var b="",c=1;c"!=d.slice(-2)&&(b+=" ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1");return a.replace(/^\n/,"")}; Blockly.Xml.textToDom=function(a){(a=(new DOMParser).parseFromString(a,"text/xml"))&&a.firstChild&&"xml"==a.firstChild.nodeName.toLowerCase()&&a.firstChild===a.lastChild||goog.asserts.fail("Blockly.Xml.textToDom did not obtain a valid XML tree.");return a.firstChild}; Blockly.Xml.domToWorkspace=function(a,b){if(a instanceof Blockly.Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to Blockly.Xml.domToWorkspace, swap the arguments.")}var d;b.RTL&&(d=b.getWidth());Blockly.Field.startCache();var c=a.childNodes.length,e=Blockly.Events.getGroup();e||Blockly.Events.setGroup(!0);for(var f=0;f} Array of XML block elements. */ Blockly.Variables.flyoutCategory = function(workspace) { - var variableList = Blockly.Variables.allVariables(workspace); + var variableList = workspace.variableList; variableList.sort(goog.string.caseInsensitiveCompare); // In addition to the user's variables, we also want to display the default // variable name at the top. We also don't want this duplicated if the @@ -148,7 +152,7 @@ Blockly.Variables.flyoutCategory = function(workspace) { * @return {string} New variable name. */ Blockly.Variables.generateUniqueName = function(workspace) { - var variableList = Blockly.Variables.allVariables(workspace); + var variableList = workspace.variableList; var newName = ''; if (variableList.length) { var nameSuffix = 1; diff --git a/core/workspace.js b/core/workspace.js index 200196b70..4d4d635d2 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -73,6 +73,12 @@ Blockly.Workspace = function(opt_options) { * @private */ this.blockDB_ = Object.create(null); + /* + * @type {!Array.} + * A list of all of the named variables in the workspace, including variables + * that are not currently in use. + */ + this.variableList = []; }; /** @@ -112,6 +118,14 @@ Blockly.Workspace.SCAN_ANGLE = 3; */ Blockly.Workspace.prototype.addTopBlock = function(block) { this.topBlocks_.push(block); + if (this.isFlyout) { + var variables = Blockly.Variables.allVariables(block); + for (var i = 0; i < variables.length; i++) { + if (this.variableList.indexOf(variables[i]) == -1) { + this.variableList.push(variables[i]); + } + } + } }; /** @@ -181,6 +195,40 @@ Blockly.Workspace.prototype.clear = function() { if (!existingGroup) { Blockly.Events.setGroup(false); } + + this.variableList.length = 0; +}; + +/** + * Walk the workspace and update the list of variables to only contain ones in + * use on the workspace. Use when loading new workspaces from disk. + */ +Blockly.Workspace.prototype.updateVariableList = function() { + // TODO: Sort + if (!this.isFlyout) { + // Update the list in place so that the flyout's references stay correct. + this.variableList.length = 0; + var allVariables = Blockly.Variables.allVariables(this); + for (var i = 0; i < allVariables.length; i++) { + this.variableList.push(allVariables[i]); + } + } +}; + +/** + * Rename a variable by updating its name in the variable list. + * @param {string} oldName Variable to rename. + * @param {string} newName New variable name. + */ +Blockly.Workspace.prototype.renameVariable = function(oldName, newName) { + // Find the old name in the list and replace it. + var variableIndex = this.variableList.indexOf(oldName); + if (variableIndex != -1) { + this.variableList[variableIndex] = newName; + } else { + this.variableList.push(newName); + console.log('Tried to rename an non-existent variable.'); + } }; /** diff --git a/core/xml.js b/core/xml.js index 70fd915a5..cd21298f8 100644 --- a/core/xml.js +++ b/core/xml.js @@ -313,6 +313,8 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) { Blockly.Events.setGroup(false); } Blockly.Field.stopCache(); + + workspace.updateVariableList(); }; /** diff --git a/generators/dart.js b/generators/dart.js index f0d7715ea..cb91dbfd9 100644 --- a/generators/dart.js +++ b/generators/dart.js @@ -90,7 +90,7 @@ Blockly.Dart.init = function(workspace) { } var defvars = []; - var variables = Blockly.Variables.allVariables(workspace); + var variables = workspace.variableList; if (variables.length) { for (var i = 0; i < variables.length; i++) { defvars[i] = Blockly.Dart.variableDB_.getName(variables[i], diff --git a/generators/javascript.js b/generators/javascript.js index dcd1f146d..ff50db982 100644 --- a/generators/javascript.js +++ b/generators/javascript.js @@ -159,7 +159,7 @@ Blockly.JavaScript.init = function(workspace) { } var defvars = []; - var variables = Blockly.Variables.allVariables(workspace); + var variables = workspace.variableList; if (variables.length) { for (var i = 0; i < variables.length; i++) { defvars[i] = Blockly.JavaScript.variableDB_.getName(variables[i], diff --git a/generators/php/procedures.js b/generators/php/procedures.js index 1fd4cc872..c5ef5ea6d 100644 --- a/generators/php/procedures.js +++ b/generators/php/procedures.js @@ -31,7 +31,7 @@ goog.require('Blockly.PHP'); Blockly.PHP['procedures_defreturn'] = function(block) { // Define a procedure with a return value. // First, add a 'global' statement for every variable that is assigned. - var globals = Blockly.Variables.allVariables(block); + var globals = block.workspace.variableList; for (var i = globals.length - 1; i >= 0; i--) { var varName = globals[i]; if (block.arguments_.indexOf(varName) == -1) { diff --git a/generators/python.js b/generators/python.js index 2e77c0753..60a654f28 100644 --- a/generators/python.js +++ b/generators/python.js @@ -129,7 +129,7 @@ Blockly.Python.init = function(workspace) { } var defvars = []; - var variables = Blockly.Variables.allVariables(workspace); + var variables = workspace.variableList; for (var i = 0; i < variables.length; i++) { defvars[i] = Blockly.Python.variableDB_.getName(variables[i], Blockly.Variables.NAME_TYPE) + ' = None'; diff --git a/generators/python/procedures.js b/generators/python/procedures.js index daa7386aa..0d000d050 100644 --- a/generators/python/procedures.js +++ b/generators/python/procedures.js @@ -32,7 +32,7 @@ goog.require('Blockly.Python'); Blockly.Python['procedures_defreturn'] = function(block) { // Define a procedure with a return value. // First, add a 'global' statement for every variable that is assigned. - var globals = Blockly.Variables.allVariables(block); + var globals = block.workspace.variableList; for (var i = globals.length - 1; i >= 0; i--) { var varName = globals[i]; if (block.arguments_.indexOf(varName) == -1) {