Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Daniel Varga 2019-05-23 18:54:21 +03:00
Родитель 5b4c150005 273ef90da4
Коммит 4cbc287f63
94 изменённых файлов: 1634 добавлений и 1192 удалений

Просмотреть файл

@ -27,6 +27,7 @@
#include "mozilla/dom/CustomEvent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/BrowserHost.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeOwner.h"
@ -669,12 +670,12 @@ ProxyAccessible* RootAccessible::GetPrimaryRemoteTopLevelContentDoc() const {
mDocumentNode->GetDocShell()->GetTreeOwner(getter_AddRefs(owner));
NS_ENSURE_TRUE(owner, nullptr);
nsCOMPtr<nsIRemoteTab> browserParent;
owner->GetPrimaryRemoteTab(getter_AddRefs(browserParent));
if (!browserParent) {
nsCOMPtr<nsIRemoteTab> remoteTab;
owner->GetPrimaryRemoteTab(getter_AddRefs(remoteTab));
if (!remoteTab) {
return nullptr;
}
auto tab = static_cast<dom::BrowserParent*>(browserParent.get());
auto tab = static_cast<dom::BrowserHost*>(remoteTab.get());
return tab->GetTopLevelDocAccessible();
}

Просмотреть файл

@ -672,8 +672,8 @@ void DocAccessibleParent::MaybeInitWindowEmulation() {
rect.MoveToX(rootRect.X() - rect.X());
rect.MoveToY(rect.Y() - rootRect.Y());
auto tab = static_cast<dom::BrowserParent*>(Manager());
tab->GetDocShellIsActive(&isActive);
auto browserParent = static_cast<dom::BrowserParent*>(Manager());
isActive = browserParent->GetDocShellIsActive();
}
nsWinUtils::NativeWindowCreateProc onCreate([this](HWND aHwnd) -> void {

Просмотреть файл

@ -239,6 +239,9 @@ var BrowserPageActions = {
"subviewbutton-iconic",
"pageAction-panel-button"
);
if (action.isBadged) {
buttonNode.setAttribute("badged", "true");
}
buttonNode.setAttribute("actionid", action.id);
buttonNode.addEventListener("command", event => {
this.doCommandForAction(action, event, buttonNode);
@ -1126,7 +1129,6 @@ BrowserPageActions.addSearchEngine = {
this._updateTitleAndIcon();
this.action.setWantsSubview(this.engines.length > 1, window);
let button = BrowserPageActions.panelButtonNodeForActionID(this.action.id);
button.classList.add("badged-button");
button.setAttribute("image", this.engines[0].icon);
button.setAttribute("uri", this.engines[0].uri);
button.setAttribute("crop", "center");
@ -1139,7 +1141,7 @@ BrowserPageActions.addSearchEngine = {
}
for (let engine of this.engines) {
let button = document.createXULElement("toolbarbutton");
button.classList.add("subviewbutton", "subviewbutton-iconic");
button.classList.add("subviewbutton", "subviewbutton-iconic", "badged-button");
button.setAttribute("label", engine.title);
button.setAttribute("image", engine.icon);
button.setAttribute("uri", engine.uri);

Просмотреть файл

@ -1136,8 +1136,7 @@ var LibraryUI = {
let animatableBox = document.getElementById("library-animatable-box");
let navBar = document.getElementById("nav-bar");
let libraryIcon = document.getAnonymousElementByAttribute(libraryButton, "class", "toolbarbutton-icon");
let iconBounds = window.windowUtils.getBoundsWithoutFlushing(libraryIcon);
let iconBounds = window.windowUtils.getBoundsWithoutFlushing(libraryButton.icon);
let libraryBounds = window.windowUtils.getBoundsWithoutFlushing(libraryButton);
animatableBox.style.setProperty("--library-button-height", libraryBounds.height + "px");
@ -1197,8 +1196,7 @@ var LibraryUI = {
}
let animatableBox = document.getElementById("library-animatable-box");
let libraryIcon = document.getAnonymousElementByAttribute(libraryButton, "class", "toolbarbutton-icon");
let iconBounds = window.windowUtils.getBoundsWithoutFlushing(libraryIcon);
let iconBounds = window.windowUtils.getBoundsWithoutFlushing(libraryButton.icon);
// Resizing the window will only have the ability to change the X offset of the
// library button.

Просмотреть файл

@ -568,7 +568,7 @@ function UpdateBackForwardCommands(aWebNavigation) {
/**
* Click-and-Hold implementation for the Back and Forward buttons
* XXXmano: should this live in toolbarbutton.xml?
* XXXmano: should this live in toolbarbutton.js?
*/
function SetClickAndHoldHandlers() {
// Bug 414797: Clone the back/forward buttons' context menu into both buttons.
@ -579,13 +579,13 @@ function SetClickAndHoldHandlers() {
let backButton = document.getElementById("back-button");
backButton.setAttribute("type", "menu");
backButton.appendChild(popup);
backButton.prepend(popup);
gClickAndHoldListenersOnElement.add(backButton);
let forwardButton = document.getElementById("forward-button");
popup = popup.cloneNode(true);
forwardButton.setAttribute("type", "menu");
forwardButton.appendChild(popup);
forwardButton.prepend(popup);
gClickAndHoldListenersOnElement.add(forwardButton);
}
@ -600,7 +600,7 @@ const gClickAndHoldListenersOnElement = {
return;
// Prevent the menupopup from opening immediately
aEvent.currentTarget.firstElementChild.hidden = true;
aEvent.currentTarget.menupopup.hidden = true;
aEvent.currentTarget.addEventListener("mouseout", this);
aEvent.currentTarget.addEventListener("mouseup", this);
@ -8391,8 +8391,7 @@ var PanicButtonNotifier = {
popup.addEventListener("popuphidden", removeListeners);
let widget = CustomizableUI.getWidget("panic-button").forWindow(window);
let anchor = widget.anchor;
anchor = document.getAnonymousElementByAttribute(anchor, "class", "toolbarbutton-icon");
let anchor = widget.anchor.icon;
popup.openPopup(anchor, popup.getAttribute("position"));
} catch (ex) {
Cu.reportError(ex);

Просмотреть файл

@ -745,7 +745,8 @@
removable="true"/>
<toolbarbutton id="alltabs-button"
class="toolbarbutton-1 chromeclass-toolbar-additional tabs-alltabs-button badged-button"
class="toolbarbutton-1 chromeclass-toolbar-additional tabs-alltabs-button"
badged="true"
oncommand="gTabsPanel.showAllTabsPanel();"
label="&listAllTabs.label;"
tooltiptext="&listAllTabs.label;"
@ -1021,7 +1022,8 @@
during the customization of the toolbar, in the palette, and before
the Downloads Indicator overlay is loaded. -->
<toolbarbutton id="downloads-button"
class="toolbarbutton-1 chromeclass-toolbar-additional badged-button"
class="toolbarbutton-1 chromeclass-toolbar-additional"
badged="true"
key="key_openDownloads"
onmousedown="DownloadsIndicatorView.onCommand(event);"
onkeypress="DownloadsIndicatorView.onCommand(event);"
@ -1057,7 +1059,8 @@
tooltiptext="&libraryButton.tooltip;"
label="&places.library.title;"/>
<toolbarbutton id="fxa-toolbar-menu-button" class="toolbarbutton-1 badged-button chromeclass-toolbar-additional subviewbutton-nav"
<toolbarbutton id="fxa-toolbar-menu-button" class="toolbarbutton-1 chromeclass-toolbar-additional subviewbutton-nav"
badged="true"
onmousedown="gSync.toggleAccountPanel('PanelUI-fxa', event)"
onkeypress="gSync.toggleAccountPanel('PanelUI-fxa', event)"
consumeanchor="fxa-toolbar-menu-button"
@ -1084,7 +1087,8 @@
<toolbaritem id="PanelUI-button"
removable="false">
<toolbarbutton id="PanelUI-menu-button"
class="toolbarbutton-1 badged-button"
class="toolbarbutton-1"
badged="true"
consumeanchor="PanelUI-button"
label="&brandShortName;"
tooltiptext="&appmenu.tooltip;"/>
@ -1203,7 +1207,6 @@
type="menu"
label="&bookmarksMenuButton2.label;"
tooltip="dynamic-shortcut-tooltip"
anchor="dropmarker"
ondragenter="PlacesMenuDNDHandler.onDragEnter(event);"
ondragover="PlacesMenuDNDHandler.onDragOver(event);"
ondragleave="PlacesMenuDNDHandler.onDragLeave(event);"

Просмотреть файл

@ -210,6 +210,9 @@
containersEnabled = false;
}
// There are separate "new tab" buttons for when the tab strip
// is overflowed and when it is not. Attach the long click
// popup to both of them.
const newTab = document.getElementById("new-tab-button");
const newTab2 = document.getAnonymousElementByAttribute(this, "anonid", "tabs-newtab-button");
@ -219,8 +222,8 @@
gClickAndHoldListenersOnElement.remove(parent);
parent.removeAttribute("type");
if (parent.firstElementChild) {
parent.firstElementChild.remove();
if (parent.menupopup) {
parent.menupopup.remove();
}
if (containersEnabled) {
@ -240,7 +243,7 @@
showDefaultTab: Services.prefs.getIntPref("privacy.userContext.longPressBehavior") == 1,
});
});
parent.appendChild(popup);
parent.prepend(popup);
// longPressBehavior == 2 means that the menu is shown after X
// millisecs. Otherwise, with 1, the menu is open immediatelly.

Просмотреть файл

@ -167,8 +167,7 @@ async function test_playing_icon_on_hidden_tab(tab) {
];
let tabContainer = tab.parentNode;
let alltabsButton = document.getElementById("alltabs-button");
let alltabsBadge = document.getAnonymousElementByAttribute(
alltabsButton, "class", "toolbarbutton-badge");
let alltabsBadge = alltabsButton.badgeLabel;
function assertIconShowing() {
is(getComputedStyle(alltabsBadge).backgroundImage,

Просмотреть файл

@ -4438,7 +4438,7 @@ OverflowableToolbar.prototype = {
let mainView = doc.getElementById(mainViewId);
let contextMenu = doc.getElementById(mainView.getAttribute("context"));
gELS.addSystemEventListener(contextMenu, "command", this, true);
let anchor = doc.getAnonymousElementByAttribute(this._chevron, "class", "toolbarbutton-icon");
let anchor = this._chevron.icon;
// Ensure we update the gEditUIVisible flag when opening the popup, in
// case the edit controls are in it.
this._panel.addEventListener("popupshowing", () => doc.defaultView.updateEditUIVisibility(), {once: true});

Просмотреть файл

@ -1348,6 +1348,11 @@ var PanelView = class extends AssociatedToNode {
continue;
}
// Ignore content inside a <toolbarbutton>
if (element.tagName != "toolbarbutton" && element.closest("toolbarbutton")) {
continue;
}
// Take the label for toolbarbuttons; it only exists on those elements.
element = element.multilineLabel || element;

Просмотреть файл

@ -866,11 +866,7 @@ const PanelUI = {
_getBadgeStatus(notification) { return notification.id; },
_getPanelAnchor(candidate) {
let iconAnchor =
document.getAnonymousElementByAttribute(candidate, "class",
"toolbarbutton-badge-stack") ||
document.getAnonymousElementByAttribute(candidate, "class",
"toolbarbutton-icon");
let iconAnchor = candidate.badgeStack || candidate.icon;
return iconAnchor || candidate;
},

Просмотреть файл

@ -30,7 +30,7 @@ const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kForceOverflowWidthPx = 300;
function createDummyXULButton(id, label, win = window) {
let btn = document.createElementNS(kNSXUL, "toolbarbutton");
let btn = win.document.createElementNS(kNSXUL, "toolbarbutton");
btn.id = id;
btn.setAttribute("label", label || id);
btn.className = "toolbarbutton-1 chromeclass-toolbar-additional";
@ -445,8 +445,7 @@ function checkContextMenu(aContextMenu, aExpectedEntries, aWindow = window) {
function waitForOverflowButtonShown(win = window) {
let ov = win.document.getElementById("nav-bar-overflow-button");
let icon = win.document.getAnonymousElementByAttribute(ov, "class", "toolbarbutton-icon");
return waitForElementShown(icon);
return waitForElementShown(ov.icon);
}
function waitForElementShown(element) {
let win = element.ownerGlobal;

Просмотреть файл

@ -613,11 +613,10 @@ const DownloadsIndicatorView = {
let widgetGroup = CustomizableUI.getWidget("downloads-button");
if (widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL) {
let overflowIcon = widgetGroup.forWindow(window).anchor;
return document.getAnonymousElementByAttribute(overflowIcon, "class", "toolbarbutton-icon");
return overflowIcon.icon;
}
return document.getAnonymousElementByAttribute(this.indicator, "class",
"toolbarbutton-badge-stack");
return this.indicator.badgeStack;
},
get _progressIcon() {

Просмотреть файл

@ -34,9 +34,8 @@ add_task(async function test_overflow_anchor() {
let panel = DownloadsPanel.panel;
let chevron = document.getElementById("nav-bar-overflow-button");
let chevronIcon = document.getAnonymousElementByAttribute(chevron,
"class", "toolbarbutton-icon");
is(panel.anchorNode, chevronIcon, "Panel should be anchored to the chevron`s icon.");
is(panel.anchorNode, chevron.icon, "Panel should be anchored to the chevron`s icon.");
DownloadsPanel.hidePanel();
@ -47,8 +46,7 @@ add_task(async function test_overflow_anchor() {
EventUtils.sendMouseEvent({ type: "mousedown", button: 0 }, button.node);
await promise;
let downloadsAnchor = document.getAnonymousElementByAttribute(button.node, "class",
"toolbarbutton-badge-stack");
let downloadsAnchor = button.node.badgeStack;
is(panel.anchorNode, downloadsAnchor);
DownloadsPanel.hidePanel();

Просмотреть файл

@ -275,8 +275,7 @@ class ExtensionControlledPopup {
// Anchor to a toolbar browserAction if found, otherwise use the menu button.
anchorButton = action || doc.getElementById("PanelUI-menu-button");
}
let anchor = doc.getAnonymousElementByAttribute(
anchorButton, "class", "toolbarbutton-icon");
let anchor = anchorButton.icon;
panel.hidden = false;
popupnotification.show();
panel.openPopup(anchor);

Просмотреть файл

@ -165,8 +165,8 @@ this.browserAction = class extends ExtensionAPI {
},
onCreated: node => {
node.classList.add("badged-button");
node.classList.add("webextension-browser-action");
node.setAttribute("badged", "true");
node.setAttribute("constrain-size", "true");
node.setAttribute("data-extensionid", this.extension.id);

Просмотреть файл

@ -129,8 +129,7 @@ async function runTests(options) {
is(button.getAttribute("disabled") == "true", !details.enabled, "disabled state is correct");
if (details.badge) {
let badge = button.ownerDocument.getAnonymousElementByAttribute(
button, "class", "toolbarbutton-badge");
let badge = button.badgeLabel;
let style = window.getComputedStyle(badge);
let expected = {
backgroundColor: serializeColor(details.badgeBackgroundColor),
@ -426,7 +425,7 @@ add_task(async function testBadgeColorPersistence() {
function getBadgeForWindow(win) {
const widget = getBrowserActionWidget(extension).forWindow(win).node;
return document.getAnonymousElementByAttribute(widget, "class", "toolbarbutton-badge");
return widget.badgeLabel;
}
let badge = getBadgeForWindow(window);

Просмотреть файл

@ -247,7 +247,7 @@ add_task(async function browseraction_contextmenu_manage_extension() {
info("Wait until the overflow menu is ready");
let overflowButton = win.document.getElementById("nav-bar-overflow-button");
let icon = win.document.getAnonymousElementByAttribute(overflowButton, "class", "toolbarbutton-icon");
let icon = overflowButton.icon;
await waitForElementShown(icon);
if (!customizing) {
@ -326,7 +326,7 @@ async function runTestContextMenu({
info("Wait until the overflow menu is ready");
let overflowButton = win.document.getElementById("nav-bar-overflow-button");
let icon = win.document.getAnonymousElementByAttribute(overflowButton, "class", "toolbarbutton-icon");
let icon = overflowButton.icon;
await waitForElementShown(icon);
if (!customizing) {

Просмотреть файл

@ -1519,7 +1519,7 @@ PlacesToolbar.prototype = {
// If the menu is open, close it.
if (draggedElt.open) {
draggedElt.lastElementChild.hidePopup();
draggedElt.menupopup.hidePopup();
draggedElt.open = false;
}
}

Просмотреть файл

@ -289,7 +289,7 @@ function getNodeForToolbarItem(itemGuid, validator) {
// Don't search in queries, they could contain our item in a
// different position. Search only folders
if (PlacesUtils.nodeIsFolder(child._placesNode)) {
var popup = child.lastElementChild;
var popup = child.menupopup;
popup.openPopup();
var foundNode = findNode(popup);
popup.hidePopup();

Просмотреть файл

@ -37,7 +37,7 @@ add_task(async function test() {
Assert.equal(menuButton.type, "menu", "A menu button");
// Mouse over the menu button to open it.
let buttonPopup = menuButton.firstElementChild;
let buttonPopup = menuButton.menupopup;
promise = promiseEvent(buttonPopup, "popupshown");
EventUtils.synthesizeMouse(menuButton, 5, 5, { type: "mousemove" });
await promise;

Просмотреть файл

@ -2331,7 +2331,7 @@ var SessionStoreInternal = {
// Tell our caller to redirect the load into this newly created process.
let remoteTab = aBrowser.frameLoader.remoteTab;
debug(`[process-switch]: new tabID: ${remoteTab.tabId}`);
return remoteTab;
return remoteTab.contentProcessId;
},
/**

Просмотреть файл

@ -87,9 +87,7 @@ var UITour = {
// Otherwise use the sync setup icon.
let statusButton = aDocument.getElementById("appMenu-fxa-label");
return aDocument.getAnonymousElementByAttribute(statusButton,
"class",
"toolbarbutton-icon");
return statusButton.icon;
},
// This is a fake widgetName starting with the "appMenu-" prefix so we know
// to automatically open the appMenu when annotating this target.

Просмотреть файл

@ -455,6 +455,9 @@ var PageActions = {
* some reason. You can also pass an object that maps pixel sizes to
* URLs, like { 16: url16, 32: url32 }. The best size for the user's
* screen will be used.
* @param isBadged (bool, optional)
* If true, the toolbarbutton for this action will get the
* "badged-button" class.
* @param onBeforePlacedInWindow (function, optional)
* Called before the action is placed in the window:
* onBeforePlacedInWindow(window)
@ -537,6 +540,7 @@ function Action(options) {
disabled: false,
extensionID: false,
iconURL: false,
isBadged: false,
labelForHistogram: false,
onBeforePlacedInWindow: false,
onCommand: false,
@ -816,6 +820,10 @@ Action.prototype = {
return this._wantsIframe || false;
},
get isBadged() {
return this._isBadged || false;
},
get labelForHistogram() {
// The histogram label value has a length limit of 20 and restricted to a
// pattern. See MAX_LABEL_LENGTH and CPP_IDENTIFIER_PATTERN in
@ -1184,6 +1192,7 @@ var gBuiltInActions = [
id: "addSearchEngine",
// The title is set in browser-pageActions.js.
title: "",
isBadged: true,
_transient: true,
onShowingInPanel(buttonNode) {
browserPageActions(buttonNode).addSearchEngine.onShowingInPanel();

Просмотреть файл

@ -12,14 +12,14 @@ const TEST_URL = URL_ROOT + "doc_markup_anonymous_xul.xul";
add_task(async function() {
const {inspector} = await openInspectorForURL(TEST_URL);
const toolbarbutton = await getNodeFront("toolbarbutton", inspector);
const children = await inspector.walker.children(toolbarbutton);
const boundNode = await getNodeFront("#xbl-host", inspector);
const children = await inspector.walker.children(boundNode);
is(toolbarbutton.numChildren, 4, "Correct number of children");
is(children.nodes.length, 4, "Children returned from walker");
is(boundNode.numChildren, 2, "Correct number of children");
is(children.nodes.length, 2, "Children returned from walker");
is(toolbarbutton.isAnonymous, false, "Toolbarbutton is not anonymous");
await isEditingMenuEnabled(toolbarbutton, inspector);
is(boundNode.isAnonymous, false, "Node with XBL binding is not anonymous");
await isEditingMenuEnabled(boundNode, inspector);
for (const node of children.nodes) {
ok(node.isAnonymous, "Child is anonymous");

Просмотреть файл

@ -3,6 +3,15 @@
<xul:window xmlns="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Test anonymous xul nodes.">
<xul:toolbarbutton id="test"></xul:toolbarbutton>
<xbl:bindings xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gaktekeeper/there.is.only.xul">
<xbl:binding id="test">
<xbl:content>
<xul:box anonid="xbl-anon1">Anonymous</xul:box>
<xul:box anonid="xbl-anon2">Anonymous</xul:box>
</xbl:content>
</xbl:binding>
</xbl:bindings>
<box id="xbl-host" style="-moz-binding: url(#test)"/>
</xul:window>

Просмотреть файл

@ -26,7 +26,7 @@ nsDocShell* ParentSHistory::GetDocShell() {
}
BrowserParent* ParentSHistory::GetBrowserParent() {
return static_cast<BrowserParent*>(mFrameLoader->GetRemoteBrowser());
return mFrameLoader->GetBrowserParent();
}
already_AddRefed<ChildSHistory> ParentSHistory::GetChildIfSameProcess() {

Просмотреть файл

@ -552,11 +552,11 @@ nsresult DragDataProducer::Produce(DataTransfer* aDataTransfer, bool* aCanDrag,
if (flo) {
RefPtr<nsFrameLoader> fl = flo->GetFrameLoader();
if (fl) {
BrowserParent* tp = static_cast<BrowserParent*>(fl->GetRemoteBrowser());
if (tp) {
BrowserParent* bp = fl->GetBrowserParent();
if (bp) {
// We have a BrowserParent, so it may have data for dnd in case the
// child process started a dnd session.
tp->AddInitialDnDDataTo(aDataTransfer, aPrincipal);
bp->AddInitialDnDDataTo(aDataTransfer, aPrincipal);
}
}
}

Просмотреть файл

@ -60,7 +60,8 @@ class nsAttrHashKey : public PLDHashEntryHdr {
typedef const nsAttrKey* KeyTypePointer;
explicit nsAttrHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
nsAttrHashKey(const nsAttrHashKey& aCopy) : mKey(aCopy.mKey) {}
nsAttrHashKey(const nsAttrHashKey& aCopy)
: PLDHashEntryHdr{}, mKey(aCopy.mKey) {}
~nsAttrHashKey() {}
KeyType GetKey() const { return mKey; }

Просмотреть файл

@ -109,6 +109,8 @@
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/BrowserBridgeChild.h"
#include "mozilla/dom/BrowserHost.h"
#include "mozilla/dom/BrowserBridgeHost.h"
#include "mozilla/dom/HTMLBodyElement.h"
@ -155,7 +157,7 @@ typedef ScrollableLayerGuid::ViewID ViewID;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsFrameLoader, mBrowsingContext,
mMessageManager, mChildMessageManager,
mParentSHistory, mBrowserParent)
mParentSHistory, mRemoteBrowser)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader)
@ -172,7 +174,6 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
mOwnerContent(aOwner),
mDetachedSubdocFrame(nullptr),
mPendingSwitchID(0),
mBrowserParent(nullptr),
mChildID(0),
mDepthTooGreat(false),
mIsTopLevelContent(false),
@ -197,7 +198,6 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
mOwnerContent(aOwner),
mDetachedSubdocFrame(nullptr),
mPendingSwitchID(0),
mBrowserParent(nullptr),
mChildID(0),
mDepthTooGreat(false),
mIsTopLevelContent(false),
@ -543,28 +543,16 @@ nsresult nsFrameLoader::ReallyStartLoadingInternal() {
AUTO_PROFILER_LABEL("nsFrameLoader::ReallyStartLoadingInternal", OTHER);
if (IsRemoteFrame()) {
if (!mBrowserParent && !mBrowserBridgeChild && !TryRemoteBrowser()) {
if (!EnsureRemoteBrowser()) {
NS_WARNING("Couldn't create child process for iframe.");
return NS_ERROR_FAILURE;
}
if (mPendingSwitchID) {
if (mBrowserBridgeChild) {
Unused << mBrowserBridgeChild->SendResumeLoad(mPendingSwitchID);
} else {
mBrowserParent->ResumeLoad(mPendingSwitchID);
}
mRemoteBrowser->ResumeLoad(mPendingSwitchID);
mPendingSwitchID = 0;
} else {
if (mBrowserBridgeChild) {
nsAutoCString spec;
mURIToLoad->GetSpec(spec);
Unused << mBrowserBridgeChild->SendLoadURL(spec);
} else {
// FIXME get error codes from child
mBrowserParent->LoadURL(mURIToLoad);
}
mRemoteBrowser->LoadURL(mURIToLoad);
}
if (!mRemoteBrowserShown) {
@ -1029,7 +1017,7 @@ bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
NS_ASSERTION(IsRemoteFrame(),
"ShowRemote only makes sense on remote frames.");
if (!mBrowserParent && !mBrowserBridgeChild && !TryRemoteBrowser()) {
if (!EnsureRemoteBrowser()) {
NS_ERROR("Couldn't create child process.");
return false;
}
@ -1048,7 +1036,8 @@ bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
return false;
}
if (mBrowserBridgeChild) {
if (RefPtr<BrowserBridgeChild> browserBridgeChild =
GetBrowserBridgeChild()) {
nsCOMPtr<nsISupports> container =
mOwnerContent->OwnerDoc()->GetContainer();
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
@ -1057,21 +1046,16 @@ bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
nsSizeMode sizeMode =
mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
Unused << mBrowserBridgeChild->SendShow(
Unused << browserBridgeChild->SendShow(
size, ParentWindowIsActive(mOwnerContent->OwnerDoc()), sizeMode);
mRemoteBrowserShown = true;
return true;
}
RenderFrame* rf =
mBrowserParent ? mBrowserParent->GetRenderFrame() : nullptr;
if (!rf || !rf->AttachLayerManager()) {
// This is just not going to work.
if (!mRemoteBrowser->Show(
size, ParentWindowIsActive(mOwnerContent->OwnerDoc()))) {
return false;
}
mBrowserParent->Show(size, ParentWindowIsActive(mOwnerContent->OwnerDoc()));
mRemoteBrowserShown = true;
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
@ -1084,11 +1068,7 @@ bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
// Don't show remote iframe if we are waiting for the completion of reflow.
if (!aFrame || !(aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
if (mBrowserParent) {
mBrowserParent->UpdateDimensions(dimensions, size);
} else if (mBrowserBridgeChild) {
mBrowserBridgeChild->UpdateDimensions(dimensions, size);
}
mRemoteBrowser->UpdateDimensions(dimensions, size);
}
}
@ -1181,17 +1161,15 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
return NS_ERROR_NOT_IMPLEMENTED;
}
// FIXME: Consider supporting FrameLoader swapping for remote sub frames.
if (mBrowserBridgeChild) {
auto* browserParent = GetBrowserParent();
auto* otherBrowserParent = aOther->GetBrowserParent();
if (!browserParent || !otherBrowserParent) {
return NS_ERROR_NOT_IMPLEMENTED;
}
if (!mBrowserParent || !aOther->mBrowserParent) {
return NS_ERROR_NOT_IMPLEMENTED;
}
if (mBrowserParent->IsIsolatedMozBrowserElement() !=
aOther->mBrowserParent->IsIsolatedMozBrowserElement()) {
if (browserParent->IsIsolatedMozBrowserElement() !=
otherBrowserParent->IsIsolatedMozBrowserElement()) {
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -1203,12 +1181,12 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
// This is the reason why now we must retrieve the correct value from the
// usercontextid attribute before comparing our originAttributes with the
// other one.
OriginAttributes ourOriginAttributes = mBrowserParent->OriginAttributesRef();
OriginAttributes ourOriginAttributes = browserParent->OriginAttributesRef();
rv = PopulateUserContextIdFromAttribute(ourOriginAttributes);
NS_ENSURE_SUCCESS(rv, rv);
OriginAttributes otherOriginAttributes =
aOther->mBrowserParent->OriginAttributesRef();
otherBrowserParent->OriginAttributesRef();
rv = aOther->PopulateUserContextIdFromAttribute(otherOriginAttributes);
NS_ENSURE_SUCCESS(rv, rv);
@ -1252,9 +1230,9 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
}
nsCOMPtr<nsIBrowserDOMWindow> otherBrowserDOMWindow =
aOther->mBrowserParent->GetBrowserDOMWindow();
otherBrowserParent->GetBrowserDOMWindow();
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWindow =
mBrowserParent->GetBrowserDOMWindow();
browserParent->GetBrowserDOMWindow();
if (!!otherBrowserDOMWindow != !!browserDOMWindow) {
return NS_ERROR_NOT_IMPLEMENTED;
@ -1268,8 +1246,8 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
aOther->DestroyBrowserFrameScripts();
}
aOther->mBrowserParent->SetBrowserDOMWindow(browserDOMWindow);
mBrowserParent->SetBrowserDOMWindow(otherBrowserDOMWindow);
otherBrowserParent->SetBrowserDOMWindow(browserDOMWindow);
browserParent->SetBrowserDOMWindow(otherBrowserDOMWindow);
#ifdef XP_WIN
// Native plugin windows used by this remote content need to be reparented.
@ -1277,7 +1255,7 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
RefPtr<nsIWidget> newParent =
nsGlobalWindowOuter::Cast(newWin)->GetMainWidget();
const ManagedContainer<mozilla::plugins::PPluginWidgetParent>& plugins =
aOther->mBrowserParent->ManagedPPluginWidgetParent();
otherBrowserParent->ManagedPPluginWidgetParent();
for (auto iter = plugins.ConstIter(); !iter.Done(); iter.Next()) {
static_cast<mozilla::plugins::PluginWidgetParent*>(iter.Get()->GetKey())
->SetParent(newParent);
@ -1291,13 +1269,13 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
SetOwnerContent(otherContent);
aOther->SetOwnerContent(ourContent);
mBrowserParent->SetOwnerElement(otherContent);
aOther->mBrowserParent->SetOwnerElement(ourContent);
browserParent->SetOwnerElement(otherContent);
otherBrowserParent->SetOwnerElement(ourContent);
// Update window activation state for the swapped owner content.
Unused << mBrowserParent->SendParentActivated(
Unused << browserParent->SendParentActivated(
ParentWindowIsActive(otherContent->OwnerDoc()));
Unused << aOther->mBrowserParent->SendParentActivated(
Unused << otherBrowserParent->SendParentActivated(
ParentWindowIsActive(ourContent->OwnerDoc()));
MaybeUpdatePrimaryBrowserParent(eBrowserParentChanged);
@ -1344,9 +1322,9 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
return rv;
}
Unused << mBrowserParent->SendSwappedWithOtherRemoteLoader(
Unused << browserParent->SendSwappedWithOtherRemoteLoader(
ourContext.AsIPCTabContext());
Unused << aOther->mBrowserParent->SendSwappedWithOtherRemoteLoader(
Unused << otherBrowserParent->SendSwappedWithOtherRemoteLoader(
otherContext.AsIPCTabContext());
return NS_OK;
}
@ -1800,10 +1778,10 @@ void nsFrameLoader::StartDestroy() {
// Retain references to the <browser> element and the frameloader in case we
// receive any messages from the message manager on the frame. These
// references are dropped in DestroyComplete.
if (mChildMessageManager || mBrowserParent) {
if (mChildMessageManager || mRemoteBrowser) {
mOwnerContentStrong = mOwnerContent;
if (mBrowserParent) {
mBrowserParent->CacheFrameLoader(this);
if (auto* browserParent = GetBrowserParent()) {
browserParent->CacheFrameLoader(this);
}
if (mChildMessageManager) {
mChildMessageManager->CacheFrameLoader(this);
@ -1812,8 +1790,8 @@ void nsFrameLoader::StartDestroy() {
// If the BrowserParent has installed any event listeners on the window, this
// is its last chance to remove them while we're still in the document.
if (mBrowserParent) {
mBrowserParent->RemoveWindowListeners();
if (auto* browserParent = GetBrowserParent()) {
browserParent->RemoveWindowListeners();
}
nsCOMPtr<Document> doc;
@ -1912,13 +1890,8 @@ void nsFrameLoader::DestroyDocShell() {
// Ask the BrowserChild to fire the frame script "unload" event, destroy its
// docshell, and finally destroy the PBrowser actor. This eventually leads to
// nsFrameLoader::DestroyComplete being called.
if (mBrowserParent) {
mBrowserParent->Destroy();
}
if (mBrowserBridgeChild) {
Unused << mBrowserBridgeChild->Send__delete__(mBrowserBridgeChild);
mBrowserBridgeChild = nullptr;
if (mRemoteBrowser) {
mRemoteBrowser->DestroyStart();
}
// Fire the "unload" event if we're in-process.
@ -1951,10 +1924,10 @@ void nsFrameLoader::DestroyComplete() {
// case, StartDestroy might not have been called.
// Drop the strong references created in StartDestroy.
if (mChildMessageManager || mBrowserParent) {
if (mChildMessageManager || mRemoteBrowser) {
mOwnerContentStrong = nullptr;
if (mBrowserParent) {
mBrowserParent->CacheFrameLoader(nullptr);
if (auto* browserParent = GetBrowserParent()) {
browserParent->CacheFrameLoader(nullptr);
}
if (mChildMessageManager) {
mChildMessageManager->CacheFrameLoader(nullptr);
@ -1962,15 +1935,9 @@ void nsFrameLoader::DestroyComplete() {
}
// Call BrowserParent::Destroy if we haven't already (in case of a crash).
if (mBrowserParent) {
mBrowserParent->SetOwnerElement(nullptr);
mBrowserParent->Destroy();
mBrowserParent = nullptr;
}
if (mBrowserBridgeChild) {
Unused << mBrowserBridgeChild->Send__delete__(mBrowserBridgeChild);
mBrowserBridgeChild = nullptr;
if (mRemoteBrowser) {
mRemoteBrowser->DestroyComplete();
mRemoteBrowser = nullptr;
}
if (mMessageManager) {
@ -2494,7 +2461,7 @@ nsresult nsFrameLoader::GetWindowDimensions(nsIntRect& aRect) {
nsresult nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame* aIFrame) {
if (IsRemoteFrame()) {
if (mBrowserParent || mBrowserBridgeChild) {
if (mRemoteBrowser) {
ScreenIntSize size = aIFrame->GetSubdocumentSize();
// If we were not able to show remote frame before, we should probably
// retry now to send correct showInfo.
@ -2504,11 +2471,7 @@ nsresult nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame* aIFrame) {
nsIntRect dimensions;
NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), NS_ERROR_FAILURE);
mLazySize = size;
if (mBrowserParent) {
mBrowserParent->UpdateDimensions(dimensions, size);
} else if (mBrowserBridgeChild) {
mBrowserBridgeChild->UpdateDimensions(dimensions, size);
}
mRemoteBrowser->UpdateDimensions(dimensions, size);
}
return NS_OK;
}
@ -2520,8 +2483,8 @@ void nsFrameLoader::SendIsUnderHiddenEmbedderElement(
bool aIsUnderHiddenEmbedderElement) {
MOZ_ASSERT(IsRemoteFrame());
if (mBrowserBridgeChild) {
mBrowserBridgeChild->SetIsUnderHiddenEmbedderElement(
if (auto* browserBridgeChild = GetBrowserBridgeChild()) {
browserBridgeChild->SetIsUnderHiddenEmbedderElement(
aIsUnderHiddenEmbedderElement);
}
}
@ -2597,8 +2560,13 @@ static Tuple<ContentParent*, BrowserParent*> GetContentParent(
return ReturnTuple(nullptr, nullptr);
}
bool nsFrameLoader::EnsureRemoteBrowser() {
MOZ_ASSERT(IsRemoteFrame());
return mRemoteBrowser || TryRemoteBrowser();
}
bool nsFrameLoader::TryRemoteBrowser() {
NS_ASSERTION(!mBrowserParent && !mBrowserBridgeChild,
NS_ASSERTION(!mRemoteBrowser,
"TryRemoteBrowser called with a remote browser already?");
if (!mOwnerContent) {
@ -2631,13 +2599,10 @@ bool nsFrameLoader::TryRemoteBrowser() {
return false;
}
BrowserParent* openingTab =
BrowserParent::GetFrom(parentDocShell->GetOpener());
RefPtr<ContentParent> openerContentParent;
RefPtr<BrowserParent> sameTabGroupAs;
if (openingTab && openingTab->Manager()) {
openerContentParent = openingTab->Manager();
if (auto* host = BrowserHost::GetFrom(parentDocShell->GetOpener())) {
openerContentParent = host->GetActor()->Manager();
}
// <iframe mozbrowser> gets to skip these checks.
@ -2720,29 +2685,32 @@ bool nsFrameLoader::TryRemoteBrowser() {
if (XRE_IsContentProcess()) {
mBrowsingContext->SetEmbedderElement(mOwnerContent);
mBrowserBridgeChild = BrowserBridgeChild::Create(
mRemoteBrowser = ContentChild::CreateBrowser(
this, context, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
mBrowsingContext);
return !!mBrowserBridgeChild;
return !!mRemoteBrowser;
}
mBrowserParent = ContentParent::CreateBrowser(
mRemoteBrowser = ContentParent::CreateBrowser(
context, ownerElement, mBrowsingContext, openerContentParent,
sameTabGroupAs, nextRemoteTabId);
if (!mBrowserParent) {
if (!mRemoteBrowser) {
return false;
}
// Grab the reference to the actor
RefPtr<BrowserParent> browserParent = GetBrowserParent();
// We no longer need the remoteType attribute on the frame element.
// The remoteType can be queried by asking the message manager instead.
ownerElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType, false);
// Now that mBrowserParent is set, we can initialize the RenderFrame
mBrowserParent->InitRendering();
// Now that browserParent is set, we can initialize the RenderFrame
browserParent->InitRendering();
MaybeUpdatePrimaryBrowserParent(eBrowserParentChanged);
mChildID = mBrowserParent->Manager()->ChildID();
mChildID = browserParent->Manager()->ChildID();
nsCOMPtr<nsIDocShellTreeItem> rootItem;
parentDocShell->GetRootTreeItem(getter_AddRefs(rootItem));
@ -2752,7 +2720,7 @@ bool nsFrameLoader::TryRemoteBrowser() {
if (rootChromeWin) {
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
mBrowserParent->SetBrowserDOMWindow(browserDOMWin);
browserParent->SetBrowserDOMWindow(browserDOMWin);
}
// Set up a parent SHistory
@ -2765,17 +2733,17 @@ bool nsFrameLoader::TryRemoteBrowser() {
// For xul:browsers, update some settings based on attributes:
if (mOwnerContent->IsXULElement()) {
// Send down the name of the browser through mBrowserParent if it is set.
// Send down the name of the browser through browserParent if it is set.
nsAutoString frameName;
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName);
if (nsContentUtils::IsOverridingWindowName(frameName)) {
Unused << mBrowserParent->SendSetWindowName(frameName);
Unused << browserParent->SendSetWindowName(frameName);
}
// Allow scripts to close the window if the browser specified so:
if (mOwnerContent->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::allowscriptstoclose,
nsGkAtoms::_true, eCaseMatters)) {
Unused << mBrowserParent->SendAllowScriptsToClose();
Unused << browserParent->SendAllowScriptsToClose();
}
}
@ -2793,41 +2761,58 @@ bool nsFrameLoader::IsRemoteFrame() {
return false;
}
mozilla::dom::PBrowserParent* nsFrameLoader::GetRemoteBrowser() const {
return mBrowserParent;
BrowserParent* nsFrameLoader::GetBrowserParent() const {
if (!mRemoteBrowser) {
return nullptr;
}
RefPtr<BrowserHost> browserHost = mRemoteBrowser->AsBrowserHost();
if (!browserHost) {
return nullptr;
}
return browserHost->GetActor();
}
mozilla::dom::BrowserBridgeChild* nsFrameLoader::GetBrowserBridgeChild() const {
return mBrowserBridgeChild;
BrowserBridgeChild* nsFrameLoader::GetBrowserBridgeChild() const {
if (!mRemoteBrowser) {
return nullptr;
}
RefPtr<BrowserBridgeHost> browserBridgeHost =
mRemoteBrowser->AsBrowserBridgeHost();
if (!browserBridgeHost) {
return nullptr;
}
return browserBridgeHost->GetActor();
}
mozilla::layers::LayersId nsFrameLoader::GetLayersId() const {
MOZ_ASSERT(mIsRemoteFrame);
if (mBrowserParent) {
return mBrowserParent->GetRenderFrame()->GetLayersId();
if (auto* browserParent = GetBrowserParent()) {
return browserParent->GetRenderFrame()->GetLayersId();
}
if (mBrowserBridgeChild) {
return mBrowserBridgeChild->GetLayersId();
if (auto* browserBridgeChild = GetBrowserBridgeChild()) {
return browserBridgeChild->GetLayersId();
}
return mozilla::layers::LayersId{};
}
void nsFrameLoader::ActivateRemoteFrame(ErrorResult& aRv) {
if (!mBrowserParent) {
auto* browserParent = GetBrowserParent();
if (!browserParent) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
mBrowserParent->Activate();
browserParent->Activate();
}
void nsFrameLoader::DeactivateRemoteFrame(ErrorResult& aRv) {
if (!mBrowserParent) {
auto* browserParent = GetBrowserParent();
if (!browserParent) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
mBrowserParent->Deactivate();
browserParent->Deactivate();
}
void nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType, float aX,
@ -2836,23 +2821,25 @@ void nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType, float aX,
int32_t aModifiers,
bool aIgnoreRootScrollFrame,
ErrorResult& aRv) {
if (!mBrowserParent) {
auto* browserParent = GetBrowserParent();
if (!browserParent) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
mBrowserParent->SendMouseEvent(aType, aX, aY, aButton, aClickCount,
aModifiers, aIgnoreRootScrollFrame);
browserParent->SendMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers,
aIgnoreRootScrollFrame);
}
void nsFrameLoader::ActivateFrameEvent(const nsAString& aType, bool aCapture,
ErrorResult& aRv) {
if (!mBrowserParent) {
auto* browserParent = GetBrowserParent();
if (!browserParent) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
bool ok = mBrowserParent->SendActivateFrameEvent(nsString(aType), aCapture);
bool ok = browserParent->SendActivateFrameEvent(nsString(aType), aCapture);
if (!ok) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
}
@ -2883,8 +2870,7 @@ nsresult nsFrameLoader::CreateStaticClone(nsFrameLoader* aDest) {
bool nsFrameLoader::DoLoadMessageManagerScript(const nsAString& aURL,
bool aRunInGlobalScope) {
auto* browserParent = BrowserParent::GetFrom(GetRemoteBrowser());
if (browserParent) {
if (auto* browserParent = GetBrowserParent()) {
return browserParent->SendLoadRemoteScript(nsString(aURL),
aRunInGlobalScope);
}
@ -2928,7 +2914,7 @@ nsresult nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal) {
BrowserParent* browserParent = mBrowserParent;
auto* browserParent = GetBrowserParent();
if (browserParent) {
ClonedMessageData data;
ContentParent* cp = browserParent->Manager();
@ -3048,15 +3034,15 @@ already_AddRefed<Element> nsFrameLoader::GetOwnerElement() {
return do_AddRef(mOwnerContent);
}
void nsFrameLoader::SetRemoteBrowser(nsIRemoteTab* aBrowserParent) {
MOZ_ASSERT(!mBrowserParent);
void nsFrameLoader::InitializeFromBrowserParent(BrowserParent* aBrowserParent) {
MOZ_ASSERT(!mRemoteBrowser);
mIsRemoteFrame = true;
mBrowserParent = BrowserParent::GetFrom(aBrowserParent);
mChildID = mBrowserParent ? mBrowserParent->Manager()->ChildID() : 0;
mRemoteBrowser = new BrowserHost(aBrowserParent);
mChildID = aBrowserParent ? aBrowserParent->Manager()->ChildID() : 0;
MaybeUpdatePrimaryBrowserParent(eBrowserParentChanged);
ReallyLoadFrameScripts();
InitializeBrowserAPI();
mBrowserParent->InitRendering();
aBrowserParent->InitRendering();
ShowRemoteFrame(ScreenIntSize(0, 0));
}
@ -3160,13 +3146,13 @@ void nsFrameLoader::AttributeChanged(mozilla::dom::Element* aElement,
*/
void nsFrameLoader::RequestNotifyAfterRemotePaint() {
// If remote browsing (e10s), handle this with the BrowserParent.
if (mBrowserParent) {
Unused << mBrowserParent->SendRequestNotifyAfterRemotePaint();
if (auto* browserParent = GetBrowserParent()) {
Unused << browserParent->SendRequestNotifyAfterRemotePaint();
}
}
void nsFrameLoader::RequestUpdatePosition(ErrorResult& aRv) {
if (auto* browserParent = BrowserParent::GetFrom(GetRemoteBrowser())) {
if (auto* browserParent = GetBrowserParent()) {
nsresult rv = browserParent->UpdatePosition();
if (NS_FAILED(rv)) {
@ -3183,8 +3169,8 @@ bool nsFrameLoader::RequestTabStateFlush(uint32_t aFlushId, bool aIsFinal) {
}
// If remote browsing (e10s), handle this with the BrowserParent.
if (mBrowserParent) {
Unused << mBrowserParent->SendFlushTabState(aFlushId, aIsFinal);
if (auto* browserParent = GetBrowserParent()) {
Unused << browserParent->SendFlushTabState(aFlushId, aIsFinal);
return true;
}
@ -3196,9 +3182,9 @@ void nsFrameLoader::Print(uint64_t aOuterWindowID,
nsIWebProgressListener* aProgressListener,
ErrorResult& aRv) {
#if defined(NS_PRINTING)
if (mBrowserParent) {
if (auto* browserParent = GetBrowserParent()) {
RefPtr<embedding::PrintingParent> printingParent =
mBrowserParent->Manager()->GetPrintingParent();
browserParent->Manager()->GetPrintingParent();
embedding::PrintData printData;
nsresult rv = printingParent->SerializeAndEnsureRemotePrintJob(
@ -3208,7 +3194,7 @@ void nsFrameLoader::Print(uint64_t aOuterWindowID,
return;
}
bool success = mBrowserParent->SendPrint(aOuterWindowID, printData);
bool success = browserParent->SendPrint(aOuterWindowID, printData);
if (!success) {
aRv.Throw(NS_ERROR_FAILURE);
}
@ -3240,6 +3226,12 @@ void nsFrameLoader::Print(uint64_t aOuterWindowID,
already_AddRefed<mozilla::dom::Promise> nsFrameLoader::DrawSnapshot(
double aX, double aY, double aW, double aH, double aScale,
const nsAString& aBackgroundColor, mozilla::ErrorResult& aRv) {
MOZ_ASSERT(XRE_IsParentProcess());
if (!XRE_IsParentProcess()) {
aRv = NS_ERROR_FAILURE;
return nullptr;
}
RefPtr<nsIGlobalObject> global = GetOwnerContent()->GetOwnerGlobal();
RefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
@ -3269,7 +3261,7 @@ already_AddRefed<mozilla::dom::Promise> nsFrameLoader::DrawSnapshot(
gfx::IntRect rect = gfx::IntRect::RoundOut(gfx::Rect(aX, aY, aW, aH));
if (IsRemoteFrame()) {
gfx::CrossProcessPaint::StartRemote(mBrowserParent->GetTabId(), rect,
gfx::CrossProcessPaint::StartRemote(GetBrowserParent()->GetTabId(), rect,
aScale, color, promise);
} else {
gfx::CrossProcessPaint::StartLocal(GetDocShell(), rect, aScale, color,
@ -3280,18 +3272,19 @@ already_AddRefed<mozilla::dom::Promise> nsFrameLoader::DrawSnapshot(
}
already_AddRefed<nsIRemoteTab> nsFrameLoader::GetRemoteTab() {
return do_AddRef(mBrowserParent);
if (!mRemoteBrowser) {
return nullptr;
}
if (auto* browserHost = mRemoteBrowser->AsBrowserHost()) {
return do_AddRef(browserHost);
}
return nullptr;
}
already_AddRefed<nsILoadContext> nsFrameLoader::LoadContext() {
nsCOMPtr<nsILoadContext> loadContext;
if (IsRemoteFrame() &&
(mBrowserParent || mBrowserBridgeChild || TryRemoteBrowser())) {
if (mBrowserParent) {
loadContext = mBrowserParent->GetLoadContext();
} else {
loadContext = mBrowserBridgeChild->GetLoadContext();
}
if (IsRemoteFrame() && EnsureRemoteBrowser()) {
loadContext = mRemoteBrowser->GetLoadContext();
} else {
loadContext = do_GetInterface(ToSupports(GetDocShell(IgnoreErrors())));
}
@ -3300,13 +3293,8 @@ already_AddRefed<nsILoadContext> nsFrameLoader::LoadContext() {
already_AddRefed<BrowsingContext> nsFrameLoader::GetBrowsingContext() {
RefPtr<BrowsingContext> browsingContext;
if (IsRemoteFrame() &&
(mBrowserParent || mBrowserBridgeChild || TryRemoteBrowser())) {
if (mBrowserParent) {
browsingContext = mBrowserParent->GetBrowsingContext();
} else {
browsingContext = mBrowserBridgeChild->GetBrowsingContext();
}
if (IsRemoteFrame() && EnsureRemoteBrowser()) {
browsingContext = mRemoteBrowser->GetBrowsingContext();
} else if (GetDocShell(IgnoreErrors())) {
browsingContext = GetDocShell()->GetBrowsingContext();
}
@ -3350,8 +3338,8 @@ void nsFrameLoader::StartPersistence(
ErrorResult& aRv) {
MOZ_ASSERT(aRecv);
if (mBrowserParent) {
mBrowserParent->StartPersistence(aOuterWindowID, aRecv, aRv);
if (auto* browserParent = GetBrowserParent()) {
browserParent->StartPersistence(aOuterWindowID, aRecv, aRv);
return;
}
@ -3376,34 +3364,41 @@ void nsFrameLoader::StartPersistence(
void nsFrameLoader::MaybeUpdatePrimaryBrowserParent(
BrowserParentChange aChange) {
if (mBrowserParent && mOwnerContent) {
nsCOMPtr<nsIDocShell> docShell = mOwnerContent->OwnerDoc()->GetDocShell();
if (!docShell) {
return;
}
if (!mOwnerContent || !mRemoteBrowser) {
return;
}
int32_t parentType = docShell->ItemType();
if (parentType != nsIDocShellTreeItem::typeChrome) {
return;
}
RefPtr<BrowserHost> browserHost = mRemoteBrowser->AsBrowserHost();
if (!browserHost) {
return;
}
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
if (!parentTreeOwner) {
return;
}
nsCOMPtr<nsIDocShell> docShell = mOwnerContent->OwnerDoc()->GetDocShell();
if (!docShell) {
return;
}
if (!mObservingOwnerContent) {
mOwnerContent->AddMutationObserver(this);
mObservingOwnerContent = true;
}
int32_t parentType = docShell->ItemType();
if (parentType != nsIDocShellTreeItem::typeChrome) {
return;
}
parentTreeOwner->RemoteTabRemoved(mBrowserParent);
if (aChange == eBrowserParentChanged) {
bool isPrimary = mOwnerContent->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::primary, nsGkAtoms::_true, eIgnoreCase);
parentTreeOwner->RemoteTabAdded(mBrowserParent, isPrimary);
}
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
if (!parentTreeOwner) {
return;
}
if (!mObservingOwnerContent) {
mOwnerContent->AddMutationObserver(this);
mObservingOwnerContent = true;
}
parentTreeOwner->RemoteTabRemoved(browserHost);
if (aChange == eBrowserParentChanged) {
bool isPrimary = mOwnerContent->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::primary, nsGkAtoms::_true, eIgnoreCase);
parentTreeOwner->RemoteTabAdded(browserHost, isPrimary);
}
}
@ -3478,8 +3473,10 @@ nsresult nsFrameLoader::PopulateUserContextIdFromAttribute(
}
ProcessMessageManager* nsFrameLoader::GetProcessMessageManager() const {
return mBrowserParent ? mBrowserParent->Manager()->GetMessageManager()
: nullptr;
if (auto* browserParent = GetBrowserParent()) {
return browserParent->Manager()->GetMessageManager();
}
return nullptr;
};
JSObject* nsFrameLoader::WrapObject(JSContext* cx,
@ -3492,12 +3489,12 @@ JSObject* nsFrameLoader::WrapObject(JSContext* cx,
void nsFrameLoader::SkipBrowsingContextDetach() {
if (IsRemoteFrame()) {
// OOP Browser - Go directly over Browser Parent
if (mBrowserParent) {
Unused << mBrowserParent->SendSkipBrowsingContextDetach();
if (auto* browserParent = GetBrowserParent()) {
Unused << browserParent->SendSkipBrowsingContextDetach();
}
// OOP IFrame - Through Browser Bridge Parent, set on browser child
else if (mBrowserBridgeChild) {
Unused << mBrowserBridgeChild->SendSkipBrowsingContextDetach();
else if (auto* browserBridgeChild = GetBrowserBridgeChild()) {
Unused << browserBridgeChild->SendSkipBrowsingContextDetach();
}
return;
}

Просмотреть файл

@ -23,6 +23,7 @@
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ParentSHistory.h"
#include "mozilla/dom/RemoteBrowser.h"
#include "mozilla/Attributes.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsStubMutationObserver.h"
@ -92,9 +93,9 @@ class nsFrameLoader final : public nsStubMutationObserver,
public nsWrapperCache {
friend class AutoResetInShow;
friend class AutoResetInFrameSwap;
typedef mozilla::dom::PBrowserParent PBrowserParent;
typedef mozilla::dom::Document Document;
typedef mozilla::dom::BrowserParent BrowserParent;
typedef mozilla::dom::BrowserBridgeChild BrowserBridgeChild;
typedef mozilla::dom::BrowsingContext BrowsingContext;
typedef mozilla::layout::RenderFrame RenderFrame;
@ -311,13 +312,13 @@ class nsFrameLoader final : public nsStubMutationObserver,
* Returns the IPDL actor used if this is a top-level remote browser, or null
* otherwise.
*/
PBrowserParent* GetRemoteBrowser() const;
BrowserParent* GetBrowserParent() const;
/**
* Returns the BrowserBridgeChild if this is an out-of-process iframe, or null
* Returns the IPDL actor used if this is an out-of-process iframe, or null
* otherwise.
*/
mozilla::dom::BrowserBridgeChild* GetBrowserBridgeChild() const;
BrowserBridgeChild* GetBrowserBridgeChild() const;
/**
* Returns the layers ID that this remote frame is using to render.
@ -342,7 +343,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
* this object, which means you can't have called ShowRemoteFrame()
* or ReallyStartLoading().
*/
void SetRemoteBrowser(nsIRemoteTab* aBrowserParent);
void InitializeFromBrowserParent(BrowserParent* aBrowserParent);
/**
* Stashes a detached nsIFrame on the frame loader. We do this when we're
@ -445,6 +446,10 @@ class nsFrameLoader final : public nsStubMutationObserver,
void FireErrorEvent();
nsresult ReallyStartLoadingInternal();
// Returns true if we have a remote browser or else attempts to create a
// remote browser and returns true if successful.
bool EnsureRemoteBrowser();
// Return true if remote browser created; nothing else to do
bool TryRemoteBrowser();
@ -492,11 +497,8 @@ class nsFrameLoader final : public nsStubMutationObserver,
// target process.
uint64_t mPendingSwitchID;
RefPtr<BrowserParent> mBrowserParent;
uint64_t mChildID;
// This is used when this refers to a remote sub frame
RefPtr<mozilla::dom::BrowserBridgeChild> mBrowserBridgeChild;
RefPtr<mozilla::dom::RemoteBrowser> mRemoteBrowser;
// Holds the last known size of the frame.
mozilla::ScreenIntSize mLazySize;

Просмотреть файл

@ -61,11 +61,10 @@ class nsPIWindowRoot : public mozilla::dom::EventTarget {
virtual mozilla::dom::EventTarget* GetParentTarget() = 0;
// Stores a weak reference to the browser.
virtual void AddBrowser(mozilla::dom::BrowserParent* aBrowser) = 0;
virtual void RemoveBrowser(mozilla::dom::BrowserParent* aBrowser) = 0;
virtual void AddBrowser(nsIRemoteTab* aBrowser) = 0;
virtual void RemoveBrowser(nsIRemoteTab* aBrowser) = 0;
typedef void (*BrowserEnumerator)(mozilla::dom::BrowserParent* aTab,
void* aArg);
typedef void (*BrowserEnumerator)(nsIRemoteTab* aTab, void* aArg);
// Enumerate all stored browsers that for which the weak reference is valid.
virtual void EnumerateBrowsers(BrowserEnumerator aEnumFunc, void* aArg) = 0;

Просмотреть файл

@ -297,32 +297,29 @@ JSObject* nsWindowRoot::WrapObject(JSContext* aCx,
return mozilla::dom::WindowRoot_Binding::Wrap(aCx, this, aGivenProto);
}
void nsWindowRoot::AddBrowser(mozilla::dom::BrowserParent* aBrowser) {
nsWeakPtr weakBrowser =
do_GetWeakReference(static_cast<nsIRemoteTab*>(aBrowser));
void nsWindowRoot::AddBrowser(nsIRemoteTab* aBrowser) {
nsWeakPtr weakBrowser = do_GetWeakReference(aBrowser);
mWeakBrowsers.PutEntry(weakBrowser);
}
void nsWindowRoot::RemoveBrowser(mozilla::dom::BrowserParent* aBrowser) {
nsWeakPtr weakBrowser =
do_GetWeakReference(static_cast<nsIRemoteTab*>(aBrowser));
void nsWindowRoot::RemoveBrowser(nsIRemoteTab* aBrowser) {
nsWeakPtr weakBrowser = do_GetWeakReference(aBrowser);
mWeakBrowsers.RemoveEntry(weakBrowser);
}
void nsWindowRoot::EnumerateBrowsers(BrowserEnumerator aEnumFunc, void* aArg) {
// Collect strong references to all browsers in a separate array in
// case aEnumFunc alters mWeakBrowsers.
nsTArray<RefPtr<BrowserParent>> browserParents;
nsTArray<nsCOMPtr<nsIRemoteTab>> remoteTabs;
for (auto iter = mWeakBrowsers.ConstIter(); !iter.Done(); iter.Next()) {
nsCOMPtr<nsIRemoteTab> browserParent(
do_QueryReferent(iter.Get()->GetKey()));
if (BrowserParent* tab = BrowserParent::GetFrom(browserParent)) {
browserParents.AppendElement(tab);
nsCOMPtr<nsIRemoteTab> remoteTab(do_QueryReferent(iter.Get()->GetKey()));
if (remoteTab) {
remoteTabs.AppendElement(remoteTab);
}
}
for (uint32_t i = 0; i < browserParents.Length(); ++i) {
aEnumFunc(browserParents[i], aArg);
for (uint32_t i = 0; i < remoteTabs.Length(); ++i) {
aEnumFunc(remoteTabs[i], aArg);
}
}

Просмотреть файл

@ -70,8 +70,8 @@ class nsWindowRoot final : public nsPIWindowRoot {
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsWindowRoot)
virtual void AddBrowser(mozilla::dom::BrowserParent* aBrowser) override;
virtual void RemoveBrowser(mozilla::dom::BrowserParent* aBrowser) override;
virtual void AddBrowser(nsIRemoteTab* aBrowser) override;
virtual void RemoveBrowser(nsIRemoteTab* aBrowser) override;
virtual void EnumerateBrowsers(BrowserEnumerator aEnumFunc,
void* aArg) override;

Просмотреть файл

@ -2,6 +2,7 @@
skip-if = os == 'android'
support-files =
bug418986-1.js
clonedoc/**
cpows_child.js
cpows_parent.xul
file_bug549682.xul

Просмотреть файл

@ -0,0 +1 @@
content clonedoc content/

Просмотреть файл

@ -0,0 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<something>
<somethinglese/>
</something>

Просмотреть файл

@ -17,10 +17,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=467123
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
/** Test for Bug 467123 **/
let url = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(document.location.href);
let file = Cc["@mozilla.org/chrome/chrome-registry;1"]
.getService(Ci.nsIChromeRegistry)
.convertChromeURL(url)
.QueryInterface(Ci.nsIFileURL)
.file.parent;
file.append("clonedoc");
Components.manager.addBootstrappedManifestLocation(file);
var xhr = new XMLHttpRequest();
xhr.open("GET", "chrome://global/content/bindings/button.xml", false);
xhr.open("GET", "chrome://clonedoc/content/doc.xml", false);
xhr.send();
ok(xhr.responseXML, "We should have response document!");
var e = null;

Просмотреть файл

@ -23,8 +23,6 @@ interface WindowGlobalParent {
readonly attribute WindowGlobalChild? childActor; // in-process only
readonly attribute RemoteTab? remoteTab; // out-of-process only
// Information about the currently loaded document.
readonly attribute Principal documentPrincipal;
readonly attribute URI? documentURI;
@ -35,7 +33,7 @@ interface WindowGlobalParent {
JSWindowActorParent getActor(DOMString name);
[Throws]
Promise<RemoteTab> changeFrameRemoteness(
Promise<unsigned long long> changeFrameRemoteness(
BrowsingContext? bc, DOMString remoteType,
unsigned long long pendingSwitchId);
};

Просмотреть файл

@ -1096,9 +1096,7 @@ static bool HandleAccessKeyInRemoteChild(BrowserParent* aBrowserParent,
AccessKeyInfo* accessKeyInfo = static_cast<AccessKeyInfo*>(aArg);
// Only forward accesskeys for the active tab.
bool active;
aBrowserParent->GetDocShellIsActive(&active);
if (active) {
if (aBrowserParent->GetDocShellIsActive()) {
// Even if there is no target for the accesskey in this process,
// the event may match with a content accesskey. If so, the keyboard
// event should be handled with reply event for preventing double action.

Просмотреть файл

@ -132,12 +132,26 @@ void nsGenericHTMLFrameElement::EnsureFrameLoader() {
mFrameLoader = nsFrameLoader::Create(this, mOpenerWindow, mNetworkCreated);
}
nsresult nsGenericHTMLFrameElement::CreateRemoteFrameLoader(
nsIRemoteTab* aBrowserParent) {
void nsGenericHTMLFrameElement::DisallowCreateFrameLoader() {
MOZ_ASSERT(!mFrameLoader);
MOZ_ASSERT(!mFrameLoaderCreationDisallowed);
mFrameLoaderCreationDisallowed = true;
}
void nsGenericHTMLFrameElement::AllowCreateFrameLoader() {
MOZ_ASSERT(!mFrameLoader);
MOZ_ASSERT(mFrameLoaderCreationDisallowed);
mFrameLoaderCreationDisallowed = false;
}
void nsGenericHTMLFrameElement::CreateRemoteFrameLoader(
BrowserParent* aBrowserParent) {
MOZ_ASSERT(!mFrameLoader);
EnsureFrameLoader();
NS_ENSURE_STATE(mFrameLoader);
mFrameLoader->SetRemoteBrowser(aBrowserParent);
if (NS_WARN_IF(!mFrameLoader)) {
return;
}
mFrameLoader->InitializeFromBrowserParent(aBrowserParent);
if (nsSubDocumentFrame* subdocFrame = do_QueryFrame(GetPrimaryFrame())) {
// The reflow for this element already happened while we were waiting
@ -146,7 +160,6 @@ nsresult nsGenericHTMLFrameElement::CreateRemoteFrameLoader(
// ReflowFinished, and we need to do it properly now.
mFrameLoader->UpdatePositionAndSize(subdocFrame);
}
return NS_OK;
}
void nsGenericHTMLFrameElement::PresetOpenerWindow(
@ -442,22 +455,6 @@ NS_IMETHODIMP nsGenericHTMLFrameElement::GetIsolated(bool* aOut) {
return NS_OK;
}
NS_IMETHODIMP
nsGenericHTMLFrameElement::DisallowCreateFrameLoader() {
MOZ_ASSERT(!mFrameLoader);
MOZ_ASSERT(!mFrameLoaderCreationDisallowed);
mFrameLoaderCreationDisallowed = true;
return NS_OK;
}
NS_IMETHODIMP
nsGenericHTMLFrameElement::AllowCreateFrameLoader() {
MOZ_ASSERT(!mFrameLoader);
MOZ_ASSERT(mFrameLoaderCreationDisallowed);
mFrameLoaderCreationDisallowed = false;
return NS_OK;
}
NS_IMETHODIMP
nsGenericHTMLFrameElement::InitializeBrowserAPI() {
MOZ_ASSERT(mFrameLoader);

Просмотреть файл

@ -19,6 +19,7 @@
namespace mozilla {
namespace dom {
class BrowserParent;
template <typename>
struct Nullable;
class WindowProxyHolder;
@ -90,6 +91,31 @@ class nsGenericHTMLFrameElement : public nsGenericHTMLElement,
mozilla::dom::WindowProxyHolder>& aOpenerWindow,
mozilla::ErrorResult& aRv);
/**
* Normally, a frame tries to create its frame loader when its src is
* modified, or its contentWindow is accessed.
*
* disallowCreateFrameLoader prevents the frame element from creating its
* frame loader (in the same way that not being inside a document prevents the
* creation of a frame loader). allowCreateFrameLoader lifts this
* restriction.
*
* These methods are not re-entrant -- it is an error to call
* disallowCreateFrameLoader twice without first calling allowFrameLoader.
*
* It's also an error to call either method if we already have a frame loader.
*/
void DisallowCreateFrameLoader();
void AllowCreateFrameLoader();
/**
* Create a remote (i.e., out-of-process) frame loader attached to the given
* remote tab.
*
* It is an error to call this method if we already have a frame loader.
*/
void CreateRemoteFrameLoader(mozilla::dom::BrowserParent* aBrowserParent);
static void InitStatics();
static bool BrowserFramesEnabled();

Просмотреть файл

@ -57,6 +57,8 @@ interface nsIRemoteTab : nsISupports
readonly attribute uint64_t tabId;
readonly attribute uint64_t contentProcessId;
/**
* The OS level process Id of the related child process.
*/
@ -144,4 +146,9 @@ interface nsIRemoteTab : nsISupports
void maybeCancelContentJSExecution(
in nsIRemoteTab_NavigationType aNavigationType,
[optional] in jsval aCancelContentJSOptions);
/**
* Notify the remote tab that the resolution has changed.
*/
[noscript] void notifyResolutionChanged();
};

Просмотреть файл

@ -35,30 +35,6 @@ interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
*/
[infallible] readonly attribute boolean isolated;
/**
* Normally, a frame tries to create its frame loader when its src is
* modified, or its contentWindow is accessed.
*
* disallowCreateFrameLoader prevents the frame element from creating its
* frame loader (in the same way that not being inside a document prevents the
* creation of a frame loader). allowCreateFrameLoader lifts this restriction.
*
* These methods are not re-entrant -- it is an error to call
* disallowCreateFrameLoader twice without first calling allowFrameLoader.
*
* It's also an error to call either method if we already have a frame loader.
*/
void disallowCreateFrameLoader();
void allowCreateFrameLoader();
/**
* Create a remote (i.e., out-of-process) frame loader attached to the given
* remote tab.
*
* It is an error to call this method if we already have a frame loader.
*/
void createRemoteFrameLoader(in nsIRemoteTab aRemoteTab);
/**
* Initialize the API, and add frame message listener that supports API
* invocations.

Просмотреть файл

@ -26,88 +26,6 @@ BrowserBridgeChild::BrowserBridgeChild(nsFrameLoader* aFrameLoader,
BrowserBridgeChild::~BrowserBridgeChild() {}
already_AddRefed<BrowserBridgeChild> BrowserBridgeChild::Create(
nsFrameLoader* aFrameLoader, const TabContext& aContext,
const nsString& aRemoteType, BrowsingContext* aBrowsingContext) {
MOZ_ASSERT(XRE_IsContentProcess());
// Determine our embedder's BrowserChild actor.
RefPtr<Element> owner = aFrameLoader->GetOwnerContent();
MOZ_DIAGNOSTIC_ASSERT(owner);
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(owner->GetOwnerGlobal());
MOZ_DIAGNOSTIC_ASSERT(docShell);
RefPtr<BrowserChild> browserChild = BrowserChild::GetFrom(docShell);
MOZ_DIAGNOSTIC_ASSERT(browserChild);
uint32_t chromeFlags = 0;
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
if (docShell) {
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
}
if (treeOwner) {
nsCOMPtr<nsIWebBrowserChrome> wbc = do_GetInterface(treeOwner);
if (wbc) {
wbc->GetChromeFlags(&chromeFlags);
}
}
// Checking that this actually does something useful is
// https://bugzilla.mozilla.org/show_bug.cgi?id=1542710
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
if (loadContext && loadContext->UsePrivateBrowsing()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
}
if (docShell->GetAffectPrivateSessionLifetime()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
}
RefPtr<BrowserBridgeChild> browserBridge =
new BrowserBridgeChild(aFrameLoader, aBrowsingContext);
// Reference is freed in BrowserChild::DeallocPBrowserBridgeChild.
browserChild->SendPBrowserBridgeConstructor(
do_AddRef(browserBridge).take(),
PromiseFlatString(aContext.PresentationURL()), aRemoteType,
aBrowsingContext, chromeFlags);
browserBridge->mIPCOpen = true;
return browserBridge.forget();
}
void BrowserBridgeChild::UpdateDimensions(const nsIntRect& aRect,
const mozilla::ScreenIntSize& aSize) {
MOZ_DIAGNOSTIC_ASSERT(mIPCOpen);
RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForContent(owner);
if (!widget) {
widget = nsContentUtils::WidgetForDocument(owner->OwnerDoc());
}
MOZ_DIAGNOSTIC_ASSERT(widget);
CSSToLayoutDeviceScale widgetScale = widget->GetDefaultScale();
LayoutDeviceIntRect devicePixelRect = ViewAs<LayoutDevicePixel>(
aRect, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
LayoutDeviceIntSize devicePixelSize = ViewAs<LayoutDevicePixel>(
aSize, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
// XXX What are clientOffset and chromeOffset used for? Are they meaningful
// for nested iframes with transforms?
LayoutDeviceIntPoint clientOffset;
LayoutDeviceIntPoint chromeOffset;
CSSRect unscaledRect = devicePixelRect / widgetScale;
CSSSize unscaledSize = devicePixelSize / widgetScale;
hal::ScreenOrientation orientation = hal::eScreenOrientation_Default;
DimensionInfo di(unscaledRect, unscaledSize, orientation, clientOffset,
chromeOffset);
Unused << SendUpdateDimensions(di);
}
void BrowserBridgeChild::NavigateByKey(bool aForward,
bool aForDocumentNavigation) {
Unused << SendNavigateByKey(aForward, aForDocumentNavigation);

Просмотреть файл

@ -13,6 +13,7 @@
namespace mozilla {
namespace dom {
class BrowsingContext;
class ContentChild;
/**
* BrowserBridgeChild implements the child actor part of the PBrowserBridge
@ -28,19 +29,13 @@ class BrowserBridgeChild : public PBrowserBridgeChild {
}
mozilla::layers::LayersId GetLayersId() { return mLayersId; }
nsFrameLoader* GetFrameLoader() const { return mFrameLoader; }
BrowsingContext* GetBrowsingContext() { return mBrowsingContext; }
// XXX(nika): We should have a load context here. (bug 1532664)
nsILoadContext* GetLoadContext() { return nullptr; }
static already_AddRefed<BrowserBridgeChild> Create(
nsFrameLoader* aFrameLoader, const TabContext& aContext,
const nsString& aRemoteType, BrowsingContext* aBrowsingContext);
void UpdateDimensions(const nsIntRect& aRect,
const mozilla::ScreenIntSize& aSize);
void NavigateByKey(bool aForward, bool aForDocumentNavigation);
void Activate();
@ -54,8 +49,12 @@ class BrowserBridgeChild : public PBrowserBridgeChild {
static BrowserBridgeChild* GetFrom(nsIContent* aContent);
protected:
friend class ContentChild;
friend class PBrowserBridgeChild;
BrowserBridgeChild(nsFrameLoader* aFrameLoader,
BrowsingContext* aBrowsingContext);
mozilla::ipc::IPCResult RecvSetLayersId(
const mozilla::layers::LayersId& aLayersId);
@ -67,8 +66,6 @@ class BrowserBridgeChild : public PBrowserBridgeChild {
void ActorDestroy(ActorDestroyReason aWhy) override;
private:
explicit BrowserBridgeChild(nsFrameLoader* aFrameLoader,
BrowsingContext* aBrowsingContext);
~BrowserBridgeChild();
mozilla::layers::LayersId mLayersId;

Просмотреть файл

@ -0,0 +1,101 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "mozilla/dom/BrowserBridgeHost.h"
namespace mozilla {
namespace dom {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserBridgeHost)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(BrowserBridgeHost)
NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowserBridgeHost)
NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserBridgeHost)
BrowserBridgeHost::BrowserBridgeHost(BrowserBridgeChild* aChild)
: mBridge(aChild) {}
mozilla::layers::LayersId BrowserBridgeHost::GetLayersId() const {
return mBridge->GetLayersId();
}
BrowsingContext* BrowserBridgeHost::GetBrowsingContext() const {
return mBridge->GetBrowsingContext();
}
nsILoadContext* BrowserBridgeHost::GetLoadContext() const {
return mBridge->GetLoadContext();
}
void BrowserBridgeHost::LoadURL(nsIURI* aURI) {
nsAutoCString spec;
aURI->GetSpec(spec);
Unused << mBridge->SendLoadURL(spec);
}
void BrowserBridgeHost::ResumeLoad(uint64_t aPendingSwitchId) {
Unused << mBridge->SendResumeLoad(aPendingSwitchId);
}
void BrowserBridgeHost::DestroyStart() { DestroyComplete(); }
void BrowserBridgeHost::DestroyComplete() {
if (!mBridge) {
return;
}
Unused << mBridge->Send__delete__(mBridge);
mBridge = nullptr;
}
bool BrowserBridgeHost::Show(const ScreenIntSize& aSize, bool aParentIsActive) {
RefPtr<Element> owner = mBridge->GetFrameLoader()->GetOwnerContent();
nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForContent(owner);
if (!widget) {
widget = nsContentUtils::WidgetForDocument(owner->OwnerDoc());
}
MOZ_DIAGNOSTIC_ASSERT(widget);
nsSizeMode sizeMode = widget ? widget->SizeMode() : nsSizeMode_Normal;
Unused << mBridge->SendShow(aSize, aParentIsActive, sizeMode);
return true;
}
void BrowserBridgeHost::UpdateDimensions(const nsIntRect& aRect,
const ScreenIntSize& aSize) {
RefPtr<Element> owner = mBridge->GetFrameLoader()->GetOwnerContent();
nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForContent(owner);
if (!widget) {
widget = nsContentUtils::WidgetForDocument(owner->OwnerDoc());
}
MOZ_DIAGNOSTIC_ASSERT(widget);
CSSToLayoutDeviceScale widgetScale = widget->GetDefaultScale();
LayoutDeviceIntRect devicePixelRect = ViewAs<LayoutDevicePixel>(
aRect, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
LayoutDeviceIntSize devicePixelSize = ViewAs<LayoutDevicePixel>(
aSize, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
// XXX What are clientOffset and chromeOffset used for? Are they meaningful
// for nested iframes with transforms?
LayoutDeviceIntPoint clientOffset;
LayoutDeviceIntPoint chromeOffset;
CSSRect unscaledRect = devicePixelRect / widgetScale;
CSSSize unscaledSize = devicePixelSize / widgetScale;
hal::ScreenOrientation orientation = hal::eScreenOrientation_Default;
DimensionInfo di(unscaledRect, unscaledSize, orientation, clientOffset,
chromeOffset);
Unused << mBridge->SendUpdateDimensions(di);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_BrowserBridgeHost_h
#define mozilla_dom_BrowserBridgeHost_h
#include "mozilla/dom/RemoteBrowser.h"
#include "mozilla/dom/BrowserBridgeChild.h"
namespace mozilla {
namespace dom {
/**
* BrowserBridgeHost manages a remote browser from a content process.
*
* It is used via the RemoteBrowser interface in nsFrameLoader and proxies
* work to the chrome process via PBrowserBridge.
*
* See `dom/docs/Fission-IPC-Diagram.svg` for an overview of the DOM IPC
* actors.
*/
class BrowserBridgeHost : public RemoteBrowser {
public:
typedef mozilla::layers::LayersId LayersId;
explicit BrowserBridgeHost(BrowserBridgeChild* aChild);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(BrowserBridgeHost)
// Get the IPDL actor for the BrowserBridgeChild.
BrowserBridgeChild* GetActor() { return mBridge; }
BrowserHost* AsBrowserHost() override { return nullptr; }
BrowserBridgeHost* AsBrowserBridgeHost() override { return this; }
LayersId GetLayersId() const override;
BrowsingContext* GetBrowsingContext() const override;
nsILoadContext* GetLoadContext() const override;
void LoadURL(nsIURI* aURI) override;
void ResumeLoad(uint64_t aPendingSwitchId) override;
void DestroyStart() override;
void DestroyComplete() override;
bool Show(const ScreenIntSize& aSize, bool aParentIsActive) override;
void UpdateDimensions(const nsIntRect& aRect,
const ScreenIntSize& aSize) override;
private:
virtual ~BrowserBridgeHost() = default;
// The IPDL actor for proxying browser operations
RefPtr<BrowserBridgeChild> mBridge;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_BrowserBridgeHost_h

Просмотреть файл

@ -61,9 +61,9 @@ nsresult BrowserBridgeParent::Init(const nsString& aPresentationURL,
constructorSender->ChildID());
// Construct the BrowserParent object for our subframe.
RefPtr<BrowserParent> browserParent(
new BrowserParent(constructorSender, tabId, tabContext, aBrowsingContext,
aChromeFlags, this));
RefPtr<BrowserParent> browserParent(new BrowserParent(
constructorSender, tabId, tabContext, aBrowsingContext, aChromeFlags));
browserParent->SetBrowserBridgeParent(this);
// Open a remote endpoint for our PBrowser actor. DeallocPBrowserParent
// releases the ref taken.

379
dom/ipc/BrowserHost.cpp Normal file
Просмотреть файл

@ -0,0 +1,379 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "mozilla/dom/BrowserHost.h"
#include "mozilla/dom/CancelContentJSOptionsBinding.h"
#include "mozilla/dom/WindowGlobalParent.h"
namespace mozilla {
namespace dom {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserHost)
NS_INTERFACE_MAP_ENTRY(nsIRemoteTab)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, RemoteBrowser)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(BrowserHost, mRoot)
NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowserHost)
NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserHost)
BrowserHost::BrowserHost(BrowserParent* aParent)
: mId(aParent->GetTabId()), mRoot(aParent) {
mRoot->SetBrowserHost(this);
}
BrowserHost* BrowserHost::GetFrom(nsIRemoteTab* aRemoteTab) {
return static_cast<BrowserHost*>(aRemoteTab);
}
mozilla::layers::LayersId BrowserHost::GetLayersId() const {
return mRoot->GetRenderFrame()->GetLayersId();
}
BrowsingContext* BrowserHost::GetBrowsingContext() const {
return mRoot->GetBrowsingContext();
}
nsILoadContext* BrowserHost::GetLoadContext() const {
RefPtr<nsILoadContext> loadContext = mRoot->GetLoadContext();
return loadContext;
}
a11y::DocAccessibleParent* BrowserHost::GetTopLevelDocAccessible() const {
return mRoot->GetTopLevelDocAccessible();
}
void BrowserHost::LoadURL(nsIURI* aURI) { mRoot->LoadURL(aURI); }
void BrowserHost::ResumeLoad(uint64_t aPendingSwitchId) {
mRoot->ResumeLoad(aPendingSwitchId);
}
void BrowserHost::DestroyStart() { mRoot->Destroy(); }
void BrowserHost::DestroyComplete() {
if (!mRoot) {
return;
}
mRoot->SetOwnerElement(nullptr);
mRoot->Destroy();
mRoot = nullptr;
}
bool BrowserHost::Show(const ScreenIntSize& aSize, bool aParentIsActive) {
return mRoot->Show(aSize, aParentIsActive);
}
void BrowserHost::UpdateDimensions(const nsIntRect& aRect,
const ScreenIntSize& aSize) {
mRoot->UpdateDimensions(aRect, aSize);
}
/* attribute boolean docShellIsActive; */
NS_IMETHODIMP
BrowserHost::GetDocShellIsActive(bool* aDocShellIsActive) {
if (!mRoot) {
*aDocShellIsActive = false;
return NS_OK;
}
*aDocShellIsActive = mRoot->GetDocShellIsActive();
return NS_OK;
}
NS_IMETHODIMP
BrowserHost::SetDocShellIsActive(bool aDocShellIsActive) {
if (!mRoot) {
return NS_OK;
}
VisitAll([&](BrowserParent* aBrowserParent) {
aBrowserParent->SetDocShellIsActive(aDocShellIsActive);
});
return NS_OK;
}
/* attribute boolean renderLayers; */
NS_IMETHODIMP
BrowserHost::GetRenderLayers(bool* aRenderLayers) {
if (!mRoot) {
*aRenderLayers = false;
return NS_OK;
}
*aRenderLayers = mRoot->GetRenderLayers();
return NS_OK;
}
NS_IMETHODIMP
BrowserHost::SetRenderLayers(bool aRenderLayers) {
if (!mRoot) {
return NS_OK;
}
VisitAll([&](BrowserParent* aBrowserParent) {
aBrowserParent->SetRenderLayers(aRenderLayers);
});
return NS_OK;
}
/* readonly attribute boolean hasLayers; */
NS_IMETHODIMP
BrowserHost::GetHasLayers(bool* aHasLayers) {
if (!mRoot) {
*aHasLayers = false;
return NS_OK;
}
*aHasLayers = mRoot->GetHasLayers();
return NS_OK;
}
/* void forceRepaint (); */
NS_IMETHODIMP
BrowserHost::ForceRepaint(void) {
if (!mRoot) {
return NS_OK;
}
VisitAll(
[](BrowserParent* aBrowserParent) { aBrowserParent->ForceRepaint(); });
return NS_OK;
}
/* void resolutionChanged (); */
NS_IMETHODIMP
BrowserHost::NotifyResolutionChanged(void) {
if (!mRoot) {
return NS_OK;
}
VisitAll([](BrowserParent* aBrowserParent) {
aBrowserParent->NotifyResolutionChanged();
});
return NS_OK;
}
/* void deprioritize (); */
NS_IMETHODIMP
BrowserHost::Deprioritize(void) {
if (!mRoot) {
return NS_OK;
}
VisitAll(
[](BrowserParent* aBrowserParent) { aBrowserParent->Deprioritize(); });
return NS_OK;
}
/* void preserveLayers (in boolean aPreserveLayers); */
NS_IMETHODIMP
BrowserHost::PreserveLayers(bool aPreserveLayers) {
if (!mRoot) {
return NS_OK;
}
VisitAll([&](BrowserParent* aBrowserParent) {
aBrowserParent->PreserveLayers(aPreserveLayers);
});
return NS_OK;
}
/* readonly attribute uint64_t tabId; */
NS_IMETHODIMP
BrowserHost::GetTabId(uint64_t* aTabId) {
*aTabId = mId;
return NS_OK;
}
/* readonly attribute uint64_t contentProcessId; */
NS_IMETHODIMP
BrowserHost::GetContentProcessId(uint64_t* aContentProcessId) {
if (!mRoot) {
*aContentProcessId = 0;
return NS_OK;
}
*aContentProcessId = GetContentParent()->ChildID();
return NS_OK;
}
/* readonly attribute int32_t osPid; */
NS_IMETHODIMP
BrowserHost::GetOsPid(int32_t* aOsPid) {
if (!mRoot) {
*aOsPid = 0;
return NS_OK;
}
*aOsPid = GetContentParent()->Pid();
return NS_OK;
}
/* readonly attribute boolean hasContentOpener; */
NS_IMETHODIMP
BrowserHost::GetHasContentOpener(bool* aHasContentOpener) {
if (!mRoot) {
*aHasContentOpener = false;
return NS_OK;
}
*aHasContentOpener = mRoot->GetHasContentOpener();
return NS_OK;
}
/* readonly attribute boolean hasPresented; */
NS_IMETHODIMP
BrowserHost::GetHasPresented(bool* aHasPresented) {
if (!mRoot) {
*aHasPresented = false;
return NS_OK;
}
*aHasPresented = mRoot->GetHasPresented();
return NS_OK;
}
NS_IMETHODIMP
BrowserHost::GetWindowGlobalParents(
nsTArray<RefPtr<WindowGlobalParent>>& aWindowGlobalParents) {
if (!mRoot) {
aWindowGlobalParents = nsTArray<RefPtr<WindowGlobalParent>>();
return NS_OK;
}
VisitAll([&](BrowserParent* aBrowser) {
const auto& windowGlobalParents = aBrowser->ManagedPWindowGlobalParent();
for (auto iter = windowGlobalParents.ConstIter(); !iter.Done();
iter.Next()) {
WindowGlobalParent* windowGlobalParent =
static_cast<WindowGlobalParent*>(iter.Get()->GetKey());
aWindowGlobalParents.AppendElement(windowGlobalParent);
}
});
return NS_OK;
}
/* void transmitPermissionsForPrincipal (in nsIPrincipal aPrincipal); */
NS_IMETHODIMP
BrowserHost::TransmitPermissionsForPrincipal(nsIPrincipal* aPrincipal) {
if (!mRoot) {
return NS_OK;
}
return GetContentParent()->TransmitPermissionsForPrincipal(aPrincipal);
}
/* readonly attribute boolean hasBeforeUnload; */
NS_IMETHODIMP
BrowserHost::GetHasBeforeUnload(bool* aHasBeforeUnload) {
if (!mRoot) {
*aHasBeforeUnload = false;
return NS_OK;
}
*aHasBeforeUnload = mRoot->GetHasBeforeUnload();
return NS_OK;
}
/* readonly attribute Element ownerElement; */
NS_IMETHODIMP
BrowserHost::GetOwnerElement(mozilla::dom::Element** aOwnerElement) {
if (!mRoot) {
*aOwnerElement = nullptr;
return NS_OK;
}
*aOwnerElement = mRoot->GetOwnerElement();
return NS_OK;
}
/* boolean startApzAutoscroll (in float aAnchorX, in float aAnchorY, in nsViewID
* aScrollId, in uint32_t aPresShellId); */
NS_IMETHODIMP
BrowserHost::StartApzAutoscroll(float aAnchorX, float aAnchorY,
nsViewID aScrollId, uint32_t aPresShellId,
bool* _retval) {
if (!mRoot) {
return NS_OK;
}
*_retval =
mRoot->StartApzAutoscroll(aAnchorX, aAnchorY, aScrollId, aPresShellId);
return NS_OK;
}
/* void stopApzAutoscroll (in nsViewID aScrollId, in uint32_t aPresShellId); */
NS_IMETHODIMP
BrowserHost::StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId) {
if (!mRoot) {
return NS_OK;
}
mRoot->StopApzAutoscroll(aScrollId, aPresShellId);
return NS_OK;
}
/* bool saveRecording (in AString aFileName); */
NS_IMETHODIMP
BrowserHost::SaveRecording(const nsAString& aFileName, bool* _retval) {
if (!mRoot) {
return NS_OK;
}
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(aFileName, false, getter_AddRefs(file));
if (NS_FAILED(rv)) {
return rv;
}
return GetContentParent()->SaveRecording(file, _retval);
}
/* Promise getContentBlockingLog (); */
NS_IMETHODIMP
BrowserHost::GetContentBlockingLog(::mozilla::dom::Promise** aPromise) {
if (!mRoot) {
*aPromise = nullptr;
return NS_OK;
}
NS_ENSURE_ARG_POINTER(aPromise);
*aPromise = nullptr;
if (!mRoot->GetOwnerElement()) {
return NS_ERROR_FAILURE;
}
ErrorResult rv;
RefPtr<Promise> jsPromise = Promise::Create(
mRoot->GetOwnerElement()->OwnerDoc()->GetOwnerGlobal(), rv);
if (rv.Failed()) {
return NS_ERROR_FAILURE;
}
RefPtr<Promise> copy(jsPromise);
copy.forget(aPromise);
auto cblPromise = mRoot->SendGetContentBlockingLog();
cblPromise->Then(
GetMainThreadSerialEventTarget(), __func__,
[jsPromise](Tuple<nsCString, bool>&& aResult) {
if (Get<1>(aResult)) {
NS_ConvertUTF8toUTF16 utf16(Get<0>(aResult));
jsPromise->MaybeResolve(std::move(utf16));
} else {
jsPromise->MaybeRejectWithUndefined();
}
},
[jsPromise](ResponseRejectReason&& aReason) {
jsPromise->MaybeRejectWithUndefined();
});
return NS_OK;
}
NS_IMETHODIMP
BrowserHost::MaybeCancelContentJSExecutionFromScript(
nsIRemoteTab::NavigationType aNavigationType,
JS::Handle<JS::Value> aCancelContentJSOptions, JSContext* aCx) {
if (!mRoot) {
return NS_OK;
}
dom::CancelContentJSOptions cancelContentJSOptions;
if (!cancelContentJSOptions.Init(aCx, aCancelContentJSOptions)) {
return NS_ERROR_INVALID_ARG;
}
if (StaticPrefs::dom_ipc_cancel_content_js_when_navigating()) {
GetContentParent()->CancelContentJSExecutionIfRunning(
mRoot, aNavigationType, cancelContentJSOptions);
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla

107
dom/ipc/BrowserHost.h Normal file
Просмотреть файл

@ -0,0 +1,107 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_BrowserHost_h
#define mozilla_dom_BrowserHost_h
#include "nsIRemoteTab.h"
#include "mozilla/dom/RemoteBrowser.h"
#include "mozilla/dom/BrowserParent.h"
class nsPIDOMWindowOuter;
namespace mozilla {
namespace a11y {
class DocAccessibleParent;
} // namespace a11y
namespace dom {
class Element;
/**
* BrowserHost manages a remote browser from the chrome process.
*
* It is used via the RemoteBrowser interface in nsFrameLoader and supports
* operations over the tree of BrowserParent/BrowserBridgeParent's.
*
* See `dom/docs/Fission-IPC-Diagram.svg` for an overview of the DOM IPC
* actors.
*/
class BrowserHost : public RemoteBrowser,
public nsIRemoteTab,
public nsSupportsWeakReference {
public:
typedef mozilla::layers::LayersId LayersId;
explicit BrowserHost(BrowserParent* aParent);
static BrowserHost* GetFrom(nsIRemoteTab* aRemoteTab);
// NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
// nsIRemoteTab
NS_DECL_NSIREMOTETAB
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(BrowserHost, RemoteBrowser)
// Get the IPDL actor for the root BrowserParent. This method should be
// avoided and consumers migrated to use this class.
BrowserParent* GetActor() { return mRoot; }
ContentParent* GetContentParent() const {
return mRoot ? mRoot->Manager() : nullptr;
}
TabId GetTabId() const {
return mId;
}
BrowserHost* AsBrowserHost() override { return this; }
BrowserBridgeHost* AsBrowserBridgeHost() override { return nullptr; }
LayersId GetLayersId() const override;
BrowsingContext* GetBrowsingContext() const override;
nsILoadContext* GetLoadContext() const override;
Element* GetOwnerElement() const { return mRoot->GetOwnerElement(); }
already_AddRefed<nsPIDOMWindowOuter> GetParentWindowOuter() const {
return mRoot->GetParentWindowOuter();
}
a11y::DocAccessibleParent* GetTopLevelDocAccessible() const;
// Visit each BrowserParent in the tree formed by PBrowser and
// PBrowserBridge that is anchored by `mRoot`.
template <typename Callback>
void VisitAll(Callback aCallback) {
if (!mRoot) {
return;
}
mRoot->VisitAll(aCallback);
}
void LoadURL(nsIURI* aURI) override;
void ResumeLoad(uint64_t aPendingSwitchId) override;
void DestroyStart() override;
void DestroyComplete() override;
bool Show(const ScreenIntSize& aSize, bool aParentIsActive) override;
void UpdateDimensions(const nsIntRect& aRect,
const ScreenIntSize& aSize) override;
private:
virtual ~BrowserHost() = default;
// The TabID for the root BrowserParent, we cache this so that we can access
// it after the remote browser has been destroyed
TabId mId;
// The root BrowserParent of this remote browser
RefPtr<BrowserParent> mRoot;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_BrowserHost_h

Просмотреть файл

@ -160,10 +160,9 @@ BrowserParent::LayerToBrowserParentTable*
BrowserParent::sLayerToBrowserParentTable = nullptr;
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserParent)
NS_INTERFACE_MAP_ENTRY(nsIRemoteTab)
NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRemoteTab)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventListener)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(BrowserParent, mFrameElement, mBrowserDOMWindow,
mLoadContext, mFrameLoader, mBrowsingContext)
@ -173,8 +172,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserParent)
BrowserParent::BrowserParent(ContentParent* aManager, const TabId& aTabId,
const TabContext& aContext,
CanonicalBrowsingContext* aBrowsingContext,
uint32_t aChromeFlags,
BrowserBridgeParent* aBrowserBridgeParent)
uint32_t aChromeFlags)
: TabContext(aContext),
mTabId(aTabId),
mManager(aManager),
@ -184,7 +182,8 @@ BrowserParent::BrowserParent(ContentParent* aManager, const TabId& aTabId,
mBrowserDOMWindow(nullptr),
mFrameLoader(nullptr),
mChromeFlags(aChromeFlags),
mBrowserBridgeParent(aBrowserBridgeParent),
mBrowserBridgeParent(nullptr),
mBrowserHost(nullptr),
mContentCache(*this),
mRenderFrame{},
mLayerTreeEpoch{1},
@ -257,13 +256,7 @@ BrowserParent* BrowserParent::GetFrom(nsFrameLoader* aFrameLoader) {
if (!aFrameLoader) {
return nullptr;
}
PBrowserParent* remoteBrowser = aFrameLoader->GetRemoteBrowser();
return static_cast<BrowserParent*>(remoteBrowser);
}
/*static*/
BrowserParent* BrowserParent::GetFrom(nsIRemoteTab* aBrowserParent) {
return static_cast<BrowserParent*>(aBrowserParent);
return aFrameLoader->GetBrowserParent();
}
/*static*/
@ -443,6 +436,12 @@ RenderFrame* BrowserParent::GetRenderFrame() {
return &mRenderFrame;
}
BrowserBridgeParent* BrowserParent::GetBrowserBridgeParent() const {
return mBrowserBridgeParent;
}
BrowserHost* BrowserParent::GetBrowserHost() const { return mBrowserHost; }
ShowInfo BrowserParent::GetShowInfo() {
TryCacheDPIAndScale();
if (mFrameElement) {
@ -479,15 +478,15 @@ void BrowserParent::SetOwnerElement(Element* aElement) {
newTopLevelWin = nsContentUtils::GetWindowRoot(aElement->OwnerDoc());
}
bool isSameTopLevelWin = curTopLevelWin == newTopLevelWin;
if (curTopLevelWin && !isSameTopLevelWin) {
curTopLevelWin->RemoveBrowser(this);
if (mBrowserHost && curTopLevelWin && !isSameTopLevelWin) {
curTopLevelWin->RemoveBrowser(mBrowserHost);
}
// Update to the new content, and register to listen for events from it.
mFrameElement = aElement;
if (newTopLevelWin && !isSameTopLevelWin) {
newTopLevelWin->AddBrowser(this);
if (mBrowserHost && newTopLevelWin && !isSameTopLevelWin) {
newTopLevelWin->AddBrowser(mBrowserHost);
}
if (mFrameElement) {
@ -546,11 +545,6 @@ void BrowserParent::SetOwnerElement(Element* aElement) {
});
}
NS_IMETHODIMP BrowserParent::GetOwnerElement(Element** aElement) {
*aElement = do_AddRef(GetOwnerElement()).take();
return NS_OK;
}
void BrowserParent::CacheFrameLoader(nsFrameLoader* aFrameLoader) {
mFrameLoader = aFrameLoader;
}
@ -726,9 +720,8 @@ void BrowserParent::ActorDestroy(ActorDestroyReason why) {
}
mFrameLoader = nullptr;
if (os) {
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIRemoteTab*, this),
if (os && mBrowserHost) {
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIRemoteTab*, mBrowserHost),
"ipc:browser-destroyed", nullptr);
}
}
@ -884,9 +877,10 @@ void BrowserParent::ResumeLoad(uint64_t aPendingSwitchID) {
}
void BrowserParent::InitRendering() {
MOZ_ASSERT(!mRenderFrame.IsInitialized());
if (mRenderFrame.IsInitialized()) {
return;
}
mRenderFrame.Initialize(this);
MOZ_ASSERT(mRenderFrame.IsInitialized());
layers::LayersId layersId = mRenderFrame.GetLayersId();
AddBrowserParentToTable(layersId, this);
@ -906,13 +900,16 @@ void BrowserParent::MaybeShowFrame() {
frameLoader->MaybeShowFrame();
}
void BrowserParent::Show(const ScreenIntSize& size, bool aParentIsActive) {
bool BrowserParent::Show(const ScreenIntSize& size, bool aParentIsActive) {
mDimensions = size;
if (mIsDestroyed) {
return;
return false;
}
MOZ_ASSERT(mRenderFrame.IsInitialized());
if (!mRenderFrame.AttachLayerManager()) {
return false;
}
nsCOMPtr<nsISupports> container = mFrameElement->OwnerDoc()->GetContainer();
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
@ -921,6 +918,7 @@ void BrowserParent::Show(const ScreenIntSize& size, bool aParentIsActive) {
mSizeMode = mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
Unused << SendShow(size, GetShowInfo(), aParentIsActive, mSizeMode);
return true;
}
mozilla::ipc::IPCResult BrowserParent::RecvSetDimensions(const uint32_t& aFlags,
@ -1051,21 +1049,6 @@ void BrowserParent::SizeModeChanged(const nsSizeMode& aSizeMode) {
}
}
void BrowserParent::UIResolutionChanged() {
if (!mIsDestroyed) {
// TryCacheDPIAndScale()'s cache is keyed off of
// mDPI being greater than 0, so this invalidates it.
mDPI = -1;
TryCacheDPIAndScale();
// If mDPI was set to -1 to invalidate it and then TryCacheDPIAndScale
// fails to cache the values, then mDefaultScale.scale might be invalid.
// We don't want to send that value to content. Just send -1 for it too in
// that case.
Unused << SendUIResolutionChanged(mDPI, mRounding,
mDPI < 0 ? -1.0 : mDefaultScale.scale);
}
}
void BrowserParent::ThemeChanged() {
if (!mIsDestroyed) {
// The theme has changed, and any cached values we had sent down
@ -2970,9 +2953,9 @@ mozilla::ipc::IPCResult BrowserParent::RecvRespondStartSwipeEvent(
return IPC_OK();
}
// defined in nsIRemoteTab
NS_IMETHODIMP
BrowserParent::SetDocShellIsActive(bool isActive) {
bool BrowserParent::GetDocShellIsActive() { return mDocShellIsActive; }
void BrowserParent::SetDocShellIsActive(bool isActive) {
mDocShellIsActive = isActive;
SetRenderLayers(isActive);
Unused << SendSetDocShellIsActive(isActive);
@ -2998,18 +2981,15 @@ BrowserParent::SetDocShellIsActive(bool isActive) {
if (Manager()->IsRecordingOrReplaying()) {
SetIsActiveRecordReplayTab(isActive);
}
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::GetDocShellIsActive(bool* aIsActive) {
*aIsActive = mDocShellIsActive;
return NS_OK;
}
bool BrowserParent::GetHasPresented() { return mHasPresented; }
NS_IMETHODIMP
BrowserParent::SetRenderLayers(bool aEnabled) {
bool BrowserParent::GetHasLayers() { return mHasLayers; }
bool BrowserParent::GetRenderLayers() { return mRenderLayers; }
void BrowserParent::SetRenderLayers(bool aEnabled) {
if (mActiveInPriorityManager != aEnabled) {
mActiveInPriorityManager = aEnabled;
// Let's inform the priority manager. This operation can end up with the
@ -3032,54 +3012,18 @@ BrowserParent::SetRenderLayers(bool aEnabled) {
}));
}
return NS_OK;
return;
}
// Preserve layers means that attempts to stop rendering layers
// will be ignored.
if (!aEnabled && mPreserveLayers) {
return NS_OK;
return;
}
mRenderLayers = aEnabled;
SetRenderLayersInternal(aEnabled, false /* aForceRepaint */);
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::GetRenderLayers(bool* aResult) {
*aResult = mRenderLayers;
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::GetHasLayers(bool* aResult) {
*aResult = mHasLayers;
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::Deprioritize() {
if (mActiveInPriorityManager) {
ProcessPriorityManager::TabActivityChanged(this, false);
mActiveInPriorityManager = false;
}
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::ForceRepaint() {
if (!mActiveInPriorityManager) {
// If a tab is left and then returned to very rapidly, it can be
// deprioritized without losing its loaded status. In this case we won't
// go through SetRenderLayers.
mActiveInPriorityManager = true;
ProcessPriorityManager::TabActivityChanged(this, true);
}
SetRenderLayersInternal(true /* aEnabled */, true /* aForceRepaint */);
return NS_OK;
}
void BrowserParent::SetRenderLayersInternal(bool aEnabled, bool aForceRepaint) {
@ -3097,72 +3041,98 @@ void BrowserParent::SetRenderLayersInternal(bool aEnabled, bool aForceRepaint) {
}
}
NS_IMETHODIMP
BrowserParent::PreserveLayers(bool aPreserveLayers) {
void BrowserParent::PreserveLayers(bool aPreserveLayers) {
mPreserveLayers = aPreserveLayers;
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::SaveRecording(const nsAString& aFilename, bool* aRetval) {
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(aFilename, false, getter_AddRefs(file));
if (NS_FAILED(rv)) {
return rv;
void BrowserParent::ForceRepaint() {
if (!mActiveInPriorityManager) {
// If a tab is left and then returned to very rapidly, it can be
// deprioritized without losing its loaded status. In this case we won't
// go through SetRenderLayers.
mActiveInPriorityManager = true;
ProcessPriorityManager::TabActivityChanged(this, true);
}
return Manager()->SaveRecording(file, aRetval);
SetRenderLayersInternal(true /* aEnabled */, true /* aForceRepaint */);
}
NS_IMETHODIMP
BrowserParent::GetContentBlockingLog(Promise** aPromise) {
NS_ENSURE_ARG_POINTER(aPromise);
*aPromise = nullptr;
if (!mFrameElement) {
return NS_ERROR_FAILURE;
void BrowserParent::NotifyResolutionChanged() {
if (!mIsDestroyed) {
// TryCacheDPIAndScale()'s cache is keyed off of
// mDPI being greater than 0, so this invalidates it.
mDPI = -1;
TryCacheDPIAndScale();
// If mDPI was set to -1 to invalidate it and then TryCacheDPIAndScale
// fails to cache the values, then mDefaultScale.scale might be invalid.
// We don't want to send that value to content. Just send -1 for it too in
// that case.
Unused << SendUIResolutionChanged(mDPI, mRounding,
mDPI < 0 ? -1.0 : mDefaultScale.scale);
}
ErrorResult rv;
RefPtr<Promise> jsPromise =
Promise::Create(mFrameElement->OwnerDoc()->GetOwnerGlobal(), rv);
if (rv.Failed()) {
return NS_ERROR_FAILURE;
}
RefPtr<Promise> copy(jsPromise);
copy.forget(aPromise);
auto cblPromise = SendGetContentBlockingLog();
cblPromise->Then(
GetMainThreadSerialEventTarget(), __func__,
[jsPromise](Tuple<nsCString, bool>&& aResult) {
if (Get<1>(aResult)) {
NS_ConvertUTF8toUTF16 utf16(Get<0>(aResult));
jsPromise->MaybeResolve(std::move(utf16));
} else {
jsPromise->MaybeRejectWithUndefined();
}
},
[jsPromise](ResponseRejectReason&& aReason) {
jsPromise->MaybeRejectWithUndefined();
});
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::MaybeCancelContentJSExecutionFromScript(
nsIRemoteTab::NavigationType aNavigationType,
JS::Handle<JS::Value> aCancelContentJSOptions, JSContext* aCx) {
dom::CancelContentJSOptions cancelContentJSOptions;
if (!cancelContentJSOptions.Init(aCx, aCancelContentJSOptions)) {
return NS_ERROR_INVALID_ARG;
void BrowserParent::Deprioritize() {
if (mActiveInPriorityManager) {
ProcessPriorityManager::TabActivityChanged(this, false);
mActiveInPriorityManager = false;
}
if (StaticPrefs::dom_ipc_cancel_content_js_when_navigating()) {
Manager()->CancelContentJSExecutionIfRunning(this, aNavigationType,
cancelContentJSOptions);
}
bool BrowserParent::GetHasContentOpener() { return mHasContentOpener; }
void BrowserParent::SetHasContentOpener(bool aHasContentOpener) {
mHasContentOpener = aHasContentOpener;
}
bool BrowserParent::GetHasBeforeUnload() { return mHasBeforeUnload; }
bool BrowserParent::StartApzAutoscroll(float aAnchorX, float aAnchorY,
nsViewID aScrollId,
uint32_t aPresShellId) {
if (!AsyncPanZoomEnabled()) {
return false;
}
bool success = false;
if (mRenderFrame.IsInitialized()) {
layers::LayersId layersId = mRenderFrame.GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
SLGuidAndRenderRoot guid(layersId, aPresShellId, aScrollId,
gfxUtils::GetContentRenderRoot());
// The anchor coordinates that are passed in are relative to the origin
// of the screen, but we are sending them to APZ which only knows about
// coordinates relative to the widget, so convert them accordingly.
CSSPoint anchorCss{aAnchorX, aAnchorY};
LayoutDeviceIntPoint anchor =
RoundedToInt(anchorCss * widget->GetDefaultScale());
anchor -= widget->WidgetToScreenOffset();
success = widget->StartAsyncAutoscroll(
ViewAs<ScreenPixel>(
anchor, PixelCastJustification::LayoutDeviceIsScreenForBounds),
guid);
}
}
return success;
}
void BrowserParent::StopApzAutoscroll(nsViewID aScrollId,
uint32_t aPresShellId) {
if (!AsyncPanZoomEnabled()) {
return;
}
if (mRenderFrame.IsInitialized()) {
layers::LayersId layersId = mRenderFrame.GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
SLGuidAndRenderRoot guid(layersId, aPresShellId, aScrollId,
gfxUtils::GetContentRenderRoot());
widget->StopAsyncAutoscroll(guid);
}
}
return NS_OK;
}
void BrowserParent::SuppressDisplayport(bool aEnabled) {
@ -3182,64 +3152,10 @@ void BrowserParent::SuppressDisplayport(bool aEnabled) {
Unused << SendSuppressDisplayport(aEnabled);
}
NS_IMETHODIMP
BrowserParent::GetTabId(uint64_t* aId) {
*aId = GetTabId();
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::GetOsPid(int32_t* aId) {
*aId = Manager()->Pid();
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::GetHasContentOpener(bool* aResult) {
*aResult = mHasContentOpener;
return NS_OK;
}
void BrowserParent::SetHasContentOpener(bool aHasContentOpener) {
mHasContentOpener = aHasContentOpener;
}
NS_IMETHODIMP
BrowserParent::GetHasPresented(bool* aResult) {
*aResult = mHasPresented;
return NS_OK;
}
void BrowserParent::NavigateByKey(bool aForward, bool aForDocumentNavigation) {
Unused << SendNavigateByKey(aForward, aForDocumentNavigation);
}
NS_IMETHODIMP
BrowserParent::GetWindowGlobalParents(
nsTArray<RefPtr<WindowGlobalParent>>& aWindowGlobalParents) {
VisitAll([&aWindowGlobalParents](BrowserParent* aBrowser) {
const auto& windowGlobalParents = aBrowser->ManagedPWindowGlobalParent();
for (auto iter = windowGlobalParents.ConstIter(); !iter.Done();
iter.Next()) {
WindowGlobalParent* windowGlobalParent =
static_cast<WindowGlobalParent*>(iter.Get()->GetKey());
aWindowGlobalParents.AppendElement(windowGlobalParent);
}
});
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::TransmitPermissionsForPrincipal(nsIPrincipal* aPrincipal) {
return Manager()->TransmitPermissionsForPrincipal(aPrincipal);
}
NS_IMETHODIMP
BrowserParent::GetHasBeforeUnload(bool* aResult) {
*aResult = mHasBeforeUnload;
return NS_OK;
}
void BrowserParent::LayerTreeUpdate(const LayersObserverEpoch& aEpoch,
bool aActive) {
// Ignore updates from old epochs. They might tell us that layers are
@ -3657,58 +3573,6 @@ void BrowserParent::StartPersistence(
// (The actor will be destroyed on constructor failure.)
}
NS_IMETHODIMP
BrowserParent::StartApzAutoscroll(float aAnchorX, float aAnchorY,
nsViewID aScrollId, uint32_t aPresShellId,
bool* aOutRetval) {
if (!AsyncPanZoomEnabled()) {
*aOutRetval = false;
return NS_OK;
}
bool success = false;
if (mRenderFrame.IsInitialized()) {
layers::LayersId layersId = mRenderFrame.GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
SLGuidAndRenderRoot guid(layersId, aPresShellId, aScrollId,
gfxUtils::GetContentRenderRoot());
// The anchor coordinates that are passed in are relative to the origin
// of the screen, but we are sending them to APZ which only knows about
// coordinates relative to the widget, so convert them accordingly.
CSSPoint anchorCss{aAnchorX, aAnchorY};
LayoutDeviceIntPoint anchor =
RoundedToInt(anchorCss * widget->GetDefaultScale());
anchor -= widget->WidgetToScreenOffset();
success = widget->StartAsyncAutoscroll(
ViewAs<ScreenPixel>(
anchor, PixelCastJustification::LayoutDeviceIsScreenForBounds),
guid);
}
}
*aOutRetval = success;
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId) {
if (!AsyncPanZoomEnabled()) {
return NS_OK;
}
if (mRenderFrame.IsInitialized()) {
layers::LayersId layersId = mRenderFrame.GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
SLGuidAndRenderRoot guid(layersId, aPresShellId, aScrollId,
gfxUtils::GetContentRenderRoot());
widget->StopAsyncAutoscroll(guid);
}
}
return NS_OK;
}
void BrowserParent::SkipBrowsingContextDetach() {
RefPtr<nsFrameLoader> fl = GetFrameLoader();
MOZ_ASSERT(fl);
@ -3805,6 +3669,24 @@ void BrowserParent::LiveResizeStarted() { SuppressDisplayport(true); }
void BrowserParent::LiveResizeStopped() { SuppressDisplayport(false); }
void BrowserParent::SetBrowserBridgeParent(BrowserBridgeParent* aBrowser) {
// We should not have either a browser bridge or browser host yet
MOZ_ASSERT(!mBrowserBridgeParent);
MOZ_ASSERT(!mBrowserHost);
// We should not have owner content yet
MOZ_ASSERT(!mFrameElement);
mBrowserBridgeParent = aBrowser;
}
void BrowserParent::SetBrowserHost(BrowserHost* aBrowser) {
// We should not have either a browser bridge or browser host yet
MOZ_ASSERT(!mBrowserBridgeParent);
MOZ_ASSERT(!mBrowserHost);
// We should not have owner content yet
MOZ_ASSERT(!mFrameElement);
mBrowserHost = aBrowser;
}
/* static */
size_t BrowserParent::gNumActiveRecordReplayTabs;

Просмотреть файл

@ -73,6 +73,8 @@ class ClonedMessageData;
class ContentParent;
class Element;
class DataTransfer;
class BrowserHost;
class BrowserBridgeParent;
namespace ipc {
class StructuredCloneData;
@ -84,7 +86,6 @@ class StructuredCloneData;
*/
class BrowserParent final : public PBrowserParent,
public nsIDOMEventListener,
public nsIRemoteTab,
public nsIAuthPromptProvider,
public nsIKeyEventInPluginCallback,
public nsSupportsWeakReference,
@ -93,7 +94,6 @@ class BrowserParent final : public PBrowserParent,
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
friend class PBrowserParent;
friend class BrowserBridgeParent; // for clearing mBrowserBridgeParent
virtual ~BrowserParent();
@ -103,18 +103,15 @@ class BrowserParent final : public PBrowserParent,
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIAUTHPROMPTPROVIDER
// nsIRemoteTab
NS_DECL_NSIREMOTETAB
// nsIDOMEventListener interfaces
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(BrowserParent, nsIRemoteTab)
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(BrowserParent, nsIDOMEventListener)
BrowserParent(ContentParent* aManager, const TabId& aTabId,
const TabContext& aContext,
CanonicalBrowsingContext* aBrowsingContext,
uint32_t aChromeFlags,
BrowserBridgeParent* aBrowserBridgeParent = nullptr);
uint32_t aChromeFlags);
// Call from LayoutStatics only
static void InitializeStatics();
@ -127,8 +124,6 @@ class BrowserParent final : public PBrowserParent,
static BrowserParent* GetFrom(nsFrameLoader* aFrameLoader);
static BrowserParent* GetFrom(nsIRemoteTab* aBrowserParent);
static BrowserParent* GetFrom(PBrowserParent* aBrowserParent);
static BrowserParent* GetFrom(nsIContent* aContent);
@ -154,12 +149,6 @@ class BrowserParent final : public PBrowserParent,
nsIBrowserDOMWindow* GetBrowserDOMWindow() const { return mBrowserDOMWindow; }
// Returns the BrowserBridgeParent if this BrowserParent is for an
// out-of-process iframe and nullptr otherwise.
BrowserBridgeParent* GetBrowserBridgeParent() const {
return mBrowserBridgeParent;
}
already_AddRefed<nsPIDOMWindowOuter> GetParentWindowOuter();
already_AddRefed<nsIWidget> GetTopLevelWidget();
@ -179,6 +168,14 @@ class BrowserParent final : public PBrowserParent,
layout::RenderFrame* GetRenderFrame();
// Returns the BrowserBridgeParent if this BrowserParent is for an
// out-of-process iframe and nullptr otherwise.
BrowserBridgeParent* GetBrowserBridgeParent() const;
// Returns the BrowserHost if this BrowserParent is for a top-level browser
// and nullptr otherwise.
BrowserHost* GetBrowserHost() const;
ShowInfo GetShowInfo();
/**
@ -463,10 +460,7 @@ class BrowserParent final : public PBrowserParent,
void InitRendering();
void MaybeShowFrame();
// XXX/cjones: it's not clear what we gain by hiding these
// message-sending functions under a layer of indirection and
// eating the return values
void Show(const ScreenIntSize& aSize, bool aParentIsActive);
bool Show(const ScreenIntSize& aSize, bool aParentIsActive);
void UpdateDimensions(const nsIntRect& aRect, const ScreenIntSize& aSize);
@ -476,8 +470,6 @@ class BrowserParent final : public PBrowserParent,
void SizeModeChanged(const nsSizeMode& aSizeMode);
void UIResolutionChanged();
void ThemeChanged();
void HandleAccessKey(const WidgetKeyboardEvent& aEvent,
@ -681,7 +673,33 @@ class BrowserParent final : public PBrowserParent,
void SkipBrowsingContextDetach();
bool GetDocShellIsActive();
void SetDocShellIsActive(bool aDocShellIsActive);
bool GetHasPresented();
bool GetHasLayers();
bool GetRenderLayers();
void SetRenderLayers(bool aRenderLayers);
void PreserveLayers(bool aPreserveLayers);
void ForceRepaint();
void NotifyResolutionChanged();
void Deprioritize();
bool GetHasContentOpener();
bool GetHasBeforeUnload();
bool StartApzAutoscroll(float aAnchorX, float aAnchorY, nsViewID aScrollId,
uint32_t aPresShellId);
void StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId);
protected:
friend BrowserBridgeParent;
friend BrowserHost;
void SetBrowserBridgeParent(BrowserBridgeParent* aBrowser);
void SetBrowserHost(BrowserHost* aBrowser);
bool ReceiveMessage(
const nsString& aMessage, bool aSync, ipc::StructuredCloneData* aData,
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
@ -792,6 +810,10 @@ class BrowserParent final : public PBrowserParent,
// by the BrowserBridgeParent instance, which has the strong reference
// to this BrowserParent.
BrowserBridgeParent* mBrowserBridgeParent;
// Pointer to the BrowserHost that owns us, if any. This is mutually
// exclusive with mBrowserBridgeParent, and one is guaranteed to be
// non-null.
BrowserHost* mBrowserHost;
ContentCacheInParent mContentCache;

Просмотреть файл

@ -30,6 +30,7 @@
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/BrowsingContextGroup.h"
#include "mozilla/dom/BrowserBridgeHost.h"
#include "mozilla/dom/ClientManager.h"
#include "mozilla/dom/ClientOpenWindowOpActors.h"
#include "mozilla/dom/ChildProcessMessageManager.h"
@ -131,6 +132,7 @@
#include "mozInlineSpellChecker.h"
#include "nsDocShell.h"
#include "nsDocShellLoadState.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIConsoleListener.h"
#include "nsIContentViewer.h"
#include "nsICycleCollectorListener.h"
@ -243,6 +245,7 @@
#include "nsIPrincipal.h"
#include "DomainPolicy.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/ipc/CrashReporterClient.h"
#include "mozilla/net/NeckoMessageUtils.h"
#include "mozilla/widget/PuppetBidiKeyboard.h"
@ -2005,6 +2008,58 @@ void ContentChild::UpdateCookieStatus(nsIChannel* aChannel) {
csChild->TrackCookieLoad(aChannel);
}
already_AddRefed<RemoteBrowser> ContentChild::CreateBrowser(
nsFrameLoader* aFrameLoader, const TabContext& aContext,
const nsString& aRemoteType, BrowsingContext* aBrowsingContext) {
MOZ_ASSERT(XRE_IsContentProcess());
// Determine our embedder's BrowserChild actor.
RefPtr<Element> owner = aFrameLoader->GetOwnerContent();
MOZ_DIAGNOSTIC_ASSERT(owner);
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(owner->GetOwnerGlobal());
MOZ_DIAGNOSTIC_ASSERT(docShell);
RefPtr<BrowserChild> browserChild = BrowserChild::GetFrom(docShell);
MOZ_DIAGNOSTIC_ASSERT(browserChild);
uint32_t chromeFlags = 0;
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
if (docShell) {
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
}
if (treeOwner) {
nsCOMPtr<nsIWebBrowserChrome> wbc = do_GetInterface(treeOwner);
if (wbc) {
wbc->GetChromeFlags(&chromeFlags);
}
}
// Checking that this actually does something useful is
// https://bugzilla.mozilla.org/show_bug.cgi?id=1542710
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
if (loadContext && loadContext->UsePrivateBrowsing()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
}
if (docShell->GetAffectPrivateSessionLifetime()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
}
RefPtr<BrowserBridgeChild> browserBridge =
new BrowserBridgeChild(aFrameLoader, aBrowsingContext);
// Reference is freed in BrowserChild::DeallocPBrowserBridgeChild.
browserChild->SendPBrowserBridgeConstructor(
do_AddRef(browserBridge).take(),
PromiseFlatString(aContext.PresentationURL()), aRemoteType,
aBrowsingContext, chromeFlags);
browserBridge->mIPCOpen = true;
RefPtr<BrowserBridgeHost> browserBridgeHost =
new BrowserBridgeHost(browserBridge);
return browserBridgeHost.forget();
}
PScriptCacheChild* ContentChild::AllocPScriptCacheChild(
const FileDescOrError& cacheFile, const bool& wantCacheData) {
return new loader::ScriptCacheChild();

Просмотреть файл

@ -10,8 +10,10 @@
#include "base/shared_memory.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/BrowserBridgeChild.h"
#include "mozilla/dom/PBrowserOrId.h"
#include "mozilla/dom/PContentChild.h"
#include "mozilla/dom/RemoteBrowser.h"
#include "mozilla/dom/CPOWManagerGetter.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/ipc/Shmem.h"
@ -38,6 +40,7 @@ class nsIDomainPolicy;
class nsIURIClassifierCallback;
struct LookAndFeelInt;
class nsDocShellLoadState;
class nsFrameLoader;
namespace mozilla {
class RemoteSpellcheckEngineChild;
@ -77,6 +80,7 @@ class ConsoleListener;
class ClonedMessageData;
class BrowserChild;
class GetFilesHelperChild;
class TabContext;
class ContentChild final : public PContentChild,
public nsIWindowProvider,
@ -159,6 +163,10 @@ class ContentChild final : public PContentChild,
static void UpdateCookieStatus(nsIChannel* aChannel);
static already_AddRefed<RemoteBrowser> CreateBrowser(
nsFrameLoader* aFrameLoader, const TabContext& aContext,
const nsString& aRemoteType, BrowsingContext* aBrowsingContext);
mozilla::ipc::IPCResult RecvInitGMPService(
Endpoint<PGMPServiceChild>&& aGMPService);

Просмотреть файл

@ -1083,12 +1083,10 @@ mozilla::ipc::IPCResult ContentParent::RecvLaunchRDDProcess(
}
/*static*/
BrowserParent* ContentParent::CreateBrowser(const TabContext& aContext,
Element* aFrameElement,
BrowsingContext* aBrowsingContext,
ContentParent* aOpenerContentParent,
BrowserParent* aSameTabGroupAs,
uint64_t aNextRemoteTabId) {
already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
const TabContext& aContext, Element* aFrameElement,
BrowsingContext* aBrowsingContext, ContentParent* aOpenerContentParent,
BrowserParent* aSameTabGroupAs, uint64_t aNextRemoteTabId) {
AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER);
if (!sCanLaunchSubprocesses) {
@ -1105,10 +1103,11 @@ BrowserParent* ContentParent::CreateBrowser(const TabContext& aContext,
if (BrowserParent* parent =
sNextBrowserParents.GetAndRemove(aNextRemoteTabId)
.valueOr(nullptr)) {
RefPtr<BrowserHost> browserHost = new BrowserHost(parent);
MOZ_ASSERT(!parent->GetOwnerElement(),
"Shouldn't have an owner elemnt before");
parent->SetOwnerElement(aFrameElement);
return parent;
return browserHost.forget();
}
}
@ -1216,8 +1215,9 @@ BrowserParent* ContentParent::CreateBrowser(const TabContext& aContext,
Unused << browserParent->SendAwaitLargeAlloc();
}
RefPtr<BrowserHost> browserHost = new BrowserHost(browserParent);
browserParent->SetOwnerElement(aFrameElement);
return browserParent;
return browserHost.forget();
}
return nullptr;
}
@ -4683,7 +4683,7 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
const bool& aCalledFromJS, const bool& aPositionSpecified,
const bool& aSizeSpecified, nsIURI* aURIToLoad, const nsCString& aFeatures,
const float& aFullZoom, uint64_t aNextRemoteTabId, const nsString& aName,
nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewBrowserParent,
nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewRemoteTab,
bool* aWindowIsNew, int32_t& aOpenLocation,
nsIPrincipal* aTriggeringPrincipal, nsIReferrerInfo* aReferrerInfo,
bool aLoadURI, nsIContentSecurityPolicy* aCsp)
@ -4700,6 +4700,9 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
}
BrowserParent* thisBrowserParent = BrowserParent::GetFrom(aThisTab);
BrowserHost* thisBrowserHost =
thisBrowserParent ? thisBrowserParent->GetBrowserHost() : nullptr;
MOZ_ASSERT(!thisBrowserParent == !thisBrowserHost);
nsCOMPtr<nsIContent> frame;
if (thisBrowserParent) {
frame = thisBrowserParent->GetOwnerElement();
@ -4749,8 +4752,8 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
// Read the origin attributes for the tab from the opener browserParent.
OriginAttributes openerOriginAttributes;
if (thisBrowserParent) {
nsCOMPtr<nsILoadContext> loadContext = thisBrowserParent->GetLoadContext();
if (thisBrowserHost) {
nsCOMPtr<nsILoadContext> loadContext = thisBrowserHost->GetLoadContext();
loadContext->GetOriginAttributes(openerOriginAttributes);
} else if (Preferences::GetBool("browser.privatebrowsing.autostart")) {
openerOriginAttributes.mPrivateBrowsingId = 1;
@ -4786,7 +4789,7 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
if (NS_SUCCEEDED(aResult) && frameLoaderOwner) {
RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
if (frameLoader) {
aNewBrowserParent = frameLoader->GetRemoteTab();
aNewRemoteTab = frameLoader->GetRemoteTab();
// At this point, it's possible the inserted frameloader hasn't gone
// through layout yet. To ensure that the dimensions that we send down
// when telling the frameloader to display will be correct (instead of
@ -4816,13 +4819,15 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
}
aResult = pwwatch->OpenWindowWithRemoteTab(
thisBrowserParent, aFeatures, aCalledFromJS, aFullZoom, aNextRemoteTabId,
!aSetOpener, getter_AddRefs(aNewBrowserParent));
thisBrowserHost, aFeatures, aCalledFromJS, aFullZoom, aNextRemoteTabId,
!aSetOpener, getter_AddRefs(aNewRemoteTab));
if (NS_WARN_IF(NS_FAILED(aResult))) {
return IPC_OK();
}
MOZ_ASSERT(aNewBrowserParent);
MOZ_ASSERT(aNewRemoteTab);
BrowserHost* newBrowserHost = BrowserHost::GetFrom(aNewRemoteTab.get());
BrowserParent* newBrowserParent = newBrowserHost->GetActor();
// At this point, it's possible the inserted frameloader hasn't gone through
// layout yet. To ensure that the dimensions that we send down when telling
@ -4833,8 +4838,7 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
// This involves doing a bit of gymnastics in order to get at the FrameLoader,
// so we scope this to avoid polluting the main function scope.
{
nsCOMPtr<Element> frameElement =
BrowserParent::GetFrom(aNewBrowserParent)->GetOwnerElement();
nsCOMPtr<Element> frameElement = newBrowserHost->GetOwnerElement();
MOZ_ASSERT(frameElement);
RefPtr<nsFrameLoaderOwner> frameLoaderOwner = do_QueryObject(frameElement);
MOZ_ASSERT(frameLoaderOwner);
@ -4846,8 +4850,7 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
// If we were passed a name for the window which would override the default,
// we should send it down to the new tab.
if (nsContentUtils::IsOverridingWindowName(aName)) {
Unused
<< BrowserParent::GetFrom(aNewBrowserParent)->SendSetWindowName(aName);
Unused << newBrowserParent->SendSetWindowName(aName);
}
// Don't send down the OriginAttributes if the content process is handling
@ -4856,8 +4859,7 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
// If we send it down in the non-async case, then we might set the
// OriginAttributes after the document has already navigated.
if (!aSetOpener) {
Unused << BrowserParent::GetFrom(aNewBrowserParent)
->SendSetOriginAttributes(openerOriginAttributes);
Unused << newBrowserParent->SendSetOriginAttributes(openerOriginAttributes);
}
if (aURIToLoad && aLoadURI) {
@ -4866,7 +4868,7 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
openerWindow = thisBrowserParent->GetParentWindowOuter();
}
nsCOMPtr<nsIBrowserDOMWindow> newBrowserDOMWin =
BrowserParent::GetFrom(aNewBrowserParent)->GetBrowserDOMWindow();
newBrowserParent->GetBrowserDOMWindow();
if (NS_WARN_IF(!newBrowserDOMWin)) {
aResult = NS_ERROR_ABORT;
return IPC_OK();
@ -4946,7 +4948,8 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
if (sNextBrowserParents.GetAndRemove(nextRemoteTabId).valueOr(nullptr)) {
cwi.windowOpened() = false;
}
MOZ_ASSERT(BrowserParent::GetFrom(newRemoteTab) == newTab);
MOZ_ASSERT(BrowserHost::GetFrom(newRemoteTab.get()) ==
newTab->GetBrowserHost());
newTab->SwapFrameScriptsFrom(cwi.frameScripts());
newTab->MaybeShowFrame();

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/dom/PContentParent.h"
#include "mozilla/dom/CPOWManagerGetter.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/dom/RemoteBrowser.h"
#include "mozilla/gfx/gfxVarReceiver.h"
#include "mozilla/gfx/GPUProcessListener.h"
#include "mozilla/ipc/BackgroundUtils.h"
@ -208,12 +209,10 @@ class ContentParent final : public PContentParent,
* should be the frame/iframe element with which this process will
* associated.
*/
static BrowserParent* CreateBrowser(const TabContext& aContext,
Element* aFrameElement,
BrowsingContext* aBrowsingContext,
ContentParent* aOpenerContentParent,
BrowserParent* aSameTabGroupAs,
uint64_t aNextRemoteTabId);
static already_AddRefed<RemoteBrowser> CreateBrowser(
const TabContext& aContext, Element* aFrameElement,
BrowsingContext* aBrowsingContext, ContentParent* aOpenerContentParent,
BrowserParent* aSameTabGroupAs, uint64_t aNextRemoteTabId);
static void GetAll(nsTArray<ContentParent*>& aArray);
@ -682,7 +681,7 @@ class ContentParent final : public PContentParent,
const bool& aSizeSpecified, nsIURI* aURIToLoad,
const nsCString& aFeatures, const float& aFullZoom,
uint64_t aNextRemoteTabId, const nsString& aName, nsresult& aResult,
nsCOMPtr<nsIRemoteTab>& aNewBrowserParent, bool* aWindowIsNew,
nsCOMPtr<nsIRemoteTab>& aNewRemoteTab, bool* aWindowIsNew,
int32_t& aOpenLocation, nsIPrincipal* aTriggeringPrincipal,
nsIReferrerInfo* aReferrerInfo, bool aLoadUri,
nsIContentSecurityPolicy* aCsp);

Просмотреть файл

@ -6,6 +6,7 @@
#include "mozilla/dom/JSWindowActorBinding.h"
#include "mozilla/dom/JSWindowActorChild.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/dom/MessageManagerBinding.h"

Просмотреть файл

@ -72,7 +72,7 @@ void JSWindowActorParent::SendRawMessage(const JSWindowActorMessageMeta& aMeta,
// Cross-process case - send data over WindowGlobalParent to other side.
ClonedMessageData msgData;
RefPtr<BrowserParent> browserParent = mManager->GetRemoteTab();
RefPtr<BrowserParent> browserParent = mManager->GetBrowserParent();
ContentParent* cp = browserParent->Manager();
if (NS_WARN_IF(!aData.BuildClonedMessageDataForParent(cp, msgData))) {
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);

Просмотреть файл

@ -8,6 +8,7 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/BrowserHost.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/Hal.h"
#include "mozilla/IntegerPrintfMacros.h"
@ -683,20 +684,17 @@ void ParticularProcessPriorityManager::OnRemoteBrowserFrameShown(
void ParticularProcessPriorityManager::OnBrowserParentDestroyed(
nsISupports* aSubject) {
nsCOMPtr<nsIRemoteTab> tp = do_QueryInterface(aSubject);
NS_ENSURE_TRUE_VOID(tp);
nsCOMPtr<nsIRemoteTab> remoteTab = do_QueryInterface(aSubject);
NS_ENSURE_TRUE_VOID(remoteTab);
BrowserHost* browserHost = BrowserHost::GetFrom(remoteTab.get());
MOZ_ASSERT(XRE_IsParentProcess());
if (BrowserParent::GetFrom(tp)->Manager() != mContentParent) {
if (browserHost->GetContentParent() &&
browserHost->GetContentParent() != mContentParent) {
return;
}
uint64_t tabId;
if (NS_WARN_IF(NS_FAILED(tp->GetTabId(&tabId)))) {
return;
}
mActiveBrowserParents.RemoveEntry(tabId);
mActiveBrowserParents.RemoveEntry(browserHost->GetTabId());
ResetPriority();
}

63
dom/ipc/RemoteBrowser.h Normal file
Просмотреть файл

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_ipc_RemoteBrowser_h
#define mozilla_dom_ipc_RemoteBrowser_h
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsILoadContext.h"
#include "nsISupports.h"
#include "nsISupportsImpl.h"
#include "nsIURI.h"
#include "nsRect.h"
#include "Units.h"
namespace mozilla {
namespace dom {
class BrowserHost;
class BrowserBridgeHost;
/**
* An interface to control a browser hosted in another process.
*
* This is used by nsFrameLoader to abstract between hosting a top-level remote
* browser in the chrome process and hosting an OOP-iframe in a content process.
*
* There are two concrete implementations that are used depending on whether
* the nsFrameLoader is in the chrome or content process. A chrome process
* nsFrameLoader will use BrowserHost, and a content process nsFrameLoader will
* use BrowserBridgeHost.
*/
class RemoteBrowser : public nsISupports {
public:
typedef mozilla::layers::LayersId LayersId;
// Try to cast this RemoteBrowser to a BrowserHost, may return null
virtual BrowserHost* AsBrowserHost() = 0;
// Try to cast this RemoteBrowser to a BrowserBridgeHost, may return null
virtual BrowserBridgeHost* AsBrowserBridgeHost() = 0;
virtual LayersId GetLayersId() const = 0;
virtual BrowsingContext* GetBrowsingContext() const = 0;
virtual nsILoadContext* GetLoadContext() const = 0;
virtual void LoadURL(nsIURI* aURI) = 0;
virtual void ResumeLoad(uint64_t aPendingSwitchId) = 0;
virtual void DestroyStart() = 0;
virtual void DestroyComplete() = 0;
virtual bool Show(const ScreenIntSize& aSize, bool aParentIsActive) = 0;
virtual void UpdateDimensions(const nsIntRect& aRect,
const ScreenIntSize& aSize) = 0;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_RemoteBrowser_h

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/dom/BrowserBridgeParent.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/BrowserHost.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/dom/WindowGlobalActorsBinding.h"
#include "mozilla/dom/WindowGlobalChild.h"
@ -143,7 +144,7 @@ already_AddRefed<WindowGlobalChild> WindowGlobalParent::GetChildActor() {
return do_AddRef(static_cast<WindowGlobalChild*>(otherSide));
}
already_AddRefed<BrowserParent> WindowGlobalParent::GetRemoteTab() {
already_AddRefed<BrowserParent> WindowGlobalParent::GetBrowserParent() {
if (IsInProcess() || mIPCClosed) {
return nullptr;
}
@ -164,7 +165,7 @@ IPCResult WindowGlobalParent::RecvBecomeCurrentWindowGlobal() {
IPCResult WindowGlobalParent::RecvDestroy() {
if (!mIPCClosed) {
RefPtr<BrowserParent> browserParent = GetRemoteTab();
RefPtr<BrowserParent> browserParent = GetBrowserParent();
if (!browserParent || !browserParent->IsDestroyed()) {
// Make a copy so that we can avoid potential iterator invalidation when
// calling the user-provided Destroy() methods.
@ -200,7 +201,7 @@ void WindowGlobalParent::ReceiveRawMessage(
}
const nsAString& WindowGlobalParent::GetRemoteType() {
if (RefPtr<BrowserParent> browserParent = GetRemoteTab()) {
if (RefPtr<BrowserParent> browserParent = GetBrowserParent()) {
return browserParent->Manager()->GetRemoteType();
}
@ -253,7 +254,7 @@ IPCResult WindowGlobalParent::RecvDidEmbedBrowsingContext(
already_AddRefed<Promise> WindowGlobalParent::ChangeFrameRemoteness(
dom::BrowsingContext* aBc, const nsAString& aRemoteType,
uint64_t aPendingSwitchId, ErrorResult& aRv) {
RefPtr<BrowserParent> browserParent = GetRemoteTab();
RefPtr<BrowserParent> browserParent = GetBrowserParent();
if (NS_WARN_IF(!browserParent)) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
@ -277,12 +278,13 @@ already_AddRefed<Promise> WindowGlobalParent::ChangeFrameRemoteness(
}
// If we got a BrowserBridgeParent, the frame is out-of-process, so pull
// our target BrowserParent off of it. Otherwise, it's an in-process
// our target content process off of it. Otherwise, it's an in-process
// frame, so we can directly use ours.
if (bridge) {
promise->MaybeResolve(bridge->GetBrowserParent());
promise->MaybeResolve(
bridge->GetBrowserParent()->Manager()->ChildID());
} else {
promise->MaybeResolve(browserParent);
promise->MaybeResolve(browserParent->Manager()->ChildID());
}
};

Просмотреть файл

@ -64,7 +64,7 @@ class WindowGlobalParent final : public WindowGlobalActor,
// Get this actor's manager if it is not an in-process actor. Returns
// |nullptr| if the actor has been torn down, or is in-process.
already_AddRefed<BrowserParent> GetRemoteTab();
already_AddRefed<BrowserParent> GetBrowserParent();
void ReceiveRawMessage(const JSWindowActorMessageMeta& aMeta,
ipc::StructuredCloneData&& aData);

Просмотреть файл

@ -35,8 +35,10 @@ EXPORTS.mozilla.dom.ipc += [
EXPORTS.mozilla.dom += [
'BrowserBridgeChild.h',
'BrowserBridgeHost.h',
'BrowserBridgeParent.h',
'BrowserChild.h',
'BrowserHost.h',
'BrowserParent.h',
'CoalescedInputData.h',
'CoalescedMouseData.h',
@ -56,6 +58,7 @@ EXPORTS.mozilla.dom += [
'MemoryReportRequest.h',
'PermissionMessageUtils.h',
'ReferrerInfoUtils.h',
'RemoteBrowser.h',
'RemoteWebProgress.h',
'RemoteWebProgressRequest.h',
'TabContext.h',
@ -76,8 +79,10 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [
'BrowserBridgeChild.cpp',
'BrowserBridgeHost.cpp',
'BrowserBridgeParent.cpp',
'BrowserChild.cpp',
'BrowserHost.cpp',
'BrowserParent.cpp',
'CoalescedMouseData.cpp',
'CoalescedWheelData.cpp',

Просмотреть файл

@ -5943,7 +5943,7 @@ mozilla::ipc::IPCResult Snapshot::RecvCheckpoint(
nsTArray<LSWriteInfo>&& aWriteInfos) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(mUsage >= 0);
MOZ_DIAGNOSTIC_ASSERT(mPeakUsage >= mUsage);
MOZ_ASSERT(mPeakUsage >= mUsage);
if (NS_WARN_IF(aWriteInfos.IsEmpty())) {
ASSERT_UNLESS_FUZZING();

Просмотреть файл

@ -862,8 +862,9 @@ nsresult mozJSComponentLoader::ObjectForLocation(
JS::SourceText<mozilla::Utf8Unit> srcBuf;
if (srcBuf.init(cx, buf.get(), map.size(),
JS::SourceOwnership::Borrowed)) {
script = reuseGlobal ? CompileForNonSyntacticScope(cx, options, srcBuf)
: Compile(cx, options, srcBuf);
script = reuseGlobal ? CompileForNonSyntacticScopeDontInflate(
cx, options, srcBuf)
: CompileDontInflate(cx, options, srcBuf);
} else {
MOZ_ASSERT(!script);
}
@ -874,8 +875,9 @@ nsresult mozJSComponentLoader::ObjectForLocation(
JS::SourceText<mozilla::Utf8Unit> srcBuf;
if (srcBuf.init(cx, str.get(), str.Length(),
JS::SourceOwnership::Borrowed)) {
script = reuseGlobal ? CompileForNonSyntacticScope(cx, options, srcBuf)
: Compile(cx, options, srcBuf);
script = reuseGlobal ? CompileForNonSyntacticScopeDontInflate(
cx, options, srcBuf)
: CompileDontInflate(cx, options, srcBuf);
} else {
MOZ_ASSERT(!script);
}

Просмотреть файл

@ -18,9 +18,9 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "xpcprivate.h" // For xpc::OptionsBase
#include "js/CompilationAndEvaluation.h"
#include "js/SourceText.h" // JS::Source{Ownership,Text}
#include "xpcprivate.h" // xpc::OptionsBase
#include "js/CompilationAndEvaluation.h" // JS::Compile{,ForNonSyntacticScope}DontInflate
#include "js/SourceText.h" // JS::Source{Ownership,Text}
#include "js/Wrapper.h"
#include "mozilla/ContentPrincipal.h"
@ -150,9 +150,9 @@ static JSScript* PrepareScript(nsIURI* uri, JSContext* cx,
}
if (wantGlobalScript) {
return JS::Compile(cx, options, srcBuf);
return JS::CompileDontInflate(cx, options, srcBuf);
}
return JS::CompileForNonSyntacticScope(cx, options, srcBuf);
return JS::CompileForNonSyntacticScopeDontInflate(cx, options, srcBuf);
}
static bool EvalScript(JSContext* cx, HandleObject targetObj,

Просмотреть файл

@ -1393,8 +1393,8 @@ bool nsPresContext::UIResolutionChangedSubdocumentCallback(
return true;
}
static void NotifyTabUIResolutionChanged(BrowserParent* aTab, void* aArg) {
aTab->UIResolutionChanged();
static void NotifyTabUIResolutionChanged(nsIRemoteTab* aTab, void* aArg) {
aTab->NotifyResolutionChanged();
}
static void NotifyChildrenUIResolutionChanged(nsPIDOMWindowOuter* aWindow) {

Просмотреть файл

@ -625,25 +625,6 @@ nsresult nsMenuFrame::AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
return NS_OK;
}
nsIContent* nsMenuFrame::GetAnchor() {
mozilla::dom::Element* anchor = nullptr;
nsAutoString id;
mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::anchor, id);
if (!id.IsEmpty()) {
Document* doc = mContent->OwnerDoc();
anchor =
doc->GetAnonymousElementByAttribute(mContent, nsGkAtoms::anonid, id);
if (!anchor) {
anchor = doc->GetElementById(id);
}
}
// Always return the menu's content if the anchor wasn't set or wasn't found.
return anchor && anchor->GetPrimaryFrame() ? anchor : GetContent();
}
void nsMenuFrame::OpenMenu(bool aSelectFirstItem) {
if (!mContent) return;
@ -693,8 +674,7 @@ nsMenuFrame::DoXULLayout(nsBoxLayoutState& aState) {
nsMenuPopupFrame* popupFrame = GetPopup();
if (popupFrame) {
bool sizeToPopup = IsSizedToPopup(mContent, false);
popupFrame->LayoutPopup(aState, this, GetAnchor()->GetPrimaryFrame(),
sizeToPopup);
popupFrame->LayoutPopup(aState, this, sizeToPopup);
}
return rv;

Просмотреть файл

@ -123,12 +123,6 @@ class nsMenuFrame final : public nsBoxFrame, public nsIReflowCallback {
virtual nsIScrollableFrame* GetScrollTargetFrame() override;
// Retrieve the element that the menu should be anchored to. By default this
// is the menu itself. However, the anchor attribute may refer to the value of
// an anonid within the menu's binding, or, if not found, the id of an element
// in the document.
nsIContent* GetAnchor();
/**
* NOTE: OpenMenu will open the menu asynchronously.
*/

Просмотреть файл

@ -461,8 +461,7 @@ void nsMenuPopupFrame::UpdateWidgetProperties() {
}
void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState,
nsIFrame* aParentMenu, nsIFrame* aAnchor,
bool aSizedToPopup) {
nsIFrame* aParentMenu, bool aSizedToPopup) {
if (IsLeaf()) {
return;
}
@ -517,7 +516,7 @@ void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState,
bool needCallback = false;
if (shouldPosition) {
SetPopupPosition(aAnchor, false, aSizedToPopup,
SetPopupPosition(aParentMenu, false, aSizedToPopup,
mPopupState == ePopupPositioning);
needCallback = true;
}
@ -544,7 +543,7 @@ void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState,
}
if (rePosition) {
SetPopupPosition(aAnchor, false, aSizedToPopup, false);
SetPopupPosition(aParentMenu, false, aSizedToPopup, false);
}
nsPresContext* pc = PresContext();
@ -604,7 +603,7 @@ void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState,
if (needCallback && !mReflowCallbackData.mPosted) {
pc->PresShell()->PostReflowCallback(this);
mReflowCallbackData.MarkPosted(aAnchor, aSizedToPopup, openChanged);
mReflowCallbackData.MarkPosted(aParentMenu, aSizedToPopup, openChanged);
}
}

Просмотреть файл

@ -257,7 +257,7 @@ class nsMenuPopupFrame final : public nsBoxFrame,
// layout, position and display the popup as needed
MOZ_CAN_RUN_SCRIPT_BOUNDARY
void LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu,
nsIFrame* aAnchor, bool aSizedToPopup);
bool aSizedToPopup);
nsView* GetRootViewForPopup(nsIFrame* aStartFrame);

Просмотреть файл

@ -109,7 +109,7 @@ nsPopupSetFrame::DoXULLayout(nsBoxLayoutState& aState) {
// lay out all of our currently open popups.
for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
nsMenuPopupFrame* popupChild = static_cast<nsMenuPopupFrame*>(e.get());
popupChild->LayoutPopup(aState, nullptr, nullptr, false);
popupChild->LayoutPopup(aState, nullptr, false);
}
return rv;

Просмотреть файл

@ -682,7 +682,7 @@ void nsXULPopupManager::ShowMenu(nsIContent* aMenu, bool aSelectFirstItem,
// there is no trigger event for menus
InitTriggerEvent(nullptr, nullptr, nullptr);
popupFrame->InitializePopup(menuFrame->GetAnchor(), nullptr, position, 0, 0,
popupFrame->InitializePopup(aMenu, nullptr, position, 0, 0,
MenuPopupAnchorType_Node, true);
if (aAsynchronous) {

Просмотреть файл

@ -6,7 +6,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=987230
-->
<window title="Mozilla Bug 987230"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="SimpleTest.waitForFocus(nextTest, window)">
onload="SimpleTest.waitForFocus(startTest, window)">
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
@ -108,9 +108,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=987230
popup.openPopup(anchor, "bottomcenter topright");
}
let popup = document.getElementById("mypopup");
let outerAnchor = document.getElementById("toolbarbutton-anchor");
let anchor = document.getAnonymousElementByAttribute(outerAnchor, "class", "toolbarbutton-icon");
let popup, outerAnchor, anchor;
function startTest() {
popup = document.getElementById("mypopup");
outerAnchor = document.getElementById("toolbarbutton-anchor");
anchor = outerAnchor.icon;
nextTest();
}
function nextTest(e) {
synthesizeMouse(outerAnchor, 5, 5, {});

Просмотреть файл

@ -8,6 +8,8 @@
#include "HttpLog.h"
#include "HttpChannelParentListener.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentProcessManager.h"
#include "mozilla/dom/ServiceWorkerInterceptController.h"
#include "mozilla/dom/ServiceWorkerUtils.h"
#include "mozilla/net/HttpChannelParent.h"
@ -158,13 +160,14 @@ nsresult HttpChannelParentListener::TriggerCrossProcessRedirect(
nsCOMPtr<nsIChannel> channel = aChannel;
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(channel);
RefPtr<nsHttpChannel::TabPromise> p = httpChannel->TakeRedirectTabPromise();
RefPtr<nsHttpChannel::ContentProcessIdPromise> p =
httpChannel->TakeRedirectContentProcessIdPromise();
nsCOMPtr<nsILoadInfo> loadInfo = aLoadInfo;
RefPtr<HttpChannelParentListener> self = this;
p->Then(
GetMainThreadSerialEventTarget(), __func__,
[=](nsCOMPtr<nsIRemoteTab> tp) {
[=](uint64_t cpId) {
nsresult rv;
// Register the new channel and obtain id for it
@ -199,8 +202,13 @@ nsresult HttpChannelParentListener::TriggerCrossProcessRedirect(
MOZ_ALWAYS_SUCCEEDS(internalChannel->GetRedirectMode(&redirectMode));
}
dom::BrowserParent* browserParent = dom::BrowserParent::GetFrom(tp);
auto result = browserParent->Manager()->SendCrossProcessRedirect(
dom::ContentParent* cp =
dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
ContentParentId{cpId});
if (!cp) {
return NS_ERROR_UNEXPECTED;
}
auto result = cp->SendCrossProcessRedirect(
self->mRedirectChannelId, uri, newLoadFlags, loadInfoArgs,
channelId, originalURI, aIdentifier, redirectMode);

Просмотреть файл

@ -128,6 +128,7 @@
#include "HttpTrafficAnalyzer.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "js/Conversions.h"
#ifdef MOZ_TASK_TRACER
# include "GeckoTaskTracer.h"
@ -2569,7 +2570,7 @@ nsresult nsHttpChannel::ContinueProcessResponse1() {
// notify "http-on-may-change-process" observers
gHttpHandler->OnMayChangeProcess(this);
if (mRedirectTabPromise) {
if (mRedirectContentProcessIdPromise) {
MOZ_ASSERT(!mOnStartRequestCalled);
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
@ -7249,10 +7250,11 @@ nsHttpChannel::GetRequestMethod(nsACString& aMethod) {
class DomPromiseListener final : dom::PromiseNativeHandler {
NS_DECL_ISUPPORTS
static RefPtr<nsHttpChannel::TabPromise> Create(dom::Promise* aDOMPromise) {
static RefPtr<nsHttpChannel::ContentProcessIdPromise> Create(
dom::Promise* aDOMPromise) {
MOZ_ASSERT(aDOMPromise);
RefPtr<DomPromiseListener> handler = new DomPromiseListener();
RefPtr<nsHttpChannel::TabPromise> promise =
RefPtr<nsHttpChannel::ContentProcessIdPromise> promise =
handler->mPromiseHolder.Ensure(__func__);
aDOMPromise->AppendNativeHandler(handler);
return promise;
@ -7260,15 +7262,12 @@ class DomPromiseListener final : dom::PromiseNativeHandler {
virtual void ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) override {
nsCOMPtr<nsIRemoteTab> browserParent;
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
nsresult rv =
UnwrapArg<nsIRemoteTab>(aCx, obj, getter_AddRefs(browserParent));
if (NS_FAILED(rv)) {
mPromiseHolder.Reject(rv, __func__);
uint64_t cpId;
if (!JS::ToUint64(aCx, aValue, &cpId)) {
mPromiseHolder.Reject(NS_ERROR_FAILURE, __func__);
return;
}
mPromiseHolder.Resolve(browserParent, __func__);
mPromiseHolder.Resolve(cpId, __func__);
}
virtual void RejectedCallback(JSContext* aCx,
@ -7283,15 +7282,15 @@ class DomPromiseListener final : dom::PromiseNativeHandler {
private:
DomPromiseListener() = default;
~DomPromiseListener() = default;
MozPromiseHolder<nsHttpChannel::TabPromise> mPromiseHolder;
MozPromiseHolder<nsHttpChannel::ContentProcessIdPromise> mPromiseHolder;
};
NS_IMPL_ISUPPORTS0(DomPromiseListener)
NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(dom::Promise* aTabPromise,
uint64_t aIdentifier) {
NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) {
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_ARG(aTabPromise);
NS_ENSURE_ARG(aContentProcessIdPromise);
LOG(("nsHttpChannel::SwitchProcessTo [this=%p]", this));
LogCallingScriptLocation(this);
@ -7299,7 +7298,8 @@ NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(dom::Promise* aTabPromise,
// We cannot do this after OnStartRequest of the listener has been called.
NS_ENSURE_FALSE(mOnStartRequestCalled, NS_ERROR_NOT_AVAILABLE);
mRedirectTabPromise = DomPromiseListener::Create(aTabPromise);
mRedirectContentProcessIdPromise =
DomPromiseListener::Create(aContentProcessIdPromise);
mCrossProcessRedirectIdentifier = aIdentifier;
return NS_OK;
}
@ -7650,7 +7650,7 @@ nsHttpChannel::OnStartRequest(nsIRequest* request) {
// notify "http-on-may-change-process" observers
gHttpHandler->OnMayChangeProcess(this);
if (mRedirectTabPromise) {
if (mRedirectContentProcessIdPromise) {
PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest1);
rv = StartCrossProcessRedirect();
if (NS_SUCCEEDED(rv)) {

Просмотреть файл

@ -286,9 +286,10 @@ class nsHttpChannel final : public HttpBaseChannel,
}
TransactionObserver* GetTransactionObserver() { return mTransactionObserver; }
typedef MozPromise<nsCOMPtr<nsIRemoteTab>, nsresult, false> TabPromise;
already_AddRefed<TabPromise> TakeRedirectTabPromise() {
return mRedirectTabPromise.forget();
typedef MozPromise<uint64_t, nsresult, false> ContentProcessIdPromise;
already_AddRefed<ContentProcessIdPromise>
TakeRedirectContentProcessIdPromise() {
return mRedirectContentProcessIdPromise.forget();
}
uint64_t CrossProcessRedirectIdentifier() {
return mCrossProcessRedirectIdentifier;
@ -576,7 +577,7 @@ class nsHttpChannel final : public HttpBaseChannel,
// The associated childChannel is getting relocated to another process.
// This promise will be resolved when that process is set up.
RefPtr<TabPromise> mRedirectTabPromise;
RefPtr<ContentProcessIdPromise> mRedirectContentProcessIdPromise;
// This identifier is passed to the childChannel in order to identify it.
uint64_t mCrossProcessRedirectIdentifier = 0;

Просмотреть файл

@ -70,7 +70,7 @@ ProcessChooser.prototype = {
// Can asyncly create a tab, or can resolve with a tab that was
// previously created.
info("resolving");
resolve(self.remoteTab);
resolve(self.remoteTab.contentProcessId);
});
info("calling switchprocessto");

Просмотреть файл

@ -32,7 +32,7 @@ add_task(async function test_button_background_properties() {
await extension.startup();
let toolbarButton = document.querySelector("#home-button");
let toolbarButtonIcon = document.getAnonymousElementByAttribute(toolbarButton, "class", "toolbarbutton-icon");
let toolbarButtonIcon = toolbarButton.icon;
let toolbarButtonIconCS = window.getComputedStyle(toolbarButtonIcon);
InspectorUtils.addPseudoClassLock(toolbarButton, ":hover");

Просмотреть файл

@ -22,7 +22,7 @@
#include "mozilla/Unused.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/dom/BrowserHost.h"
#include "nsIContentPolicy.h"
#include "nsIHttpChannelInternal.h"
#include "nsIHttpHeaderVisitor.h"
@ -140,10 +140,10 @@ already_AddRefed<ChannelWrapper> ChannelWrapper::Get(const GlobalObject& global,
already_AddRefed<ChannelWrapper> ChannelWrapper::GetRegisteredChannel(
const GlobalObject& global, uint64_t aChannelId,
const WebExtensionPolicy& aAddon, nsIRemoteTab* aBrowserParent) {
const WebExtensionPolicy& aAddon, nsIRemoteTab* aRemoteTab) {
ContentParent* contentParent = nullptr;
if (BrowserParent* parent = static_cast<BrowserParent*>(aBrowserParent)) {
contentParent = parent->Manager();
if (BrowserHost* host = BrowserHost::GetFrom(aRemoteTab)) {
contentParent = host->GetActor()->Manager();
}
auto& webreq = WebRequestService::GetSingleton();
@ -682,12 +682,12 @@ void ChannelWrapper::RegisterTraceableChannel(const WebExtensionPolicy& aAddon,
already_AddRefed<nsITraceableChannel> ChannelWrapper::GetTraceableChannel(
nsAtom* aAddonId, dom::ContentParent* aContentParent) const {
nsCOMPtr<nsIRemoteTab> browserParent;
if (mAddonEntries.Get(aAddonId, getter_AddRefs(browserParent))) {
nsCOMPtr<nsIRemoteTab> remoteTab;
if (mAddonEntries.Get(aAddonId, getter_AddRefs(remoteTab))) {
ContentParent* contentParent = nullptr;
if (browserParent) {
if (remoteTab) {
contentParent =
static_cast<BrowserParent*>(browserParent.get())->Manager();
BrowserHost::GetFrom(remoteTab.get())->GetActor()->Manager();
}
if (contentParent == aContentParent) {

Просмотреть файл

@ -66,6 +66,7 @@
#include "mozilla/dom/Storage.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/dom/BrowserHost.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/TabGroup.h"
#include "nsIXULWindow.h"
@ -476,7 +477,7 @@ nsWindowWatcher::OpenWindowWithRemoteTab(
if (aRemoteTab) {
// We need to examine the window that aRemoteTab belongs to in
// order to inform us of what kind of window we're going to open.
BrowserParent* openingTab = BrowserParent::GetFrom(aRemoteTab);
BrowserHost* openingTab = BrowserHost::GetFrom(aRemoteTab);
parentWindowOuter = openingTab->GetParentWindowOuter();
// Propagate the privacy & fission status of the parent window, if

Просмотреть файл

@ -659,6 +659,7 @@ if (!isDummyDocument) {
"chrome://global/content/elements/textbox.js",
"chrome://global/content/elements/tabbox.js",
"chrome://global/content/elements/text.js",
"chrome://global/content/elements/toolbarbutton.js",
"chrome://global/content/elements/tree.js",
"chrome://global/content/elements/wizard.js",
]) {

Просмотреть файл

@ -62,7 +62,6 @@ toolkit.jar:
#endif
content/global/widgets.css
content/global/bindings/autocomplete.xml (widgets/autocomplete.xml)
content/global/bindings/button.xml (widgets/button.xml)
content/global/bindings/calendar.js (widgets/calendar.js)
content/global/bindings/datekeeper.js (widgets/datekeeper.js)
content/global/bindings/datepicker.js (widgets/datepicker.js)
@ -77,7 +76,6 @@ toolkit.jar:
* content/global/bindings/textbox.xml (widgets/textbox.xml)
content/global/bindings/timekeeper.js (widgets/timekeeper.js)
content/global/bindings/timepicker.js (widgets/timepicker.js)
content/global/bindings/toolbarbutton.xml (widgets/toolbarbutton.xml)
content/global/bindings/wizard.xml (widgets/wizard.xml)
content/global/elements/autocomplete-popup.js (widgets/autocomplete-popup.js)
content/global/elements/autocomplete-richlistitem.js (widgets/autocomplete-richlistitem.js)
@ -103,6 +101,7 @@ toolkit.jar:
content/global/elements/tabbox.js (widgets/tabbox.js)
content/global/elements/text.js (widgets/text.js)
content/global/elements/textbox.js (widgets/textbox.js)
content/global/elements/toolbarbutton.js (widgets/toolbarbutton.js)
content/global/elements/videocontrols.js (widgets/videocontrols.js)
content/global/elements/tree.js (widgets/tree.js)
content/global/elements/wizard.js (widgets/wizard.js)

Просмотреть файл

@ -127,7 +127,6 @@ support-files = window_maximized_persist.xul
[test_navigate_persist.html]
support-files = window_navigate_persist.html
[test_menu.xul]
[test_menu_anchored.xul]
[test_menu_withcapture.xul]
[test_menu_hide.xul]
[test_menuchecks.xul]

Просмотреть файл

@ -9,22 +9,14 @@
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<xbl:bindings xmlns:xbl="http://www.mozilla.org/xbl">
<xbl:binding id="menu" extends="chrome://global/content/bindings/button.xml#button-base">
<xbl:content>
<xbl:children includes="menupopup"/>
<xul:stack>
<xul:button width="100" left="0" top="0" height="30" allowevents="true"
onclick="eventReceived('clickbutton1'); return false;"/>
<xul:button width="100" left="70" top="0" height="30"
onclick="eventReceived('clickbutton2'); return false;"/>
</xul:stack>
</xbl:content>
</xbl:binding>
</xbl:bindings>
<toolbarbutton type="menu" id="toolbarmenu" height="200" style="-moz-binding: url(#menu);">
<toolbarbutton type="menu" id="toolbarmenu" height="200">
<menupopup id="menupopup" onpopupshowing="eventReceived('popupshowing'); return false;"/>
<stack>
<button width="100" left="0" top="0" height="30" allowevents="true"
onclick="eventReceived('clickbutton1'); return false;"/>
<button width="100" left="70" top="0" height="30"
onclick="eventReceived('clickbutton2'); return false;"/>
</stack>
</toolbarbutton>
<!-- test results are displayed in the html:body -->

Просмотреть файл

@ -1,77 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<!--
Test for menus with the anchor attribute set
-->
<window title="Anchored Menus Test"
align="start"
onload="setTimeout(runTest, 0, 'tb1');"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="xul_selectcontrol.js"/>
<hbox>
<toolbarbutton id="tb1" type="menu" label="Open" anchor="dropmarker">
<menupopup id="popup1"
onpopupshown="checkPopup(this, document.getAnonymousElementByAttribute(this.parentNode, 'anonid', 'dropmarker'))"
onpopuphidden="runTest('tb2')">
<menuitem label="Item"/>
</menupopup>
</toolbarbutton>
<toolbarbutton id="tb2" type="menu" label="Open" anchor="someanchor">
<menupopup id="popup2" onpopupshown="checkPopup(this, $('someanchor'))" onpopuphidden="runTest('tb3')">
<menuitem label="Item"/>
</menupopup>
</toolbarbutton>
<toolbarbutton id="tb3" type="menu" label="Open" anchor="noexist">
<menupopup id="popup3" onpopupshown="checkPopup(this, this.parentNode)" onpopuphidden="SimpleTest.finish()">
<menuitem label="Item"/>
</menupopup>
</toolbarbutton>
</hbox>
<hbox pack="end" width="180">
<button id="someanchor" label="Anchor"/>
</hbox>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
<script type="application/javascript"><![CDATA[
function runTest(menuid)
{
let menu = $(menuid);
let dropmarker = document.getAnonymousElementByAttribute(menu, "anonid", "dropmarker");
synthesizeMouseAtCenter(dropmarker, { });
}
function isWithinHalfPixel(a, b)
{
return Math.abs(a - b) <= 0.5;
}
function checkPopup(popup, anchor)
{
let popupRect = popup.getBoundingClientRect();
let anchorRect = anchor.getBoundingClientRect();
ok(isWithinHalfPixel(popupRect.left, anchorRect.left), popup.id + " left");
ok(isWithinHalfPixel(popupRect.top, anchorRect.bottom), popup.id + " top");
popup.hidePopup();
}
SimpleTest.waitForExplicitFinish();
]]>
</script>
</window>

Просмотреть файл

@ -214,6 +214,8 @@
MozXULElement.implementCustomInterface(MozButtonBase, [Ci.nsIDOMXULButtonElement]);
MozElements.ButtonBase = MozButtonBase;
class MozButton extends MozButtonBase {
static get inheritedAttributes() {
return {

Просмотреть файл

@ -1,192 +0,0 @@
<?xml version="1.0"?>
<!-- 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/. -->
<bindings id="buttonBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="button-base" extends="chrome://global/content/bindings/general.xml#basetext">
<implementation implements="nsIDOMXULButtonElement">
<property name="type"
onget="return this.getAttribute('type');"
onset="this.setAttribute('type', val); return val;"/>
<property name="dlgType"
onget="return this.getAttribute('dlgtype');"
onset="this.setAttribute('dlgtype', val); return val;"/>
<property name="group"
onget="return this.getAttribute('group');"
onset="this.setAttribute('group', val); return val;"/>
<property name="open" onget="return this.hasAttribute('open');">
<setter><![CDATA[
if (this.hasMenu()) {
this.openMenu(val);
} else if (val) {
// Fall back to just setting the attribute
this.setAttribute("open", "true");
} else {
this.removeAttribute("open");
}
return val;
]]></setter>
</property>
<property name="checked" onget="return this.hasAttribute('checked');">
<setter><![CDATA[
if (this.type == "radio" && val) {
var sibs = this.parentNode.getElementsByAttribute("group", this.group);
for (var i = 0; i < sibs.length; ++i)
sibs[i].removeAttribute("checked");
}
if (val)
this.setAttribute("checked", "true");
else
this.removeAttribute("checked");
return val;
]]></setter>
</property>
<method name ="filterButtons">
<parameter name="node"/>
<body>
<![CDATA[
// if the node isn't visible, don't descend into it.
var cs = node.ownerGlobal.getComputedStyle(node);
if (cs.visibility != "visible" || cs.display == "none") {
return NodeFilter.FILTER_REJECT;
}
// but it may be a popup element, in which case we look at "state"...
if (cs.display == "-moz-popup" && node.state != "open") {
return NodeFilter.FILTER_REJECT;
}
// OK - the node seems visible, so it is a candidate.
if (node.localName == "button" && node.accessKey && !node.disabled)
return NodeFilter.FILTER_ACCEPT;
return NodeFilter.FILTER_SKIP;
]]>
</body>
</method>
<method name="fireAccessKeyButton">
<parameter name="aSubtree"/>
<parameter name="aAccessKeyLower"/>
<body>
<![CDATA[
var iterator = aSubtree.ownerDocument.createTreeWalker(aSubtree,
NodeFilter.SHOW_ELEMENT,
this.filterButtons);
while (iterator.nextNode()) {
var test = iterator.currentNode;
if (test.accessKey.toLowerCase() == aAccessKeyLower &&
!test.disabled && !test.collapsed && !test.hidden) {
test.focus();
test.click();
return true;
}
}
return false;
]]>
</body>
</method>
<method name="_handleClick">
<body>
<![CDATA[
if (!this.disabled) {
if (this.type == "checkbox") {
this.checked = !this.checked;
} else if (this.type == "radio") {
this.checked = true;
}
}
]]>
</body>
</method>
</implementation>
<handlers>
<!-- While it would seem we could do this by handling oncommand, we can't
because any external oncommand handlers might get called before ours,
and then they would see the incorrect value of checked. Additionally
a command attribute would redirect the command events anyway.-->
<handler event="click" button="0" action="this._handleClick();"/>
<handler event="keypress" key=" ">
<![CDATA[
this._handleClick();
// Prevent page from scrolling on the space key.
event.preventDefault();
]]>
</handler>
<handler event="keypress">
<![CDATA[
if (this.hasMenu()) {
if (this.open)
return;
} else {
if (event.keyCode == KeyEvent.DOM_VK_UP ||
(event.keyCode == KeyEvent.DOM_VK_LEFT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "ltr") ||
(event.keyCode == KeyEvent.DOM_VK_RIGHT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "rtl")) {
event.preventDefault();
window.document.commandDispatcher.rewindFocus();
return;
}
if (event.keyCode == KeyEvent.DOM_VK_DOWN ||
(event.keyCode == KeyEvent.DOM_VK_RIGHT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "ltr") ||
(event.keyCode == KeyEvent.DOM_VK_LEFT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "rtl")) {
event.preventDefault();
window.document.commandDispatcher.advanceFocus();
return;
}
}
if (event.keyCode || event.charCode <= 32 || event.altKey ||
event.ctrlKey || event.metaKey)
return; // No printable char pressed, not a potential accesskey
// Possible accesskey pressed
var charPressedLower = String.fromCharCode(event.charCode).toLowerCase();
// If the accesskey of the current button is pressed, just activate it
if (this.accessKey.toLowerCase() == charPressedLower) {
this.click();
return;
}
// Search for accesskey in the list of buttons for this doc and each subdoc
// Get the buttons for the main document and all sub-frames
for (var frameCount = -1; frameCount < window.top.frames.length; frameCount++) {
var doc = (frameCount == -1) ? window.top.document :
window.top.frames[frameCount].document;
if (this.fireAccessKeyButton(doc.documentElement, charPressedLower))
return;
}
// Test anonymous buttons
var dlg = window.top.document;
var buttonBox = dlg.getAnonymousElementByAttribute(dlg.documentElement,
"anonid", "buttons");
if (buttonBox)
this.fireAccessKeyButton(buttonBox, charPressedLower);
]]>
</handler>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -0,0 +1,153 @@
/* 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 is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
const KEEP_CHILDREN = new Set(["observes", "template", "menupopup", "panel", "tooltip"]);
window.addEventListener("popupshowing", (e) => {
if (e.originalTarget.ownerDocument != document) {
return;
}
e.originalTarget.setAttribute("hasbeenopened", "true");
for (let el of e.originalTarget.querySelectorAll("toolbarbutton")) {
el.render();
}
}, {capture: true});
class MozToolbarbutton extends MozElements.ButtonBase {
static get inheritedAttributes() {
return {
".toolbarbutton-icon": "validate,src=image,label,type,consumeanchor,triggeringprincipal=iconloadingprincipal",
".toolbarbutton-text": "value=label,accesskey,crop,dragover-top,wrap",
".toolbarbutton-multiline-text": "text=label,accesskey,wrap",
".toolbarbutton-menu-dropmarker": "disabled,label",
".toolbarbutton-badge": "value=badge,style=badgeStyle",
};
}
static get fragment() {
let frag = document.importNode(MozXULElement.parseXULToFragment(`
<image class="toolbarbutton-icon"></image>
<label class="toolbarbutton-text" crop="right" flex="1"></label>
<label class="toolbarbutton-multiline-text" flex="1"></label>
<dropmarker type="menu" class="toolbarbutton-menu-dropmarker"></dropmarker>`), true);
Object.defineProperty(this, "fragment", {value: frag});
return frag;
}
static get badgedFragment() {
let frag = document.importNode(MozXULElement.parseXULToFragment(`
<stack class="toolbarbutton-badge-stack">
<image class="toolbarbutton-icon"/>
<label class="toolbarbutton-badge" top="0" end="0" crop="none"/>
</stack>
<label class="toolbarbutton-text" crop="right" flex="1"/>
<label class="toolbarbutton-multiline-text" flex="1"/>
<dropmarker anonid="dropmarker" type="menu"
class="toolbarbutton-menu-dropmarker"/>`), true);
Object.defineProperty(this, "badgedFragment", {value: frag});
return frag;
}
get _hasRendered() {
return (this.querySelector(":scope > .toolbarbutton-text") != null);
}
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
// Defer creating DOM elements for content inside popups.
// These will be added in the popupshown handler above.
let panel = this.closest("panel");
if (panel && !panel.hasAttribute("hasbeenopened")) {
return;
}
this.render();
}
render() {
if (this._hasRendered) {
return;
}
let badged = (this.getAttribute("badged") == "true");
if (badged) {
let moveChildren = [];
for (let child of this.children) {
if (!KEEP_CHILDREN.has(child.tagName)) {
moveChildren.push(child);
}
}
this.appendChild(this.constructor.badgedFragment.cloneNode(true));
if (moveChildren.length > 0) {
let {badgeStack, icon} = this;
for (let child of moveChildren) {
badgeStack.insertBefore(child, icon);
}
}
} else {
let moveChildren = [];
for (let child of this.children) {
if (!KEEP_CHILDREN.has(child.tagName) && child.tagName != "box") {
// XBL toolbarbutton doesn't insert any anonymous content
// if it has a child of any other type
return;
}
if (child.tagName == "box") {
moveChildren.push(child);
}
}
this.appendChild(this.constructor.fragment.cloneNode(true));
// XBL toolbarbutton explicitly places any <box> children
// right before the menu marker.
for (let child of moveChildren) {
this.insertBefore(child, this.lastChild);
}
}
this.initializeAttributeInheritance();
}
get icon() {
return this.querySelector(".toolbarbutton-icon");
}
get badgeLabel() {
return this.querySelector(".toolbarbutton-badge");
}
get badgeStack() {
return this.querySelector(".toolbarbutton-badge-stack");
}
get multilineLabel() {
return this.querySelector(".toolbarbutton-multiline-text");
}
get dropmarker() {
return this.querySelector(".toolbarbutton-menu-dropmarker");
}
get menupopup() {
return this.querySelector("menupopup");
}
}
customElements.define("toolbarbutton", MozToolbarbutton);
}

Просмотреть файл

@ -1,48 +0,0 @@
<?xml version="1.0"?>
<!-- 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/. -->
<bindings id="toolbarbuttonBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="toolbarbutton"
extends="chrome://global/content/bindings/button.xml#button-base">
<implementation>
<property name="multilineLabel"
onget="return document.getAnonymousElementByAttribute(this, 'class', 'toolbarbutton-multiline-text');" />
</implementation>
<content>
<children includes="observes|template|menupopup|panel|tooltip"/>
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label,type,consumeanchor,triggeringprincipal=iconloadingprincipal"/>
<xul:label class="toolbarbutton-text" crop="right" flex="1"
xbl:inherits="value=label,accesskey,crop,dragover-top,wrap"/>
<xul:label class="toolbarbutton-multiline-text" flex="1"
xbl:inherits="xbl:text=label,accesskey,wrap"/>
<children includes="box"/>
<xul:dropmarker anonid="dropmarker" type="menu"
class="toolbarbutton-menu-dropmarker" xbl:inherits="disabled,label"/>
</content>
</binding>
<binding id="toolbarbutton-badged"
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
<content>
<children includes="observes|template|menupopup|panel|tooltip"/>
<xul:stack class="toolbarbutton-badge-stack">
<children/>
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label,consumeanchor"/>
<xul:label class="toolbarbutton-badge" xbl:inherits="value=badge,style=badgeStyle" top="0" end="0" crop="none"/>
</xul:stack>
<xul:label class="toolbarbutton-text" crop="right" flex="1"
xbl:inherits="value=label,accesskey,crop,wrap"/>
<xul:label class="toolbarbutton-multiline-text" flex="1"
xbl:inherits="xbl:text=label,accesskey,wrap"/>
<xul:dropmarker anonid="dropmarker" type="menu"
class="toolbarbutton-menu-dropmarker" xbl:inherits="disabled,label"/>
</content>
</binding>
</bindings>

Просмотреть файл

@ -107,15 +107,6 @@ label html|span.accesskey {
/********** toolbarbutton **********/
toolbarbutton {
-moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton");
}
toolbarbutton.badged-button > toolbarbutton,
toolbarbutton.badged-button {
-moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-badged");
}
.toolbarbutton-badge:not([value]),
.toolbarbutton-badge[value=""] {
display: none;

Просмотреть файл

@ -566,9 +566,8 @@ nsresult nsBaseDragService::DrawDrag(nsINode* aDOMNode,
if (flo) {
RefPtr<nsFrameLoader> fl = flo->GetFrameLoader();
if (fl) {
auto* tp =
static_cast<mozilla::dom::BrowserParent*>(fl->GetRemoteBrowser());
if (tp && tp->TakeDragVisualization(*aSurface, aScreenDragRect)) {
auto* bp = fl->GetBrowserParent();
if (bp && bp->TakeDragVisualization(*aSurface, aScreenDragRect)) {
if (mImage) {
// Just clear the surface if chrome has overridden it with an image.
*aSurface = nullptr;

Просмотреть файл

@ -59,6 +59,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/BrowserHost.h"
#include "mozilla/dom/BrowserParent.h"
#ifdef MOZ_NEW_XULSTORE
@ -352,9 +353,8 @@ nsTArray<RefPtr<mozilla::LiveResizeListener>>
nsXULWindow::GetLiveResizeListeners() {
nsTArray<RefPtr<mozilla::LiveResizeListener>> listeners;
if (mPrimaryBrowserParent) {
BrowserParent* parent =
static_cast<BrowserParent*>(mPrimaryBrowserParent.get());
listeners.AppendElement(parent);
BrowserHost* host = BrowserHost::GetFrom(mPrimaryBrowserParent.get());
listeners.AppendElement(host->GetActor());
}
return listeners;
}
@ -1864,9 +1864,9 @@ nsXULWindow::GetPrimaryContentSize(int32_t* aWidth, int32_t* aHeight) {
nsresult nsXULWindow::GetPrimaryRemoteTabSize(int32_t* aWidth,
int32_t* aHeight) {
BrowserParent* browserParent = BrowserParent::GetFrom(mPrimaryBrowserParent);
BrowserHost* host = BrowserHost::GetFrom(mPrimaryBrowserParent.get());
// Need strong ref, since Client* can run script.
nsCOMPtr<Element> element = browserParent->GetOwnerElement();
nsCOMPtr<Element> element = host->GetOwnerElement();
NS_ENSURE_STATE(element);
*aWidth = element->ClientWidth();