forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			209 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 | |
| // This Source Code Form is subject to the terms of the Mozilla Public
 | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | |
| 
 | |
| const lazy = {};
 | |
| ChromeUtils.defineESModuleGetters(lazy, {
 | |
|   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
 | |
| });
 | |
| 
 | |
| // This object implements the JS parts of nsIWebNavigation.
 | |
| export class RemoteWebNavigation {
 | |
|   constructor(aBrowser) {
 | |
|     this._browser = aBrowser;
 | |
|     this._cancelContentJSEpoch = 1;
 | |
|     this._currentURI = null;
 | |
|     this._canGoBack = false;
 | |
|     this._canGoForward = false;
 | |
|     this.referringURI = null;
 | |
|   }
 | |
| 
 | |
|   swapBrowser(aBrowser) {
 | |
|     this._browser = aBrowser;
 | |
|   }
 | |
| 
 | |
|   maybeCancelContentJSExecution(aNavigationType, aOptions = {}) {
 | |
|     const epoch = this._cancelContentJSEpoch++;
 | |
|     this._browser.frameLoader.remoteTab.maybeCancelContentJSExecution(
 | |
|       aNavigationType,
 | |
|       { ...aOptions, epoch }
 | |
|     );
 | |
|     return epoch;
 | |
|   }
 | |
| 
 | |
|   get canGoBack() {
 | |
|     if (Services.appinfo.sessionHistoryInParent) {
 | |
|       return this._browser.browsingContext.sessionHistory?.index > 0;
 | |
|     }
 | |
|     return this._canGoBack;
 | |
|   }
 | |
| 
 | |
|   get canGoForward() {
 | |
|     if (Services.appinfo.sessionHistoryInParent) {
 | |
|       let sessionHistory = this._browser.browsingContext.sessionHistory;
 | |
|       return sessionHistory?.index < sessionHistory?.count - 1;
 | |
|     }
 | |
|     return this._canGoForward;
 | |
|   }
 | |
| 
 | |
|   goBack(requireUserInteraction = false) {
 | |
|     let cancelContentJSEpoch = this.maybeCancelContentJSExecution(
 | |
|       Ci.nsIRemoteTab.NAVIGATE_BACK
 | |
|     );
 | |
|     this._browser.browsingContext.goBack(
 | |
|       cancelContentJSEpoch,
 | |
|       requireUserInteraction,
 | |
|       true
 | |
|     );
 | |
|   }
 | |
|   goForward(requireUserInteraction = false) {
 | |
|     let cancelContentJSEpoch = this.maybeCancelContentJSExecution(
 | |
|       Ci.nsIRemoteTab.NAVIGATE_FORWARD
 | |
|     );
 | |
|     this._browser.browsingContext.goForward(
 | |
|       cancelContentJSEpoch,
 | |
|       requireUserInteraction,
 | |
|       true
 | |
|     );
 | |
|   }
 | |
|   gotoIndex(aIndex) {
 | |
|     let cancelContentJSEpoch = this.maybeCancelContentJSExecution(
 | |
|       Ci.nsIRemoteTab.NAVIGATE_INDEX,
 | |
|       { index: aIndex }
 | |
|     );
 | |
|     this._browser.browsingContext.goToIndex(aIndex, cancelContentJSEpoch, true);
 | |
|   }
 | |
| 
 | |
|   _speculativeConnect(uri, loadURIOptions) {
 | |
|     try {
 | |
|       // Let's start a network connection before the content process asks.
 | |
|       // Note that we might have already set up the speculative connection in
 | |
|       // some cases, especially when the url is from location bar or its popup
 | |
|       // menu.
 | |
|       if (uri.schemeIs("http") || uri.schemeIs("https")) {
 | |
|         let isBrowserPrivate = lazy.PrivateBrowsingUtils.isBrowserPrivate(
 | |
|           this._browser
 | |
|         );
 | |
|         let principal = loadURIOptions.triggeringPrincipal;
 | |
|         // We usually have a triggeringPrincipal assigned, but in case we
 | |
|         // don't have one or if it's a SystemPrincipal, let's create it with OA
 | |
|         // inferred from the current context.
 | |
|         if (!principal || principal.isSystemPrincipal) {
 | |
|           let attrs = {
 | |
|             userContextId: this._browser.getAttribute("usercontextid") || 0,
 | |
|             privateBrowsingId: isBrowserPrivate ? 1 : 0,
 | |
|           };
 | |
|           principal = Services.scriptSecurityManager.createContentPrincipal(
 | |
|             uri,
 | |
|             attrs
 | |
|           );
 | |
|         }
 | |
|         Services.io.speculativeConnect(uri, principal, null, false);
 | |
|       }
 | |
|     } catch (ex) {
 | |
|       // Can't setup speculative connection for this uri for some
 | |
|       // reason, just ignore it.
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   loadURI(uri, loadURIOptions) {
 | |
|     this._speculativeConnect(uri, loadURIOptions);
 | |
|     let cancelContentJSEpoch = this.maybeCancelContentJSExecution(
 | |
|       Ci.nsIRemoteTab.NAVIGATE_URL,
 | |
|       { uri }
 | |
|     );
 | |
|     this._browser.browsingContext.loadURI(uri, {
 | |
|       ...loadURIOptions,
 | |
|       cancelContentJSEpoch,
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   fixupAndLoadURIString(uriString, loadURIOptions) {
 | |
|     let uri;
 | |
|     try {
 | |
|       let fixupFlags = Services.uriFixup.webNavigationFlagsToFixupFlags(
 | |
|         uriString,
 | |
|         loadURIOptions.loadFlags
 | |
|       );
 | |
|       let isBrowserPrivate = lazy.PrivateBrowsingUtils.isBrowserPrivate(
 | |
|         this._browser
 | |
|       );
 | |
|       if (isBrowserPrivate) {
 | |
|         fixupFlags |= Services.uriFixup.FIXUP_FLAG_PRIVATE_CONTEXT;
 | |
|       }
 | |
| 
 | |
|       uri = Services.uriFixup.getFixupURIInfo(
 | |
|         uriString,
 | |
|         fixupFlags
 | |
|       ).preferredURI;
 | |
|     } catch (ex) {
 | |
|       // In rare cases `uriFixup` can throw. We ignore this here, but it's
 | |
|       // likely that the fixupAndLoadURIString call below will still throw,
 | |
|       // hopefully with more details.
 | |
|     }
 | |
|     if (uri) {
 | |
|       this._speculativeConnect(uri, loadURIOptions);
 | |
|     }
 | |
| 
 | |
|     let cancelContentJSEpoch = this.maybeCancelContentJSExecution(
 | |
|       Ci.nsIRemoteTab.NAVIGATE_URL,
 | |
|       { uri }
 | |
|     );
 | |
|     // For now, continue to use fixup here, but note that ideally we should be
 | |
|     // doing fixup only once and reusing the URI we created above. Addressing
 | |
|     // this is bug 1815509.
 | |
|     this._browser.browsingContext.fixupAndLoadURIString(uriString, {
 | |
|       ...loadURIOptions,
 | |
|       cancelContentJSEpoch,
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   reload(aReloadFlags) {
 | |
|     this._browser.browsingContext.reload(aReloadFlags);
 | |
|   }
 | |
|   stop(aStopFlags) {
 | |
|     this._browser.browsingContext.stop(aStopFlags);
 | |
|   }
 | |
| 
 | |
|   get document() {
 | |
|     return this._browser.contentDocument;
 | |
|   }
 | |
| 
 | |
|   get currentURI() {
 | |
|     if (!this._currentURI) {
 | |
|       this._currentURI = Services.io.newURI("about:blank");
 | |
|     }
 | |
|     return this._currentURI;
 | |
|   }
 | |
|   set currentURI(aURI) {
 | |
|     // Bug 1498600 verify usages of systemPrincipal here
 | |
|     let loadURIOptions = {
 | |
|       triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
 | |
|     };
 | |
|     this.loadURI(aURI.spec, loadURIOptions);
 | |
|   }
 | |
| 
 | |
|   // Bug 1233803 - accessing the sessionHistory of remote browsers should be
 | |
|   // done in content scripts.
 | |
|   get sessionHistory() {
 | |
|     throw new Components.Exception(
 | |
|       "Not implemented",
 | |
|       Cr.NS_ERROR_NOT_IMPLEMENTED
 | |
|     );
 | |
|   }
 | |
|   set sessionHistory(aValue) {
 | |
|     throw new Components.Exception(
 | |
|       "Not implemented",
 | |
|       Cr.NS_ERROR_NOT_IMPLEMENTED
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   _sendMessage(aMessage, aData) {
 | |
|     try {
 | |
|       this._browser.sendMessageToActor(aMessage, aData, "WebNavigation");
 | |
|     } catch (e) {
 | |
|       console.error(e);
 | |
|     }
 | |
|   }
 | |
| }
 | 
