From 674625c47ea85143d2c5dcf814bb70258237b2ea Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Fri, 28 Nov 2014 21:43:39 -0800 Subject: [PATCH] Add red 'X' to mouse cursor if blocks are over flyout. --- blockly_compressed.js | 102 ++++++++++++++++++++-------------------- blockly_uncompressed.js | 6 +-- core/block.js | 19 +++++--- core/css.js | 25 ++++++++-- core/flyout.js | 18 +++++++ core/inject.js | 5 -- core/mutator.js | 27 ++++------- core/trashcan.js | 35 ++++---------- core/workspace.js | 49 +++++++++++++++++++ 9 files changed, 174 insertions(+), 112 deletions(-) diff --git a/blockly_compressed.js b/blockly_compressed.js index 9de94fa4..c2132a99 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -130,7 +130,29 @@ goog.math.standardAngleInRadians=function(a){return goog.math.modulo(a,2*Math.PI goog.math.angleDifference=function(a,b){var c=goog.math.standardAngle(b)-goog.math.standardAngle(a);180=c&&(c=360+c);return c};goog.math.sign=function(a){return 0==a?0:0>a?-1:1}; goog.math.longestCommonSubsequence=function(a,b,c,d){c=c||function(a,b){return a==b};d=d||function(b,c){return a[b]};for(var e=a.length,f=b.length,g=[],h=0;hg[h][k-1]?h--:k--;return l}; goog.math.sum=function(a){return goog.array.reduce(arguments,function(a,c){return a+c},0)};goog.math.average=function(a){return goog.math.sum.apply(null,arguments)/arguments.length};goog.math.sampleVariance=function(a){var b=arguments.length;if(2>b)return 0;var c=goog.math.average.apply(null,arguments);return goog.math.sum.apply(null,goog.array.map(arguments,function(a){return Math.pow(a-c,2)}))/(b-1)};goog.math.standardDeviation=function(a){return Math.sqrt(goog.math.sampleVariance.apply(null,arguments))}; -goog.math.isInt=function(a){return isFinite(a)&&0==a%1};goog.math.isFiniteNumber=function(a){return isFinite(a)&&!isNaN(a)};goog.math.log10Floor=function(a){if(0a)}return 0==a?-Infinity:NaN};goog.math.safeFloor=function(a,b){goog.asserts.assert(!goog.isDef(b)||0a)}return 0==a?-Infinity:NaN};goog.math.safeFloor=function(a,b){goog.asserts.assert(!goog.isDef(b)||0=a.left&&b.right<=a.right&&b.top>=a.top&&b.bottom<=a.bottom:b.x>=a.left&&b.x<=a.right&&b.y>=a.top&&b.y<=a.bottom:!1};goog.math.Box.relativePositionX=function(a,b){return b.xa.right?b.x-a.right:0}; +goog.math.Box.relativePositionY=function(a,b){return b.ya.bottom?b.y-a.bottom:0};goog.math.Box.distance=function(a,b){var c=goog.math.Box.relativePositionX(a,b),d=goog.math.Box.relativePositionY(a,b);return Math.sqrt(c*c+d*d)};goog.math.Box.intersects=function(a,b){return a.left<=b.right&&b.left<=a.right&&a.top<=b.bottom&&b.top<=a.bottom};goog.math.Box.intersectsWithPadding=function(a,b,c){return a.left<=b.right+c&&b.left<=a.right+c&&a.top<=b.bottom+c&&b.top<=a.bottom+c}; +goog.math.Box.prototype.ceil=function(){this.top=Math.ceil(this.top);this.right=Math.ceil(this.right);this.bottom=Math.ceil(this.bottom);this.left=Math.ceil(this.left);return this};goog.math.Box.prototype.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this}; +goog.math.Box.prototype.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};goog.math.Box.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+=a.y):(this.left+=a,this.right+=a,goog.isNumber(b)&&(this.top+=b,this.bottom+=b));return this}; +goog.math.Box.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.left*=a;this.right*=a;this.top*=c;this.bottom*=c;return this};goog.math.Size=function(a,b){this.width=a;this.height=b};goog.math.Size.equals=function(a,b){return a==b?!0:a&&b?a.width==b.width&&a.height==b.height:!1};goog.math.Size.prototype.clone=function(){return new goog.math.Size(this.width,this.height)};goog.DEBUG&&(goog.math.Size.prototype.toString=function(){return"("+this.width+" x "+this.height+")"});goog.math.Size.prototype.getLongest=function(){return Math.max(this.width,this.height)}; +goog.math.Size.prototype.getShortest=function(){return Math.min(this.width,this.height)};goog.math.Size.prototype.area=function(){return this.width*this.height};goog.math.Size.prototype.perimeter=function(){return 2*(this.width+this.height)};goog.math.Size.prototype.aspectRatio=function(){return this.width/this.height};goog.math.Size.prototype.isEmpty=function(){return!this.area()};goog.math.Size.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this}; +goog.math.Size.prototype.fitsInside=function(a){return this.width<=a.width&&this.height<=a.height};goog.math.Size.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};goog.math.Size.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};goog.math.Size.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.width*=a;this.height*=c;return this}; +goog.math.Size.prototype.scaleToFit=function(a){a=this.aspectRatio()>a.aspectRatio()?a.width/this.width:a.height/this.height;return this.scale(a)};goog.math.Rect=function(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d};goog.math.Rect.prototype.clone=function(){return new goog.math.Rect(this.left,this.top,this.width,this.height)};goog.math.Rect.prototype.toBox=function(){return new goog.math.Box(this.top,this.left+this.width,this.top+this.height,this.left)};goog.math.Rect.createFromBox=function(a){return new goog.math.Rect(a.left,a.top,a.right-a.left,a.bottom-a.top)}; +goog.DEBUG&&(goog.math.Rect.prototype.toString=function(){return"("+this.left+", "+this.top+" - "+this.width+"w x "+this.height+"h)"});goog.math.Rect.equals=function(a,b){return a==b?!0:a&&b?a.left==b.left&&a.width==b.width&&a.top==b.top&&a.height==b.height:!1}; +goog.math.Rect.prototype.intersection=function(a){var b=Math.max(this.left,a.left),c=Math.min(this.left+this.width,a.left+a.width);if(b<=c){var d=Math.max(this.top,a.top);a=Math.min(this.top+this.height,a.top+a.height);if(d<=a)return this.left=b,this.top=d,this.width=c-b,this.height=a-d,!0}return!1}; +goog.math.Rect.intersection=function(a,b){var c=Math.max(a.left,b.left),d=Math.min(a.left+a.width,b.left+b.width);if(c<=d){var e=Math.max(a.top,b.top),f=Math.min(a.top+a.height,b.top+b.height);if(e<=f)return new goog.math.Rect(c,e,d-c,f-e)}return null};goog.math.Rect.intersects=function(a,b){return a.left<=b.left+b.width&&b.left<=a.left+a.width&&a.top<=b.top+b.height&&b.top<=a.top+a.height};goog.math.Rect.prototype.intersects=function(a){return goog.math.Rect.intersects(this,a)}; +goog.math.Rect.difference=function(a,b){var c=goog.math.Rect.intersection(a,b);if(!c||!c.height||!c.width)return[a.clone()];var c=[],d=a.top,e=a.height,f=a.left+a.width,g=a.top+a.height,h=b.left+b.width,k=b.top+b.height;b.top>a.top&&(c.push(new goog.math.Rect(a.left,a.top,a.width,b.top-a.top)),d=b.top,e-=b.top-a.top);ka.left&&c.push(new goog.math.Rect(a.left,d,b.left-a.left,e));h=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height};goog.math.Rect.prototype.squaredDistance=function(a){var b=a.xa.aspectRatio()?a.width/this.width:a.height/this.height;return this.scale(a)};goog.dom.ASSUME_QUIRKS_MODE=!1;goog.dom.ASSUME_STANDARDS_MODE=!1;goog.dom.COMPAT_MODE_KNOWN_=goog.dom.ASSUME_QUIRKS_MODE||goog.dom.ASSUME_STANDARDS_MODE;goog.dom.getDomHelper=function(a){return a?new goog.dom.DomHelper(goog.dom.getOwnerDocument(a)):goog.dom.defaultDomHelper_||(goog.dom.defaultDomHelper_=new goog.dom.DomHelper)};goog.dom.getDocument=function(){return document};goog.dom.getElement=function(a){return goog.dom.getElementHelper_(document,a)}; +TIME:"TIME",TITLE:"TITLE",TR:"TR",TRACK:"TRACK",TT:"TT",U:"U",UL:"UL",VAR:"VAR",VIDEO:"VIDEO",WBR:"WBR"};goog.dom.ASSUME_QUIRKS_MODE=!1;goog.dom.ASSUME_STANDARDS_MODE=!1;goog.dom.COMPAT_MODE_KNOWN_=goog.dom.ASSUME_QUIRKS_MODE||goog.dom.ASSUME_STANDARDS_MODE;goog.dom.getDomHelper=function(a){return a?new goog.dom.DomHelper(goog.dom.getOwnerDocument(a)):goog.dom.defaultDomHelper_||(goog.dom.defaultDomHelper_=new goog.dom.DomHelper)};goog.dom.getDocument=function(){return document};goog.dom.getElement=function(a){return goog.dom.getElementHelper_(document,a)}; goog.dom.getElementHelper_=function(a,b){return goog.isString(b)?a.getElementById(b):b};goog.dom.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(document,a)};goog.dom.getRequiredElementHelper_=function(a,b){goog.asserts.assertString(b);var c=goog.dom.getElementHelper_(a,b);return c=goog.asserts.assertElement(c,"No element found with id: "+b)};goog.dom.$=goog.dom.getElement; goog.dom.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(document,a,b,c)};goog.dom.getElementsByClass=function(a,b){var c=b||document;return goog.dom.canUseQuerySelector_(c)?c.querySelectorAll("."+a):goog.dom.getElementsByTagNameAndClass_(document,"*",a,b)};goog.dom.getElementByClass=function(a,b){var c=b||document,d=null;return(d=goog.dom.canUseQuerySelector_(c)?c.querySelector("."+a):goog.dom.getElementsByTagNameAndClass_(document,"*",a,b)[0])||null}; goog.dom.getRequiredElementByClass=function(a,b){var c=goog.dom.getElementByClass(a,b);return goog.asserts.assert(c,"No element found with className: "+a)};goog.dom.canUseQuerySelector_=function(a){return!(!a.querySelectorAll||!a.querySelector)}; @@ -275,23 +291,7 @@ goog.dom.DomHelper.prototype.getNextNode=goog.dom.getNextNode;goog.dom.DomHelper goog.dom.DomHelper.prototype.findCommonAncestor=goog.dom.findCommonAncestor;goog.dom.DomHelper.prototype.getOwnerDocument=goog.dom.getOwnerDocument;goog.dom.DomHelper.prototype.getFrameContentDocument=goog.dom.getFrameContentDocument;goog.dom.DomHelper.prototype.getFrameContentWindow=goog.dom.getFrameContentWindow;goog.dom.DomHelper.prototype.setTextContent=goog.dom.setTextContent;goog.dom.DomHelper.prototype.getOuterHtml=goog.dom.getOuterHtml;goog.dom.DomHelper.prototype.findNode=goog.dom.findNode; goog.dom.DomHelper.prototype.findNodes=goog.dom.findNodes;goog.dom.DomHelper.prototype.isFocusableTabIndex=goog.dom.isFocusableTabIndex;goog.dom.DomHelper.prototype.setFocusableTabIndex=goog.dom.setFocusableTabIndex;goog.dom.DomHelper.prototype.isFocusable=goog.dom.isFocusable;goog.dom.DomHelper.prototype.getTextContent=goog.dom.getTextContent;goog.dom.DomHelper.prototype.getNodeTextLength=goog.dom.getNodeTextLength;goog.dom.DomHelper.prototype.getNodeTextOffset=goog.dom.getNodeTextOffset; goog.dom.DomHelper.prototype.getNodeAtOffset=goog.dom.getNodeAtOffset;goog.dom.DomHelper.prototype.isNodeList=goog.dom.isNodeList;goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass=goog.dom.getAncestorByTagNameAndClass;goog.dom.DomHelper.prototype.getAncestorByClass=goog.dom.getAncestorByClass;goog.dom.DomHelper.prototype.getAncestor=goog.dom.getAncestor;goog.dom.vendor={};goog.dom.vendor.getVendorJsPrefix=function(){return goog.userAgent.WEBKIT?"Webkit":goog.userAgent.GECKO?"Moz":goog.userAgent.IE?"ms":goog.userAgent.OPERA?"O":null};goog.dom.vendor.getVendorPrefix=function(){return goog.userAgent.WEBKIT?"-webkit":goog.userAgent.GECKO?"-moz":goog.userAgent.IE?"-ms":goog.userAgent.OPERA?"-o":null}; -goog.dom.vendor.getPrefixedPropertyName=function(a,b){if(b&&a in b)return a;var c=goog.dom.vendor.getVendorJsPrefix();return c?(c=c.toLowerCase(),c+=goog.string.toTitleCase(a),!goog.isDef(b)||c in b?c:null):null};goog.dom.vendor.getPrefixedEventType=function(a){return((goog.dom.vendor.getVendorJsPrefix()||"")+a).toLowerCase()};goog.math.Box=function(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d};goog.math.Box.boundingBox=function(a){for(var b=new goog.math.Box(arguments[0].y,arguments[0].x,arguments[0].y,arguments[0].x),c=1;c=a.left&&b.right<=a.right&&b.top>=a.top&&b.bottom<=a.bottom:b.x>=a.left&&b.x<=a.right&&b.y>=a.top&&b.y<=a.bottom:!1};goog.math.Box.relativePositionX=function(a,b){return b.xa.right?b.x-a.right:0}; -goog.math.Box.relativePositionY=function(a,b){return b.ya.bottom?b.y-a.bottom:0};goog.math.Box.distance=function(a,b){var c=goog.math.Box.relativePositionX(a,b),d=goog.math.Box.relativePositionY(a,b);return Math.sqrt(c*c+d*d)};goog.math.Box.intersects=function(a,b){return a.left<=b.right&&b.left<=a.right&&a.top<=b.bottom&&b.top<=a.bottom};goog.math.Box.intersectsWithPadding=function(a,b,c){return a.left<=b.right+c&&b.left<=a.right+c&&a.top<=b.bottom+c&&b.top<=a.bottom+c}; -goog.math.Box.prototype.ceil=function(){this.top=Math.ceil(this.top);this.right=Math.ceil(this.right);this.bottom=Math.ceil(this.bottom);this.left=Math.ceil(this.left);return this};goog.math.Box.prototype.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this}; -goog.math.Box.prototype.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};goog.math.Box.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+=a.y):(this.left+=a,this.right+=a,goog.isNumber(b)&&(this.top+=b,this.bottom+=b));return this}; -goog.math.Box.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.left*=a;this.right*=a;this.top*=c;this.bottom*=c;return this};goog.math.Rect=function(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d};goog.math.Rect.prototype.clone=function(){return new goog.math.Rect(this.left,this.top,this.width,this.height)};goog.math.Rect.prototype.toBox=function(){return new goog.math.Box(this.top,this.left+this.width,this.top+this.height,this.left)};goog.math.Rect.createFromBox=function(a){return new goog.math.Rect(a.left,a.top,a.right-a.left,a.bottom-a.top)}; -goog.DEBUG&&(goog.math.Rect.prototype.toString=function(){return"("+this.left+", "+this.top+" - "+this.width+"w x "+this.height+"h)"});goog.math.Rect.equals=function(a,b){return a==b?!0:a&&b?a.left==b.left&&a.width==b.width&&a.top==b.top&&a.height==b.height:!1}; -goog.math.Rect.prototype.intersection=function(a){var b=Math.max(this.left,a.left),c=Math.min(this.left+this.width,a.left+a.width);if(b<=c){var d=Math.max(this.top,a.top);a=Math.min(this.top+this.height,a.top+a.height);if(d<=a)return this.left=b,this.top=d,this.width=c-b,this.height=a-d,!0}return!1}; -goog.math.Rect.intersection=function(a,b){var c=Math.max(a.left,b.left),d=Math.min(a.left+a.width,b.left+b.width);if(c<=d){var e=Math.max(a.top,b.top),f=Math.min(a.top+a.height,b.top+b.height);if(e<=f)return new goog.math.Rect(c,e,d-c,f-e)}return null};goog.math.Rect.intersects=function(a,b){return a.left<=b.left+b.width&&b.left<=a.left+a.width&&a.top<=b.top+b.height&&b.top<=a.top+a.height};goog.math.Rect.prototype.intersects=function(a){return goog.math.Rect.intersects(this,a)}; -goog.math.Rect.difference=function(a,b){var c=goog.math.Rect.intersection(a,b);if(!c||!c.height||!c.width)return[a.clone()];var c=[],d=a.top,e=a.height,f=a.left+a.width,g=a.top+a.height,h=b.left+b.width,k=b.top+b.height;b.top>a.top&&(c.push(new goog.math.Rect(a.left,a.top,a.width,b.top-a.top)),d=b.top,e-=b.top-a.top);ka.left&&c.push(new goog.math.Rect(a.left,d,b.left-a.left,e));h=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height};goog.math.Rect.prototype.squaredDistance=function(a){var b=a.xb.x-this.MARGIN_HOTSPOT_&&a.xb.y-this.MARGIN_HOTSPOT_&&a.ythis.lidOpen_)this.lidTask_=goog.Timer.callOnce(this.animateLid_,20,this)};Blockly.Trashcan.prototype.close=function(){this.setOpen_(!1)}; // Copyright 2012 Google Inc. Apache License 2.0 Blockly.Xml={};Blockly.Xml.workspaceToDom=function(a){var b;Blockly.RTL&&(b=a.getMetrics().viewWidth);var c=goog.dom.createDom("xml");a=a.getTopBlocks(!0);for(var d=0,e;e=a[d];d++){var f=Blockly.Xml.blockToDom_(e);e=e.getRelativeToSurfaceXY();f.setAttribute("x",Blockly.RTL?b-e.x:e.x);f.setAttribute("y",e.y);c.appendChild(f)}return c}; @@ -898,8 +897,9 @@ a.render():d.render();return d};Blockly.Xml.deleteNext=function(a){for(var b=0,c // Copyright 2012 Google Inc. Apache License 2.0 Blockly.Workspace=function(a,b){this.getMetrics=a;this.setMetrics=b;this.isFlyout=!1;this.topBlocks_=[];this.maxBlocks=Infinity;Blockly.ConnectionDB.init(this)};Blockly.Workspace.SCAN_ANGLE=3;Blockly.Workspace.prototype.dragMode=!1;Blockly.Workspace.prototype.scrollX=0;Blockly.Workspace.prototype.scrollY=0;Blockly.Workspace.prototype.trashcan=null;Blockly.Workspace.prototype.fireChangeEventPid_=null;Blockly.Workspace.prototype.scrollbar=null; Blockly.Workspace.prototype.createDom=function(){this.svgGroup_=Blockly.createSvgElement("g",{},null);this.svgBlockCanvas_=Blockly.createSvgElement("g",{},this.svgGroup_);this.svgBubbleCanvas_=Blockly.createSvgElement("g",{},this.svgGroup_);this.fireChangeEvent();return this.svgGroup_}; -Blockly.Workspace.prototype.dispose=function(){this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.svgBubbleCanvas_=this.svgBlockCanvas_=null;this.trashcan&&(this.trashcan.dispose(),this.trashcan=null)};Blockly.Workspace.prototype.addTrashcan=function(){if(Blockly.hasTrashcan&&!Blockly.readOnly){this.trashcan=new Blockly.Trashcan(this);var a=this.trashcan.createDom();this.svgGroup_.insertBefore(a,this.svgBlockCanvas_);this.trashcan.init()}}; -Blockly.Workspace.prototype.getCanvas=function(){return this.svgBlockCanvas_};Blockly.Workspace.prototype.getBubbleCanvas=function(){return this.svgBubbleCanvas_};Blockly.Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a);Blockly.Realtime.isEnabled()&&this==Blockly.mainWorkspace&&Blockly.Realtime.addTopBlock(a);this.fireChangeEvent()}; +Blockly.Workspace.prototype.dispose=function(){this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.svgBubbleCanvas_=this.svgBlockCanvas_=null;this.flyout_&&(this.flyout_.dispose(),this.flyout_=null);this.trashcan&&(this.trashcan.dispose(),this.trashcan=null)}; +Blockly.Workspace.prototype.addTrashcan=function(){if(Blockly.hasTrashcan&&!Blockly.readOnly){this.trashcan=new Blockly.Trashcan(this);var a=this.trashcan.createDom();this.svgGroup_.insertBefore(a,this.svgBlockCanvas_);this.trashcan.init()}};Blockly.Workspace.prototype.getCanvas=function(){return this.svgBlockCanvas_};Blockly.Workspace.prototype.getBubbleCanvas=function(){return this.svgBubbleCanvas_}; +Blockly.Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a);Blockly.Realtime.isEnabled()&&this==Blockly.mainWorkspace&&Blockly.Realtime.addTopBlock(a);this.fireChangeEvent()}; 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.Realtime.isEnabled()&&this==Blockly.mainWorkspace&&Blockly.Realtime.removeTopBlock(a);this.fireChangeEvent()}; Blockly.Workspace.prototype.getTopBlocks=function(a){var b=[].concat(this.topBlocks_);if(a&&1=this.remainingCapacity())){var b=Blockly.Xml.domToBlock(this,a),c=parseInt(a.getAttribute("x"),10);a=parseInt(a.getAttribute("y"),10);if(!isNaN(c)&&!isNaN(a)){Blockly.RTL&&(c=-c);do for(var d=!1,e=this.getAllBlocks(),f=0,g;g=e[f];f++)g=g.getRelativeToSurfaceXY(),1>=Math.abs(c-g.x)&&1>=Math.abs(a-g.y)&&(c=Blockly.RTL?c-Blockly.SNAP_RADIUS:c+Blockly.SNAP_RADIUS,a+=2*Blockly.SNAP_RADIUS,d=!0);while(d);b.moveBy(c, -a)}b.select()}};Blockly.Workspace.prototype.remainingCapacity=function(){return Infinity==this.maxBlocks?Infinity:this.maxBlocks-this.getAllBlocks().length};Blockly.Workspace.prototype.clear=Blockly.Workspace.prototype.clear; +a)}b.select()}};Blockly.Workspace.prototype.remainingCapacity=function(){return Infinity==this.maxBlocks?Infinity:this.maxBlocks-this.getAllBlocks().length};Blockly.Workspace.prototype.recordDeleteAreas=function(){this.deleteAreaTrash_=this.trashcan?this.trashcan.getRect():null;this.deleteAreaToolbox_=this.flyout_?this.flyout_.getRect():null}; +Blockly.Workspace.prototype.isDeleteArea=function(a){a=Blockly.mouseToSvg(a);a=new goog.math.Coordinate(a.x,a.y);if(this.deleteAreaTrash_){if(this.deleteAreaTrash_.contains(a))return this.trashcan.setOpen_(!0),Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE),!0;this.trashcan.setOpen_(!1)}if(this.deleteAreaToolbox_&&this.deleteAreaToolbox_.contains(a))return Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE),!0;Blockly.Css.setCursor(Blockly.Css.Cursor.CLOSED);return!1}; +Blockly.Workspace.prototype.clear=Blockly.Workspace.prototype.clear; // Copyright 2012 Google Inc. Apache License 2.0 Blockly.Bubble=function(a,b,c,d,e,f,g){var h=Blockly.Bubble.ARROW_ANGLE;Blockly.RTL&&(h=-h);this.arrow_radians_=goog.math.toRadians(h);this.workspace_=a;this.content_=b;this.shape_=c;a.getBubbleCanvas().appendChild(this.createDom_(b,!(!f||!g)));this.setAnchorLocation(d,e);f&&g||(a=this.content_.getBBox(),f=a.width+2*Blockly.Bubble.BORDER_WIDTH,g=a.height+2*Blockly.Bubble.BORDER_WIDTH);this.setBubbleSize(f,g);this.positionBubble_();this.renderArrow_();this.rendered_=!0;Blockly.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; @@ -1009,15 +1011,15 @@ Blockly.Msg={}; Blockly.Mutator=function(a){Blockly.Mutator.superClass_.constructor.call(this,null);this.quarkXml_=[];for(var b=0;ba||Math.abs(this.workspaceHeight_-b)>a)this.workspaceWidth_=d,this.workspaceHeight_=b,this.bubble_.setBubbleSize(d+a,b+a),this.svgDialog_.setAttribute("width",this.workspaceWidth_),this.svgDialog_.setAttribute("height",this.workspaceHeight_); -Blockly.RTL&&(a="translate("+this.workspaceWidth_+",0)",this.workspace_.getCanvas().setAttribute("transform",a))}; -Blockly.Mutator.prototype.setVisible=function(a){if(a!=this.isVisible())if(a){this.bubble_=new Blockly.Bubble(this.block_.workspace,this.createEditor_(),this.block_.svg_.svgPath_,this.iconX_,this.iconY_,null,null);var b=this;this.flyout_.init(this.workspace_);this.flyout_.show(this.quarkXml_);this.rootBlock_=this.block_.decompose(this.workspace_);a=this.rootBlock_.getDescendants();for(var c=0,d;d=a[c];c++)d.render();this.rootBlock_.setMovable(!1);this.rootBlock_.setDeletable(!1);a=2*this.flyout_.CORNER_RADIUS; -c=this.flyout_.width_+a;Blockly.RTL&&(c=-c);this.rootBlock_.moveBy(c,a);this.block_.saveConnections&&(this.block_.saveConnections(this.rootBlock_),this.sourceListener_=Blockly.bindEvent_(this.block_.workspace.getCanvas(),"blocklyWorkspaceChange",this.block_,function(){b.block_.saveConnections(b.rootBlock_)}));this.resizeBubble_();Blockly.bindEvent_(this.workspace_.getCanvas(),"blocklyWorkspaceChange",this.block_,function(){b.workspaceChanged_()});this.updateColour()}else this.svgDialog_=null,this.flyout_.dispose(), -this.flyout_=null,this.workspace_.dispose(),this.rootBlock_=this.workspace_=null,this.bubble_.dispose(),this.bubble_=null,this.workspaceHeight_=this.workspaceWidth_=0,this.sourceListener_&&(Blockly.unbindEvent_(this.sourceListener_),this.sourceListener_=null)}; -Blockly.Mutator.prototype.workspaceChanged_=function(){if(0==Blockly.Block.dragMode_)for(var a=this.workspace_.getTopBlocks(!1),b=0,c;c=a[b];b++){var d=c.getRelativeToSurfaceXY(),e=c.getHeightWidth();c.isDeletable()&&(Blockly.RTL?d.x>-this.flyout_.width_+20:d.xd.y+e.height&&c.moveBy(0,20-e.height-d.y)}this.rootBlock_.workspace==this.workspace_&&(a=this.block_.rendered,this.block_.rendered=!1,this.block_.compose(this.rootBlock_),this.block_.rendered=a,this.block_.rendered&& -this.block_.render(),this.resizeBubble_(),this.block_.workspace.fireChangeEvent())};Blockly.Mutator.prototype.getFlyoutMetrics_=function(){var a=0;Blockly.RTL&&(a+=this.workspaceWidth_);return{viewHeight:this.workspaceHeight_,viewWidth:0,absoluteTop:0,absoluteLeft:a}};Blockly.Mutator.prototype.dispose=function(){this.block_.mutator=null;Blockly.Icon.prototype.dispose.call(this)}; +Blockly.Mutator.prototype.createEditor_=function(){this.svgDialog_=Blockly.createSvgElement("svg",{x:Blockly.Bubble.BORDER_WIDTH,y:Blockly.Bubble.BORDER_WIDTH},null);Blockly.createSvgElement("rect",{"class":"blocklyMutatorBackground",height:"100%",width:"100%"},this.svgDialog_);var a=this;this.workspace_=new Blockly.Workspace(function(){return a.getFlyoutMetrics_()},null);this.workspace_.flyout_=new Blockly.Flyout;this.workspace_.flyout_.autoClose=!1;this.svgDialog_.appendChild(this.workspace_.flyout_.createDom()); +this.svgDialog_.appendChild(this.workspace_.createDom());return this.svgDialog_};Blockly.Mutator.prototype.updateEditable=function(){this.block_.isEditable()?Blockly.Icon.prototype.updateEditable.call(this):(this.setVisible(!1),Blockly.removeClass_(this.iconGroup_,"blocklyIconGroup"))}; +Blockly.Mutator.prototype.resizeBubble_=function(){var a=2*Blockly.Bubble.BORDER_WIDTH,b=this.workspace_.getCanvas().getBBox(),c=this.workspace_.flyout_.getMetrics_(),d;d=Blockly.RTL?-b.x:b.width+b.x;b=Math.max(b.height+3*a,c.contentHeight+20);d+=3*a;if(Math.abs(this.workspaceWidth_-d)>a||Math.abs(this.workspaceHeight_-b)>a)this.workspaceWidth_=d,this.workspaceHeight_=b,this.bubble_.setBubbleSize(d+a,b+a),this.svgDialog_.setAttribute("width",this.workspaceWidth_),this.svgDialog_.setAttribute("height", +this.workspaceHeight_);Blockly.RTL&&(a="translate("+this.workspaceWidth_+",0)",this.workspace_.getCanvas().setAttribute("transform",a))}; +Blockly.Mutator.prototype.setVisible=function(a){if(a!=this.isVisible())if(a){this.bubble_=new Blockly.Bubble(this.block_.workspace,this.createEditor_(),this.block_.svg_.svgPath_,this.iconX_,this.iconY_,null,null);var b=this;this.workspace_.flyout_.init(this.workspace_);this.workspace_.flyout_.show(this.quarkXml_);this.rootBlock_=this.block_.decompose(this.workspace_);a=this.rootBlock_.getDescendants();for(var c=0,d;d=a[c];c++)d.render();this.rootBlock_.setMovable(!1);this.rootBlock_.setDeletable(!1); +a=2*this.workspace_.flyout_.CORNER_RADIUS;c=this.workspace_.flyout_.width_+a;Blockly.RTL&&(c=-c);this.rootBlock_.moveBy(c,a);this.block_.saveConnections&&(this.block_.saveConnections(this.rootBlock_),this.sourceListener_=Blockly.bindEvent_(this.block_.workspace.getCanvas(),"blocklyWorkspaceChange",this.block_,function(){b.block_.saveConnections(b.rootBlock_)}));this.resizeBubble_();Blockly.bindEvent_(this.workspace_.getCanvas(),"blocklyWorkspaceChange",this.block_,function(){b.workspaceChanged_()}); +this.updateColour()}else this.svgDialog_=null,this.workspace_.dispose(),this.rootBlock_=this.workspace_=null,this.bubble_.dispose(),this.bubble_=null,this.workspaceHeight_=this.workspaceWidth_=0,this.sourceListener_&&(Blockly.unbindEvent_(this.sourceListener_),this.sourceListener_=null)}; +Blockly.Mutator.prototype.workspaceChanged_=function(){if(0==Blockly.Block.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)}this.rootBlock_.workspace==this.workspace_&&(a=this.block_.rendered,this.block_.rendered=!1,this.block_.compose(this.rootBlock_),this.block_.rendered=a,this.block_.rendered&&this.block_.render(),this.resizeBubble_(),this.block_.workspace.fireChangeEvent())}; +Blockly.Mutator.prototype.getFlyoutMetrics_=function(){var a=0;Blockly.RTL&&(a+=this.workspaceWidth_);return{viewHeight:this.workspaceHeight_,viewWidth:0,absoluteTop:0,absoluteLeft:a}};Blockly.Mutator.prototype.dispose=function(){this.block_.mutator=null;Blockly.Icon.prototype.dispose.call(this)}; // Copyright 2012 Google Inc. Apache License 2.0 Blockly.Warning=function(a){Blockly.Warning.superClass_.constructor.call(this,a);this.createIcon_()};goog.inherits(Blockly.Warning,Blockly.Icon);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;cthis.workspace.remainingCapacity()&&(d.enabled=!1);c.push(d);this.isEditable()&&!this.collapsed_&&Blockly.comments&&(d={enabled:!0},this.comment?(d.text=Blockly.Msg.REMOVE_COMMENT,d.callback=function(){b.setCommentText(null)}): (d.text=Blockly.Msg.ADD_COMMENT,d.callback=function(){b.setCommentText("")}),c.push(d));if(!this.collapsed_)for(d=0;d=a.clientX&&0==a.clientY&&0==a.button)){Blockly.removeAllRanges();var c=a.clientX-b.startDragMouseX,d=a.clientY-b.startDragMouseY;1==Blockly.Block.dragMode_&&Math.sqrt(Math.pow(c,2)+Math.pow(d,2))>Blockly.DRAG_RADIUS&&(Blockly.Block.dragMode_=2,b.setParent(null),b.setDragging_(!0));if(2==Blockly.Block.dragMode_){var e=b.startDragX+c,f=b.startDragY+d;b.svg_.getRootElement().setAttribute("transform", -"translate("+e+", "+f+")");for(e=0;e=a.clientX&&0==a.clientY&&0==a.button)){Blockly.removeAllRanges();var c=a.clientX-b.startDragMouseX,d=a.clientY-b.startDragMouseY;1==Blockly.Block.dragMode_&&Math.sqrt(Math.pow(c,2)+Math.pow(d,2))>Blockly.DRAG_RADIUS&&(Blockly.Block.dragMode_=2,b.setParent(null),b.setDragging_(!0),b.workspace.recordDeleteAreas());if(2==Blockly.Block.dragMode_){var e=b.startDragX+c,f=b.startDragY+d; +b.svg_.getRootElement().setAttribute("transform","translate("+e+", "+f+")");for(e=0;ea;d.setDisabled(e)}}; Blockly.Flyout.terminateDrag_=function(){Blockly.Flyout.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Flyout.onMouseUpWrapper_),Blockly.Flyout.onMouseUpWrapper_=null);Blockly.Flyout.onMouseMoveBlockWrapper_&&(Blockly.unbindEvent_(Blockly.Flyout.onMouseMoveBlockWrapper_),Blockly.Flyout.onMouseMoveBlockWrapper_=null);Blockly.Flyout.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Flyout.onMouseMoveWrapper_),Blockly.Flyout.onMouseMoveWrapper_=null);Blockly.Flyout.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Flyout.onMouseUpWrapper_), -Blockly.Flyout.onMouseUpWrapper_=null);Blockly.Flyout.startDownEvent_=null;Blockly.Flyout.startBlock_=null;Blockly.Flyout.startFlyout_=null}; +Blockly.Flyout.onMouseUpWrapper_=null);Blockly.Flyout.startDownEvent_=null;Blockly.Flyout.startBlock_=null;Blockly.Flyout.startFlyout_=null};Blockly.Flyout.prototype.getRect=function(){var a=Blockly.getSvgXY_(this.svgGroup_).x;Blockly.RTL||(a-=1E7);return new goog.math.Rect(a,-1E7,1E7+this.width_,this.height_+2E7)}; // Copyright 2011 Google Inc. Apache License 2.0 Blockly.Toolbox={};Blockly.Toolbox.width=0;Blockly.Toolbox.selectedOption_=null;Blockly.Toolbox.CONFIG_={indentWidth:19,cssRoot:"blocklyTreeRoot",cssHideRoot:"blocklyHidden",cssItem:"",cssTreeRow:"blocklyTreeRow",cssItemLabel:"blocklyTreeLabel",cssTreeIcon:"blocklyTreeIcon",cssExpandedFolderIcon:"blocklyTreeIconOpen",cssFileIcon:"blocklyTreeIconNone",cssSelectedRow:"blocklyTreeSelected"}; Blockly.Toolbox.createDom=function(a,b){Blockly.Toolbox.HtmlDiv=goog.dom.createDom("div","blocklyToolboxDiv");Blockly.Toolbox.HtmlDiv.setAttribute("dir",Blockly.RTL?"RTL":"LTR");b.appendChild(Blockly.Toolbox.HtmlDiv);Blockly.Toolbox.flyout_=new Blockly.Flyout;a.appendChild(Blockly.Toolbox.flyout_.createDom());Blockly.bindEvent_(Blockly.Toolbox.HtmlDiv,"mousedown",null,function(a){Blockly.isRightButton(a)||a.target==Blockly.Toolbox.HtmlDiv?Blockly.hideChaff(!1):Blockly.hideChaff(!0)})}; @@ -1229,8 +1231,8 @@ Blockly.Realtime.addAuthUi_=function(a){a.style.background="url("+Blockly.pathTo Blockly.Realtime.updateCollabUi_=function(){if(Blockly.Realtime.collabElementId){var a=goog.dom.getElement(Blockly.Realtime.collabElementId);goog.dom.removeChildren(a);for(var b=Blockly.Realtime.document_.getCollaborators(),c=0;c>>/g,Blockly.Css.mediaPath_);goog.cssom.addCssText(a);a=goog.cssom.getAllCssStyleSheets();Blockly.Css.styleSheet_=a[a.length-1];Blockly.Css.setCursor("handopen")}; -Blockly.Css.setCursor=function(a){Blockly.readOnly||goog.cssom.replaceCssRule("",".blocklyDraggable {\n cursor: url("+Blockly.Css.mediaPath_+"/"+a+".cur) "+(a==Blockly.Css.Cursor.OPEN?"8 5":"7 3")+", auto;\n}\n",Blockly.Css.styleSheet_,0)}; +Blockly.Css={};Blockly.Css.Cursor={OPEN:"handopen",CLOSED:"handclosed",DELETE:"handdelete"};Blockly.Css.currentCursor_="";Blockly.Css.styleSheet_=null;Blockly.Css.mediaPath_="";Blockly.Css.inject=function(){var a=Blockly.Css.CONTENT.join("\n");Blockly.Css.mediaPath_=Blockly.pathToMedia.replace(/[\\\/]$/,"");a=a.replace(/<<>>/g,Blockly.Css.mediaPath_);goog.cssom.addCssText(a);a=goog.cssom.getAllCssStyleSheets();Blockly.Css.styleSheet_=a[a.length-1];Blockly.Css.setCursor("handopen")}; +Blockly.Css.setCursor=function(a){if(!Blockly.readOnly&&Blockly.Css.currentCursor_!=a){Blockly.Css.currentCursor_=a;var b="url("+Blockly.Css.mediaPath_+"/"+a+".cur) "+(a==Blockly.Css.Cursor.OPEN?"8 5":"7 3")+", auto";goog.cssom.replaceCssRule("",".blocklyDraggable {\n cursor: "+b+";\n}\n",Blockly.Css.styleSheet_,0);Blockly.svg&&(Blockly.svg.style.cursor=a==Blockly.Css.Cursor.OPEN?"":b)}}; Blockly.Css.CONTENT=[".blocklyDraggable {","}",".blocklySvg {"," background-color: #fff;"," border: 1px solid #ddd;"," overflow: hidden;","}",".blocklyWidgetDiv {"," position: absolute;"," display: none;"," z-index: 999;","}",".blocklyResizeSE {"," fill: #aaa;"," cursor: se-resize;","}",".blocklyResizeSW {"," fill: #aaa;"," cursor: sw-resize;","}",".blocklyResizeLine {"," stroke-width: 1;"," stroke: #888;","}",".blocklyHighlightedConnectionPath {"," stroke-width: 4px;"," stroke: #fc3;", " fill: none;","}",".blocklyPathLight {"," fill: none;"," stroke-width: 2;"," stroke-linecap: round;","}",".blocklySelected>.blocklyPath {"," stroke-width: 3px;"," stroke: #fc3;","}",".blocklySelected>.blocklyPathLight {"," display: none;","}",".blocklyDragging>.blocklyPath,",".blocklyDragging>.blocklyPathLight {"," fill-opacity: .8;"," stroke-opacity: .8;","}",".blocklyDragging>.blocklyPathDark {"," display: none;","}",".blocklyDisabled>.blocklyPath {"," fill-opacity: .5;"," stroke-opacity: .5;", "}",".blocklyDisabled>.blocklyPathLight,",".blocklyDisabled>.blocklyPathDark {"," display: none;","}",".blocklyText {"," cursor: default;"," font-family: sans-serif;"," font-size: 11pt;"," fill: #fff;","}",".blocklyNonEditableText>text {"," pointer-events: none;","}",".blocklyNonEditableText>rect,",".blocklyEditableText>rect {"," fill: #fff;"," fill-opacity: .6;","}",".blocklyNonEditableText>text,",".blocklyEditableText>text {"," fill: #000;","}",".blocklyEditableText:hover>rect {"," stroke-width: 2;", @@ -1263,8 +1265,8 @@ stdDeviation:1,result:"blur"},d);e=Blockly.createSvgElement("feSpecularLighting" {id:"blocklyTrashcanShadowFilter"},c);Blockly.createSvgElement("feGaussianBlur",{"in":"SourceAlpha",stdDeviation:2,result:"blur"},d);Blockly.createSvgElement("feOffset",{"in":"blur",dx:1,dy:1,result:"offsetBlur"},d);d=Blockly.createSvgElement("feMerge",{},d);Blockly.createSvgElement("feMergeNode",{"in":"offsetBlur"},d);Blockly.createSvgElement("feMergeNode",{"in":"SourceGraphic"},d);d=Blockly.createSvgElement("filter",{id:"blocklyShadowFilter"},c);Blockly.createSvgElement("feGaussianBlur",{stdDeviation:2}, d);c=Blockly.createSvgElement("pattern",{id:"blocklyDisabledPattern",patternUnits:"userSpaceOnUse",width:10,height:10},c);Blockly.createSvgElement("rect",{width:10,height:10,fill:"#aaa"},c);Blockly.createSvgElement("path",{d:"M 0 0 L 10 10 M 10 0 L 0 10",stroke:"#cc0"},c);Blockly.mainWorkspace=new Blockly.Workspace(Blockly.getMainWorkspaceMetrics_,Blockly.setMainWorkspaceMetrics_);b.appendChild(Blockly.mainWorkspace.createDom());Blockly.mainWorkspace.maxBlocks=Blockly.maxBlocks;Blockly.readOnly|| (Blockly.hasCategories?Blockly.Toolbox.createDom(b,a):(Blockly.mainWorkspace.flyout_=new Blockly.Flyout,c=Blockly.mainWorkspace.flyout_,d=c.createDom(),c.autoClose=!1,goog.dom.insertSiblingBefore(d,Blockly.mainWorkspace.svgGroup_),Blockly.addChangeListener(function(){if(0==Blockly.Block.dragMode_){var a=Blockly.mainWorkspace.getMetrics();if(0>a.contentTop||a.contentTop+a.contentHeight>a.viewHeight+a.viewTop||a.contentLeft<(Blockly.RTL?a.viewLeft:0)||a.contentLeft+a.contentWidth>(Blockly.RTL?a.viewWidth: -a.viewWidth+a.viewLeft))for(var b=Blockly.mainWorkspace.getTopBlocks(!1),c=0,d;d=b[c];c++){var e=d.getRelativeToSurfaceXY(),p=d.getHeightWidth(),m=a.viewTop+25-p.height-e.y;0m&&d.moveBy(0,m);m=25+a.viewLeft-e.x-(Blockly.RTL?0:p.width);0m&&d.moveBy(m,0);d.isDeletable()&&50<(Blockly.RTL?e.x-a.viewWidth:-e.x)&&d.dispose(!1,!0)}}})));b.appendChild(Blockly.Tooltip.createDom()); -a.appendChild(b);Blockly.svg=b;Blockly.svgResize();Blockly.WidgetDiv.DIV=goog.dom.createDom("div","blocklyWidgetDiv");Blockly.WidgetDiv.DIV.style.direction=Blockly.RTL?"rtl":"ltr";document.body.appendChild(Blockly.WidgetDiv.DIV)}; +a.viewWidth+a.viewLeft))for(var b=Blockly.mainWorkspace.getTopBlocks(!1),c=0,d;d=b[c];c++){var e=d.getRelativeToSurfaceXY(),p=d.getHeightWidth(),m=a.viewTop+25-p.height-e.y;0m&&d.moveBy(0,m);m=25+a.viewLeft-e.x-(Blockly.RTL?0:p.width);0m&&d.moveBy(m,0)}}})));b.appendChild(Blockly.Tooltip.createDom());a.appendChild(b);Blockly.svg=b;Blockly.svgResize();Blockly.WidgetDiv.DIV= +goog.dom.createDom("div","blocklyWidgetDiv");Blockly.WidgetDiv.DIV.style.direction=Blockly.RTL?"rtl":"ltr";document.body.appendChild(Blockly.WidgetDiv.DIV)}; Blockly.init_=function(){Blockly.bindEvent_(Blockly.svg,"mousedown",null,Blockly.onMouseDown_);Blockly.bindEvent_(Blockly.svg,"contextmenu",null,Blockly.onContextMenu_);Blockly.bindEvent_(Blockly.WidgetDiv.DIV,"contextmenu",null,Blockly.onContextMenu_);Blockly.documentEventsBound_||(Blockly.bindEvent_(window,"resize",document,Blockly.svgResize),Blockly.bindEvent_(document,"keydown",null,Blockly.onKeyDown_),document.addEventListener("mouseup",Blockly.onMouseUp_,!1),goog.userAgent.IPAD&&Blockly.bindEvent_(window, "orientationchange",document,function(){Blockly.fireUiEvent(window,"resize")}),Blockly.documentEventsBound_=!0);if(Blockly.languageTree)if(Blockly.hasCategories)Blockly.Toolbox.init();else{Blockly.mainWorkspace.flyout_.init(Blockly.mainWorkspace);Blockly.mainWorkspace.flyout_.show(Blockly.languageTree.childNodes);Blockly.mainWorkspace.scrollX=Blockly.mainWorkspace.flyout_.width_;Blockly.RTL&&(Blockly.mainWorkspace.scrollX*=-1);var a="translate("+Blockly.mainWorkspace.scrollX+", 0)";Blockly.mainWorkspace.getCanvas().setAttribute("transform", a);Blockly.mainWorkspace.getBubbleCanvas().setAttribute("transform",a)}Blockly.hasScrollbars&&(Blockly.mainWorkspace.scrollbar=new Blockly.ScrollbarPair(Blockly.mainWorkspace),Blockly.mainWorkspace.scrollbar.resize());Blockly.mainWorkspace.addTrashcan();if(Blockly.hasSounds){Blockly.loadAudio_([Blockly.pathToMedia+"click.mp3",Blockly.pathToMedia+"click.wav",Blockly.pathToMedia+"click.ogg"],"click");Blockly.loadAudio_([Blockly.pathToMedia+"delete.mp3",Blockly.pathToMedia+"delete.ogg",Blockly.pathToMedia+ diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index 0fbff0cd..ded4f519 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -42,7 +42,7 @@ goog.addDependency("../../../" + dir + "/core/field_image.js", ['Blockly.FieldIm goog.addDependency("../../../" + dir + "/core/field_label.js", ['Blockly.FieldLabel'], ['Blockly.Field', 'Blockly.Tooltip']); goog.addDependency("../../../" + dir + "/core/field_textinput.js", ['Blockly.FieldTextInput'], ['Blockly.Field', 'Blockly.Msg', 'goog.asserts', 'goog.userAgent']); goog.addDependency("../../../" + dir + "/core/field_variable.js", ['Blockly.FieldVariable'], ['Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.Variables']); -goog.addDependency("../../../" + dir + "/core/flyout.js", ['Blockly.Flyout'], ['Blockly.Block', 'Blockly.Comment', 'goog.userAgent']); +goog.addDependency("../../../" + dir + "/core/flyout.js", ['Blockly.Flyout'], ['Blockly.Block', 'Blockly.Comment', 'goog.userAgent', 'goog.math.Rect']); goog.addDependency("../../../" + dir + "/core/generator.js", ['Blockly.Generator'], ['Blockly.Block']); goog.addDependency("../../../" + dir + "/core/icon.js", ['Blockly.Icon'], []); goog.addDependency("../../../" + dir + "/core/inject.js", ['Blockly.inject'], ['Blockly.Css', 'goog.dom']); @@ -56,12 +56,12 @@ goog.addDependency("../../../" + dir + "/core/realtime.js", ['Blockly.Realtime'] goog.addDependency("../../../" + dir + "/core/scrollbar.js", ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['goog.userAgent']); goog.addDependency("../../../" + dir + "/core/toolbox.js", ['Blockly.Toolbox'], ['Blockly.Flyout', 'goog.events.BrowserFeature', 'goog.html.SafeHtml', 'goog.style', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TreeNode']); goog.addDependency("../../../" + dir + "/core/tooltip.js", ['Blockly.Tooltip'], []); -goog.addDependency("../../../" + dir + "/core/trashcan.js", ['Blockly.Trashcan'], ['goog.math', 'goog.Timer']); +goog.addDependency("../../../" + dir + "/core/trashcan.js", ['Blockly.Trashcan'], ['goog.math', 'goog.math.Rect', 'goog.Timer']); goog.addDependency("../../../" + dir + "/core/utils.js", ['Blockly.utils'], []); goog.addDependency("../../../" + dir + "/core/variables.js", ['Blockly.Variables'], ['Blockly.Toolbox', 'Blockly.Workspace']); 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.addDependency("../../../" + dir + "/core/workspace.js", ['Blockly.Workspace'], ['Blockly.ScrollbarPair', 'Blockly.Trashcan', 'Blockly.Xml', 'goog.math']); +goog.addDependency("../../../" + dir + "/core/workspace.js", ['Blockly.Workspace'], ['Blockly.ScrollbarPair', 'Blockly.Trashcan', 'Blockly.Xml', 'goog.math', 'goog.math.Coordinate']); goog.addDependency("../../../" + dir + "/core/xml.js", ['Blockly.Xml'], []); goog.addDependency("../../alltests.js", [], []); goog.addDependency("base.js", [], []); diff --git a/core/block.js b/core/block.js index dfc0a580..0d71fa55 100644 --- a/core/block.js +++ b/core/block.js @@ -300,6 +300,7 @@ Blockly.Block.terminateDrag_ = function() { selected.workspace.fireChangeEvent(); } Blockly.Block.dragMode_ = 0; + Blockly.Css.setCursor(Blockly.Css.Cursor.OPEN); }; /** @@ -557,7 +558,6 @@ Blockly.Block.prototype.onMouseDown_ = function(e) { Blockly.Block.prototype.onMouseUp_ = function(e) { var this_ = this; Blockly.doCommand(function() { - Blockly.terminateDrag_(); if (Blockly.selected && Blockly.highlightedConnection_) { // Connect two blocks together. Blockly.localConnection_.connect(Blockly.highlightedConnection_); @@ -572,13 +572,15 @@ Blockly.Block.prototype.onMouseUp_ = function(e) { } inferiorConnection.sourceBlock_.svg_.connectionUiEffect(); } - if (this_.workspace.trashcan && this_.workspace.trashcan.isOpen) { + if (this_.workspace.trashcan) { // Don't throw an object in the trash can if it just got connected. this_.workspace.trashcan.close(); } - } else if (this_.workspace.trashcan && this_.workspace.trashcan.isOpen) { + } else if (this_.workspace.isDeleteArea(e)) { var trashcan = this_.workspace.trashcan; - goog.Timer.callOnce(trashcan.close, 100, trashcan); + if (trashcan) { + goog.Timer.callOnce(trashcan.close, 100, trashcan); + } Blockly.selected.dispose(false, true); // Dropping a block on the trash can will usually cause the workspace to // resize to contain the newly positioned block. Force a second resize @@ -589,6 +591,7 @@ Blockly.Block.prototype.onMouseUp_ = function(e) { Blockly.highlightedConnection_.unhighlight(); Blockly.highlightedConnection_ = null; } + Blockly.terminateDrag_(); }); }; @@ -862,6 +865,7 @@ Blockly.Block.prototype.onMouseMove_ = function(e) { // Push this block to the very top of the stack. this_.setParent(null); this_.setDragging_(true); + this_.workspace.recordDeleteAreas(); } } if (Blockly.Block.dragMode_ == 2) { @@ -907,9 +911,10 @@ Blockly.Block.prototype.onMouseMove_ = function(e) { Blockly.highlightedConnection_ = closestConnection; Blockly.localConnection_ = localConnection; } - // Flip the trash can lid if needed. - if (this_.workspace.trashcan && this_.isDeletable()) { - this_.workspace.trashcan.onMouseMove(e); + // Provide visual indication of whether the block will be deleted if + // dropped here. + if (this_.isDeletable()) { + this_.workspace.isDeleteArea(e); } } // This event has been handled. No need to bubble up to the document. diff --git a/core/css.js b/core/css.js index 0fcbb2ee..37fa2e66 100644 --- a/core/css.js +++ b/core/css.js @@ -28,6 +28,7 @@ goog.provide('Blockly.Css'); goog.require('goog.cssom'); + /** * List of cursors. * @enum {string} @@ -38,6 +39,12 @@ Blockly.Css.Cursor = { DELETE: 'handdelete' }; +/** + * Current cursor (cached value). + * @type string + */ +Blockly.Css.currentCursor_ = ''; + /** * Large stylesheet added by Blockly.Css.inject. * @type Element @@ -75,9 +82,10 @@ Blockly.Css.inject = function() { * @param {Blockly.Cursor} cursor Enum. */ Blockly.Css.setCursor = function(cursor) { - if (Blockly.readOnly) { + if (Blockly.readOnly || Blockly.Css.currentCursor_ == cursor) { return; } + Blockly.Css.currentCursor_ = cursor; /* Hotspot coordinates are baked into the CUR file, but they are still required in the CSS due to a Chrome bug. @@ -88,10 +96,19 @@ Blockly.Css.setCursor = function(cursor) { } else { var xy = '7 3'; } - var rule = '.blocklyDraggable {\n' + - ' cursor: url(' + Blockly.Css.mediaPath_ + '/' + cursor + '.cur)' + - ' ' + xy + ', auto;\n}\n'; + var url = 'url(' + Blockly.Css.mediaPath_ + '/' + cursor + + '.cur) ' + xy + ', auto'; + var rule = '.blocklyDraggable {\n cursor: ' + url + ';\n}\n'; goog.cssom.replaceCssRule('', rule, Blockly.Css.styleSheet_, 0); + if (Blockly.svg) { + // Set cursor on the SVG surface as well, so that rapid movements + // don't result in cursor changing to an arrow momentarily. + if (cursor == Blockly.Css.Cursor.OPEN) { + Blockly.svg.style.cursor = ''; + } else { + Blockly.svg.style.cursor = url; + } + } }; /** diff --git a/core/flyout.js b/core/flyout.js index ca35af72..e316e322 100644 --- a/core/flyout.js +++ b/core/flyout.js @@ -29,6 +29,7 @@ goog.provide('Blockly.Flyout'); goog.require('Blockly.Block'); goog.require('Blockly.Comment'); goog.require('goog.userAgent'); +goog.require('goog.math.Rect'); /** @@ -670,3 +671,20 @@ Blockly.Flyout.terminateDrag_ = function() { Blockly.Flyout.startBlock_ = null; Blockly.Flyout.startFlyout_ = null; }; + +/** + * Return the deletion rectangle for this flyout. + * @return {goog.math.Rect} Rectangle in which to delete. + */ +Blockly.Flyout.prototype.getRect = function() { + // BIG_NUM is offscreen padding so that blocks dragged beyond the shown flyout + // area are still deleted. Must be smaller than Infinity, but larger than + // the largest screen size. + var BIG_NUM = 10000000; + var x = Blockly.getSvgXY_(this.svgGroup_).x; + if (!Blockly.RTL) { + x -= BIG_NUM; + } + return new goog.math.Rect(x, -BIG_NUM, + BIG_NUM + this.width_, this.height_ + 2 * BIG_NUM); +}; diff --git a/core/inject.js b/core/inject.js index 50cc9906..8d3cdfa5 100644 --- a/core/inject.js +++ b/core/inject.js @@ -327,11 +327,6 @@ Blockly.createDom_ = function(container) { if (overflow < 0) { block.moveBy(overflow, 0); } - // Delete any block that's sitting on top of the flyout. - if (block.isDeletable() && (Blockly.RTL ? - blockXY.x - metrics.viewWidth : -blockXY.x) > MARGIN * 2) { - block.dispose(false, true); - } } } } diff --git a/core/mutator.js b/core/mutator.js index c4137ab9..72be1c2e 100644 --- a/core/mutator.js +++ b/core/mutator.js @@ -118,9 +118,9 @@ Blockly.Mutator.prototype.createEditor_ = function() { var mutator = this; this.workspace_ = new Blockly.Workspace( function() {return mutator.getFlyoutMetrics_();}, null); - this.flyout_ = new Blockly.Flyout(); - this.flyout_.autoClose = false; - this.svgDialog_.appendChild(this.flyout_.createDom()); + this.workspace_.flyout_ = new Blockly.Flyout(); + this.workspace_.flyout_.autoClose = false; + this.svgDialog_.appendChild(this.workspace_.flyout_.createDom()); this.svgDialog_.appendChild(this.workspace_.createDom()); return this.svgDialog_; }; @@ -148,7 +148,7 @@ Blockly.Mutator.prototype.updateEditable = function() { Blockly.Mutator.prototype.resizeBubble_ = function() { var doubleBorderWidth = 2 * Blockly.Bubble.BORDER_WIDTH; var workspaceSize = this.workspace_.getCanvas().getBBox(); - var flyoutMetrics = this.flyout_.getMetrics_(); + var flyoutMetrics = this.workspace_.flyout_.getMetrics_(); var width; if (Blockly.RTL) { width = -workspaceSize.x; @@ -193,8 +193,8 @@ Blockly.Mutator.prototype.setVisible = function(visible) { this.createEditor_(), this.block_.svg_.svgPath_, this.iconX_, this.iconY_, null, null); var thisObj = this; - this.flyout_.init(this.workspace_); - this.flyout_.show(this.quarkXml_); + this.workspace_.flyout_.init(this.workspace_); + this.workspace_.flyout_.show(this.quarkXml_); this.rootBlock_ = this.block_.decompose(this.workspace_); var blocks = this.rootBlock_.getDescendants(); @@ -204,8 +204,8 @@ Blockly.Mutator.prototype.setVisible = function(visible) { // The root block should not be dragable or deletable. this.rootBlock_.setMovable(false); this.rootBlock_.setDeletable(false); - var margin = this.flyout_.CORNER_RADIUS * 2; - var x = this.flyout_.width_ + margin; + var margin = this.workspace_.flyout_.CORNER_RADIUS * 2; + var x = this.workspace_.flyout_.width_ + margin; if (Blockly.RTL) { x = -x; } @@ -226,8 +226,6 @@ Blockly.Mutator.prototype.setVisible = function(visible) { } else { // Dispose of the bubble. this.svgDialog_ = null; - this.flyout_.dispose(); - this.flyout_ = null; this.workspace_.dispose(); this.workspace_ = null; this.rootBlock_ = null; @@ -244,7 +242,7 @@ Blockly.Mutator.prototype.setVisible = function(visible) { /** * Update the source block when the mutator's blocks are changed. - * Delete or bump any block that's out of bounds. + * Bump down any block that's too high. * Fired whenever a change is made to the mutator's workspace. * @private */ @@ -255,12 +253,7 @@ Blockly.Mutator.prototype.workspaceChanged_ = function() { for (var b = 0, block; block = blocks[b]; b++) { var blockXY = block.getRelativeToSurfaceXY(); var blockHW = block.getHeightWidth(); - if (block.isDeletable() && (Blockly.RTL ? - blockXY.x > -this.flyout_.width_ + MARGIN : - blockXY.x < this.flyout_.width_ - MARGIN)) { - // Delete any block that's sitting on top of the flyout. - block.dispose(false, true); - } else if (blockXY.y + blockHW.height < MARGIN) { + if (blockXY.y + blockHW.height < MARGIN) { // Bump any block that's above the top back inside. block.moveBy(0, MARGIN - blockHW.height - blockXY.y); } diff --git a/core/trashcan.js b/core/trashcan.js index 5f2a9f5d..e09fd0ba 100644 --- a/core/trashcan.js +++ b/core/trashcan.js @@ -27,6 +27,7 @@ goog.provide('Blockly.Trashcan'); goog.require('goog.math'); +goog.require('goog.math.Rect'); goog.require('goog.Timer'); @@ -238,32 +239,16 @@ Blockly.Trashcan.prototype.position_ = function() { }; /** - * Determines if the mouse is currently over the trash can. - * Opens/closes the lid and sets the isOpen flag. - * @param {!Event} e Mouse move event. + * Return the deletion rectangle for this trashcan. + * @return {goog.math.Rect} Rectangle in which to delete. */ -Blockly.Trashcan.prototype.onMouseMove = function(e) { - /* - An alternative approach would be to use onMouseOver and onMouseOut events. - However the selected block will be between the mouse and the trash can, - thus these events won't fire. - Another approach is to use HTML5's drag & drop API, but it's widely hated. - Instead, we'll just have the block's drag_ function call us. - */ - if (!this.svgGroup_) { - return; - } - var mouseXY = Blockly.mouseToSvg(e); +Blockly.Trashcan.prototype.getRect = function() { var trashXY = Blockly.getSvgXY_(this.svgGroup_); - var over = (mouseXY.x > trashXY.x - this.MARGIN_HOTSPOT_) && - (mouseXY.x < trashXY.x + this.WIDTH_ + this.MARGIN_HOTSPOT_) && - (mouseXY.y > trashXY.y - this.MARGIN_HOTSPOT_) && - (mouseXY.y < trashXY.y + this.BODY_HEIGHT_ + this.LID_HEIGHT_ + - this.MARGIN_HOTSPOT_); - // For bonus points we might want to match the trapezoidal outline. - if (this.isOpen != over) { - this.setOpen_(over); - } + return new goog.math.Rect( + trashXY.x - this.MARGIN_HOTSPOT_, + trashXY.y - this.MARGIN_HOTSPOT_, + this.WIDTH_ + 2 * this.MARGIN_HOTSPOT_, + this.BODY_HEIGHT_ + this.LID_HEIGHT_ + 2 * this.MARGIN_HOTSPOT_); }; /** @@ -278,8 +263,6 @@ Blockly.Trashcan.prototype.setOpen_ = function(state) { goog.Timer.clear(this.lidTask_); this.isOpen = state; this.animateLid_(); - Blockly.Css.setCursor(state ? Blockly.Css.Cursor.DELETE : - Blockly.Css.Cursor.CLOSED); }; /** diff --git a/core/workspace.js b/core/workspace.js index d1a123f0..6babbeaa 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -32,6 +32,7 @@ goog.require('Blockly.ScrollbarPair'); goog.require('Blockly.Trashcan'); goog.require('Blockly.Xml'); goog.require('goog.math'); +goog.require('goog.math.Coordinate'); /** @@ -134,6 +135,10 @@ Blockly.Workspace.prototype.dispose = function() { } this.svgBlockCanvas_ = null; this.svgBubbleCanvas_ = null; + if (this.flyout_) { + this.flyout_.dispose(); + this.flyout_ = null; + } if (this.trashcan) { this.trashcan.dispose(); this.trashcan = null; @@ -396,5 +401,49 @@ Blockly.Workspace.prototype.remainingCapacity = function() { return this.maxBlocks - this.getAllBlocks().length; }; +/** + * Make a list of all the delete areas for this workspace. + */ +Blockly.Workspace.prototype.recordDeleteAreas = function() { + if (this.trashcan) { + this.deleteAreaTrash_ = this.trashcan.getRect(); + } else { + this.deleteAreaTrash_ = null; + } + if (this.flyout_) { + this.deleteAreaToolbox_ = this.flyout_.getRect(); + } else { + this.deleteAreaToolbox_ = null; + } +}; + +/** + * Is the mouse event over a delete area (toolbar or non-closing flyout)? + * Opens or closes the trashcan and sets the cursor as a side effect. + * @param {!Event} e Mouse move event. + * @return {boolean} True if event is in a delete area. + */ +Blockly.Workspace.prototype.isDeleteArea = function(e) { + var isDelete = false; + var mouseXY = Blockly.mouseToSvg(e); + var xy = new goog.math.Coordinate(mouseXY.x, mouseXY.y); + if (this.deleteAreaTrash_) { + if (this.deleteAreaTrash_.contains(xy)) { + this.trashcan.setOpen_(true); + Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE); + return true; + } + this.trashcan.setOpen_(false); + } + if (this.deleteAreaToolbox_) { + if (this.deleteAreaToolbox_.contains(xy)) { + Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE); + return true; + } + } + Blockly.Css.setCursor(Blockly.Css.Cursor.CLOSED); + return false; +}; + // Export symbols that would otherwise be renamed by Closure compiler. Blockly.Workspace.prototype['clear'] = Blockly.Workspace.prototype.clear;