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 }