mirror of
https://github.com/google/blockly.git
synced 2026-01-09 10:00:09 +01:00
refactor: make Tooltip a class that is accessed via a singleton
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
goog.module('Blockly.Block');
|
||||
|
||||
const Extensions = goog.require('Blockly.Extensions');
|
||||
const Tooltip = goog.require('Blockly.Tooltip');
|
||||
const arrayUtils = goog.require('Blockly.utils.array');
|
||||
const common = goog.require('Blockly.common');
|
||||
const constants = goog.require('Blockly.constants');
|
||||
@@ -51,6 +50,8 @@ const {VariableModel} = goog.requireType('Blockly.VariableModel');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const {Workspace} = goog.requireType('Blockly.Workspace');
|
||||
const {inputTypes} = goog.require('Blockly.inputTypes');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const {tooltipManager, TipInfo} = goog.require('Blockly.Tooltip');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
/** @suppress {extraRequire} */
|
||||
@@ -191,7 +192,7 @@ const Block = function(workspace, prototypeName, opt_id) {
|
||||
* @private
|
||||
*/
|
||||
this.disabled = false;
|
||||
/** @type {!Tooltip.TipInfo} */
|
||||
/** @type {!TipInfo} */
|
||||
this.tooltip = '';
|
||||
/** @type {boolean} */
|
||||
this.contextMenu = true;
|
||||
@@ -990,7 +991,7 @@ Block.prototype.setHelpUrl = function(url) {
|
||||
|
||||
/**
|
||||
* Sets the tooltip for this block.
|
||||
* @param {!Tooltip.TipInfo} newTip The text for the tooltip, a function
|
||||
* @param {!TipInfo} newTip The text for the tooltip, a function
|
||||
* that returns the text for the tooltip, or a parent object whose tooltip
|
||||
* will be used. To not display a tooltip pass the empty string.
|
||||
*/
|
||||
@@ -1003,7 +1004,7 @@ Block.prototype.setTooltip = function(newTip) {
|
||||
* @return {!string} The tooltip text for this block.
|
||||
*/
|
||||
Block.prototype.getTooltip = function() {
|
||||
return Tooltip.getTooltipOfObject(this);
|
||||
return tooltipManager.getTooltipOfObject(this);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
goog.module('Blockly.BlockSvg');
|
||||
|
||||
const ContextMenu = goog.require('Blockly.ContextMenu');
|
||||
const Tooltip = goog.require('Blockly.Tooltip');
|
||||
const blockAnimations = goog.require('Blockly.blockAnimations');
|
||||
const blocks = goog.require('Blockly.serialization.blocks');
|
||||
const browserEvents = goog.require('Blockly.browserEvents');
|
||||
@@ -73,6 +72,7 @@ const {Theme} = goog.requireType('Blockly.Theme');
|
||||
const {Warning} = goog.requireType('Blockly.Warning');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const {WorkspaceSvg} = goog.requireType('Blockly.WorkspaceSvg');
|
||||
const {tooltipManager} = goog.require('Blockly.Tooltip');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
/** @suppress {extraRequire} */
|
||||
@@ -240,7 +240,7 @@ const BlockSvg = function(workspace, prototypeName, opt_id) {
|
||||
|
||||
const svgPath = this.pathObject.svgPath;
|
||||
svgPath.tooltip = this;
|
||||
Tooltip.bindMouseEvents(svgPath);
|
||||
tooltipManager.bindMouseEvents(svgPath);
|
||||
BlockSvg.superClass_.constructor.call(this, workspace, prototypeName, opt_id);
|
||||
|
||||
// Expose this block's ID on its top-level SVG group.
|
||||
@@ -903,8 +903,8 @@ BlockSvg.prototype.dispose = function(healStack, animate) {
|
||||
// The block has already been deleted.
|
||||
return;
|
||||
}
|
||||
Tooltip.dispose();
|
||||
Tooltip.unbindMouseEvents(this.pathObject.svgPath);
|
||||
tooltipManager.dispose();
|
||||
tooltipManager.unbindMouseEvents(this.pathObject.svgPath);
|
||||
dom.startTextWidthCache();
|
||||
// Save the block's workspace temporarily so we can resize the
|
||||
// contents once the block is disposed.
|
||||
|
||||
@@ -24,7 +24,6 @@ const Extensions = goog.require('Blockly.Extensions');
|
||||
const Procedures = goog.require('Blockly.Procedures');
|
||||
const ShortcutItems = goog.require('Blockly.ShortcutItems');
|
||||
const Themes = goog.require('Blockly.Themes');
|
||||
const Tooltip = goog.require('Blockly.Tooltip');
|
||||
const Touch = goog.require('Blockly.Touch');
|
||||
const Variables = goog.require('Blockly.Variables');
|
||||
const VariablesDynamic = goog.require('Blockly.VariablesDynamic');
|
||||
@@ -151,6 +150,7 @@ const {ToolboxCategory} = goog.require('Blockly.ToolboxCategory');
|
||||
const {ToolboxItem} = goog.require('Blockly.ToolboxItem');
|
||||
const {ToolboxSeparator} = goog.require('Blockly.ToolboxSeparator');
|
||||
const {Toolbox} = goog.require('Blockly.Toolbox');
|
||||
const {Tooltip, tooltipManager} = goog.require('Blockly.Tooltip');
|
||||
const {TouchGesture} = goog.require('Blockly.TouchGesture');
|
||||
const {Trashcan} = goog.require('Blockly.Trashcan');
|
||||
const {VariableMap} = goog.require('Blockly.VariableMap');
|
||||
@@ -838,6 +838,7 @@ exports.serialization = {
|
||||
ISerializer: ISerializer,
|
||||
};
|
||||
exports.thrasos = thrasos;
|
||||
exports.tooltipManager = tooltipManager;
|
||||
exports.uiPosition = uiPosition;
|
||||
exports.utils = utils;
|
||||
exports.zelos = zelos;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
goog.module('Blockly.Field');
|
||||
|
||||
const Tooltip = goog.require('Blockly.Tooltip');
|
||||
const WidgetDiv = goog.require('Blockly.WidgetDiv');
|
||||
const Xml = goog.require('Blockly.Xml');
|
||||
const browserEvents = goog.require('Blockly.browserEvents');
|
||||
@@ -55,6 +54,8 @@ const {ShortcutRegistry} = goog.requireType('Blockly.ShortcutRegistry');
|
||||
const {Size} = goog.require('Blockly.utils.Size');
|
||||
const {Svg} = goog.require('Blockly.utils.Svg');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const {TipInfo, tooltipManager} = goog.require('Blockly.Tooltip');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const {WorkspaceSvg} = goog.requireType('Blockly.WorkspaceSvg');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
@@ -98,7 +99,7 @@ const Field = function(value, opt_validator, opt_config) {
|
||||
/**
|
||||
* Used to cache the field's tooltip value if setTooltip is called when the
|
||||
* field is not yet initialized. Is *not* guaranteed to be accurate.
|
||||
* @type {?Tooltip.TipInfo}
|
||||
* @type {?TipInfo}
|
||||
* @private
|
||||
*/
|
||||
this.tooltip_ = null;
|
||||
@@ -411,7 +412,7 @@ Field.prototype.createTextElement_ = function() {
|
||||
* @protected
|
||||
*/
|
||||
Field.prototype.bindEvents_ = function() {
|
||||
Tooltip.bindMouseEvents(this.getClickTarget_());
|
||||
tooltipManager.bindMouseEvents(this.getClickTarget_());
|
||||
this.mouseDownWrapper_ = browserEvents.conditionalBind(
|
||||
this.getClickTarget_(), 'mousedown', this, this.onMouseDown_);
|
||||
};
|
||||
@@ -519,7 +520,7 @@ Field.prototype.loadLegacyState = function(callingClass, state) {
|
||||
Field.prototype.dispose = function() {
|
||||
DropDownDiv.hideIfOwner(this);
|
||||
WidgetDiv.hideIfOwner(this);
|
||||
Tooltip.unbindMouseEvents(this.getClickTarget_());
|
||||
tooltipManager.unbindMouseEvents(this.getClickTarget_());
|
||||
|
||||
if (this.mouseDownWrapper_) {
|
||||
browserEvents.unbind(this.mouseDownWrapper_);
|
||||
@@ -1052,7 +1053,7 @@ Field.prototype.onMouseDown_ = function(e) {
|
||||
|
||||
/**
|
||||
* Sets the tooltip for this field.
|
||||
* @param {?Tooltip.TipInfo} newTip The
|
||||
* @param {?TipInfo} newTip The
|
||||
* text for the tooltip, a function that returns the text for the tooltip, a
|
||||
* parent object whose tooltip will be used, or null to display the tooltip
|
||||
* of the parent block. To not display a tooltip pass the empty string.
|
||||
@@ -1077,10 +1078,10 @@ Field.prototype.setTooltip = function(newTip) {
|
||||
Field.prototype.getTooltip = function() {
|
||||
const clickTarget = this.getClickTarget_();
|
||||
if (clickTarget) {
|
||||
return Tooltip.getTooltipOfObject(clickTarget);
|
||||
return tooltipManager.getTooltipOfObject(clickTarget);
|
||||
}
|
||||
// Field has not been initialized yet. Return stashed this.tooltip_ value.
|
||||
return Tooltip.getTooltipOfObject({tooltip: this.tooltip_});
|
||||
return tooltipManager.getTooltipOfObject({tooltip: this.tooltip_});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
goog.module('Blockly.Flyout');
|
||||
|
||||
const Tooltip = goog.require('Blockly.Tooltip');
|
||||
const Variables = goog.require('Blockly.Variables');
|
||||
const Xml = goog.require('Blockly.Xml');
|
||||
const blocks = goog.require('Blockly.serialization.blocks');
|
||||
@@ -44,6 +43,7 @@ const {Rect} = goog.require('Blockly.utils.Rect');
|
||||
const {ScrollbarPair} = goog.require('Blockly.ScrollbarPair');
|
||||
const {Svg} = goog.require('Blockly.utils.Svg');
|
||||
const {WorkspaceSvg} = goog.require('Blockly.WorkspaceSvg');
|
||||
const {tooltipManager} = goog.require('Blockly.Tooltip');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
/** @suppress {extraRequire} */
|
||||
@@ -836,7 +836,7 @@ class Flyout extends DeleteArea {
|
||||
for (let j = 0; j < this.mats_.length; j++) {
|
||||
const rect = this.mats_[j];
|
||||
if (rect) {
|
||||
Tooltip.unbindMouseEvents(rect);
|
||||
tooltipManager.unbindMouseEvents(rect);
|
||||
dom.removeNode(rect);
|
||||
}
|
||||
}
|
||||
@@ -1041,7 +1041,7 @@ class Flyout extends DeleteArea {
|
||||
},
|
||||
null);
|
||||
rect.tooltip = block;
|
||||
Tooltip.bindMouseEvents(rect);
|
||||
tooltipManager.bindMouseEvents(rect);
|
||||
// Add the rectangles under the blocks, so that the blocks' tooltips work.
|
||||
this.workspace_.getCanvas().insertBefore(rect, block.getSvgRoot());
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
goog.module('Blockly.Gesture');
|
||||
|
||||
const Tooltip = goog.require('Blockly.Tooltip');
|
||||
const Touch = goog.require('Blockly.Touch');
|
||||
const blockAnimations = goog.require('Blockly.blockAnimations');
|
||||
const browserEvents = goog.require('Blockly.browserEvents');
|
||||
@@ -42,6 +41,7 @@ const {WorkspaceDragger} = goog.require('Blockly.WorkspaceDragger');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const {WorkspaceSvg} = goog.requireType('Blockly.WorkspaceSvg');
|
||||
const {Workspace} = goog.require('Blockly.Workspace');
|
||||
const {tooltipManager} = goog.require('Blockly.Tooltip');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.BlockDragger');
|
||||
/** @suppress {extraRequire} */
|
||||
@@ -253,7 +253,7 @@ class Gesture {
|
||||
*/
|
||||
dispose() {
|
||||
Touch.clearTouchIdentifier();
|
||||
Tooltip.unblock();
|
||||
tooltipManager.unblock();
|
||||
// Clear the owner's reference to this gesture.
|
||||
this.creatorWorkspace_.clearGesture();
|
||||
|
||||
@@ -508,7 +508,7 @@ class Gesture {
|
||||
this.startWorkspace_.markFocused();
|
||||
this.mostRecentEvent_ = e;
|
||||
|
||||
Tooltip.block();
|
||||
tooltipManager.block();
|
||||
|
||||
if (this.targetBlock_) {
|
||||
this.targetBlock_.select();
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
goog.module('Blockly.inject');
|
||||
|
||||
const Css = goog.require('Blockly.Css');
|
||||
const Tooltip = goog.require('Blockly.Tooltip');
|
||||
const Touch = goog.require('Blockly.Touch');
|
||||
const WidgetDiv = goog.require('Blockly.WidgetDiv');
|
||||
const aria = goog.require('Blockly.utils.aria');
|
||||
@@ -38,6 +37,7 @@ const {Svg} = goog.require('Blockly.utils.Svg');
|
||||
const {WorkspaceDragSurfaceSvg} = goog.require('Blockly.WorkspaceDragSurfaceSvg');
|
||||
const {WorkspaceSvg} = goog.require('Blockly.WorkspaceSvg');
|
||||
const {Workspace} = goog.require('Blockly.Workspace');
|
||||
const {tooltipManager} = goog.require('Blockly.Tooltip');
|
||||
|
||||
|
||||
/**
|
||||
@@ -193,7 +193,7 @@ const createMainWorkspace = function(
|
||||
common.svgResize(mainWorkspace);
|
||||
WidgetDiv.createDom();
|
||||
DropDownDiv.createDom();
|
||||
Tooltip.createDom();
|
||||
tooltipManager.createDom();
|
||||
return mainWorkspace;
|
||||
};
|
||||
|
||||
|
||||
826
core/tooltip.js
826
core/tooltip.js
@@ -4,217 +4,15 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Library to create tooltips for Blockly.
|
||||
* First, call init() after onload.
|
||||
* Second, set the 'tooltip' property on any SVG element that needs a tooltip.
|
||||
* If the tooltip is a string, then that message will be displayed.
|
||||
* If the tooltip is an SVG element, then that object's tooltip will be used.
|
||||
* Third, call bindMouseEvents(e) passing the SVG element.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Library to create tooltips for Blockly.
|
||||
* First, call init() after onload.
|
||||
* Second, set the 'tooltip' property on any SVG element that needs a tooltip.
|
||||
* If the tooltip is a string, then that message will be displayed.
|
||||
* If the tooltip is an SVG element, then that object's tooltip will be used.
|
||||
* Third, call bindMouseEvents(e) passing the SVG element.
|
||||
* @namespace Blockly.Tooltip
|
||||
*/
|
||||
goog.module('Blockly.Tooltip');
|
||||
|
||||
const blocklyString = goog.require('Blockly.utils.string');
|
||||
const browserEvents = goog.require('Blockly.browserEvents');
|
||||
const common = goog.require('Blockly.common');
|
||||
const deprecation = goog.require('Blockly.utils.deprecation');
|
||||
|
||||
|
||||
/**
|
||||
* A type which can define a tooltip.
|
||||
* Either a string, an object containing a tooltip property, or a function which
|
||||
* returns either a string, or another arbitrarily nested function which
|
||||
* eventually unwinds to a string.
|
||||
* @typedef {string|{tooltip}|function(): (string|!Function)}
|
||||
* @alias Blockly.Tooltip.TipInfo
|
||||
*/
|
||||
let TipInfo;
|
||||
exports.TipInfo = TipInfo;
|
||||
|
||||
/**
|
||||
* Is a tooltip currently showing?
|
||||
* @type {boolean}
|
||||
*/
|
||||
let visible = false;
|
||||
|
||||
/**
|
||||
* Returns whether or not a tooltip is showing
|
||||
* @returns {boolean} True if a tooltip is showing
|
||||
* @alias Blockly.Tooltip.isVisible
|
||||
*/
|
||||
const isVisible = function() {
|
||||
return visible;
|
||||
};
|
||||
exports.isVisible = isVisible;
|
||||
|
||||
Object.defineProperties(exports, {
|
||||
/**
|
||||
* Is a tooltip currently showing?
|
||||
* @name Blockly.Tooltip.visible
|
||||
* @type {boolean}
|
||||
* @deprecated Use Blockly.Tooltip.isVisible() instead. (September
|
||||
* 2021)
|
||||
* @suppress {checkTypes}
|
||||
*/
|
||||
visible: {
|
||||
get: function() {
|
||||
deprecation.warn(
|
||||
'Blockly.Tooltip.visible', 'September 2021', 'September 2022',
|
||||
'Blockly.Tooltip.isVisible()');
|
||||
return isVisible();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Is someone else blocking the tooltip from being shown?
|
||||
* @type {boolean}
|
||||
*/
|
||||
let blocked = false;
|
||||
|
||||
/**
|
||||
* Maximum width (in characters) of a tooltip.
|
||||
* @alias Blockly.Tooltip.LIMIT
|
||||
*/
|
||||
const LIMIT = 50;
|
||||
exports.LIMIT = LIMIT;
|
||||
|
||||
/**
|
||||
* PID of suspended thread to clear tooltip on mouse out.
|
||||
*/
|
||||
let mouseOutPid = 0;
|
||||
|
||||
/**
|
||||
* PID of suspended thread to show the tooltip.
|
||||
*/
|
||||
let showPid = 0;
|
||||
|
||||
/**
|
||||
* Last observed X location of the mouse pointer (freezes when tooltip appears).
|
||||
*/
|
||||
let lastX = 0;
|
||||
|
||||
/**
|
||||
* Last observed Y location of the mouse pointer (freezes when tooltip appears).
|
||||
*/
|
||||
let lastY = 0;
|
||||
|
||||
/**
|
||||
* Current element being pointed at.
|
||||
* @type {Element}
|
||||
*/
|
||||
let element = null;
|
||||
|
||||
/**
|
||||
* Once a tooltip has opened for an element, that element is 'poisoned' and
|
||||
* cannot respawn a tooltip until the pointer moves over a different element.
|
||||
* @type {Element}
|
||||
*/
|
||||
let poisonedElement = null;
|
||||
|
||||
/**
|
||||
* Horizontal offset between mouse cursor and tooltip.
|
||||
* @alias Blockly.Tooltip.OFFSET_X
|
||||
*/
|
||||
const OFFSET_X = 0;
|
||||
exports.OFFSET_X = OFFSET_X;
|
||||
|
||||
/**
|
||||
* Vertical offset between mouse cursor and tooltip.
|
||||
* @alias Blockly.Tooltip.OFFSET_Y
|
||||
*/
|
||||
const OFFSET_Y = 10;
|
||||
exports.OFFSET_Y = OFFSET_Y;
|
||||
|
||||
/**
|
||||
* Radius mouse can move before killing tooltip.
|
||||
* @alias Blockly.Tooltip.RADIUS_OK
|
||||
*/
|
||||
const RADIUS_OK = 10;
|
||||
exports.RADIUS_OK = RADIUS_OK;
|
||||
|
||||
/**
|
||||
* Delay before tooltip appears.
|
||||
* @alias Blockly.Tooltip.HOVER_MS
|
||||
*/
|
||||
const HOVER_MS = 750;
|
||||
exports.HOVER_MS = HOVER_MS;
|
||||
|
||||
/**
|
||||
* Horizontal padding between tooltip and screen edge.
|
||||
* @alias Blockly.Tooltip.MARGINS
|
||||
*/
|
||||
const MARGINS = 5;
|
||||
exports.MARGINS = MARGINS;
|
||||
|
||||
/**
|
||||
* The HTML container. Set once by createDom.
|
||||
* @type {Element}
|
||||
*/
|
||||
let DIV = null;
|
||||
|
||||
/**
|
||||
* Returns the HTML tooltip container.
|
||||
* @returns {Element} The HTML tooltip container.
|
||||
* @alias Blockly.Tooltip.getDiv
|
||||
*/
|
||||
const getDiv = function() {
|
||||
return DIV;
|
||||
};
|
||||
exports.getDiv = getDiv;
|
||||
|
||||
Object.defineProperties(exports, {
|
||||
/**
|
||||
* The HTML container. Set once by createDom.
|
||||
* @name Blockly.Tooltip.DIV
|
||||
* @type {Element}
|
||||
* @deprecated Use Blockly.Tooltip.getDiv() and .setDiv().
|
||||
* (September 2021)
|
||||
* @suppress {checkTypes}
|
||||
*/
|
||||
DIV: {
|
||||
get: function() {
|
||||
deprecation.warn(
|
||||
'Blockly.Tooltip.DIV', 'September 2021', 'September 2022',
|
||||
'Blockly.Tooltip.getDiv()');
|
||||
return getDiv();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns the tooltip text for the given element.
|
||||
* @param {?Object} object The object to get the tooltip text of.
|
||||
* @return {string} The tooltip text of the element.
|
||||
* @alias Blockly.Tooltip.getTooltipOfObject
|
||||
*/
|
||||
const getTooltipOfObject = function(object) {
|
||||
const obj = getTargetObject(object);
|
||||
if (obj) {
|
||||
let tooltip = obj.tooltip;
|
||||
while (typeof tooltip === 'function') {
|
||||
tooltip = tooltip();
|
||||
}
|
||||
if (typeof tooltip !== 'string') {
|
||||
throw Error('Tooltip function must return a string.');
|
||||
}
|
||||
return tooltip;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
exports.getTooltipOfObject = getTooltipOfObject;
|
||||
|
||||
/**
|
||||
* Returns the target object that the given object is targeting for its
|
||||
* tooltip. Could be the object itself.
|
||||
@@ -234,261 +32,421 @@ const getTargetObject = function(obj) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the tooltip div and inject it onto the page.
|
||||
* @alias Blockly.Tooltip.createDom
|
||||
* Class to create tooltips. This class represents a singleton and should not be
|
||||
* constructed outside of this file. Use `Blockly.tooltipManager` to interact
|
||||
* with the singleton. First, call createDom() after onload. Second, set the
|
||||
* 'tooltip' property on any SVG element that needs a tooltip. If the tooltip is
|
||||
* a string, or a function that returns a string, then that message will be
|
||||
* displayed. If the tooltip is an SVG element, then that object's tooltip will
|
||||
* be used. Third, call bindMouseEvents(e) passing the SVG element.
|
||||
*/
|
||||
const createDom = function() {
|
||||
if (DIV) {
|
||||
return; // Already created.
|
||||
}
|
||||
// Create an HTML container for popup overlays (e.g. editor widgets).
|
||||
DIV = document.createElement('div');
|
||||
DIV.className = 'blocklyTooltipDiv';
|
||||
const container = common.getParentContainer() || document.body;
|
||||
container.appendChild(DIV);
|
||||
};
|
||||
exports.createDom = createDom;
|
||||
class Tooltip {
|
||||
/**
|
||||
* Class to create tooltips. Do not instantiate this class outside of this
|
||||
* file.
|
||||
* @protected
|
||||
* @alias Blockly.Tooltip
|
||||
*/
|
||||
constructor() {
|
||||
/**
|
||||
* Is a tooltip currently showing?
|
||||
* @type {boolean}
|
||||
* @protected
|
||||
*/
|
||||
this.visible = false;
|
||||
|
||||
/**
|
||||
* Binds the required mouse events onto an SVG element.
|
||||
* @param {!Element} element SVG element onto which tooltip is to be bound.
|
||||
* @alias Blockly.Tooltip.bindMouseEvents
|
||||
*/
|
||||
const bindMouseEvents = function(element) {
|
||||
element.mouseOverWrapper_ =
|
||||
browserEvents.bind(element, 'mouseover', null, onMouseOver);
|
||||
element.mouseOutWrapper_ =
|
||||
browserEvents.bind(element, 'mouseout', null, onMouseOut);
|
||||
/**
|
||||
* Is someone else blocking the tooltip from being shown?
|
||||
* @type {boolean}
|
||||
* @protected
|
||||
*/
|
||||
this.blocked = false;
|
||||
|
||||
// Don't use bindEvent_ for mousemove since that would create a
|
||||
// corresponding touch handler, even though this only makes sense in the
|
||||
// context of a mouseover/mouseout.
|
||||
element.addEventListener('mousemove', onMouseMove, false);
|
||||
};
|
||||
exports.bindMouseEvents = bindMouseEvents;
|
||||
/**
|
||||
* PID of suspended thread to clear tooltip on mouse out.
|
||||
* @protected
|
||||
*/
|
||||
this.mouseOutPid = 0;
|
||||
|
||||
/**
|
||||
* Unbinds tooltip mouse events from the SVG element.
|
||||
* @param {!Element} element SVG element onto which tooltip is bound.
|
||||
* @alias Blockly.Tooltip.unbindMouseEvents
|
||||
*/
|
||||
const unbindMouseEvents = function(element) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
browserEvents.unbind(element.mouseOverWrapper_);
|
||||
browserEvents.unbind(element.mouseOutWrapper_);
|
||||
element.removeEventListener('mousemove', onMouseMove);
|
||||
};
|
||||
exports.unbindMouseEvents = unbindMouseEvents;
|
||||
/**
|
||||
* PID of suspended thread to show the tooltip.
|
||||
* @protected
|
||||
*/
|
||||
this.showPid = 0;
|
||||
|
||||
/**
|
||||
* Hide the tooltip if the mouse is over a different object.
|
||||
* Initialize the tooltip to potentially appear for this object.
|
||||
* @param {!Event} e Mouse event.
|
||||
*/
|
||||
const onMouseOver = function(e) {
|
||||
if (blocked) {
|
||||
// Someone doesn't want us to show tooltips.
|
||||
return;
|
||||
}
|
||||
// If the tooltip is an object, treat it as a pointer to the next object in
|
||||
// the chain to look at. Terminate when a string or function is found.
|
||||
const newElement = /** @type {Element} */ (getTargetObject(e.currentTarget));
|
||||
if (element !== newElement) {
|
||||
hide();
|
||||
poisonedElement = null;
|
||||
element = newElement;
|
||||
}
|
||||
// Forget about any immediately preceding mouseOut event.
|
||||
clearTimeout(mouseOutPid);
|
||||
};
|
||||
/**
|
||||
* Last observed X location of the mouse pointer (freezes when tooltip
|
||||
* appears).
|
||||
* @protected
|
||||
*/
|
||||
this.lastX = 0;
|
||||
|
||||
/**
|
||||
* Hide the tooltip if the mouse leaves the object and enters the workspace.
|
||||
* @param {!Event} _e Mouse event.
|
||||
*/
|
||||
const onMouseOut = function(_e) {
|
||||
if (blocked) {
|
||||
// Someone doesn't want us to show tooltips.
|
||||
return;
|
||||
}
|
||||
// Moving from one element to another (overlapping or with no gap) generates
|
||||
// a mouseOut followed instantly by a mouseOver. Fork off the mouseOut
|
||||
// event and kill it if a mouseOver is received immediately.
|
||||
// This way the task only fully executes if mousing into the void.
|
||||
mouseOutPid = setTimeout(function() {
|
||||
element = null;
|
||||
poisonedElement = null;
|
||||
hide();
|
||||
}, 1);
|
||||
clearTimeout(showPid);
|
||||
};
|
||||
/**
|
||||
* Last observed Y location of the mouse pointer (freezes when tooltip
|
||||
* appears).
|
||||
* @protected
|
||||
*/
|
||||
this.lastY = 0;
|
||||
|
||||
/**
|
||||
* When hovering over an element, schedule a tooltip to be shown. If a tooltip
|
||||
* is already visible, hide it if the mouse strays out of a certain radius.
|
||||
* @param {!Event} e Mouse event.
|
||||
*/
|
||||
const onMouseMove = function(e) {
|
||||
if (!element || !element.tooltip) {
|
||||
// No tooltip here to show.
|
||||
return;
|
||||
} else if (blocked) {
|
||||
// Someone doesn't want us to show tooltips. We are probably handling a
|
||||
// user gesture, such as a click or drag.
|
||||
return;
|
||||
/**
|
||||
* Current element being pointed at.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.element = null;
|
||||
|
||||
/**
|
||||
* Once a tooltip has opened for an element, that element is 'poisoned' and
|
||||
* cannot respawn a tooltip until the pointer moves over a different
|
||||
* element.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.poisonedElement = null;
|
||||
|
||||
/**
|
||||
* Maximum width (in characters) of a tooltip.
|
||||
* @alias Blockly.Tooltip.LIMIT
|
||||
*/
|
||||
this.LIMIT = 50;
|
||||
|
||||
/**
|
||||
* Horizontal offset between mouse cursor and tooltip.
|
||||
* @alias Blockly.Tooltip.OFFSET_X
|
||||
*/
|
||||
this.OFFSET_X = 0;
|
||||
|
||||
/**
|
||||
* Vertical offset between mouse cursor and tooltip.
|
||||
* @alias Blockly.Tooltip.OFFSET_Y
|
||||
*/
|
||||
this.OFFSET_Y = 10;
|
||||
|
||||
/**
|
||||
* Radius mouse can move before killing tooltip.
|
||||
* @alias Blockly.Tooltip.RADIUS_OK
|
||||
*/
|
||||
this.RADIUS_OK = 10;
|
||||
|
||||
/**
|
||||
* Delay before tooltip appears.
|
||||
* @alias Blockly.Tooltip.HOVER_MS
|
||||
*/
|
||||
this.HOVER_MS = 750;
|
||||
|
||||
/**
|
||||
* Horizontal padding between tooltip and screen edge.
|
||||
* @alias Blockly.Tooltip.MARGINS
|
||||
*/
|
||||
this.MARGINS = 5;
|
||||
|
||||
/**
|
||||
* The HTML container. Set once by createDom.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.DIV = null;
|
||||
}
|
||||
if (visible) {
|
||||
// Compute the distance between the mouse position when the tooltip was
|
||||
// shown and the current mouse position. Pythagorean theorem.
|
||||
const dx = lastX - e.pageX;
|
||||
const dy = lastY - e.pageY;
|
||||
if (Math.sqrt(dx * dx + dy * dy) > RADIUS_OK) {
|
||||
hide();
|
||||
|
||||
/**
|
||||
* Returns the tooltip text for the given element.
|
||||
* @param {?Object} object The object to get the tooltip text of.
|
||||
* @return {string} The tooltip text of the element.
|
||||
* @alias Blockly.Tooltip.getTooltipOfObject
|
||||
*/
|
||||
getTooltipOfObject(object) {
|
||||
const obj = getTargetObject(object);
|
||||
if (obj) {
|
||||
let tooltip = obj.tooltip;
|
||||
while (typeof tooltip === 'function') {
|
||||
tooltip = tooltip();
|
||||
}
|
||||
if (typeof tooltip !== 'string') {
|
||||
throw Error('Tooltip function must return a string.');
|
||||
}
|
||||
return tooltip;
|
||||
}
|
||||
} else if (poisonedElement !== element) {
|
||||
// The mouse moved, clear any previously scheduled tooltip.
|
||||
clearTimeout(showPid);
|
||||
// Maybe this time the mouse will stay put. Schedule showing of tooltip.
|
||||
lastX = e.pageX;
|
||||
lastY = e.pageY;
|
||||
showPid = setTimeout(show, HOVER_MS);
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of the tooltip.
|
||||
* @alias Blockly.Tooltip.dispose
|
||||
* @package
|
||||
*/
|
||||
const dispose = function() {
|
||||
element = null;
|
||||
poisonedElement = null;
|
||||
hide();
|
||||
};
|
||||
exports.dispose = dispose;
|
||||
|
||||
/**
|
||||
* Hide the tooltip.
|
||||
* @alias Blockly.Tooltip.hide
|
||||
*/
|
||||
const hide = function() {
|
||||
if (visible) {
|
||||
visible = false;
|
||||
if (DIV) {
|
||||
DIV.style.display = 'none';
|
||||
/**
|
||||
* Create the tooltip div and inject it onto the page.
|
||||
* @alias Blockly.Tooltip.createDom
|
||||
*/
|
||||
createDom() {
|
||||
if (this.DIV) {
|
||||
return; // Already created.
|
||||
}
|
||||
// Create an HTML container for popup overlays (e.g. editor widgets).
|
||||
this.DIV = document.createElement('div');
|
||||
this.DIV.className = 'blocklyTooltipDiv';
|
||||
const container = common.getParentContainer() || document.body;
|
||||
container.appendChild(this.DIV);
|
||||
}
|
||||
if (showPid) {
|
||||
clearTimeout(showPid);
|
||||
}
|
||||
};
|
||||
exports.hide = hide;
|
||||
/**
|
||||
* Binds the required mouse events onto an SVG element.
|
||||
* @param {!Element} element SVG element onto which tooltip is to be bound.
|
||||
* @alias Blockly.Tooltip.bindMouseEvents
|
||||
*/
|
||||
bindMouseEvents(element) {
|
||||
element.mouseOverWrapper_ =
|
||||
browserEvents.bind(element, 'mouseover', this, this.onMouseOver);
|
||||
element.mouseOutWrapper_ =
|
||||
browserEvents.bind(element, 'mouseout', this, this.onMouseOut);
|
||||
|
||||
/**
|
||||
* Hide any in-progress tooltips and block showing new tooltips until the next
|
||||
* call to unblock().
|
||||
* @alias Blockly.Tooltip.block
|
||||
* @package
|
||||
*/
|
||||
const block = function() {
|
||||
hide();
|
||||
blocked = true;
|
||||
};
|
||||
exports.block = block;
|
||||
|
||||
/**
|
||||
* Unblock tooltips: allow them to be scheduled and shown according to their own
|
||||
* logic.
|
||||
* @alias Blockly.Tooltip.unblock
|
||||
* @package
|
||||
*/
|
||||
const unblock = function() {
|
||||
blocked = false;
|
||||
};
|
||||
exports.unblock = unblock;
|
||||
|
||||
/**
|
||||
* Renders the tooltip content into the tooltip div.
|
||||
*/
|
||||
const renderContent = function() {
|
||||
let tip = getTooltipOfObject(element);
|
||||
tip = blocklyString.wrap(tip, LIMIT);
|
||||
// Create new text, line by line.
|
||||
const lines = tip.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const div = document.createElement('div');
|
||||
div.appendChild(document.createTextNode(lines[i]));
|
||||
DIV.appendChild(div);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the coordinates for the tooltip div, taking into account the edges of the screen to
|
||||
* prevent showing the tooltip offscreen.
|
||||
* @param {boolean} rtl True if the tooltip should be in right-to-left layout.
|
||||
* @returns {{x: number, y: number}} Coordinates at which the tooltip div should be placed.
|
||||
*/
|
||||
const getPosition = function(rtl) {
|
||||
// Position the tooltip just below the cursor.
|
||||
const windowWidth = document.documentElement.clientWidth;
|
||||
const windowHeight = document.documentElement.clientHeight;
|
||||
|
||||
let anchorX = lastX;
|
||||
if (rtl) {
|
||||
anchorX -= OFFSET_X + DIV.offsetWidth;
|
||||
} else {
|
||||
anchorX += OFFSET_X;
|
||||
// Don't use bindEvent_ for mousemove since that would create a
|
||||
// corresponding touch handler, even though this only makes sense in the
|
||||
// context of a mouseover/mouseout.
|
||||
element.addEventListener('mousemove', (e) => {
|
||||
this.onMouseMove(e);
|
||||
}, false);
|
||||
}
|
||||
|
||||
let anchorY = lastY + OFFSET_Y;
|
||||
if (anchorY + DIV.offsetHeight > windowHeight + window.scrollY) {
|
||||
// Falling off the bottom of the screen; shift the tooltip up.
|
||||
anchorY -= DIV.offsetHeight + 2 * OFFSET_Y;
|
||||
/**
|
||||
* Unbinds tooltip mouse events from the SVG element.
|
||||
* @param {!Element} element SVG element onto which tooltip is bound.
|
||||
* @alias Blockly.Tooltip.unbindMouseEvents
|
||||
*/
|
||||
unbindMouseEvents(element) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
browserEvents.unbind(element.mouseOverWrapper_);
|
||||
browserEvents.unbind(element.mouseOutWrapper_);
|
||||
element.removeEventListener('mousemove', this.onMouseMove);
|
||||
}
|
||||
|
||||
if (rtl) {
|
||||
// Prevent falling off left edge in RTL mode.
|
||||
anchorX = Math.max(MARGINS - window.scrollX, anchorX);
|
||||
} else {
|
||||
if (anchorX + DIV.offsetWidth >
|
||||
windowWidth + window.scrollX - 2 * MARGINS) {
|
||||
// Falling off the right edge of the screen;
|
||||
// clamp the tooltip on the edge.
|
||||
anchorX = windowWidth - DIV.offsetWidth - 2 * MARGINS;
|
||||
/**
|
||||
* Hide the tooltip if the mouse is over a different object.
|
||||
* Initialize the tooltip to potentially appear for this object.
|
||||
* @param {!Event} e Mouse event.
|
||||
* @protected
|
||||
*/
|
||||
onMouseOver(e) {
|
||||
if (this.blocked) {
|
||||
// Someone doesn't want us to show tooltips.
|
||||
return;
|
||||
}
|
||||
// If the tooltip is an object, treat it as a pointer to the next object in
|
||||
// the chain to look at. Terminate when a string or function is found.
|
||||
const newElement =
|
||||
/** @type {Element} */ (getTargetObject(e.currentTarget));
|
||||
if (this.element !== newElement) {
|
||||
this.hide();
|
||||
this.poisonedElement = null;
|
||||
this.element = newElement;
|
||||
}
|
||||
// Forget about any immediately preceding mouseOut event.
|
||||
clearTimeout(this.mouseOutPid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the tooltip if the mouse leaves the object and enters the workspace.
|
||||
* @param {!Event} _e Mouse event.
|
||||
* @protected
|
||||
*/
|
||||
onMouseOut(_e) {
|
||||
if (this.blocked) {
|
||||
// Someone doesn't want us to show tooltips.
|
||||
return;
|
||||
}
|
||||
// Moving from one element to another (overlapping or with no gap) generates
|
||||
// a mouseOut followed instantly by a mouseOver. Fork off the mouseOut
|
||||
// event and kill it if a mouseOver is received immediately.
|
||||
// This way the task only fully executes if mousing into the void.
|
||||
this.mouseOutPid = setTimeout(() => {
|
||||
this.element = null;
|
||||
this.poisonedElement = null;
|
||||
this.hide();
|
||||
}, 1);
|
||||
clearTimeout(this.showPid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When hovering over an element, schedule a tooltip to be shown. If a
|
||||
* tooltip is already visible, hide it if the mouse strays out of a certain
|
||||
* radius.
|
||||
* @param {!Event} e Mouse event.
|
||||
* @protected
|
||||
*/
|
||||
onMouseMove(e) {
|
||||
if (!this.element || !this.element.tooltip) {
|
||||
// No tooltip here to show.
|
||||
return;
|
||||
} else if (this.blocked) {
|
||||
// Someone doesn't want us to show tooltips. We are probably handling a
|
||||
// user gesture, such as a click or drag.
|
||||
return;
|
||||
}
|
||||
if (this.visible) {
|
||||
// Compute the distance between the mouse position when the tooltip was
|
||||
// shown and the current mouse position. Pythagorean theorem.
|
||||
const dx = this.lastX - e.pageX;
|
||||
const dy = this.lastY - e.pageY;
|
||||
if (Math.sqrt(dx * dx + dy * dy) > this.RADIUS_OK) {
|
||||
this.hide();
|
||||
}
|
||||
} else if (this.poisonedElement !== this.element) {
|
||||
// The mouse moved, clear any previously scheduled tooltip.
|
||||
clearTimeout(this.showPid);
|
||||
// Maybe this time the mouse will stay put. Schedule showing of tooltip.
|
||||
this.lastX = e.pageX;
|
||||
this.lastY = e.pageY;
|
||||
this.showPid = setTimeout(() => {
|
||||
this.show();
|
||||
}, this.HOVER_MS);
|
||||
}
|
||||
}
|
||||
|
||||
return {x: anchorX, y: anchorY};
|
||||
};
|
||||
/**
|
||||
* Dispose of the tooltip.
|
||||
* @alias Blockly.Tooltip.dispose
|
||||
* @package
|
||||
*/
|
||||
dispose() {
|
||||
this.element = null;
|
||||
this.poisonedElement = null;
|
||||
this.hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the tooltip.
|
||||
* @alias Blockly.Tooltip.hide
|
||||
*/
|
||||
hide() {
|
||||
if (this.visible) {
|
||||
this.visible = false;
|
||||
if (this.DIV) {
|
||||
this.DIV.style.display = 'none';
|
||||
}
|
||||
}
|
||||
if (this.showPid) {
|
||||
clearTimeout(this.showPid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide any in-progress tooltips and block showing new tooltips until the next
|
||||
* call to unblock().
|
||||
* @alias Blockly.Tooltip.block
|
||||
* @package
|
||||
*/
|
||||
block() {
|
||||
this.hide();
|
||||
this.blocked = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unblock tooltips: allow them to be scheduled and shown according to their
|
||||
* own logic.
|
||||
* @alias Blockly.Tooltip.unblock
|
||||
* @package
|
||||
*/
|
||||
unblock() {
|
||||
this.blocked = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the tooltip content into the tooltip div.
|
||||
* @protected
|
||||
*/
|
||||
renderContent() {
|
||||
let tip = this.getTooltipOfObject(this.element);
|
||||
tip = blocklyString.wrap(tip, this.LIMIT);
|
||||
// Create new text, line by line.
|
||||
const lines = tip.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const div = document.createElement('div');
|
||||
div.appendChild(document.createTextNode(lines[i]));
|
||||
this.DIV.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the coordinates for the tooltip div, taking into account the edges of
|
||||
* the screen to prevent showing the tooltip offscreen.
|
||||
* @param {boolean} rtl True if the tooltip should be in right-to-left layout.
|
||||
* @returns {{x: number, y: number}} Coordinates at which the tooltip div
|
||||
* should be placed.
|
||||
* @protected
|
||||
*/
|
||||
getPosition(rtl) {
|
||||
// Position the tooltip just below the cursor.
|
||||
const windowWidth = document.documentElement.clientWidth;
|
||||
const windowHeight = document.documentElement.clientHeight;
|
||||
|
||||
let anchorX = this.lastX;
|
||||
if (rtl) {
|
||||
anchorX -= this.OFFSET_X + this.DIV.offsetWidth;
|
||||
} else {
|
||||
anchorX += this.OFFSET_X;
|
||||
}
|
||||
|
||||
let anchorY = this.lastY + this.OFFSET_Y;
|
||||
if (anchorY + this.DIV.offsetHeight > windowHeight + window.scrollY) {
|
||||
// Falling off the bottom of the screen; shift the tooltip up.
|
||||
anchorY -= this.DIV.offsetHeight + 2 * this.OFFSET_Y;
|
||||
}
|
||||
|
||||
if (rtl) {
|
||||
// Prevent falling off left edge in RTL mode.
|
||||
anchorX = Math.max(this.MARGINS - window.scrollX, anchorX);
|
||||
} else {
|
||||
if (anchorX + this.DIV.offsetWidth >
|
||||
windowWidth + window.scrollX - 2 * this.MARGINS) {
|
||||
// Falling off the right edge of the screen;
|
||||
// clamp the tooltip on the edge.
|
||||
anchorX = windowWidth - this.DIV.offsetWidth - 2 * this.MARGINS;
|
||||
}
|
||||
}
|
||||
|
||||
return {x: anchorX, y: anchorY};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the tooltip and show it.
|
||||
*/
|
||||
show() {
|
||||
if (this.blocked) {
|
||||
// Someone doesn't want us to show tooltips.
|
||||
return;
|
||||
}
|
||||
this.poisonedElement = this.element;
|
||||
if (!this.DIV) {
|
||||
return;
|
||||
}
|
||||
// Erase all existing text.
|
||||
this.DIV.textContent = '';
|
||||
|
||||
// Add new content.
|
||||
this.renderContent();
|
||||
|
||||
// Display the tooltip.
|
||||
const rtl = /** @type {{RTL: boolean}} */ (this.element).RTL;
|
||||
this.DIV.style.direction = rtl ? 'rtl' : 'ltr';
|
||||
this.DIV.style.display = 'block';
|
||||
this.visible = true;
|
||||
|
||||
const {x, y} = this.getPosition(rtl);
|
||||
this.DIV.style.left = x + 'px';
|
||||
this.DIV.style.top = y + 'px';
|
||||
}
|
||||
}
|
||||
exports.Tooltip = Tooltip;
|
||||
|
||||
|
||||
/**
|
||||
* Create the tooltip and show it.
|
||||
* A type which can define a tooltip.
|
||||
* Either a string, an object containing a tooltip property, or a function which
|
||||
* returns either a string, or another arbitrarily nested function which
|
||||
* eventually unwinds to a string.
|
||||
* @typedef {string|{tooltip}|function(): (string|!Function)}
|
||||
* @alias Blockly.Tooltip.TipInfo
|
||||
*/
|
||||
const show = function() {
|
||||
if (blocked) {
|
||||
// Someone doesn't want us to show tooltips.
|
||||
return;
|
||||
}
|
||||
poisonedElement = element;
|
||||
if (!DIV) {
|
||||
return;
|
||||
}
|
||||
// Erase all existing text.
|
||||
DIV.textContent = '';
|
||||
let TipInfo;
|
||||
exports.TipInfo = TipInfo;
|
||||
|
||||
// Add new content.
|
||||
renderContent();
|
||||
|
||||
// Display the tooltip.
|
||||
const rtl = /** @type {{RTL: boolean}} */ (element).RTL;
|
||||
DIV.style.direction = rtl ? 'rtl' : 'ltr';
|
||||
DIV.style.display = 'block';
|
||||
visible = true;
|
||||
|
||||
const {x, y} = getPosition(rtl);
|
||||
DIV.style.left = x + 'px';
|
||||
DIV.style.top = y + 'px';
|
||||
};
|
||||
// Singleton tooltip manager. Only interact with this object.
|
||||
// TODO(maribethb): Get this class from the registry.
|
||||
exports.tooltipManager = new Tooltip();
|
||||
|
||||
@@ -18,7 +18,6 @@ goog.module('Blockly.WorkspaceSvg');
|
||||
const ContextMenu = goog.require('Blockly.ContextMenu');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const Procedures = goog.requireType('Blockly.Procedures');
|
||||
const Tooltip = goog.require('Blockly.Tooltip');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const Variables = goog.requireType('Blockly.Variables');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
@@ -102,6 +101,7 @@ const {WorkspaceDragSurfaceSvg} = goog.requireType('Blockly.WorkspaceDragSurface
|
||||
const {Workspace} = goog.require('Blockly.Workspace');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const {ZoomControls} = goog.requireType('Blockly.ZoomControls');
|
||||
const {tooltipManager} = goog.require('Blockly.Tooltip');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
/** @suppress {extraRequire} */
|
||||
@@ -2673,7 +2673,7 @@ class WorkspaceSvg extends Workspace {
|
||||
* @param {boolean=} opt_onlyClosePopups Whether only popups should be closed.
|
||||
*/
|
||||
hideChaff(opt_onlyClosePopups) {
|
||||
Tooltip.hide();
|
||||
tooltipManager.hide();
|
||||
WidgetDiv.hide();
|
||||
DropDownDiv.hideWithoutAnimation();
|
||||
|
||||
|
||||
@@ -80,11 +80,9 @@
|
||||
"./core/utils/math.js",
|
||||
"./core/utils/array.js",
|
||||
"./core/workspace.js",
|
||||
"./core/events/events_block_delete.js",
|
||||
"./core/keyboard_nav/basic_cursor.js",
|
||||
"./core/keyboard_nav/tab_navigate_cursor.js",
|
||||
"./core/warning.js",
|
||||
"./core/events/events_bubble_open.js",
|
||||
"./core/comment.js",
|
||||
"./core/events/events_block_drag.js",
|
||||
"./core/events/events_block_move.js",
|
||||
@@ -99,21 +97,22 @@
|
||||
"./core/zoom_controls.js",
|
||||
"./core/workspace_drag_surface_svg.js",
|
||||
"./core/events/events_selected.js",
|
||||
"./core/events/events_comment_move.js",
|
||||
"./core/events/events_comment_delete.js",
|
||||
"./core/events/events_comment_create.js",
|
||||
"./core/events/events_comment_base.js",
|
||||
"./core/events/events_comment_change.js",
|
||||
"./core/workspace_comment.js",
|
||||
"./core/interfaces/i_movable.js",
|
||||
"./core/interfaces/i_selectable.js",
|
||||
"./core/interfaces/i_copyable.js",
|
||||
"./core/events/events_comment_delete.js",
|
||||
"./core/events/events_comment_change.js",
|
||||
"./core/workspace_comment.js",
|
||||
"./core/events/events_comment_create.js",
|
||||
"./core/events/events_comment_base.js",
|
||||
"./core/events/events_comment_move.js",
|
||||
"./core/workspace_comment_svg.js",
|
||||
"./core/workspace_audio.js",
|
||||
"./core/events/events_trashcan_open.js",
|
||||
"./core/sprites.js",
|
||||
"./core/drag_target.js",
|
||||
"./core/delete_area.js",
|
||||
"./core/events/events_block_delete.js",
|
||||
"./core/positionable_helpers.js",
|
||||
"./core/trashcan.js",
|
||||
"./core/touch_gesture.js",
|
||||
@@ -197,7 +196,7 @@
|
||||
"./core/events/events_var_delete.js",
|
||||
"./core/variable_map.js",
|
||||
"./core/names.js",
|
||||
"./core/events/events_ui_base.js",
|
||||
"./core/tooltip.js",
|
||||
"./core/events/events_marker_move.js",
|
||||
"./core/renderers/common/marker_svg.js",
|
||||
"./core/keyboard_nav/marker.js",
|
||||
@@ -226,6 +225,8 @@
|
||||
"./core/utils/svg_paths.js",
|
||||
"./core/renderers/common/constants.js",
|
||||
"./core/field.js",
|
||||
"./core/events/events_ui_base.js",
|
||||
"./core/events/events_bubble_open.js",
|
||||
"./core/procedures.js",
|
||||
"./core/workspace_svg.js",
|
||||
"./core/utils/rect.js",
|
||||
@@ -237,11 +238,10 @@
|
||||
"./core/bubble_dragger.js",
|
||||
"./core/connection_type.js",
|
||||
"./core/internal_constants.js",
|
||||
"./core/block_animations.js",
|
||||
"./core/gesture.js",
|
||||
"./core/touch.js",
|
||||
"./core/browser_events.js",
|
||||
"./core/tooltip.js",
|
||||
"./core/block_animations.js",
|
||||
"./core/block_svg.js",
|
||||
"./core/events/events_block_base.js",
|
||||
"./core/events/events_block_change.js",
|
||||
@@ -253,7 +253,6 @@
|
||||
"./core/extensions.js",
|
||||
"./core/block.js",
|
||||
"./core/utils/string.js",
|
||||
"./core/utils/object.js",
|
||||
"./core/dialog.js",
|
||||
"./core/events/events_var_base.js",
|
||||
"./core/events/events_var_create.js",
|
||||
|
||||
@@ -223,7 +223,7 @@ goog.addDependency('../../core/toolbox/collapsible_category.js', ['Blockly.Colla
|
||||
goog.addDependency('../../core/toolbox/separator.js', ['Blockly.ToolboxSeparator'], ['Blockly.Css', 'Blockly.ToolboxItem', 'Blockly.registry', 'Blockly.utils.dom', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/toolbox/toolbox.js', ['Blockly.Toolbox'], ['Blockly.BlockSvg', 'Blockly.CollapsibleToolboxCategory', 'Blockly.ComponentManager', 'Blockly.Css', 'Blockly.DeleteArea', 'Blockly.Events.ToolboxItemSelect', 'Blockly.Events.utils', 'Blockly.IAutoHideable', 'Blockly.IKeyboardAccessible', 'Blockly.IStyleable', 'Blockly.IToolbox', 'Blockly.Options', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.common', 'Blockly.registry', 'Blockly.utils.KeyCodes', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem'], ['Blockly.IToolboxItem', 'Blockly.utils.idGenerator'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.common', 'Blockly.utils.deprecation', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.common', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.utils.global', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.utils.Coordinate'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events.TrashcanOpen', 'Blockly.Events.utils', 'Blockly.IAutoHideable', 'Blockly.IPositionable', 'Blockly.Options', 'Blockly.browserEvents', 'Blockly.registry', 'Blockly.sprite', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'});
|
||||
|
||||
Reference in New Issue
Block a user