Bug 732774 - [b2g] Cancel the click event when a panning action is running only if the touch happens on the panned area r=fabrice
authorVivien Nicolas <21@vingtetun.org>
Mon, 05 Mar 2012 09:55:51 +0100
changeset 88454 c0eead4d1e3f495208ec953fff373cfcb474f87f
parent 88453 d8002cdcc6fb2aa097c534285f76a2c74abbf3e8
child 88455 4be83b3f229bdb2d6400851e39193adce45e8256
push id157
push userMs2ger@gmail.com
push dateWed, 07 Mar 2012 19:27:10 +0000
reviewersfabrice
bugs732774
milestone13.0a1
Bug 732774 - [b2g] Cancel the click event when a panning action is running only if the touch happens on the panned area r=fabrice
b2g/chrome/content/webapi.js
--- a/b2g/chrome/content/webapi.js
+++ b/b2g/chrome/content/webapi.js
@@ -178,59 +178,64 @@ const ContentPanning = {
       case 'mouseup':
         this.onTouchEnd(evt);
         break;
       case 'click':
         evt.stopPropagation();
         evt.preventDefault();
         
         let target = evt.target;
-        let view = target.defaultView || target.ownerDocument.defaultView;
+        let view = target.ownerDocument ? target.ownerDocument.defaultView
+                                        : target;
         view.removeEventListener('click', this, true, true);
         break;
     }
   },
 
   position: new Point(0 , 0),
 
   onTouchStart: function cp_onTouchStart(evt) {
     this.dragging = true;
     this.panning = false;
 
+    let oldTarget = this.target;
+    [this.target, this.scrollCallback] = this.getPannable(evt.target);
+
     // If there is a pan animation running (from a previous pan gesture) and
     // the user touch back the screen, stop this animation immediatly and
-    // prevent the possible click action.
+    // prevent the possible click action if the touch happens on the same
+    // target.
+    this.preventNextClick = false;
     if (KineticPanning.active) {
       KineticPanning.stop();
-      this.preventNextClick = true;
+
+      if (oldTarget && oldTarget == this.target)
+        this.preventNextClick = true;
     }
 
-    this.scrollCallback = this.getPannable(evt.target);
-    this.targetDocument = evt.target.ownerDocument;
 
     this.position.set(evt.screenX, evt.screenY);
     KineticPanning.record(new Point(0, 0), evt.timeStamp);
   },
 
   onTouchEnd: function cp_onTouchEnd(evt) {
     if (!this.dragging)
       return;
     this.dragging = false;
 
     this.onTouchMove(evt);
 
     let click = evt.detail;
-    if (click && (this.panning || this.preventNextClick)) {
-      let target = evt.target;
-      let view = target.defaultView || target.ownerDocument.defaultView;
+    if (this.target && click && (this.panning || this.preventNextClick)) {
+      let target = this.target;
+      let view = target.ownerDocument ? target.ownerDocument.defaultView
+                                      : target;
       view.addEventListener('click', this, true, true);
     }
 
-    this.preventNextClick = false;
-
     if (this.panning)
       KineticPanning.start(this);
   },
 
   onTouchMove: function cp_onTouchMove(evt) {
     if (!this.dragging || !this.scrollCallback)
       return;
 
@@ -259,39 +264,39 @@ const ContentPanning = {
 
   onKineticEnd: function cp_onKineticEnd() {
     if (!this.dragging)
       this.scrollCallback = null;
   },
 
   getPannable: function cp_getPannable(node) {
     if (!(node instanceof Ci.nsIDOMHTMLElement) || node.tagName == 'HTML')
-      return null;
+      return [null, null];
 
     let content = node.ownerDocument.defaultView;
     while (!(node instanceof Ci.nsIDOMHTMLBodyElement)) {
       let style = content.getComputedStyle(node, null);
 
       let overflow = [style.getPropertyValue('overflow'),
                       style.getPropertyValue('overflow-x'),
                       style.getPropertyValue('overflow-y')];
 
       let rect = node.getBoundingClientRect();
       let isAuto = (overflow.indexOf('auto') != -1 &&
                    (rect.height < node.scrollHeight ||
                     rect.width < node.scrollWidth));
 
       let isScroll = (overflow.indexOf('scroll') != -1);
       if (isScroll || isAuto)
-        return this._generateCallback(node);
+        return [node, this._generateCallback(node)];
 
       node = node.parentNode;
     }
 
-    return this._generateCallback(content);
+    return [content, this._generateCallback(content)];
   },
 
   _generateCallback: function cp_generateCallback(content) {
     function scroll(delta) {
       if (content instanceof Ci.nsIDOMHTMLElement) {
         let oldX = content.scrollLeft, oldY = content.scrollTop;
         content.scrollLeft += delta.x;
         content.scrollTop += delta.y;
@@ -309,20 +314,20 @@ const ContentPanning = {
 
   get _domUtils() {
     delete this._domUtils;
     return this._domUtils = Cc['@mozilla.org/inspector/dom-utils;1']
                               .getService(Ci.inIDOMUtils);
   },
 
   _resetActive: function cp_resetActive() {
-    let root = this.targetDocument.documentElement;
+    let root = this.target.ownerDocument || this.target.document;
 
     const kStateActive = 0x00000001;
-    this._domUtils.setContentState(root, kStateActive);
+    this._domUtils.setContentState(root.documentElement, kStateActive);
   }
 };
 
 ContentPanning.init();
 
 
 // Min/max velocity of kinetic panning. This is in pixels/millisecond.
 const kMinVelocity = 0.4;