Bug 1499372 - Find the media element from context menu event dispatched from video controls r=JanH
authorTimothy Guan-tin Chien <timdream@gmail.com>
Fri, 19 Oct 2018 17:43:16 +0000
changeset 490542 655818c009b19ac39ac6b69f2e76473976fdaaeb
parent 490541 140a56e90594382a0c24298b08a5a853e95c0b32
child 490543 106c2a54ae6a95718cbb8bfb7a9453e1fefa5027
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersJanH
bugs1499372
milestone64.0a1
Bug 1499372 - Find the media element from context menu event dispatched from video controls r=JanH Differential Revision: https://phabricator.services.mozilla.com/D9016
mobile/android/chrome/content/browser.js
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -2897,16 +2897,19 @@ var NativeWindow = {
 
       // Use the highlighted element for the context menu target. When accessibility is
       // enabled, elements may not be highlighted so use the event target instead.
       this._target = BrowserEventHandler._highlightElement || event.composedTarget;
       if (!this._target) {
         return;
       }
 
+      // Find the HTMLMediaElement host if the element is inside video controls UA Widget.
+      this._target = this._findMediaElementHostFromControls(this._target);
+
       // Try to build a list of contextmenu items. If successful, actually show the
       // native context menu by passing the list to Java.
       this._buildMenu(event.clientX, event.clientY);
       if (this._shouldShow()) {
         BrowserEventHandler._cancelTapHighlight();
 
         if (this._shouldPreventDefault()) {
           // Consume / preventDefault the event.
@@ -2960,16 +2963,37 @@ var NativeWindow = {
     // Adds an array of menuitems to the current list of items to show, in the correct context
     _addMenuItems: function(items, context) {
         if (!this.menus[context]) {
           this.menus[context] = [];
         }
         this.menus[context] = this.menus[context].concat(items);
     },
 
+    _findMediaElementHostFromControls(element) {
+      if (!(element instanceof HTMLMediaElement)) {
+        let n = element;
+        while (n) {
+          if (n instanceof ShadowRoot) {
+            if (n.host instanceof HTMLMediaElement) {
+              // Node is a UA Widget Shadow Root with HTMLMediaElement as host
+              return n.host;
+            }
+            // Node is a normal Shadow Root, give up
+            return element;
+          }
+          // Set the node to its parentNode and continue the loop.
+          n = n.parentNode;
+        }
+      }
+      // Return the element given that the loop ends without finding anything,
+      // or because the element is already an HTMLMediaElement.
+      return element;
+    },
+
     /* Does the basic work of building a context menu to show. Will combine HTML and Native
      * context menus items, as well as sorting menuitems into different menus based on context.
      */
     _buildMenu: function(x, y) {
       // now walk up the tree and for each node look for any context menu items that apply
       let element = this._target;
 
       // this.menus holds a hashmap of "contexts" to menuitems associated with that context