tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PluginChild.sys.mjs (3048B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // Handle GMP crashes
      6 export class PluginChild extends JSWindowActorChild {
      7  handleEvent(event) {
      8    // Ignore events for other frames.
      9    let eventDoc = event.target.ownerDocument || event.target.document;
     10    if (eventDoc && eventDoc != this.document) {
     11      return;
     12    }
     13 
     14    let eventType = event.type;
     15    if (eventType == "PluginCrashed") {
     16      this.onPluginCrashed(event);
     17    }
     18  }
     19 
     20  /**
     21   * Determines whether or not the crashed plugin is contained within current
     22   * full screen DOM element.
     23   *
     24   * @param fullScreenElement (DOM element)
     25   *   The DOM element that is currently full screen, or null.
     26   * @param domElement
     27   *   The DOM element which contains the crashed plugin, or the crashed plugin
     28   *   itself.
     29   * @returns bool
     30   *   True if the plugin is a descendant of the full screen DOM element, false otherwise.
     31   */
     32  isWithinFullScreenElement(fullScreenElement, domElement) {
     33    /**
     34     * Traverses down iframes until it find a non-iframe full screen DOM element.
     35     *
     36     * @param fullScreenIframe
     37     *  Target iframe to begin searching from.
     38     * @returns DOM element
     39     *  The full screen DOM element contained within the iframe (could be inner iframe), or the original iframe if no inner DOM element is found.
     40     */
     41    let getTrueFullScreenElement = fullScreenIframe => {
     42      if (
     43        typeof fullScreenIframe.contentDocument !== "undefined" &&
     44        fullScreenIframe.contentDocument.mozFullScreenElement
     45      ) {
     46        return getTrueFullScreenElement(
     47          fullScreenIframe.contentDocument.mozFullScreenElement
     48        );
     49      }
     50      return fullScreenIframe;
     51    };
     52 
     53    if (fullScreenElement.tagName === "IFRAME") {
     54      fullScreenElement = getTrueFullScreenElement(fullScreenElement);
     55    }
     56 
     57    if (fullScreenElement.contains(domElement)) {
     58      return true;
     59    }
     60    let parentIframe = domElement.ownerGlobal.frameElement;
     61    if (parentIframe) {
     62      return this.isWithinFullScreenElement(fullScreenElement, parentIframe);
     63    }
     64    return false;
     65  }
     66 
     67  /**
     68   * The PluginCrashed event handler. The target of the event is the
     69   * document that GMP is being used in.
     70   */
     71  async onPluginCrashed(aEvent) {
     72    if (!this.contentWindow.PluginCrashedEvent.isInstance(aEvent)) {
     73      return;
     74    }
     75 
     76    let { target, gmpPlugin, pluginID } = aEvent;
     77    let fullScreenElement =
     78      this.contentWindow.top.document.mozFullScreenElement;
     79    if (fullScreenElement) {
     80      if (this.isWithinFullScreenElement(fullScreenElement, target)) {
     81        this.contentWindow.top.document.mozCancelFullScreen();
     82      }
     83    }
     84 
     85    if (!gmpPlugin || !target.document) {
     86      // TODO: Throw exception? How did we get here?
     87      return;
     88    }
     89 
     90    this.sendAsyncMessage("PluginContent:ShowPluginCrashedNotification", {
     91      pluginCrashID: { pluginID },
     92    });
     93  }
     94 }