mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
Move bind/unbind events functions to new file, with example usage.
This commit is contained in:
156
core/blockly.js
156
core/blockly.js
@@ -17,6 +17,7 @@
|
||||
goog.provide('Blockly');
|
||||
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.eventHandling');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.Ui');
|
||||
goog.require('Blockly.Events.UiBase');
|
||||
@@ -104,13 +105,6 @@ Blockly.cache3dSupported_ = null;
|
||||
*/
|
||||
Blockly.parentContainer = null;
|
||||
|
||||
/**
|
||||
* Blockly opaque event data used to unbind events when using
|
||||
* `Blockly.bindEvent_` and `Blockly.bindEventWithChecks_`.
|
||||
* @typedef {!Array.<!Array>}
|
||||
*/
|
||||
Blockly.EventData;
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the specified SVG image.
|
||||
* @param {!SVGElement} svg SVG image.
|
||||
@@ -388,149 +382,6 @@ Blockly.defineBlocksWithJsonArray = function(jsonArray) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind an event to a function call. When calling the function, verifies that
|
||||
* it belongs to the touch stream that is currently being processed, and splits
|
||||
* multitouch events into multiple events as needed.
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @param {boolean=} opt_noCaptureIdentifier True if triggering on this event
|
||||
* should not block execution of other event handlers on this touch or
|
||||
* other simultaneous touches. False by default.
|
||||
* @param {boolean=} opt_noPreventDefault True if triggering on this event
|
||||
* should prevent the default handler. False by default. If
|
||||
* opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be
|
||||
* provided.
|
||||
* @return {!Blockly.EventData} Opaque data that can be passed to unbindEvent_.
|
||||
*/
|
||||
Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
|
||||
opt_noCaptureIdentifier, opt_noPreventDefault) {
|
||||
var handled = false;
|
||||
var wrapFunc = function(e) {
|
||||
var captureIdentifier = !opt_noCaptureIdentifier;
|
||||
// Handle each touch point separately. If the event was a mouse event, this
|
||||
// will hand back an array with one element, which we're fine handling.
|
||||
var events = Blockly.Touch.splitEventByTouches(e);
|
||||
for (var i = 0, event; (event = events[i]); i++) {
|
||||
if (captureIdentifier && !Blockly.Touch.shouldHandleEvent(event)) {
|
||||
continue;
|
||||
}
|
||||
Blockly.Touch.setClientFromTouch(event);
|
||||
if (thisObject) {
|
||||
func.call(thisObject, event);
|
||||
} else {
|
||||
func(event);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
}
|
||||
} else {
|
||||
node.addEventListener(name, wrapFunc, false);
|
||||
bindData.push([node, name, wrapFunc]);
|
||||
|
||||
// Add equivalent touch event.
|
||||
if (name in Blockly.Touch.TOUCH_MAP) {
|
||||
var touchWrapFunc = function(e) {
|
||||
wrapFunc(e);
|
||||
// Calling preventDefault stops the browser from scrolling/zooming the
|
||||
// page.
|
||||
var preventDef = !opt_noPreventDefault;
|
||||
if (handled && preventDef) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, touchWrapFunc, false);
|
||||
bindData.push([node, type, touchWrapFunc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindData;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bind an event to a function call. Handles multitouch events by using the
|
||||
* coordinates of the first changed touch, and doesn't do any safety checks for
|
||||
* simultaneous event processing. In most cases prefer is to use
|
||||
* `Blockly.bindEventWithChecks_`.
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @return {!Blockly.EventData} Opaque data that can be passed to unbindEvent_.
|
||||
*/
|
||||
Blockly.bindEvent_ = function(node, name, thisObject, func) {
|
||||
var wrapFunc = function(e) {
|
||||
if (thisObject) {
|
||||
func.call(thisObject, e);
|
||||
} else {
|
||||
func(e);
|
||||
}
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
}
|
||||
} else {
|
||||
node.addEventListener(name, wrapFunc, false);
|
||||
bindData.push([node, name, wrapFunc]);
|
||||
|
||||
// Add equivalent touch event.
|
||||
if (name in Blockly.Touch.TOUCH_MAP) {
|
||||
var touchWrapFunc = function(e) {
|
||||
// Punt on multitouch events.
|
||||
if (e.changedTouches && e.changedTouches.length == 1) {
|
||||
// Map the touch event's properties to the event.
|
||||
var touchPoint = e.changedTouches[0];
|
||||
e.clientX = touchPoint.clientX;
|
||||
e.clientY = touchPoint.clientY;
|
||||
}
|
||||
wrapFunc(e);
|
||||
|
||||
// Stop the browser from scrolling/zooming the page.
|
||||
e.preventDefault();
|
||||
};
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, touchWrapFunc, false);
|
||||
bindData.push([node, type, touchWrapFunc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unbind one or more events event from a function call.
|
||||
* @param {!Array.<!Array>} bindData Opaque data from bindEvent_.
|
||||
* This list is emptied during the course of calling this function.
|
||||
* @return {!Function} The function call.
|
||||
*/
|
||||
Blockly.unbindEvent_ = function(bindData) {
|
||||
while (bindData.length) {
|
||||
var bindDatum = bindData.pop();
|
||||
var node = bindDatum[0];
|
||||
var name = bindDatum[1];
|
||||
var func = bindDatum[2];
|
||||
node.removeEventListener(name, func, false);
|
||||
}
|
||||
return func;
|
||||
};
|
||||
|
||||
/**
|
||||
* Is the given string a number (includes negative and decimals).
|
||||
* @param {string} str Input string.
|
||||
@@ -632,3 +483,8 @@ Blockly.checkBlockColourConstant_ = function(
|
||||
Blockly.setParentContainer = function(container) {
|
||||
Blockly.parentContainer = container;
|
||||
};
|
||||
|
||||
/** Aliases. */
|
||||
Blockly.bindEvent_ = Blockly.eventHandling.bind;
|
||||
Blockly.unbindEvent_ = Blockly.eventHandling.unbind;
|
||||
Blockly.bindEventWithChecks_ = Blockly.eventHandling.checkAndBind;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
goog.provide('Blockly.Bubble');
|
||||
|
||||
goog.require('Blockly.eventHandling');
|
||||
goog.require('Blockly.Scrollbar');
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
@@ -66,14 +67,14 @@ Blockly.Bubble = function(
|
||||
|
||||
/**
|
||||
* Mouse down on bubbleBack_ event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.eventHandling.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseDownBubbleWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse down on resizeGroup_ event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.eventHandling.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseDownResizeWrapper_ = null;
|
||||
@@ -137,14 +138,14 @@ Blockly.Bubble.ANCHOR_RADIUS = 8;
|
||||
|
||||
/**
|
||||
* Mouse up event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.eventHandling.Data}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.onMouseUpWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.eventHandling.Data}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = null;
|
||||
@@ -155,11 +156,11 @@ Blockly.Bubble.onMouseMoveWrapper_ = null;
|
||||
*/
|
||||
Blockly.Bubble.unbindDragEvents_ = function() {
|
||||
if (Blockly.Bubble.onMouseUpWrapper_) {
|
||||
Blockly.unbindEvent_(Blockly.Bubble.onMouseUpWrapper_);
|
||||
Blockly.eventHandling.unbind(Blockly.Bubble.onMouseUpWrapper_);
|
||||
Blockly.Bubble.onMouseUpWrapper_ = null;
|
||||
}
|
||||
if (Blockly.Bubble.onMouseMoveWrapper_) {
|
||||
Blockly.unbindEvent_(Blockly.Bubble.onMouseMoveWrapper_);
|
||||
Blockly.eventHandling.unbind(Blockly.Bubble.onMouseMoveWrapper_);
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = null;
|
||||
}
|
||||
};
|
||||
@@ -299,10 +300,10 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
|
||||
}
|
||||
|
||||
if (!this.workspace_.options.readOnly) {
|
||||
this.onMouseDownBubbleWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onMouseDownBubbleWrapper_ = Blockly.eventHandling.checkAndBind(
|
||||
this.bubbleBack_, 'mousedown', this, this.bubbleMouseDown_);
|
||||
if (this.resizeGroup_) {
|
||||
this.onMouseDownResizeWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onMouseDownResizeWrapper_ = Blockly.eventHandling.checkAndBind(
|
||||
this.resizeGroup_, 'mousedown', this, this.resizeMouseDown_);
|
||||
}
|
||||
}
|
||||
@@ -387,9 +388,9 @@ Blockly.Bubble.prototype.resizeMouseDown_ = function(e) {
|
||||
new Blockly.utils.Coordinate(
|
||||
this.workspace_.RTL ? -this.width_ : this.width_, this.height_));
|
||||
|
||||
Blockly.Bubble.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(
|
||||
Blockly.Bubble.onMouseUpWrapper_ = Blockly.eventHandling.checkAndBind(
|
||||
document, 'mouseup', this, Blockly.Bubble.bubbleMouseUp_);
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = Blockly.eventHandling.checkAndBind(
|
||||
document, 'mousemove', this, this.resizeMouseMove_);
|
||||
Blockly.hideChaff();
|
||||
// This event has been handled. No need to bubble up to the document.
|
||||
@@ -821,10 +822,10 @@ Blockly.Bubble.prototype.setColour = function(hexColour) {
|
||||
*/
|
||||
Blockly.Bubble.prototype.dispose = function() {
|
||||
if (this.onMouseDownBubbleWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseDownBubbleWrapper_);
|
||||
Blockly.eventHandling.unbind(this.onMouseDownBubbleWrapper_);
|
||||
}
|
||||
if (this.onMouseDownResizeWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseDownResizeWrapper_);
|
||||
Blockly.eventHandling.unbind(this.onMouseDownResizeWrapper_);
|
||||
}
|
||||
Blockly.Bubble.unbindDragEvents_();
|
||||
Blockly.utils.dom.removeNode(this.bubbleGroup_);
|
||||
|
||||
173
core/event_handling.js
Normal file
173
core/event_handling.js
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Browser event handling.
|
||||
* @author fenichel@google.com (Rachel Fenichel)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.eventHandling');
|
||||
|
||||
goog.require('Blockly.Touch');
|
||||
|
||||
|
||||
/**
|
||||
* Blockly opaque event data used to unbind events when using
|
||||
* `Blockly.eventHandling.bindEvent_` and
|
||||
* `Blockly.eventHandling.bindEventWithChecks_`.
|
||||
* @typedef {!Array.<!Array>}
|
||||
*/
|
||||
Blockly.eventHandling.Data;
|
||||
|
||||
/**
|
||||
* Bind an event to a function call. When calling the function, verifies that
|
||||
* it belongs to the touch stream that is currently being processed, and splits
|
||||
* multitouch events into multiple events as needed.
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @param {boolean=} opt_noCaptureIdentifier True if triggering on this event
|
||||
* should not block execution of other event handlers on this touch or
|
||||
* other simultaneous touches. False by default.
|
||||
* @param {boolean=} opt_noPreventDefault True if triggering on this event
|
||||
* should prevent the default handler. False by default. If
|
||||
* opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be
|
||||
* provided.
|
||||
* @return {!Blockly.eventHandling.Data} Opaque data that can be passed to
|
||||
* unbindEvent_.
|
||||
* @public
|
||||
*/
|
||||
Blockly.eventHandling.checkAndBind = function(
|
||||
node, name, thisObject, func, opt_noCaptureIdentifier,
|
||||
opt_noPreventDefault) {
|
||||
var handled = false;
|
||||
var wrapFunc = function(e) {
|
||||
var captureIdentifier = !opt_noCaptureIdentifier;
|
||||
// Handle each touch point separately. If the event was a mouse event, this
|
||||
// will hand back an array with one element, which we're fine handling.
|
||||
var events = Blockly.Touch.splitEventByTouches(e);
|
||||
for (var i = 0, event; (event = events[i]); i++) {
|
||||
if (captureIdentifier && !Blockly.Touch.shouldHandleEvent(event)) {
|
||||
continue;
|
||||
}
|
||||
Blockly.Touch.setClientFromTouch(event);
|
||||
if (thisObject) {
|
||||
func.call(thisObject, event);
|
||||
} else {
|
||||
func(event);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
}
|
||||
} else {
|
||||
node.addEventListener(name, wrapFunc, false);
|
||||
bindData.push([node, name, wrapFunc]);
|
||||
|
||||
// Add equivalent touch event.
|
||||
if (name in Blockly.Touch.TOUCH_MAP) {
|
||||
var touchWrapFunc = function(e) {
|
||||
wrapFunc(e);
|
||||
// Calling preventDefault stops the browser from scrolling/zooming the
|
||||
// page.
|
||||
var preventDef = !opt_noPreventDefault;
|
||||
if (handled && preventDef) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, touchWrapFunc, false);
|
||||
bindData.push([node, type, touchWrapFunc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindData;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bind an event to a function call. Handles multitouch events by using the
|
||||
* coordinates of the first changed touch, and doesn't do any safety checks for
|
||||
* simultaneous event processing. In most cases prefer is to use
|
||||
* `Blockly.bindEventWithChecks_`.
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @return {!Blockly.eventHandling.Data} Opaque data that can be passed to
|
||||
* unbindEvent_.
|
||||
* @public
|
||||
*/
|
||||
Blockly.eventHandling.bind = function(node, name, thisObject, func) {
|
||||
var wrapFunc = function(e) {
|
||||
if (thisObject) {
|
||||
func.call(thisObject, e);
|
||||
} else {
|
||||
func(e);
|
||||
}
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
}
|
||||
} else {
|
||||
node.addEventListener(name, wrapFunc, false);
|
||||
bindData.push([node, name, wrapFunc]);
|
||||
|
||||
// Add equivalent touch event.
|
||||
if (name in Blockly.Touch.TOUCH_MAP) {
|
||||
var touchWrapFunc = function(e) {
|
||||
// Punt on multitouch events.
|
||||
if (e.changedTouches && e.changedTouches.length == 1) {
|
||||
// Map the touch event's properties to the event.
|
||||
var touchPoint = e.changedTouches[0];
|
||||
e.clientX = touchPoint.clientX;
|
||||
e.clientY = touchPoint.clientY;
|
||||
}
|
||||
wrapFunc(e);
|
||||
|
||||
// Stop the browser from scrolling/zooming the page.
|
||||
e.preventDefault();
|
||||
};
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, touchWrapFunc, false);
|
||||
bindData.push([node, type, touchWrapFunc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unbind one or more events event from a function call.
|
||||
* @param {!Blockly.eventHandling.Data} bindData Opaque data from bindEvent_.
|
||||
* This list is emptied during the course of calling this function.
|
||||
* @return {!Function} The function call.
|
||||
* @public
|
||||
*/
|
||||
Blockly.eventHandling.unbind = function(bindData) {
|
||||
while (bindData.length) {
|
||||
var bindDatum = bindData.pop();
|
||||
var node = bindDatum[0];
|
||||
var name = bindDatum[1];
|
||||
var func = bindDatum[2];
|
||||
node.removeEventListener(name, func, false);
|
||||
}
|
||||
return func;
|
||||
};
|
||||
@@ -17,6 +17,7 @@ goog.require('Blockly.blockRendering');
|
||||
goog.require('Blockly.ConnectionDB');
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.ContextMenuRegistry');
|
||||
goog.require('Blockly.eventHandling');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
goog.require('Blockly.Events.ThemeChange');
|
||||
@@ -221,8 +222,8 @@ Blockly.utils.object.inherits(Blockly.WorkspaceSvg, Blockly.Workspace);
|
||||
|
||||
/**
|
||||
* A wrapper function called when a resize event occurs.
|
||||
* You can pass the result to `unbindEvent_`.
|
||||
* @type {Array.<!Array>}
|
||||
* You can pass the result to `eventHandling.unbind`.
|
||||
* @type {?Blockly.eventHandling.Data}
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.resizeHandlerWrapper_ = null;
|
||||
@@ -753,7 +754,8 @@ Blockly.WorkspaceSvg.prototype.getBlockCanvas = function() {
|
||||
|
||||
/**
|
||||
* Save resize handler data so we can delete it later in dispose.
|
||||
* @param {!Array.<!Array>} handler Data that can be passed to unbindEvent_.
|
||||
* @param {!Blockly.eventHandling.Data} handler Data that can be passed to
|
||||
* eventHandling.unbind.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.setResizeHandlerWrapper = function(handler) {
|
||||
this.resizeHandlerWrapper_ = handler;
|
||||
@@ -807,10 +809,10 @@ Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) {
|
||||
{'class': 'blocklyBubbleCanvas'}, this.svgGroup_);
|
||||
|
||||
if (!this.isFlyout) {
|
||||
Blockly.bindEventWithChecks_(this.svgGroup_, 'mousedown', this,
|
||||
this.onMouseDown_, false, true);
|
||||
Blockly.bindEventWithChecks_(this.svgGroup_, 'wheel', this,
|
||||
this.onMouseWheel_);
|
||||
Blockly.eventHandling.checkAndBind(
|
||||
this.svgGroup_, 'mousedown', this, this.onMouseDown_, false, true);
|
||||
Blockly.eventHandling.checkAndBind(
|
||||
this.svgGroup_, 'wheel', this, this.onMouseWheel_);
|
||||
}
|
||||
|
||||
// Determine if there needs to be a category tree, or a simple list of
|
||||
@@ -917,7 +919,7 @@ Blockly.WorkspaceSvg.prototype.dispose = function() {
|
||||
}
|
||||
}
|
||||
if (this.resizeHandlerWrapper_) {
|
||||
Blockly.unbindEvent_(this.resizeHandlerWrapper_);
|
||||
Blockly.eventHandling.unbind(this.resizeHandlerWrapper_);
|
||||
this.resizeHandlerWrapper_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user