Bug 1687263: part 4) Defer and in some cases avoid removing spellchecking-ranges...
[gecko.git] / browser / actors / PluginChild.jsm
blob881203eea01a5a49503658d54d7b01df4f8cf399
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/. */
5 "use strict";
7 var EXPORTED_SYMBOLS = ["PluginChild"];
9 // Handle GMP crashes
10 class PluginChild extends JSWindowActorChild {
11   handleEvent(event) {
12     // Ignore events for other frames.
13     let eventDoc = event.target.ownerDocument || event.target.document;
14     if (eventDoc && eventDoc != this.document) {
15       return;
16     }
18     let eventType = event.type;
19     if (eventType == "PluginCrashed") {
20       this.onPluginCrashed(event);
21     }
22   }
24   /**
25    * Determines whether or not the crashed plugin is contained within current
26    * full screen DOM element.
27    * @param fullScreenElement (DOM element)
28    *   The DOM element that is currently full screen, or null.
29    * @param domElement
30    *   The DOM element which contains the crashed plugin, or the crashed plugin
31    *   itself.
32    * @returns bool
33    *   True if the plugin is a descendant of the full screen DOM element, false otherwise.
34    **/
35   isWithinFullScreenElement(fullScreenElement, domElement) {
36     /**
37      * Traverses down iframes until it find a non-iframe full screen DOM element.
38      * @param fullScreenIframe
39      *  Target iframe to begin searching from.
40      * @returns DOM element
41      *  The full screen DOM element contained within the iframe (could be inner iframe), or the original iframe if no inner DOM element is found.
42      **/
43     let getTrueFullScreenElement = fullScreenIframe => {
44       if (
45         typeof fullScreenIframe.contentDocument !== "undefined" &&
46         fullScreenIframe.contentDocument.mozFullScreenElement
47       ) {
48         return getTrueFullScreenElement(
49           fullScreenIframe.contentDocument.mozFullScreenElement
50         );
51       }
52       return fullScreenIframe;
53     };
55     if (fullScreenElement.tagName === "IFRAME") {
56       fullScreenElement = getTrueFullScreenElement(fullScreenElement);
57     }
59     if (fullScreenElement.contains(domElement)) {
60       return true;
61     }
62     let parentIframe = domElement.ownerGlobal.frameElement;
63     if (parentIframe) {
64       return this.isWithinFullScreenElement(fullScreenElement, parentIframe);
65     }
66     return false;
67   }
69   /**
70    * The PluginCrashed event handler. The target of the event is the
71    * document that GMP is being used in.
72    */
73   async onPluginCrashed(aEvent) {
74     if (!(aEvent instanceof this.contentWindow.PluginCrashedEvent)) {
75       return;
76     }
78     let { target, gmpPlugin, pluginID } = aEvent;
79     let fullScreenElement = this.contentWindow.top.document
80       .mozFullScreenElement;
81     if (fullScreenElement) {
82       if (this.isWithinFullScreenElement(fullScreenElement, target)) {
83         this.contentWindow.top.document.mozCancelFullScreen();
84       }
85     }
87     if (!gmpPlugin || !target.document) {
88       // TODO: Throw exception? How did we get here?
89       return;
90     }
92     this.sendAsyncMessage("PluginContent:ShowPluginCrashedNotification", {
93       pluginCrashID: { pluginID },
94     });
95   }