From a67f841671dd5d61647ea4f159350e5823b69e69 Mon Sep 17 00:00:00 2001 From: picklesrus Date: Mon, 29 Feb 2016 12:52:38 -0800 Subject: [PATCH 01/14] Replace the call to getBBox() in getMainWorkspaceMetrics with a manual calculation. getBBox() can cause the browser to re-layout the whole page and we have much of the information (e.g. individual block height and width) we need already cached. Note that getBoundingRectangle's calculation is slightly different than the one returned by getBBox. It is off by 3 in the y direction due to how one of the curves is drawn. This new calculation is technically more accurate. --- core/block_svg.js | 29 +++++++++++++++++++++++++++++ core/blockly.js | 8 ++------ core/workspace_svg.js | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/core/block_svg.js b/core/block_svg.js index b351800c8f..4a1f79be17 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -348,6 +348,35 @@ Blockly.BlockSvg.prototype.getHeightWidth = function() { return {height: height, width: width}; }; +/** + * Returns the coordinates of a bounding box describing the dimensions of this block + * and any blocks stacked below it. + * @return {!{topLeft: goog.math.Coordinate, bottomRight: goog.math.Coordinate}} + * Object with top left and bottom right coordinates of the bounding box. + */ +Blockly.BlockSvg.prototype.getBoundingRectangle = function() { + var blockXY = this.getRelativeToSurfaceXY(this); + var tab = this.outputConnection ? Blockly.BlockSvg.TAB_WIDTH : 0; + var blockBounds = this.getHeightWidth(); + var topLeft; + var bottomRight; + if (this.RTL) { + // Width has the tab built into it already so subtract it here. + topLeft = new goog.math.Coordinate(blockXY.x - (blockBounds.width - tab), blockXY.y); + // Add the width of the tab/puzzle piece knob to the x coordinate + // since X is the corner of the rectangle, not the whole puzzle piece. + bottomRight = new goog.math.Coordinate(blockXY.x + tab, blockXY.y + blockBounds.height); + } else { + // Subtract the width of the tab/puzzle piece knob to the x coordinate + // since X is the corner of the rectangle, not the whole puzzle piece. + topLeft = new goog.math.Coordinate(blockXY.x - tab, blockXY.y); + // Width has the tab built into it already so subtract it here. + bottomRight = new goog.math.Coordinate(blockXY.x + blockBounds.width - tab, + blockXY.y + blockBounds.height); + } + return { topLeft : topLeft, bottomRight : bottomRight }; +}; + /** * Set whether the block is collapsed or not. * @param {boolean} collapsed True if collapsed. diff --git a/core/blockly.js b/core/blockly.js index d982503465..8c0cf9fb14 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -521,12 +521,8 @@ Blockly.getMainWorkspaceMetrics_ = function() { var MARGIN = Blockly.Flyout.prototype.CORNER_RADIUS - 1; var viewWidth = svgSize.width - MARGIN; var viewHeight = svgSize.height - MARGIN; - try { - var blockBox = this.getCanvas().getBBox(); - } catch (e) { - // Firefox has trouble with hidden elements (Bug 528969). - return null; - } + var blockBox = this.getBlocksBoundingBox(); + // Fix scale. var contentWidth = blockBox.width * this.scale; var contentHeight = blockBox.height * this.scale; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 273c04d3a5..52eabd6a06 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -660,6 +660,46 @@ Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) { e.preventDefault(); }; +/** + * Calculate the bounding box for the blocks on the workspace. + * + * @return {Object} Contains the position and size of the bounding box + * containing the blocks on the workspace. + */ +Blockly.WorkspaceSvg.prototype.getBlocksBoundingBox = function() { + var topBlocks = this.getTopBlocks(); + // There are no blocks, return empty rectangle. + if (topBlocks.length <= 0) { + return {x: 0, y: 0, width: 0, height: 0}; + } + + // Initialize boundary using the first block. + var boundary = topBlocks[0].getBoundingRectangle(); + + // Start at 1 since the 0th block was used for initialization + for (var i = 1; i < topBlocks.length; i++) { + var blockBoundary = topBlocks[i].getBoundingRectangle(); + if (blockBoundary.topLeft.x < boundary.topLeft.x) { + boundary.topLeft.x = blockBoundary.topLeft.x; + } + if (blockBoundary.bottomRight.x > boundary.bottomRight.x) { + boundary.bottomRight.x = blockBoundary.bottomRight.x + } + if (blockBoundary.topLeft.y < boundary.topLeft.y) { + boundary.topLeft.y = blockBoundary.topLeft.y; + } + if (blockBoundary.bottomRight.y > boundary.bottomRight.y) { + boundary.bottomRight.y = blockBoundary.bottomRight.y; + } + } + return { + x: boundary.topLeft.x, + y: boundary.topLeft.y, + width: boundary.bottomRight.x - boundary.topLeft.x, + height: boundary.bottomRight.y - boundary.topLeft.y + }; +}; + /** * Clean up the workspace by ordering all the blocks in a column. * @private From 23df4765c0563ee9c63247b648cd899da7ec2c39 Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Fri, 11 Mar 2016 11:41:02 -0800 Subject: [PATCH 02/14] fix test --- tests/jsunit/connection_test.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/jsunit/connection_test.js b/tests/jsunit/connection_test.js index b4448b0831..e0b91efee1 100644 --- a/tests/jsunit/connection_test.js +++ b/tests/jsunit/connection_test.js @@ -51,6 +51,7 @@ function connectionTest_tearDown() { dummyWorkspace = null; } +var isMovableFn = function() { return true; }; /** * These tests check that the reasons for failures to connect are consistent * (internal view of error states). @@ -67,10 +68,10 @@ function testCanConnectWithReason_TargetNull() { function testCanConnectWithReason_Disconnect() { connectionTest_setUp(); - var tempConnection = new Blockly.Connection({workspace: dummyWorkspace}, + var tempConnection = new Blockly.Connection({workspace: dummyWorkspace, isMovable: isMovableFn}, Blockly.OUTPUT_VALUE); - Blockly.Connection.connectReciprocally(input, tempConnection); - assertEquals(Blockly.Connection.REASON_MUST_DISCONNECT, + Blockly.Connection.connectReciprocally_(input, tempConnection); + assertEquals(Blockly.Connection.CAN_CONNECT, input.canConnectWithReason_(output)); connectionTest_tearDown(); @@ -270,7 +271,7 @@ function test_isConnectionAllowed() { var four = helper_createConnection(0, 0, Blockly.INPUT_VALUE); four.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace); - Blockly.Connection.connectReciprocally(three, four); + Blockly.Connection.connectReciprocally_(three, four); assertFalse(one.isConnectionAllowed(three, 20.0)); // Don't connect two connections on the same block. @@ -286,4 +287,4 @@ function testCheckConnection_Okay() { output.checkConnection_(input); connectionTest_tearDown(); -} \ No newline at end of file +} From f978826f77ef8e4cd823b03ca9d6f89fea230e7e Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Thu, 10 Mar 2016 15:23:15 -0800 Subject: [PATCH 03/14] Require ConnectionDB where needed; recompile --- blockly_compressed.js | 37 +- blockly_uncompressed.js | 2845 ++++++++++++++++++++------------------- core/workspace_svg.js | 1 + 3 files changed, 1447 insertions(+), 1436 deletions(-) diff --git a/blockly_compressed.js b/blockly_compressed.js index 369b0dea30..748f23b39f 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -856,9 +856,9 @@ Blockly.Workspace=function(a){this.id=Blockly.genUid();Blockly.Workspace.Workspa 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.prototype.getTopBlocks=function(a){var b=[].concat(this.topBlocks_);if(a&&1this.MAX_UNDO&&this.undoStack_.unshift());for(var b=0,c;c=this.listeners_[b];b++)c(a)};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.addChangeListener=Blockly.Workspace.prototype.addChangeListener; -Blockly.Workspace.prototype.removeChangeListener=Blockly.Workspace.prototype.removeChangeListener;Blockly.Bubble=function(a,b,c,d,e,f,g){this.workspace_=a;this.content_=b;this.shape_=c;c=Blockly.Bubble.ARROW_ANGLE;this.workspace_.RTL&&(c=-c);this.arrow_radians_=goog.math.toRadians(c);a.getBubbleCanvas().appendChild(this.createDom_(b,!(!f||!g)));this.setAnchorLocation(d,e);f&&g||(b=this.content_.getBBox(),f=b.width+2*Blockly.Bubble.BORDER_WIDTH,g=b.height+2*Blockly.Bubble.BORDER_WIDTH);this.setBubbleSize(f,g);this.positionBubble_();this.renderArrow_();this.rendered_=!0;a.options.readOnly||(Blockly.bindEvent_(this.bubbleBack_, +Blockly.Workspace.prototype.undo=function(a){var b=a?this.redoStack_:this.undoStack_,c=b.pop();if(c){for(var d=[c];b.length&&c.group&&c.group==b[b.length-1].group;)d.push(b.pop());d=Blockly.Events.filter(d);Blockly.Events.recordUndo=!1;for(b=0;c=d[b];b++)c.run(a),(a?this.undoStack_:this.redoStack_).push(c);Blockly.Events.recordUndo=!0}};Blockly.Workspace.prototype.addChangeListener=function(a){this.listeners_.push(a);return a}; +Blockly.Workspace.prototype.removeChangeListener=function(a){a=this.listeners_.indexOf(a);-1!=a&&this.listeners_.splice(a,1)};Blockly.Workspace.prototype.fireChangeListener=function(a){a.recordUndo&&(this.undoStack_.push(a),this.redoStack_.length=0,this.undoStack_.length>this.MAX_UNDO&&this.undoStack_.unshift());for(var b=0,c;c=this.listeners_[b];b++)c(a)};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.addChangeListener=Blockly.Workspace.prototype.addChangeListener;Blockly.Workspace.prototype.removeChangeListener=Blockly.Workspace.prototype.removeChangeListener;Blockly.Bubble=function(a,b,c,d,e,f,g){this.workspace_=a;this.content_=b;this.shape_=c;c=Blockly.Bubble.ARROW_ANGLE;this.workspace_.RTL&&(c=-c);this.arrow_radians_=goog.math.toRadians(c);a.getBubbleCanvas().appendChild(this.createDom_(b,!(!f||!g)));this.setAnchorLocation(d,e);f&&g||(b=this.content_.getBBox(),f=b.width+2*Blockly.Bubble.BORDER_WIDTH,g=b.height+2*Blockly.Bubble.BORDER_WIDTH);this.setBubbleSize(f,g);this.positionBubble_();this.renderArrow_();this.rendered_=!0;a.options.readOnly||(Blockly.bindEvent_(this.bubbleBack_, "mousedown",this,this.bubbleMouseDown_),this.resizeGroup_&&Blockly.bindEvent_(this.resizeGroup_,"mousedown",this,this.resizeMouseDown_))};Blockly.Bubble.BORDER_WIDTH=6;Blockly.Bubble.ARROW_THICKNESS=10;Blockly.Bubble.ARROW_ANGLE=20;Blockly.Bubble.ARROW_BEND=4;Blockly.Bubble.ANCHOR_RADIUS=8;Blockly.Bubble.onMouseUpWrapper_=null;Blockly.Bubble.onMouseMoveWrapper_=null; Blockly.Bubble.unbindDragEvents_=function(){Blockly.Bubble.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Bubble.onMouseUpWrapper_),Blockly.Bubble.onMouseUpWrapper_=null);Blockly.Bubble.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Bubble.onMouseMoveWrapper_),Blockly.Bubble.onMouseMoveWrapper_=null)};Blockly.Bubble.prototype.rendered_=!1;Blockly.Bubble.prototype.anchorX_=0;Blockly.Bubble.prototype.anchorY_=0;Blockly.Bubble.prototype.relativeLeft_=0;Blockly.Bubble.prototype.relativeTop_=0; Blockly.Bubble.prototype.width_=0;Blockly.Bubble.prototype.height_=0;Blockly.Bubble.prototype.autoLayout_=!0; @@ -945,7 +945,12 @@ Blockly.FieldLabel.prototype.dispose=function(){goog.dom.removeNode(this.textEle Blockly.Input.prototype.appendField=function(a,b){if(!a&&!b)return this;goog.isString(a)&&(a=new Blockly.FieldLabel(a));this.sourceBlock_.rendered&&a.init(this.sourceBlock_);a.name=b;a.prefixField&&this.appendField(a.prefixField);this.fieldRow.push(a);a.suffixField&&this.appendField(a.suffixField);this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours_());return this}; Blockly.Input.prototype.appendTitle=function(a,b){console.warn("Deprecated call to appendTitle, use appendField instead.");return this.appendField(a,b)};Blockly.Input.prototype.removeField=function(a){for(var b=0,c;c=this.fieldRow[b];b++)if(c.name===a){c.dispose();this.fieldRow.splice(b,1);this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours_());return}goog.asserts.fail('Field "%s" not found.',a)};Blockly.Input.prototype.isVisible=function(){return this.visible_}; Blockly.Input.prototype.setVisible=function(a){var b=[];if(this.visible_==a)return b;for(var c=(this.visible_=a)?"block":"none",d=0,e;e=this.fieldRow[d];d++)e.setVisible(a);this.connection&&(a?b=this.connection.unhideAll():this.connection.hideAll(),d=this.connection.targetBlock())&&(d.getSvgRoot().style.display=c,a||(d.rendered=!1));return b};Blockly.Input.prototype.setCheck=function(a){if(!this.connection)throw"This input does not have a connection.";this.connection.setCheck(a);return this}; -Blockly.Input.prototype.setAlign=function(a){this.align=a;this.sourceBlock_.rendered&&this.sourceBlock_.render();return this};Blockly.Input.prototype.init=function(){if(this.sourceBlock_.workspace.rendered)for(var a=0;a=this.length)return-1;for(var c=a.y_,d=b;0<=d&&this[d].y_==c;){if(this[d]==a)return d;d--}for(;ba.y_)c=d;else{b=d;break}}return b};Blockly.ConnectionDB.prototype.removeConnection_=function(a){if(!a.inDB_)throw"Connection not in database.";var b=this.findConnection(a);if(-1==b)throw"Unable to find connection in connectionDB.";a.inDB_=!1;this.splice(b,1)}; +Blockly.ConnectionDB.prototype.getNeighbours=function(a,b){function c(a){var c=e-d[a].x_,g=f-d[a].y_;Math.sqrt(c*c+g*g)<=b&&l.push(d[a]);return gd.y+e.height&&c.moveBy(0,20-e.height-d.y)}this.rootBlock_.workspace==this.workspace_&&(a=(a=this.block_.mutationToDom())&&Blockly.Xml.domToText(a),b=this.block_.rendered,this.block_.rendered=!1,this.block_.compose(this.rootBlock_),this.block_.rendered=b,this.block_.initSvg(),b=(b=this.block_.mutationToDom())&& -Blockly.Xml.domToText(b),a!=b&&(Blockly.Events.fire(new Blockly.Events.Change(this.block_,"mutation",null,a,b)),goog.Timer.callOnce(this.block_.bumpNeighbours_,Blockly.BUMP_DELAY,this.block_)),this.block_.rendered&&this.block_.render(),this.resizeBubble_())};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.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.workspaceChanged_=function(){if(0==Blockly.dragMode_)for(var a=this.workspace_.getTopBlocks(!1),b=0,c;c=a[b];b++){var d=c.getRelativeToSurfaceXY(),e=c.getHeightWidth();20>d.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.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.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"+a+""),b.domToMutation(a.firstChild))}}; -Blockly.Events.Move=function(a){Blockly.Events.Move.superClass_.constructor.call(this,a);a=this.currentLocation_();this.oldParentId=a.parentId;this.oldInputName=a.inputName;this.oldCoordinate=a.coordinate};goog.inherits(Blockly.Events.Move,Blockly.Events.Abstract);Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate}; -Blockly.Events.Move.prototype.currentLocation_=function(){var a=Blockly.Block.getById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b};Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&goog.math.Coordinate.equals(this.oldCoordinate,this.newCoordinate)}; -Blockly.Events.Move.prototype.run=function(a){var b=Blockly.Block.getById(this.blockId);if(b){var c=a?this.newParentId:this.oldParentId,d=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var e=null;if(c&&(e=Blockly.Block.getById(c),!e))return;b.getParent()&&b.unplug();if(a){var f=b.getRelativeToSurfaceXY();b.moveBy(a.x-f.x,a.y-f.y)}else{b=b.outputConnection||b.previousConnection;if(d){if(d=e.getInput(d))f=d.connection}else b.type==Blockly.PREVIOUS_STATEMENT&&(f=e.nextConnection); -f&&b.connect(f)}}};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)}; +Blockly.Events.Change.prototype.run=function(a){var b=Blockly.Block.getById(this.blockId);if(b)switch(a=a?this.newValue:this.oldValue,this.element){case "field":(b=b.getField(this.name))?b.setValue(a):console.warn("Can't set non-existant field: "+this.name);break;case "comment":b.setCommentText(a||null);break;case "collapsed":b.setCollapsed(a);break;case "disabled":b.setDisabled(a);break;case "inline":b.setInputsInline(a);break;case "mutation":b.mutator&&b.mutator.setVisible(!1);var c="";b.mutationToDom&& +(c=(c=b.mutationToDom())&&Blockly.Xml.domToText(c));if(b.domToMutation){var d=Blockly.Xml.textToDom(""+a+"");b.domToMutation(d.firstChild)}Blockly.Events.fire(new Blockly.Events.Change(b,"mutation",null,c,a))}};Blockly.Events.Move=function(a){Blockly.Events.Move.superClass_.constructor.call(this,a);a=this.currentLocation_();this.oldParentId=a.parentId;this.oldInputName=a.inputName;this.oldCoordinate=a.coordinate};goog.inherits(Blockly.Events.Move,Blockly.Events.Abstract); +Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate};Blockly.Events.Move.prototype.currentLocation_=function(){var a=Blockly.Block.getById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b}; +Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&goog.math.Coordinate.equals(this.oldCoordinate,this.newCoordinate)}; +Blockly.Events.Move.prototype.run=function(a){var b=Blockly.Block.getById(this.blockId);if(b){var c=a?this.newParentId:this.oldParentId,d=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var e=null;if(c&&(e=Blockly.Block.getById(c),!e))return;b.getParent()&&b.unplug();if(a)d=b.getRelativeToSurfaceXY(),b.moveBy(a.x-d.x,a.y-d.y);else{var b=b.outputConnection||b.previousConnection,f;d?(c=e.getInput(d))?f=c.connection:console.warn("Can't connect to non-existant input: "+ +d):b.type==Blockly.PREVIOUS_STATEMENT&&(f=e.nextConnection);f&&b.connect(f)}}};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)}; Blockly.FieldTextInput.prototype.setValue=function(a){if(null!==a){if(this.sourceBlock_&&this.validator_){var b=this.validator_(a);null!==b&&void 0!==b&&(a=b)}Blockly.Field.prototype.setValue.call(this,a)}};Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a}; Blockly.FieldTextInput.prototype.showEditor_=function(a){var b=this.sourceBlock_.workspace;a=a||!1;if(!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD))b=window.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_),this.sourceBlock_&&this.validator_&&(a=this.validator_(b),void 0!==a&&(b=a)),this.setValue(b);else{Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,this.widgetDispose_());var c=Blockly.WidgetDiv.DIV,d=goog.dom.createDom("input","blocklyHtmlInput");d.setAttribute("spellcheck", this.spellcheck_);var e=Blockly.FieldTextInput.FONTSIZE*b.scale+"pt";c.style.fontSize=e;d.style.fontSize=e;Blockly.FieldTextInput.htmlInput_=d;c.appendChild(d);d.value=d.defaultValue=this.text_;d.oldValue_=null;this.validate_();this.resizeEditor_();a||(d.focus(),d.select());d.onKeyDownWrapper_=Blockly.bindEvent_(d,"keydown",this,this.onHtmlInputKeyDown_);d.onKeyUpWrapper_=Blockly.bindEvent_(d,"keyup",this,this.onHtmlInputChange_);d.onKeyPressWrapper_=Blockly.bindEvent_(d,"keypress",this,this.onHtmlInputChange_); @@ -1219,7 +1226,7 @@ Blockly.FieldDropdown.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner Blockly.FieldImage.prototype.init=function(a){this.sourceBlock_||(this.sourceBlock_=a,this.fieldGroup_=Blockly.createSvgElement("g",{},null),this.visible_||(this.fieldGroup_.style.display="none"),this.imageElement_=Blockly.createSvgElement("image",{height:this.height_+"px",width:this.width_+"px"},this.fieldGroup_),this.setValue(this.src_),goog.userAgent.GECKO&&(this.rectElement_=Blockly.createSvgElement("rect",{height:this.height_+"px",width:this.width_+"px","fill-opacity":0},this.fieldGroup_)),a.getSvgRoot().appendChild(this.fieldGroup_), a=this.rectElement_||this.imageElement_,a.tooltip=this.sourceBlock_,Blockly.Tooltip.bindMouseEvents(a))};Blockly.FieldImage.prototype.dispose=function(){goog.dom.removeNode(this.fieldGroup_);this.rectElement_=this.imageElement_=this.fieldGroup_=null};Blockly.FieldImage.prototype.setTooltip=function(a){(this.rectElement_||this.imageElement_).tooltip=a};Blockly.FieldImage.prototype.getValue=function(){return this.src_}; Blockly.FieldImage.prototype.setValue=function(a){null!==a&&(this.src_=a,this.imageElement_&&this.imageElement_.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",goog.isString(a)?a:""))};Blockly.FieldImage.prototype.setText=function(a){null!==a&&(this.text_=a)};Blockly.FieldImage.prototype.render_=function(){};Blockly.Variables={};Blockly.Variables.NAME_TYPE="VARIABLE";Blockly.Variables.allVariables=function(a){var b;if(a.getDescendants)b=a.getDescendants();else if(a.getAllBlocks)b=a.getAllBlocks();else throw"Not Block or Workspace: "+a;a=Object.create(null);for(var c=0;c Date: Fri, 11 Mar 2016 13:13:34 -0800 Subject: [PATCH 04/14] Fix search for closest --- core/connection.js | 8 +------- core/connection_db.js | 11 +++++++---- tests/jsunit/connection_db_test.js | 3 ++- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/core/connection.js b/core/connection.js index 81017f21c5..4db07585f1 100644 --- a/core/connection.js +++ b/core/connection.js @@ -645,13 +645,7 @@ Blockly.Connection.prototype.tighten_ = function() { * and 'radius' which is the distance. */ Blockly.Connection.prototype.closest = function(maxLimit, dx, dy) { - var closestConnection = this.dbOpposite_.searchForClosest(this, maxLimit, dx, - dy); - if (closestConnection) { - return {connection: closestConnection, - radius: this.distanceFrom(closestConnection)}; - } - return {connection: null, radius: maxLimit}; + return this.dbOpposite_.searchForClosest(this, maxLimit, dx, dy); }; /** diff --git a/core/connection_db.js b/core/connection_db.js index b64c5e23ac..b1c85b1b33 100644 --- a/core/connection_db.js +++ b/core/connection_db.js @@ -221,14 +221,15 @@ Blockly.ConnectionDB.prototype.isInYRange_ = function(index, baseY, maxRadius) { * in the database and the current location (as a result of dragging). * @param {number} dy Vertical offset between this connection's location * in the database and the current location (as a result of dragging). - * @return ?Blockly.Connection the closest valid connection. - * another connection or null, and 'radius' which is the distance. + * @return {!{connection: ?Blockly.Connection, radius: number}} Contains two + * properties:' connection' which is either another connection or null, + * and 'radius' which is the distance. */ Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius, dx, dy) { // Don't bother. if (!this.length) { - return null; + return {connection: null, radius: maxRadius}; } // Stash the values of x and y from before the drag. @@ -273,7 +274,9 @@ Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius, dx, // Reset the values of x and y. conn.x_ = baseX; conn.y_ = baseY; - return bestConnection; + + // If there were no valid connections, bestConnection will be null. + return {connection: bestConnection, radius: bestRadius}; }; /** diff --git a/tests/jsunit/connection_db_test.js b/tests/jsunit/connection_db_test.js index 0e7b334011..67f6eeb5db 100644 --- a/tests/jsunit/connection_db_test.js +++ b/tests/jsunit/connection_db_test.js @@ -260,7 +260,8 @@ function helper_searchDB(db, x, y, radius, shared_workspace) { var tempConn = helper_createConnection(x, y, Blockly.NEXT_STATEMENT, shared_workspace); tempConn.sourceBlock_ = helper_makeSourceBlock(shared_workspace); - return db.searchForClosest(tempConn, radius, 0, 0); + var closest = db.searchForClosest(tempConn, radius, 0, 0); + return closest.connection; } function helper_makeSourceBlock(sharedWorkspace) { From 4ae34599e032b7bf03b991d70003043771738b1c Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Fri, 11 Mar 2016 17:38:59 -0800 Subject: [PATCH 05/14] Don't connect a block with no next connection if that would force a bump. --- core/connection.js | 8 ++++++++ tests/jsunit/connection_test.js | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/core/connection.js b/core/connection.js index 4db07585f1..1e38fe42cc 100644 --- a/core/connection.js +++ b/core/connection.js @@ -373,6 +373,14 @@ Blockly.Connection.prototype.isConnectionAllowed = function(candidate, return false; } + // Don't let a block with no next connection bump other blocks out of the + // stack. + if (this.type == Blockly.PREVIOUS_STATEMENT && + candidate.targetConnection && + !this.sourceBlock_.nextConnection) { + return false; + } + // Don't let blocks try to connect to themselves or ones they nest. var targetSourceBlock = candidate.sourceBlock_; var sourceBlock = this.sourceBlock_; diff --git a/tests/jsunit/connection_test.js b/tests/jsunit/connection_test.js index e0b91efee1..c9ad00daee 100644 --- a/tests/jsunit/connection_test.js +++ b/tests/jsunit/connection_test.js @@ -279,6 +279,25 @@ function test_isConnectionAllowed() { assertFalse(one.isConnectionAllowed(two, 1000.0)); } +function test_isConnectionAllowed_NoNext() { + var sharedWorkspace = {}; + var one = helper_createConnection(0, 0, Blockly.NEXT_STATEMENT); + one.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace); + one.sourceBlock_.nextConnection = one; + + var two = helper_createConnection(0, 0, Blockly.PREVIOUS_STATEMENT); + two.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace); + + assertTrue(two.isConnectionAllowed(one, 1000.0)); + + var three = helper_createConnection(0, 0, Blockly.PREVIOUS_STATEMENT); + three.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace); + three.sourceBlock_.previousConnection = three; + Blockly.Connection.connectReciprocally_(one, three); + + assertFalse(two.isConnectionAllowed(one, 1000.0)); +} + function testCheckConnection_Okay() { connectionTest_setUp(); previous.checkConnection_(next); From 74ea1f1ffee0d4475b9a546acb896026ae4ef293 Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Fri, 11 Mar 2016 18:07:26 -0800 Subject: [PATCH 06/14] consider the last block on the stack when looking for places to attach a dragging stack. --- core/block.js | 19 +++++++++++++++++++ core/block_svg.js | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/core/block.js b/core/block.js index 1fd24d0b01..7bc90abd03 100644 --- a/core/block.js +++ b/core/block.js @@ -278,6 +278,25 @@ Blockly.Block.prototype.getConnections_ = function(all) { return myConnections; }; +/** + * Walks down a stack of blocks and finds the last next connection on the stack. + * @return {Blockly.Connection} The last next connection on the stack, or null. + * @private + */ +Blockly.Block.prototype.lastConnectionInStack_ = function() { + var nextConnection = this.nextConnection; + while (nextConnection) { + var nextBlock = nextConnection.targetBlock(); + if (!nextBlock) { + // Found a next connection with nothing on the other side. + return nextConnection; + } + nextConnection = nextBlock.nextConnection; + } + // Ran out of next connections. + return null; +}; + /** * Bump unconnected blocks out of alignment. Two blocks which aren't actually * connected should not coincidentally line up on screen. diff --git a/core/block_svg.js b/core/block_svg.js index dec74441ae..094615fcef 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -822,6 +822,11 @@ Blockly.BlockSvg.prototype.onMouseMove_ = function(e) { // Check to see if any of this block's connections are within range of // another block's connection. var myConnections = this.getConnections_(false); + // Also check the last connection on this stack + var lastOnStack = this.lastConnectionInStack_(); + if (lastOnStack && lastOnStack != this.nextConnection) { + myConnections.push(lastOnStack); + } var closestConnection = null; var localConnection = null; var radiusConnection = Blockly.SNAP_RADIUS; From 9ce81a24aa3d4af8a00878d5604552eb66acc1e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Laxstr=C3=B6m?= Date: Mon, 14 Mar 2016 08:05:02 +0100 Subject: [PATCH 07/14] Localisation updates from https://translatewiki.net. --- msg/json/fr.json | 23 ++++++++++++----------- msg/json/pt.json | 5 +++-- msg/json/qqq.json | 2 +- msg/json/sr.json | 21 ++++++++++++++++++--- msg/json/zh-hant.json | 22 +++++++++++++++++----- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/msg/json/fr.json b/msg/json/fr.json index efcc495b94..2d2da429cc 100644 --- a/msg/json/fr.json +++ b/msg/json/fr.json @@ -7,7 +7,8 @@ "Wladek92", "Fredlefred", "Grimault", - "Rixed" + "Rixed", + "Frigory" ] }, "VARIABLES_DEFAULT_NAME": "élément", @@ -28,14 +29,14 @@ "DISABLE_BLOCK": "Désactiver le bloc", "ENABLE_BLOCK": "Activer le bloc", "HELP": "Aide", - "CHAT": "Discuter avec votre collaborateur en tapant dans cette zone !", + "CHAT": "Discutez avec votre collaborateur en tapant dans cette zone !", "AUTH": "Veuillez autoriser cette application à permettre la sauvegarde de votre travail et à l’autoriser à la partager.", "ME": "Moi", "CHANGE_VALUE_TITLE": "Modifier la valeur :", "NEW_VARIABLE": "Nouvelle variable…", "NEW_VARIABLE_TITLE": "Nom de la nouvelle variable :", "RENAME_VARIABLE": "Renommer la variable…", - "RENAME_VARIABLE_TITLE": "Renommer toutes les variables '%1' en :", + "RENAME_VARIABLE_TITLE": "Renommer toutes les variables « %1 » en :", "COLOUR_PICKER_HELPURL": "https://fr.wikipedia.org/wiki/Couleur", "COLOUR_PICKER_TOOLTIP": "Choisir une couleur dans la palette.", "COLOUR_RANDOM_TITLE": "couleur aléatoire", @@ -45,7 +46,7 @@ "COLOUR_RGB_RED": "rouge", "COLOUR_RGB_GREEN": "vert", "COLOUR_RGB_BLUE": "bleu", - "COLOUR_RGB_TOOLTIP": "Créer une couleur avec la quantité spécifiée de rouge, vert et bleu. Ces valeurs doivent être comprises entre 0 et 100.", + "COLOUR_RGB_TOOLTIP": "Créer une couleur avec la quantité spécifiée de rouge, vert et bleu. Les valeurs doivent être comprises entre 0 et 100.", "COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/", "COLOUR_BLEND_TITLE": "mélanger", "COLOUR_BLEND_COLOUR1": "couleur 1", @@ -55,17 +56,17 @@ "CONTROLS_REPEAT_HELPURL": "http://fr.wikipedia.org/wiki/Boucle_for", "CONTROLS_REPEAT_TITLE": "répéter %1 fois", "CONTROLS_REPEAT_INPUT_DO": "faire", - "CONTROLS_REPEAT_TOOLTIP": "Exécuter certains ordres plusieurs fois.", + "CONTROLS_REPEAT_TOOLTIP": "Exécuter des instructions plusieurs fois.", "CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "répéter tant que", "CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "répéter jusqu’à", - "CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Tant qu’une valeur est vraie, alors exécuter certains ordres.", - "CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Tant qu’une valeur est fausse, alors exécuter certains ordres.", - "CONTROLS_FOR_TOOLTIP": "Faire en sorte que la variable « %1 » prenne ses valeurs depuis le nombre de début jusqu’au nombre de fin, en s’incrémentant de l’intervalle spécifié, et exécuter les ordres spécifiés.", + "CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Tant qu’une valeur est vraie, alors exécuter des instructions.", + "CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Tant qu’une valeur est fausse, alors exécuter des instructions.", + "CONTROLS_FOR_TOOLTIP": "Faire prendre à la variable « %1 » les valeurs depuis le nombre de début jusqu’au nombre de fin, en s’incrémentant du pas spécifié, et exécuter les instructions spécifiées.", "CONTROLS_FOR_TITLE": "compter avec %1 de %2 à %3 par %4", "CONTROLS_FOREACH_TITLE": "pour chaque élément %1 dans la liste %2", - "CONTROLS_FOREACH_TOOLTIP": "Pour chaque élément dans une liste, donner la valeur de l’élément à la variable '%1', puis exécuter certains ordres.", - "CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "sortir de la boucle", - "CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continuer avec la prochaine itération de la boucle", + "CONTROLS_FOREACH_TOOLTIP": "Pour chaque élément d’une liste, assigner la valeur de l’élément à la variable '%1', puis exécuter des instructions.", + "CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "quitter la boucle", + "CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "passer à l’itération de boucle suivante", "CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Sortir de la boucle englobante.", "CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Sauter le reste de cette boucle, et poursuivre avec l’itération suivante.", "CONTROLS_FLOW_STATEMENTS_WARNING": "Attention : Ce bloc ne devrait être utilisé que dans une boucle.", diff --git a/msg/json/pt.json b/msg/json/pt.json index b2472c1eca..5b7a7b89a5 100644 --- a/msg/json/pt.json +++ b/msg/json/pt.json @@ -6,7 +6,8 @@ "Vitorvicentevalente", "아라", "Nicola Nascimento", - "Önni" + "Önni", + "Diniscoelho" ] }, "VARIABLES_DEFAULT_NAME": "item", @@ -247,7 +248,7 @@ "LISTS_INLIST": "na lista", "LISTS_INDEX_OF_FIRST": "encontre a primeira ocorrência do item", "LISTS_INDEX_OF_LAST": "encontre a última ocorrência do item", - "LISTS_INDEX_OF_TOOLTIP": "Retorna a posição da primeira/última ocorrência do item na lista. Retorna 0 se o texto não for encontrado.", + "LISTS_INDEX_OF_TOOLTIP": "Retorna a posição da primeira/última ocorrência do item na lista. Retorna 0 se o item não for encontrado.", "LISTS_GET_INDEX_GET": "obter", "LISTS_GET_INDEX_GET_REMOVE": "obter e remover", "LISTS_GET_INDEX_REMOVE": "remover", diff --git a/msg/json/qqq.json b/msg/json/qqq.json index 703a06a06a..e00b76fa35 100644 --- a/msg/json/qqq.json +++ b/msg/json/qqq.json @@ -90,7 +90,7 @@ "LOGIC_COMPARE_TOOLTIP_GTE": "tooltip - Describes the greater than or equals (≥) block.", "LOGIC_OPERATION_HELPURL": "url - Information about the Boolean conjunction ('and') and disjunction ('or') operators. Consider using the translation of [https://en.wikipedia.org/wiki/Boolean_logic https://en.wikipedia.org/wiki/Boolean_logic], if it exists in your language.", "LOGIC_OPERATION_TOOLTIP_AND": "tooltip - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].", - "LOGIC_OPERATION_AND": "block text - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].", + "LOGIC_OPERATION_AND": "block text - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].\n{{Identical|And}}", "LOGIC_OPERATION_TOOLTIP_OR": "block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].", "LOGIC_OPERATION_OR": "block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].", "LOGIC_NEGATE_HELPURL": "url - Information about logical negation. The translation of [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation] is recommended if it exists in the target language.", diff --git a/msg/json/sr.json b/msg/json/sr.json index 9f00233b60..abd20a4db3 100644 --- a/msg/json/sr.json +++ b/msg/json/sr.json @@ -2,10 +2,12 @@ "@metadata": { "authors": [ "Rancher", - "아라" + "아라", + "Perevod16" ] }, "VARIABLES_DEFAULT_NAME": "ставка", + "TODAY": "Данас", "DUPLICATE_BLOCK": "Дуплирај", "ADD_COMMENT": "Додај коментар", "REMOVE_COMMENT": "Уклони коментар", @@ -14,6 +16,7 @@ "DELETE_BLOCK": "Обриши блок", "DELETE_X_BLOCKS": "Обриши %1 блокова", "DELETE_ALL_BLOCKS": "Обрисати %1 блокова?", + "CLEAN_UP": "Уклоните блокова", "COLLAPSE_BLOCK": "Скупи блок", "COLLAPSE_ALL": "Скупи блокове", "EXPAND_BLOCK": "Прошири блок", @@ -21,6 +24,9 @@ "DISABLE_BLOCK": "Онемогући блок", "ENABLE_BLOCK": "Омогући блок", "HELP": "Помоћ", + "CHAT": "Комуницирају са својим колегом, уносећи у то поље!", + "AUTH": "Пријавите се молим то је апликација да се окрену свој посао, да побегне и да му се омогући да буде заједничко за вас.", + "ME": "Ми", "CHANGE_VALUE_TITLE": "Промените вредност:", "NEW_VARIABLE": "Нова променљива…", "NEW_VARIABLE_TITLE": "Име нове променљиве:", @@ -216,7 +222,7 @@ "TEXT_CHANGECASE_OPERATOR_LOWERCASE": "малим словима", "TEXT_CHANGECASE_OPERATOR_TITLECASE": "свака реч великим словом", "TEXT_TRIM_TOOLTIP": "Враћа копију текста са уклонјеним простором са једног од два краја.", - "TEXT_TRIM_OPERATOR_BOTH": "скратити простор са обе стране", + "TEXT_TRIM_OPERATOR_BOTH": "трим празнине са обе стране", "TEXT_TRIM_OPERATOR_LEFT": "скратити простор са леве стране", "TEXT_TRIM_OPERATOR_RIGHT": "скратити простор са десне стране", "TEXT_PRINT_TITLE": "прикажи %1", @@ -242,7 +248,7 @@ "LISTS_INLIST": "на списку", "LISTS_INDEX_OF_FIRST": "пронађи прво појављивање ставке", "LISTS_INDEX_OF_LAST": "пронађи последње појављивање ставке", - "LISTS_INDEX_OF_TOOLTIP": "Враћа однос првог/последнјег појавлјиванја ставке у листи. Враћа 0 ако се текст не наће.", + "LISTS_INDEX_OF_TOOLTIP": "Враћа број првог и/последњег уласка елемента у листу. Враћа 0 Ако елемент није пронађен.", "LISTS_GET_INDEX_GET": "преузми", "LISTS_GET_INDEX_GET_REMOVE": "преузми и уклони", "LISTS_GET_INDEX_REMOVE": "уклони", @@ -288,6 +294,11 @@ "LISTS_GET_SUBLIST_END_LAST": "до последње", "LISTS_GET_SUBLIST_TAIL": "", "LISTS_GET_SUBLIST_TOOLTIP": "Прави копију одређеног дела листе.", + "LISTS_SPLIT_LIST_FROM_TEXT": "направите листу са текста", + "LISTS_SPLIT_TEXT_FROM_LIST": "да текст из листе", + "LISTS_SPLIT_WITH_DELIMITER": "са раздвајање", + "LISTS_SPLIT_TOOLTIP_SPLIT": "Поделити текст у листу текстова, разбијање на сваком граничник.", + "LISTS_SPLIT_TOOLTIP_JOIN": "Да се придружи листу текстова у један текст, подељених за раздвајање.", "ORDINAL_NUMBER_SUFFIX": "", "VARIABLES_GET_TOOLTIP": "Враћа вредност ове променљиве.", "VARIABLES_GET_CREATE_SET": "Направи „постави %1“", @@ -301,16 +312,20 @@ "PROCEDURES_CALL_BEFORE_PARAMS": "са:", "PROCEDURES_DEFNORETURN_DO": "", "PROCEDURES_DEFNORETURN_TOOLTIP": "Прави функцију без излаза.", + "PROCEDURES_DEFNORETURN_COMMENT": "Описати ову функцију...", "PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29", "PROCEDURES_DEFRETURN_RETURN": "врати", "PROCEDURES_DEFRETURN_TOOLTIP": "Прави функцију са излазом.", + "PROCEDURES_ALLOW_STATEMENTS": "дозволити изреке", "PROCEDURES_DEF_DUPLICATE_WARNING": "Упозорење: Ова функција има дупликате параметара.", "PROCEDURES_CALLNORETURN_HELPURL": "https://sr.wikipedia.org/wiki/Функција_(програмирање)", "PROCEDURES_CALLNORETURN_TOOLTIP": "Покрените прилагођену функцију „%1“.", "PROCEDURES_CALLRETURN_HELPURL": "https://sr.wikipedia.org/wiki/Функција_(програмирање)", "PROCEDURES_CALLRETURN_TOOLTIP": "Покрените прилагођену функцију „%1“ и користи њен излаз.", "PROCEDURES_MUTATORCONTAINER_TITLE": "улази", + "PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Да додате, уклоните или переупорядочить улаза за ову функцију.", "PROCEDURES_MUTATORARG_TITLE": "назив улаза:", + "PROCEDURES_MUTATORARG_TOOLTIP": "Додајте улазна функција.", "PROCEDURES_HIGHLIGHT_DEF": "Истакни дефиницију функције", "PROCEDURES_CREATE_DO": "Направи „%1“", "PROCEDURES_IFRETURN_TOOLTIP": "Уколико је вредност тачна, врати другу вредност.", diff --git a/msg/json/zh-hant.json b/msg/json/zh-hant.json index 80c2e4aed7..a1314c122e 100644 --- a/msg/json/zh-hant.json +++ b/msg/json/zh-hant.json @@ -5,7 +5,8 @@ "Wehwei", "Liuxinyu970226", "LNDDYL", - "Cwlin0416" + "Cwlin0416", + "Kasimtan" ] }, "VARIABLES_DEFAULT_NAME": "變量", @@ -17,7 +18,8 @@ "INLINE_INPUTS": "單行輸入", "DELETE_BLOCK": "刪除積木", "DELETE_X_BLOCKS": "刪除 %1 塊積木", - "DELETE_ALL_BLOCKS": "刪除共 %1 個積木?", + "DELETE_ALL_BLOCKS": "刪除共 %1 塊積木?", + "CLEAN_UP": "清理積木", "COLLAPSE_BLOCK": "收合積木", "COLLAPSE_ALL": "收合積木", "EXPAND_BLOCK": "展開積木", @@ -26,6 +28,7 @@ "ENABLE_BLOCK": "啟用積木", "HELP": "說明", "CHAT": "與您的合作者洽談藉由在此框輸入!", + "AUTH": "請授權這個應用程式以保存您的作品並共享。", "ME": "我", "CHANGE_VALUE_TITLE": "修改值:", "NEW_VARIABLE": "新變量...", @@ -218,7 +221,7 @@ "LISTS_CREATE_EMPTY_TOOLTIP": "返回一個長度為 0 的列表,不包含任何資料記錄", "LISTS_CREATE_WITH_TOOLTIP": "建立一個具備任意數量項目的列表。", "LISTS_CREATE_WITH_INPUT_WITH": "使用這些值建立列表", - "LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "加入", + "LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "列表", "LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "添加、 刪除或重新排列各區塊來此重新配置這個 列表 積木。", "LISTS_CREATE_WITH_ITEM_TOOLTIP": "將一個項目加入到列表中。", "LISTS_REPEAT_TOOLTIP": "建立包含指定重複次數的 值 的列表。", @@ -263,7 +266,7 @@ "LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "設定列表中隨機的一個項目", "LISTS_SET_INDEX_TOOLTIP_INSERT_FROM_START": "插入在列表中的指定位置的項目。#1 是第一個項目。", "LISTS_SET_INDEX_TOOLTIP_INSERT_FROM_END": "插入在列表中的指定位置的項目。#1 是最後一個項目。", - "LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "在列表的起始處添加一個項目。", + "LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "在列表的起始處添加一個項目", "LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "在列表的尾端加入一個項目", "LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "在列表中隨機插入項目", "LISTS_GET_SUBLIST_START_FROM_START": "從 # 取得子列表", @@ -273,8 +276,13 @@ "LISTS_GET_SUBLIST_END_FROM_END": "到 倒數 # 位", "LISTS_GET_SUBLIST_END_LAST": "到 最後", "LISTS_GET_SUBLIST_TOOLTIP": "複製列表中指定的部分。", + "LISTS_SPLIT_LIST_FROM_TEXT": "從文本製作列表", + "LISTS_SPLIT_TEXT_FROM_LIST": "從列表拆出文本", + "LISTS_SPLIT_WITH_DELIMITER": "用分隔符", + "LISTS_SPLIT_TOOLTIP_SPLIT": "拆分文本到文本列表,按每個分隔符拆分。", + "LISTS_SPLIT_TOOLTIP_JOIN": "串起文本列表成一個文本,由分隔符分隔。", "VARIABLES_GET_TOOLTIP": "返回此變量的值。", - "VARIABLES_GET_CREATE_SET": "創立 '設定 %1'", + "VARIABLES_GET_CREATE_SET": "建立 '設定 %1'", "VARIABLES_SET": "賦值 %1 到 %2", "VARIABLES_SET_TOOLTIP": "設定此變量,好和輸入值相等。", "VARIABLES_SET_CREATE_GET": "建立 '取得 %1'", @@ -283,15 +291,19 @@ "PROCEDURES_BEFORE_PARAMS": "與:", "PROCEDURES_CALL_BEFORE_PARAMS": "與:", "PROCEDURES_DEFNORETURN_TOOLTIP": "創建一個無回傳值的函數。", + "PROCEDURES_DEFNORETURN_COMMENT": "描述此函數...", "PROCEDURES_DEFRETURN_RETURN": "回傳", "PROCEDURES_DEFRETURN_TOOLTIP": "創建一個有回傳值的函數。", + "PROCEDURES_ALLOW_STATEMENTS": "允許語句", "PROCEDURES_DEF_DUPLICATE_WARNING": "警告: 此函數中有重複的參數。", "PROCEDURES_CALLNORETURN_HELPURL": "https://zh.wikipedia.org/wiki/子程式", "PROCEDURES_CALLNORETURN_TOOLTIP": "執行使用者定義的函數 '%1'。", "PROCEDURES_CALLRETURN_HELPURL": "https://zh.wikipedia.org/wiki/子程式", "PROCEDURES_CALLRETURN_TOOLTIP": "執行使用者定義的函數 '%1' 並使用它的回傳值", "PROCEDURES_MUTATORCONTAINER_TITLE": "參數", + "PROCEDURES_MUTATORCONTAINER_TOOLTIP": "添加、刪除或重新排列此函數的輸入。", "PROCEDURES_MUTATORARG_TITLE": "變量:", + "PROCEDURES_MUTATORARG_TOOLTIP": "添加函數輸入。", "PROCEDURES_HIGHLIGHT_DEF": "反白顯示函式定義", "PROCEDURES_CREATE_DO": "建立 '%1'", "PROCEDURES_IFRETURN_TOOLTIP": "如果值為 真,則返回第二個值。", From 0aec80a08812555ceede24e15686d807404c7945 Mon Sep 17 00:00:00 2001 From: Rodrigo Queiro Date: Mon, 14 Mar 2016 15:07:30 +0100 Subject: [PATCH 08/14] Add missing comma to Lua reserved words This meant that variables could be called _, conflicting with use in Lua as a dummy variable, and in particular with scrubNakedValue. --- generators/lua.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/lua.js b/generators/lua.js index 885e77c23e..a1265b6694 100644 --- a/generators/lua.js +++ b/generators/lua.js @@ -45,7 +45,7 @@ Blockly.Lua = new Blockly.Generator('Lua'); */ Blockly.Lua.addReservedWords( // Special character - '_' + + '_,' + // From theoriginalbit's script: // https://github.com/espertus/blockly-lua/issues/6 '__inext,assert,bit,colors,colours,coroutine,disk,dofile,error,fs,' + From 37d3ecc304d5ddb14e4452b2f33dc5deb9a76c53 Mon Sep 17 00:00:00 2001 From: Rodrigo Queiro Date: Mon, 14 Mar 2016 15:08:49 +0100 Subject: [PATCH 09/14] Fix JSDoc syntax on Blockly.Lua.lists.getIndex_ Also fix a return type warning in one of the branches. --- generators/lua/lists.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generators/lua/lists.js b/generators/lua/lists.js index 91f2c97342..619f6d8d7f 100644 --- a/generators/lua/lists.js +++ b/generators/lua/lists.js @@ -119,12 +119,12 @@ Blockly.Lua['lists_indexOf'] = function(block) { * @private * @param {string} listname Name of the list, used to calculate length. * @param {string} where The method of indexing, selected by dropdown in Blockly - * @param {=string} opt_at The optional offset when indexing from start/end. + * @param {string=} opt_at The optional offset when indexing from start/end. * @return {string} Index expression. */ Blockly.Lua.lists.getIndex_ = function(listname, where, opt_at) { if (where == 'FIRST') { - return 1; + return '1'; } else if (where == 'FROM_END') { return '#' + listname + ' + 1 - ' + opt_at; } else if (where == 'LAST') { From 8fb1178ed82fd97edd40575ff624332e07c151a2 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Mon, 14 Mar 2016 16:00:25 -0700 Subject: [PATCH 10/14] Update message descriptions. --- core/connection.js | 2 +- core/connection_db.js | 4 ++-- core/events.js | 4 ++-- core/workspace_svg.js | 2 +- msg/messages.js | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/connection.js b/core/connection.js index 1e38fe42cc..eda88eafa9 100644 --- a/core/connection.js +++ b/core/connection.js @@ -816,7 +816,7 @@ Blockly.Connection.prototype.unhideAll = function() { for (var c = 0; c < connections.length; c++) { renderList.push.apply(renderList, connections[c].unhideAll()); } - if (renderList.length == 0) { + if (!renderList.length) { // Leaf block. renderList[0] = block; } diff --git a/core/connection_db.js b/core/connection_db.js index b1c85b1b33..2da1ac703c 100644 --- a/core/connection_db.js +++ b/core/connection_db.js @@ -71,7 +71,7 @@ Blockly.ConnectionDB.prototype.addConnection = function(connection) { * @return The index of the connection, or -1 if the connection was not found. */ Blockly.ConnectionDB.prototype.findConnection = function(conn) { - if (this.length == 0) { + if (!this.length) { return -1; } @@ -110,7 +110,7 @@ Blockly.ConnectionDB.prototype.findConnection = function(conn) { * @private */ Blockly.ConnectionDB.prototype.findPositionForConnection_ = function(connection) { - if (this.length == 0) { + if (!this.length) { return 0; } var pointerMin = 0; diff --git a/core/events.js b/core/events.js index 3f6cfb208f..9cf1c92177 100644 --- a/core/events.js +++ b/core/events.js @@ -85,8 +85,8 @@ Blockly.Events.fire = function(event) { if (!Blockly.Events.isEnabled()) { return; } - if (Blockly.Events.FIRE_QUEUE_.length == 0) { - // Schedule a firing of the event queue. + if (!Blockly.Events.FIRE_QUEUE_.length) { + // First event added; schedule a firing of the event queue. setTimeout(Blockly.Events.fireNow_, 0); } Blockly.Events.FIRE_QUEUE_.push(event); diff --git a/core/workspace_svg.js b/core/workspace_svg.js index d2ccf64c2d..444a73109c 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -670,7 +670,7 @@ Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) { Blockly.WorkspaceSvg.prototype.getBlocksBoundingBox = function() { var topBlocks = this.getTopBlocks(); // There are no blocks, return empty rectangle. - if (topBlocks.length <= 0) { + if (!topBlocks.length) { return {x: 0, y: 0, width: 0, height: 0}; } diff --git a/msg/messages.js b/msg/messages.js index 7e4a3dddd6..66ef72bb58 100644 --- a/msg/messages.js +++ b/msg/messages.js @@ -250,11 +250,11 @@ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE = 'Return true if the first input is great Blockly.Msg.LOGIC_OPERATION_HELPURL = 'https://github.com/google/blockly/wiki/Logic#logical-operations'; /// tooltip - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction]. Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND = 'Return true if both inputs are true.'; -/// block text - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction]. +/// block text - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].\n{{Identical|And}} Blockly.Msg.LOGIC_OPERATION_AND = 'and'; /// block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction]. Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR = 'Return true if at least one of the inputs is true.'; -/// block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction]. +/// block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].\n{{Identical|Or}} Blockly.Msg.LOGIC_OPERATION_OR = 'or'; /// url - Information about logical negation. The translation of [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation] is recommended if it exists in the target language. From 72bb08a4ec448f7a0210c2b03c88a8542bc0b822 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Mon, 14 Mar 2016 23:14:05 -0700 Subject: [PATCH 11/14] Add undo/redo. Some bugs in undoing function argument changes. --- blocks/lists.js | 13 +------------ blocks/logic.js | 12 +++--------- blocks/text.js | 28 ++++++++++++---------------- core/events.js | 26 ++++++++++++++++++++++---- core/mutator.js | 32 ++++++++++++++++++++++++++++++++ core/workspace.js | 19 ++++++++++++------- 6 files changed, 82 insertions(+), 48 deletions(-) diff --git a/blocks/lists.js b/blocks/lists.js index 2e2da5a550..5dcbadb759 100644 --- a/blocks/lists.js +++ b/blocks/lists.js @@ -123,18 +123,7 @@ Blockly.Blocks['lists_create_with'] = { this.updateShape_(); // Reconnect any child blocks. for (var i = 0; i < this.itemCount_; i++) { - var connectionChild = connections[i]; - if (connectionChild) { - var parent = connectionChild.targetBlock(); - var connectionParent = this.getInput('ADD' + i).connection; - if (connectionParent.targetConnection != connectionChild && - (!parent || parent == this)) { - if (connectionParent.targetConnection) { - connectionParent.disconnect(); - } - connectionParent.connect(connectionChild); - } - } + Blockly.Mutator.reconnect(connections[i], this, 'ADD' + i); } }, /** diff --git a/blocks/logic.js b/blocks/logic.js index 2704bc8b00..e07287edb4 100644 --- a/blocks/logic.js +++ b/blocks/logic.js @@ -152,16 +152,10 @@ Blockly.Blocks['controls_if'] = { this.updateShape_(); // Reconnect any child blocks. for (var i = 1; i <= this.elseifCount_; i++) { - if (valueConnections[i]) { - this.getInput('IF' + i).connection.connect(valueConnections[i]); - } - if (statementConnections[i]) { - this.getInput('DO' + i).connection.connect(statementConnections[i]); - } - } - if (elseStatementConnection) { - this.getInput('ELSE').connection.connect(elseStatementConnection); + Blockly.Mutator.reconnect(valueConnections[i], this, 'IF' + i); + Blockly.Mutator.reconnect(statementConnections[i], this, 'DO' + i); } + Blockly.Mutator.reconnect(elseStatementConnection, this, 'ELSE'); }, /** * Store pointers to any connected child blocks. diff --git a/blocks/text.js b/blocks/text.js index ddf6197352..ff485dacfb 100644 --- a/blocks/text.js +++ b/blocks/text.js @@ -141,9 +141,7 @@ Blockly.Blocks['text_join'] = { this.updateShape_(); // Reconnect any child blocks. for (var i = 0; i < this.itemCount_; i++) { - if (connections[i]) { - this.getInput('ADD' + i).connection.connect(connections[i]); - } + Blockly.Mutator.reconnect(connections[i], this, 'ADD' + i); } }, /** @@ -168,29 +166,27 @@ Blockly.Blocks['text_join'] = { * @this Blockly.Block */ updateShape_: function() { - // Delete everything. - if (this.getInput('EMPTY')) { + if (this.itemCount_ && this.getInput('EMPTY')) { this.removeInput('EMPTY'); - } else { - var i = 0; - while (this.getInput('ADD' + i)) { - this.removeInput('ADD' + i); - i++; - } - } - // Rebuild block. - if (this.itemCount_ == 0) { + } else if (!this.itemCount_ && !this.getInput('EMPTY')) { this.appendDummyInput('EMPTY') .appendField(this.newQuote_(true)) .appendField(this.newQuote_(false)); - } else { - for (var i = 0; i < this.itemCount_; i++) { + } + // Add new inputs. + for (var i = 0; i < this.itemCount_; i++) { + if (!this.getInput('ADD' + i)) { var input = this.appendValueInput('ADD' + i); if (i == 0) { input.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH); } } } + // Remove deleted inputs. + while (this.getInput('ADD' + i)) { + this.removeInput('ADD' + i); + i++; + } }, newQuote_: Blockly.Blocks['text'].newQuote_ }; diff --git a/core/events.js b/core/events.js index 9cf1c92177..8b741d8a12 100644 --- a/core/events.js +++ b/core/events.js @@ -97,7 +97,7 @@ Blockly.Events.fire = function(event) { * @private */ Blockly.Events.fireNow_ = function() { - var queue = Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_); + var queue = Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_, true); Blockly.Events.FIRE_QUEUE_.length = 0; for (var i = 0, event; event = queue[i]; i++) { var workspace = Blockly.Workspace.getById(event.workspaceId); @@ -110,10 +110,15 @@ Blockly.Events.fireNow_ = function() { /** * Filter the queued events and merge duplicates. * @param {!Array.} queueIn Array of events. + * @param {boolean} forward True if forward (redo), false if backward (undo). * @return {!Array.} Array of filtered events. */ -Blockly.Events.filter = function(queueIn) { +Blockly.Events.filter = function(queueIn, forward) { var queue = goog.array.clone(queueIn); + if (!forward) { + // Undo is merged in reverse order. + queue.reverse(); + } // Merge duplicates. O(n^2), but n should be very small. for (var i = 0, event1; event1 = queue[i]; i++) { for (var j = i + 1, event2; event2 = queue[j]; j++) { @@ -144,6 +149,10 @@ Blockly.Events.filter = function(queueIn) { queue.splice(i, 1); } } + if (!forward) { + // Restore undo order. + queue.reverse(); + } // Move mutation events to the top of the queue. // Intentionally skip first event. for (var i = 1, event; event = queue[i]; i++) { @@ -251,6 +260,8 @@ Blockly.Events.Create.prototype.run = function(forward) { var block = Blockly.Block.getById(this.blockId); if (block) { block.dispose(false, true); + } else { + console.warn("Can't delete non-existant block: " + this.blockId); } } }; @@ -285,6 +296,8 @@ Blockly.Events.Delete.prototype.run = function(forward) { var block = Blockly.Block.getById(this.blockId); if (block) { block.dispose(false, true); + } else { + console.warn("Can't delete non-existant block: " + this.blockId); } } else { var workspace = Blockly.Workspace.getById(this.workspaceId); @@ -334,6 +347,7 @@ Blockly.Events.Change.prototype.isNull = function() { Blockly.Events.Change.prototype.run = function(forward) { var block = Blockly.Block.getById(this.blockId); if (!block) { + console.warn("Can't change non-existant block: " + this.blockId); return; } var value = forward ? this.newValue : this.oldValue; @@ -375,6 +389,8 @@ Blockly.Events.Change.prototype.run = function(forward) { Blockly.Events.fire(new Blockly.Events.Change( block, 'mutation', null, oldMutation, value)); break; + default: + console.warn("Unknown change type: " + this.element); } }; @@ -448,6 +464,7 @@ Blockly.Events.Move.prototype.isNull = function() { Blockly.Events.Move.prototype.run = function(forward) { var block = Blockly.Block.getById(this.blockId); if (!block) { + console.warn("Can't move non-existant block: " + this.blockId); return; } var parentId = forward ? this.newParentId : this.oldParentId; @@ -457,6 +474,7 @@ Blockly.Events.Move.prototype.run = function(forward) { if (parentId) { parentBlock = Blockly.Block.getById(parentId); if (!parentBlock) { + console.warn("Can't connect to non-existant block: " + parentId); return; } } @@ -473,14 +491,14 @@ Blockly.Events.Move.prototype.run = function(forward) { var input = parentBlock.getInput(inputName); if (input) { parentConnection = input.connection; - } else { - console.warn("Can't connect to non-existant input: " + inputName); } } else if (blockConnection.type == Blockly.PREVIOUS_STATEMENT) { parentConnection = parentBlock.nextConnection; } if (parentConnection) { blockConnection.connect(parentConnection); + } else { + console.warn("Can't connect to non-existant input: " + inputName); } } }; diff --git a/core/mutator.js b/core/mutator.js index b3e9d90e87..8488ee0fbb 100644 --- a/core/mutator.js +++ b/core/mutator.js @@ -340,3 +340,35 @@ Blockly.Mutator.prototype.dispose = function() { this.block_.mutator = null; Blockly.Icon.prototype.dispose.call(this); }; + +/** + * Reconnect an block to a mutated input. + * @param {Blockly.Connection} connectionChild Connection on child block. + * @param {!Blockly.Block} block Parent block. + * @param {string} inputName Name of input on parent block. + */ +Blockly.Mutator.reconnect = function(connectionChild, block, inputName) { + if (!connectionChild) { + return; + } + var connectionParent = block.getInput(inputName).connection; + var currentParent = connectionChild.targetBlock(); + if ((!currentParent || currentParent == block) && + connectionParent.targetConnection != connectionChild) { + if (connectionParent.targetConnection) { + // There's already something connected here. Get rid of it. + connectionParent.disconnect(); + } + connectionParent.connect(connectionChild); + } +}; + +// Export symbols that would otherwise be renamed by Closure compiler. +if (!goog.global['Blockly']) { + goog.global['Blockly'] = {}; +} +if (!goog.global['Blockly']['Mutator']) { + goog.global['Blockly']['Mutator'] = {}; +} +goog.global['Blockly']['Mutator']['reconnect'] = Blockly.Mutator.reconnect; + diff --git a/core/workspace.js b/core/workspace.js index 49f3fac880..7cc7886a4b 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -209,22 +209,27 @@ Blockly.Workspace.prototype.remainingCapacity = function() { * @param {boolean} redo False if undo, true if redo. */ Blockly.Workspace.prototype.undo = function(redo) { - var sourceStack = redo ? this.redoStack_ : this.undoStack_; - var event = sourceStack.pop(); + var inputStack = redo ? this.redoStack_ : this.undoStack_; + var outputStack = redo ? this.undoStack_ : this.redoStack_; + var event = inputStack.pop(); if (!event) { return; } var events = [event]; // Do another undo/redo if the next one is of the same group. - while (sourceStack.length && event.group && - event.group == sourceStack[sourceStack.length - 1].group) { - events.push(sourceStack.pop()); + while (inputStack.length && event.group && + event.group == inputStack[inputStack.length - 1].group) { + events.push(inputStack.pop()); } - events = Blockly.Events.filter(events); + // Push these popped events on the opposite stack. + for (var i = 0, event; event = events[i]; i++) { + outputStack.push(event); + } + events = Blockly.Events.filter(events, redo); Blockly.Events.recordUndo = false; for (var i = 0, event; event = events[i]; i++) { + console.log(event); event.run(redo); - (redo ? this.undoStack_ : this.redoStack_).push(event); } Blockly.Events.recordUndo = true; }; From 95fbc0bb49a717707b716c018f189a602964c790 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Mon, 14 Mar 2016 23:14:58 -0700 Subject: [PATCH 12/14] Fix checkbox events. Fix block deletion while mutator is open. --- core/block_svg.js | 2 +- core/field_checkbox.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/block_svg.js b/core/block_svg.js index 094615fcef..8b6c36ed92 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -941,13 +941,13 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) { // Stop rerendering. this.rendered = false; - Blockly.BlockSvg.superClass_.dispose.call(this, healStack); Blockly.Events.disable(); var icons = this.getIcons(); for (var i = 0; i < icons.length; i++) { icons[i].dispose(); } Blockly.Events.enable(); + Blockly.BlockSvg.superClass_.dispose.call(this, healStack); goog.dom.removeNode(this.svgGroup_); // Sever JavaScript to DOM connections. diff --git a/core/field_checkbox.js b/core/field_checkbox.js index 7619c4e274..241336dc6b 100644 --- a/core/field_checkbox.js +++ b/core/field_checkbox.js @@ -85,6 +85,10 @@ Blockly.FieldCheckbox.prototype.getValue = function() { Blockly.FieldCheckbox.prototype.setValue = function(strBool) { var newState = (strBool == 'TRUE'); if (this.state_ !== newState) { + if (this.sourceBlock_ && Blockly.Events.isEnabled()) { + Blockly.Events.fire(new Blockly.Events.Change( + this.sourceBlock_, 'field', this.name, this.state_, newState)); + } this.state_ = newState; if (this.checkElement_) { this.checkElement_.style.display = newState ? 'block' : 'none'; From fa64881f80f79a9975eb8d67946a00cf2223be39 Mon Sep 17 00:00:00 2001 From: Tim Mickel Date: Tue, 15 Mar 2016 10:36:06 -0400 Subject: [PATCH 13/14] Remove Lua generators --- generators/lua.js | 188 ---------------- generators/lua/colour.js | 90 -------- generators/lua/lists.js | 363 ------------------------------ generators/lua/logic.js | 125 ----------- generators/lua/loops.js | 166 -------------- generators/lua/math.js | 425 ----------------------------------- generators/lua/procedures.js | 110 --------- generators/lua/text.js | 293 ------------------------ generators/lua/variables.js | 46 ---- 9 files changed, 1806 deletions(-) delete mode 100644 generators/lua.js delete mode 100644 generators/lua/colour.js delete mode 100644 generators/lua/lists.js delete mode 100644 generators/lua/logic.js delete mode 100644 generators/lua/loops.js delete mode 100644 generators/lua/math.js delete mode 100644 generators/lua/procedures.js delete mode 100644 generators/lua/text.js delete mode 100644 generators/lua/variables.js diff --git a/generators/lua.js b/generators/lua.js deleted file mode 100644 index a1265b6694..0000000000 --- a/generators/lua.js +++ /dev/null @@ -1,188 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Helper functions for generating Lua for blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - * Based on Ellen Spertus's blocky-lua project. - */ -'use strict'; - -goog.provide('Blockly.Lua'); - -goog.require('Blockly.Generator'); - - -/** - * Lua code generator. - * @type {!Blockly.Generator} - */ -Blockly.Lua = new Blockly.Generator('Lua'); - -/** - * List of illegal variable names. - * This is not intended to be a security feature. Blockly is 100% client-side, - * so bypassing this list is trivial. This is intended to prevent users from - * accidentally clobbering a built-in object or function. - * @private - */ -Blockly.Lua.addReservedWords( - // Special character - '_,' + - // From theoriginalbit's script: - // https://github.com/espertus/blockly-lua/issues/6 - '__inext,assert,bit,colors,colours,coroutine,disk,dofile,error,fs,' + - 'fetfenv,getmetatable,gps,help,io,ipairs,keys,loadfile,loadstring,math,' + - 'native,next,os,paintutils,pairs,parallel,pcall,peripheral,print,' + - 'printError,rawequal,rawget,rawset,read,rednet,redstone,rs,select,' + - 'setfenv,setmetatable,sleep,string,table,term,textutils,tonumber,' + - 'tostring,turtle,type,unpack,vector,write,xpcall,_VERSION,__indext,' + - // Not included in the script, probably because it wasn't enabled: - 'HTTP,' + - // Keywords (http://www.lua.org/pil/1.3.html). - 'and,break,do,else,elseif,end,false,for,function,if,in,local,nil,not,or,' + - 'repeat,return,then,true,until,while,' + - // Metamethods (http://www.lua.org/manual/5.2/manual.html). - 'add,sub,mul,div,mod,pow,unm,concat,len,eq,lt,le,index,newindex,call,' + - // Basic functions (http://www.lua.org/manual/5.2/manual.html, section 6.1). - 'assert,collectgarbage,dofile,error,_G,getmetatable,inpairs,load,' + - 'loadfile,next,pairs,pcall,print,rawequal,rawget,rawlen,rawset,select,' + - 'setmetatable,tonumber,tostring,type,_VERSION,xpcall,' + - // Modules (http://www.lua.org/manual/5.2/manual.html, section 6.3). - 'require,package,string,table,math,bit32,io,file,os,debug' -); - -/** - * Order of operation ENUMs. - * http://www.lua.org/manual/5.3/manual.html#3.4.8 - */ -Blockly.Lua.ORDER_ATOMIC = 0; // literals -// The next level was not explicit in documentation and inferred by Ellen. -Blockly.Lua.ORDER_HIGH = 1; // Function calls, tables[] -Blockly.Lua.ORDER_EXPONENTIATION = 2; // ^ -Blockly.Lua.ORDER_UNARY = 3; // not # - () -Blockly.Lua.ORDER_MULTIPLICATIVE = 4; // * / % -Blockly.Lua.ORDER_ADDITIVE = 5; // + - -Blockly.Lua.ORDER_CONCATENATION = 6; // .. -Blockly.Lua.ORDER_RELATIONAL = 7; // < > <= >= ~= == -Blockly.Lua.ORDER_AND = 8; // and -Blockly.Lua.ORDER_OR = 9; // or -Blockly.Lua.ORDER_NONE = 99; - -/** - * Initialise the database of variable names. - * @param {!Blockly.Workspace} workspace Workspace to generate code from. - */ -Blockly.Lua.init = function(workspace) { - // Create a dictionary of definitions to be printed before the code. - Blockly.Lua.definitions_ = Object.create(null); - // Create a dictionary mapping desired function names in definitions_ - // to actual function names (to avoid collisions with user functions). - Blockly.Lua.functionNames_ = Object.create(null); - - if (!Blockly.Lua.variableDB_) { - Blockly.Lua.variableDB_ = - new Blockly.Names(Blockly.Lua.RESERVED_WORDS_); - } else { - Blockly.Lua.variableDB_.reset(); - } -}; - -/** - * Prepend the generated code with the variable definitions. - * @param {string} code Generated code. - * @return {string} Completed code. - */ -Blockly.Lua.finish = function(code) { - // Convert the definitions dictionary into a list. - var definitions = []; - for (var name in Blockly.Lua.definitions_) { - definitions.push(Blockly.Lua.definitions_[name]); - } - // Clean up temporary data. - delete Blockly.Lua.definitions_; - delete Blockly.Lua.functionNames_; - Blockly.Lua.variableDB_.reset(); - return definitions.join('\n\n') + '\n\n\n' + code; -}; - -/** - * Naked values are top-level blocks with outputs that aren't plugged into - * anything. In Lua, an expression is not a legal statement, so we must assign - * the value to the (conventionally ignored) _. - * http://lua-users.org/wiki/ExpressionsAsStatements - * @param {string} line Line of generated code. - * @return {string} Legal line of code. - */ -Blockly.Lua.scrubNakedValue = function(line) { - return 'local _ = ' + line + '\n'; -}; - -/** - * Encode a string as a properly escaped Lua string, complete with - * quotes. - * @param {string} string Text to encode. - * @return {string} Lua string. - * @private - */ -Blockly.Lua.quote_ = function(string) { - // TODO: This is a quick hack. Replace with goog.string.quote - string = string.replace(/\\/g, '\\\\') - .replace(/\n/g, '\\\n') - .replace(/'/g, '\\\''); - return '\'' + string + '\''; -}; - -/** - * Common tasks for generating Lua from blocks. - * Handles comments for the specified block and any connected value blocks. - * Calls any statements following this block. - * @param {!Blockly.Block} block The current block. - * @param {string} code The Lua code created for this block. - * @return {string} Lua code with comments and subsequent blocks added. - * @private - */ -Blockly.Lua.scrub_ = function(block, code) { - var commentCode = ''; - // Only collect comments for blocks that aren't inline. - if (!block.outputConnection || !block.outputConnection.targetConnection) { - // Collect comment for this block. - var comment = block.getCommentText(); - if (comment) { - commentCode += Blockly.Lua.prefixLines(comment, '-- ') + '\n'; - } - // Collect comments for all value arguments. - // Don't collect comments for nested statements. - for (var x = 0; x < block.inputList.length; x++) { - if (block.inputList[x].type == Blockly.INPUT_VALUE) { - var childBlock = block.inputList[x].connection.targetBlock(); - if (childBlock) { - comment = Blockly.Lua.allNestedComments(childBlock); - if (comment) { - commentCode += Blockly.Lua.prefixLines(comment, '-- '); - } - } - } - } - } - var nextBlock = block.nextConnection && block.nextConnection.targetBlock(); - var nextCode = Blockly.Lua.blockToCode(nextBlock); - return commentCode + code + nextCode; -}; diff --git a/generators/lua/colour.js b/generators/lua/colour.js deleted file mode 100644 index 9175a9de91..0000000000 --- a/generators/lua/colour.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Generating Lua for colour blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - */ -'use strict'; - -goog.provide('Blockly.Lua.colour'); - -goog.require('Blockly.Lua'); - - -Blockly.Lua['colour_picker'] = function(block) { - // Colour picker. - var code = '\'' + block.getFieldValue('COLOUR') + '\''; - return [code, Blockly.Lua.ORDER_ATOMIC]; -}; - -Blockly.Lua['colour_random'] = function(block) { - // Generate a random colour. - var code = 'string.format("#%06x", math.random(0, 2^24 - 1))'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['colour_rgb'] = function(block) { - // Compose a colour from RGB components expressed as percentages. - var functionName = Blockly.Lua.provideFunction_( - 'colour_rgb', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b)', - ' r = math.floor(math.min(100, math.max(0, r)) * 2.55 + .5)', - ' g = math.floor(math.min(100, math.max(0, g)) * 2.55 + .5)', - ' b = math.floor(math.min(100, math.max(0, b)) * 2.55 + .5)', - ' return string.format("#%02x%02x%02x", r, g, b)', - 'end']); - var r = Blockly.Lua.valueToCode(block, 'RED', - Blockly.Lua.ORDER_NONE) || 0; - var g = Blockly.Lua.valueToCode(block, 'GREEN', - Blockly.Lua.ORDER_NONE) || 0; - var b = Blockly.Lua.valueToCode(block, 'BLUE', - Blockly.Lua.ORDER_NONE) || 0; - var code = functionName + '(' + r + ', ' + g + ', ' + b + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['colour_blend'] = function(block) { - // Blend two colours together. - var functionName = Blockly.Lua.provideFunction_( - 'colour_blend', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + - '(colour1, colour2, ratio)', - ' local r1 = tonumber(string.sub(colour1, 2, 3), 16)', - ' local r2 = tonumber(string.sub(colour2, 2, 3), 16)', - ' local g1 = tonumber(string.sub(colour1, 4, 5), 16)', - ' local g2 = tonumber(string.sub(colour2, 4, 5), 16)', - ' local b1 = tonumber(string.sub(colour1, 6, 7), 16)', - ' local b2 = tonumber(string.sub(colour2, 6, 7), 16)', - ' local ratio = math.min(1, math.max(0, ratio))', - ' local r = math.floor(r1 * (1 - ratio) + r2 * ratio + .5)', - ' local g = math.floor(g1 * (1 - ratio) + g2 * ratio + .5)', - ' local b = math.floor(b1 * (1 - ratio) + b2 * ratio + .5)', - ' return string.format("#%02x%02x%02x", r, g, b)', - 'end']); - var colour1 = Blockly.Lua.valueToCode(block, 'COLOUR1', - Blockly.Lua.ORDER_NONE) || '\'#000000\''; - var colour2 = Blockly.Lua.valueToCode(block, 'COLOUR2', - Blockly.Lua.ORDER_NONE) || '\'#000000\''; - var ratio = Blockly.Lua.valueToCode(block, 'RATIO', - Blockly.Lua.ORDER_NONE) || 0; - var code = functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; diff --git a/generators/lua/lists.js b/generators/lua/lists.js deleted file mode 100644 index 619f6d8d7f..0000000000 --- a/generators/lua/lists.js +++ /dev/null @@ -1,363 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Generating Lua for list blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - */ -'use strict'; - -goog.provide('Blockly.Lua.lists'); - -goog.require('Blockly.Lua'); - - -Blockly.Lua['lists_create_empty'] = function(block) { - // Create an empty list. - // List literals must be parenthesized before indexing into. - return ['({})', Blockly.Lua.ORDER_ATOMIC]; -}; - -Blockly.Lua['lists_create_with'] = function(block) { - // Create a list with any number of elements of any type. - var code = new Array(block.itemCount_); - for (var n = 0; n < block.itemCount_; n++) { - code[n] = Blockly.Lua.valueToCode(block, 'ADD' + n, - Blockly.Lua.ORDER_NONE) || 'None'; - } - code = '({' + code.join(', ') + '})'; - return [code, Blockly.Lua.ORDER_ATOMIC]; -}; - -Blockly.Lua['lists_repeat'] = function(block) { - // Create a list with one element repeated. - var functionName = Blockly.Lua.provideFunction_( - 'create_list_repeated', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(item, count)', - ' local t = {}', - ' for i = 1, count do', - ' table.insert(t, item)', - ' end', - ' return t', - 'end']); - var argument0 = Blockly.Lua.valueToCode(block, 'ITEM', - Blockly.Lua.ORDER_NONE) || 'None'; - var argument1 = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_NONE) || '0'; - var code = functionName + '(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['lists_length'] = function(block) { - // String or array length. - var argument0 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_HIGH) || '({})'; - return ['#' + argument0, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['lists_isEmpty'] = function(block) { - // Is the string null or array empty? - var argument0 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_HIGH) || '({})'; - var code = '#' + argument0 + ' == 0'; - return [code, Blockly.Lua.ORDER_RELATIONAL]; -}; - -Blockly.Lua['lists_indexOf'] = function(block) { - // Find an item in the list. - var argument0 = Blockly.Lua.valueToCode(block, 'FIND', - Blockly.Lua.ORDER_NONE) || '\'\''; - var argument1 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '({})'; - var functionName; - if (block.getTitleValue('END') == 'FIRST') { - functionName = Blockly.Lua.provideFunction_( - 'first_index', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)', - ' for k, v in ipairs(t) do', - ' if v == elem then', - ' return k', - ' end', - ' end', - ' return 0', - 'end']); - } else { - functionName = Blockly.Lua.provideFunction_( - 'last_index', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)', - ' for i = #t, 1, -1 do', - ' if t[i] == elem then', - ' return i', - ' end', - ' end', - ' return 0', - 'end']); - } - var code = functionName + '(' + argument1 + ', ' + argument0 + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -/** - * Returns an expression calculating the index into a list. - * @private - * @param {string} listname Name of the list, used to calculate length. - * @param {string} where The method of indexing, selected by dropdown in Blockly - * @param {string=} opt_at The optional offset when indexing from start/end. - * @return {string} Index expression. - */ -Blockly.Lua.lists.getIndex_ = function(listname, where, opt_at) { - if (where == 'FIRST') { - return '1'; - } else if (where == 'FROM_END') { - return '#' + listname + ' + 1 - ' + opt_at; - } else if (where == 'LAST') { - return '#' + listname; - } else if (where == 'RANDOM') { - return 'math.random(#' + listname + ')'; - } else { - return opt_at; - } -}; - -/** - * Counter for generating unique symbols. - * @private - * @type {number} - */ -Blockly.Lua.lists.gensym_counter_ = 0; - -/** - * Generate a unique symbol. - * @private - * @return {string} unique symbol, eg 'G123' - */ -Blockly.Lua.lists.gensym_ = function() { - return 'G' + Blockly.Lua.lists.gensym_counter_++; -}; - -Blockly.Lua['lists_getIndex'] = function(block) { - // Get element at index. - // Note: Until January 2013 this block did not have MODE or WHERE inputs. - var mode = block.getTitleValue('MODE') || 'GET'; - var where = block.getTitleValue('WHERE') || 'FROM_START'; - var at = Blockly.Lua.valueToCode(block, 'AT', - Blockly.Lua.ORDER_ADDITIVE) || '1'; - var list = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_HIGH) || '({})'; - var getIndex_ = Blockly.Lua.lists.getIndex_; - var gensym_ = Blockly.Lua.lists.gensym_; - - // If `list` would be evaluated more than once (which is the case for LAST, - // FROM_END, and RANDOM) and is non-trivial, make sure to access it only once. - if ((where == 'LAST' || where == 'FROM_END' || where == 'RANDOM') && - !list.match(/^\w+$/)) { - // `list` is an expression, so we may not evaluate it more than once. - if (mode == 'REMOVE') { - // We can use multiple statements. - var listVar = Blockly.Lua.variableDB_.getDistinctName( - 'tmp_list', Blockly.Variables.NAME_TYPE); - var code = listVar + ' = ' + list + '\n' + - 'table.remove(' + listVar + ', ' + getIndex_(listVar, where, at) + - ')\n'; - return code; - } else { - // We need to create a procedure to avoid reevaluating values. - if (mode == 'GET') { - // Note that getIndex_() ignores `at` when `where` == 'LAST' or - // 'RANDOM', so we only need one procedure for each of those 'where' - // values. The value for 'FROM_END' depends on `at`, so we will - // generate a unique procedure (name) each time. - var functionName = Blockly.Lua.provideFunction_( - 'list_get_' + where.toLowerCase() + - (where == 'FROM_END' ? '_' + gensym_() : ''), - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' return t[' + getIndex_('t', where, at) + ']', - 'end']); - } else { // mode == 'GET_REMOVE' - // We need to create a procedure. - var functionName = Blockly.Lua.provideFunction_( - 'list_remove_' + where.toLowerCase() + - (where == 'FROM_END' ? '_' + gensym_() : ''), - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' return table.remove(t, ' + getIndex_('t', where, at) + ')', - 'end']); - } - var code = functionName + '(' + list + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; - } - } else { - // Either `list` is a simple variable, or we only need to refer to `list` - // once. - if (mode == 'GET') { - var code = list + '[' + getIndex_(list, where, at) + ']'; - return [code, Blockly.Lua.ORDER_HIGH]; - } else { - var code = 'table.remove(' + list + ', ' + getIndex_(list, where, at) + - ')'; - if (mode == 'GET_REMOVE') { - return [code, Blockly.Lua.ORDER_HIGH]; - } else { // `mode` == 'REMOVE' - return code + '\n'; - } - } - } -}; - -Blockly.Lua['lists_setIndex'] = function(block) { - // Set element at index. - // Note: Until February 2013 this block did not have MODE or WHERE inputs. - var list = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_HIGH) || '({})'; - var mode = block.getFieldValue('MODE') || 'SET'; - var where = block.getFieldValue('WHERE') || 'FROM_START'; - var at = Blockly.Lua.valueToCode(block, 'AT', - Blockly.Lua.ORDER_ADDITIVE) || '1'; - var value = Blockly.Lua.valueToCode(block, 'TO', - Blockly.Lua.ORDER_NONE) || 'None'; - var getIndex_ = Blockly.Lua.lists.getIndex_; - - // If `list` would be evaluated more than once (which is the case for LAST, - // FROM_END, and RANDOM) and is non-trivial, make sure to access it only once. - if ((where == 'LAST' || where == 'FROM_END' || where == 'RANDOM') && - !list.match(/^\w+$/)) { - // `list` is an expression, so we may not evaluate it more than once. - if (where == 'RANDOM' || where == 'LAST') { - // In these cases, `at` is implicit. getIndex_() ignores its value. - if (mode == 'SET') { - var functionName = Blockly.Lua.provideFunction_( - 'list_set_' + where.toLowerCase(), - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, val)', - ' t[' + getIndex_('t', where, at) + '] = val', - 'end']); - } else { // `mode` == 'INSERT' - var functionName = Blockly.Lua.provideFunction_( - 'list_insert_' + where.toLowerCase(), - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, val)', - ' table.insert(t, ' + - // LAST is a special case, because we want to insert - // *after* not *before*, the existing last element. - getIndex_('t', where, at) + (where == 'LAST' ? ' + 1' : '') + - ', val)', - 'end']); - } - var code = functionName + '(' + list + ', ' + value + ')\n'; - return code; - } else { // `where` = 'FROM_END' - if (mode == 'SET') { - var functionName = Blockly.Lua.provideFunction_( - 'list_set_from_end', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + - '(t, index, val)', - ' t[#t + 1 - index] = val', - 'end']); - } else { // `mode` == 'INSERT' - var functionName = Blockly.Lua.provideFunction_( - 'list_insert_from_end', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + - '(t, index, val)', - ' table.insert(t, #t + 1 - index, val)', - 'end']); - } - var code = functionName + '(' + list + ', ' + at + ', ' + value + ')\n'; - return code; - } - } else { - // It's okay to have multiple references to the list. - if (mode == 'SET') { - var code = list + '[' + getIndex_(list, where, at) + '] = ' + value; - } else { // `mode` == 'INSERT' - // LAST is a special case, because we want to insert - // *after* not *before*, the existing last element. - var code = 'table.insert(' + list + ', ' + - (getIndex_(list, where, at) + (where == 'LAST' ? ' + 1' : '')) + - ', ' + value + ')'; - } - return code + '\n'; - } -}; - -Blockly.Lua['lists_getSublist'] = function(block) { - // Get sublist. - var list = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_HIGH) || '({})'; - var where1 = block.getFieldValue('WHERE1'); - var where2 = block.getFieldValue('WHERE2'); - var at1 = Blockly.Lua.valueToCode(block, 'AT1', - Blockly.Lua.ORDER_ADDITIVE) || '1'; - var at2 = Blockly.Lua.valueToCode(block, 'AT2', - Blockly.Lua.ORDER_ADDITIVE) || '1'; - var getIndex_ = Blockly.Lua.lists.getIndex_; - - var functionName = Blockly.Lua.provideFunction_( - 'list_sublist_' + Blockly.Lua.lists.gensym_(), - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(source)', - ' local t = {}', - ' local start = ' + getIndex_('source', where1, at1), - ' local finish = ' + getIndex_('source', where2, at2), - ' for i = start, finish do', - ' table.insert(t, source[i])', - ' end', - ' return t', - 'end']); - var code = functionName + '(' + list + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['lists_split'] = function(block) { - // Block for splitting text into a list, or joining a list into text. - var value_input = Blockly.Lua.valueToCode(block, 'INPUT', - Blockly.Lua.ORDER_NONE); - var value_delim = Blockly.Lua.valueToCode(block, 'DELIM', - Blockly.Lua.ORDER_NONE) || '\'\''; - var mode = block.getFieldValue('MODE'); - var functionName; - if (mode == 'SPLIT') { - if (!value_input) { - value_input = '\'\''; - } - functionName = Blockly.Lua.provideFunction_( - 'list_string_split', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + - '(input, delim)', - ' local t = {}', - ' local pos = 1', - ' while true do', - ' next_delim = string.find(input, delim, pos)', - ' if next_delim == nil then', - ' table.insert(t, string.sub(input, pos))', - ' break', - ' else', - ' table.insert(t, string.sub(input, pos, next_delim-1))', - ' pos = next_delim + #delim', - ' end', - ' end', - ' return t', - 'end']); - } else if (mode == 'JOIN') { - if (!value_input) { - value_input = '({})'; - } - functionName = 'table.concat'; - } else { - throw 'Unknown mode: ' + mode; - } - var code = functionName + '(' + value_input + ', ' + value_delim + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; diff --git a/generators/lua/logic.js b/generators/lua/logic.js deleted file mode 100644 index cc3c5a95cf..0000000000 --- a/generators/lua/logic.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Generating Lua for logic blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - */ -'use strict'; - -goog.provide('Blockly.Lua.logic'); - -goog.require('Blockly.Lua'); - - -Blockly.Lua['controls_if'] = function(block) { - // If/elseif/else condition. - var n = 0; - var argument = Blockly.Lua.valueToCode(block, 'IF' + n, - Blockly.Lua.ORDER_NONE) || 'false'; - var branch = Blockly.Lua.statementToCode(block, 'DO' + n); - var code = 'if ' + argument + ' then\n' + branch; - for (n = 1; n <= block.elseifCount_; n++) { - argument = Blockly.Lua.valueToCode(block, 'IF' + n, - Blockly.Lua.ORDER_NONE) || 'false'; - branch = Blockly.Lua.statementToCode(block, 'DO' + n); - code += ' elseif ' + argument + ' then\n' + branch; - } - if (block.elseCount_) { - branch = Blockly.Lua.statementToCode(block, 'ELSE'); - code += ' else\n' + branch; - } - return code + 'end\n'; -}; - -Blockly.Lua['logic_compare'] = function(block) { - // Comparison operator. - var OPERATORS = { - 'EQ': '==', - 'NEQ': '~=', - 'LT': '<', - 'LTE': '<=', - 'GT': '>', - 'GTE': '>=' - }; - var operator = OPERATORS[block.getFieldValue('OP')]; - var argument0 = Blockly.Lua.valueToCode(block, 'A', - Blockly.Lua.ORDER_RELATIONAL) || '0'; - var argument1 = Blockly.Lua.valueToCode(block, 'B', - Blockly.Lua.ORDER_RELATIONAL) || '0'; - var code = argument0 + ' ' + operator + ' ' + argument1; - return [code, Blockly.Lua.ORDER_RELATIONAL]; -}; - -Blockly.Lua['logic_operation'] = function(block) { - // Operations 'and', 'or'. - var operator = (block.getFieldValue('OP') == 'AND') ? 'and' : 'or'; - var order = (operator == 'and') ? Blockly.Lua.ORDER_AND : - Blockly.Lua.ORDER_OR; - var argument0 = Blockly.Lua.valueToCode(block, 'A', order); - var argument1 = Blockly.Lua.valueToCode(block, 'B', order); - if (!argument0 && !argument1) { - // If there are no arguments, then the return value is false. - argument0 = 'false'; - argument1 = 'false'; - } else { - // Single missing arguments have no effect on the return value. - var defaultArgument = (operator == 'and') ? 'true' : 'false'; - if (!argument0) { - argument0 = defaultArgument; - } - if (!argument1) { - argument1 = defaultArgument; - } - } - var code = argument0 + ' ' + operator + ' ' + argument1; - return [code, order]; -}; - -Blockly.Lua['logic_negate'] = function(block) { - // Negation. - var argument0 = Blockly.Lua.valueToCode(block, 'BOOL', - Blockly.Lua.ORDER_UNARY) || 'true'; - var code = 'not ' + argument0; - return [code, Blockly.Lua.ORDER_UNARY]; -}; - -Blockly.Lua['logic_boolean'] = function(block) { - // Boolean values true and false. - var code = (block.getFieldValue('BOOL') == 'TRUE') ? 'true' : 'false'; - return [code, Blockly.Lua.ORDER_ATOMIC]; -}; - -Blockly.Lua['logic_null'] = function(block) { - // Null data type. - return ['nil', Blockly.Lua.ORDER_ATOMIC]; -}; - -Blockly.Lua['logic_ternary'] = function(block) { - // Ternary operator. - var value_if = Blockly.Lua.valueToCode(block, 'IF', - Blockly.Lua.ORDER_AND) || 'false'; - var value_then = Blockly.Lua.valueToCode(block, 'THEN', - Blockly.Lua.ORDER_AND) || 'nil'; - var value_else = Blockly.Lua.valueToCode(block, 'ELSE', - Blockly.Lua.ORDER_OR) || 'nil'; - var code = value_if + ' and ' + value_then + ' or ' + value_else; - return [code, Blockly.Lua.ORDER_OR]; -}; diff --git a/generators/lua/loops.js b/generators/lua/loops.js deleted file mode 100644 index 785398ff76..0000000000 --- a/generators/lua/loops.js +++ /dev/null @@ -1,166 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Generating Lua for loop blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - */ -'use strict'; - -goog.provide('Blockly.Lua.loops'); - -goog.require('Blockly.Lua'); - - -/** - * This is the text used to implement a
continue
. - * It is also used to recognise
continue
s in generated code so that - * the appropriate label can be put at the end of the loop body. - * @const {string} - */ -Blockly.Lua.CONTINUE_STATEMENT = 'goto continue\n'; - -/** - * If the loop body contains a "goto continue" statement, add a continue label - * to the loop body. Slightly inefficient, as continue labels will be generated - * in all outer loops, but this is safer than duplicating the logic of - * blockToCode. - * - * @param {string} branch Generated code of the loop body - * @return {string} Generated label or '' if unnecessary - */ -Blockly.Lua.addContinueLabel = function(branch) { - if (branch.indexOf(Blockly.Lua.CONTINUE_STATEMENT) > -1) { - return branch + Blockly.Lua.INDENT + '::continue::\n'; - } else { - return branch; - } -}; - -Blockly.Lua['controls_repeat'] = function(block) { - // Repeat n times (internal number). - var repeats = parseInt(block.getFieldValue('TIMES'), 10); - var branch = Blockly.Lua.statementToCode(block, 'DO') || ''; - branch = Blockly.Lua.addContinueLabel(branch); - var loopVar = Blockly.Lua.variableDB_.getDistinctName( - 'count', Blockly.Variables.NAME_TYPE); - var code = 'for ' + loopVar + ' = 1, ' + repeats + ' do\n' + branch + 'end\n'; - return code; -}; - -Blockly.Lua['controls_repeat_ext'] = function(block) { - // Repeat n times (external number). - var repeats = Blockly.Lua.valueToCode(block, 'TIMES', - Blockly.Lua.ORDER_NONE) || '0'; - if (Blockly.isNumber(repeats)) { - repeats = parseInt(repeats, 10); - } else { - repeats = 'math.floor(' + repeats + ')'; - } - var branch = Blockly.Lua.statementToCode(block, 'DO') || '\n'; - branch = Blockly.Lua.addContinueLabel(branch); - var loopVar = Blockly.Lua.variableDB_.getDistinctName( - 'count', Blockly.Variables.NAME_TYPE); - var code = 'for ' + loopVar + ' = 1, ' + repeats + ' do\n' + - branch + 'end\n'; - return code; -}; - -Blockly.Lua['controls_whileUntil'] = function(block) { - // Do while/until loop. - var until = block.getFieldValue('MODE') == 'UNTIL'; - var argument0 = Blockly.Lua.valueToCode(block, 'BOOL', - until ? Blockly.Lua.ORDER_UNARY : - Blockly.Lua.ORDER_NONE) || 'false'; - var branch = Blockly.Lua.statementToCode(block, 'DO') || '\n'; - branch = Blockly.Lua.addLoopTrap(branch, block.id); - branch = Blockly.Lua.addContinueLabel(branch); - if (until) { - argument0 = 'not ' + argument0; - } - return 'while ' + argument0 + ' do\n' + branch + 'end\n'; -}; - -Blockly.Lua['controls_for'] = function(block) { - // For loop. - var variable0 = Blockly.Lua.variableDB_.getName( - block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); - var startVar = Blockly.Lua.valueToCode(block, 'FROM', - Blockly.Lua.ORDER_NONE) || '0'; - var endVar = Blockly.Lua.valueToCode(block, 'TO', - Blockly.Lua.ORDER_NONE) || '0'; - var increment = Blockly.Lua.valueToCode(block, 'BY', - Blockly.Lua.ORDER_NONE) || '1'; - var branch = Blockly.Lua.statementToCode(block, 'DO') || '\n'; - branch = Blockly.Lua.addLoopTrap(branch, block.id); - branch = Blockly.Lua.addContinueLabel(branch); - var code = ''; - var incValue; - if (Blockly.isNumber(startVar) && Blockly.isNumber(endVar) && - Blockly.isNumber(increment)) { - // All arguments are simple numbers. - var up = parseFloat(startVar) <= parseFloat(endVar); - var step = Math.abs(parseFloat(increment)); - incValue = (up ? '' : '-') + step; - } else { - code = ''; - // Determine loop direction at start, in case one of the bounds - // changes during loop execution. - incValue = Blockly.Lua.variableDB_.getDistinctName( - variable0 + '_inc', Blockly.Variables.NAME_TYPE); - code += incValue + ' = '; - if (Blockly.isNumber(increment)) { - code += Math.abs(increment) + '\n'; - } else { - code += 'math.abs(' + increment + ')\n'; - } - code += 'if (' + startVar + ') > (' + endVar + ') then\n'; - code += Blockly.Lua.INDENT + incValue + ' = -' + incValue + '\n'; - code += 'end\n'; - } - code += 'for ' + variable0 + ' = ' + startVar + ', ' + endVar + - ', ' + incValue; - code += ' do\n' + branch + 'end\n'; - return code; -}; - -Blockly.Lua['controls_forEach'] = function(block) { - // For each loop. - var variable0 = Blockly.Lua.variableDB_.getName( - block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); - var argument0 = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_NONE) || '{}'; - var branch = Blockly.Lua.statementToCode(block, 'DO') || '\n'; - branch = Blockly.Lua.addContinueLabel(branch); - var code = 'for _, ' + variable0 + ' in ipairs(' + argument0 + ') do \n' + - branch + 'end\n'; - return code; -}; - -Blockly.Lua['controls_flow_statements'] = function(block) { - // Flow statements: continue, break. - switch (block.getFieldValue('FLOW')) { - case 'BREAK': - return 'break\n'; - case 'CONTINUE': - return Blockly.Lua.CONTINUE_STATEMENT; - } - throw 'Unknown flow statement.'; -}; diff --git a/generators/lua/math.js b/generators/lua/math.js deleted file mode 100644 index c104bfc166..0000000000 --- a/generators/lua/math.js +++ /dev/null @@ -1,425 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Generating Lua for math blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - */ -'use strict'; - -goog.provide('Blockly.Lua.math'); - -goog.require('Blockly.Lua'); - - -Blockly.Lua['math_number'] = function(block) { - // Numeric value. - var code = parseFloat(block.getFieldValue('NUM')); - var order = code < 0 ? Blockly.Lua.ORDER_UNARY : - Blockly.Lua.ORDER_ATOMIC; - return [code, order]; -}; - -Blockly.Lua['math_arithmetic'] = function(block) { - // Basic arithmetic operators, and power. - var OPERATORS = { - ADD: [' + ', Blockly.Lua.ORDER_ADDITIVE], - MINUS: [' - ', Blockly.Lua.ORDER_ADDITIVE], - MULTIPLY: [' * ', Blockly.Lua.ORDER_MULTIPLICATIVE], - DIVIDE: [' / ', Blockly.Lua.ORDER_MULTIPLICATIVE], - POWER: [' ^ ', Blockly.Lua.ORDER_EXPONENTIATION] - }; - var tuple = OPERATORS[block.getFieldValue('OP')]; - var operator = tuple[0]; - var order = tuple[1]; - var argument0 = Blockly.Lua.valueToCode(block, 'A', order) || '0'; - var argument1 = Blockly.Lua.valueToCode(block, 'B', order) || '0'; - var code = argument0 + operator + argument1; - return [code, order]; -}; - -Blockly.Lua['math_single'] = function(block) { - // Math operators with single operand. - var operator = block.getFieldValue('OP'); - var code; - var arg; - if (operator == 'NEG') { - // Negation is a special case given its different operator precedence. - arg = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_UNARY) || '0'; - return ['-' + arg, Blockly.Lua.ORDER_UNARY]; - } - if (operator == 'SIN' || operator == 'COS' || operator == 'TAN') { - arg = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_MULTIPLICATIVE) || '0'; - } else { - arg = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_NONE) || '0'; - } - switch (operator) { - case 'ABS': - code = 'math.abs(' + arg + ')'; - break; - case 'ROOT': - code = 'math.sqrt(' + arg + ')'; - break; - case 'LN': - code = 'math.log(' + arg + ')'; - break; - case 'LOG10': - code = 'math.log10(' + arg + ')'; - break; - case 'EXP': - code = 'math.exp(' + arg + ')'; - break; - case 'POW10': - code = 'math.pow(10,' + arg + ')'; - break; - case 'ROUND': - // This rounds up. Blockly does not specify rounding direction. - code = 'math.floor(' + arg + ' + .5)'; - break; - case 'ROUNDUP': - code = 'math.ceil(' + arg + ')'; - break; - case 'ROUNDDOWN': - code = 'math.floor(' + arg + ')'; - break; - case 'SIN': - code = 'math.sin(math.rad(' + arg + '))'; - break; - case 'COS': - code = 'math.cos(math.rad(' + arg + '))'; - break; - case 'TAN': - code = 'math.tan(math.rad(' + arg + '))'; - break; - case 'ASIN': - code = 'math.deg(math.asin(' + arg + '))'; - break; - case 'ACOS': - code = 'math.deg(math.acos(' + arg + '))'; - break; - case 'ATAN': - code = 'math.deg(math.atan(' + arg + '))'; - break; - default: - throw 'Unknown math operator: ' + operator; - } - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['math_constant'] = function(block) { - // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY. - var CONSTANTS = { - PI: ['math.pi', Blockly.Lua.ORDER_HIGH], - E: ['math.exp(1)', Blockly.Lua.ORDER_HIGH], - GOLDEN_RATIO: ['(1 + math.sqrt(5)) / 2', Blockly.Lua.ORDER_MULTIPLICATIVE], - SQRT2: ['math.sqrt(2)', Blockly.Lua.ORDER_HIGH], - SQRT1_2: ['math.sqrt(1 / 2)', Blockly.Lua.ORDER_HIGH], - INFINITY: ['math.huge', Blockly.Lua.ORDER_HIGH] - }; - return CONSTANTS[block.getFieldValue('CONSTANT')]; -}; - -Blockly.Lua['math_number_property'] = function(block) { - // Check if a number is even, odd, prime, whole, positive, or negative - // or if it is divisible by certain number. Returns true or false. - var number_to_check = Blockly.Lua.valueToCode(block, 'NUMBER_TO_CHECK', - Blockly.Lua.ORDER_MULTIPLICATIVE) || '0'; - var dropdown_property = block.getFieldValue('PROPERTY'); - var code; - if (dropdown_property == 'PRIME') { - // Prime is a special case as it is not a one-liner test. - var functionName = Blockly.Lua.provideFunction_( - 'math_isPrime', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(n)', - ' -- https://en.wikipedia.org/wiki/Primality_test#Naive_methods', - ' if n == 2 or n == 3 then', - ' return true', - ' end', - ' -- False if n is NaN, negative, is 1, or not whole.', - ' -- And false if n is divisible by 2 or 3.', - ' if not(n > 1) or n % 1 ~= 0 or n % 2 == 0 or n % 3 == 0 then', - ' return false', - ' end', - ' -- Check all the numbers of form 6k +/- 1, up to sqrt(n).', - ' for x = 6, math.sqrt(n) + 1.5, 6 do', - ' if n % (x - 1) == 0 or n % (x + 1) == 0 then', - ' return false', - ' end', - ' end', - ' return true', - 'end']); - code = functionName + '(' + number_to_check + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; - } - switch (dropdown_property) { - case 'EVEN': - code = number_to_check + ' % 2 == 0'; - break; - case 'ODD': - code = number_to_check + ' % 2 == 1'; - break; - case 'WHOLE': - code = number_to_check + ' % 1 == 0'; - break; - case 'POSITIVE': - code = number_to_check + ' > 0'; - break; - case 'NEGATIVE': - code = number_to_check + ' < 0'; - break; - case 'DIVISIBLE_BY': - var divisor = Blockly.Lua.valueToCode(block, 'DIVISOR', - Blockly.Lua.ORDER_MULTIPLICATIVE); - // If 'divisor' is some code that evals to 0, Lua will produce a nan. - // Let's produce nil if we can determine this at compile-time. - if (!divisor || divisor == '0') { - return ['nil', Blockly.Lua.ORDER_ATOMIC]; - } - // The normal trick to implement ?: with and/or doesn't work here: - // divisor == 0 and nil or number_to_check % divisor == 0 - // because nil is false, so allow a runtime failure. :-( - code = number_to_check + ' % ' + divisor + ' == 0'; - break; - } - return [code, Blockly.Lua.ORDER_RELATIONAL]; -}; - -Blockly.Lua['math_change'] = function(block) { - // Add to a variable in place. - var argument0 = Blockly.Lua.valueToCode(block, 'DELTA', - Blockly.Lua.ORDER_ADDITIVE) || '0'; - var varName = Blockly.Lua.variableDB_.getName( - block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); - return varName + ' = ' + varName + ' + ' + argument0 + '\n'; -}; - -// Rounding functions have a single operand. -Blockly.Lua['math_round'] = Blockly.Lua['math_single']; -// Trigonometry functions have a single operand. -Blockly.Lua['math_trig'] = Blockly.Lua['math_single']; - -Blockly.Lua['math_on_list'] = function(block) { - // Math functions for lists. - var func = block.getFieldValue('OP'); - var list = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_NONE) || '{}'; - var functionName; - - // Functions needed in more than one case. - function provideSum() { - return Blockly.Lua.provideFunction_( - 'math_sum', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' local result = 0', - ' for _, v in ipairs(t) do', - ' result = result + v', - ' end', - ' return result', - 'end']); - } - - switch (func) { - case 'SUM': - functionName = provideSum(); - break; - - case 'MIN': - // Returns 0 for the empty list. - functionName = Blockly.Lua.provideFunction_( - 'math_min', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' if #t == 0 then', - ' return 0', - ' end', - ' local result = math.huge', - ' for _, v in ipairs(t) do', - ' if v < result then', - ' result = v', - ' end', - ' end', - ' return result', - 'end']); - break; - - case 'AVERAGE': - // Returns 0 for the empty list. - functionName = Blockly.Lua.provideFunction_( - 'math_average', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' if #t == 0 then', - ' return 0', - ' end', - ' return ' + provideSum() + '(t) / #t', - 'end']); - break; - - case 'MAX': - // Returns 0 for the empty list. - functionName = Blockly.Lua.provideFunction_( - 'math_max', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' if #t == 0 then', - ' return 0', - ' end', - ' local result = -math.huge', - ' for _, v in ipairs(t) do', - ' if v > result then', - ' result = v', - ' end', - ' end', - ' return result', - 'end']); - break; - - case 'MEDIAN': - functionName = Blockly.Lua.provideFunction_( - 'math_median', - // This operation excludes non-numbers. - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' -- Source: http://lua-users.org/wiki/SimpleStats', - ' if #t == 0 then', - ' return 0', - ' end', - ' local temp={}', - ' for _, v in ipairs(t) do', - ' if type(v) == "number" then', - ' table.insert(temp, v)', - ' end', - ' end', - ' table.sort(temp)', - ' if #temp % 2 == 0 then', - ' return (temp[#temp/2] + temp[(#temp/2)+1]) / 2', - ' else', - ' return temp[math.ceil(#temp/2)]', - ' end', - 'end']); - break; - - case 'MODE': - functionName = Blockly.Lua.provideFunction_( - 'math_modes', - // As a list of numbers can contain more than one mode, - // the returned result is provided as an array. - // The Lua version includes non-numbers. - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' -- Source: http://lua-users.org/wiki/SimpleStats', - ' local counts={}', - ' for _, v in ipairs(t) do', - ' if counts[v] == nil then', - ' counts[v] = 1', - ' else', - ' counts[v] = counts[v] + 1', - ' end', - ' end', - ' local biggestCount = 0', - ' for _, v in pairs(counts) do', - ' if v > biggestCount then', - ' biggestCount = v', - ' end', - ' end', - ' local temp={}', - ' for k, v in pairs(counts) do', - ' if v == biggestCount then', - ' table.insert(temp, k)', - ' end', - ' end', - ' return temp', - 'end']); - break; - - case 'STD_DEV': - functionName = Blockly.Lua.provideFunction_( - 'math_standard_deviation', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' local m', - ' local vm', - ' local total = 0', - ' local count = 0', - ' local result', - ' m = #t == 0 and 0 or ' + provideSum() + '(t) / #t', - ' for _, v in ipairs(t) do', - " if type(v) == 'number' then", - ' vm = v - m', - ' total = total + (vm * vm)', - ' count = count + 1', - ' end', - ' end', - ' result = math.sqrt(total / (count-1))', - ' return result', - 'end']); - break; - - case 'RANDOM': - functionName = Blockly.Lua.provideFunction_( - 'math_random_list', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', - ' if #t == 0 then', - ' return nil', - ' end', - ' return t[math.random(#t)]', - 'end']); - break; - - default: - throw 'Unknown operator: ' + func; - } - return [functionName + '(' + list + ')', Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['math_modulo'] = function(block) { - // Remainder computation. - var argument0 = Blockly.Lua.valueToCode(block, 'DIVIDEND', - Blockly.Lua.ORDER_MULTIPLICATIVE) || '0'; - var argument1 = Blockly.Lua.valueToCode(block, 'DIVISOR', - Blockly.Lua.ORDER_MULTIPLICATIVE) || '0'; - var code = argument0 + ' % ' + argument1; - return [code, Blockly.Lua.ORDER_MULTIPLICATIVE]; -}; - -Blockly.Lua['math_constrain'] = function(block) { - // Constrain a number between two limits. - var argument0 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '0'; - var argument1 = Blockly.Lua.valueToCode(block, 'LOW', - Blockly.Lua.ORDER_NONE) || '-math.huge'; - var argument2 = Blockly.Lua.valueToCode(block, 'HIGH', - Blockly.Lua.ORDER_NONE) || 'math.huge'; - var code = 'math.min(math.max(' + argument0 + ', ' + argument1 + '), ' + - argument2 + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['math_random_int'] = function(block) { - // Random integer between [X] and [Y]. - var argument0 = Blockly.Lua.valueToCode(block, 'FROM', - Blockly.Lua.ORDER_NONE) || '0'; - var argument1 = Blockly.Lua.valueToCode(block, 'TO', - Blockly.Lua.ORDER_NONE) || '0'; - var code = 'math.random(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['math_random_float'] = function(block) { - // Random fraction between 0 and 1. - return ['math.random()', Blockly.Lua.ORDER_HIGH]; -}; diff --git a/generators/lua/procedures.js b/generators/lua/procedures.js deleted file mode 100644 index e8a37c0794..0000000000 --- a/generators/lua/procedures.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Generating Lua for procedure blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - */ -'use strict'; - -goog.provide('Blockly.Lua.procedures'); - -goog.require('Blockly.Lua'); - - -Blockly.Lua['procedures_defreturn'] = function(block) { - // Define a procedure with a return value. - var funcName = Blockly.Lua.variableDB_.getName( - block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE); - var branch = Blockly.Lua.statementToCode(block, 'STACK'); - if (Blockly.Lua.STATEMENT_PREFIX) { - branch = Blockly.Lua.prefixLines( - Blockly.Lua.STATEMENT_PREFIX.replace(/%1/g, - '\'' + block.id + '\''), Blockly.Lua.INDENT) + branch; - } - if (Blockly.Lua.INFINITE_LOOP_TRAP) { - branch = Blockly.Lua.INFINITE_LOOP_TRAP.replace(/%1/g, - '\'' + block.id + '\'') + branch; - } - var returnValue = Blockly.Lua.valueToCode(block, 'RETURN', - Blockly.Lua.ORDER_NONE) || ''; - if (returnValue) { - returnValue = ' return ' + returnValue + '\n'; - } else if (!branch) { - branch = ''; - } - var args = []; - for (var x = 0; x < block.arguments_.length; x++) { - args[x] = Blockly.Lua.variableDB_.getName(block.arguments_[x], - Blockly.Variables.NAME_TYPE); - } - var code = 'function ' + funcName + '(' + args.join(', ') + ')\n' + - branch + returnValue + 'end\n'; - code = Blockly.Lua.scrub_(block, code); - Blockly.Lua.definitions_[funcName] = code; - return null; -}; - -// Defining a procedure without a return value uses the same generator as -// a procedure with a return value. -Blockly.Lua['procedures_defnoreturn'] = - Blockly.Lua['procedures_defreturn']; - -Blockly.Lua['procedures_callreturn'] = function(block) { - // Call a procedure with a return value. - var funcName = Blockly.Lua.variableDB_.getName( - block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE); - var args = []; - for (var x = 0; x < block.arguments_.length; x++) { - args[x] = Blockly.Lua.valueToCode(block, 'ARG' + x, - Blockly.Lua.ORDER_NONE) || 'nil'; - } - var code = funcName + '(' + args.join(', ') + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['procedures_callnoreturn'] = function(block) { - // Call a procedure with no return value. - var funcName = Blockly.Lua.variableDB_.getName( - block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE); - var args = []; - for (var x = 0; x < block.arguments_.length; x++) { - args[x] = Blockly.Lua.valueToCode(block, 'ARG' + x, - Blockly.Lua.ORDER_NONE) || 'nil'; - } - var code = funcName + '(' + args.join(', ') + ')\n'; - return code; -}; - -Blockly.Lua['procedures_ifreturn'] = function(block) { - // Conditionally return value from a procedure. - var condition = Blockly.Lua.valueToCode(block, 'CONDITION', - Blockly.Lua.ORDER_NONE) || 'false'; - var code = 'if ' + condition + ' then\n'; - if (block.hasReturnValue_) { - var value = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || 'nil'; - code += ' return ' + value + '\n'; - } else { - code += ' return\n'; - } - code += 'end\n'; - return code; -}; diff --git a/generators/lua/text.js b/generators/lua/text.js deleted file mode 100644 index 7e7c73f6a3..0000000000 --- a/generators/lua/text.js +++ /dev/null @@ -1,293 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Generating Lua for text blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - */ -'use strict'; - -goog.provide('Blockly.Lua.texts'); - -goog.require('Blockly.Lua'); - - -Blockly.Lua['text'] = function(block) { - // Text value. - var code = Blockly.Lua.quote_(block.getFieldValue('TEXT')); - return [code, Blockly.Lua.ORDER_ATOMIC]; -}; - -Blockly.Lua['text_join'] = function(block) { - // Create a string made up of any number of elements of any type. - if (block.itemCount_ == 0) { - return ['\'\'', Blockly.Lua.ORDER_ATOMIC]; - } else if (block.itemCount_ == 1) { - var argument0 = Blockly.Lua.valueToCode(block, 'ADD0', - Blockly.Lua.ORDER_NONE) || '\'\''; - var code = argument0; - return [code, Blockly.Lua.ORDER_HIGH]; - } else if (block.itemCount_ == 2) { - var argument0 = Blockly.Lua.valueToCode(block, 'ADD0', - Blockly.Lua.ORDER_NONE) || '\'\''; - var argument1 = Blockly.Lua.valueToCode(block, 'ADD1', - Blockly.Lua.ORDER_NONE) || '\'\''; - var code = argument0 + ' .. ' + argument1; - return [code, Blockly.Lua.ORDER_UNARY]; - } else { - var code = []; - for (var n = 0; n < block.itemCount_; n++) { - code[n] = Blockly.Lua.valueToCode(block, 'ADD' + n, - Blockly.Lua.ORDER_NONE) || '\'\''; - } - code = 'table.concat({' + code.join(', ') + '})'; - return [code, Blockly.Lua.ORDER_HIGH]; - } -}; - -Blockly.Lua['text_append'] = function(block) { - // Append to a variable in place. - var varName = Blockly.Lua.variableDB_.getName( - block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); - var argument0 = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; - return varName + ' = ' + varName + ' .. ' + argument0 + '\n'; -}; - -Blockly.Lua['text_length'] = function(block) { - // String or array length. - var argument0 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_HIGH) || '\'\''; - return ['#' + argument0, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['text_isEmpty'] = function(block) { - // Is the string null or array empty? - var argument0 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_HIGH) || '\'\''; - return ['#' + argument0 + ' == 0', Blockly.Lua.ORDER_RELATIONAL]; -}; - -Blockly.Lua['text_indexOf'] = function(block) { - // Search the text for a substring. - var operator = block.getFieldValue('END') == 'FIRST' ? - 'indexOf' : 'lastIndexOf'; - var substr = Blockly.Lua.valueToCode(block, 'FIND', - Blockly.Lua.ORDER_NONE) || '\'\''; - var str = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '\'\''; - if (block.getTitleValue('END') == 'FIRST') { - var functionName = Blockly.Lua.provideFunction_( - 'firstIndexOf', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + - '(str, substr) ', - ' local i = string.find(str, substr, 1, true)', - ' if i == nil then', - ' return 0', - ' else', - ' return i', - ' end', - 'end']); - } else { - var functionName = Blockly.Lua.provideFunction_( - 'lastIndexOf', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + - '(str, substr)', - ' local i = string.find(string.reverse(str), ' + - 'string.reverse(substr), 1, true)', - ' if i then', - ' return #str + 2 - i - #substr', - ' end', - ' return 0', - 'end']); - } - var code = functionName + '(' + str + ', ' + substr + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['text_charAt'] = function(block) { - // Get letter at index. - // Note: Until January 2013 this block did not have the WHERE input. - var where = block.getFieldValue('WHERE') || 'FROM_START'; - var at = Blockly.Lua.valueToCode(block, 'AT', - Blockly.Lua.ORDER_UNARY) || '1'; - var text = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '\'\''; - var code; - if (where == 'RANDOM') { - var functionName = Blockly.Lua.provideFunction_( - 'text_random_letter', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)', - ' local index = math.random(string.len(str))', - ' return string.sub(str, index, index)', - 'end']); - code = functionName + '(' + text + ')'; - } else { - if (where == 'FIRST') { - var start = '1'; - } else if (where == 'LAST') { - var start = '-1'; - } else { - if (where == 'FROM_START') { - var start = at; - } else if (where == 'FROM_END') { - var start = '-' + at; - } else { - throw 'Unhandled option (text_charAt).'; - } - } - if (start.match(/^-?\w*$/)) { - code = 'string.sub(' + text + ', ' + start + ', ' + start + ')'; - } else { - // use function to avoid reevaluation - var functionName = Blockly.Lua.provideFunction_( - 'text_char_at', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + - '(str, index)', - ' return string.sub(str, index, index)', - 'end']); - code = functionName + '(' + text + ', ' + start + ')'; - } - } - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['text_getSubstring'] = function(block) { - // Get substring. - var text = Blockly.Lua.valueToCode(block, 'STRING', - Blockly.Lua.ORDER_NONE) || '\'\''; - - // Get start index. - var where1 = block.getFieldValue('WHERE1'); - var at1 = Blockly.Lua.valueToCode(block, 'AT1', - Blockly.Lua.ORDER_UNARY) || '1'; - if (where1 == 'FIRST') { - var start = 1; - } else if (where1 == 'FROM_START') { - var start = at1; - } else if (where1 == 'FROM_END') { - var start = '-' + at1; - } else { - throw 'Unhandled option (text_getSubstring)'; - } - - // Get end index. - var where2 = block.getFieldValue('WHERE2'); - var at2 = Blockly.Lua.valueToCode(block, 'AT2', - Blockly.Lua.ORDER_UNARY) || '1'; - if (where2 == 'LAST') { - var end = -1; - } else if (where2 == 'FROM_START') { - var end = at2; - } else if (where2 == 'FROM_END') { - var end = '-' + at2; - } else { - throw 'Unhandled option (text_getSubstring)'; - } - var code = 'string.sub(' + text + ', ' + start + ', ' + end + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['text_changeCase'] = function(block) { - // Change capitalization. - var operator = block.getFieldValue('CASE'); - var argument0 = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; - if (operator == 'UPPERCASE') { - var functionName = 'string.upper'; - } else if (operator == 'LOWERCASE') { - var functionName = 'string.lower'; - } else if (operator == 'TITLECASE') { - var functionName = Blockly.Lua.provideFunction_( - 'text_titlecase', - // There are shorter versions at - // http://lua-users.org/wiki/SciteTitleCase - // that do not preserve whitespace. - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)', - ' local buf = {}', - ' local inWord = false', - ' for i = 1, #str do', - ' local c = string.sub(str, i, i)', - ' if inWord then', - ' table.insert(buf, string.lower(c))', - ' if string.find(c, "%s") then', - ' inWord = false', - ' end', - ' else', - ' table.insert(buf, string.upper(c))', - ' inWord = true', - ' end', - ' end', - ' return table.concat(buf)', - 'end']); - } - var code = functionName + '(' + argument0 + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['text_trim'] = function(block) { - // Trim spaces. - var OPERATORS = { - LEFT: '^%s*(,-)', - RIGHT: '(.-)%s*$', - BOTH: '^%s*(.-)%s*$' - }; - var operator = OPERATORS[block.getFieldValue('MODE')]; - var text = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; - var code = 'string.gsub(' + text + ', "' + operator + '", "%1")'; - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['text_print'] = function(block) { - // Print statement. - var argument0 = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; - return 'print(' + argument0 + ')\n'; -}; - -Blockly.Lua['text_prompt_ext'] = function(block) { - // Prompt function. - if (block.getField('TEXT')) { - // Internal message. - var msg = Blockly.Lua.quote_(block.getFieldValue('TEXT')); - } else { - // External message. - var msg = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; - } - - var functionName = Blockly.Lua.provideFunction_( - 'text_prompt', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(msg)', - ' io.write(msg)', - ' io.flush()', - ' return io.read()', - 'end']); - var code = functionName + '(' + msg + ')'; - - var toNumber = block.getFieldValue('TYPE') == 'NUMBER'; - if (toNumber) { - code = 'tonumber(' + code + ', 10)'; - } - return [code, Blockly.Lua.ORDER_HIGH]; -}; - -Blockly.Lua['text_prompt'] = Blockly.Lua['text_prompt_ext']; diff --git a/generators/lua/variables.js b/generators/lua/variables.js deleted file mode 100644 index 10b53d1de8..0000000000 --- a/generators/lua/variables.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @license - * Visual Blocks Language - * - * 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 Generating Lua for variable blocks. - * @author rodrigoq@google.com (Rodrigo Queiro) - */ -'use strict'; - -goog.provide('Blockly.Lua.variables'); - -goog.require('Blockly.Lua'); - - -Blockly.Lua['variables_get'] = function(block) { - // Variable getter. - var code = Blockly.Lua.variableDB_.getName(block.getFieldValue('VAR'), - Blockly.Variables.NAME_TYPE); - return [code, Blockly.Lua.ORDER_ATOMIC]; -}; - -Blockly.Lua['variables_set'] = function(block) { - // Variable setter. - var argument0 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '0'; - var varName = Blockly.Lua.variableDB_.getName( - block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); - return varName + ' = ' + argument0 + '\n'; -}; From 1d0db41521b8c4aff1dab2886e6c6058bd469ae3 Mon Sep 17 00:00:00 2001 From: Tim Mickel Date: Tue, 15 Mar 2016 10:39:41 -0400 Subject: [PATCH 14/14] Recompile March 15 --- blockly_compressed_horizontal.js | 83 +++++++++++++++++------------- blockly_compressed_vertical.js | 81 ++++++++++++++++------------- blockly_uncompressed_horizontal.js | 2 +- blockly_uncompressed_vertical.js | 2 +- blocks_compressed.js | 17 +++--- msg/js/fr.js | 20 +++---- msg/js/pt.js | 2 +- msg/js/sr.js | 32 ++++++------ msg/js/zh-hant.js | 30 +++++------ msg/json/en.json | 2 +- msg/json/qqq.json | 2 +- 11 files changed, 147 insertions(+), 126 deletions(-) diff --git a/blockly_compressed_horizontal.js b/blockly_compressed_horizontal.js index 8a12219bdc..a979eeaa1b 100644 --- a/blockly_compressed_horizontal.js +++ b/blockly_compressed_horizontal.js @@ -856,7 +856,7 @@ Blockly.Workspace=function(a){this.id=Blockly.genUid();Blockly.Workspace.Workspa 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.prototype.getTopBlocks=function(a){var b=[].concat(this.topBlocks_);if(a&&1this.MAX_UNDO&&this.undoStack_.unshift());for(var b=0,c;c=this.listeners_[b];b++)c(a)};Blockly.Workspace.prototype.addTapListener=function(a){this.tapListeners_.push(a);return a}; Blockly.Workspace.prototype.removeTapListener=function(a){a=this.tapListeners_.indexOf(a);-1!=a&&this.tapListeners_.splice(a,1)};Blockly.Workspace.prototype.fireTapListener=function(a,b){for(var c=0,d;d=this.tapListeners_[c];c++)d(a,b)};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.addChangeListener=Blockly.Workspace.prototype.addChangeListener; Blockly.Workspace.prototype.removeChangeListener=Blockly.Workspace.prototype.removeChangeListener;Blockly.Bubble=function(a,b,c,d,e,f,g){this.workspace_=a;this.content_=b;this.shape_=c;c=Blockly.Bubble.ARROW_ANGLE;this.workspace_.RTL&&(c=-c);this.arrow_radians_=goog.math.toRadians(c);a.getBubbleCanvas().appendChild(this.createDom_(b,!(!f||!g)));this.setAnchorLocation(d,e);f&&g||(b=this.content_.getBBox(),f=b.width+2*Blockly.Bubble.BORDER_WIDTH,g=b.height+2*Blockly.Bubble.BORDER_WIDTH);this.setBubbleSize(f,g);this.positionBubble_();this.renderArrow_();this.rendered_=!0;a.options.readOnly||(Blockly.bindEvent_(this.bubbleBack_, @@ -904,8 +904,8 @@ Blockly.Connection.prototype.canConnectWithReason_=function(a){if(a){if(this.sou 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 are on different workspaces.";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())return!1;var c=a.sourceBlock_,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.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&& +!this.sourceBlock_.nextConnection)return!1;var c=a.sourceBlock_,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;d=this.length)return-1;for(var c=a.y_,d=b;0<=d&&this[d].y_==c;){if(this[d]==a)return d;d--}for(;ba.y_)c=d;else{b=d;break}}return b};Blockly.ConnectionDB.prototype.removeConnection_=function(a){if(!a.inDB_)throw"Connection not in database.";var b=this.findConnection(a);if(-1==b)throw"Unable to find connection in connectionDB.";a.inDB_=!1;this.splice(b,1)}; +Blockly.ConnectionDB.prototype.getNeighbours=function(a,b){function c(a){var c=e-d[a].x_,g=f-d[a].y_;Math.sqrt(c*c+g*g)<=b&&l.push(d[a]);return g=this.remainingCapacity())){Blockly.terminateDrag_();Blockly.Events.disable();var b=Blockly.Xml.domToBlock(this,a),c=parseInt(a.getAttribute("x"),10);a=parseInt(a.getAttribute("y"),10);if(!isNaN(c)&&!isNaN(a)){this.RTL&&(c=-c);do{for(var d=!1,e=this.getAllBlocks(),f=0,g;g=e[f];f++)if(g=g.getRelativeToSurfaceXY(),1>=Math.abs(c-g.x)&&1>=Math.abs(a-g.y)){d=!0;break}if(!d)for(e=b.getConnections_(!1), f=0;g=e[f];f++)if(g.closest(Blockly.SNAP_RADIUS,c,a).connection){d=!0;break}d&&(c=this.RTL?c-Blockly.SNAP_RADIUS:c+Blockly.SNAP_RADIUS,a+=2*Blockly.SNAP_RADIUS)}while(d);b.moveBy(c,a)}Blockly.Events.enable();Blockly.Events.isEnabled()&&!b.isShadow()&&Blockly.Events.fire(new Blockly.Events.Create(b));b.select()}}; Blockly.WorkspaceSvg.prototype.recordDeleteAreas=function(){this.deleteAreaTrash_=this.trashcan?this.trashcan.getClientRect():null;this.deleteAreaToolbox_=this.flyout_?this.flyout_.getClientRect():this.toolbox_?this.toolbox_.getClientRect():null}; @@ -1022,7 +1026,8 @@ Blockly.WorkspaceSvg.prototype.onMouseDown_=function(a){this.markFocused();Block a.clientY,this.startDragMetrics=this.getMetrics(),this.startScrollX=this.scrollX,this.startScrollY=this.scrollY,"mouseup"in Blockly.bindEvent_.TOUCH_MAP&&(Blockly.onTouchUpWrapper_=Blockly.onTouchUpWrapper_||[],Blockly.onTouchUpWrapper_=Blockly.onTouchUpWrapper_.concat(Blockly.bindEvent_(document,"mouseup",null,Blockly.onMouseUp_))),Blockly.onMouseMoveWrapper_=Blockly.onMouseMoveWrapper_||[],Blockly.onMouseMoveWrapper_=Blockly.onMouseMoveWrapper_.concat(Blockly.bindEvent_(document,"mousemove",null, Blockly.onMouseMove_))),a.stopPropagation())};Blockly.WorkspaceSvg.prototype.startDrag=function(a,b,c){a=Blockly.mouseToSvg(a,this.getParentSvg());a.x/=this.scale;a.y/=this.scale;this.dragDeltaX_=b-a.x;this.dragDeltaY_=c-a.y};Blockly.WorkspaceSvg.prototype.moveDrag=function(a){a=Blockly.mouseToSvg(a,this.getParentSvg());a.x/=this.scale;a.y/=this.scale;return new goog.math.Coordinate(this.dragDeltaX_+a.x,this.dragDeltaY_+a.y)}; Blockly.WorkspaceSvg.prototype.onMouseWheel_=function(a){Blockly.terminateDrag_();var b=0b.bottomRight.x&&(b.bottomRight.x=d.bottomRight.x);d.topLeft.yb.bottomRight.y&&(b.bottomRight.y=d.bottomRight.y)}return{x:b.topLeft.x,y:b.topLeft.y,width:b.bottomRight.x- +b.topLeft.x,height:b.bottomRight.y-b.topLeft.y}};Blockly.WorkspaceSvg.prototype.cleanUp_=function(){Blockly.Events.setGroup(!0);for(var a=this.getTopBlocks(!0),b=0,c=0,d;d=a[c];c++){var e=d.getRelativeToSurfaceXY();d.moveBy(-e.x,b-e.y);d.snapToGrid();b=d.getRelativeToSurfaceXY().y+d.getHeightWidth().height+Blockly.BlockSvg.MIN_BLOCK_Y}Blockly.Events.setGroup(!1);Blockly.fireUiEvent(window,"resize")}; Blockly.WorkspaceSvg.prototype.showContextMenu_=function(a){function b(a){if(a.isDeletable())n=n.concat(a.getDescendants());else{a=a.getChildren();for(var c=0;c=n.length?Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",String(n.length)),enabled:0< n.length,callback:function(){(2>n.length||window.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace("%1",String(n.length))))&&c()}};d.push(f);Blockly.ContextMenu.show(a,d,this.RTL)}};Blockly.Workspace.prototype.setAudioCallback=function(a){this.audioCallback_=a};Blockly.WorkspaceSvg.prototype.playAudio=function(a){this.audioCallback_&&this.audioCallback_(a)}; @@ -1046,7 +1051,7 @@ this.workspace_.flyout_?(a=2*this.workspace_.flyout_.CORNER_RADIUS,b=this.worksp null,this.workspace_.dispose(),this.rootBlock_=this.workspace_=null,this.bubble_.dispose(),this.bubble_=null,this.workspaceHeight_=this.workspaceWidth_=0,this.sourceListener_&&(this.block_.workspace.removeChangeListener(this.sourceListener_),this.sourceListener_=null)}; Blockly.Mutator.prototype.workspaceChanged_=function(){if(0==Blockly.dragMode_)for(var a=this.workspace_.getTopBlocks(!1),b=0,c;c=a[b];b++){var d=c.getRelativeToSurfaceXY(),e=c.getHeightWidth();20>d.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.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.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){c=b.getInput(c).connection;var d=a.targetBlock();d&&d!=b||c.targetConnection==a||(c.targetConnection&&c.disconnect(),c.connect(a))}};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.svgPath_=Blockly.createSvgElement("path",{"class":"blocklyPath"},this.svgGroup_);this.svgPath_.tooltip=this;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.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.svgPath_=Blockly.createSvgElement("path",{"class":"blocklyPath"},this.svgGroup_);this.svgPath_.tooltip=this;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.prototype.isGlowing_=!1;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=a.clientX&&0==a.clientY&&0==a.button)){Blockly.removeAllRanges();var b=this.getRelativeToSurfaceXY(),c=this.workspace.moveDrag(a),d=this.getSvgRoot();1==Blockly.dragMode_&&goog.math.Coordinate.distance(b,c)*this.workspace.scale>Blockly.DRAG_RADIUS&&(Blockly.dragMode_=2,Blockly.longStop_(),d.translate_="",d.skew_="",this.parentBlock_&&(this.unplug(),this.disconnectUiEffect()),this.setDragging_(!0));if(2==Blockly.dragMode_){var e= -b.x-this.dragStartXY_.x,b=b.y-this.dragStartXY_.y;d.translate_="translate("+c.x+","+c.y+")";d.setAttribute("transform",d.translate_+d.skew_);for(c=0;c"+a+"");b.domToMutation(d.firstChild)}Blockly.Events.fire(new Blockly.Events.Change(b,"mutation",null,c,a))}};Blockly.Events.Move=function(a){Blockly.Events.Move.superClass_.constructor.call(this,a);a=this.currentLocation_();this.oldParentId=a.parentId;this.oldInputName=a.inputName;this.oldCoordinate=a.coordinate};goog.inherits(Blockly.Events.Move,Blockly.Events.Abstract); -Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate};Blockly.Events.Move.prototype.currentLocation_=function(){var a=Blockly.Block.getById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b}; -Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&goog.math.Coordinate.equals(this.oldCoordinate,this.newCoordinate)}; -Blockly.Events.Move.prototype.run=function(a){var b=Blockly.Block.getById(this.blockId);if(b){var c=a?this.newParentId:this.oldParentId,d=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var e=null;if(c&&(e=Blockly.Block.getById(c),!e))return;b.getParent()&&b.unplug();if(a)d=b.getRelativeToSurfaceXY(),b.moveBy(a.x-d.x,a.y-d.y);else{var b=b.outputConnection||b.previousConnection,f;d?(c=e.getInput(d))?f=c.connection:console.warn("Can't connect to non-existant input: "+ -d):b.type==Blockly.PREVIOUS_STATEMENT&&(f=e.nextConnection);f&&b.connect(f)}}};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)}; +(c=(c=b.mutationToDom())&&Blockly.Xml.domToText(c));if(b.domToMutation){var d=Blockly.Xml.textToDom(""+a+"");b.domToMutation(d.firstChild)}Blockly.Events.fire(new Blockly.Events.Change(b,"mutation",null,c,a));break;default:console.warn("Unknown change type: "+this.element)}else console.warn("Can't change non-existant block: "+this.blockId)}; +Blockly.Events.Move=function(a){Blockly.Events.Move.superClass_.constructor.call(this,a);a=this.currentLocation_();this.oldParentId=a.parentId;this.oldInputName=a.inputName;this.oldCoordinate=a.coordinate};goog.inherits(Blockly.Events.Move,Blockly.Events.Abstract);Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate}; +Blockly.Events.Move.prototype.currentLocation_=function(){var a=Blockly.Block.getById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b};Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&goog.math.Coordinate.equals(this.oldCoordinate,this.newCoordinate)}; +Blockly.Events.Move.prototype.run=function(a){var b=Blockly.Block.getById(this.blockId);if(b){var c=a?this.newParentId:this.oldParentId,d=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var e=null;if(c&&(e=Blockly.Block.getById(c),!e)){console.warn("Can't connect to non-existant block: "+c);return}b.getParent()&&b.unplug();if(a)d=b.getRelativeToSurfaceXY(),b.moveBy(a.x-d.x,a.y-d.y);else{var b=b.outputConnection||b.previousConnection,f;if(d){if(c=e.getInput(d))f=c.connection}else b.type== +Blockly.PREVIOUS_STATEMENT&&(f=e.nextConnection);f?b.connect(f):console.warn("Can't connect to non-existant input: "+d)}}else console.warn("Can't move non-existant block: "+this.blockId)};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)}; Blockly.FieldTextInput.prototype.setValue=function(a){if(null!==a){if(this.sourceBlock_&&this.validator_){var b=this.validator_(a);null!==b&&void 0!==b&&(a=b)}Blockly.Field.prototype.setValue.call(this,a)}};Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a}; Blockly.FieldTextInput.prototype.showEditor_=function(a){var b=this.sourceBlock_.workspace;a=a||!1;if(!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD))b=window.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_),this.sourceBlock_&&this.validator_&&(a=this.validator_(b),void 0!==a&&(b=a)),this.setValue(b);else{Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,this.widgetDispose_());var c=Blockly.WidgetDiv.DIV,d=goog.dom.createDom("input","blocklyHtmlInput");d.setAttribute("spellcheck", this.spellcheck_);var e=Blockly.FieldTextInput.FONTSIZE*b.scale+"pt";c.style.fontSize=e;d.style.fontSize=e;Blockly.FieldTextInput.htmlInput_=d;c.appendChild(d);d.value=d.defaultValue=this.text_;d.oldValue_=null;this.validate_();this.resizeEditor_();a||(d.focus(),d.select());d.onKeyDownWrapper_=Blockly.bindEvent_(d,"keydown",this,this.onHtmlInputKeyDown_);d.onKeyUpWrapper_=Blockly.bindEvent_(d,"keyup",this,this.onHtmlInputChange_);d.onKeyPressWrapper_=Blockly.bindEvent_(d,"keypress",this,this.onHtmlInputChange_); @@ -1183,7 +1193,7 @@ Blockly.FieldAngle.prototype.updateGraph_=function(){if(this.gauge_){var a=Numbe Blockly.FieldAngle.RADIUS;b=Math.abs(Math.floor((b-e)/Math.PI)%2);Blockly.FieldAngle.CLOCKWISE&&(b=1-b);a.push(" l ",f,",",g," A ",Blockly.FieldAngle.RADIUS,",",Blockly.FieldAngle.RADIUS," 0 ",b," ",Number(Blockly.FieldAngle.CLOCKWISE)," ",c,",",d," z")}this.gauge_.setAttribute("d",a.join(""));this.line_.setAttribute("x2",c);this.line_.setAttribute("y2",d)}}; Blockly.FieldAngle.angleValidator=function(a){a=Blockly.FieldTextInput.numberValidator(a);null!==a&&(a%=360,0>a&&(a+=360),a>Blockly.FieldAngle.WRAP&&(a-=360),a=String(a));return a};Blockly.FieldCheckbox=function(a,b){Blockly.FieldCheckbox.superClass_.constructor.call(this,"",b);this.setValue(a)};goog.inherits(Blockly.FieldCheckbox,Blockly.Field);Blockly.FieldCheckbox.prototype.CURSOR="default"; Blockly.FieldCheckbox.prototype.init=function(a){this.sourceBlock_||(Blockly.FieldCheckbox.superClass_.init.call(this,a),this.checkElement_=Blockly.createSvgElement("text",{"class":"blocklyText",x:-3,y:14},this.fieldGroup_),a=document.createTextNode("\u2713"),this.checkElement_.appendChild(a),this.checkElement_.style.display=this.state_?"block":"none")};Blockly.FieldCheckbox.prototype.getValue=function(){return String(this.state_).toUpperCase()}; -Blockly.FieldCheckbox.prototype.setValue=function(a){a="TRUE"==a;this.state_!==a&&(this.state_=a,this.checkElement_&&(this.checkElement_.style.display=a?"block":"none"))};Blockly.FieldCheckbox.prototype.showEditor_=function(){var a=!this.state_;if(this.sourceBlock_&&this.validator_){var b=this.validator_(a);void 0!==b&&(a=b)}null!==a&&this.setValue(String(a).toUpperCase())};Blockly.FieldColour=function(a,b){Blockly.FieldColour.superClass_.constructor.call(this,a,b);this.setText(Blockly.Field.NBSP+Blockly.Field.NBSP+Blockly.Field.NBSP)};goog.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.prototype.colours_=null;Blockly.FieldColour.prototype.columns_=0;Blockly.FieldColour.prototype.init=function(a){Blockly.FieldColour.superClass_.init.call(this,a);this.borderRect_.style.fillOpacity=1;this.setValue(this.getValue())}; +Blockly.FieldCheckbox.prototype.setValue=function(a){a="TRUE"==a;this.state_!==a&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.Change(this.sourceBlock_,"field",this.name,this.state_,a)),this.state_=a,this.checkElement_&&(this.checkElement_.style.display=a?"block":"none"))};Blockly.FieldCheckbox.prototype.showEditor_=function(){var a=!this.state_;if(this.sourceBlock_&&this.validator_){var b=this.validator_(a);void 0!==b&&(a=b)}null!==a&&this.setValue(String(a).toUpperCase())};Blockly.FieldColour=function(a,b){Blockly.FieldColour.superClass_.constructor.call(this,a,b);this.setText(Blockly.Field.NBSP+Blockly.Field.NBSP+Blockly.Field.NBSP)};goog.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.prototype.colours_=null;Blockly.FieldColour.prototype.columns_=0;Blockly.FieldColour.prototype.init=function(a){Blockly.FieldColour.superClass_.init.call(this,a);this.borderRect_.style.fillOpacity=1;this.setValue(this.getValue())}; Blockly.FieldColour.prototype.CURSOR="default";Blockly.FieldColour.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldColour.superClass_.dispose.call(this)};Blockly.FieldColour.prototype.getValue=function(){return this.colour_}; Blockly.FieldColour.prototype.setValue=function(a){this.sourceBlock_&&Blockly.Events.isEnabled()&&this.colour_!=a&&Blockly.Events.fire(new Blockly.Events.Change(this.sourceBlock_,"field",this.name,this.colour_,a));this.colour_=a;this.borderRect_&&(this.borderRect_.style.fill=a)};Blockly.FieldColour.prototype.getText=function(){var a=this.colour_,b=a.match(/^#(.)\1(.)\2(.)\3$/);b&&(a="#"+b[1]+b[2]+b[3]);return a};Blockly.FieldColour.COLOURS=goog.ui.ColorPicker.SIMPLE_GRID_COLORS; Blockly.FieldColour.COLUMNS=7;Blockly.FieldColour.prototype.setColours=function(a){this.colours_=a;return this};Blockly.FieldColour.prototype.setColumns=function(a){this.columns_=a;return this}; @@ -1309,7 +1319,8 @@ parseFloat(q.startScale);t.maxScale=void 0===q.maxScale?3:parseFloat(q.maxScale) void 0,toolboxPosition:m}}; Blockly.createDom_=function(a,b){a.setAttribute("dir","LTR");goog.ui.Component.setDefaultRightToLeft(b.RTL);Blockly.Css.inject(b.hasCss,b.pathToMedia);var c=Blockly.createSvgElement("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:html":"http://www.w3.org/1999/xhtml","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1","class":"blocklySvg"},a),d=Blockly.createSvgElement("defs",{},c),e=String(Math.random()).substring(2),f=Blockly.createSvgElement("filter",{id:"blocklyEmbossFilter"+e},d);Blockly.createSvgElement("feGaussianBlur", {"in":"SourceAlpha",stdDeviation:1,result:"blur"},f);var g=Blockly.createSvgElement("feSpecularLighting",{"in":"blur",surfaceScale:1,specularConstant:.5,specularExponent:10,"lighting-color":"white",result:"specOut"},f);Blockly.createSvgElement("fePointLight",{x:-5E3,y:-1E4,z:2E4},g);Blockly.createSvgElement("feComposite",{"in":"specOut",in2:"SourceAlpha",operator:"in",result:"specOut"},f);Blockly.createSvgElement("feComposite",{"in":"SourceGraphic",in2:"specOut",operator:"arithmetic",k1:0,k2:1,k3:1, -k4:0},f);b.embossFilterId=f.id;f=Blockly.createSvgElement("pattern",{id:"blocklyDisabledPattern"+e,patternUnits:"userSpaceOnUse",width:10,height:10},d);Blockly.createSvgElement("rect",{width:10,height:10,fill:"#aaa"},f);Blockly.createSvgElement("path",{d:"M 0 0 L 10 10 M 10 0 L 0 10",stroke:"#cc0"},f);b.disabledPatternId=f.id;d=Blockly.createSvgElement("pattern",{id:"blocklyGridPattern"+e,patternUnits:"userSpaceOnUse"},d);0a.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(),n=k.getHeightWidth(),m=f+25-n.height-l.y;0m&&k.moveBy(0,m);m=25+e-l.x-(b.RTL?0:n.width);0m&&k.moveBy(m,0)}}});Blockly.svgResize(c);Blockly.WidgetDiv.createDom();Blockly.Tooltip.createDom(); @@ -1339,7 +1350,7 @@ Blockly.onKeyDown_=function(a){if(!Blockly.isTargetInput_(a)){var b=!1;if(27==a. Blockly.clipboardSource_.paste(Blockly.clipboardXml_):90==a.keyCode&&Blockly.mainWorkspace.undo(a.shiftKey);b&&(Blockly.hideChaff(),Blockly.selected.dispose(2!=Blockly.dragMode_,!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.copy_=function(a){var b=Blockly.Xml.blockToDom(a);2!=Blockly.dragMode_&&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;try{var e=this.getCanvas().getBBox()}catch(l){return null}var 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),e=Math.max(k+g+d/2,k+d)):(b=e.x,c=b+e.width,f=e.y,e=f+e.height);d=0;this.toolbox_&& -this.toolbox_.toolboxPosition==Blockly.TOOLBOX_AT_LEFT&&(d=this.toolbox_.width);return{viewHeight:a.height,viewWidth:a.width,contentHeight:e-f,contentWidth:c-b,viewTop:-this.scrollY,viewLeft:-this.scrollX,contentTop:f,contentLeft:b,absoluteTop:0,absoluteLeft:d}}; +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.toolbox_&&this.toolbox_.toolboxPosition== +Blockly.TOOLBOX_AT_LEFT&&(e=this.toolbox_.width);return{viewHeight:a.height,viewWidth:a.width,contentHeight:d-f,contentWidth:c-b,viewTop:-this.scrollY,viewLeft:-this.scrollX,contentTop:f,contentLeft:b,absoluteTop:0,absoluteLeft:e}}; Blockly.setMainWorkspaceMetrics_=function(a){if(!this.scrollbar)throw"Attempt to set main workspace scroll without scrollbars.";var b=this.getMetrics();goog.isNumber(a.x)&&(this.scrollX=-b.contentWidth*a.x-b.contentLeft);goog.isNumber(a.y)&&(this.scrollY=-b.contentHeight*a.y-b.contentTop);a=this.scrollX+b.absoluteLeft;b=this.scrollY+b.absoluteTop;this.translate(a,b);this.options.gridPattern&&(this.options.gridPattern.setAttribute("x",a),this.options.gridPattern.setAttribute("y",b),goog.userAgent.IE&& this.updateGridPattern_())};Blockly.addChangeListener=function(a){console.warn("Deprecated call to Blockly.addChangeListener, use workspace.addChangeListener instead.");return Blockly.getMainWorkspace().addChangeListener(a)};Blockly.getMainWorkspace=function(){return Blockly.mainWorkspace};goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.getMainWorkspace=Blockly.getMainWorkspace;goog.global.Blockly.addChangeListener=Blockly.addChangeListener; \ No newline at end of file diff --git a/blockly_compressed_vertical.js b/blockly_compressed_vertical.js index fa67265b7a..19b44bf328 100644 --- a/blockly_compressed_vertical.js +++ b/blockly_compressed_vertical.js @@ -856,7 +856,7 @@ Blockly.Workspace=function(a){this.id=Blockly.genUid();Blockly.Workspace.Workspa 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.prototype.getTopBlocks=function(a){var b=[].concat(this.topBlocks_);if(a&&1this.MAX_UNDO&&this.undoStack_.unshift());for(var b=0,c;c=this.listeners_[b];b++)c(a)};Blockly.Workspace.prototype.addTapListener=function(a){this.tapListeners_.push(a);return a}; Blockly.Workspace.prototype.removeTapListener=function(a){a=this.tapListeners_.indexOf(a);-1!=a&&this.tapListeners_.splice(a,1)};Blockly.Workspace.prototype.fireTapListener=function(a,b){for(var c=0,d;d=this.tapListeners_[c];c++)d(a,b)};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.addChangeListener=Blockly.Workspace.prototype.addChangeListener; Blockly.Workspace.prototype.removeChangeListener=Blockly.Workspace.prototype.removeChangeListener;Blockly.Bubble=function(a,b,c,d,e,f,g){this.workspace_=a;this.content_=b;this.shape_=c;c=Blockly.Bubble.ARROW_ANGLE;this.workspace_.RTL&&(c=-c);this.arrow_radians_=goog.math.toRadians(c);a.getBubbleCanvas().appendChild(this.createDom_(b,!(!f||!g)));this.setAnchorLocation(d,e);f&&g||(b=this.content_.getBBox(),f=b.width+2*Blockly.Bubble.BORDER_WIDTH,g=b.height+2*Blockly.Bubble.BORDER_WIDTH);this.setBubbleSize(f,g);this.positionBubble_();this.renderArrow_();this.rendered_=!0;a.options.readOnly||(Blockly.bindEvent_(this.bubbleBack_, @@ -904,8 +904,8 @@ Blockly.Connection.prototype.canConnectWithReason_=function(a){if(a){if(this.sou 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 are on different workspaces.";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())return!1;var c=a.sourceBlock_,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.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&& +!this.sourceBlock_.nextConnection)return!1;var c=a.sourceBlock_,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;d=this.length)return-1;for(var c=a.y_,d=b;0<=d&&this[d].y_==c;){if(this[d]==a)return d;d--}for(;ba.y_)c=d;else{b=d;break}}return b};Blockly.ConnectionDB.prototype.removeConnection_=function(a){if(!a.inDB_)throw"Connection not in database.";var b=this.findConnection(a);if(-1==b)throw"Unable to find connection in connectionDB.";a.inDB_=!1;this.splice(b,1)}; +Blockly.ConnectionDB.prototype.getNeighbours=function(a,b){function c(a){var c=e-d[a].x_,g=f-d[a].y_;Math.sqrt(c*c+g*g)<=b&&m.push(d[a]);return g=this.remainingCapacity())){Blockly.terminateDrag_();Blockly.Events.disable();var b=Blockly.Xml.domToBlock(this,a),c=parseInt(a.getAttribute("x"),10);a=parseInt(a.getAttribute("y"),10);if(!isNaN(c)&&!isNaN(a)){this.RTL&&(c=-c);do{for(var d=!1,e=this.getAllBlocks(),f=0,g;g=e[f];f++)if(g=g.getRelativeToSurfaceXY(),1>=Math.abs(c-g.x)&&1>=Math.abs(a-g.y)){d=!0;break}if(!d)for(e=b.getConnections_(!1), f=0;g=e[f];f++)if(g.closest(Blockly.SNAP_RADIUS,c,a).connection){d=!0;break}d&&(c=this.RTL?c-Blockly.SNAP_RADIUS:c+Blockly.SNAP_RADIUS,a+=2*Blockly.SNAP_RADIUS)}while(d);b.moveBy(c,a)}Blockly.Events.enable();Blockly.Events.isEnabled()&&!b.isShadow()&&Blockly.Events.fire(new Blockly.Events.Create(b));b.select()}}; Blockly.WorkspaceSvg.prototype.recordDeleteAreas=function(){this.deleteAreaTrash_=this.trashcan?this.trashcan.getClientRect():null;this.deleteAreaToolbox_=this.flyout_?this.flyout_.getClientRect():this.toolbox_?this.toolbox_.getClientRect():null}; @@ -1022,7 +1026,8 @@ Blockly.WorkspaceSvg.prototype.onMouseDown_=function(a){this.markFocused();Block a.clientY,this.startDragMetrics=this.getMetrics(),this.startScrollX=this.scrollX,this.startScrollY=this.scrollY,"mouseup"in Blockly.bindEvent_.TOUCH_MAP&&(Blockly.onTouchUpWrapper_=Blockly.onTouchUpWrapper_||[],Blockly.onTouchUpWrapper_=Blockly.onTouchUpWrapper_.concat(Blockly.bindEvent_(document,"mouseup",null,Blockly.onMouseUp_))),Blockly.onMouseMoveWrapper_=Blockly.onMouseMoveWrapper_||[],Blockly.onMouseMoveWrapper_=Blockly.onMouseMoveWrapper_.concat(Blockly.bindEvent_(document,"mousemove",null, Blockly.onMouseMove_))),a.stopPropagation())};Blockly.WorkspaceSvg.prototype.startDrag=function(a,b,c){a=Blockly.mouseToSvg(a,this.getParentSvg());a.x/=this.scale;a.y/=this.scale;this.dragDeltaX_=b-a.x;this.dragDeltaY_=c-a.y};Blockly.WorkspaceSvg.prototype.moveDrag=function(a){a=Blockly.mouseToSvg(a,this.getParentSvg());a.x/=this.scale;a.y/=this.scale;return new goog.math.Coordinate(this.dragDeltaX_+a.x,this.dragDeltaY_+a.y)}; Blockly.WorkspaceSvg.prototype.onMouseWheel_=function(a){Blockly.terminateDrag_();var b=0b.bottomRight.x&&(b.bottomRight.x=d.bottomRight.x);d.topLeft.yb.bottomRight.y&&(b.bottomRight.y=d.bottomRight.y)}return{x:b.topLeft.x,y:b.topLeft.y,width:b.bottomRight.x- +b.topLeft.x,height:b.bottomRight.y-b.topLeft.y}};Blockly.WorkspaceSvg.prototype.cleanUp_=function(){Blockly.Events.setGroup(!0);for(var a=this.getTopBlocks(!0),b=0,c=0,d;d=a[c];c++){var e=d.getRelativeToSurfaceXY();d.moveBy(-e.x,b-e.y);d.snapToGrid();b=d.getRelativeToSurfaceXY().y+d.getHeightWidth().height+Blockly.BlockSvg.MIN_BLOCK_Y}Blockly.Events.setGroup(!1);Blockly.fireUiEvent(window,"resize")}; Blockly.WorkspaceSvg.prototype.showContextMenu_=function(a){function b(a){if(a.isDeletable())n=n.concat(a.getDescendants());else{a=a.getChildren();for(var c=0;c=n.length?Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",String(n.length)),enabled:0< n.length,callback:function(){(2>n.length||window.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace("%1",String(n.length))))&&c()}};d.push(f);Blockly.ContextMenu.show(a,d,this.RTL)}};Blockly.Workspace.prototype.setAudioCallback=function(a){this.audioCallback_=a};Blockly.WorkspaceSvg.prototype.playAudio=function(a){this.audioCallback_&&this.audioCallback_(a)}; @@ -1046,7 +1051,7 @@ this.workspace_.flyout_?(a=2*this.workspace_.flyout_.CORNER_RADIUS,b=this.worksp null,this.workspace_.dispose(),this.rootBlock_=this.workspace_=null,this.bubble_.dispose(),this.bubble_=null,this.workspaceHeight_=this.workspaceWidth_=0,this.sourceListener_&&(this.block_.workspace.removeChangeListener(this.sourceListener_),this.sourceListener_=null)}; Blockly.Mutator.prototype.workspaceChanged_=function(){if(0==Blockly.dragMode_)for(var a=this.workspace_.getTopBlocks(!1),b=0,c;c=a[b];b++){var d=c.getRelativeToSurfaceXY(),e=c.getHeightWidth();20>d.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.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.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){c=b.getInput(c).connection;var d=a.targetBlock();d&&d!=b||c.targetConnection==a||(c.targetConnection&&c.disconnect(),c.connect(a))}};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.svgPath_=Blockly.createSvgElement("path",{"class":"blocklyPath"},this.svgGroup_);this.svgPath_.tooltip=this;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.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.svgPath_=Blockly.createSvgElement("path",{"class":"blocklyPath"},this.svgGroup_);this.svgPath_.tooltip=this;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.prototype.isGlowing_=!1;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=a.clientX&&0==a.clientY&&0==a.button)){Blockly.removeAllRanges();var b=this.getRelativeToSurfaceXY(),c=this.workspace.moveDrag(a),d=this.getSvgRoot();1==Blockly.dragMode_&&goog.math.Coordinate.distance(b,c)*this.workspace.scale>Blockly.DRAG_RADIUS&&(Blockly.dragMode_=2,Blockly.longStop_(),d.translate_="",d.skew_="",this.parentBlock_&&(this.unplug(),this.disconnectUiEffect()),this.setDragging_(!0));if(2==Blockly.dragMode_){var e= -b.x-this.dragStartXY_.x,b=b.y-this.dragStartXY_.y;d.translate_="translate("+c.x+","+c.y+")";d.setAttribute("transform",d.translate_+d.skew_);for(c=0;c"+a+"");b.domToMutation(d.firstChild)}Blockly.Events.fire(new Blockly.Events.Change(b,"mutation",null,c,a))}};Blockly.Events.Move=function(a){Blockly.Events.Move.superClass_.constructor.call(this,a);a=this.currentLocation_();this.oldParentId=a.parentId;this.oldInputName=a.inputName;this.oldCoordinate=a.coordinate};goog.inherits(Blockly.Events.Move,Blockly.Events.Abstract); -Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate};Blockly.Events.Move.prototype.currentLocation_=function(){var a=Blockly.Block.getById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b}; -Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&goog.math.Coordinate.equals(this.oldCoordinate,this.newCoordinate)}; -Blockly.Events.Move.prototype.run=function(a){var b=Blockly.Block.getById(this.blockId);if(b){var c=a?this.newParentId:this.oldParentId,d=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var e=null;if(c&&(e=Blockly.Block.getById(c),!e))return;b.getParent()&&b.unplug();if(a)d=b.getRelativeToSurfaceXY(),b.moveBy(a.x-d.x,a.y-d.y);else{var b=b.outputConnection||b.previousConnection,f;d?(c=e.getInput(d))?f=c.connection:console.warn("Can't connect to non-existant input: "+ -d):b.type==Blockly.PREVIOUS_STATEMENT&&(f=e.nextConnection);f&&b.connect(f)}}};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)}; +(c=(c=b.mutationToDom())&&Blockly.Xml.domToText(c));if(b.domToMutation){var d=Blockly.Xml.textToDom(""+a+"");b.domToMutation(d.firstChild)}Blockly.Events.fire(new Blockly.Events.Change(b,"mutation",null,c,a));break;default:console.warn("Unknown change type: "+this.element)}else console.warn("Can't change non-existant block: "+this.blockId)}; +Blockly.Events.Move=function(a){Blockly.Events.Move.superClass_.constructor.call(this,a);a=this.currentLocation_();this.oldParentId=a.parentId;this.oldInputName=a.inputName;this.oldCoordinate=a.coordinate};goog.inherits(Blockly.Events.Move,Blockly.Events.Abstract);Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate}; +Blockly.Events.Move.prototype.currentLocation_=function(){var a=Blockly.Block.getById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b};Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&goog.math.Coordinate.equals(this.oldCoordinate,this.newCoordinate)}; +Blockly.Events.Move.prototype.run=function(a){var b=Blockly.Block.getById(this.blockId);if(b){var c=a?this.newParentId:this.oldParentId,d=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var e=null;if(c&&(e=Blockly.Block.getById(c),!e)){console.warn("Can't connect to non-existant block: "+c);return}b.getParent()&&b.unplug();if(a)d=b.getRelativeToSurfaceXY(),b.moveBy(a.x-d.x,a.y-d.y);else{var b=b.outputConnection||b.previousConnection,f;if(d){if(c=e.getInput(d))f=c.connection}else b.type== +Blockly.PREVIOUS_STATEMENT&&(f=e.nextConnection);f?b.connect(f):console.warn("Can't connect to non-existant input: "+d)}}else console.warn("Can't move non-existant block: "+this.blockId)};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)}; Blockly.FieldTextInput.prototype.setValue=function(a){if(null!==a){if(this.sourceBlock_&&this.validator_){var b=this.validator_(a);null!==b&&void 0!==b&&(a=b)}Blockly.Field.prototype.setValue.call(this,a)}};Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a}; Blockly.FieldTextInput.prototype.showEditor_=function(a){var b=this.sourceBlock_.workspace;a=a||!1;if(!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD))b=window.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_),this.sourceBlock_&&this.validator_&&(a=this.validator_(b),void 0!==a&&(b=a)),this.setValue(b);else{Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,this.widgetDispose_());var c=Blockly.WidgetDiv.DIV,d=goog.dom.createDom("input","blocklyHtmlInput");d.setAttribute("spellcheck", this.spellcheck_);var e=Blockly.FieldTextInput.FONTSIZE*b.scale+"pt";c.style.fontSize=e;d.style.fontSize=e;Blockly.FieldTextInput.htmlInput_=d;c.appendChild(d);d.value=d.defaultValue=this.text_;d.oldValue_=null;this.validate_();this.resizeEditor_();a||(d.focus(),d.select());d.onKeyDownWrapper_=Blockly.bindEvent_(d,"keydown",this,this.onHtmlInputKeyDown_);d.onKeyUpWrapper_=Blockly.bindEvent_(d,"keyup",this,this.onHtmlInputChange_);d.onKeyPressWrapper_=Blockly.bindEvent_(d,"keypress",this,this.onHtmlInputChange_); @@ -1188,7 +1198,7 @@ Blockly.FieldAngle.prototype.updateGraph_=function(){if(this.gauge_){var a=Numbe Blockly.FieldAngle.RADIUS;b=Math.abs(Math.floor((b-e)/Math.PI)%2);Blockly.FieldAngle.CLOCKWISE&&(b=1-b);a.push(" l ",f,",",g," A ",Blockly.FieldAngle.RADIUS,",",Blockly.FieldAngle.RADIUS," 0 ",b," ",Number(Blockly.FieldAngle.CLOCKWISE)," ",c,",",d," z")}this.gauge_.setAttribute("d",a.join(""));this.line_.setAttribute("x2",c);this.line_.setAttribute("y2",d)}}; Blockly.FieldAngle.angleValidator=function(a){a=Blockly.FieldTextInput.numberValidator(a);null!==a&&(a%=360,0>a&&(a+=360),a>Blockly.FieldAngle.WRAP&&(a-=360),a=String(a));return a};Blockly.FieldCheckbox=function(a,b){Blockly.FieldCheckbox.superClass_.constructor.call(this,"",b);this.setValue(a)};goog.inherits(Blockly.FieldCheckbox,Blockly.Field);Blockly.FieldCheckbox.prototype.CURSOR="default"; Blockly.FieldCheckbox.prototype.init=function(a){this.sourceBlock_||(Blockly.FieldCheckbox.superClass_.init.call(this,a),this.checkElement_=Blockly.createSvgElement("text",{"class":"blocklyText",x:-3,y:14},this.fieldGroup_),a=document.createTextNode("\u2713"),this.checkElement_.appendChild(a),this.checkElement_.style.display=this.state_?"block":"none")};Blockly.FieldCheckbox.prototype.getValue=function(){return String(this.state_).toUpperCase()}; -Blockly.FieldCheckbox.prototype.setValue=function(a){a="TRUE"==a;this.state_!==a&&(this.state_=a,this.checkElement_&&(this.checkElement_.style.display=a?"block":"none"))};Blockly.FieldCheckbox.prototype.showEditor_=function(){var a=!this.state_;if(this.sourceBlock_&&this.validator_){var b=this.validator_(a);void 0!==b&&(a=b)}null!==a&&this.setValue(String(a).toUpperCase())};Blockly.FieldColour=function(a,b){Blockly.FieldColour.superClass_.constructor.call(this,a,b);this.setText(Blockly.Field.NBSP+Blockly.Field.NBSP+Blockly.Field.NBSP)};goog.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.prototype.colours_=null;Blockly.FieldColour.prototype.columns_=0;Blockly.FieldColour.prototype.init=function(a){Blockly.FieldColour.superClass_.init.call(this,a);this.borderRect_.style.fillOpacity=1;this.setValue(this.getValue())}; +Blockly.FieldCheckbox.prototype.setValue=function(a){a="TRUE"==a;this.state_!==a&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.Change(this.sourceBlock_,"field",this.name,this.state_,a)),this.state_=a,this.checkElement_&&(this.checkElement_.style.display=a?"block":"none"))};Blockly.FieldCheckbox.prototype.showEditor_=function(){var a=!this.state_;if(this.sourceBlock_&&this.validator_){var b=this.validator_(a);void 0!==b&&(a=b)}null!==a&&this.setValue(String(a).toUpperCase())};Blockly.FieldColour=function(a,b){Blockly.FieldColour.superClass_.constructor.call(this,a,b);this.setText(Blockly.Field.NBSP+Blockly.Field.NBSP+Blockly.Field.NBSP)};goog.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.prototype.colours_=null;Blockly.FieldColour.prototype.columns_=0;Blockly.FieldColour.prototype.init=function(a){Blockly.FieldColour.superClass_.init.call(this,a);this.borderRect_.style.fillOpacity=1;this.setValue(this.getValue())}; Blockly.FieldColour.prototype.CURSOR="default";Blockly.FieldColour.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldColour.superClass_.dispose.call(this)};Blockly.FieldColour.prototype.getValue=function(){return this.colour_}; Blockly.FieldColour.prototype.setValue=function(a){this.sourceBlock_&&Blockly.Events.isEnabled()&&this.colour_!=a&&Blockly.Events.fire(new Blockly.Events.Change(this.sourceBlock_,"field",this.name,this.colour_,a));this.colour_=a;this.borderRect_&&(this.borderRect_.style.fill=a)};Blockly.FieldColour.prototype.getText=function(){var a=this.colour_,b=a.match(/^#(.)\1(.)\2(.)\3$/);b&&(a="#"+b[1]+b[2]+b[3]);return a};Blockly.FieldColour.COLOURS=goog.ui.ColorPicker.SIMPLE_GRID_COLORS; Blockly.FieldColour.COLUMNS=7;Blockly.FieldColour.prototype.setColours=function(a){this.colours_=a;return this};Blockly.FieldColour.prototype.setColumns=function(a){this.columns_=a;return this}; @@ -1314,7 +1324,8 @@ parseFloat(r.startScale);v.maxScale=void 0===r.maxScale?3:parseFloat(r.maxScale) void 0,toolboxPosition:l}}; Blockly.createDom_=function(a,b){a.setAttribute("dir","LTR");goog.ui.Component.setDefaultRightToLeft(b.RTL);Blockly.Css.inject(b.hasCss,b.pathToMedia);var c=Blockly.createSvgElement("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:html":"http://www.w3.org/1999/xhtml","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1","class":"blocklySvg"},a),d=Blockly.createSvgElement("defs",{},c),e=String(Math.random()).substring(2),f=Blockly.createSvgElement("filter",{id:"blocklyEmbossFilter"+e},d);Blockly.createSvgElement("feGaussianBlur", {"in":"SourceAlpha",stdDeviation:1,result:"blur"},f);var g=Blockly.createSvgElement("feSpecularLighting",{"in":"blur",surfaceScale:1,specularConstant:.5,specularExponent:10,"lighting-color":"white",result:"specOut"},f);Blockly.createSvgElement("fePointLight",{x:-5E3,y:-1E4,z:2E4},g);Blockly.createSvgElement("feComposite",{"in":"specOut",in2:"SourceAlpha",operator:"in",result:"specOut"},f);Blockly.createSvgElement("feComposite",{"in":"SourceGraphic",in2:"specOut",operator:"arithmetic",k1:0,k2:1,k3:1, -k4:0},f);b.embossFilterId=f.id;f=Blockly.createSvgElement("pattern",{id:"blocklyDisabledPattern"+e,patternUnits:"userSpaceOnUse",width:10,height:10},d);Blockly.createSvgElement("rect",{width:10,height:10,fill:"#aaa"},f);Blockly.createSvgElement("path",{d:"M 0 0 L 10 10 M 10 0 L 0 10",stroke:"#cc0"},f);b.disabledPatternId=f.id;d=Blockly.createSvgElement("pattern",{id:"blocklyGridPattern"+e,patternUnits:"userSpaceOnUse"},d);0a.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 m=k.getRelativeToSurfaceXY(),n=k.getHeightWidth(),l=f+25-n.height-m.y;0l&&k.moveBy(0,l);l=25+e-m.x-(b.RTL?0:n.width);0l&&k.moveBy(l,0)}}});Blockly.svgResize(c);Blockly.WidgetDiv.createDom();Blockly.Tooltip.createDom(); @@ -1344,7 +1355,7 @@ Blockly.onKeyDown_=function(a){if(!Blockly.isTargetInput_(a)){var b=!1;if(27==a. Blockly.clipboardSource_.paste(Blockly.clipboardXml_):90==a.keyCode&&Blockly.mainWorkspace.undo(a.shiftKey);b&&(Blockly.hideChaff(),Blockly.selected.dispose(2!=Blockly.dragMode_,!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.copy_=function(a){var b=Blockly.Xml.blockToDom(a);2!=Blockly.dragMode_&&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;try{var e=this.getCanvas().getBBox()}catch(m){return null}var 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),e=Math.max(k+g+d/2,k+d)):(b=e.x,c=b+e.width,f=e.y,e=f+e.height);d=0;this.toolbox_&& -this.toolbox_.toolboxPosition==Blockly.TOOLBOX_AT_LEFT&&(d=this.toolbox_.width);return{viewHeight:a.height,viewWidth:a.width,contentHeight:e-f,contentWidth:c-b,viewTop:-this.scrollY,viewLeft:-this.scrollX,contentTop:f,contentLeft:b,absoluteTop:0,absoluteLeft:d}}; +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.toolbox_&&this.toolbox_.toolboxPosition== +Blockly.TOOLBOX_AT_LEFT&&(e=this.toolbox_.width);return{viewHeight:a.height,viewWidth:a.width,contentHeight:d-f,contentWidth:c-b,viewTop:-this.scrollY,viewLeft:-this.scrollX,contentTop:f,contentLeft:b,absoluteTop:0,absoluteLeft:e}}; Blockly.setMainWorkspaceMetrics_=function(a){if(!this.scrollbar)throw"Attempt to set main workspace scroll without scrollbars.";var b=this.getMetrics();goog.isNumber(a.x)&&(this.scrollX=-b.contentWidth*a.x-b.contentLeft);goog.isNumber(a.y)&&(this.scrollY=-b.contentHeight*a.y-b.contentTop);a=this.scrollX+b.absoluteLeft;b=this.scrollY+b.absoluteTop;this.translate(a,b);this.options.gridPattern&&(this.options.gridPattern.setAttribute("x",a),this.options.gridPattern.setAttribute("y",b),goog.userAgent.IE&& this.updateGridPattern_())};Blockly.addChangeListener=function(a){console.warn("Deprecated call to Blockly.addChangeListener, use workspace.addChangeListener instead.");return Blockly.getMainWorkspace().addChangeListener(a)};Blockly.getMainWorkspace=function(){return Blockly.mainWorkspace};goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.getMainWorkspace=Blockly.getMainWorkspace;goog.global.Blockly.addChangeListener=Blockly.addChangeListener; \ No newline at end of file diff --git a/blockly_uncompressed_horizontal.js b/blockly_uncompressed_horizontal.js index b6ed870b0a..5400d5884b 100644 --- a/blockly_uncompressed_horizontal.js +++ b/blockly_uncompressed_horizontal.js @@ -79,7 +79,7 @@ goog.addDependency("../../../" + dir + "/core/variables.js", ['Blockly.Variables goog.addDependency("../../../" + dir + "/core/warning.js", ['Blockly.Warning'], ['Blockly.Bubble', 'Blockly.Icon']); goog.addDependency("../../../" + dir + "/core/widgetdiv.js", ['Blockly.WidgetDiv'], ['Blockly.Css', 'goog.dom', 'goog.style']); goog.addDependency("../../../" + dir + "/core/workspace.js", ['Blockly.Workspace'], ['goog.math']); -goog.addDependency("../../../" + dir + "/core/workspace_svg.js", ['Blockly.WorkspaceSvg'], ['Blockly.ScrollbarPair', 'Blockly.Trashcan', 'Blockly.ZoomControls', 'Blockly.Workspace', 'Blockly.Xml', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']); +goog.addDependency("../../../" + dir + "/core/workspace_svg.js", ['Blockly.WorkspaceSvg'], ['Blockly.ConnectionDB', 'Blockly.ScrollbarPair', 'Blockly.Trashcan', 'Blockly.ZoomControls', 'Blockly.Workspace', 'Blockly.Xml', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']); goog.addDependency("../../../" + dir + "/core/xml.js", ['Blockly.Xml'], ['goog.dom']); goog.addDependency("../../../" + dir + "/core/zoom_controls.js", ['Blockly.ZoomControls'], ['goog.dom']); goog.addDependency("../../alltests.js", [], []); diff --git a/blockly_uncompressed_vertical.js b/blockly_uncompressed_vertical.js index 9b2f73f441..878e90d72b 100644 --- a/blockly_uncompressed_vertical.js +++ b/blockly_uncompressed_vertical.js @@ -79,7 +79,7 @@ goog.addDependency("../../../" + dir + "/core/variables.js", ['Blockly.Variables goog.addDependency("../../../" + dir + "/core/warning.js", ['Blockly.Warning'], ['Blockly.Bubble', 'Blockly.Icon']); goog.addDependency("../../../" + dir + "/core/widgetdiv.js", ['Blockly.WidgetDiv'], ['Blockly.Css', 'goog.dom', 'goog.style']); goog.addDependency("../../../" + dir + "/core/workspace.js", ['Blockly.Workspace'], ['goog.math']); -goog.addDependency("../../../" + dir + "/core/workspace_svg.js", ['Blockly.WorkspaceSvg'], ['Blockly.ScrollbarPair', 'Blockly.Trashcan', 'Blockly.ZoomControls', 'Blockly.Workspace', 'Blockly.Xml', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']); +goog.addDependency("../../../" + dir + "/core/workspace_svg.js", ['Blockly.WorkspaceSvg'], ['Blockly.ConnectionDB', 'Blockly.ScrollbarPair', 'Blockly.Trashcan', 'Blockly.ZoomControls', 'Blockly.Workspace', 'Blockly.Xml', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']); goog.addDependency("../../../" + dir + "/core/xml.js", ['Blockly.Xml'], ['goog.dom']); goog.addDependency("../../../" + dir + "/core/zoom_controls.js", ['Blockly.ZoomControls'], ['goog.dom']); goog.addDependency("../../alltests.js", [], []); diff --git a/blocks_compressed.js b/blocks_compressed.js index 99c037e41b..edd2ce1a02 100644 --- a/blocks_compressed.js +++ b/blocks_compressed.js @@ -10,10 +10,9 @@ this.setOutput(!0,"Colour");this.setTooltip(Blockly.Msg.COLOUR_RGB_TOOLTIP)}}; Blockly.Blocks.colour_blend={init:function(){this.setHelpUrl(Blockly.Msg.COLOUR_BLEND_HELPURL);this.setColour(Blockly.Blocks.colour.HUE);this.appendValueInput("COLOUR1").setCheck("Colour").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.COLOUR_BLEND_TITLE).appendField(Blockly.Msg.COLOUR_BLEND_COLOUR1);this.appendValueInput("COLOUR2").setCheck("Colour").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.COLOUR_BLEND_COLOUR2);this.appendValueInput("RATIO").setCheck("Number").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.COLOUR_BLEND_RATIO); this.setOutput(!0,"Colour");this.setTooltip(Blockly.Msg.COLOUR_BLEND_TOOLTIP)}};Blockly.Blocks.lists={};Blockly.Blocks.lists.HUE=260;Blockly.Blocks.lists_create_empty={init:function(){this.jsonInit({message0:Blockly.Msg.LISTS_CREATE_EMPTY_TITLE,output:"Array",colour:Blockly.Blocks.lists.HUE,tooltip:Blockly.Msg.LISTS_CREATE_EMPTY_TOOLTIP,helpUrl:Blockly.Msg.LISTS_CREATE_EMPTY_HELPURL})}}; Blockly.Blocks.lists_create_with={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.itemCount_=3;this.updateShape_();this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"), -10);this.updateShape_()},decompose:function(a){var b=a.newBlock("lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d", - "lastupdated": "2016-03-03 11:56:58.060962", + "lastupdated": "2016-03-15 10:36:12.416062", "locale": "en", "messagedocumentation" : "qqq" }, diff --git a/msg/json/qqq.json b/msg/json/qqq.json index 21e32c763b..75aaa6d35e 100644 --- a/msg/json/qqq.json +++ b/msg/json/qqq.json @@ -85,7 +85,7 @@ "LOGIC_OPERATION_TOOLTIP_AND": "tooltip - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].", "LOGIC_OPERATION_AND": "block text - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].\n{{Identical|And}}", "LOGIC_OPERATION_TOOLTIP_OR": "block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].", - "LOGIC_OPERATION_OR": "block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].", + "LOGIC_OPERATION_OR": "block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].\n{{Identical|Or}}", "LOGIC_NEGATE_HELPURL": "url - Information about logical negation. The translation of [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation] is recommended if it exists in the target language.", "LOGIC_NEGATE_TITLE": "block text - This is a unary operator that returns ''false'' when the input is ''true'', and ''true'' when the input is ''false''. \n\nParameters:\n* %1 - the input (which should be either the value 'true' or 'false')", "LOGIC_NEGATE_TOOLTIP": "tooltip - See [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation].",