cloud-blocks
Version:
Cloud Blocks is a library for building scratch computing interfaces with Luxrobo MODI.
896 lines (831 loc) • 24.7 kB
JavaScript
/**
* @license
* Visual Blocks Editor
*
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Methods for rendering a workspace comment as SVG
* @author fenichel@google.com (Rachel Fenichel)
*/
'use strict';
goog.provide('Blockly.WorkspaceCommentSvg.render');
goog.require('Blockly.WorkspaceCommentSvg');
/**
* Radius of the border around the comment.
* @type {number}
* @const
* @private
*/
Blockly.WorkspaceCommentSvg.BORDER_WIDTH = 1;
/**
* Size of the resize icon.
* @type {number}
* @const
* @private
*/
Blockly.WorkspaceCommentSvg.RESIZE_SIZE = 16;
/**
* Offset from the foreignobject edge to the textarea edge.
* @type {number}
* @const
* @private
*/
Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET = 12;
/**
* The height of the comment top bar.
* @package
*/
Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT = 32;
/**
* The size of the minimize arrow icon in the comment top bar.
* @private
*/
Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE = 32;
/**
* The size of the delete icon in the comment top bar.
* @private
*/
Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE = 32;
/**
* The inset for the top bar icons.
* @private
*/
Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET = 0;
/**
* The bottom corner padding of the resize handle touch target.
* Extends slightly outside the comment box.
* @private
*/
Blockly.WorkspaceCommentSvg.RESIZE_CORNER_PAD = 4;
/**
* The top/side padding around resize handle touch target.
* Extends about one extra "diagonal" above resize handle.
* @private
*/
Blockly.WorkspaceCommentSvg.RESIZE_OUTER_PAD = 8;
/**
* Width that a minimized comment should have.
* @private
*/
Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH = 200;
/**
* Returns a bounding box describing the dimensions of this comment.
* @return {!{height: number, width: number}} Object with height and width
* properties in workspace units.
* @package
*/
Blockly.WorkspaceCommentSvg.prototype.getHeightWidth = function () {
return { width: this.getWidth(), height: this.getHeight() };
};
/**
* Renders the workspace comment.
* @package
*/
Blockly.WorkspaceCommentSvg.prototype.render = function () {
if (this.rendered_) {
return;
}
var size = this.getHeightWidth();
// Add text area
this.commentEditor_ = this.createEditor_();
this.svgGroup_.appendChild(this.commentEditor_);
this.createCommentTopBar_();
this.svgRectTarget_ = Blockly.utils.createSvgElement('rect', {
class: 'blocklyDraggable scratchCommentTarget',
x: 0,
y: Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT,
rx: 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
ry: 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH
});
this.svgGroup_.appendChild(this.svgRectTarget_);
// Add the resize icon
this.addResizeDom_();
// Show / hide relevant things based on minimized state
if (this.isMinimized()) {
this.minimizeArrow_.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-up.svg'
);
this.commentEditor_.setAttribute('display', 'none');
this.resizeGroup_.setAttribute('display', 'none');
} else {
this.minimizeArrow_.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-down.svg'
);
this.topBarLabel_.setAttribute('display', 'none');
}
this.setSize(size.width, size.height);
// Set the content
this.textarea_.value = this.content_;
this.rendered_ = true;
if (this.resizeGroup_) {
Blockly.bindEventWithChecks_(
this.resizeGroup_,
'mousedown',
this,
this.resizeMouseDown_
);
Blockly.bindEventWithChecks_(
this.resizeGroup_,
'mouseup',
this,
this.resizeMouseUp_
);
}
Blockly.bindEventWithChecks_(
this.minimizeArrow_,
'mousedown',
this,
this.minimizeArrowMouseDown_,
true
);
Blockly.bindEventWithChecks_(
this.minimizeArrow_,
'mouseout',
this,
this.minimizeArrowMouseOut_,
true
);
Blockly.bindEventWithChecks_(
this.minimizeArrow_,
'mouseup',
this,
this.minimizeArrowMouseUp_,
true
);
Blockly.bindEventWithChecks_(
this.deleteIcon_,
'mousedown',
this,
this.deleteMouseDown_,
true
);
Blockly.bindEventWithChecks_(
this.deleteIcon_,
'mouseout',
this,
this.deleteMouseOut_,
true
);
Blockly.bindEventWithChecks_(
this.deleteIcon_,
'mouseup',
this,
this.deleteMouseUp_,
true
);
};
/**
* Create the text area for the comment.
* @return {!Element} The top-level node of the editor.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.createEditor_ = function () {
this.foreignObject_ = Blockly.utils.createSvgElement(
'foreignObject',
{
x: Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
y:
Blockly.WorkspaceCommentSvg.BORDER_WIDTH +
Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT,
class: 'scratchCommentForeignObject'
},
null
);
var body = document.createElementNS(Blockly.HTML_NS, 'body');
body.setAttribute('xmlns', Blockly.HTML_NS);
body.className = 'blocklyMinimalBody scratchCommentBody';
var textarea = document.createElementNS(Blockly.HTML_NS, 'textarea');
textarea.className = 'scratchCommentTextarea scratchCommentText';
textarea.setAttribute('dir', this.RTL ? 'RTL' : 'LTR');
textarea.setAttribute(
'maxlength',
Blockly.WorkspaceComment.COMMENT_TEXT_LIMIT
);
textarea.setAttribute(
'placeholder',
Blockly.Msg.WORKSPACE_COMMENT_DEFAULT_TEXT
);
body.appendChild(textarea);
this.textarea_ = textarea;
this.textarea_.style.margin =
Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET + 'px';
this.foreignObject_.appendChild(body);
Blockly.bindEventWithChecks_(
textarea,
'mousedown',
this,
function (e) {
e.stopPropagation(); // Propagation causes preventDefault from workspace handler
},
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.text_ != textarea.value) {
this.setText(textarea.value);
}
});
this.labelText_ = this.getLabelText();
return this.foreignObject_;
};
/**
* Add the resize icon to the DOM
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.addResizeDom_ = function () {
this.resizeGroup_ = Blockly.utils.createSvgElement(
'g',
{
class: this.RTL ? 'scratchCommentResizeSW' : 'scratchCommentResizeSE'
},
this.svgGroup_
);
var resizeSize = Blockly.WorkspaceCommentSvg.RESIZE_SIZE;
var outerPad = Blockly.ScratchBubble.RESIZE_OUTER_PAD;
var cornerPad = Blockly.ScratchBubble.RESIZE_CORNER_PAD;
// Build an (invisible) triangle that will catch resizes. It is padded on the
// top/left by outerPad, and padded down/right by cornerPad.
Blockly.utils.createSvgElement(
'polygon',
{
points: [
-outerPad,
resizeSize + cornerPad,
resizeSize + cornerPad,
resizeSize + cornerPad,
resizeSize + cornerPad,
-outerPad
].join(' ')
},
this.resizeGroup_
);
Blockly.utils.createSvgElement(
'line',
{
class: 'blocklyResizeLine',
x1: resizeSize / 3,
y1: resizeSize - 1,
x2: resizeSize - 1,
y2: resizeSize / 3
},
this.resizeGroup_
);
Blockly.utils.createSvgElement(
'line',
{
class: 'blocklyResizeLine',
x1: (resizeSize * 2) / 3,
y1: resizeSize - 1,
x2: resizeSize - 1,
y2: (resizeSize * 2) / 3
},
this.resizeGroup_
);
};
/**
* Create the comment top bar and its contents.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.createCommentTopBar_ = function () {
this.svgHandleTarget_ = Blockly.utils.createSvgElement(
'rect',
{
class: 'blocklyDraggable scratchCommentTopBar',
rx: Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
ry: Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
height: Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT
},
this.svgGroup_
);
this.createTopBarIcons_();
this.createTopBarLabel_();
};
/**
* Create the comment top bar label. This is the truncated comment text
* that shows when comment is minimized.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.createTopBarLabel_ = function () {
this.topBarLabel_ = Blockly.utils.createSvgElement(
'text',
{
class: 'scratchCommentText',
x: this.width_ / 2,
y:
Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT / 2 +
Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
'text-anchor': 'middle',
'dominant-baseline': 'middle'
},
this.svgGroup_
);
var labelTextNode = document.createTextNode(this.labelText_);
this.topBarLabel_.appendChild(labelTextNode);
};
/**
* Create the minimize toggle and delete icons that in the comment top bar.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.createTopBarIcons_ = function () {
var topBarMiddleY =
Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT / 2 +
Blockly.WorkspaceCommentSvg.BORDER_WIDTH;
// Minimize Toggle Icon in Comment Top Bar
var xInset = Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET;
this.minimizeArrow_ = Blockly.utils.createSvgElement(
'image',
{
x: xInset,
y: topBarMiddleY - Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE / 2,
width: Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE,
height: Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE
},
this.svgGroup_
);
// Delete Icon in Comment Top Bar
this.deleteIcon_ = Blockly.utils.createSvgElement(
'image',
{
x: xInset,
y: topBarMiddleY - Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE / 2,
width: Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE,
height: Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE
},
this.svgGroup_
);
this.deleteIcon_.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
Blockly.mainWorkspace.options.pathToMedia + 'delete-x.svg'
);
};
/**
* Handle a mouse-down on bubble's minimize icon.
* @param {!Event} e Mouse down event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.minimizeArrowMouseDown_ = function (e) {
// Set a property to indicate that this minimize arrow icon had a mouse down
// event. This property will get reset if the mouse leaves the icon, or when
// a mouse up event occurs on this icon.
this.shouldToggleMinimize_ = true;
e.stopPropagation();
};
/**
* Handle a mouse-out on bubble's minimize icon.
* @param {!Event} _e Mouse out event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.minimizeArrowMouseOut_ = function (_e) {
// If the mouse leaves the minimize arrow icon, make sure the
// shouldToggleMinimize_ property gets reset.
this.shouldToggleMinimize_ = false;
};
/**
* Handle a mouse-up on bubble's minimize icon.
* @param {!Event} e Mouse up event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.minimizeArrowMouseUp_ = function (e) {
// First check if this is the icon that had a mouse down event on it and that
// the mouse never left the icon.
if (this.shouldToggleMinimize_) {
this.shouldToggleMinimize = false;
this.toggleMinimize_();
}
e.stopPropagation();
};
/**
* Handle a mouse-down on bubble's minimize icon.
* @param {!Event} e Mouse down event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.deleteMouseDown_ = function (e) {
// Set a property to indicate that this delete icon had a mouse down event.
// This property will get reset if the mouse leaves the icon, or when
// a mouse up event occurs on this icon.
this.shouldDelete_ = true;
e.stopPropagation();
};
/**
* Handle a mouse-out on bubble's minimize icon.
* @param {!Event} _e Mouse out event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.deleteMouseOut_ = function (_e) {
// If the mouse leaves the delete icon, reset the shouldDelete_ property.
this.shouldDelete_ = false;
};
/**
* Handle a mouse-up on bubble's delete icon.
* @param {!Event} e Mouse up event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.deleteMouseUp_ = function (e) {
// First check that this same icon had a mouse down event on it and that the
// mouse never left the icon.
if (this.shouldDelete_) {
this.dispose();
}
e.stopPropagation();
};
/**
* Handle a mouse-down on comment's resize corner.
* @param {!Event} e Mouse down event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.resizeMouseDown_ = function (e) {
this.resizeStartSize_ = { width: this.width_, height: this.height_ };
this.unbindDragEvents_();
this.workspace.setResizesEnabled(false);
if (Blockly.utils.isRightButton(e)) {
// No right-click.
e.stopPropagation();
return;
}
// Left-click (or middle click)
this.workspace.startDrag(
e,
new goog.math.Coordinate(
this.workspace.RTL ? -this.width_ : this.width_,
this.height_
)
);
this.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(
document,
'mouseup',
this,
this.resizeMouseUp_
);
this.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(
document,
'mousemove',
this,
this.resizeMouseMove_
);
Blockly.hideChaff();
// This event has been handled. No need to bubble up to the document.
e.stopPropagation();
};
/**
* Set the apperance of the workspace comment bubble to the minimized or full size
* appearance. In the minimized state, the comment should only have the top bar
* displayed, with the minimize icon swapped to the minimized state, and
* truncated comment text is shown in the middle of the top bar. There should be
* no resize handle when the workspace comment is in its minimized state.
* @param {boolean} minimize Whether the bubble should be minimized
* @param {?string} labelText Optional label text for the comment top bar
* when it is minimized.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.setRenderedMinimizeState_ = function (
minimize,
labelText
) {
if (minimize) {
// Change minimize icon
this.minimizeArrow_.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-up.svg'
);
// Hide text area
this.commentEditor_.setAttribute('display', 'none');
// Hide resize handle if it exists
if (this.resizeGroup_) {
this.resizeGroup_.setAttribute('display', 'none');
}
if (labelText && this.labelText_ != labelText) {
// Update label and display
// TODO is there a better way to do this?
this.topBarLabel_.textContent = labelText;
}
Blockly.utils.removeAttribute(this.topBarLabel_, 'display');
} else {
// Change minimize icon
this.minimizeArrow_.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-down.svg'
);
// Hide label
this.topBarLabel_.setAttribute('display', 'none');
// Show text area
Blockly.utils.removeAttribute(this.commentEditor_, 'display');
// Display resize handle if it exists
if (this.resizeGroup_) {
Blockly.utils.removeAttribute(this.resizeGroup_, 'display');
}
}
};
/**
* Stop binding to the global mouseup and mousemove events.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.unbindDragEvents_ = function () {
if (this.onMouseUpWrapper_) {
Blockly.unbindEvent_(this.onMouseUpWrapper_);
this.onMouseUpWrapper_ = null;
}
if (this.onMouseMoveWrapper_) {
Blockly.unbindEvent_(this.onMouseMoveWrapper_);
this.onMouseMoveWrapper_ = null;
}
};
/*
* Handle a mouse-up event while dragging a comment's border or resize handle.
* @param {!Event} e Mouse up event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.resizeMouseUp_ = function (/*e*/) {
Blockly.Touch.clearTouchIdentifier();
this.unbindDragEvents_();
var oldHW = this.resizeStartSize_;
this.resizeStartSize_ = null;
if (this.width_ == oldHW.width && this.height_ == oldHW.height) {
return;
}
// Fire a change event for the new width/height after
// resize mouse up
Blockly.Events.fire(
new Blockly.Events.CommentChange(
this,
{ width: oldHW.width, height: oldHW.height },
{ width: this.width_, height: this.height_ }
)
);
this.workspace.setResizesEnabled(true);
};
/**
* Resize this comment to follow the mouse.
* @param {!Event} e Mouse move event.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.resizeMouseMove_ = function (e) {
this.autoLayout_ = false;
var newXY = this.workspace.moveDrag(e);
// The call to setSize below emits a CommentChange event,
// but we don't want multiple CommentChange events to be
// emitted while the user is still in the process of resizing
// the comment, so disable events here. The event is emitted in
// resizeMouseUp_.
var disabled = false;
if (Blockly.Events.isEnabled()) {
Blockly.Events.disable();
disabled = true;
}
this.setSize(this.RTL ? -newXY.x : newXY.x, newXY.y);
if (disabled) {
Blockly.Events.enable();
}
};
/**
* Callback function triggered when the comment has resized.
* Resize the text area accordingly.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.resizeComment_ = function () {
var doubleBorderWidth = 2 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH;
var topOffset = Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT;
var textOffset = Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET * 2;
this.foreignObject_.setAttribute('width', this.width_ - doubleBorderWidth);
this.foreignObject_.setAttribute(
'height',
this.height_ - doubleBorderWidth - topOffset
);
if (this.RTL) {
this.foreignObject_.setAttribute('x', -this.width_);
}
this.textarea_.style.width = this.width_ - textOffset + 'px';
this.textarea_.style.height =
this.height_ - doubleBorderWidth - textOffset - topOffset + 'px';
};
/**
* Set size
* @param {number} width width of the container
* @param {number} height height of the container
* @package
*/
Blockly.WorkspaceCommentSvg.prototype.setSize = function (width, height) {
var oldWidth = this.width_;
var oldHeight = this.height_;
var doubleBorderWidth = 2 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH;
if (this.isMinimized_) {
width = Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH;
height = Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT;
} else {
// Minimum size of a 'full size' (not minimized) comment.
width = Math.max(width, doubleBorderWidth + 50);
height = Math.max(
height,
doubleBorderWidth + 20 + Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT
);
// Note we are only updating this.width_ or this.height_ here
// and not in the case above, because when we're minimizing a comment,
// we want to keep track of the width/height of the maximized comment
this.width_ = width;
this.height_ = height;
Blockly.Events.fire(
new Blockly.Events.CommentChange(
this,
{ width: oldWidth, height: oldHeight },
{ width: this.width_, height: this.height_ }
)
);
}
this.svgRect_.setAttribute('width', width);
this.svgRect_.setAttribute('height', height);
this.svgRectTarget_.setAttribute('width', width);
this.svgRectTarget_.setAttribute(
'height',
height - Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT
);
this.svgHandleTarget_.setAttribute('width', width);
this.svgHandleTarget_.setAttribute(
'height',
Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT
);
if (this.RTL) {
this.minimizeArrow_.setAttribute(
'x',
width -
Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE -
Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET
);
this.deleteIcon_.setAttribute(
'x',
-width + Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET
);
this.svgRect_.setAttribute('transform', 'scale(-1 1)');
this.svgHandleTarget_.setAttribute('transform', 'scale(-1 1)');
this.svgHandleTarget_.setAttribute(
'transform',
'translate(' + -width + ', 1)'
);
this.minimizeArrow_.setAttribute(
'transform',
'translate(' + -width + ', 1)'
);
this.deleteIcon_.setAttribute('tranform', 'translate(' + -width + ', 1)');
this.svgRectTarget_.setAttribute(
'transform',
'translate(' + -width + ', 1)'
);
this.topBarLabel_.setAttribute('transform', 'translate(' + -width + ', 1)');
} else {
this.deleteIcon_.setAttribute(
'x',
width -
Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE -
Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET
);
}
var resizeSize = Blockly.WorkspaceCommentSvg.RESIZE_SIZE;
if (this.resizeGroup_) {
if (this.RTL) {
// Mirror the resize group.
this.resizeGroup_.setAttribute(
'transform',
'translate(' +
(-width + doubleBorderWidth + resizeSize) +
',' +
(height - doubleBorderWidth - resizeSize) +
') scale(-1 1)'
);
} else {
this.resizeGroup_.setAttribute(
'transform',
'translate(' +
(width - doubleBorderWidth - resizeSize) +
',' +
(height - doubleBorderWidth - resizeSize) +
')'
);
}
}
if (this.isMinimized_) {
this.topBarLabel_.setAttribute('x', width / 2);
this.topBarLabel_.setAttribute('y', height / 2);
}
// Allow the contents to resize.
this.resizeComment_();
};
/**
* Toggle the minimization state of this comment.
* @private
*/
Blockly.WorkspaceComment.prototype.toggleMinimize_ = function () {
this.setMinimized(!this.isMinimized_);
};
/**
* Set the minimized state for this comment. If the comment is rendered,
* change the appearance of the comment accordingly.
* @param {boolean} minimize Whether the comment should be minimized
* @package
*/
Blockly.WorkspaceComment.prototype.setMinimized = function (minimize) {
if (this.isMinimized_ == minimize) {
return;
}
Blockly.Events.fire(
new Blockly.Events.CommentChange(
this,
{ minimized: this.isMinimized_ },
{ minimized: minimize }
)
);
this.isMinimized_ = minimize;
if (minimize) {
if (this.rendered_) {
this.setRenderedMinimizeState_(true, this.getLabelText());
}
this.setSize(
Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH,
Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT
);
} else {
if (this.rendered_) {
this.setRenderedMinimizeState_(false);
}
this.setText(this.content_);
this.setSize(this.width_, this.height_);
}
};
/**
* Dispose of any rendered comment components.
* @private
*/
Blockly.WorkspaceCommentSvg.prototype.disposeInternal_ = function () {
this.textarea_ = null;
this.foreignObject_ = null;
this.svgRect_ = null;
this.svgRectTarget_ = null;
this.svgHandleTarget_ = null;
};
/**
* Set the focus on the text area.
* @package
*/
Blockly.WorkspaceCommentSvg.prototype.setFocus = function () {
var comment = this;
this.focused_ = true;
comment.textarea_.focus();
// Defer CSS changes.
setTimeout(function () {
comment.addFocus();
Blockly.utils.addClass(
comment.svgRectTarget_,
'scratchCommentTargetFocused'
);
Blockly.utils.addClass(
comment.svgHandleTarget_,
'scratchCommentHandleTargetFocused'
);
}, 0);
};
/**
* Remove focus from the text area.
* @package
*/
Blockly.WorkspaceCommentSvg.prototype.blurFocus = function () {
var comment = this;
this.focused_ = false;
comment.textarea_.blur();
// Defer CSS changes.
setTimeout(function () {
if (comment.svgGroup_) {
// Could have been deleted in the meantime
comment.removeFocus();
Blockly.utils.removeClass(
comment.svgRectTarget_,
'scratchCommentTargetFocused'
);
Blockly.utils.removeClass(
comment.svgHandleTarget_,
'scratchCommentHandleTargetFocused'
);
}
}, 0);
};