зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
4cbc287f63
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче