diff --git a/core/trashcan.js b/core/trashcan.js index 619299b21..fb60ca3a1 100644 --- a/core/trashcan.js +++ b/core/trashcan.js @@ -10,47 +10,56 @@ */ 'use strict'; -goog.provide('Blockly.Trashcan'); +goog.module('Blockly.Trashcan'); +goog.module.declareLegacyNamespace(); -goog.require('Blockly.browserEvents'); -goog.require('Blockly.ComponentManager'); -goog.require('Blockly.DeleteArea'); -goog.require('Blockly.Events'); +/* eslint-disable-next-line no-unused-vars */ +const Abstract = goog.requireType('Blockly.Events.Abstract'); +/* eslint-disable-next-line no-unused-vars */ +const Blockly = goog.requireType('Blockly'); +const ComponentManager = goog.require('Blockly.ComponentManager'); +const DeleteArea = goog.require('Blockly.DeleteArea'); +const Events = goog.require('Blockly.Events'); +/* eslint-disable-next-line no-unused-vars */ +const IAutoHideable = goog.require('Blockly.IAutoHideable'); +/* eslint-disable-next-line no-unused-vars */ +const IDraggable = goog.requireType('Blockly.IDraggable'); +/* eslint-disable-next-line no-unused-vars */ +const IFlyout = goog.requireType('Blockly.IFlyout'); +/* eslint-disable-next-line no-unused-vars */ +const IPositionable = goog.require('Blockly.IPositionable'); +/* eslint-disable-next-line no-unused-vars */ +const MetricsManager = goog.requireType('Blockly.MetricsManager'); +const Options = goog.require('Blockly.Options'); +const Rect = goog.require('Blockly.utils.Rect'); +const Svg = goog.require('Blockly.utils.Svg'); +/* eslint-disable-next-line no-unused-vars */ +const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg'); +const Xml = goog.require('Blockly.Xml'); +const browserEvents = goog.require('Blockly.browserEvents'); +const dom = goog.require('Blockly.utils.dom'); +const internalConstants = goog.require('Blockly.internalConstants'); +const registry = goog.require('Blockly.registry'); +const toolbox = goog.require('Blockly.utils.toolbox'); +const uiPosition = goog.require('Blockly.uiPosition'); +const utils = goog.require('Blockly.utils'); /** @suppress {extraRequire} */ goog.require('Blockly.Events.TrashcanOpen'); -goog.require('Blockly.IAutoHideable'); -goog.require('Blockly.internalConstants'); -goog.require('Blockly.IPositionable'); -goog.require('Blockly.Options'); -goog.require('Blockly.registry'); -goog.require('Blockly.uiPosition'); -goog.require('Blockly.utils'); -goog.require('Blockly.utils.dom'); -goog.require('Blockly.utils.Rect'); -goog.require('Blockly.utils.Svg'); -goog.require('Blockly.utils.toolbox'); -goog.require('Blockly.Xml'); - -goog.requireType('Blockly.Events.Abstract'); -goog.requireType('Blockly.IDraggable'); -goog.requireType('Blockly.IFlyout'); -goog.requireType('Blockly.utils.Rect'); -goog.requireType('Blockly.WorkspaceSvg'); /** * Class for a trash can. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in. + * @param {!WorkspaceSvg} workspace The workspace to sit in. * @constructor - * @implements {Blockly.IAutoHideable} - * @implements {Blockly.IPositionable} - * @extends {Blockly.DeleteArea} + * @implements {IAutoHideable} + * @implements {IPositionable} + * @extends {DeleteArea} */ -Blockly.Trashcan = function(workspace) { - Blockly.Trashcan.superClass_.constructor.call(this); +const Trashcan = function(workspace) { + Trashcan.superClass_.constructor.call(this); /** * The workspace the trashcan sits in. - * @type {!Blockly.WorkspaceSvg} + * @type {!WorkspaceSvg} * @private */ this.workspace_ = workspace; @@ -71,7 +80,7 @@ Blockly.Trashcan = function(workspace) { /** * The trashcan flyout. - * @type {Blockly.IFlyout} + * @type {IFlyout} * @package */ this.flyout = null; @@ -80,7 +89,7 @@ Blockly.Trashcan = function(workspace) { return; } // Create flyout options. - var flyoutWorkspaceOptions = new Blockly.Options( + const flyoutWorkspaceOptions = new Options( /** @type {!Blockly.BlocklyOptions} */ ({ 'scrollbars': true, @@ -96,130 +105,103 @@ Blockly.Trashcan = function(workspace) { // Create vertical or horizontal flyout. if (this.workspace_.horizontalLayout) { flyoutWorkspaceOptions.toolboxPosition = - this.workspace_.toolboxPosition == Blockly.utils.toolbox.Position.TOP ? - Blockly.utils.toolbox.Position.BOTTOM : Blockly.utils.toolbox.Position.TOP; - var HorizontalFlyout = Blockly.registry.getClassFromOptions( - Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX, - this.workspace_.options, true); + this.workspace_.toolboxPosition == toolbox.Position.TOP ? + toolbox.Position.BOTTOM : + toolbox.Position.TOP; + const HorizontalFlyout = registry.getClassFromOptions( + registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX, this.workspace_.options, + true); this.flyout = new HorizontalFlyout(flyoutWorkspaceOptions); } else { flyoutWorkspaceOptions.toolboxPosition = - this.workspace_.toolboxPosition == Blockly.utils.toolbox.Position.RIGHT ? - Blockly.utils.toolbox.Position.LEFT : Blockly.utils.toolbox.Position.RIGHT; - var VerticalFlyout = Blockly.registry.getClassFromOptions( - Blockly.registry.Type.FLYOUTS_VERTICAL_TOOLBOX, - this.workspace_.options, true); + this.workspace_.toolboxPosition == toolbox.Position.RIGHT ? + toolbox.Position.LEFT : + toolbox.Position.RIGHT; + const VerticalFlyout = registry.getClassFromOptions( + registry.Type.FLYOUTS_VERTICAL_TOOLBOX, this.workspace_.options, true); this.flyout = new VerticalFlyout(flyoutWorkspaceOptions); } this.workspace_.addChangeListener(this.onDelete_.bind(this)); }; -Blockly.utils.object.inherits(Blockly.Trashcan, Blockly.DeleteArea); +utils.object.inherits(Trashcan, DeleteArea); /** * Width of both the trash can and lid images. - * @const {number} - * @private */ -Blockly.Trashcan.prototype.WIDTH_ = 47; +const WIDTH = 47; /** * Height of the trashcan image (minus lid). - * @const {number} - * @private */ -Blockly.Trashcan.prototype.BODY_HEIGHT_ = 44; +const BODY_HEIGHT = 44; /** * Height of the lid image. - * @const {number} - * @private */ -Blockly.Trashcan.prototype.LID_HEIGHT_ = 16; +const LID_HEIGHT = 16; /** * Distance between trashcan and bottom or top edge of workspace. - * @const {number} - * @private */ -Blockly.Trashcan.prototype.MARGIN_VERTICAL_ = 20; +const MARGIN_VERTICAL = 20; /** * Distance between trashcan and right or left edge of workspace. - * @const {number} - * @private */ -Blockly.Trashcan.prototype.MARGIN_HORIZONTAL_ = 20; +const MARGIN_HORIZONTAL = 20; /** * Extent of hotspot on all sides beyond the size of the image. - * @const {number} - * @private */ -Blockly.Trashcan.prototype.MARGIN_HOTSPOT_ = 10; +const MARGIN_HOTSPOT = 10; /** * Location of trashcan in sprite image. - * @const {number} - * @private */ -Blockly.Trashcan.prototype.SPRITE_LEFT_ = 0; +const SPRITE_LEFT = 0; /** * Location of trashcan in sprite image. - * @const {number} - * @private */ -Blockly.Trashcan.prototype.SPRITE_TOP_ = 32; +const SPRITE_TOP = 32; /** * The openness of the lid when the trashcan contains blocks. * (0.0 = closed, 1.0 = open) - * @const {number} - * @private */ -Blockly.Trashcan.prototype.HAS_BLOCKS_LID_ANGLE_ = 0.1; +const HAS_BLOCKS_LID_ANGLE = 0.1; /** * The length of the lid open/close animation in milliseconds. - * @const {number} - * @private */ -Blockly.Trashcan.ANIMATION_LENGTH_ = 80; +const ANIMATION_LENGTH = 80; /** * The number of frames in the animation. - * @const {number} - * @private */ -Blockly.Trashcan.ANIMATION_FRAMES_ = 4; +const ANIMATION_FRAMES = 4; /** * The minimum (resting) opacity of the trashcan and lid. - * @const {number} - * @private */ -Blockly.Trashcan.OPACITY_MIN_ = 0.4; +const OPACITY_MIN = 0.4; /** * The maximum (hovered) opacity of the trashcan and lid. - * @const {number} - * @private */ -Blockly.Trashcan.OPACITY_MAX_ = 0.8; +const OPACITY_MAX = 0.8; /** * The maximum angle the trashcan lid can opens to. At the end of the open * animation the lid will be open to this angle. - * @const {number} - * @private */ -Blockly.Trashcan.MAX_LID_ANGLE_ = 45; +const MAX_LID_ANGLE = 45; /** * Current open/close state of the lid. * @type {boolean} */ -Blockly.Trashcan.prototype.isLidOpen = false; +Trashcan.prototype.isLidOpen = false; /** * The minimum openness of the lid. Used to indicate if the trashcan contains @@ -227,62 +209,62 @@ Blockly.Trashcan.prototype.isLidOpen = false; * @type {number} * @private */ -Blockly.Trashcan.prototype.minOpenness_ = 0; +Trashcan.prototype.minOpenness_ = 0; /** * The SVG group containing the trash can. * @type {SVGElement} * @private */ -Blockly.Trashcan.prototype.svgGroup_ = null; +Trashcan.prototype.svgGroup_ = null; /** * The SVG image element of the trash can lid. * @type {SVGElement} * @private */ -Blockly.Trashcan.prototype.svgLid_ = null; +Trashcan.prototype.svgLid_ = null; /** * Task ID of opening/closing animation. * @type {number} * @private */ -Blockly.Trashcan.prototype.lidTask_ = 0; +Trashcan.prototype.lidTask_ = 0; /** * Current state of lid opening (0.0 = closed, 1.0 = open). * @type {number} * @private */ -Blockly.Trashcan.prototype.lidOpen_ = 0; +Trashcan.prototype.lidOpen_ = 0; /** * Left coordinate of the trash can. * @type {number} * @private */ -Blockly.Trashcan.prototype.left_ = 0; +Trashcan.prototype.left_ = 0; /** * Top coordinate of the trash can. * @type {number} * @private */ -Blockly.Trashcan.prototype.top_ = 0; +Trashcan.prototype.top_ = 0; /** * Whether this has been initialized. * @type {boolean} * @private */ -Blockly.Trashcan.prototype.initialized_ = false; +Trashcan.prototype.initialized_ = false; /** * Create the trash can elements. * @return {!SVGElement} The trash can's SVG group. */ -Blockly.Trashcan.prototype.createDom = function() { +Trashcan.prototype.createDom = function() { /* Here's the markup that will be generated: @@ -297,68 +279,52 @@ Blockly.Trashcan.prototype.createDom = function() { clip-path="url(#blocklyTrashLidClipPath837493)"> */ - this.svgGroup_ = Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.G, - {'class': 'blocklyTrash'}, null); - var clip; - var rnd = String(Math.random()).substring(2); - clip = Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.CLIPPATH, - {'id': 'blocklyTrashBodyClipPath' + rnd}, - this.svgGroup_); - Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.RECT, - { - 'width': this.WIDTH_, - 'height': this.BODY_HEIGHT_, - 'y': this.LID_HEIGHT_ - }, - clip); - var body = Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.IMAGE, { - 'width': Blockly.internalConstants.SPRITE.width, - 'x': -this.SPRITE_LEFT_, - 'height': Blockly.internalConstants.SPRITE.height, - 'y': -this.SPRITE_TOP_, + this.svgGroup_ = dom.createSvgElement(Svg.G, {'class': 'blocklyTrash'}, null); + let clip; + const rnd = String(Math.random()).substring(2); + clip = dom.createSvgElement( + Svg.CLIPPATH, {'id': 'blocklyTrashBodyClipPath' + rnd}, this.svgGroup_); + dom.createSvgElement( + Svg.RECT, {'width': WIDTH, 'height': BODY_HEIGHT, 'y': LID_HEIGHT}, clip); + const body = dom.createSvgElement( + Svg.IMAGE, { + 'width': internalConstants.SPRITE.width, + 'x': -SPRITE_LEFT, + 'height': internalConstants.SPRITE.height, + 'y': -SPRITE_TOP, 'clip-path': 'url(#blocklyTrashBodyClipPath' + rnd + ')' }, this.svgGroup_); body.setAttributeNS( - Blockly.utils.dom.XLINK_NS, 'xlink:href', - this.workspace_.options.pathToMedia + - Blockly.internalConstants.SPRITE.url); + dom.XLINK_NS, 'xlink:href', + this.workspace_.options.pathToMedia + internalConstants.SPRITE.url); - clip = Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.CLIPPATH, - {'id': 'blocklyTrashLidClipPath' + rnd}, - this.svgGroup_); - Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.RECT, - {'width': this.WIDTH_, 'height': this.LID_HEIGHT_}, clip); - this.svgLid_ = Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.IMAGE, { - 'width': Blockly.internalConstants.SPRITE.width, - 'x': -this.SPRITE_LEFT_, - 'height': Blockly.internalConstants.SPRITE.height, - 'y': -this.SPRITE_TOP_, + clip = dom.createSvgElement( + Svg.CLIPPATH, {'id': 'blocklyTrashLidClipPath' + rnd}, this.svgGroup_); + dom.createSvgElement(Svg.RECT, {'width': WIDTH, 'height': LID_HEIGHT}, clip); + this.svgLid_ = dom.createSvgElement( + Svg.IMAGE, { + 'width': internalConstants.SPRITE.width, + 'x': -SPRITE_LEFT, + 'height': internalConstants.SPRITE.height, + 'y': -SPRITE_TOP, 'clip-path': 'url(#blocklyTrashLidClipPath' + rnd + ')' }, this.svgGroup_); this.svgLid_.setAttributeNS( - Blockly.utils.dom.XLINK_NS, 'xlink:href', - this.workspace_.options.pathToMedia + - Blockly.internalConstants.SPRITE.url); + dom.XLINK_NS, 'xlink:href', + this.workspace_.options.pathToMedia + internalConstants.SPRITE.url); // bindEventWithChecks_ quashes events too aggressively. See: // https://groups.google.com/forum/#!topic/blockly/QF4yB9Wx00s // Using bindEventWithChecks_ for blocking mousedown causes issue in mobile. // See #4303 - Blockly.browserEvents.bind( + browserEvents.bind( this.svgGroup_, 'mousedown', this, this.blockMouseDownWhenOpenable_); - Blockly.browserEvents.bind(this.svgGroup_, 'mouseup', this, this.click); + browserEvents.bind(this.svgGroup_, 'mouseup', this, this.click); // Bind to body instead of this.svgGroup_ so that we don't get lid jitters - Blockly.browserEvents.bind(body, 'mouseover', this, this.mouseOver_); - Blockly.browserEvents.bind(body, 'mouseout', this, this.mouseOut_); + browserEvents.bind(body, 'mouseover', this, this.mouseOver_); + browserEvents.bind(body, 'mouseout', this, this.mouseOut_); this.animateLid_(); return this.svgGroup_; }; @@ -366,21 +332,20 @@ Blockly.Trashcan.prototype.createDom = function() { /** * Initializes the trash can. */ -Blockly.Trashcan.prototype.init = function() { +Trashcan.prototype.init = function() { if (this.workspace_.options.maxTrashcanContents > 0) { - Blockly.utils.dom.insertAfter( - this.flyout.createDom(Blockly.utils.Svg.SVG), - this.workspace_.getParentSvg()); + dom.insertAfter( + this.flyout.createDom(Svg.SVG), this.workspace_.getParentSvg()); this.flyout.init(this.workspace_); } this.workspace_.getComponentManager().addComponent({ component: this, weight: 1, capabilities: [ - Blockly.ComponentManager.Capability.AUTOHIDEABLE, - Blockly.ComponentManager.Capability.DELETE_AREA, - Blockly.ComponentManager.Capability.DRAG_TARGET, - Blockly.ComponentManager.Capability.POSITIONABLE + ComponentManager.Capability.AUTOHIDEABLE, + ComponentManager.Capability.DELETE_AREA, + ComponentManager.Capability.DRAG_TARGET, + ComponentManager.Capability.POSITIONABLE ] }); this.initialized_ = true; @@ -392,10 +357,10 @@ Blockly.Trashcan.prototype.init = function() { * Unlink from all DOM elements to prevent memory leaks. * @suppress {checkTypes} */ -Blockly.Trashcan.prototype.dispose = function() { +Trashcan.prototype.dispose = function() { this.workspace_.getComponentManager().removeComponent('trashcan'); if (this.svgGroup_) { - Blockly.utils.dom.removeNode(this.svgGroup_); + dom.removeNode(this.svgGroup_); this.svgGroup_ = null; } this.svgLid_ = null; @@ -408,7 +373,7 @@ Blockly.Trashcan.prototype.dispose = function() { * @return {boolean} True if the trashcan has contents. * @private */ -Blockly.Trashcan.prototype.hasContents_ = function() { +Trashcan.prototype.hasContents_ = function() { return !!this.contents_.length; }; @@ -416,18 +381,18 @@ Blockly.Trashcan.prototype.hasContents_ = function() { * Returns true if the trashcan contents-flyout is currently open. * @return {boolean} True if the trashcan contents-flyout is currently open. */ -Blockly.Trashcan.prototype.contentsIsOpen = function() { +Trashcan.prototype.contentsIsOpen = function() { return this.flyout.isVisible(); }; /** * Opens the trashcan flyout. */ -Blockly.Trashcan.prototype.openFlyout = function() { +Trashcan.prototype.openFlyout = function() { if (this.contentsIsOpen()) { return; } - var xml = this.contents_.map(Blockly.Xml.textToDom); + const xml = this.contents_.map(Xml.textToDom); this.flyout.show(xml); this.fireUiEvent_(true); }; @@ -435,7 +400,7 @@ Blockly.Trashcan.prototype.openFlyout = function() { /** * Closes the trashcan flyout. */ -Blockly.Trashcan.prototype.closeFlyout = function() { +Trashcan.prototype.closeFlyout = function() { if (!this.contentsIsOpen()) { return; } @@ -448,7 +413,7 @@ Blockly.Trashcan.prototype.closeFlyout = function() { * @param {boolean} onlyClosePopups Whether only popups should be closed. * Flyouts should not be closed if this is true. */ -Blockly.Trashcan.prototype.autoHide = function(onlyClosePopups) { +Trashcan.prototype.autoHide = function(onlyClosePopups) { // For now the trashcan flyout always autocloses because it overlays the // trashcan UI (no trashcan to click to close it). if (!onlyClosePopups && this.flyout) { @@ -460,7 +425,7 @@ Blockly.Trashcan.prototype.autoHide = function(onlyClosePopups) { * Empties the trashcan's contents. If the contents-flyout is currently open * it will be closed. */ -Blockly.Trashcan.prototype.emptyContents = function() { +Trashcan.prototype.emptyContents = function() { if (!this.hasContents_()) { return; } @@ -473,99 +438,97 @@ Blockly.Trashcan.prototype.emptyContents = function() { * Positions the trashcan. * It is positioned in the opposite corner to the corner the * categories/toolbox starts at. - * @param {!Blockly.MetricsManager.UiMetrics} metrics The workspace metrics. - * @param {!Array} savedPositions List of rectangles that + * @param {!MetricsManager.UiMetrics} metrics The workspace metrics. + * @param {!Array} savedPositions List of rectangles that * are already on the workspace. */ -Blockly.Trashcan.prototype.position = function(metrics, savedPositions) { +Trashcan.prototype.position = function(metrics, savedPositions) { // Not yet initialized. if (!this.initialized_) { return; } - var cornerPosition = - Blockly.uiPosition.getCornerOppositeToolbox(this.workspace_, metrics); + const cornerPosition = + uiPosition.getCornerOppositeToolbox(this.workspace_, metrics); - var height = this.BODY_HEIGHT_ + this.LID_HEIGHT_; - var startRect = Blockly.uiPosition.getStartPositionRect( - cornerPosition, new Blockly.utils.Size(this.WIDTH_, height), - this.MARGIN_HORIZONTAL_, this.MARGIN_VERTICAL_, metrics, this.workspace_); + const height = BODY_HEIGHT + LID_HEIGHT; + const startRect = uiPosition.getStartPositionRect( + cornerPosition, new utils.Size(WIDTH, height), MARGIN_HORIZONTAL, + MARGIN_VERTICAL, metrics, this.workspace_); - var verticalPosition = cornerPosition.vertical; - var bumpDirection = - verticalPosition === Blockly.uiPosition.verticalPosition.TOP ? - Blockly.uiPosition.bumpDirection.DOWN : - Blockly.uiPosition.bumpDirection.UP; - var positionRect = Blockly.uiPosition.bumpPositionRect( - startRect, this.MARGIN_VERTICAL_, bumpDirection, savedPositions); + const verticalPosition = cornerPosition.vertical; + const bumpDirection = verticalPosition === uiPosition.verticalPosition.TOP ? + uiPosition.bumpDirection.DOWN : + uiPosition.bumpDirection.UP; + const positionRect = uiPosition.bumpPositionRect( + startRect, MARGIN_VERTICAL, bumpDirection, savedPositions); this.top_ = positionRect.top; this.left_ = positionRect.left; - this.svgGroup_.setAttribute('transform', - 'translate(' + this.left_ + ',' + this.top_ + ')'); + this.svgGroup_.setAttribute( + 'transform', 'translate(' + this.left_ + ',' + this.top_ + ')'); }; /** * Returns the bounding rectangle of the UI element in pixel units relative to * the Blockly injection div. - * @return {?Blockly.utils.Rect} The UI elements’s bounding box. Null if + * @return {?Rect} The UI elements’s bounding box. Null if * bounding box should be ignored by other UI elements. */ -Blockly.Trashcan.prototype.getBoundingRectangle = function() { - var bottom = this.top_ + this.BODY_HEIGHT_ + this.LID_HEIGHT_; - var right = this.left_ + this.WIDTH_; - return new Blockly.utils.Rect(this.top_, bottom, this.left_, right); +Trashcan.prototype.getBoundingRectangle = function() { + const bottom = this.top_ + BODY_HEIGHT + LID_HEIGHT; + const right = this.left_ + WIDTH; + return new Rect(this.top_, bottom, this.left_, right); }; /** * Returns the bounding rectangle of the drag target area in pixel units * relative to viewport. - * @return {?Blockly.utils.Rect} The component's bounding box. Null if drag + * @return {?Rect} The component's bounding box. Null if drag * target area should be ignored. */ -Blockly.Trashcan.prototype.getClientRect = function() { +Trashcan.prototype.getClientRect = function() { if (!this.svgGroup_) { return null; } - var trashRect = this.svgGroup_.getBoundingClientRect(); - var top = trashRect.top + this.SPRITE_TOP_ - this.MARGIN_HOTSPOT_; - var bottom = top + this.LID_HEIGHT_ + this.BODY_HEIGHT_ + - 2 * this.MARGIN_HOTSPOT_; - var left = trashRect.left + this.SPRITE_LEFT_ - this.MARGIN_HOTSPOT_; - var right = left + this.WIDTH_ + 2 * this.MARGIN_HOTSPOT_; - return new Blockly.utils.Rect(top, bottom, left, right); + const trashRect = this.svgGroup_.getBoundingClientRect(); + const top = trashRect.top + SPRITE_TOP - MARGIN_HOTSPOT; + const bottom = top + LID_HEIGHT + BODY_HEIGHT + 2 * MARGIN_HOTSPOT; + const left = trashRect.left + SPRITE_LEFT - MARGIN_HOTSPOT; + const right = left + WIDTH + 2 * MARGIN_HOTSPOT; + return new Rect(top, bottom, left, right); }; /** * Handles when a cursor with a block or bubble is dragged over this drag * target. - * @param {!Blockly.IDraggable} _dragElement The block or bubble currently being + * @param {!IDraggable} _dragElement The block or bubble currently being * dragged. * @override */ -Blockly.Trashcan.prototype.onDragOver = function(_dragElement) { +Trashcan.prototype.onDragOver = function(_dragElement) { this.setLidOpen(this.wouldDelete_); }; /** * Handles when a cursor with a block or bubble exits this drag target. - * @param {!Blockly.IDraggable} _dragElement The block or bubble currently being + * @param {!IDraggable} _dragElement The block or bubble currently being * dragged. * @override */ -Blockly.Trashcan.prototype.onDragExit = function(_dragElement) { +Trashcan.prototype.onDragExit = function(_dragElement) { this.setLidOpen(false); }; /** * Handles when a block or bubble is dropped on this component. * Should not handle delete here. - * @param {!Blockly.IDraggable} _dragElement The block or bubble currently being + * @param {!IDraggable} _dragElement The block or bubble currently being * dragged. * @override */ -Blockly.Trashcan.prototype.onDrop = function(_dragElement) { +Trashcan.prototype.onDrop = function(_dragElement) { setTimeout(this.setLidOpen.bind(this, false), 100); }; @@ -574,7 +537,7 @@ Blockly.Trashcan.prototype.onDrop = function(_dragElement) { * @param {boolean} state True if open. * @package */ -Blockly.Trashcan.prototype.setLidOpen = function(state) { +Trashcan.prototype.setLidOpen = function(state) { if (this.isLidOpen == state) { return; } @@ -587,24 +550,22 @@ Blockly.Trashcan.prototype.setLidOpen = function(state) { * Rotate the lid open or closed by one step. Then wait and recurse. * @private */ -Blockly.Trashcan.prototype.animateLid_ = function() { - var frames = Blockly.Trashcan.ANIMATION_FRAMES_; +Trashcan.prototype.animateLid_ = function() { + const frames = ANIMATION_FRAMES; - var delta = 1 / (frames + 1); + const delta = 1 / (frames + 1); this.lidOpen_ += this.isLidOpen ? delta : -delta; this.lidOpen_ = Math.min(Math.max(this.lidOpen_, this.minOpenness_), 1); - this.setLidAngle_(this.lidOpen_ * Blockly.Trashcan.MAX_LID_ANGLE_); + this.setLidAngle_(this.lidOpen_ * MAX_LID_ANGLE); - var minOpacity = Blockly.Trashcan.OPACITY_MIN_; - var maxOpacity = Blockly.Trashcan.OPACITY_MAX_; // Linear interpolation between min and max. - var opacity = minOpacity + this.lidOpen_ * (maxOpacity - minOpacity); + const opacity = OPACITY_MIN + this.lidOpen_ * (OPACITY_MAX - OPACITY_MIN); this.svgGroup_.style.opacity = opacity; if (this.lidOpen_ > this.minOpenness_ && this.lidOpen_ < 1) { - this.lidTask_ = setTimeout(this.animateLid_.bind(this), - Blockly.Trashcan.ANIMATION_LENGTH_ / frames); + this.lidTask_ = + setTimeout(this.animateLid_.bind(this), ANIMATION_LENGTH / frames); } }; @@ -613,14 +574,14 @@ Blockly.Trashcan.prototype.animateLid_ = function() { * @param {number} lidAngle The angle at which to set the lid. * @private */ -Blockly.Trashcan.prototype.setLidAngle_ = function(lidAngle) { - var openAtRight = - this.workspace_.toolboxPosition == Blockly.utils.toolbox.Position.RIGHT || +Trashcan.prototype.setLidAngle_ = function(lidAngle) { + const openAtRight = + this.workspace_.toolboxPosition == toolbox.Position.RIGHT || (this.workspace_.horizontalLayout && this.workspace_.RTL); - this.svgLid_.setAttribute('transform', 'rotate(' + - (openAtRight ? -lidAngle : lidAngle) + ',' + - (openAtRight ? 4 : this.WIDTH_ - 4) + ',' + - (this.LID_HEIGHT_ - 2) + ')'); + this.svgLid_.setAttribute( + 'transform', + 'rotate(' + (openAtRight ? -lidAngle : lidAngle) + ',' + + (openAtRight ? 4 : WIDTH - 4) + ',' + (LID_HEIGHT - 2) + ')'); }; /** @@ -630,10 +591,10 @@ Blockly.Trashcan.prototype.setLidAngle_ = function(lidAngle) { * 0 and 1. * @private */ -Blockly.Trashcan.prototype.setMinOpenness_ = function(newMin) { +Trashcan.prototype.setMinOpenness_ = function(newMin) { this.minOpenness_ = newMin; if (!this.isLidOpen) { - this.setLidAngle_(newMin * Blockly.Trashcan.MAX_LID_ANGLE_); + this.setLidAngle_(newMin * MAX_LID_ANGLE); } }; @@ -641,14 +602,14 @@ Blockly.Trashcan.prototype.setMinOpenness_ = function(newMin) { * Flip the lid shut. * Called externally after a drag. */ -Blockly.Trashcan.prototype.closeLid = function() { +Trashcan.prototype.closeLid = function() { this.setLidOpen(false); }; /** * Inspect the contents of the trash. */ -Blockly.Trashcan.prototype.click = function() { +Trashcan.prototype.click = function() { if (!this.hasContents_()) { return; } @@ -660,10 +621,10 @@ Blockly.Trashcan.prototype.click = function() { * @param {boolean} trashcanOpen Whether the flyout is opening. * @private */ -Blockly.Trashcan.prototype.fireUiEvent_ = function(trashcanOpen) { - var uiEvent = new (Blockly.Events.get(Blockly.Events.TRASHCAN_OPEN))( - trashcanOpen,this.workspace_.id); - Blockly.Events.fire(uiEvent); +Trashcan.prototype.fireUiEvent_ = function(trashcanOpen) { + const uiEvent = + new (Events.get(Events.TRASHCAN_OPEN))(trashcanOpen, this.workspace_.id); + Events.fire(uiEvent); }; /** @@ -671,7 +632,7 @@ Blockly.Trashcan.prototype.fireUiEvent_ = function(trashcanOpen) { * @param {!Event} e A mouse down event. * @private */ -Blockly.Trashcan.prototype.blockMouseDownWhenOpenable_ = function(e) { +Trashcan.prototype.blockMouseDownWhenOpenable_ = function(e) { if (!this.contentsIsOpen() && this.hasContents_()) { e.stopPropagation(); // Don't start a workspace scroll. } @@ -681,7 +642,7 @@ Blockly.Trashcan.prototype.blockMouseDownWhenOpenable_ = function(e) { * Indicate that the trashcan can be clicked (by opening it) if it has blocks. * @private */ -Blockly.Trashcan.prototype.mouseOver_ = function() { +Trashcan.prototype.mouseOver_ = function() { if (this.hasContents_()) { this.setLidOpen(true); } @@ -692,7 +653,7 @@ Blockly.Trashcan.prototype.mouseOver_ = function() { * blocks). * @private */ -Blockly.Trashcan.prototype.mouseOut_ = function() { +Trashcan.prototype.mouseOut_ = function() { // No need to do a .hasBlocks check here because if it doesn't the trashcan // won't be open in the first place, and setOpen won't run. this.setLidOpen(false); @@ -700,27 +661,27 @@ Blockly.Trashcan.prototype.mouseOut_ = function() { /** * Handle a BLOCK_DELETE event. Adds deleted blocks oldXml to the content array. - * @param {!Blockly.Events.Abstract} event Workspace event. + * @param {!Abstract} event Workspace event. * @private */ -Blockly.Trashcan.prototype.onDelete_ = function(event) { +Trashcan.prototype.onDelete_ = function(event) { if (this.workspace_.options.maxTrashcanContents <= 0) { return; } // Must check that the tagName exists since oldXml can be a DocumentFragment. - if (event.type == Blockly.Events.BLOCK_DELETE && event.oldXml.tagName && + if (event.type == Events.BLOCK_DELETE && event.oldXml.tagName && event.oldXml.tagName.toLowerCase() != 'shadow') { - var cleanedXML = this.cleanBlockXML_(event.oldXml); + const cleanedXML = this.cleanBlockXML_(event.oldXml); if (this.contents_.indexOf(cleanedXML) != -1) { return; } this.contents_.unshift(cleanedXML); while (this.contents_.length > - this.workspace_.options.maxTrashcanContents) { + this.workspace_.options.maxTrashcanContents) { this.contents_.pop(); } - this.setMinOpenness_(this.HAS_BLOCKS_LID_ANGLE_); + this.setMinOpenness_(HAS_BLOCKS_LID_ANGLE); } }; @@ -733,9 +694,9 @@ Blockly.Trashcan.prototype.onDelete_ = function(event) { * attributes. * @private */ -Blockly.Trashcan.prototype.cleanBlockXML_ = function(xml) { - var xmlBlock = xml.cloneNode(true); - var node = xmlBlock; +Trashcan.prototype.cleanBlockXML_ = function(xml) { + const xmlBlock = xml.cloneNode(true); + let node = xmlBlock; while (node) { // Things like text inside tags are still treated as nodes, but they // don't have attributes (or the removeAttribute function) so we can @@ -753,7 +714,7 @@ Blockly.Trashcan.prototype.cleanBlockXML_ = function(xml) { } // Try to go down the tree - var nextNode = node.firstChild || node.nextSibling; + let nextNode = node.firstChild || node.nextSibling; // If we can't go down, try to go back up the tree. if (!nextNode) { nextNode = node.parentNode; @@ -770,5 +731,7 @@ Blockly.Trashcan.prototype.cleanBlockXML_ = function(xml) { } node = nextNode; } - return Blockly.Xml.domToText(xmlBlock); + return Xml.domToText(xmlBlock); }; + +exports = Trashcan; diff --git a/tests/deps.js b/tests/deps.js index c213988b6..3eaba3083 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -175,7 +175,7 @@ goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem'] goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.utils.string']); goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.string']); goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object']); -goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.IAutoHideable', 'Blockly.IPositionable', 'Blockly.Options', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.registry', 'Blockly.uiPosition', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'}); +goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.IAutoHideable', 'Blockly.IPositionable', 'Blockly.Options', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.registry', 'Blockly.uiPosition', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.internalConstants', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.colour', 'Blockly.utils.global', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.userAgent']); goog.addDependency('../../core/utils/aria.js', ['Blockly.utils.aria'], []); goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], [], {'lang': 'es6', 'module': 'goog'});