From b77c08067829f240999f73c40eb9140e972e051e Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 25 Aug 2016 15:18:53 -0700 Subject: [PATCH] Fix bugs with missing mouseUp events on mutators. Also stop filtering out key presses. --- core/blockly.js | 12 ++++++++++++ core/field.js | 4 +++- core/scrollbar.js | 17 +++++++++++++---- core/utils.js | 11 ++++++++++- core/workspace_svg.js | 1 + 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/core/blockly.js b/core/blockly.js index d01ff28c6..730179867 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -156,6 +156,18 @@ Blockly.resizeSvgContents = function(workspace) { workspace.resizeContents(); }; +/** + * Decide whether Blockly should handle or ignore this event. + * Mouse and touch events require special checks because we only want to deal + * with one touch stream at a time. All other events should always be handled. + * @param {!Event} e The event to check. + * @return {boolean} True if this event should be passed through to the + * registered handler; false if it should be blocked. + */ +Blockly.shouldHandleEvent = function(e) { + return !Blockly.isMouseOrTouchEvent(e) || Blockly.checkTouchIdentifier(e); +}; + /** * Check whether the touch identifier on the event matches the current saved * identifier. If there is no identifier, that means it's a mouse event and diff --git a/core/field.js b/core/field.js index 9e10d253a..72070a588 100644 --- a/core/field.js +++ b/core/field.js @@ -457,7 +457,6 @@ Blockly.Field.prototype.setValue = function(newText) { * @private */ Blockly.Field.prototype.onMouseUp_ = function(e) { - Blockly.touchIdentifier_ = null; if ((goog.userAgent.IPHONE || goog.userAgent.IPAD) && !goog.userAgent.isVersionOrHigher('537.51.2') && e.layerX !== 0 && e.layerY !== 0) { @@ -473,6 +472,9 @@ Blockly.Field.prototype.onMouseUp_ = function(e) { } else if (this.sourceBlock_.isEditable()) { // Non-abstract sub-classes must define a showEditor_ method. this.showEditor_(); + // The field is handling the touch, but we also want the blockSvg onMouseUp + // handler to fire, so we will leave the touch identifier as it is. + // The next onMouseUp is responsible for nulling it out. } }; diff --git a/core/scrollbar.js b/core/scrollbar.js index c0f83f373..6f91889f9 100644 --- a/core/scrollbar.js +++ b/core/scrollbar.js @@ -297,7 +297,7 @@ Blockly.Scrollbar.metricsAreEquivalent_ = function(first, second) { * Unlink from all DOM elements to prevent memory leaks. */ Blockly.Scrollbar.prototype.dispose = function() { - this.onMouseUpHandle_(); + this.cleanUp_(); Blockly.unbindEvent_(this.onMouseDownBarWrapper_); this.onMouseDownBarWrapper_ = null; Blockly.unbindEvent_(this.onMouseDownHandleWrapper_); @@ -599,7 +599,7 @@ Blockly.Scrollbar.prototype.setVisible = function(visible) { * @private */ Blockly.Scrollbar.prototype.onMouseDownBar_ = function(e) { - this.onMouseUpHandle_(); + this.cleanUp_(); if (Blockly.isRightButton(e)) { // Right-click. // Scrollbars have no context menu. @@ -637,7 +637,7 @@ Blockly.Scrollbar.prototype.onMouseDownBar_ = function(e) { * @private */ Blockly.Scrollbar.prototype.onMouseDownHandle_ = function(e) { - Blockly.hideChaff(true); + this.cleanUp_(); if (Blockly.isRightButton(e)) { // Right-click. // Scrollbars have no context menu. @@ -671,11 +671,20 @@ Blockly.Scrollbar.prototype.onMouseMoveHandle_ = function(e) { }; /** - * Stop binding to the global mouseup and mousemove events. + * Release the scrollbar handle and reset state accordingly. * @private */ Blockly.Scrollbar.prototype.onMouseUpHandle_ = function() { Blockly.touchIdentifier_ = null; + this.cleanUp_(); +}; + +/** + * Hide chaff and stop binding to mouseup and mousemove events. Call this to + * wrap up lose ends associated with the scrollbar. + * @private + */ +Blockly.Scrollbar.prototype.cleanUp_ = function() { Blockly.hideChaff(true); if (Blockly.Scrollbar.onMouseUpWrapper_) { Blockly.unbindEvent_(Blockly.Scrollbar.onMouseUpWrapper_); diff --git a/core/utils.js b/core/utils.js index 350333b14..42fd77f1a 100644 --- a/core/utils.js +++ b/core/utils.js @@ -104,7 +104,7 @@ Blockly.bindEvent_ = function(node, name, thisObject, func) { // will hand back an array with one element, which we're fine handling. var events = Blockly.bindEvent_.splitEventByTouches(e); for (var i = 0, event; event = events[i]; i++) { - if (!Blockly.checkTouchIdentifier(event)) { + if (!Blockly.shouldHandleEvent(event)) { return; } Blockly.bindEvent_.setClientFromTouch(event); @@ -163,6 +163,15 @@ Blockly.bindEvent_.setClientFromTouch = function(e) { } }; +/** + * Check whether a given event is a mouse or touch event. + * @param {!Event} e An event. + * @return {boolean} true if it is a mouse or touch event; false otherwise. + */ +Blockly.isMouseOrTouchEvent = function(e) { + return e.type.indexOf('touch') == 0 || e.type.indexOf('mouse') == 0; +}; + /** * Split an event into an array of events, one per changed touch or mouse * point. diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 6979df497..a3c0b5344 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -29,6 +29,7 @@ goog.provide('Blockly.WorkspaceSvg'); // TODO(scr): Fix circular dependencies //goog.require('Blockly.BlockSvg'); goog.require('Blockly.ConnectionDB'); +goog.require('Blockly.constants'); goog.require('Blockly.Options'); goog.require('Blockly.ScrollbarPair'); goog.require('Blockly.Trashcan');