GeckoViewContentParent.sys.mjs (3867B)
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 import { GeckoViewUtils } from "resource://gre/modules/GeckoViewUtils.sys.mjs"; 6 import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs"; 7 8 const lazy = {}; 9 10 ChromeUtils.defineESModuleGetters(lazy, { 11 SessionHistory: "resource://gre/modules/sessionstore/SessionHistory.sys.mjs", 12 SessionStoreHelper: 13 "resource://gre/modules/sessionstore/SessionStoreHelper.sys.mjs", 14 }); 15 16 const { debug, warn } = GeckoViewUtils.initLogging("GeckoViewContentParent"); 17 18 export class GeckoViewContentParent extends GeckoViewActorParent { 19 didDestroy() { 20 this._didDestroy = true; 21 } 22 23 async collectState() { 24 return this.sendQuery("CollectSessionState"); 25 } 26 27 async containsFormData() { 28 return this.sendQuery("ContainsFormData"); 29 } 30 31 async receiveMessage(aMsg) { 32 switch (aMsg.name) { 33 case "GeckoView:PinOnScreen": { 34 return this.eventDispatcher.sendRequest({ 35 ...aMsg.data, 36 type: "GeckoView:PinOnScreen", 37 }); 38 } 39 default: { 40 return super.receiveMessage(aMsg); 41 } 42 } 43 } 44 45 restoreState({ history, switchId, formdata, scrolldata }) { 46 if (Services.appinfo.sessionHistoryInParent) { 47 const { browsingContext } = this.browser; 48 lazy.SessionHistory.restoreFromParent( 49 browsingContext.sessionHistory, 50 history 51 ); 52 53 // TODO Bug 1648158 this should include scroll, form history, etc 54 return SessionStoreUtils.initializeRestore( 55 browsingContext, 56 lazy.SessionStoreHelper.buildRestoreData(formdata, scrolldata) 57 ); 58 } 59 60 // Restoring is made of two parts. First we need to restore the history 61 // of the tab and navigating to the current page, after the page 62 // navigates to the current page we need to restore the state of the 63 // page (scroll position, form data, etc). 64 // 65 // We can't do everything in one step inside the child actor because 66 // the actor is recreated when navigating, so we need to keep the state 67 // on the parent side until we navigate. 68 this.sendAsyncMessage("RestoreHistoryAndNavigate", { 69 history, 70 switchId, 71 }); 72 73 if (!formdata && !scrolldata) { 74 return null; 75 } 76 77 const progressFilter = Cc[ 78 "@mozilla.org/appshell/component/browser-status-filter;1" 79 ].createInstance(Ci.nsIWebProgress); 80 81 const { browser } = this; 82 const progressListener = { 83 QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener"]), 84 85 onLocationChange(aWebProgress) { 86 if (!aWebProgress.isTopLevel) { 87 return; 88 } 89 // The actor might get recreated between navigations so we need to 90 // query it again for the up-to-date instance. 91 browser.browsingContext.currentWindowGlobal 92 .getActor("GeckoViewContent") 93 .sendAsyncMessage("RestoreSessionState", { formdata, scrolldata }); 94 progressFilter.removeProgressListener(this); 95 browser.removeProgressListener(progressFilter); 96 }, 97 }; 98 99 const flags = Ci.nsIWebProgress.NOTIFY_LOCATION; 100 progressFilter.addProgressListener(progressListener, flags); 101 browser.addProgressListener(progressFilter, flags); 102 return null; 103 } 104 105 // This is a copy of browser/actors/DOMFullscreenParent.sys.mjs 106 hasBeenDestroyed() { 107 if (this._didDestroy) { 108 return true; 109 } 110 111 // The 'didDestroy' callback is not always getting called. 112 // So we can't rely on it here. Instead, we will try to access 113 // the browsing context to judge wether the actor has 114 // been destroyed or not. 115 try { 116 return !this.browsingContext; 117 } catch { 118 return true; 119 } 120 } 121 }