Bug 1020995 - Contextmenus should fire on children of highlighted element. r=margaret
authorWes Johnston <wjohnston@mozilla.com>
Tue, 10 Jun 2014 12:42:17 -0700
changeset 187892 c437201095220b64209e8c2b6b198ed2d2079832
parent 187891 845ea9c7b71ccc4176ab59e9ec6dd855c39de6c1
child 187893 33eac5a39078d5c0e3e0f4191e203b3e37ab1459
push id7220
push userwjohnston@mozilla.com
push dateTue, 10 Jun 2014 19:42:35 +0000
treeherderfx-team@c43720109522 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmargaret
bugs1020995
milestone33.0a1
Bug 1020995 - Contextmenus should fire on children of highlighted element. r=margaret
mobile/android/chrome/content/browser.js
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -2278,26 +2278,56 @@ var NativeWindow = {
         if (!this._findMenuItem(item.id) && item.matches(element, x, y)) {
           res.push(item);
         }
       }
 
       return res;
     },
 
+    _findTarget: function(x, y) {
+      let isDescendant = function(parent, child) {
+        let node = child;
+        while (node) {
+          if (node === parent) {
+            return true;
+          }
+
+          node = node.parentNode;
+        }
+
+        return false;
+      };
+
+      let target = BrowserEventHandler._highlightElement;
+      let touchTarget = ElementTouchHelper.anyElementFromPoint(x, y);
+
+      // If we have a highlighted element that has a click handler, we want to ensure our target is inside it
+      if (isDescendant(target, touchTarget)) {
+        target = touchTarget;
+      } else if (!target) {
+        // Otherwise, let's try to find something clickable
+        target = ElementTouchHelper.elementFromPoint(x, y);
+
+        // If that failed, we'll just fall back to anything under the user's finger
+        if (!target) {
+          target = touchTarget;
+        }
+      }
+
+      return target;
+    },
+
     /* Checks if there are context menu items to show, and if it finds them
      * sends a contextmenu event to content. We also send showing events to
      * any html5 context menus we are about to show, and fire some local notifications
      * for chrome consumers to do lazy menuitem construction
      */
     _sendToContent: function(x, y) {
-      let target = BrowserEventHandler._highlightElement || ElementTouchHelper.elementFromPoint(x, y);
-      if (!target)
-        target = ElementTouchHelper.anyElementFromPoint(x, y);
-
+      let target = this._findTarget(x, y);
       if (!target)
         return;
 
       this._target = target;
 
       Services.obs.notifyObservers(null, "before-build-contextmenu", "");
       this._buildMenu(x, y);