mirror of
https://github.com/google/blockly.git
synced 2026-01-11 02:47:09 +01:00
Fire function events instead of DOM events.
This commit is contained in:
@@ -125,6 +125,11 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
|
||||
var xmlBlock = Blockly.Xml.blockToDom(this);
|
||||
Blockly.Events.fire(new Blockly.Events.Create(workspace, xmlBlock));
|
||||
}
|
||||
// Bind an onchange function, if it exists.
|
||||
if (goog.isFunction(this.onchange)) {
|
||||
this.onchangeWrapper_ = this.onchange.bind(this);
|
||||
this.workspace.addChangeListener(this.onchangeWrapper_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -162,6 +167,10 @@ Blockly.Block.prototype.colour_ = '#000000';
|
||||
* all children of this block.
|
||||
*/
|
||||
Blockly.Block.prototype.dispose = function(healStack) {
|
||||
// Terminate onchange event calls.
|
||||
if (this.onchangeWrapper_) {
|
||||
this.workspace.removeChangeListener(this.onchangeWrapper_)
|
||||
}
|
||||
this.unplug(healStack);
|
||||
if (Blockly.Events.isEnabled() && !this.isShadow()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Delete(this));
|
||||
|
||||
@@ -112,11 +112,6 @@ Blockly.BlockSvg.prototype.initSvg = function() {
|
||||
Blockly.bindEvent_(this.getSvgRoot(), 'touchstart', null,
|
||||
function(e) {Blockly.longStart_(e, thisBlock);});
|
||||
}
|
||||
// Bind an onchange function, if it exists.
|
||||
if (goog.isFunction(this.onchange) && !this.eventsInit_) {
|
||||
this.onchangeWrapper_ = Blockly.bindEvent_(this.workspace.getCanvas(),
|
||||
'blocklyWorkspaceChange', this, this.onchange);
|
||||
}
|
||||
this.eventsInit_ = true;
|
||||
|
||||
if (!this.getSvgRoot().parentNode) {
|
||||
@@ -1094,11 +1089,6 @@ Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_LTR =
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.dispose = function(healStack, animate) {
|
||||
Blockly.Field.startCache();
|
||||
// Terminate onchange event calls.
|
||||
if (this.onchangeWrapper_) {
|
||||
Blockly.unbindEvent_(this.onchangeWrapper_);
|
||||
this.onchangeWrapper_ = null;
|
||||
}
|
||||
// If this block is being dragged, unlink the mouse events.
|
||||
if (Blockly.selected == this) {
|
||||
Blockly.terminateDrag_();
|
||||
|
||||
@@ -591,9 +591,6 @@ Blockly.Connection.prototype.closest = function(maxLimit, dx, dy) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Connection.prototype.checkType_ = function(otherConnection) {
|
||||
if (Blockly.OPPOSITE_TYPE[this.type] != otherConnection.type) {
|
||||
return false;
|
||||
}
|
||||
// Don't split a connection where both sides are immovable.
|
||||
var thisTargetBlock = this.targetBlock();
|
||||
if (thisTargetBlock && !thisTargetBlock.isMovable() &&
|
||||
|
||||
@@ -64,12 +64,6 @@ Blockly.Events.MOVE = 'move';
|
||||
*/
|
||||
Blockly.Events.FIRE_QUEUE_ = [];
|
||||
|
||||
/**
|
||||
* PID of next scheduled firing.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Events.fireTask_ = null;
|
||||
|
||||
/**
|
||||
* Create a custom event and fire it.
|
||||
* @param {!Blockly.Events.Abstract} event Custom data for event.
|
||||
@@ -78,10 +72,11 @@ Blockly.Events.fire = function(event) {
|
||||
if (!Blockly.Events.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
Blockly.Events.FIRE_QUEUE_.push(event);
|
||||
if (Blockly.Events.fireTask_ === null) {
|
||||
Blockly.Events.fireTask_ = setTimeout(Blockly.Events.fireNow_, 0);
|
||||
if (Blockly.Events.FIRE_QUEUE_.length == 0) {
|
||||
// Schedule a firing of the event queue.
|
||||
setTimeout(Blockly.Events.fireNow_, 0);
|
||||
}
|
||||
Blockly.Events.FIRE_QUEUE_.push(event);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -91,21 +86,10 @@ Blockly.Events.fire = function(event) {
|
||||
Blockly.Events.fireNow_ = function() {
|
||||
var queue = Blockly.Events.filter_(Blockly.Events.FIRE_QUEUE_);
|
||||
Blockly.Events.FIRE_QUEUE_.length = 0;
|
||||
Blockly.Events.fireTask_ = null;
|
||||
for (var i = 0, detail; detail = queue[i]; i++) {
|
||||
console.log(detail);
|
||||
var workspace = Blockly.Workspace.getById(detail.workspaceId);
|
||||
if (workspace && workspace.rendered) {
|
||||
// Create a custom event in a browser-compatible way.
|
||||
if (typeof CustomEvent == 'function') {
|
||||
// W3
|
||||
var evt = new CustomEvent('blocklyWorkspaceChange', {'detail': detail});
|
||||
} else {
|
||||
// MSIE
|
||||
var evt = document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent(eventName, false, false, detail);
|
||||
}
|
||||
workspace.getCanvas().dispatchEvent(evt);
|
||||
for (var i = 0, event; event = queue[i]; i++) {
|
||||
var workspace = Blockly.Workspace.getById(event.workspaceId);
|
||||
if (workspace) {
|
||||
workspace.fireChangeListener(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,9 +154,8 @@ Blockly.FieldTextInput.prototype.showEditor_ = function(opt_quietInput) {
|
||||
// Bind to keyPress -- repeatedly resize when holding down a key.
|
||||
htmlInput.onKeyPressWrapper_ =
|
||||
Blockly.bindEvent_(htmlInput, 'keypress', this, this.onHtmlInputChange_);
|
||||
htmlInput.onWorkspaceChangeWrapper_ =
|
||||
Blockly.bindEvent_(workspace.getCanvas(), 'blocklyWorkspaceChange', this,
|
||||
this.resizeEditor_);
|
||||
htmlInput.onWorkspaceChangeWrapper_ = this.resizeEditor_.bind(this);
|
||||
workspace.addChangeListener(htmlInput.onWorkspaceChangeWrapper_);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -279,7 +278,8 @@ Blockly.FieldTextInput.prototype.widgetDispose_ = function() {
|
||||
Blockly.unbindEvent_(htmlInput.onKeyDownWrapper_);
|
||||
Blockly.unbindEvent_(htmlInput.onKeyUpWrapper_);
|
||||
Blockly.unbindEvent_(htmlInput.onKeyPressWrapper_);
|
||||
Blockly.unbindEvent_(htmlInput.onWorkspaceChangeWrapper_);
|
||||
thisField.sourceBlock_.workspace.removeChangeListener(
|
||||
htmlInput.onWorkspaceChangeWrapper_);
|
||||
Blockly.FieldTextInput.htmlInput_ = null;
|
||||
// Delete style properties.
|
||||
var style = Blockly.WidgetDiv.DIV.style;
|
||||
|
||||
@@ -155,9 +155,8 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) {
|
||||
Array.prototype.push.apply(this.eventWrappers_,
|
||||
Blockly.bindEvent_(this.svgGroup_, 'wheel', this, this.wheel_));
|
||||
if (!this.autoClose) {
|
||||
Array.prototype.push.apply(this.eventWrappers_,
|
||||
Blockly.bindEvent_(this.targetWorkspace_.getCanvas(),
|
||||
'blocklyWorkspaceChange', this, this.filterForCapacity_));
|
||||
this.filterWrapper_ = this.filterForCapacity_.bind(this);
|
||||
this.targetWorkspace_.addChangeListener(this.filterWrapper_);
|
||||
}
|
||||
// Dragging the flyout up and down.
|
||||
Array.prototype.push.apply(this.eventWrappers_,
|
||||
@@ -171,6 +170,10 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) {
|
||||
Blockly.Flyout.prototype.dispose = function() {
|
||||
this.hide();
|
||||
Blockly.unbindEvent_(this.eventWrappers_);
|
||||
if (this.filterWrapper_) {
|
||||
this.targetWorkspace_.removeChangeListener(this.filterWrapper_);
|
||||
this.filterWrapper_ = null;
|
||||
}
|
||||
if (this.scrollbar_) {
|
||||
this.scrollbar_.dispose();
|
||||
this.scrollbar_ = null;
|
||||
@@ -345,7 +348,7 @@ Blockly.Flyout.prototype.hide = function() {
|
||||
}
|
||||
this.listeners_.length = 0;
|
||||
if (this.reflowWrapper_) {
|
||||
Blockly.unbindEvent_(this.reflowWrapper_);
|
||||
this.workspace_.removeChangeListener(this.reflowWrapper_);
|
||||
this.reflowWrapper_ = null;
|
||||
}
|
||||
// Do NOT delete the blocks here. Wait until Flyout.show.
|
||||
@@ -466,8 +469,8 @@ Blockly.Flyout.prototype.show = function(xmlList) {
|
||||
|
||||
// Fire a resize event to update the flyout's scrollbar.
|
||||
Blockly.fireUiEventNow(window, 'resize');
|
||||
this.reflowWrapper_ = Blockly.bindEvent_(this.workspace_.getCanvas(),
|
||||
'blocklyWorkspaceChange', this, this.reflow);
|
||||
this.reflowWrapper_ = this.reflow.bind(this);
|
||||
this.workspace_.addChangeListener(this.reflowWrapper_);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -232,17 +232,14 @@ Blockly.Mutator.prototype.setVisible = function(visible) {
|
||||
if (this.block_.saveConnections) {
|
||||
var thisMutator = this;
|
||||
this.block_.saveConnections(this.rootBlock_);
|
||||
this.sourceListener_ = Blockly.bindEvent_(
|
||||
this.block_.workspace.getCanvas(),
|
||||
'blocklyWorkspaceChange', null,
|
||||
function() {
|
||||
thisMutator.block_.saveConnections(thisMutator.rootBlock_)
|
||||
});
|
||||
this.sourceListener_ = function() {
|
||||
thisMutator.block_.saveConnections(thisMutator.rootBlock_)
|
||||
};
|
||||
this.block_.workspace.addChangeListener(this.sourceListener_);
|
||||
}
|
||||
this.resizeBubble_();
|
||||
// When the mutator's workspace changes, update the source block.
|
||||
Blockly.bindEvent_(this.workspace_.getCanvas(), 'blocklyWorkspaceChange',
|
||||
this, this.workspaceChanged_);
|
||||
this.workspace_.addChangeListener(this.workspaceChanged_.bind(this));
|
||||
this.updateColour();
|
||||
} else {
|
||||
// Dispose of the bubble.
|
||||
@@ -255,7 +252,7 @@ Blockly.Mutator.prototype.setVisible = function(visible) {
|
||||
this.workspaceWidth_ = 0;
|
||||
this.workspaceHeight_ = 0;
|
||||
if (this.sourceListener_) {
|
||||
Blockly.unbindEvent_(this.sourceListener_);
|
||||
this.block_.workspace.removeChangeListener(this.sourceListener_);
|
||||
this.sourceListener_ = null;
|
||||
}
|
||||
}
|
||||
@@ -283,7 +280,8 @@ Blockly.Mutator.prototype.workspaceChanged_ = function() {
|
||||
|
||||
// When the mutator's workspace changes, update the source block.
|
||||
if (this.rootBlock_.workspace == this.workspace_) {
|
||||
var oldMutation = this.block_.mutationToDom();
|
||||
var oldMutationDom = this.block_.mutationToDom();
|
||||
var oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
|
||||
// Switch off rendering while the source block is rebuilt.
|
||||
var savedRendered = this.block_.rendered;
|
||||
this.block_.rendered = false;
|
||||
@@ -293,9 +291,9 @@ Blockly.Mutator.prototype.workspaceChanged_ = function() {
|
||||
this.block_.rendered = savedRendered;
|
||||
// Mutation may have added some elements that need initalizing.
|
||||
this.block_.initSvg();
|
||||
var newMutation = this.block_.mutationToDom();
|
||||
if (Blockly.Xml.domToText(oldMutation) !=
|
||||
Blockly.Xml.domToText(newMutation)) {
|
||||
var newMutationDom = this.block_.mutationToDom();
|
||||
var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
|
||||
if (oldMutation != newMutation) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
this.block_, 'mutation', null, oldMutation, newMutation));
|
||||
goog.Timer.callOnce(
|
||||
|
||||
@@ -45,6 +45,8 @@ Blockly.Workspace = function(opt_options) {
|
||||
this.RTL = !!this.options.RTL;
|
||||
/** @type {!Array.<!Blockly.Block>} */
|
||||
this.topBlocks_ = [];
|
||||
/** @type {!Array.<!Function>} */
|
||||
this.listeners_ = [];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -58,6 +60,7 @@ Blockly.Workspace.prototype.rendered = false;
|
||||
* Unlink from all DOM elements to prevent memory leaks.
|
||||
*/
|
||||
Blockly.Workspace.prototype.dispose = function() {
|
||||
this.listeners_.length = 0;
|
||||
this.clear();
|
||||
// Remove from workspace database.
|
||||
delete Blockly.Workspace.WorkspaceDB_[this.id];
|
||||
@@ -191,6 +194,38 @@ Blockly.Workspace.prototype.remainingCapacity = function() {
|
||||
return this.options.maxBlocks - this.getAllBlocks().length;
|
||||
};
|
||||
|
||||
/**
|
||||
* When something in this workspace changes, call a function.
|
||||
* @param {!Function} func Function to call.
|
||||
* @return {!Function} Function that can be passed to
|
||||
* removeChangeListener.
|
||||
*/
|
||||
Blockly.Workspace.prototype.addChangeListener = function(func) {
|
||||
this.listeners_.push(func);
|
||||
return func;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop listening for this workspace's changes.
|
||||
* @param {Function} func Function to stop calling.
|
||||
*/
|
||||
Blockly.Workspace.prototype.removeChangeListener = function(func) {
|
||||
var i = this.listeners_.indexOf(func);
|
||||
if (i != -1) {
|
||||
this.listeners_.splice(i, 1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fire a change event.
|
||||
* @param {!Blockly.Events.Abstract} event Event to fire.
|
||||
*/
|
||||
Blockly.Workspace.prototype.fireChangeListener = function(event) {
|
||||
for (var i = 0, func; func = this.listeners_[i]; i++) {
|
||||
func(event);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Database of all workspaces.
|
||||
* @private
|
||||
@@ -208,3 +243,7 @@ Blockly.Workspace.getById = function(id) {
|
||||
|
||||
// Export symbols that would otherwise be renamed by Closure compiler.
|
||||
Blockly.Workspace.prototype['clear'] = Blockly.Workspace.prototype.clear;
|
||||
Blockly.Workspace.prototype['addChangeListener'] =
|
||||
Blockly.Workspace.prototype.addChangeListener;
|
||||
Blockly.Workspace.prototype['removeChangeListener'] =
|
||||
Blockly.Workspace.prototype.removeChangeListener;
|
||||
|
||||
@@ -59,13 +59,6 @@ Blockly.WorkspaceSvg = function(options) {
|
||||
* @const
|
||||
*/
|
||||
this.SOUNDS_ = Object.create(null);
|
||||
|
||||
/**
|
||||
* Opaque data that can be passed to Blockly.unbindEvent_.
|
||||
* @type {!Array.<!Array>}
|
||||
* @private
|
||||
*/
|
||||
this.eventWrappers_ = [];
|
||||
};
|
||||
goog.inherits(Blockly.WorkspaceSvg, Blockly.Workspace);
|
||||
|
||||
@@ -212,7 +205,6 @@ Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) {
|
||||
Blockly.WorkspaceSvg.prototype.dispose = function() {
|
||||
// Stop rerendering.
|
||||
this.rendered = false;
|
||||
Blockly.unbindEvent_(this.eventWrappers_);
|
||||
Blockly.WorkspaceSvg.superClass_.dispose.call(this);
|
||||
if (this.svgGroup_) {
|
||||
goog.dom.removeNode(this.svgGroup_);
|
||||
@@ -904,31 +896,6 @@ Blockly.WorkspaceSvg.prototype.updateToolbox = function(tree) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* When something in this workspace changes, call a function.
|
||||
* @param {!Function} func Function to call.
|
||||
* @return {!Array.<!Array>} Opaque data that can be passed to
|
||||
* removeChangeListener.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.addChangeListener = function(func) {
|
||||
var wrapper = Blockly.bindEvent_(this.getCanvas(),
|
||||
'blocklyWorkspaceChange', null, func);
|
||||
Array.prototype.push.apply(this.eventWrappers_, wrapper);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop listening for this workspace's changes.
|
||||
* @param {!Array.<!Array>} bindData Opaque data from addChangeListener.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.removeChangeListener = function(bindData) {
|
||||
Blockly.unbindEvent_(bindData);
|
||||
var i = this.eventWrappers_.indexOf(bindData);
|
||||
if (i != -1) {
|
||||
this.eventWrappers_.splice(i, 1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark this workspace as the currently focused main workspace.
|
||||
*/
|
||||
@@ -1005,7 +972,7 @@ Blockly.WorkspaceSvg.prototype.zoomCenter = function(type) {
|
||||
Blockly.WorkspaceSvg.prototype.zoomToFit = function() {
|
||||
var workspaceBBox = this.svgBackground_.getBBox();
|
||||
var blocksBBox = this.svgBlockCanvas_.getBBox();
|
||||
var workspaceWidth = workspaceBBox.width - this.toolbox_.width -
|
||||
var workspaceWidth = workspaceBBox.width - this.toolbox_.width -
|
||||
Blockly.Scrollbar.scrollbarThickness;
|
||||
var workspaceHeight = workspaceBBox.height -
|
||||
Blockly.Scrollbar.scrollbarThickness;
|
||||
@@ -1106,7 +1073,3 @@ Blockly.WorkspaceSvg.prototype.updateGridPattern_ = function() {
|
||||
// Export symbols that would otherwise be renamed by Closure compiler.
|
||||
Blockly.WorkspaceSvg.prototype['setVisible'] =
|
||||
Blockly.WorkspaceSvg.prototype.setVisible;
|
||||
Blockly.WorkspaceSvg.prototype['addChangeListener'] =
|
||||
Blockly.WorkspaceSvg.prototype.addChangeListener;
|
||||
Blockly.WorkspaceSvg.prototype['removeChangeListener'] =
|
||||
Blockly.WorkspaceSvg.prototype.removeChangeListener;
|
||||
|
||||
Reference in New Issue
Block a user