mirror of
https://github.com/google/blockly.git
synced 2026-01-10 18:37:09 +01:00
Merge branch 'develop' into single_field_blocks
This commit is contained in:
@@ -660,8 +660,12 @@ Blockly.BlockSvg.prototype.setCollapsed = function(collapsed) {
|
||||
Blockly.BlockSvg.prototype.tab = function(start, forward) {
|
||||
var tabCursor = new Blockly.TabNavigateCursor();
|
||||
tabCursor.setCurNode(Blockly.ASTNode.createFieldNode(start));
|
||||
var action = forward ?
|
||||
Blockly.navigation.ACTION_NEXT : Blockly.navigation.ACTION_PREVIOUS;
|
||||
|
||||
var nextNode = forward ? tabCursor.next() : tabCursor.prev();
|
||||
tabCursor.onBlocklyAction(action);
|
||||
|
||||
var nextNode = tabCursor.getCurNode();
|
||||
if (nextNode) {
|
||||
var nextField = /** @type {!Blockly.Field} */ (nextNode.getLocation());
|
||||
nextField.showEditor();
|
||||
@@ -1752,11 +1756,5 @@ Blockly.BlockSvg.prototype.getHeightWidth = function() {
|
||||
* @package
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.highlightForReplacement = function(add) {
|
||||
if (add) {
|
||||
Blockly.utils.dom.addClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyReplaceable');
|
||||
} else {
|
||||
Blockly.utils.dom.removeClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyReplaceable');
|
||||
}
|
||||
this.pathObject.updateReplacementHighlight(add);
|
||||
};
|
||||
|
||||
@@ -51,6 +51,42 @@ Blockly.Bubble = function(workspace, content, shape, anchorXY,
|
||||
this.content_ = content;
|
||||
this.shape_ = shape;
|
||||
|
||||
/**
|
||||
* Method to call on resize of bubble.
|
||||
* @type {?function()}
|
||||
* @private
|
||||
*/
|
||||
this.resizeCallback_ = null;
|
||||
|
||||
/**
|
||||
* Method to call on move of bubble.
|
||||
* @type {?function()}
|
||||
* @private
|
||||
*/
|
||||
this.moveCallback_ = null;
|
||||
|
||||
/**
|
||||
* Mouse down on bubbleBack_ event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseDownBubbleWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse down on resizeGroup_ event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseDownResizeWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Describes whether this bubble has been disposed of (nodes and event
|
||||
* listeners removed from the page) or not.
|
||||
* @type {boolean}
|
||||
* @package
|
||||
*/
|
||||
this.disposed = false;
|
||||
|
||||
var angle = Blockly.Bubble.ARROW_ANGLE;
|
||||
if (this.workspace_.RTL) {
|
||||
angle = -angle;
|
||||
@@ -72,29 +108,6 @@ Blockly.Bubble = function(workspace, content, shape, anchorXY,
|
||||
this.positionBubble_();
|
||||
this.renderArrow_();
|
||||
this.rendered_ = true;
|
||||
|
||||
if (!workspace.options.readOnly) {
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.bubbleBack_, 'mousedown', this, this.bubbleMouseDown_);
|
||||
if (this.resizeGroup_) {
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.resizeGroup_, 'mousedown', this, this.resizeMouseDown_);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to call on resize of bubble.
|
||||
* @type {?function()}
|
||||
* @private
|
||||
*/
|
||||
this.resizeCallback_ = null;
|
||||
|
||||
/**
|
||||
* Method to call on move of bubble.
|
||||
* @type {?function()}
|
||||
* @private
|
||||
*/
|
||||
this.moveCallback_ = null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -124,15 +137,15 @@ Blockly.Bubble.ARROW_BEND = 4;
|
||||
Blockly.Bubble.ANCHOR_RADIUS = 8;
|
||||
|
||||
/**
|
||||
* Wrapper function called when a mouseUp occurs during a drag operation.
|
||||
* @type {Array.<!Array>}
|
||||
* Mouse up event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.onMouseUpWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Wrapper function called when a mouseMove occurs during a drag operation.
|
||||
* @type {Array.<!Array>}
|
||||
* Mouse move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = null;
|
||||
@@ -278,6 +291,15 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
|
||||
} else {
|
||||
this.resizeGroup_ = null;
|
||||
}
|
||||
|
||||
if (!this.workspace_.options.readOnly) {
|
||||
this.onMouseDownBubbleWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.bubbleBack_, 'mousedown', this, this.bubbleMouseDown_);
|
||||
if (this.resizeGroup_) {
|
||||
this.onMouseDownResizeWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.resizeGroup_, 'mousedown', this, this.resizeMouseDown_);
|
||||
}
|
||||
}
|
||||
this.bubbleGroup_.appendChild(content);
|
||||
return this.bubbleGroup_;
|
||||
};
|
||||
@@ -782,16 +804,15 @@ Blockly.Bubble.prototype.setColour = function(hexColour) {
|
||||
* Dispose of this bubble.
|
||||
*/
|
||||
Blockly.Bubble.prototype.dispose = function() {
|
||||
if (this.onMouseDownBubbleWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseDownBubbleWrapper_);
|
||||
}
|
||||
if (this.onMouseDownResizeWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseDownResizeWrapper_);
|
||||
}
|
||||
Blockly.Bubble.unbindDragEvents_();
|
||||
// Dispose of and unlink the bubble.
|
||||
Blockly.utils.dom.removeNode(this.bubbleGroup_);
|
||||
this.bubbleGroup_ = null;
|
||||
this.bubbleArrow_ = null;
|
||||
this.bubbleBack_ = null;
|
||||
this.resizeGroup_ = null;
|
||||
this.workspace_ = null;
|
||||
this.content_ = null;
|
||||
this.shape_ = null;
|
||||
this.disposed = true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,6 +61,34 @@ Blockly.Comment = function(block) {
|
||||
*/
|
||||
this.cachedText_ = '';
|
||||
|
||||
/**
|
||||
* Mouse up event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseUpWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Wheel event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onWheelWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Change event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onChangeWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Input event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onInputWrapper_ = null;
|
||||
|
||||
this.createIcon();
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.Comment, Blockly.Icon);
|
||||
@@ -137,21 +165,24 @@ Blockly.Comment.prototype.createEditor_ = function() {
|
||||
// Ideally this would be hooked to the focus event for the comment.
|
||||
// However doing so in Firefox swallows the cursor for unknown reasons.
|
||||
// So this is hooked to mouseup instead. No big deal.
|
||||
Blockly.bindEventWithChecks_(textarea, 'mouseup', this, this.startEdit_,
|
||||
true, true);
|
||||
this.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(
|
||||
textarea, 'mouseup', this, this.startEdit_, true, true);
|
||||
// Don't zoom with mousewheel.
|
||||
Blockly.bindEventWithChecks_(textarea, 'wheel', this, function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
Blockly.bindEventWithChecks_(textarea, 'change', this, function(_e) {
|
||||
if (this.cachedText_ != this.model_.text) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.block_, 'comment', null, this.cachedText_, this.model_.text));
|
||||
}
|
||||
});
|
||||
Blockly.bindEventWithChecks_(textarea, 'input', this, function(_e) {
|
||||
this.model_.text = textarea.value;
|
||||
});
|
||||
this.onWheelWrapper_ = Blockly.bindEventWithChecks_(
|
||||
textarea, 'wheel', this, function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
this.onChangeWrapper_ = Blockly.bindEventWithChecks_(
|
||||
textarea, 'change', this, function(_e) {
|
||||
if (this.cachedText_ != this.model_.text) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.block_, 'comment', null, this.cachedText_, this.model_.text));
|
||||
}
|
||||
});
|
||||
this.onInputWrapper_ = Blockly.bindEventWithChecks_(
|
||||
textarea, 'input', this, function(_e) {
|
||||
this.model_.text = textarea.value;
|
||||
});
|
||||
|
||||
setTimeout(textarea.focus.bind(textarea), 0);
|
||||
|
||||
@@ -271,7 +302,22 @@ Blockly.Comment.prototype.disposeBubble_ = function() {
|
||||
Blockly.Warning.prototype.disposeBubble.call(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.onMouseUpWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseUpWrapper_);
|
||||
this.onMouseUpWrapper_ = null;
|
||||
}
|
||||
if (this.onWheelWrapper_) {
|
||||
Blockly.unbindEvent_(this.onWheelWrapper_);
|
||||
this.onWheelWrapper_ = null;
|
||||
}
|
||||
if (this.onChangeWrapper_) {
|
||||
Blockly.unbindEvent_(this.onChangeWrapper_);
|
||||
this.onChangeWrapper_ = null;
|
||||
}
|
||||
if (this.onInputWrapper_) {
|
||||
Blockly.unbindEvent_(this.onInputWrapper_);
|
||||
this.onInputWrapper_ = null;
|
||||
}
|
||||
this.bubble_.dispose();
|
||||
this.bubble_ = null;
|
||||
this.textarea_ = null;
|
||||
|
||||
@@ -44,6 +44,41 @@ Blockly.Menu = function() {
|
||||
* @private
|
||||
*/
|
||||
this.highlightedIndex_ = -1;
|
||||
|
||||
/**
|
||||
* Mouse over event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.mouseOverHandler_ = null;
|
||||
|
||||
/**
|
||||
* Click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.clickHandler_ = null;
|
||||
|
||||
/**
|
||||
* Mouse enter event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.mouseEnterHandler_ = null;
|
||||
|
||||
/**
|
||||
* Mouse leave event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.mouseLeaveHandler_ = null;
|
||||
|
||||
/**
|
||||
* Key down event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onKeyDownWrapper_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.Menu, Blockly.Component);
|
||||
|
||||
@@ -73,7 +108,7 @@ Blockly.Menu.prototype.createDom = function() {
|
||||
Blockly.Menu.prototype.focus = function() {
|
||||
var el = this.getElement();
|
||||
if (el) {
|
||||
el.focus();
|
||||
el.focus({preventScroll:true});
|
||||
Blockly.utils.dom.addClass(el, 'focused');
|
||||
}
|
||||
};
|
||||
@@ -147,7 +182,6 @@ Blockly.Menu.prototype.attachEvents_ = function() {
|
||||
'mouseenter', this, this.handleMouseEnter_, true);
|
||||
this.mouseLeaveHandler_ = Blockly.bindEventWithChecks_(el,
|
||||
'mouseleave', this, this.handleMouseLeave_, true);
|
||||
|
||||
this.onKeyDownWrapper_ = Blockly.bindEventWithChecks_(el,
|
||||
'keydown', this, this.handleKeyEvent);
|
||||
};
|
||||
@@ -157,11 +191,26 @@ Blockly.Menu.prototype.attachEvents_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Menu.prototype.detachEvents_ = function() {
|
||||
Blockly.unbindEvent_(this.mouseOverHandler_);
|
||||
Blockly.unbindEvent_(this.clickHandler_);
|
||||
Blockly.unbindEvent_(this.mouseEnterHandler_);
|
||||
Blockly.unbindEvent_(this.mouseLeaveHandler_);
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
if (this.mouseOverHandler_) {
|
||||
Blockly.unbindEvent_(this.mouseOverHandler_);
|
||||
this.mouseOverHandler_ = null;
|
||||
}
|
||||
if (this.clickHandler_) {
|
||||
Blockly.unbindEvent_(this.clickHandler_);
|
||||
this.clickHandler_ = null;
|
||||
}
|
||||
if (this.mouseEnterHandler_) {
|
||||
Blockly.unbindEvent_(this.mouseEnterHandler_);
|
||||
this.mouseEnterHandler_ = null;
|
||||
}
|
||||
if (this.mouseLeaveHandler_) {
|
||||
Blockly.unbindEvent_(this.mouseLeaveHandler_);
|
||||
this.mouseLeaveHandler_ = null;
|
||||
}
|
||||
if (this.onKeyDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
this.onKeyDownWrapper_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
// Child component management.
|
||||
|
||||
@@ -44,6 +44,34 @@ goog.require('Blockly.utils.style');
|
||||
Blockly.tree.TreeControl = function(toolbox, config) {
|
||||
this.toolbox_ = toolbox;
|
||||
|
||||
/**
|
||||
* Focus event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onFocusWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Blur event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onBlurWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onClickWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Key down event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onKeydownWrapper_ = null;
|
||||
|
||||
Blockly.tree.BaseNode.call(this, '', config);
|
||||
|
||||
// The root is open and selected by default.
|
||||
@@ -272,10 +300,8 @@ Blockly.tree.TreeControl.prototype.attachEvents_ = function() {
|
||||
'focus', this, this.handleFocus_);
|
||||
this.onBlurWrapper_ = Blockly.bindEvent_(el,
|
||||
'blur', this, this.handleBlur_);
|
||||
|
||||
this.onClickWrapper_ = Blockly.bindEventWithChecks_(el,
|
||||
'click', this, this.handleMouseEvent_);
|
||||
|
||||
this.onKeydownWrapper_ = Blockly.bindEvent_(el,
|
||||
'keydown', this, this.handleKeyEvent_);
|
||||
};
|
||||
@@ -285,10 +311,22 @@ Blockly.tree.TreeControl.prototype.attachEvents_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.tree.TreeControl.prototype.detachEvents_ = function() {
|
||||
Blockly.unbindEvent_(this.onFocusWrapper_);
|
||||
Blockly.unbindEvent_(this.onBlurWrapper_);
|
||||
Blockly.unbindEvent_(this.onClickWrapper_);
|
||||
Blockly.unbindEvent_(this.onKeydownWrapper_);
|
||||
if (this.onFocusWrapper_) {
|
||||
Blockly.unbindEvent_(this.onFocusWrapper_);
|
||||
this.onFocusWrapper_ = null;
|
||||
}
|
||||
if (this.onBlurWrapper_) {
|
||||
Blockly.unbindEvent_(this.onBlurWrapper_);
|
||||
this.onBlurWrapper_ = null;
|
||||
}
|
||||
if (this.onClickWrapper_) {
|
||||
Blockly.unbindEvent_(this.onClickWrapper_);
|
||||
this.onClickWrapper_ = null;
|
||||
}
|
||||
if (this.onKeydownWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeydownWrapper_);
|
||||
this.onKeydownWrapper_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -166,6 +166,7 @@ Blockly.ContextMenu.hide = function() {
|
||||
Blockly.ContextMenu.currentBlock = null;
|
||||
if (Blockly.ContextMenu.eventWrapper_) {
|
||||
Blockly.unbindEvent_(Blockly.ContextMenu.eventWrapper_);
|
||||
Blockly.ContextMenu.eventWrapper_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -129,6 +129,13 @@ Blockly.Field = function(value, opt_validator, opt_config) {
|
||||
*/
|
||||
this.mouseDownWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Constants associated with the source block's renderer.
|
||||
* @type {Blockly.blockRendering.ConstantProvider}
|
||||
* @protected
|
||||
*/
|
||||
this.constants_ = null;
|
||||
|
||||
opt_config && this.configure_(opt_config);
|
||||
this.setValue(value);
|
||||
opt_validator && this.setValidator(opt_validator);
|
||||
@@ -257,24 +264,6 @@ Blockly.Field.prototype.EDITABLE = true;
|
||||
*/
|
||||
Blockly.Field.prototype.SERIALIZABLE = false;
|
||||
|
||||
/**
|
||||
* Point size of text. Should match blocklyText's font-size in CSS.
|
||||
* @const {number}
|
||||
*/
|
||||
Blockly.Field.FONTSIZE = 11;
|
||||
|
||||
/**
|
||||
* Text font weight. Should match blocklyText's font-weight in CSS.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.Field.FONTWEIGHT = 'normal';
|
||||
|
||||
/**
|
||||
* Text font family. Should match blocklyText's font-family in CSS.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.Field.FONTFAMILY = 'sans-serif';
|
||||
|
||||
/**
|
||||
* Process the configuration map passed to the field.
|
||||
* @param {!Object} config A map of options used to configure the field. See
|
||||
@@ -303,6 +292,9 @@ Blockly.Field.prototype.setSourceBlock = function(block) {
|
||||
throw Error('Field already bound to a block.');
|
||||
}
|
||||
this.sourceBlock_ = block;
|
||||
if (block.workspace.rendered) {
|
||||
this.constants_ = block.workspace.getRenderer().getConstants();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -661,8 +653,9 @@ Blockly.Field.prototype.updateWidth = function() {
|
||||
Blockly.Field.prototype.updateSize_ = function() {
|
||||
var textWidth = Blockly.utils.dom.getFastTextWidth(
|
||||
/** @type {!SVGTextElement} */ (this.textElement_),
|
||||
Blockly.Field.FONTSIZE, Blockly.Field.FONTWEIGHT,
|
||||
Blockly.Field.FONTFAMILY);
|
||||
this.constants_.FIELD_TEXT_FONTSIZE,
|
||||
this.constants_.FIELD_TEXT_FONTWEIGHT,
|
||||
this.constants_.FIELD_TEXT_FONTFAMILY);
|
||||
var totalWidth = textWidth;
|
||||
if (this.borderRect_) {
|
||||
totalWidth += Blockly.Field.X_PADDING;
|
||||
|
||||
@@ -330,9 +330,11 @@ Blockly.FieldAngle.prototype.dropdownCreate_ = function() {
|
||||
// a click handler on the drag surface to update the value if the surface
|
||||
// is clicked.
|
||||
this.clickSurfaceWrapper_ =
|
||||
Blockly.bindEventWithChecks_(circle, 'click', this, this.onMouseMove_, true, true);
|
||||
Blockly.bindEventWithChecks_(circle, 'click', this, this.onMouseMove_,
|
||||
true, true);
|
||||
this.moveSurfaceWrapper_ =
|
||||
Blockly.bindEventWithChecks_(circle, 'mousemove', this, this.onMouseMove_, true, true);
|
||||
Blockly.bindEventWithChecks_(circle, 'mousemove', this, this.onMouseMove_,
|
||||
true, true);
|
||||
return svg;
|
||||
};
|
||||
|
||||
@@ -343,12 +345,15 @@ Blockly.FieldAngle.prototype.dropdownCreate_ = function() {
|
||||
Blockly.FieldAngle.prototype.dropdownDispose_ = function() {
|
||||
if (this.clickWrapper_) {
|
||||
Blockly.unbindEvent_(this.clickWrapper_);
|
||||
this.clickWrapper_ = null;
|
||||
}
|
||||
if (this.clickSurfaceWrapper_) {
|
||||
Blockly.unbindEvent_(this.clickSurfaceWrapper_);
|
||||
this.clickSurfaceWrapper_ = null;
|
||||
}
|
||||
if (this.moveSurfaceWrapper_) {
|
||||
Blockly.unbindEvent_(this.moveSurfaceWrapper_);
|
||||
this.moveSurfaceWrapper_ = null;
|
||||
}
|
||||
this.gauge_ = null;
|
||||
this.line_ = null;
|
||||
|
||||
@@ -334,7 +334,7 @@ Blockly.FieldColour.prototype.showEditor_ = function() {
|
||||
this, this.dropdownDispose_.bind(this));
|
||||
|
||||
// Focus so we can start receiving keyboard events.
|
||||
this.picker_.focus();
|
||||
this.picker_.focus({preventScroll:true});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -487,7 +487,7 @@ Blockly.FieldColour.prototype.onMouseMove_ = function(e) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldColour.prototype.onMouseEnter_ = function() {
|
||||
this.picker_.focus();
|
||||
this.picker_.focus({preventScroll:true});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -610,18 +610,23 @@ Blockly.FieldColour.prototype.dropdownCreate_ = function() {
|
||||
Blockly.FieldColour.prototype.dropdownDispose_ = function() {
|
||||
if (this.onClickWrapper_) {
|
||||
Blockly.unbindEvent_(this.onClickWrapper_);
|
||||
this.onClickWrapper_ = null;
|
||||
}
|
||||
if (this.onMouseMoveWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseMoveWrapper_);
|
||||
this.onMouseMoveWrapper_ = null;
|
||||
}
|
||||
if (this.onMouseEnterWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseEnterWrapper_);
|
||||
this.onMouseEnterWrapper_ = null;
|
||||
}
|
||||
if (this.onMouseLeaveWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseLeaveWrapper_);
|
||||
this.onMouseLeaveWrapper_ = null;
|
||||
}
|
||||
if (this.onKeyDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
this.onKeyDownWrapper_ = null;
|
||||
}
|
||||
this.picker_ = null;
|
||||
this.highlightedIndex_ = null;
|
||||
|
||||
@@ -516,8 +516,9 @@ Blockly.FieldDropdown.prototype.renderSelectedImage_ = function(imageJson) {
|
||||
|
||||
var arrowWidth = Blockly.utils.dom.getFastTextWidth(
|
||||
/** @type {!SVGTSpanElement} */ (this.arrow_),
|
||||
Blockly.Field.FONTSIZE, Blockly.Field.FONTWEIGHT,
|
||||
Blockly.Field.FONTFAMILY);
|
||||
this.constants_.FIELD_TEXT_FONTSIZE,
|
||||
this.constants_.FIELD_TEXT_FONTWEIGHT,
|
||||
this.constants_.FIELD_TEXT_FONTFAMILY);
|
||||
|
||||
var imageHeight = Number(imageJson.height);
|
||||
var imageWidth = Number(imageJson.width);
|
||||
@@ -552,8 +553,9 @@ Blockly.FieldDropdown.prototype.renderSelectedText_ = function() {
|
||||
// Height and width include the border rect.
|
||||
this.size_.height = Blockly.Field.BORDER_RECT_DEFAULT_HEIGHT;
|
||||
this.size_.width = Blockly.utils.dom.getFastTextWidth(this.textElement_,
|
||||
Blockly.Field.FONTSIZE, Blockly.Field.FONTWEIGHT,
|
||||
Blockly.Field.FONTFAMILY) +
|
||||
this.constants_.FIELD_TEXT_FONTSIZE,
|
||||
this.constants_.FIELD_TEXT_FONTWEIGHT,
|
||||
this.constants_.FIELD_TEXT_FONTFAMILY) +
|
||||
Blockly.Field.X_PADDING;
|
||||
};
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ Blockly.FieldMultilineInput.prototype.widgetCreate_ = function() {
|
||||
var htmlInput = /** @type {HTMLTextAreaElement} */ (document.createElement('textarea'));
|
||||
htmlInput.className = 'blocklyHtmlInput blocklyHtmlTextAreaInput';
|
||||
htmlInput.setAttribute('spellcheck', this.spellcheck_);
|
||||
var fontSize = (Blockly.Field.FONTSIZE * scale) + 'pt';
|
||||
var fontSize = (this.constants_.FIELD_TEXT_FONTSIZE * scale) + 'pt';
|
||||
div.style.fontSize = fontSize;
|
||||
htmlInput.style.fontSize = fontSize;
|
||||
var borderRadius = (Blockly.FieldTextInput.BORDERRADIUS * scale) + 'px';
|
||||
|
||||
@@ -91,6 +91,13 @@ Blockly.FieldTextInput = function(opt_value, opt_validator, opt_config) {
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.fullBlockClickTarget_ = false;
|
||||
|
||||
/**
|
||||
* Blur input event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onBlurInputWrapper_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FieldTextInput, Blockly.Field);
|
||||
|
||||
@@ -319,7 +326,7 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) {
|
||||
this.isBeingEdited_ = true;
|
||||
|
||||
if (!quietInput) {
|
||||
this.htmlInput_.focus();
|
||||
this.htmlInput_.focus({preventScroll:true});
|
||||
this.htmlInput_.select();
|
||||
}
|
||||
};
|
||||
@@ -336,7 +343,7 @@ Blockly.FieldTextInput.prototype.widgetCreate_ = function() {
|
||||
htmlInput.className = 'blocklyHtmlInput';
|
||||
htmlInput.setAttribute('spellcheck', this.spellcheck_);
|
||||
var fontSize =
|
||||
(Blockly.Field.FONTSIZE * this.workspace_.scale) + 'pt';
|
||||
(this.constants_.FIELD_TEXT_FONTSIZE * this.workspace_.scale) + 'pt';
|
||||
div.style.fontSize = fontSize;
|
||||
htmlInput.style.fontSize = fontSize;
|
||||
var borderRadius =
|
||||
@@ -411,6 +418,9 @@ Blockly.FieldTextInput.prototype.bindInputEvents_ = function(htmlInput) {
|
||||
this.onKeyInputWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
htmlInput, 'input', this, this.onHtmlInputChange_);
|
||||
this.onBlurInputWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
htmlInput, 'blur', this, this.onHtmlInputBlur_);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -420,9 +430,15 @@ Blockly.FieldTextInput.prototype.bindInputEvents_ = function(htmlInput) {
|
||||
Blockly.FieldTextInput.prototype.unbindInputEvents_ = function() {
|
||||
if (this.onKeyDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
this.onKeyDownWrapper_ = null;
|
||||
}
|
||||
if (this.onKeyInputWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyInputWrapper_);
|
||||
this.onKeyInputWrapper_ = null;
|
||||
}
|
||||
if (this.onBlurInputWrapper_) {
|
||||
Blockly.unbindEvent_(this.onBlurInputWrapper_);
|
||||
this.onBlurInputWrapper_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -468,6 +484,16 @@ Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(_e) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle blur for the editor.
|
||||
* @param {!Event} _e Focus event.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.onHtmlInputBlur_ = function(_e) {
|
||||
Blockly.WidgetDiv.hide();
|
||||
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the html input value and the field's internal value. The difference
|
||||
* between this and ``setValue`` is that this also updates the html input
|
||||
|
||||
@@ -847,3 +847,15 @@ Blockly.Flyout.prototype.placeNewBlock_ = function(oldBlock) {
|
||||
block.moveBy(finalOffset.x, finalOffset.y);
|
||||
return block;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard accessibility mode is enabled.
|
||||
* @param {!Blockly.Action} action The action to be handled.
|
||||
* @return {boolean} True if the flyout handled the action, false otherwise.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Flyout.prototype.onBlocklyAction = function(action) {
|
||||
var cursor = this.workspace_.getCursor();
|
||||
return cursor.onBlocklyAction(action);
|
||||
};
|
||||
|
||||
@@ -87,6 +87,13 @@ Blockly.FlyoutButton = function(workspace, targetWorkspace, xml, isLabel) {
|
||||
* @private
|
||||
*/
|
||||
this.cssClass_ = xml.getAttribute('web-class') || null;
|
||||
|
||||
/**
|
||||
* Mouse up event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseUpWrapper_ = null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -106,13 +113,6 @@ Blockly.FlyoutButton.prototype.width = 0;
|
||||
*/
|
||||
Blockly.FlyoutButton.prototype.height = 0;
|
||||
|
||||
/**
|
||||
* Opaque data that can be passed to Blockly.unbindEvent_.
|
||||
* @type {Array.<!Array>}
|
||||
* @private
|
||||
*/
|
||||
Blockly.FlyoutButton.prototype.onMouseUpWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Create the button elements.
|
||||
* @return {!SVGElement} The button's SVG group.
|
||||
|
||||
@@ -162,7 +162,7 @@ Blockly.Gesture = function(e, creatorWorkspace) {
|
||||
/**
|
||||
* A handle to use to unbind a mouse move listener at the end of a drag.
|
||||
* Opaque data returned from Blockly.bindEventWithChecks_.
|
||||
* @type {Array.<!Array>}
|
||||
* @type {?Blockly.EventData}
|
||||
* @protected
|
||||
*/
|
||||
this.onMoveWrapper_ = null;
|
||||
@@ -170,7 +170,7 @@ Blockly.Gesture = function(e, creatorWorkspace) {
|
||||
/**
|
||||
* A handle to use to unbind a mouse up listener at the end of a drag.
|
||||
* Opaque data returned from Blockly.bindEventWithChecks_.
|
||||
* @type {Array.<!Array>}
|
||||
* @type {?Blockly.EventData}
|
||||
* @protected
|
||||
*/
|
||||
this.onUpWrapper_ = null;
|
||||
@@ -483,12 +483,14 @@ Blockly.Gesture.prototype.doStart = function(e) {
|
||||
// dragged, the block was moved, the parent workspace zoomed, etc.
|
||||
this.startWorkspace_.resize();
|
||||
}
|
||||
this.startWorkspace_.markFocused();
|
||||
this.mostRecentEvent_ = e;
|
||||
|
||||
// Hide chaff also hides the flyout, so don't do it if the click is in a
|
||||
// flyout.
|
||||
Blockly.hideChaff(!!this.flyout_);
|
||||
|
||||
this.startWorkspace_.markFocused();
|
||||
this.mostRecentEvent_ = e;
|
||||
|
||||
Blockly.Tooltip.block();
|
||||
|
||||
if (this.targetBlock_) {
|
||||
|
||||
@@ -78,18 +78,16 @@ Blockly.inject = function(container, opt_options) {
|
||||
Blockly.user.keyMap.setKeyMap(options.keyMap);
|
||||
|
||||
Blockly.init_(workspace);
|
||||
|
||||
// Keep focus on the first workspace so entering keyboard navigation looks correct.
|
||||
Blockly.mainWorkspace = workspace;
|
||||
|
||||
Blockly.svgResize(workspace);
|
||||
|
||||
subContainer.addEventListener('focus', function() {
|
||||
subContainer.addEventListener('focusin', function() {
|
||||
Blockly.mainWorkspace = workspace;
|
||||
});
|
||||
|
||||
subContainer.addEventListener('blur', function() {
|
||||
Blockly.mainWorkspace = null;
|
||||
});
|
||||
|
||||
return workspace;
|
||||
};
|
||||
|
||||
@@ -127,7 +125,8 @@ Blockly.createDom_ = function(container, options) {
|
||||
'xmlns:html': Blockly.utils.dom.HTML_NS,
|
||||
'xmlns:xlink': Blockly.utils.dom.XLINK_NS,
|
||||
'version': '1.1',
|
||||
'class': 'blocklySvg'
|
||||
'class': 'blocklySvg',
|
||||
'tabindex': '0'
|
||||
}, container);
|
||||
/*
|
||||
<defs>
|
||||
@@ -183,7 +182,6 @@ Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface,
|
||||
|
||||
// A null translation will also apply the correct initial scale.
|
||||
mainWorkspace.translate(0, 0);
|
||||
Blockly.mainWorkspace = mainWorkspace;
|
||||
|
||||
if (!options.readOnly && !mainWorkspace.isMovable()) {
|
||||
// Helper function for the workspaceChanged callback.
|
||||
@@ -253,7 +251,9 @@ Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface,
|
||||
case Blockly.Events.BLOCK_CREATE:
|
||||
case Blockly.Events.BLOCK_MOVE:
|
||||
var object = mainWorkspace.getBlockById(e.blockId);
|
||||
object = object.getRootBlock();
|
||||
if (object) {
|
||||
object = object.getRootBlock();
|
||||
}
|
||||
break;
|
||||
case Blockly.Events.COMMENT_CREATE:
|
||||
case Blockly.Events.COMMENT_MOVE:
|
||||
@@ -311,7 +311,7 @@ Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface,
|
||||
object.moveBy(deltaX, deltaY);
|
||||
}
|
||||
if (e) {
|
||||
if (!e.group) {
|
||||
if (!e.group && object) {
|
||||
console.log('WARNING: Moved object in bounds but there was no' +
|
||||
' event group. This may break undo.');
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
goog.provide('Blockly.Cursor');
|
||||
|
||||
goog.require('Blockly.navigation');
|
||||
|
||||
/**
|
||||
* Class for a cursor.
|
||||
@@ -94,10 +95,42 @@ Blockly.Cursor.prototype.hide = function() {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard navigation is enabled.
|
||||
* @param {!Blockly.Action} action The action to be handled.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
*/
|
||||
Blockly.Cursor.prototype.onBlocklyAction = function(action) {
|
||||
// If we are on a field give it the option to handle the action
|
||||
if (this.getCurNode() &&
|
||||
this.getCurNode().getType() === Blockly.ASTNode.types.FIELD &&
|
||||
this.getCurNode().getLocation().onBlocklyAction(action)) {
|
||||
return true;
|
||||
}
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.PREVIOUS:
|
||||
this.prev();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.OUT:
|
||||
this.out();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.NEXT:
|
||||
this.next();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.IN:
|
||||
this.in();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the next connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The next element, or null if the current node is
|
||||
* not set or there is no next value.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Cursor.prototype.next = function() {
|
||||
var curNode = this.getCurNode();
|
||||
@@ -122,6 +155,7 @@ Blockly.Cursor.prototype.next = function() {
|
||||
* Find the in connection or field.
|
||||
* @return {Blockly.ASTNode} The in element, or null if the current node is
|
||||
* not set or there is no in value.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Cursor.prototype.in = function() {
|
||||
var curNode = this.getCurNode();
|
||||
@@ -146,6 +180,7 @@ Blockly.Cursor.prototype.in = function() {
|
||||
* Find the previous connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The previous element, or null if the current node
|
||||
* is not set or there is no previous value.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Cursor.prototype.prev = function() {
|
||||
var curNode = this.getCurNode();
|
||||
@@ -170,6 +205,7 @@ Blockly.Cursor.prototype.prev = function() {
|
||||
* Find the out connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The out element, or null if the current node is
|
||||
* not set or there is no out value.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Cursor.prototype.out = function() {
|
||||
var curNode = this.getCurNode();
|
||||
|
||||
@@ -39,6 +39,26 @@ Blockly.FlyoutCursor = function() {
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FlyoutCursor, Blockly.Cursor);
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard navigation is enabled.
|
||||
* @param {!Blockly.Action} action The action to be handled.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutCursor.prototype.onBlocklyAction = function(action) {
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.PREVIOUS:
|
||||
this.prev();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.NEXT:
|
||||
this.next();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the next connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The next element, or null if the current node is
|
||||
|
||||
@@ -749,8 +749,8 @@ Blockly.navigation.onKeyPress = function(e) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute any actions on the flyout, workspace, or toolbox that correspond to
|
||||
* the given action.
|
||||
* Decides which actions to handle depending on keyboard navigation and readonly
|
||||
* states.
|
||||
* @param {!Blockly.Action} action The current action.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
*/
|
||||
@@ -775,92 +775,44 @@ Blockly.navigation.onBlocklyAction = function(action) {
|
||||
|
||||
/**
|
||||
* Handles the action or dispatches to the appropriate action handler.
|
||||
* @param {!Blockly.Action} action The current action
|
||||
* @param {!Blockly.Action} action The action to handle.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.handleActions_ = function(action) {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
if (action.name === Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV) {
|
||||
if (action.name == Blockly.navigation.actionNames.TOOLBOX ||
|
||||
Blockly.navigation.currentState_ == Blockly.navigation.STATE_TOOLBOX) {
|
||||
return Blockly.navigation.toolboxOnAction_(action);
|
||||
} else if (action.name == Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV) {
|
||||
Blockly.navigation.disableKeyboardAccessibility();
|
||||
return true;
|
||||
} else if (action.name === Blockly.navigation.actionNames.TOOLBOX) {
|
||||
if (!workspace.getToolbox()) {
|
||||
Blockly.navigation.focusFlyout_();
|
||||
} else {
|
||||
Blockly.navigation.focusToolbox_();
|
||||
}
|
||||
return true;
|
||||
} else if (Blockly.navigation.currentState_ === Blockly.navigation.STATE_WS) {
|
||||
var curNode = workspace.getCursor().getCurNode();
|
||||
var actionHandled = false;
|
||||
if (curNode && curNode.getType() === Blockly.ASTNode.types.FIELD) {
|
||||
actionHandled = curNode.getLocation().onBlocklyAction(action);
|
||||
}
|
||||
if (!actionHandled) {
|
||||
actionHandled = Blockly.navigation.workspaceOnAction_(action);
|
||||
}
|
||||
return actionHandled;
|
||||
} else if (Blockly.navigation.currentState_ === Blockly.navigation.STATE_FLYOUT) {
|
||||
} if (Blockly.navigation.currentState_ == Blockly.navigation.STATE_WS) {
|
||||
return Blockly.navigation.workspaceOnAction_(action);
|
||||
} else if (Blockly.navigation.currentState_ == Blockly.navigation.STATE_FLYOUT) {
|
||||
return Blockly.navigation.flyoutOnAction_(action);
|
||||
} else if (Blockly.navigation.currentState_ === Blockly.navigation.STATE_TOOLBOX) {
|
||||
return Blockly.navigation.toolboxOnAction_(action);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle all actions performed on the workspace.
|
||||
* @param {!Blockly.Action} action The action to handle.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.workspaceOnAction_ = function(action) {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.PREVIOUS:
|
||||
workspace.getCursor().prev();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.OUT:
|
||||
workspace.getCursor().out();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.NEXT:
|
||||
workspace.getCursor().next();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.IN:
|
||||
workspace.getCursor().in();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.INSERT:
|
||||
Blockly.navigation.modify_();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.MARK:
|
||||
Blockly.navigation.handleEnterForWS_();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.DISCONNECT:
|
||||
Blockly.navigation.disconnectBlocks_();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle all actions performed on the flyout.
|
||||
* Handles the given action for the flyout.
|
||||
* @param {!Blockly.Action} action The action to handle.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.flyoutOnAction_ = function(action) {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var toolbox = workspace.getToolbox();
|
||||
var flyout = toolbox ? toolbox.flyout_ : workspace.getFlyout();
|
||||
|
||||
if (flyout && flyout.onBlocklyAction(action)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.PREVIOUS:
|
||||
Blockly.navigation.getFlyoutCursor_().prev();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.OUT:
|
||||
Blockly.navigation.focusToolbox_();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.NEXT:
|
||||
Blockly.navigation.getFlyoutCursor_().next();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.MARK:
|
||||
Blockly.navigation.insertFromFlyout();
|
||||
return true;
|
||||
@@ -873,24 +825,60 @@ Blockly.navigation.flyoutOnAction_ = function(action) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle all actions performeed on the toolbox.
|
||||
* Handles the given action for the toolbox.
|
||||
* @param {!Blockly.Action} action The action to handle.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.toolboxOnAction_ = function(action) {
|
||||
if (action.name === Blockly.navigation.actionNames.EXIT) {
|
||||
Blockly.navigation.focusWorkspace_();
|
||||
return true;
|
||||
}
|
||||
var toolbox = Blockly.getMainWorkspace().getToolbox();
|
||||
var handled = toolbox.onBlocklyAction(action);
|
||||
if (!handled && action.name === Blockly.navigation.actionNames.IN) {
|
||||
Blockly.navigation.focusFlyout_();
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
var toolbox = workspace.getToolbox();
|
||||
var handled = toolbox ? toolbox.onBlocklyAction(action) : false;
|
||||
|
||||
if (handled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return handled;
|
||||
if (action.name === Blockly.navigation.actionNames.TOOLBOX) {
|
||||
if (!workspace.getToolbox()) {
|
||||
Blockly.navigation.focusFlyout_();
|
||||
} else {
|
||||
Blockly.navigation.focusToolbox_();
|
||||
}
|
||||
return true;
|
||||
} else if (action.name === Blockly.navigation.actionNames.IN) {
|
||||
Blockly.navigation.focusFlyout_();
|
||||
return true;
|
||||
} else if (action.name === Blockly.navigation.actionNames.EXIT) {
|
||||
Blockly.navigation.focusWorkspace_();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the given action for the workspace.
|
||||
* @param {!Blockly.Action} action The action to handle.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.workspaceOnAction_ = function(action) {
|
||||
if (Blockly.getMainWorkspace().getCursor().onBlocklyAction(action)) {
|
||||
return true;
|
||||
}
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.INSERT:
|
||||
Blockly.navigation.modify_();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.MARK:
|
||||
Blockly.navigation.handleEnterForWS_();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.DISCONNECT:
|
||||
Blockly.navigation.disconnectBlocks_();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -136,6 +136,27 @@ Blockly.blockRendering.ConstantProvider = function() {
|
||||
*/
|
||||
this.JAGGED_TEETH_WIDTH = 6;
|
||||
|
||||
/**
|
||||
* Point size of text. Should match blocklyText's font-size in CSS.
|
||||
* @type {number}
|
||||
* @const
|
||||
*/
|
||||
this.FIELD_TEXT_FONTSIZE = 11;
|
||||
|
||||
/**
|
||||
* Text font weight. Should match blocklyText's font-weight in CSS.
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
this.FIELD_TEXT_FONTWEIGHT = 'normal';
|
||||
|
||||
/**
|
||||
* Text font family. Should match blocklyText's font-family in CSS.
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
this.FIELD_TEXT_FONTFAMILY = 'sans-serif';
|
||||
|
||||
/**
|
||||
* The ID of the emboss filter, or the empty string if no filter is set.
|
||||
* @type {string}
|
||||
|
||||
@@ -111,3 +111,12 @@ Blockly.blockRendering.IPathObject.prototype.updateInsertionMarker;
|
||||
* @package
|
||||
*/
|
||||
Blockly.blockRendering.IPathObject.prototype.updateMovable;
|
||||
|
||||
/**
|
||||
* Add or remove styling that shows that if the dragging block is dropped, this
|
||||
* block will be replaced. If a shadow block, it will disappear. Otherwise it
|
||||
* will bump.
|
||||
* @param {boolean} enable True if styling should be added.
|
||||
* @package
|
||||
*/
|
||||
Blockly.blockRendering.IPathObject.prototype.updateReplacementHighlight;
|
||||
|
||||
@@ -451,6 +451,12 @@ Blockly.blockRendering.RenderInfo.prototype.addElemSpacing_ = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.blockRendering.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) {
|
||||
if (!prev) {
|
||||
// Statement input padding.
|
||||
if (next && Blockly.blockRendering.Types.isStatementInput(next)) {
|
||||
return this.constants_.STATEMENT_INPUT_PADDING_LEFT;
|
||||
}
|
||||
}
|
||||
// Between inputs and the end of the row.
|
||||
if (prev && Blockly.blockRendering.Types.isInput(prev) && !next) {
|
||||
if (Blockly.blockRendering.Types.isExternalInput(prev)) {
|
||||
|
||||
@@ -221,3 +221,15 @@ Blockly.blockRendering.PathObject.prototype.updateMovable = function(enable) {
|
||||
this.setClass_('blocklyDraggable', enable);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add or remove styling that shows that if the dragging block is dropped, this
|
||||
* block will be replaced. If a shadow block, it will disappear. Otherwise it
|
||||
* will bump.
|
||||
* @param {boolean} enable True if styling should be added.
|
||||
* @package
|
||||
*/
|
||||
Blockly.blockRendering.PathObject.prototype.updateReplacementHighlight =
|
||||
function(enable) {
|
||||
/* eslint-disable indent */
|
||||
this.setClass_('blocklyReplaceable', enable);
|
||||
}; /* eslint-enable indent */
|
||||
|
||||
@@ -41,6 +41,26 @@ Blockly.zelos.ConstantProvider = function() {
|
||||
|
||||
this.GRID_UNIT = 4;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.SMALL_PADDING = this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.MEDIUM_PADDING = 2 * this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.MEDIUM_LARGE_PADDING = 3 * this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.LARGE_PADDING = 4 * this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -76,10 +96,21 @@ Blockly.zelos.ConstantProvider = function() {
|
||||
*/
|
||||
this.STATEMENT_BOTTOM_SPACER = -this.NOTCH_HEIGHT;
|
||||
|
||||
/**
|
||||
* Minimum statement input spacer width.
|
||||
* @type {number}
|
||||
*/
|
||||
this.STATEMENT_INPUT_SPACER_MIN_WIDTH = 30 * this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.AFTER_STATEMENT_BOTTOM_ROW_MIN_HEIGHT = this.LARGE_PADDING * 2;
|
||||
this.STATEMENT_INPUT_PADDING_LEFT = 4 * this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.AFTER_STATEMENT_BOTTOM_ROW_MIN_HEIGHT = 7 * this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -91,6 +122,11 @@ Blockly.zelos.ConstantProvider = function() {
|
||||
*/
|
||||
this.EMPTY_INLINE_INPUT_HEIGHT = 8 * this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
this.DUMMY_INPUT_MIN_HEIGHT = 6 * this.GRID_UNIT;
|
||||
|
||||
/**
|
||||
* The ID of the highlight glow filter, or the empty string if no filter is
|
||||
* set.
|
||||
|
||||
@@ -109,148 +109,6 @@ Blockly.zelos.RenderInfo.prototype.computeBounds_ = function() {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) {
|
||||
if (!prev || !next) {
|
||||
// No need for padding at the beginning or end of the row if the
|
||||
// output shape is dynamic.
|
||||
if (this.outputConnection && this.outputConnection.isDynamicShape) {
|
||||
return this.constants_.NO_PADDING;
|
||||
}
|
||||
}
|
||||
if (!prev) {
|
||||
// Between an editable field and the beginning of the row.
|
||||
if (next && Blockly.blockRendering.Types.isField(next) && next.isEditable) {
|
||||
return this.constants_.MEDIUM_PADDING;
|
||||
}
|
||||
// Inline input at the beginning of the row.
|
||||
if (next && Blockly.blockRendering.Types.isInlineInput(next)) {
|
||||
return this.constants_.MEDIUM_LARGE_PADDING;
|
||||
}
|
||||
if (next && Blockly.blockRendering.Types.isStatementInput(next)) {
|
||||
return this.constants_.STATEMENT_INPUT_PADDING_LEFT;
|
||||
}
|
||||
// Anything else at the beginning of the row.
|
||||
return this.constants_.LARGE_PADDING;
|
||||
}
|
||||
|
||||
// Spacing between a non-input and the end of the row.
|
||||
if (!Blockly.blockRendering.Types.isInput(prev) && !next) {
|
||||
// Between an editable field and the end of the row.
|
||||
if (Blockly.blockRendering.Types.isField(prev) && prev.isEditable) {
|
||||
return this.constants_.MEDIUM_PADDING;
|
||||
}
|
||||
// Padding at the end of an icon-only row to make the block shape clearer.
|
||||
if (Blockly.blockRendering.Types.isIcon(prev)) {
|
||||
return (this.constants_.LARGE_PADDING * 2) + 1;
|
||||
}
|
||||
if (Blockly.blockRendering.Types.isHat(prev)) {
|
||||
return this.constants_.NO_PADDING;
|
||||
}
|
||||
// Establish a minimum width for a block with a previous or next connection.
|
||||
if (Blockly.blockRendering.Types.isPreviousOrNextConnection(prev)) {
|
||||
return this.constants_.LARGE_PADDING;
|
||||
}
|
||||
// Between rounded corner and the end of the row.
|
||||
if (Blockly.blockRendering.Types.isLeftRoundedCorner(prev)) {
|
||||
return this.constants_.MIN_BLOCK_WIDTH;
|
||||
}
|
||||
// Between a jagged edge and the end of the row.
|
||||
if (Blockly.blockRendering.Types.isJaggedEdge(prev)) {
|
||||
return this.constants_.NO_PADDING;
|
||||
}
|
||||
// Between noneditable fields and icons and the end of the row.
|
||||
return this.constants_.LARGE_PADDING;
|
||||
}
|
||||
|
||||
// Between inputs and the end of the row.
|
||||
if (Blockly.blockRendering.Types.isInput(prev) && !next) {
|
||||
if (Blockly.blockRendering.Types.isExternalInput(prev)) {
|
||||
return this.constants_.NO_PADDING;
|
||||
} else if (Blockly.blockRendering.Types.isInlineInput(prev)) {
|
||||
return this.constants_.LARGE_PADDING;
|
||||
} else if (Blockly.blockRendering.Types.isStatementInput(prev)) {
|
||||
return this.constants_.NO_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
// Spacing between a non-input and an input.
|
||||
if (!Blockly.blockRendering.Types.isInput(prev) &&
|
||||
next && Blockly.blockRendering.Types.isInput(next)) {
|
||||
// Between an editable field and an input.
|
||||
if (prev.isEditable) {
|
||||
if (Blockly.blockRendering.Types.isInlineInput(next)) {
|
||||
return this.constants_.MEDIUM_PADDING;
|
||||
} else if (Blockly.blockRendering.Types.isExternalInput(next)) {
|
||||
return this.constants_.MEDIUM_PADDING;
|
||||
}
|
||||
} else {
|
||||
if (Blockly.blockRendering.Types.isInlineInput(next)) {
|
||||
return this.constants_.MEDIUM_LARGE_PADDING;
|
||||
} else if (Blockly.blockRendering.Types.isExternalInput(next)) {
|
||||
return this.constants_.MEDIUM_LARGE_PADDING;
|
||||
} else if (Blockly.blockRendering.Types.isStatementInput(next)) {
|
||||
return this.constants_.LARGE_PADDING;
|
||||
}
|
||||
}
|
||||
return this.constants_.LARGE_PADDING - 1;
|
||||
}
|
||||
|
||||
// Spacing between an icon and an icon or field.
|
||||
if (Blockly.blockRendering.Types.isIcon(prev) &&
|
||||
next && !Blockly.blockRendering.Types.isInput(next)) {
|
||||
return this.constants_.LARGE_PADDING;
|
||||
}
|
||||
|
||||
// Spacing between an inline input and a field.
|
||||
if (Blockly.blockRendering.Types.isInlineInput(prev) &&
|
||||
next && !Blockly.blockRendering.Types.isInput(next)) {
|
||||
// Editable field after inline input.
|
||||
if (next.isEditable) {
|
||||
return this.constants_.MEDIUM_PADDING;
|
||||
} else {
|
||||
// Noneditable field after inline input.
|
||||
return this.constants_.LARGE_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
if (Blockly.blockRendering.Types.isLeftSquareCorner(prev) && next) {
|
||||
// Spacing between a hat and a corner
|
||||
if (Blockly.blockRendering.Types.isHat(next)) {
|
||||
return this.constants_.NO_PADDING;
|
||||
}
|
||||
// Spacing between a square corner and a previous or next connection
|
||||
if (Blockly.blockRendering.Types.isPreviousConnection(next) ||
|
||||
Blockly.blockRendering.Types.isNextConnection(next)) {
|
||||
return next.notchOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// Spacing between a rounded corner and a previous or next connection.
|
||||
if (Blockly.blockRendering.Types.isLeftRoundedCorner(prev) && next) {
|
||||
if (Blockly.blockRendering.Types.isPreviousConnection(next) ||
|
||||
Blockly.blockRendering.Types.isNextConnection(next)) {
|
||||
return next.notchOffset - this.constants_.CORNER_RADIUS;
|
||||
}
|
||||
}
|
||||
|
||||
// Spacing between two fields of the same editability.
|
||||
if (!Blockly.blockRendering.Types.isInput(prev) &&
|
||||
next && !Blockly.blockRendering.Types.isInput(next) &&
|
||||
(prev.isEditable == next.isEditable)) {
|
||||
return this.constants_.LARGE_PADDING;
|
||||
}
|
||||
|
||||
// Spacing between anything and a jagged edge.
|
||||
if (next && Blockly.blockRendering.Types.isJaggedEdge(next)) {
|
||||
return this.constants_.LARGE_PADDING;
|
||||
}
|
||||
|
||||
return this.constants_.MEDIUM_PADDING;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -291,10 +149,10 @@ Blockly.zelos.RenderInfo.prototype.getSpacerRowHeight_ = function(
|
||||
return this.constants_.EMPTY_BLOCK_SPACER_HEIGHT;
|
||||
}
|
||||
// Top and bottom rows act as a spacer so we don't need any extra padding.
|
||||
if ((Blockly.blockRendering.Types.isTopRow(prev) && !prev.hasPreviousConnection)) {
|
||||
if ((Blockly.blockRendering.Types.isTopRow(prev))) {
|
||||
return this.constants_.NO_PADDING;
|
||||
}
|
||||
if ((Blockly.blockRendering.Types.isBottomRow(next) && !next.hasNextConnection)) {
|
||||
if ((Blockly.blockRendering.Types.isBottomRow(next))) {
|
||||
return this.constants_.NO_PADDING;
|
||||
}
|
||||
return this.constants_.MEDIUM_PADDING;
|
||||
|
||||
@@ -81,7 +81,7 @@ Blockly.TouchGesture = function(e, creatorWorkspace) {
|
||||
* A handle to use to unbind the second touch start or pointer down listener
|
||||
* at the end of a drag.
|
||||
* Opaque data returned from Blockly.bindEventWithChecks_.
|
||||
* @type {Array.<!Array>}
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onStartWrapper_ = null;
|
||||
|
||||
@@ -49,6 +49,21 @@ goog.require('Blockly.WorkspaceComment');
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg = function(workspace, content, height, width,
|
||||
opt_id) {
|
||||
|
||||
/**
|
||||
* Mouse up event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseUpWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseMoveWrapper_ = null;
|
||||
|
||||
// Create core elements for the block.
|
||||
/**
|
||||
* @type {SVGElement}
|
||||
|
||||
@@ -1874,7 +1874,7 @@ Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() {
|
||||
}
|
||||
try {
|
||||
// Focus the workspace SVG - this is for Chrome and Firefox.
|
||||
this.getParentSvg().focus();
|
||||
this.getParentSvg().focus({preventScroll:true});
|
||||
} catch (e) {
|
||||
// IE and Edge do not support focus on SVG elements. When that fails
|
||||
// above, get the injectionDiv (the workspace's parent) and focus that
|
||||
@@ -1886,7 +1886,7 @@ Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() {
|
||||
} catch (e) {
|
||||
// setActive support was discontinued in Edge so when that fails, call
|
||||
// focus instead.
|
||||
this.getParentSvg().parentNode.focus();
|
||||
this.getParentSvg().parentNode.focus({preventScroll:true});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,6 +39,20 @@ var CustomFields = CustomFields || {};
|
||||
*/
|
||||
CustomFields.FieldPitch = function(text) {
|
||||
CustomFields.FieldPitch.superClass_.constructor.call(this, text);
|
||||
|
||||
/**
|
||||
* Click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.clickWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.moveWrapper_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(CustomFields.FieldPitch, Blockly.FieldTextInput);
|
||||
|
||||
@@ -112,8 +126,15 @@ CustomFields.FieldPitch.prototype.dropdownCreate_ = function() {
|
||||
* @private
|
||||
*/
|
||||
CustomFields.FieldPitch.prototype.dropdownDispose_ = function() {
|
||||
Blockly.unbindEvent_(this.clickWrapper_);
|
||||
Blockly.unbindEvent_(this.moveWrapper_);
|
||||
if (this.clickWrapper_) {
|
||||
Blockly.unbindEvent_(this.clickWrapper_);
|
||||
this.clickWrapper_ = null;
|
||||
}
|
||||
if (this.moveWrapper_) {
|
||||
Blockly.unbindEvent_(this.moveWrapper_);
|
||||
this.moveWrapper_ = null;
|
||||
}
|
||||
this.imageElement_ = null;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
26
externs/goog-externs.js
Normal file
26
externs/goog-externs.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* 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 Externs for goog.
|
||||
* @externs
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {!Object}
|
||||
*/
|
||||
var goog = {};
|
||||
54
gulpfile.js
54
gulpfile.js
@@ -32,8 +32,10 @@ var path = require('path');
|
||||
var fs = require('fs');
|
||||
var rimraf = require('rimraf');
|
||||
var execSync = require('child_process').execSync;
|
||||
var through2 = require('through2');
|
||||
|
||||
var closureCompiler = require('google-closure-compiler').gulp();
|
||||
var closureDeps = require('google-closure-deps');
|
||||
var packageJson = require('./package.json');
|
||||
var argv = require('yargs').argv;
|
||||
|
||||
@@ -183,7 +185,7 @@ gulp.task('build-core', function () {
|
||||
dependency_mode: 'PRUNE',
|
||||
entry_point: './core-requires.js',
|
||||
js_output_file: 'blockly_compressed.js',
|
||||
externs: './externs/svg-externs.js',
|
||||
externs: ['./externs/svg-externs.js', './externs/goog-externs.js'],
|
||||
define: defines
|
||||
}, argv.verbose, argv.strict))
|
||||
.pipe(prependHeader())
|
||||
@@ -217,6 +219,7 @@ goog.provide('Blockly.Warning');`;
|
||||
.pipe(stripApacheLicense())
|
||||
.pipe(compile({
|
||||
dependency_mode: 'NONE',
|
||||
externs: ['./externs/goog-externs.js'],
|
||||
js_output_file: 'blocks_compressed.js'
|
||||
}, argv.verbose, argv.strict))
|
||||
.pipe(gulp.replace('\'use strict\';', '\'use strict\';\n\n\n'))
|
||||
@@ -245,6 +248,7 @@ goog.provide('Blockly.utils.string');`;
|
||||
`${provides}goog.provide('Blockly.${namespace}');`))
|
||||
.pipe(compile({
|
||||
dependency_mode: 'NONE',
|
||||
externs: ['./externs/goog-externs.js'],
|
||||
js_output_file: `${language}_compressed.js`
|
||||
}, argv.verbose, argv.strict))
|
||||
.pipe(gulp.replace('\'use strict\';', '\'use strict\';\n\n\n'))
|
||||
@@ -338,27 +342,37 @@ if (this.IS_NODE_JS) {
|
||||
document.write('<script>this.BLOCKLY_BOOT(this);</script>');
|
||||
}
|
||||
`;
|
||||
const file = 'blockly_uncompressed.js';
|
||||
// Run depswriter.py and which scans the core directory and writes out a ``goog.addDependency`` line for each file.
|
||||
const cmd = `python ./node_modules/google-closure-library/closure/bin/build/depswriter.py \
|
||||
--root_with_prefix="./core ../core" > ${file}`;
|
||||
execSync(cmd, { stdio: 'inherit' });
|
||||
|
||||
const requires = `goog.addDependency("base.js", [], []);\n\n// Load Blockly.\ngoog.require('Blockly.requires')\n`;
|
||||
let deps = [];
|
||||
return gulp.src('core/**/**/*.js')
|
||||
.pipe(through2.obj((file, _enc, cb) => {
|
||||
deps.push(closureDeps.parser.parseFile(file.path).dependency);
|
||||
cb(null);
|
||||
}))
|
||||
.on('end', () => {
|
||||
const graph = new closureDeps.depGraph.Graph(deps);
|
||||
let addDependency = [];
|
||||
graph.depsByPath.forEach(dep => {
|
||||
addDependency.push('goog.addDependency(' + [
|
||||
'"' + path.relative('./closure/goog', dep.path) + '"',
|
||||
'[' + dep.closureSymbols
|
||||
.map(s => `'${s}'`).join(', ') + ']',
|
||||
'[' + dep.imports
|
||||
.map(i => i.symOrPath)
|
||||
.filter(i => i !== 'goog')
|
||||
.sort()
|
||||
.map(i => `'${i}'`).join(', ') + ']',
|
||||
].join(', ') + ');');
|
||||
});
|
||||
const requires = `
|
||||
goog.addDependency("base.js", [], []);
|
||||
|
||||
return gulp.src(file)
|
||||
// Remove comments so we're compatible with the build.py script
|
||||
.pipe(gulp.replace(/\/\/.*\n/gm, ''))
|
||||
// Replace quotes to be compatible with build.py
|
||||
.pipe(gulp.replace(/\'(.*\.js)\'/gm, '"$1"'))
|
||||
// Remove last parameter to be compatible with build.py
|
||||
.pipe(gulp.replace(/, \{\}\);/gm, ');'))
|
||||
// Find the Blockly directory name and replace it with a JS variable.
|
||||
// This allows blockly_uncompressed.js to be compiled on one computer and be
|
||||
// used on another, even if the directory name differs.
|
||||
.pipe(gulp.replace(/\.\.\/core/gm, `../../core`))
|
||||
.pipe(gulp.insert.wrap(header, requires + footer))
|
||||
.pipe(gulp.dest('./'));
|
||||
// Load Blockly.
|
||||
goog.require('Blockly.requires')
|
||||
`;
|
||||
fs.writeFileSync('blockly_uncompressed.js',
|
||||
header + addDependency.join('\n') + requires + footer);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"RENAME_VARIABLE": "Преименувај променлива...",
|
||||
"RENAME_VARIABLE_TITLE": "Преименувај ги сите променливи „%1“ во:",
|
||||
"NEW_VARIABLE": "Создај променлива...",
|
||||
"NEW_STRING_VARIABLE": "Создај променлива на низа...",
|
||||
"NEW_VARIABLE_TYPE_TITLE": "Тип на новата променлива:",
|
||||
"NEW_VARIABLE_TITLE": "Назив на новата променлива:",
|
||||
"VARIABLE_ALREADY_EXISTS": "Променлива со име '%1' веќе постои.",
|
||||
@@ -66,13 +67,16 @@
|
||||
"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "излези од јамката",
|
||||
"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "продолжи со следното повторување на јамката",
|
||||
"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Излези од содржечката јамка.",
|
||||
"CONTROLS_IF_TOOLTIP_1": "Ако вредноста е вистинита, исполни некои наредби.",
|
||||
"CONTROLS_IF_MSG_IF": "ако",
|
||||
"CONTROLS_IF_MSG_ELSEIF": "инаку ако",
|
||||
"CONTROLS_IF_MSG_ELSE": "инаку",
|
||||
"CONTROLS_IF_IF_TOOLTIP": "Додава, отстранува или прередува делови за прераспоредување на овој блок „ако“.",
|
||||
"CONTROLS_IF_ELSEIF_TOOLTIP": "Додај услов кон „ако“ блокот.",
|
||||
"IOS_OK": "ОК",
|
||||
"IOS_CANCEL": "Откажи",
|
||||
"IOS_ERROR": "Грешка",
|
||||
"IOS_PROCEDURES_ADD_INPUT": "+ Додај влез",
|
||||
"IOS_PROCEDURES_ALLOW_STATEMENTS": "Дозволи тврдења",
|
||||
"IOS_VARIABLES_ADD_VARIABLE": "+ Додај променлива",
|
||||
"IOS_VARIABLES_ADD_BUTTON": "Додај",
|
||||
@@ -139,17 +143,34 @@
|
||||
"MATH_ONLIST_TOOLTIP_MEDIAN": "Дава медијана од броевите на списокот.",
|
||||
"MATH_ONLIST_OPERATOR_MODE": "модул на списокот",
|
||||
"MATH_ONLIST_TOOLTIP_MODE": "Дава список на најзастапен(и) елемент(и) на списокот.",
|
||||
"MATH_ONLIST_OPERATOR_RANDOM": "случајна ставка од списокот",
|
||||
"TEXT_JOIN_TITLE_CREATEWITH": "создај текст со",
|
||||
"TEXT_CREATE_JOIN_TITLE_JOIN": "поврзи",
|
||||
"TEXT_CREATE_JOIN_TOOLTIP": "Додај, отстрани или пререди ги деловите за прераспоредување на овој блок „текст“.",
|
||||
"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Додај ставка кон текстот.",
|
||||
"TEXT_LENGTH_TITLE": "должина на %1",
|
||||
"TEXT_ISEMPTY_TITLE": "%1 е празен",
|
||||
"TEXT_INDEXOF_TITLE": "во текст %1 %2 %3",
|
||||
"TEXT_CHARAT_TITLE": "во текст %1 %2",
|
||||
"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "во текстот",
|
||||
"TEXT_COUNT_MESSAGE0": "пресметка на %1 во %2",
|
||||
"TEXT_REPLACE_MESSAGE0": "замени го %1 со %2 во %3",
|
||||
"LISTS_CREATE_EMPTY_TITLE": "создај празен список",
|
||||
"LISTS_CREATE_WITH_INPUT_WITH": "создај список со",
|
||||
"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "список",
|
||||
"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Додај, отстрани или пререди ги деловите за прераспоредување на овој блок „список“.",
|
||||
"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Додај ставка кон списокот.",
|
||||
"LISTS_LENGTH_TITLE": "должина на %1",
|
||||
"LISTS_ISEMPTY_TITLE": "%1 е празен",
|
||||
"LISTS_INLIST": "во списокот",
|
||||
"LISTS_GET_INDEX_REMOVE": "отстрани",
|
||||
"LISTS_GET_INDEX_FROM_END": "# од крајот",
|
||||
"LISTS_GET_INDEX_FIRST": "прв",
|
||||
"LISTS_GET_INDEX_LAST": "последен",
|
||||
"LISTS_GET_INDEX_RANDOM": "случаен",
|
||||
"LISTS_SET_INDEX_SET": "задај",
|
||||
"LISTS_SET_INDEX_INSERT": "вметни на",
|
||||
"LISTS_SET_INDEX_INPUT_TO": "како",
|
||||
"LISTS_SORT_TITLE": "подреди %1 %2 %3",
|
||||
"VARIABLES_GET_CREATE_SET": "Создај „задавање на %1“",
|
||||
"VARIABLES_SET": "задај %1 на %2",
|
||||
@@ -161,6 +182,7 @@
|
||||
"PROCEDURES_DEFRETURN_RETURN": "назад",
|
||||
"PROCEDURES_ALLOW_STATEMENTS": "дозволи тврдења",
|
||||
"PROCEDURES_CALLNORETURN_HELPURL": "https://mk.wikipedia.org/wiki/Потпрограма",
|
||||
"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Додај, отстрани или пренареди ги влезните параметри за оваа функција.",
|
||||
"PROCEDURES_CREATE_DO": "Создај го '%1'",
|
||||
"WORKSPACE_ARIA_LABEL": "Работен простор на Blockly"
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"佛壁灯",
|
||||
"Htq110219891",
|
||||
"Ambeta",
|
||||
"A Chinese Wikipedian"
|
||||
"A Chinese Wikipedian",
|
||||
"沈澄心"
|
||||
]
|
||||
},
|
||||
"VARIABLES_DEFAULT_NAME": "项目",
|
||||
@@ -376,5 +377,6 @@
|
||||
"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
|
||||
"PROCEDURES_IFRETURN_WARNING": "警告:这个块只能在函数内部使用。",
|
||||
"WORKSPACE_COMMENT_DEFAULT_TEXT": "说点什么...",
|
||||
"WORKSPACE_ARIA_LABEL": "Blockly工作区",
|
||||
"COLLAPSED_WARNINGS_WARNING": "已收起的信息块内包含警告。"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"Dnowba",
|
||||
"Dnow",
|
||||
"和平至上",
|
||||
"Jessica1213"
|
||||
"Jessica1213",
|
||||
"沈澄心"
|
||||
]
|
||||
},
|
||||
"VARIABLES_DEFAULT_NAME": "項目",
|
||||
@@ -357,6 +358,6 @@
|
||||
"PROCEDURES_IFRETURN_TOOLTIP": "如果值為 true,則返回第二個值。",
|
||||
"PROCEDURES_IFRETURN_WARNING": "警告:這個區塊只可以在定義函式時使用。",
|
||||
"WORKSPACE_COMMENT_DEFAULT_TEXT": "來說些事情...",
|
||||
"WORKSPACE_ARIA_LABEL": "Blockly 工作區",
|
||||
"WORKSPACE_ARIA_LABEL": "Blockly工作區",
|
||||
"COLLAPSED_WARNINGS_WARNING": "收合含有警告的區塊。"
|
||||
}
|
||||
|
||||
269
package-lock.json
generated
269
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "blockly",
|
||||
"version": "2.20190722.0-develop",
|
||||
"version": "3.20191014.0-develop",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -2105,6 +2105,18 @@
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.11",
|
||||
"through2": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
@@ -2815,17 +2827,17 @@
|
||||
}
|
||||
},
|
||||
"google-closure-compiler": {
|
||||
"version": "20190618.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20190618.0.0.tgz",
|
||||
"integrity": "sha512-f5zJQSWnlawuQlGo9TxcuprBGxIS5ksikj/pjDxdlRTXWt3dOKqEFA3CN8QshNYDl6oEjtO/ehiNx64fqEgkUA==",
|
||||
"version": "20191027.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20191027.0.0.tgz",
|
||||
"integrity": "sha512-W8MVm/fUg6pPVDHbkP2R8HmeLXNVkjhQHwFpikAhRnF8znhjn7e78V+VXYUiOnjBwDGP1/We1sGk4QGMYY2UfA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "2.x",
|
||||
"google-closure-compiler-java": "^20190618.0.0",
|
||||
"google-closure-compiler-js": "^20190618.0.0",
|
||||
"google-closure-compiler-linux": "^20190618.0.0",
|
||||
"google-closure-compiler-osx": "^20190618.0.0",
|
||||
"google-closure-compiler-windows": "^20190618.0.0",
|
||||
"google-closure-compiler-java": "^20191027.0.0",
|
||||
"google-closure-compiler-js": "^20191027.0.0",
|
||||
"google-closure-compiler-linux": "^20191027.0.0",
|
||||
"google-closure-compiler-osx": "^20191027.0.0",
|
||||
"google-closure-compiler-windows": "^20191027.0.0",
|
||||
"minimist": "1.x",
|
||||
"vinyl": "2.x",
|
||||
"vinyl-sourcemaps-apply": "^0.2.0"
|
||||
@@ -2840,43 +2852,144 @@
|
||||
}
|
||||
},
|
||||
"google-closure-compiler-java": {
|
||||
"version": "20190618.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20190618.0.0.tgz",
|
||||
"integrity": "sha512-y6gAyJHMH5k2SM0qj/lyErEjmFGMvcT3glcx5Lsrl99CGwImJY0gDi+Cy9S0pczZvLG+wUW33AEfEW9MtdRZ6A==",
|
||||
"version": "20191027.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20191027.0.0.tgz",
|
||||
"integrity": "sha512-3C0bRnXOp9yYbb6Qm0FqWm53xDmuRRB90tAA57rYzpreZg96Kxz2moVGcoYBh4jFlBkLIywHjV+AWYMaXA3lSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"google-closure-compiler-js": {
|
||||
"version": "20190618.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-js/-/google-closure-compiler-js-20190618.0.0.tgz",
|
||||
"integrity": "sha512-Xc/84uN00GLUzRwWx25Lg11VuSTz/1odWy0d+pM3F/26fXqi16ZhhkVoe6VVFklSSMVDyGTPAH0ZkyfZhinKhA==",
|
||||
"version": "20191027.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-js/-/google-closure-compiler-js-20191027.0.0.tgz",
|
||||
"integrity": "sha512-D3UHBQ0fbPl3VZ2BDK4OWfqDzp/q1FywwEQBbC2qrEKa6Q1wYJRSSY21z+xwscQ1qyPHZjdqIIPXTBrnJvP0WQ==",
|
||||
"dev": true
|
||||
},
|
||||
"google-closure-compiler-linux": {
|
||||
"version": "20190618.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20190618.0.0.tgz",
|
||||
"integrity": "sha512-idWJ/sFmOSYfCmDbCVMcaBX2NCUCxukjt2UzT5PJmpoVLmJuwwoVbpQZVfvgRvEH4bLzvvcvJRfn5nIiODjjaQ==",
|
||||
"version": "20191027.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20191027.0.0.tgz",
|
||||
"integrity": "sha512-zWg+3UdqhsFOkP895azl9ioFOx+JZVFHdETZwhO59PA+zTNTulZqDCX6wqq8YFRoO3HKvYfedUp7Cp+jdaELnA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"google-closure-compiler-osx": {
|
||||
"version": "20190618.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20190618.0.0.tgz",
|
||||
"integrity": "sha512-OzXMW+hKq76NJt9MIRQhV7pHTzHISCXtg+LZUPcqNT+V/tcvOlrSaflokmvyJPzEVk889QArYp8JgZ7mqHuY5g==",
|
||||
"version": "20191027.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20191027.0.0.tgz",
|
||||
"integrity": "sha512-Ko/+43oeMD8u6MhKMGPhx61B5e2lR5+C9pzlhnibQwuXuDVcp2ruFbblhWBXiT2FrStTX65SZzFvza0bRVYikA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"google-closure-compiler-windows": {
|
||||
"version": "20190618.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20190618.0.0.tgz",
|
||||
"integrity": "sha512-2qzY/fQneEg+zFvRGoNeJkAY6VU5OcmBT37l+xTBGQvy/AauCLWltSGcOYNEi7Qd3OEBVIcAJ+CzNOV9s3jfwA==",
|
||||
"version": "20191027.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20191027.0.0.tgz",
|
||||
"integrity": "sha512-kAzGFGaeAL9qsieotjb5qq5SsYD2Vwtl7aCeIVUnzWyNfhz7WZCmAMSGwGdtaShfM+4uzOwG1mahtPWasTaBxg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"google-closure-library": {
|
||||
"version": "20190618.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-library/-/google-closure-library-20190618.0.0.tgz",
|
||||
"integrity": "sha512-V0RbatvAmCfdOTeTXXbXklGU1hgPus8YkpjyaMBmoCcajgtk9vL+SsRhD1Ntk6QNkbzD9WGKLdyovMw7NJ8VnA==",
|
||||
"dev": true
|
||||
"google-closure-deps": {
|
||||
"version": "20190121.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-deps/-/google-closure-deps-20190121.0.0.tgz",
|
||||
"integrity": "sha512-UdFzI/6sQt2q66GFO9M/DRw/F5dk8TY7JRav54jsK+VORRoTfjH99xvHqEva4BOZ2+JdzG9IoTcH0nyIOAbxfQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.9",
|
||||
"google-closure-compiler": "^20181008.0.0",
|
||||
"yargs": "^12.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"google-closure-compiler": {
|
||||
"version": "20181008.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20181008.0.0.tgz",
|
||||
"integrity": "sha512-XmJIasXHyy4kirthlsuDev2LZcXjYXWfOHwHdCLUQnfJH8T2sxWDNjFLQycaCIXwQLOyw2Kem38VgxrYfG0hzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^1.0.0",
|
||||
"google-closure-compiler-linux": "^20181008.0.0",
|
||||
"google-closure-compiler-osx": "^20181008.0.0",
|
||||
"minimist": "^1.2.0",
|
||||
"vinyl": "^2.0.1",
|
||||
"vinyl-sourcemaps-apply": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"google-closure-compiler-linux": {
|
||||
"version": "20181008.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20181008.0.0.tgz",
|
||||
"integrity": "sha512-k8njGfH2uzWJiRPPvUxM7MJB28gPrf4kI2bbuiF0gJk/1arXcWCPGjLD6pzCU0UylMy52MUXLgsIpRorqf2brw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"google-closure-compiler-osx": {
|
||||
"version": "20181008.0.0",
|
||||
"resolved": "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20181008.0.0.tgz",
|
||||
"integrity": "sha512-xzf/yH/4MXdb6GbP84iHnpcVCOPBbH0gMVOs0JhR/KbrQh+DlJU+Y8Z/DQzTkw9HgD650R2/WZmBknURyg9OTw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "12.0.5",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
|
||||
"integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^4.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^1.0.1",
|
||||
"os-locale": "^3.0.0",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^1.0.1",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^2.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^3.2.1 || ^4.0.0",
|
||||
"yargs-parser": "^11.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.2",
|
||||
@@ -3063,6 +3176,18 @@
|
||||
"concat-with-sourcemaps": "^1.0.0",
|
||||
"through2": "^2.0.0",
|
||||
"vinyl": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gulp-insert": {
|
||||
@@ -3158,6 +3283,18 @@
|
||||
"concat-stream": "^1.6.2",
|
||||
"lodash.template": "^4.4.0",
|
||||
"through2": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gulplog": {
|
||||
@@ -3192,6 +3329,23 @@
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
@@ -5210,6 +5364,18 @@
|
||||
"remove-bom-buffer": "^3.0.0",
|
||||
"safe-buffer": "^5.1.0",
|
||||
"through2": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove-trailing-separator": {
|
||||
@@ -6102,13 +6268,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
|
||||
"integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
"readable-stream": "2 || 3"
|
||||
}
|
||||
},
|
||||
"through2-filter": {
|
||||
@@ -6119,6 +6284,18 @@
|
||||
"requires": {
|
||||
"through2": "~2.0.0",
|
||||
"xtend": "~4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"time-stamp": {
|
||||
@@ -6195,6 +6372,18 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"through2": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
@@ -6511,6 +6700,18 @@
|
||||
"value-or-function": "^3.0.0",
|
||||
"vinyl": "^2.0.0",
|
||||
"vinyl-sourcemap": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vinyl-sourcemap": {
|
||||
|
||||
@@ -55,8 +55,8 @@
|
||||
"eslint": "^5.13.0",
|
||||
"eslint-plugin-es5": "^1.4.1",
|
||||
"fs": "0.0.1-security",
|
||||
"google-closure-compiler": "^20190618.0.0",
|
||||
"google-closure-library": "^20190618.0.0",
|
||||
"google-closure-compiler": "^20191027.0.0",
|
||||
"google-closure-deps": "20190121.0.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-insert": "^0.5.0",
|
||||
@@ -71,6 +71,7 @@
|
||||
"pngjs": "^3.4.0",
|
||||
"selenium-standalone": "^6.16.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"through2": "^3.0.1",
|
||||
"typescript-closure-tools": "^0.0.7",
|
||||
"webdriverio": "^5.11.5",
|
||||
"yargs": "^14.0.0"
|
||||
|
||||
@@ -78,6 +78,7 @@ COMPILATION_COMMAND="java -jar $COMPILER --js='$BLOCKLY_ROOT/tests/compile/main.
|
||||
--js='$BLOCKLY_ROOT/blocks/**.js' \
|
||||
--js='$BLOCKLY_ROOT/generators/**.js' \
|
||||
--generate_exports \
|
||||
--externs $BLOCKLY_ROOT/externs/goog-externs.js \
|
||||
--externs $BLOCKLY_ROOT/externs/svg-externs.js \
|
||||
--compilation_level ADVANCED_OPTIMIZATIONS \
|
||||
--language_in ECMASCRIPT5_STRICT \
|
||||
|
||||
@@ -228,6 +228,11 @@ suite('Text Input Fields', function() {
|
||||
scale: 1
|
||||
}
|
||||
};
|
||||
field.constants_ = {
|
||||
FIELD_TEXT_FONTSIZE: 11,
|
||||
FIELD_TEXT_FONTWEIGHT: 'normal',
|
||||
FIELD_TEXT_FONTFAMILY: 'sans-serif'
|
||||
};
|
||||
Blockly.WidgetDiv.DIV = document.createElement('div');
|
||||
this.stub = sinon.stub(field, 'resizeEditor_');
|
||||
};
|
||||
|
||||
@@ -54,8 +54,9 @@ function svgToPng_(data, width, height, callback) {
|
||||
* Create an SVG of the blocks on the workspace.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace.
|
||||
* @param {!Function} callback Callback.
|
||||
* @param {string=} customCss Custom CSS to append to the SVG.
|
||||
*/
|
||||
function workspaceToSvg_(workspace, callback) {
|
||||
function workspaceToSvg_(workspace, callback, customCss) {
|
||||
|
||||
// Go through all text areas and set their value.
|
||||
var textAreas = document.getElementsByTagName("textarea");
|
||||
@@ -87,7 +88,7 @@ function workspaceToSvg_(workspace, callback) {
|
||||
var css = [].slice.call(document.head.querySelectorAll('style'))
|
||||
.filter(function(el) { return /\.blocklySvg/.test(el.innerText); })[0];
|
||||
var style = document.createElement('style');
|
||||
style.innerHTML = css.innerText;
|
||||
style.innerHTML = css.innerText + '\n' + customCss;
|
||||
svg.insertBefore(style, svg.firstChild);
|
||||
|
||||
var svgAsXML = (new XMLSerializer).serializeToString(svg);
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.output {
|
||||
height: 500px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -145,6 +149,18 @@
|
||||
<iframe id="pxtblockly" src="./pxtblockly.html"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div id="zelosout">
|
||||
<h2>Zelos Rendering</h2>
|
||||
<img id="zelosoutput" class="output" />
|
||||
</div>
|
||||
<div id="pxtblocklyout">
|
||||
<h2>PXT-Blockly Rendering</h2>
|
||||
<img id="pxtblocklyoutput" class="output" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
@@ -156,6 +172,25 @@
|
||||
selector.value = hash.substring(1);
|
||||
}
|
||||
|
||||
window.addEventListener('message', function (msg) {
|
||||
var data = msg.data;
|
||||
if (data.type === 'svg') {
|
||||
var output = document.getElementById(data.from + 'output');
|
||||
output.src = data.text;
|
||||
}
|
||||
});
|
||||
|
||||
var current = 'zelos';
|
||||
var pause = false;
|
||||
document.getElementById('pxtblocklyout').style.display = 'none';
|
||||
setInterval(function () {
|
||||
if (!pause) {
|
||||
document.getElementById(current + 'out').style.display = 'none';
|
||||
current = current == 'zelos' ? 'pxtblockly' : 'zelos';
|
||||
document.getElementById(current + 'out').style.display = 'block';
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
pxtblockly.addEventListener('load', function () {
|
||||
updateWorkspaces(selector.value);
|
||||
});
|
||||
@@ -179,8 +214,14 @@
|
||||
if (rawFile.status === 200 || rawFile.status == 0) {
|
||||
var xml = rawFile.responseText;
|
||||
if (xml) {
|
||||
pxtblockly.contentWindow.postMessage(xml, '*');
|
||||
zelos.contentWindow.postMessage(xml, '*');
|
||||
pxtblockly.contentWindow.postMessage({
|
||||
type: 'post',
|
||||
xml: xml
|
||||
}, '*');
|
||||
zelos.contentWindow.postMessage({
|
||||
type: 'post',
|
||||
xml: xml
|
||||
}, '*');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,10 +236,12 @@
|
||||
} else if (e.keyCode === 39) {
|
||||
selector.selectedIndex = selector.selectedIndex + 1;
|
||||
updateWorkspaces(selector.value);
|
||||
} else if (e.keyCode === 32) {
|
||||
pause = !pause;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -4,6 +4,7 @@
|
||||
<script type="text/javascript" src="https://unpkg.com/pxt-blockly@2.1.12/blockly_compressed.js"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/pxt-blockly@2.1.12/blocks_compressed.js"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/pxt-blockly@2.1.12/msg/messages.js"></script>
|
||||
<script type="text/javascript" src="../../playgrounds/screenshot.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -12,7 +13,11 @@
|
||||
var blocklyDiv = document.getElementById('blocklyDiv');
|
||||
var workspace;
|
||||
window.addEventListener('message', function (msg) {
|
||||
var xml = msg.data;
|
||||
var data = msg.data;
|
||||
if (data.type !== 'post') {
|
||||
return;
|
||||
}
|
||||
var xml = data.xml;
|
||||
try {
|
||||
if (workspace) {
|
||||
workspace.dispose();
|
||||
@@ -26,13 +31,25 @@
|
||||
drag: true,
|
||||
wheel: false,
|
||||
},
|
||||
zoom: {
|
||||
wheel: true,
|
||||
startScale: 2,
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
|
||||
var topBlock = workspace.getTopBlocks()[0];
|
||||
workspaceToSvg_(workspace, function (datauri) {
|
||||
window.parent.postMessage({
|
||||
type: 'svg',
|
||||
from: 'pxtblockly',
|
||||
text: datauri
|
||||
}, '*');
|
||||
});
|
||||
} catch { }
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -4,13 +4,26 @@
|
||||
<script type="text/javascript" src="../../../blockly_uncompressed.js"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/pxt-blockly@2.1.12/blocks_compressed.js"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/pxt-blockly@2.1.12/msg/messages.js"></script>
|
||||
<script type="text/javascript" src="../../playgrounds/screenshot.js"></script>
|
||||
|
||||
<style>
|
||||
.blocklyText {
|
||||
<style id="blocklycss">
|
||||
.blocklyText,
|
||||
.blocklyHtmlInput {
|
||||
font-family: "Helvetica Neue", "Segoe UI", Helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.blocklyNonEditableText>text,
|
||||
.blocklyEditableText>text,
|
||||
.blocklyNonEditableText>g>text,
|
||||
.blocklyEditableText>g>text {
|
||||
fill: #575E75;
|
||||
}
|
||||
|
||||
.blocklyHtmlInput {
|
||||
color: #575E75;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -26,7 +39,11 @@
|
||||
var blocklyDiv = document.getElementById('blocklyDiv');
|
||||
var workspace;
|
||||
window.addEventListener('message', function (msg) {
|
||||
var xml = msg.data;
|
||||
var data = msg.data;
|
||||
if (data.type !== 'post') {
|
||||
return;
|
||||
}
|
||||
var xml = data.xml;
|
||||
try {
|
||||
if (workspace) {
|
||||
workspace.dispose();
|
||||
@@ -41,11 +58,25 @@
|
||||
drag: true,
|
||||
wheel: false,
|
||||
},
|
||||
zoom: {
|
||||
wheel: true,
|
||||
startScale: 2,
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
|
||||
} catch { }
|
||||
var topBlock = workspace.getTopBlocks()[0];
|
||||
workspaceToSvg_(workspace, function (datauri) {
|
||||
window.parent.postMessage({
|
||||
type: 'svg',
|
||||
from: 'zelos',
|
||||
text: datauri
|
||||
}, '*');
|
||||
}, document.getElementById('blocklycss').innerText);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user