зеркало из https://github.com/mozilla/gecko-dev.git
Bug 999239: Copy session history when recreating browser element for the remote -> non-remote transition. r=bz, r=felipe, sr=gavin
This commit is contained in:
Родитель
e132fb9f69
Коммит
8b46b5daab
|
@ -13,6 +13,8 @@ Cu.import("resource://gre/modules/WindowsPrefSync.jsm");
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
|
||||
"resource:///modules/BrowserUITelemetry.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
|
||||
"resource:///modules/E10SUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
|
@ -166,6 +168,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "SitePermissions",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
|
||||
"resource:///modules/sessionstore/SessionStore.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TabState",
|
||||
"resource:///modules/sessionstore/TabState.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
|
||||
"resource://gre/modules/FxAccounts.jsm");
|
||||
|
||||
|
@ -766,6 +771,36 @@ function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
|
|||
gDNSService.asyncResolve(hostName, 0, onLookupComplete, Services.tm.mainThread);
|
||||
}
|
||||
|
||||
// Called when a docshell has attempted to load a page in an incorrect process.
|
||||
// This function is responsible for loading the page in the correct process.
|
||||
function RedirectLoad({ target: browser, data }) {
|
||||
let tab = gBrowser._getTabForBrowser(browser);
|
||||
// Flush the tab state before getting it
|
||||
TabState.flush(browser);
|
||||
let tabState = JSON.parse(SessionStore.getTabState(tab));
|
||||
|
||||
if (data.historyIndex < 0) {
|
||||
// Add a pseudo-history state for the new url to load
|
||||
let newEntry = {
|
||||
url: data.uri,
|
||||
referrer: data.referrer,
|
||||
};
|
||||
|
||||
tabState.entries = tabState.entries.slice(0, tabState.index);
|
||||
tabState.entries.push(newEntry);
|
||||
tabState.index++;
|
||||
tabState.userTypedValue = null;
|
||||
}
|
||||
else {
|
||||
// Update the history state to point to the requested index
|
||||
tabState.index = data.historyIndex + 1;
|
||||
}
|
||||
|
||||
// SessionStore takes care of setting the browser remoteness before restoring
|
||||
// history into it.
|
||||
SessionStore.setTabState(tab, JSON.stringify(tabState));
|
||||
}
|
||||
|
||||
var gBrowserInit = {
|
||||
delayedStartupFinished: false,
|
||||
|
||||
|
@ -1064,6 +1099,7 @@ var gBrowserInit = {
|
|||
Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
|
||||
Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
|
||||
window.messageManager.addMessageListener("Browser:URIFixup", gKeywordURIFixup);
|
||||
window.messageManager.addMessageListener("Browser:LoadURI", RedirectLoad);
|
||||
|
||||
BrowserOffline.init();
|
||||
OfflineApps.init();
|
||||
|
@ -1372,6 +1408,7 @@ var gBrowserInit = {
|
|||
Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
|
||||
Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
|
||||
window.messageManager.removeMessageListener("Browser:URIFixup", gKeywordURIFixup);
|
||||
window.messageManager.removeMessageListener("Browser:LoadURI", RedirectLoad);
|
||||
|
||||
try {
|
||||
gPrefService.removeObserver(gHomeButton.prefDomain, gHomeButton);
|
||||
|
@ -3551,6 +3588,28 @@ var XULBrowserWindow = {
|
|||
return target;
|
||||
},
|
||||
|
||||
// Check whether this URI should load in the current process
|
||||
shouldLoadURI: function(aDocShell, aURI, aReferrer) {
|
||||
if (!gMultiProcessBrowser)
|
||||
return true;
|
||||
|
||||
let browser = aDocShell.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.sameTypeRootTreeItem
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
|
||||
// Ignore loads that aren't in the main tabbrowser
|
||||
if (browser.localName != "browser" || browser.getTabBrowser() != gBrowser)
|
||||
return true;
|
||||
|
||||
if (!E10SUtils.shouldLoadURI(aDocShell, aURI, aReferrer)) {
|
||||
E10SUtils.redirectLoad(aDocShell, aURI, aReferrer);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
onProgressChange: function (aWebProgress, aRequest,
|
||||
aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress) {
|
||||
|
|
|
@ -9,6 +9,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/ContentWebRTC.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
|
||||
"resource:///modules/E10SUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ContentLinkHandler",
|
||||
|
@ -683,6 +685,16 @@ let WebBrowserChrome = {
|
|||
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
|
||||
return BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
|
||||
},
|
||||
|
||||
// Check whether this URI should load in the current process
|
||||
shouldLoadURI: function(aDocShell, aURI, aReferrer) {
|
||||
if (!E10SUtils.shouldLoadURI(aDocShell, aURI, aReferrer)) {
|
||||
E10SUtils.redirectLoad(aDocShell, aURI, aReferrer);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
|
|
|
@ -9,11 +9,6 @@
|
|||
%tabBrowserDTD;
|
||||
]>
|
||||
|
||||
# MAKE_E10S_WORK surrounds code needed to have the front-end try to be smart
|
||||
# about using non-remote browsers for loading certain URIs when remote tabs
|
||||
# (browser.tabs.remote) are enabled.
|
||||
#define MAKE_E10S_WORK 1
|
||||
|
||||
<bindings id="tabBrowserBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
|
@ -1474,49 +1469,18 @@
|
|||
</body>
|
||||
</method>
|
||||
|
||||
#ifdef MAKE_E10S_WORK
|
||||
<method name="updateBrowserRemotenessByURL">
|
||||
<parameter name="aBrowser"/>
|
||||
<parameter name="aURL"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
let shouldBeRemote = this._shouldBrowserBeRemote(aURL);
|
||||
let shouldBeRemote = gMultiProcessBrowser &&
|
||||
E10SUtils.shouldBrowserBeRemote(aURL);
|
||||
return this.updateBrowserRemoteness(aBrowser, shouldBeRemote);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
Returns true if we want to load the content for this URL in a
|
||||
remote process. Eventually this should just check whether aURL
|
||||
is unprivileged. Right now, though, we would like to load
|
||||
some unprivileged URLs (like about:neterror) in the main
|
||||
process since they interact with chrome code through
|
||||
BrowserOnClick.
|
||||
-->
|
||||
<method name="_shouldBrowserBeRemote">
|
||||
<parameter name="aURL"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!gMultiProcessBrowser)
|
||||
return false;
|
||||
|
||||
// loadURI in browser.xml treats null as about:blank
|
||||
if (!aURL)
|
||||
aURL = "about:blank";
|
||||
|
||||
if (aURL.startsWith("about:") &&
|
||||
aURL.toLowerCase() != "about:home" &&
|
||||
aURL.toLowerCase() != "about:blank") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
#endif
|
||||
|
||||
<method name="addTab">
|
||||
<parameter name="aURI"/>
|
||||
<parameter name="aReferrerURI"/>
|
||||
|
@ -1558,11 +1522,7 @@
|
|||
t.setAttribute("onerror", "this.removeAttribute('image');");
|
||||
t.className = "tabbrowser-tab";
|
||||
|
||||
#ifdef MAKE_E10S_WORK
|
||||
let remote = this._shouldBrowserBeRemote(aURI);
|
||||
#else
|
||||
let remote = gMultiProcessBrowser;
|
||||
#endif
|
||||
let remote = gMultiProcessBrowser && E10SUtils.shouldBrowserBeRemote(aURI);
|
||||
if (remote)
|
||||
t.setAttribute("remote", "true");
|
||||
|
||||
|
@ -2790,18 +2750,7 @@
|
|||
<parameter name="aCharset"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
#ifdef MAKE_E10S_WORK
|
||||
this.updateBrowserRemotenessByURL(this.mCurrentBrowser, aURI);
|
||||
try {
|
||||
#endif
|
||||
return this.mCurrentBrowser.loadURI(aURI, aReferrerURI, aCharset);
|
||||
#ifdef MAKE_E10S_WORK
|
||||
} catch (e) {
|
||||
let url = this.mCurrentBrowser.currentURI.spec;
|
||||
this.updateBrowserRemotenessByURL(this.mCurrentBrowser, url);
|
||||
throw e;
|
||||
}
|
||||
#endif
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -2815,18 +2764,7 @@
|
|||
<parameter name="aPostData"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
#ifdef MAKE_E10S_WORK
|
||||
this.updateBrowserRemotenessByURL(this.mCurrentBrowser, aURI);
|
||||
try {
|
||||
#endif
|
||||
return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData);
|
||||
#ifdef MAKE_E10S_WORK
|
||||
} catch (e) {
|
||||
let url = this.mCurrentBrowser.currentURI.spec;
|
||||
this.updateBrowserRemotenessByURL(this.mCurrentBrowser, url);
|
||||
throw e;
|
||||
}
|
||||
#endif
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
|
|
@ -483,4 +483,6 @@ skip-if = e10s
|
|||
[browser_addCertException.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (content.document.getElementById)
|
||||
[browser_bug1045809.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s # Bug 1068360 - [e10s] Mixed content blocker doorhanger doesn't work
|
||||
[browser_e10s_switchbrowser.js]
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const URL = "about:robots";
|
||||
const URL = "http://example.com/browser/browser/base/content/test/general/dummy_page.html";
|
||||
|
||||
function test() {
|
||||
let win;
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
const DUMMY_PATH = "browser/browser/base/content/test/general/dummy_page.html";
|
||||
|
||||
const gExpectedHistory = {
|
||||
index: -1,
|
||||
entries: []
|
||||
};
|
||||
|
||||
function check_history() {
|
||||
let webNav = gBrowser.webNavigation;
|
||||
let sessionHistory = webNav.sessionHistory;
|
||||
|
||||
let count = sessionHistory.count;
|
||||
is(count, gExpectedHistory.entries.length, "Should have the right number of history entries");
|
||||
is(sessionHistory.index, gExpectedHistory.index, "Should have the right history index");
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
let entry = sessionHistory.getEntryAtIndex(i, false);
|
||||
is(entry.URI.spec, gExpectedHistory.entries[i].uri, "Should have the right URI");
|
||||
is(entry.title, gExpectedHistory.entries[i].title, "Should have the right title");
|
||||
}
|
||||
}
|
||||
|
||||
// Waits for a load and updates the known history
|
||||
let waitForLoad = Task.async(function*(uri) {
|
||||
info("Loading " + uri);
|
||||
gBrowser.loadURI(uri);
|
||||
|
||||
yield waitForDocLoadComplete();
|
||||
gExpectedHistory.index++;
|
||||
gExpectedHistory.entries.push({
|
||||
uri: gBrowser.currentURI.spec,
|
||||
title: gBrowser.contentTitle
|
||||
});
|
||||
});
|
||||
|
||||
let back = Task.async(function*() {
|
||||
info("Going back");
|
||||
gBrowser.goBack();
|
||||
yield waitForDocLoadComplete();
|
||||
gExpectedHistory.index--;
|
||||
});
|
||||
|
||||
let forward = Task.async(function*() {
|
||||
info("Going forward");
|
||||
gBrowser.goForward();
|
||||
yield waitForDocLoadComplete();
|
||||
gExpectedHistory.index++;
|
||||
});
|
||||
|
||||
// Tests that navigating from a page that should be in the remote process and
|
||||
// a page that should be in the main process works and retains history
|
||||
add_task(function*() {
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
let remoting = Services.prefs.getBoolPref("browser.tabs.remote.autostart");
|
||||
let expectedRemote = remoting ? "true" : "";
|
||||
|
||||
info("1");
|
||||
// Create a tab and load a remote page in it
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
|
||||
yield waitForLoad("http://example.org/" + DUMMY_PATH);
|
||||
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
|
||||
|
||||
info("2");
|
||||
// Load another page
|
||||
yield waitForLoad("http://example.com/" + DUMMY_PATH);
|
||||
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
|
||||
check_history();
|
||||
|
||||
info("3");
|
||||
// Load a non-remote page
|
||||
yield waitForLoad("about:robots");
|
||||
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
|
||||
check_history();
|
||||
|
||||
info("4");
|
||||
// Load a remote page
|
||||
yield waitForLoad("http://example.org/" + DUMMY_PATH);
|
||||
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
|
||||
check_history();
|
||||
|
||||
info("5");
|
||||
yield back();
|
||||
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
|
||||
check_history();
|
||||
|
||||
info("6");
|
||||
yield back();
|
||||
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
|
||||
check_history();
|
||||
|
||||
info("7");
|
||||
yield forward();
|
||||
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
|
||||
check_history();
|
||||
|
||||
info("8");
|
||||
yield forward();
|
||||
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
|
||||
check_history();
|
||||
|
||||
info("9");
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
|
@ -454,12 +454,15 @@ function waitForDocLoadComplete(aBrowser=gBrowser) {
|
|||
let deferred = Promise.defer();
|
||||
let progressListener = {
|
||||
onStateChange: function (webProgress, req, flags, status) {
|
||||
let docStart = Ci.nsIWebProgressListener.STATE_IS_NETWORK |
|
||||
Ci.nsIWebProgressListener.STATE_STOP;
|
||||
info("Saw state " + flags.toString(16));
|
||||
if ((flags & docStart) == docStart) {
|
||||
let docStop = Ci.nsIWebProgressListener.STATE_IS_NETWORK |
|
||||
Ci.nsIWebProgressListener.STATE_STOP;
|
||||
info("Saw state " + flags.toString(16) + " and status " + status.toString(16));
|
||||
|
||||
// When a load needs to be retargetted to a new process it is cancelled
|
||||
// with NS_BINDING_ABORTED so ignore that case
|
||||
if ((flags & docStop) == docStop && status != Cr.NS_BINDING_ABORTED) {
|
||||
aBrowser.removeProgressListener(progressListener);
|
||||
info("Browser loaded");
|
||||
info("Browser loaded " + aBrowser.contentWindow.location);
|
||||
deferred.resolve();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["E10SUtils"];
|
||||
|
||||
const {interfaces: Ci, utils: Cu, classes: Cc} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
this.E10SUtils = {
|
||||
shouldBrowserBeRemote: function(aURL) {
|
||||
// loadURI in browser.xml treats null as about:blank
|
||||
if (!aURL)
|
||||
aURL = "about:blank";
|
||||
|
||||
if (aURL.startsWith("about:") &&
|
||||
aURL.toLowerCase() != "about:home" &&
|
||||
aURL.toLowerCase() != "about:blank" &&
|
||||
!aURL.toLowerCase().startsWith("about:neterror")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
shouldLoadURI: function(aDocShell, aURI, aReferrer) {
|
||||
// about:blank is the initial document and can load anywhere
|
||||
if (aURI.spec == "about:blank")
|
||||
return true;
|
||||
|
||||
// Inner frames should always load in the current process
|
||||
if (aDocShell.QueryInterface(Ci.nsIDocShellTreeItem).sameTypeParent)
|
||||
return true;
|
||||
|
||||
// If the URI can be loaded in the current process then continue
|
||||
let isRemote = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
|
||||
if (this.shouldBrowserBeRemote(aURI.spec) == isRemote)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
redirectLoad: function(aDocShell, aURI, aReferrer) {
|
||||
// Retarget the load to the correct process
|
||||
let messageManager = aDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
let sessionHistory = aDocShell.getInterface(Ci.nsIWebNavigation).sessionHistory;
|
||||
|
||||
messageManager.sendAsyncMessage("Browser:LoadURI", {
|
||||
uri: aURI.spec,
|
||||
referrer: aReferrer ? aReferrer.spec : null,
|
||||
historyIndex: sessionHistory.requestedIndex,
|
||||
});
|
||||
return false;
|
||||
},
|
||||
};
|
|
@ -96,7 +96,6 @@ this.TabCrashReporter = {
|
|||
return;
|
||||
|
||||
let url = browser.currentURI.spec;
|
||||
browser.getTabBrowser().updateBrowserRemotenessByURL(browser, url);
|
||||
browser.loadURIWithFlags(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
|
||||
},
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ EXTRA_JS_MODULES += [
|
|||
'ContentSearch.jsm',
|
||||
'ContentWebRTC.jsm',
|
||||
'CustomizationTabPreloader.jsm',
|
||||
'E10SUtils.jsm',
|
||||
'Feeds.jsm',
|
||||
'FormSubmitObserver.jsm',
|
||||
'FormValidationHandler.jsm',
|
||||
|
|
|
@ -9838,7 +9838,18 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if the webbrowser chrome wants the load to proceed; this can be
|
||||
// used to cancel attempts to load URIs in the wrong process.
|
||||
nsCOMPtr<nsIWebBrowserChrome3> browserChrome3 = do_GetInterface(mTreeOwner);
|
||||
if (browserChrome3) {
|
||||
bool shouldLoad;
|
||||
rv = browserChrome3->ShouldLoadURI(this, aURI, aReferrer, &shouldLoad);
|
||||
if (NS_SUCCEEDED(rv) && !shouldLoad) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// mContentViewer->PermitUnload can destroy |this| docShell, which
|
||||
// causes the next call of CanSavePresentation to crash.
|
||||
// Hold onto |this| until we return, to prevent a crash from happening.
|
||||
|
|
|
@ -80,7 +80,6 @@
|
|||
#include "UnitTransforms.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "nsIWebBrowserChrome3.h"
|
||||
|
||||
#include "nsColorPickerProxy.h"
|
||||
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
#include "nsIURI.idl"
|
||||
#include "nsIDOMNode.idl"
|
||||
|
||||
interface nsIDocShell;
|
||||
interface nsIInputStream;
|
||||
|
||||
/**
|
||||
* nsIWebBrowserChrome3 is an extension to nsIWebBrowserChrome2.
|
||||
*/
|
||||
[scriptable, uuid(7f2aa813-b250-4e46-afeb-97b1e91bc9a5)]
|
||||
[scriptable, uuid(9e6c2372-5d9d-4ce8-ab9e-c5df1494dc84)]
|
||||
interface nsIWebBrowserChrome3 : nsIWebBrowserChrome2
|
||||
{
|
||||
/**
|
||||
|
@ -30,4 +33,18 @@ interface nsIWebBrowserChrome3 : nsIWebBrowserChrome2
|
|||
in nsIURI linkURI,
|
||||
in nsIDOMNode linkNode,
|
||||
in boolean isAppTab);
|
||||
|
||||
/**
|
||||
* Determines whether a load should continue.
|
||||
*
|
||||
* @param aDocShell
|
||||
* The docshell performing the load.
|
||||
* @param aURI
|
||||
* The URI being loaded.
|
||||
* @param aReferrer
|
||||
* The referrer of the load.
|
||||
*/
|
||||
bool shouldLoadURI(in nsIDocShell aDocShell,
|
||||
in nsIURI aURI,
|
||||
in nsIURI aReferrer);
|
||||
};
|
||||
|
|
|
@ -445,6 +445,23 @@ NS_IMETHODIMP nsContentTreeOwner::OnBeforeLinkTraversal(const nsAString &origina
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsContentTreeOwner::ShouldLoadURI(nsIDocShell *aDocShell,
|
||||
nsIURI *aURI,
|
||||
nsIURI *aReferrer,
|
||||
bool *_retval)
|
||||
{
|
||||
NS_ENSURE_STATE(mXULWindow);
|
||||
|
||||
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
|
||||
mXULWindow->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
|
||||
|
||||
if (xulBrowserWindow)
|
||||
return xulBrowserWindow->ShouldLoadURI(aDocShell, aURI, aReferrer, _retval);
|
||||
|
||||
*_retval = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsContentTreeOwner::nsIWebBrowserChrome2
|
||||
//*****************************************************************************
|
||||
|
|
|
@ -10,13 +10,15 @@
|
|||
|
||||
interface nsIRequest;
|
||||
interface nsIDOMElement;
|
||||
interface nsIInputStream;
|
||||
interface nsIDocShell;
|
||||
|
||||
/**
|
||||
* The nsIXULBrowserWindow supplies the methods that may be called from the
|
||||
* internals of the browser area to tell the containing xul window to update
|
||||
* its ui.
|
||||
*/
|
||||
[scriptable, uuid(e4ee85a0-645d-11e3-949a-0800200c9a66)]
|
||||
[scriptable, uuid(162d3378-a7d5-410c-8635-fe80e32020fc)]
|
||||
interface nsIXULBrowserWindow : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -38,6 +40,19 @@ interface nsIXULBrowserWindow : nsISupports
|
|||
in nsIDOMNode linkNode,
|
||||
in boolean isAppTab);
|
||||
|
||||
/**
|
||||
* Determines whether a load should continue.
|
||||
*
|
||||
* @param aDocShell
|
||||
* The docshell performing the load.
|
||||
* @param aURI
|
||||
* The URI being loaded.
|
||||
* @param aReferrer
|
||||
* The referrer of the load.
|
||||
*/
|
||||
bool shouldLoadURI(in nsIDocShell aDocShell,
|
||||
in nsIURI aURI,
|
||||
in nsIURI aReferrer);
|
||||
/**
|
||||
* Show/hide a tooltip (when the user mouses over a link, say).
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче