Ignore everything but the first touch stream

This commit is contained in:
Rachel Fenichel
2016-07-20 17:03:06 -07:00
parent d9a3569706
commit 6b7965a727
6 changed files with 73 additions and 12 deletions

View File

@@ -523,7 +523,7 @@ Blockly.BlockSvg.prototype.tab = function(start, forward) {
/**
* Handle a mouse-down on an SVG block.
* @param {!Event} e Mouse down event.
* @param {!Event} e Mouse down event or touch start event.
* @private
*/
Blockly.BlockSvg.prototype.onMouseDown_ = function(e) {
@@ -585,6 +585,7 @@ Blockly.BlockSvg.prototype.onMouseDown_ = function(e) {
* @private
*/
Blockly.BlockSvg.prototype.onMouseUp_ = function(e) {
Blockly.touchIdentifier_ = null;
if (Blockly.dragMode_ != Blockly.DRAG_FREE &&
!Blockly.WidgetDiv.isVisible()) {
Blockly.Events.fire(

View File

@@ -120,6 +120,12 @@ Blockly.dragMode_ = Blockly.DRAG_NONE;
*/
Blockly.onTouchUpWrapper_ = null;
/**
* Which touch events are we currently paying attention to?
* @type {?DOMString}
*/
Blockly.touchIdentifier_ = null;
/**
* Convert a hue (HSV model) into an RGB hex triplet.
* @param {number} hue Hue on a colour wheel (0-360).
@@ -149,6 +155,38 @@ Blockly.resizeSvgContents = function(workspace) {
workspace.resizeContents();
};
/**
* 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
* we'll use the identifier "mouse". This means we won't deal well with
* multiple mice being used at the same time. That seems okay.
* If the current identifier was unset, save the identifier from the
* event.
* @param {!Event} e Mouse event or touch event.
* @return {boolean} Whether the identifier on the event matches the current
* saved identifier.
*/
Blockly.checkTouchIdentifier = function(e) {
var identifier = (e.changedTouches && e.changedTouches.item(0) &&
e.changedTouches.item(0).identifier != undefined) ?
e.changedTouches.item(0).identifier : "mouse";
if (Blockly.touchIdentifier_ != null &&
Blockly.touchIdentifier_ != undefined) {
// We're already tracking some touch/mouse event. Is this from the same
// source?
return Blockly.touchIdentifier_ == identifier;
}
if (e.type == "mousedown" || e.type == "touchstart") {
// No identifier set yet, and this is the start of a drag. Set it and
// return.
Blockly.touchIdentifier_ = identifier;
return true;
}
// There was no identifier yet, but this wasn't a start event so we're going
// to ignore it. This probably means that another drag finished while this
// pointer was down.
return false;
};
/**
* Size the SVG image to completely fill its container. Call this when the view
@@ -188,6 +226,7 @@ Blockly.svgResize = function(workspace) {
* @private
*/
Blockly.onMouseUp_ = function(e) {
Blockly.touchIdentifier_ = null;
var workspace = Blockly.getMainWorkspace();
Blockly.Css.setCursor(Blockly.Css.Cursor.OPEN);
workspace.dragMode_ = Blockly.DRAG_NONE;
@@ -208,9 +247,6 @@ Blockly.onMouseUp_ = function(e) {
* @private
*/
Blockly.onMouseMove_ = function(e) {
if (e.touches && e.touches.length >= 2) {
return; // Multi-touch gestures won't have e.clientX.
}
var workspace = Blockly.getMainWorkspace();
if (workspace.dragMode_ != Blockly.DRAG_NONE) {
var dx = e.clientX - workspace.startDragMouseX;

View File

@@ -460,6 +460,7 @@ 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) {

View File

@@ -791,6 +791,7 @@ Blockly.Flyout.prototype.onMouseDown_ = function(e) {
* @private
*/
Blockly.Flyout.prototype.onMouseUp_ = function(e) {
Blockly.touchIdentifier_ = null;
if (!this.workspace_.isDragging()) {
if (this.autoClose) {
this.createBlockFunc_(Blockly.Flyout.startBlock_)(

View File

@@ -637,7 +637,7 @@ Blockly.Scrollbar.prototype.onMouseDownBar_ = function(e) {
* @private
*/
Blockly.Scrollbar.prototype.onMouseDownHandle_ = function(e) {
this.onMouseUpHandle_();
Blockly.hideChaff(true);
if (Blockly.isRightButton(e)) {
// Right-click.
// Scrollbars have no context menu.
@@ -675,6 +675,7 @@ Blockly.Scrollbar.prototype.onMouseMoveHandle_ = function(e) {
* @private
*/
Blockly.Scrollbar.prototype.onMouseUpHandle_ = function() {
Blockly.touchIdentifier_ = null;
Blockly.hideChaff(true);
if (Blockly.Scrollbar.onMouseUpWrapper_) {
Blockly.unbindEvent_(Blockly.Scrollbar.onMouseUpWrapper_);

View File

@@ -101,23 +101,30 @@ Blockly.hasClass_ = function(element, className) {
Blockly.bindEvent_ = function(node, name, thisObject, func) {
if (thisObject) {
var wrapFunc = function(e) {
if (!Blockly.checkTouchIdentifier(e)) {
return;
}
Blockly.bindEvent_.setClientFromTouch(e);
func.call(thisObject, e);
};
} else {
var wrapFunc = func;
var wrapFunc = function(e) {
if (!Blockly.checkTouchIdentifier(e)) {
return;
}
Blockly.bindEvent_.setClientFromTouch(e);
func(e);
};
}
node.addEventListener(name, wrapFunc, false);
var bindData = [[node, name, wrapFunc]];
// Add equivalent touch event.
if (name in Blockly.bindEvent_.TOUCH_MAP) {
wrapFunc = function(e) {
// Punt on multitouch events.
if (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;
if (!Blockly.checkTouchIdentifier(e)) {
return;
}
Blockly.bindEvent_.setClientFromTouch(e);
func.call(thisObject, e);
// Stop the browser from scrolling/zooming the page.
e.preventDefault();
@@ -145,6 +152,20 @@ if (goog.events.BrowserFeature.TOUCH_ENABLED) {
};
}
/**
* Set an event's clientX and clientY from its first changed touch. Use this to
* make a touch event work in a mouse event handler.
* @param {Event} e A touch event.
*/
Blockly.bindEvent_.setClientFromTouch = function(e) {
if (e.type.indexOf('touch') == 0) {
// Map the touch event's properties to the event.
var touchPoint = e.changedTouches[0];
e.clientX = touchPoint.clientX;
e.clientY = touchPoint.clientY;
}
};
/**
* Unbind one or more events event from a function call.
* @param {!Array.<!Array>} bindData Opaque data from bindEvent_. This list is