mirror of
https://github.com/google/blockly.git
synced 2026-01-23 00:30:10 +01:00
More field dispose (#3201)
* Dispose of element references in fields. * Fewer warnings
This commit is contained in:
@@ -113,6 +113,13 @@ Blockly.clipboardTypeCounts_ = null;
|
||||
*/
|
||||
Blockly.cache3dSupported_ = null;
|
||||
|
||||
/**
|
||||
* Blockly opaque event data used to unbind events when using
|
||||
* `Blockly.bindEvent_` and `Blockly.bindEventWithChecks_`.
|
||||
* @typedef {!Array.<!Array>}
|
||||
*/
|
||||
Blockly.EventData;
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the specified SVG image.
|
||||
* @param {!Element} svg SVG image.
|
||||
@@ -455,7 +462,7 @@ Blockly.defineBlocksWithJsonArray = function(jsonArray) {
|
||||
* should prevent the default handler. False by default. If
|
||||
* opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be
|
||||
* provided.
|
||||
* @return {!Array.<!Array>} Opaque data that can be passed to unbindEvent_.
|
||||
* @return {!Blockly.EventData} Opaque data that can be passed to unbindEvent_.
|
||||
*/
|
||||
Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
|
||||
opt_noCaptureIdentifier, opt_noPreventDefault) {
|
||||
@@ -521,7 +528,7 @@ Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @return {!Array.<!Array>} Opaque data that can be passed to unbindEvent_.
|
||||
* @return {!Blockly.EventData} Opaque data that can be passed to unbindEvent_.
|
||||
*/
|
||||
Blockly.bindEvent_ = function(node, name, thisObject, func) {
|
||||
var wrapFunc = function(e) {
|
||||
|
||||
@@ -339,7 +339,7 @@ Blockly.Component.prototype.exitDocument = function() {
|
||||
/**
|
||||
* Disposes of the object. If the object hasn't already been disposed of, calls
|
||||
* {@link #disposeInternal}.
|
||||
* @protected
|
||||
* @package
|
||||
*/
|
||||
Blockly.Component.prototype.dispose = function() {
|
||||
if (!this.disposed_) {
|
||||
|
||||
@@ -94,6 +94,41 @@ Blockly.Field = function(value, opt_validator, opt_config) {
|
||||
*/
|
||||
this.markerSvg_ = null;
|
||||
|
||||
/**
|
||||
* The rendered field's SVG group element.
|
||||
* @type {SVGGElement}
|
||||
* @protected
|
||||
*/
|
||||
this.fieldGroup_ = null;
|
||||
|
||||
/**
|
||||
* The rendered field's SVG border element.
|
||||
* @type {SVGRectElement}
|
||||
* @protected
|
||||
*/
|
||||
this.borderRect_ = null;
|
||||
|
||||
/**
|
||||
* The rendered field's SVG text element.
|
||||
* @type {SVGTextElement}
|
||||
* @protected
|
||||
*/
|
||||
this.textElement_ = null;
|
||||
|
||||
/**
|
||||
* The rendered field's text content element.
|
||||
* @type {Text}
|
||||
* @protected
|
||||
*/
|
||||
this.textContent_ = null;
|
||||
|
||||
/**
|
||||
* Mouse down event listener data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.mouseDownWrapper_ = null;
|
||||
|
||||
opt_config && this.configure_(opt_config);
|
||||
this.setValue(value);
|
||||
opt_validator && this.setValidator(opt_validator);
|
||||
@@ -186,11 +221,21 @@ Blockly.Field.prototype.clickTarget_ = null;
|
||||
* A developer hook to override the returned text of this field.
|
||||
* Override if the text representation of the value of this field
|
||||
* is not just a string cast of its value.
|
||||
* Return null to resort to a string cast.
|
||||
* @return {?string} Current text. Return null to resort to a string cast.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.getText_;
|
||||
|
||||
/**
|
||||
* An optional method that can be defined to show an editor when the field is
|
||||
* clicked. Blockly will automatically set the field as clickable if this
|
||||
* method is defined.
|
||||
* @return {void}
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.showEditor_;
|
||||
|
||||
/**
|
||||
* Non-breaking space.
|
||||
* @const
|
||||
@@ -260,11 +305,13 @@ Blockly.Field.prototype.init = function() {
|
||||
// Field has already been initialized once.
|
||||
return;
|
||||
}
|
||||
this.fieldGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null);
|
||||
this.fieldGroup_ = /** @type {!SVGGElement} **/
|
||||
(Blockly.utils.dom.createSvgElement('g', {}, null));
|
||||
if (!this.isVisible()) {
|
||||
this.fieldGroup_.style.display = 'none';
|
||||
}
|
||||
this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
|
||||
var sourceBlockSvg = /** @type {!Blockly.BlockSvg} **/ (this.sourceBlock_);
|
||||
sourceBlockSvg.getSvgRoot().appendChild(this.fieldGroup_);
|
||||
this.initView();
|
||||
this.updateEditable();
|
||||
this.setTooltip(this.tooltip_);
|
||||
@@ -300,15 +347,16 @@ Blockly.Field.prototype.createBorderRect_ = function() {
|
||||
Math.max(this.size_.height, Blockly.Field.BORDER_RECT_DEFAULT_HEIGHT);
|
||||
this.size_.width =
|
||||
Math.max(this.size_.width, Blockly.Field.X_PADDING);
|
||||
this.borderRect_ = Blockly.utils.dom.createSvgElement('rect',
|
||||
{
|
||||
'rx': 4,
|
||||
'ry': 4,
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
'height': this.size_.height,
|
||||
'width': this.size_.width
|
||||
}, this.fieldGroup_);
|
||||
this.borderRect_ = /** @type {!SVGRectElement} **/
|
||||
(Blockly.utils.dom.createSvgElement('rect',
|
||||
{
|
||||
'rx': 4,
|
||||
'ry': 4,
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
'height': this.size_.height,
|
||||
'width': this.size_.width
|
||||
}, this.fieldGroup_));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -319,13 +367,14 @@ Blockly.Field.prototype.createBorderRect_ = function() {
|
||||
*/
|
||||
Blockly.Field.prototype.createTextElement_ = function() {
|
||||
var xOffset = this.borderRect_ ? Blockly.Field.DEFAULT_TEXT_OFFSET : 0;
|
||||
this.textElement_ = Blockly.utils.dom.createSvgElement('text',
|
||||
{
|
||||
'class': 'blocklyText',
|
||||
// The y position is the baseline of the text.
|
||||
'y': Blockly.Field.TEXT_DEFAULT_HEIGHT,
|
||||
'x': xOffset
|
||||
}, this.fieldGroup_);
|
||||
this.textElement_ = /** @type {!SVGTextElement} **/
|
||||
(Blockly.utils.dom.createSvgElement('text',
|
||||
{
|
||||
'class': 'blocklyText',
|
||||
// The y position is the baseline of the text.
|
||||
'y': Blockly.Field.TEXT_DEFAULT_HEIGHT,
|
||||
'x': xOffset
|
||||
}, this.fieldGroup_));
|
||||
this.textContent_ = document.createTextNode('');
|
||||
this.textElement_.appendChild(this.textContent_);
|
||||
};
|
||||
@@ -534,10 +583,10 @@ Blockly.Field.prototype.callValidator = function(text) {
|
||||
/**
|
||||
* Gets the group element for this editable field.
|
||||
* Used for measuring the size and for positioning.
|
||||
* @return {!SVGElement} The group element.
|
||||
* @return {!SVGGElement} The group element.
|
||||
*/
|
||||
Blockly.Field.prototype.getSvgRoot = function() {
|
||||
return /** @type {!SVGElement} */ (this.fieldGroup_);
|
||||
return /** @type {!SVGGElement} */ (this.fieldGroup_);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -582,7 +631,8 @@ Blockly.Field.prototype.updateWidth = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.updateSize_ = function() {
|
||||
var textWidth = Blockly.utils.dom.getTextWidth(this.textElement_);
|
||||
var textWidth = Blockly.utils.dom.getTextWidth(
|
||||
/** @type {!SVGTextElement} */ (this.textElement_));
|
||||
var totalWidth = textWidth;
|
||||
if (this.borderRect_) {
|
||||
totalWidth += Blockly.Field.X_PADDING;
|
||||
@@ -881,7 +931,8 @@ Blockly.Field.prototype.getClickTarget_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Field.prototype.getAbsoluteXY_ = function() {
|
||||
return Blockly.utils.style.getPageOffset(this.borderRect_);
|
||||
return Blockly.utils.style.getPageOffset(
|
||||
/** @type {!SVGRectElement} */ (this.borderRect_));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,6 +83,39 @@ Blockly.FieldAngle = function(opt_value, opt_validator, opt_config) {
|
||||
|
||||
Blockly.FieldAngle.superClass_.constructor.call(
|
||||
this, opt_value || 0, opt_validator, opt_config);
|
||||
|
||||
/**
|
||||
* The angle picker's gauge path depending on the value.
|
||||
* @type {SVGElement}
|
||||
*/
|
||||
this.gauge_ = null;
|
||||
|
||||
/**
|
||||
* The angle picker's line drawn representing the value's angle.
|
||||
* @type {SVGElement}
|
||||
*/
|
||||
this.line_ = null;
|
||||
|
||||
/**
|
||||
* Wrapper click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.clickWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Surface click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.clickSurfaceWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Surface mouse move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.moveSurfaceWrapper_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FieldAngle, Blockly.FieldTextInput);
|
||||
|
||||
@@ -309,9 +342,15 @@ Blockly.FieldAngle.prototype.dropdownCreate_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.dropdownDispose_ = function() {
|
||||
Blockly.unbindEvent_(this.clickWrapper_);
|
||||
Blockly.unbindEvent_(this.clickSurfaceWrapper_);
|
||||
Blockly.unbindEvent_(this.moveSurfaceWrapper_);
|
||||
if (this.clickWrapper_) {
|
||||
Blockly.unbindEvent_(this.clickWrapper_);
|
||||
}
|
||||
if (this.clickSurfaceWrapper_) {
|
||||
Blockly.unbindEvent_(this.clickSurfaceWrapper_);
|
||||
}
|
||||
if (this.moveSurfaceWrapper_) {
|
||||
Blockly.unbindEvent_(this.moveSurfaceWrapper_);
|
||||
}
|
||||
this.gauge_ = null;
|
||||
this.line_ = null;
|
||||
};
|
||||
|
||||
@@ -65,6 +65,55 @@ Blockly.FieldColour = function(opt_value, opt_validator, opt_config) {
|
||||
*/
|
||||
this.size_ = new Blockly.utils.Size(Blockly.FieldColour.DEFAULT_WIDTH,
|
||||
Blockly.FieldColour.DEFAULT_HEIGHT);
|
||||
|
||||
/**
|
||||
* The field's colour picker element.
|
||||
* @type {Element}
|
||||
* @private
|
||||
*/
|
||||
this.picker_ = null;
|
||||
|
||||
/**
|
||||
* Index of the currently highlighted element.
|
||||
* @type {?number}
|
||||
* @private
|
||||
*/
|
||||
this.highlightedIndex_ = null;
|
||||
|
||||
/**
|
||||
* Mouse click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onClickWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseMoveWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse enter event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseEnterWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse leave event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseLeaveWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Key down event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onKeyDownWrapper_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FieldColour, Blockly.Field);
|
||||
|
||||
@@ -160,7 +209,7 @@ Blockly.FieldColour.prototype.configure_ = function(config) {
|
||||
*/
|
||||
Blockly.FieldColour.prototype.initView = function() {
|
||||
this.createBorderRect_();
|
||||
this.borderRect_.style['fillOpacity'] = 1;
|
||||
this.borderRect_.style['fillOpacity'] = '1';
|
||||
this.borderRect_.style.fill = this.value_;
|
||||
};
|
||||
|
||||
@@ -415,7 +464,7 @@ Blockly.FieldColour.prototype.moveHighlightBy_ = function(dx, dy) {
|
||||
}
|
||||
|
||||
// Move the highlight to the new coordinates.
|
||||
var cell = this.picker_.childNodes[y].childNodes[x];
|
||||
var cell = /** @type {!Element} */ (this.picker_.childNodes[y].childNodes[x]);
|
||||
var index = (y * columns) + x;
|
||||
this.setHighlightedCell_(cell, index);
|
||||
};
|
||||
@@ -427,9 +476,9 @@ Blockly.FieldColour.prototype.moveHighlightBy_ = function(dx, dy) {
|
||||
*/
|
||||
Blockly.FieldColour.prototype.onMouseMove_ = function(e) {
|
||||
var cell = /** @type {!Element} */ (e.target);
|
||||
var index = cell && cell.getAttribute('data-index');
|
||||
var index = cell && Number(cell.getAttribute('data-index'));
|
||||
if (index !== null && index !== this.highlightedIndex_) {
|
||||
this.setHighlightedCell_(cell, Number(index));
|
||||
this.setHighlightedCell_(cell, index);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -456,7 +505,7 @@ Blockly.FieldColour.prototype.onMouseLeave_ = function() {
|
||||
|
||||
/**
|
||||
* Returns the currently highlighted item (if any).
|
||||
* @return {Element} Highlighted item (null if none).
|
||||
* @return {HTMLElement} Highlighted item (null if none).
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldColour.prototype.getHighlighted_ = function() {
|
||||
@@ -467,7 +516,7 @@ Blockly.FieldColour.prototype.getHighlighted_ = function() {
|
||||
if (!row) {
|
||||
return null;
|
||||
}
|
||||
var col = row.childNodes[x];
|
||||
var col = /** @type {HTMLElement} */ (row.childNodes[x]);
|
||||
return col;
|
||||
};
|
||||
|
||||
@@ -489,7 +538,7 @@ Blockly.FieldColour.prototype.setHighlightedCell_ = function(cell, index) {
|
||||
this.highlightedIndex_ = index;
|
||||
|
||||
// Update accessibility roles.
|
||||
Blockly.utils.aria.setState(this.picker_,
|
||||
Blockly.utils.aria.setState(/** @type {!Element} */ (this.picker_),
|
||||
Blockly.utils.aria.State.ACTIVEDESCENDANT, cell.getAttribute('id'));
|
||||
};
|
||||
|
||||
@@ -560,12 +609,23 @@ Blockly.FieldColour.prototype.dropdownCreate_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldColour.prototype.dropdownDispose_ = function() {
|
||||
Blockly.unbindEvent_(this.onClickWrapper_);
|
||||
Blockly.unbindEvent_(this.onMouseMoveWrapper_);
|
||||
Blockly.unbindEvent_(this.onMouseEnterWrapper_);
|
||||
Blockly.unbindEvent_(this.onMouseLeaveWrapper_);
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
if (this.onClickWrapper_) {
|
||||
Blockly.unbindEvent_(this.onClickWrapper_);
|
||||
}
|
||||
if (this.onMouseMoveWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseMoveWrapper_);
|
||||
}
|
||||
if (this.onMouseEnterWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseEnterWrapper_);
|
||||
}
|
||||
if (this.onMouseLeaveWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseLeaveWrapper_);
|
||||
}
|
||||
if (this.onKeyDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
}
|
||||
this.picker_ = null;
|
||||
this.highlightedIndex_ = null;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,19 +91,33 @@ Blockly.FieldDropdown = function(menuGenerator, opt_validator, opt_config) {
|
||||
Blockly.FieldDropdown.superClass_.constructor.call(
|
||||
this, firstTuple[1], opt_validator, opt_config);
|
||||
|
||||
/**
|
||||
* SVG image element if currently selected option is an image, or null.
|
||||
* @type {SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.imageElement_ = null;
|
||||
|
||||
/**
|
||||
* A reference to the currently selected menu item.
|
||||
* @type {Blockly.MenuItem}
|
||||
* @private
|
||||
*/
|
||||
this.selectedMenuItem_ = null;
|
||||
|
||||
/**
|
||||
* The dropdown menu.
|
||||
* @type {Blockly.Menu}
|
||||
* @private
|
||||
*/
|
||||
this.menu_ = null;
|
||||
|
||||
/**
|
||||
* SVG image element if currently selected option is an image, or null.
|
||||
* @type {SVGImageElement}
|
||||
* @private
|
||||
*/
|
||||
this.imageElement_ = null;
|
||||
|
||||
/**
|
||||
* SVG arrow element.
|
||||
* @type {SVGTSpanElement}
|
||||
* @private
|
||||
*/
|
||||
this.arrow_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FieldDropdown, Blockly.Field);
|
||||
|
||||
@@ -182,12 +196,15 @@ Blockly.FieldDropdown.prototype.CURSOR = 'default';
|
||||
Blockly.FieldDropdown.prototype.initView = function() {
|
||||
Blockly.FieldDropdown.superClass_.initView.call(this);
|
||||
|
||||
this.imageElement_ = Blockly.utils.dom.createSvgElement( 'image',
|
||||
{
|
||||
'y': Blockly.FieldDropdown.IMAGE_Y_OFFSET
|
||||
}, this.fieldGroup_);
|
||||
this.imageElement_ = /** @type {!SVGImageElement} */
|
||||
(Blockly.utils.dom.createSvgElement('image',
|
||||
{
|
||||
'y': Blockly.FieldDropdown.IMAGE_Y_OFFSET
|
||||
}, this.fieldGroup_));
|
||||
|
||||
this.arrow_ = Blockly.utils.dom.createSvgElement('tspan', {}, this.textElement_);
|
||||
this.arrow_ = /** @type {!SVGTSpanElement} */
|
||||
(Blockly.utils.dom.createSvgElement('tspan',
|
||||
{}, this.textElement_));
|
||||
this.arrow_.appendChild(document.createTextNode(
|
||||
this.sourceBlock_.RTL ?
|
||||
Blockly.FieldDropdown.ARROW_CHAR + ' ' :
|
||||
@@ -228,7 +245,7 @@ Blockly.FieldDropdown.prototype.showEditor_ = function() {
|
||||
|
||||
/**
|
||||
* Create the dropdown editor.
|
||||
* @return {Blockly.Menu} The newly created dropdown menu.
|
||||
* @return {!Blockly.Menu} The newly created dropdown menu.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.dropdownCreate_ = function() {
|
||||
@@ -273,8 +290,11 @@ Blockly.FieldDropdown.prototype.dropdownCreate_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.dropdownDispose_ = function() {
|
||||
this.menu_.dispose();
|
||||
if (this.menu_) {
|
||||
this.menu_.dispose();
|
||||
}
|
||||
this.menu_ = null;
|
||||
this.selectedMenuItem_ = null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -284,15 +304,16 @@ Blockly.FieldDropdown.prototype.dropdownDispose_ = function() {
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.handleMenuActionEvent_ = function(menuItem) {
|
||||
Blockly.DropDownDiv.hideIfOwner(this, true);
|
||||
this.onItemSelected(this.menu_, menuItem);
|
||||
this.onItemSelected_(/** @type {!Blockly.Menu} */ (this.menu_), menuItem);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the selection of an item in the dropdown menu.
|
||||
* @param {!Blockly.Menu} menu The Menu component clicked.
|
||||
* @param {!Blockly.MenuItem} menuItem The MenuItem selected within menu.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.onItemSelected = function(menu, menuItem) {
|
||||
Blockly.FieldDropdown.prototype.onItemSelected_ = function(menu, menuItem) {
|
||||
this.setValue(menuItem.getValue());
|
||||
};
|
||||
|
||||
@@ -492,7 +513,8 @@ Blockly.FieldDropdown.prototype.renderSelectedImage_ = function(imageJson) {
|
||||
this.imageElement_.setAttribute('height', imageJson.height);
|
||||
this.imageElement_.setAttribute('width', imageJson.width);
|
||||
|
||||
var arrowWidth = Blockly.utils.dom.getTextWidth(this.arrow_);
|
||||
var arrowWidth = Blockly.utils.dom.getTextWidth(
|
||||
/** @type {!SVGTSpanElement} */ (this.arrow_));
|
||||
|
||||
var imageHeight = Number(imageJson.height);
|
||||
var imageWidth = Number(imageJson.width);
|
||||
@@ -531,9 +553,9 @@ Blockly.FieldDropdown.prototype.renderSelectedText_ = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Use the `getText_` developer hook to override the field's text representation.
|
||||
* Get the selected option text. If the selected option is an image
|
||||
* we return the image alt text.
|
||||
* Use the `getText_` developer hook to override the field's text
|
||||
* representation. Get the selected option text. If the selected option is an
|
||||
* image we return the image alt text.
|
||||
* @return {?string} Selected option text.
|
||||
* @protected
|
||||
* @override
|
||||
@@ -611,4 +633,5 @@ Blockly.FieldDropdown.prototype.onBlocklyAction = function(action) {
|
||||
return Blockly.FieldDropdown.superClass_.onBlocklyAction.call(this, action);
|
||||
};
|
||||
|
||||
|
||||
Blockly.fieldRegistry.register('field_dropdown', Blockly.FieldDropdown);
|
||||
|
||||
@@ -115,6 +115,13 @@ Blockly.FieldImage = function(src, width, height,
|
||||
if (typeof opt_onClick == 'function') {
|
||||
this.clickHandler_ = opt_onClick;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rendered field's image element.
|
||||
* @type {SVGImageElement}
|
||||
* @private
|
||||
*/
|
||||
this.imageElement_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FieldImage, Blockly.Field);
|
||||
|
||||
@@ -173,14 +180,15 @@ Blockly.FieldImage.prototype.configure_ = function(config) {
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldImage.prototype.initView = function() {
|
||||
this.imageElement_ = Blockly.utils.dom.createSvgElement(
|
||||
'image',
|
||||
{
|
||||
'height': this.imageHeight_ + 'px',
|
||||
'width': this.size_.width + 'px',
|
||||
'alt': this.altText_
|
||||
},
|
||||
this.fieldGroup_);
|
||||
this.imageElement_ = /** @type {!SVGImageElement} */
|
||||
(Blockly.utils.dom.createSvgElement(
|
||||
'image',
|
||||
{
|
||||
'height': this.imageHeight_ + 'px',
|
||||
'width': this.size_.width + 'px',
|
||||
'alt': this.altText_
|
||||
},
|
||||
this.fieldGroup_));
|
||||
this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,
|
||||
'xlink:href', /** @type {string} */ (this.value_));
|
||||
};
|
||||
@@ -208,7 +216,7 @@ Blockly.FieldImage.prototype.doValueUpdate_ = function(newValue) {
|
||||
this.value_ = newValue;
|
||||
if (this.imageElement_) {
|
||||
this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,
|
||||
'xlink:href', this.value_ || '');
|
||||
'xlink:href', String(this.value_));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -58,6 +58,13 @@ Blockly.FieldMultilineInput = function(opt_value, opt_validator, opt_config) {
|
||||
}
|
||||
Blockly.FieldMultilineInput.superClass_.constructor.call(this,
|
||||
opt_value, opt_validator, opt_config);
|
||||
|
||||
/**
|
||||
* The SVG group element that will contain a text element for each text row
|
||||
* when initialized.
|
||||
* @type {SVGGElement}
|
||||
*/
|
||||
this.textGroup_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FieldMultilineInput,
|
||||
Blockly.FieldTextInput);
|
||||
@@ -89,10 +96,11 @@ Blockly.FieldMultilineInput.fromJson = function(options) {
|
||||
*/
|
||||
Blockly.FieldMultilineInput.prototype.initView = function() {
|
||||
this.createBorderRect_();
|
||||
this.textGroup_ = Blockly.utils.dom.createSvgElement('g',
|
||||
{
|
||||
'class': 'blocklyEditableText',
|
||||
}, this.fieldGroup_);
|
||||
this.textGroup_ = /** @type {!SVGGElement} **/
|
||||
(Blockly.utils.dom.createSvgElement('g',
|
||||
{
|
||||
'class': 'blocklyEditableText',
|
||||
}, this.fieldGroup_));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -167,12 +175,13 @@ Blockly.FieldMultilineInput.prototype.render_ = function() {
|
||||
} else {
|
||||
this.resizeEditor_();
|
||||
}
|
||||
var htmlInput = /** @type {!HTMLElement} */(this.htmlInput_);
|
||||
if (!this.isTextValid_) {
|
||||
Blockly.utils.dom.addClass(this.htmlInput_, 'blocklyInvalidInput');
|
||||
Blockly.utils.aria.setState(this.htmlInput_, 'invalid', true);
|
||||
Blockly.utils.dom.addClass(htmlInput, 'blocklyInvalidInput');
|
||||
Blockly.utils.aria.setState(htmlInput, 'invalid', true);
|
||||
} else {
|
||||
Blockly.utils.dom.removeClass(this.htmlInput_, 'blocklyInvalidInput');
|
||||
Blockly.utils.aria.setState(this.htmlInput_, 'invalid', false);
|
||||
Blockly.utils.dom.removeClass(htmlInput, 'blocklyInvalidInput');
|
||||
Blockly.utils.aria.setState(htmlInput, 'invalid', false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -186,7 +195,7 @@ Blockly.FieldMultilineInput.prototype.updateSize_ = function() {
|
||||
var totalWidth = 0;
|
||||
var totalHeight = 0;
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var tspan = nodes[i];
|
||||
var tspan = /** @type {!Element} */ (nodes[i]);
|
||||
var textWidth = Blockly.utils.dom.getTextWidth(tspan);
|
||||
if (textWidth > totalWidth) {
|
||||
totalWidth = textWidth;
|
||||
|
||||
@@ -64,6 +64,26 @@ Blockly.FieldTextInput = function(opt_value, opt_validator, opt_config) {
|
||||
}
|
||||
Blockly.FieldTextInput.superClass_.constructor.call(this,
|
||||
opt_value, opt_validator, opt_config);
|
||||
|
||||
/**
|
||||
* The HTML input element.
|
||||
* @type {HTMLElement}
|
||||
*/
|
||||
this.htmlInput_ = null;
|
||||
|
||||
/**
|
||||
* Key down event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onKeyDownWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Key input event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @private
|
||||
*/
|
||||
this.onKeyInputWrapper_ = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FieldTextInput, Blockly.Field);
|
||||
|
||||
@@ -183,12 +203,13 @@ Blockly.FieldTextInput.prototype.render_ = function() {
|
||||
} else {
|
||||
this.resizeEditor_();
|
||||
}
|
||||
var htmlInput = /** @type {!HTMLElement} */(this.htmlInput_);
|
||||
if (!this.isTextValid_) {
|
||||
Blockly.utils.dom.addClass(this.htmlInput_, 'blocklyInvalidInput');
|
||||
Blockly.utils.aria.setState(this.htmlInput_, 'invalid', true);
|
||||
Blockly.utils.dom.addClass(htmlInput, 'blocklyInvalidInput');
|
||||
Blockly.utils.aria.setState(htmlInput, 'invalid', true);
|
||||
} else {
|
||||
Blockly.utils.dom.removeClass(this.htmlInput_, 'blocklyInvalidInput');
|
||||
Blockly.utils.aria.setState(this.htmlInput_, 'invalid', false);
|
||||
Blockly.utils.dom.removeClass(htmlInput, 'blocklyInvalidInput');
|
||||
Blockly.utils.aria.setState(htmlInput, 'invalid', false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -338,8 +359,12 @@ Blockly.FieldTextInput.prototype.bindInputEvents_ = function(htmlInput) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.unbindInputEvents_ = function() {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
Blockly.unbindEvent_(this.onKeyInputWrapper_);
|
||||
if (this.onKeyDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
}
|
||||
if (this.onKeyInputWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyInputWrapper_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -440,8 +440,9 @@ Blockly.FieldVariable.dropdownCreate = function() {
|
||||
* In the rename case, prompt the user for a new name.
|
||||
* @param {!Blockly.Menu} menu The Menu component clicked.
|
||||
* @param {!Blockly.MenuItem} menuItem The MenuItem selected within menu.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) {
|
||||
Blockly.FieldVariable.prototype.onItemSelected_ = function(menu, menuItem) {
|
||||
var id = menuItem.getValue();
|
||||
// Handle special cases.
|
||||
if (this.sourceBlock_ && this.sourceBlock_.workspace) {
|
||||
|
||||
Reference in New Issue
Block a user