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

This commit is contained in:
Cosmin Sabou
2018-08-15 03:51:45 +03:00
376 changed files with 10286 additions and 6195 deletions

1
Cargo.lock generated
View File

@@ -2021,7 +2021,6 @@ dependencies = [
"hashglobe 0.1.0",
"itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1",

View File

@@ -0,0 +1,150 @@
/* vim: set ts=2 sw=2 sts=2 et 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["AboutReaderChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.defineModuleGetter(this, "AboutReader",
"resource://gre/modules/AboutReader.jsm");
ChromeUtils.defineModuleGetter(this, "ReaderMode",
"resource://gre/modules/ReaderMode.jsm");
class AboutReaderChild extends ActorChild {
constructor(mm) {
super(mm);
this._articlePromise = null;
this._isLeavingReaderableReaderMode = false;
}
receiveMessage(message) {
switch (message.name) {
case "Reader:ToggleReaderMode":
if (!this.isAboutReader) {
this._articlePromise = ReaderMode.parseDocument(this.content.document).catch(Cu.reportError);
ReaderMode.enterReaderMode(this.mm.docShell, this.content);
} else {
this._isLeavingReaderableReaderMode = this.isReaderableAboutReader;
ReaderMode.leaveReaderMode(this.mm.docShell, this.content);
}
break;
case "Reader:PushState":
this.updateReaderButton(!!(message.data && message.data.isArticle));
break;
}
}
get isAboutReader() {
if (!this.content) {
return false;
}
return this.content.document.documentURI.startsWith("about:reader");
}
get isReaderableAboutReader() {
return this.isAboutReader &&
!this.content.document.documentElement.dataset.isError;
}
handleEvent(aEvent) {
if (aEvent.originalTarget.defaultView != this.content) {
return;
}
switch (aEvent.type) {
case "AboutReaderContentLoaded":
if (!this.isAboutReader) {
return;
}
if (this.content.document.body) {
// Update the toolbar icon to show the "reader active" icon.
this.mm.sendAsyncMessage("Reader:UpdateReaderButton");
new AboutReader(this.mm, this.content, this._articlePromise);
this._articlePromise = null;
}
break;
case "pagehide":
this.cancelPotentialPendingReadabilityCheck();
// this._isLeavingReaderableReaderMode is used here to keep the Reader Mode icon
// visible in the location bar when transitioning from reader-mode page
// back to the readable source page.
this.mm.sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: this._isLeavingReaderableReaderMode });
if (this._isLeavingReaderableReaderMode) {
this._isLeavingReaderableReaderMode = false;
}
break;
case "pageshow":
// If a page is loaded from the bfcache, we won't get a "DOMContentLoaded"
// event, so we need to rely on "pageshow" in this case.
if (aEvent.persisted) {
this.updateReaderButton();
}
break;
case "DOMContentLoaded":
this.updateReaderButton();
break;
}
}
/**
* NB: this function will update the state of the reader button asynchronously
* after the next mozAfterPaint call (assuming reader mode is enabled and
* this is a suitable document). Calling it on things which won't be
* painted is not going to work.
*/
updateReaderButton(forceNonArticle) {
if (!ReaderMode.isEnabledForParseOnLoad || this.isAboutReader ||
!this.content || !(this.content.document instanceof this.content.HTMLDocument) ||
this.content.document.mozSyntheticDocument) {
return;
}
this.scheduleReadabilityCheckPostPaint(forceNonArticle);
}
cancelPotentialPendingReadabilityCheck() {
if (this._pendingReadabilityCheck) {
this.mm.removeEventListener("MozAfterPaint", this._pendingReadabilityCheck);
delete this._pendingReadabilityCheck;
}
}
scheduleReadabilityCheckPostPaint(forceNonArticle) {
if (this._pendingReadabilityCheck) {
// We need to stop this check before we re-add one because we don't know
// if forceNonArticle was true or false last time.
this.cancelPotentialPendingReadabilityCheck();
}
this._pendingReadabilityCheck = this.onPaintWhenWaitedFor.bind(this, forceNonArticle);
this.mm.addEventListener("MozAfterPaint", this._pendingReadabilityCheck);
}
onPaintWhenWaitedFor(forceNonArticle, event) {
// In non-e10s, we'll get called for paints other than ours, and so it's
// possible that this page hasn't been laid out yet, in which case we
// should wait until we get an event that does relate to our layout. We
// determine whether any of our this.content got painted by checking if there
// are any painted rects.
if (!event.clientRects.length) {
return;
}
this.cancelPotentialPendingReadabilityCheck();
// Only send updates when there are articles; there's no point updating with
// |false| all the time.
if (ReaderMode.isProbablyReaderable(this.content.document)) {
this.mm.sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: true });
} else if (forceNonArticle) {
this.mm.sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: false });
}
}
}

View File

@@ -5,7 +5,9 @@
ChromeUtils.import("resource://gre/modules/Services.jsm");
var EXPORTED_SYMBOLS = ["BlockedSiteContent"];
var EXPORTED_SYMBOLS = ["BlockedSiteChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.defineModuleGetter(this, "SafeBrowsing",
"resource://gre/modules/SafeBrowsing.jsm");
@@ -35,21 +37,26 @@ function getSiteBlockedErrorDetails(docShell) {
return blockedInfo;
}
var BlockedSiteContent = {
receiveMessage(global, msg) {
class BlockedSiteChild extends ActorChild {
receiveMessage(msg) {
if (msg.name == "DeceptiveBlockedDetails") {
global.sendAsyncMessage("DeceptiveBlockedDetails:Result", {
blockedInfo: getSiteBlockedErrorDetails(global.docShell),
this.mm.sendAsyncMessage("DeceptiveBlockedDetails:Result", {
blockedInfo: getSiteBlockedErrorDetails(this.mm.docShell),
});
}
},
}
handleEvent(global, aEvent) {
if (aEvent.type != "AboutBlockedLoaded") {
return;
handleEvent(event) {
if (event.type == "AboutBlockedLoaded") {
this.onAboutBlockedLoaded(event);
} else if (event.type == "click" && event.button == 0) {
this.onClick(event);
}
}
let {content} = global;
onAboutBlockedLoaded(aEvent) {
let global = this.mm;
let content = aEvent.target.ownerGlobal;
let blockedInfo = getSiteBlockedErrorDetails(global.docShell);
let provider = blockedInfo.provider || "";
@@ -120,9 +127,14 @@ var BlockedSiteContent = {
let anchorEl = content.document.getElementById("advisory_provider");
anchorEl.setAttribute("href", advisoryUrl);
anchorEl.textContent = advisoryLinkText;
},
}
onClick(event) {
let ownerDoc = event.target.ownerDocument;
if (!ownerDoc) {
return;
}
onAboutBlocked(global, targetElement, ownerDoc) {
var reason = "phishing";
if (/e=malwareBlocked/.test(ownerDoc.documentURI)) {
reason = "malware";
@@ -132,14 +144,12 @@ var BlockedSiteContent = {
reason = "harmful";
}
let docShell = ownerDoc.defaultView.docShell;
global.sendAsyncMessage("Browser:SiteBlockedError", {
this.mm.sendAsyncMessage("Browser:SiteBlockedError", {
location: ownerDoc.location.href,
reason,
elementId: targetElement.getAttribute("id"),
elementId: event.target.getAttribute("id"),
isTopFrame: (ownerDoc.defaultView.parent === ownerDoc.defaultView),
blockedInfo: getSiteBlockedErrorDetails(docShell),
blockedInfo: getSiteBlockedErrorDetails(ownerDoc.defaultView.docShell),
});
},
};
}
}

View File

@@ -0,0 +1,112 @@
/* vim: set ts=2 sw=2 sts=2 et 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["BrowserTabChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.defineModuleGetter(this, "E10SUtils",
"resource://gre/modules/E10SUtils.jsm");
class BrowserTabChild extends ActorChild {
handleEvent(event) {
switch (event.type) {
case "DOMWindowCreated":
let loadContext = this.mm.docShell.QueryInterface(Ci.nsILoadContext);
let userContextId = loadContext.originAttributes.userContextId;
this.mm.sendAsyncMessage("Browser:WindowCreated", { userContextId });
break;
case "MozAfterPaint":
this.mm.sendAsyncMessage("Browser:FirstPaint");
break;
case "MozDOMPointerLock:Entered":
this.mm.sendAsyncMessage("PointerLock:Entered", {
originNoSuffix: event.target.nodePrincipal.originNoSuffix
});
break;
case "MozDOMPointerLock:Exited":
this.mm.sendAsyncMessage("PointerLock:Exited");
break;
}
}
switchDocumentDirection(window = this.content) {
// document.dir can also be "auto", in which case it won't change
if (window.document.dir == "ltr" || window.document.dir == "") {
window.document.dir = "rtl";
} else if (window.document.dir == "rtl") {
window.document.dir = "ltr";
}
for (let i = 0; i < window.frames.length; i++) {
this.switchDocumentDirection(window.frames[i]);
}
}
receiveMessage(message) {
switch (message.name) {
case "AllowScriptsToClose":
this.content.windowUtils.allowScriptsToClose();
break;
case "Browser:AppTab":
if (this.docShell) {
this.docShell.isAppTab = message.data.isAppTab;
}
break;
case "Browser:HasSiblings":
try {
let tabChild = this.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsITabChild);
let hasSiblings = message.data;
tabChild.hasSiblings = hasSiblings;
} catch (e) {
}
break;
// XXX(nika): Should we try to call this in the parent process instead?
case "Browser:Reload":
/* First, we'll try to use the session history object to reload so
* that framesets are handled properly. If we're in a special
* window (such as view-source) that has no session history, fall
* back on using the web navigation's reload method.
*/
let webNav = this.docShell.QueryInterface(Ci.nsIWebNavigation);
try {
if (webNav.sessionHistory) {
webNav = webNav.sessionHistory;
}
} catch (e) {
}
let reloadFlags = message.data.flags;
try {
E10SUtils.wrapHandlingUserInput(this.content, message.data.handlingUserInput,
() => webNav.reload(reloadFlags));
} catch (e) {
}
break;
case "MixedContent:ReenableProtection":
this.docShell.mixedContentChannel = null;
break;
case "SwitchDocumentDirection":
this.switchDocumentDirection();
break;
case "UpdateCharacterSet":
this.docShell.charset = message.data.value;
this.docShell.gatherCharsetMenuTelemetry();
break;
}
}
}

View File

@@ -3,26 +3,19 @@
* 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/. */
var EXPORTED_SYMBOLS = ["ClickEventHandler"];
var EXPORTED_SYMBOLS = ["ClickHandlerChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "BlockedSiteContent",
"resource:///modules/BlockedSiteContent.jsm");
ChromeUtils.defineModuleGetter(this, "BrowserUtils",
"resource://gre/modules/BrowserUtils.jsm");
ChromeUtils.defineModuleGetter(this, "NetErrorContent",
"resource:///modules/NetErrorContent.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
ChromeUtils.defineModuleGetter(this, "WebNavigationFrames",
"resource://gre/modules/WebNavigationFrames.jsm");
class ClickEventHandler {
constructor(mm) {
this.mm = mm;
}
class ClickHandlerChild extends ActorChild {
handleEvent(event) {
if (!event.isTrusted || event.defaultPrevented || event.button == 2) {
return;
@@ -36,14 +29,7 @@ class ClickEventHandler {
// Handle click events from about pages
if (event.button == 0) {
if (this.mm.AboutNetAndCertErrorListener.isAboutCertError(ownerDoc)) {
NetErrorContent.onCertError(this.mm, originalTarget, ownerDoc.defaultView);
return;
} else if (ownerDoc.documentURI.startsWith("about:blocked")) {
BlockedSiteContent.onAboutBlocked(this.mm, originalTarget, ownerDoc);
return;
} else if (this.mm.AboutNetAndCertErrorListener.isAboutNetError(ownerDoc)) {
NetErrorContent.onAboutNetError(this.mm, event, ownerDoc.documentURI);
if (ownerDoc.documentURI.startsWith("about:blocked")) {
return;
}
}

View File

@@ -0,0 +1,37 @@
/* vim: set ts=2 sw=2 sts=2 et 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["ContentSearchChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
class ContentSearchChild extends ActorChild {
handleEvent(event) {
this._sendMsg(event.detail.type, event.detail.data);
}
receiveMessage(msg) {
this._fireEvent(msg.data.type, msg.data.data);
}
_sendMsg(type, data = null) {
this.mm.sendAsyncMessage("ContentSearch", {
type,
data,
});
}
_fireEvent(type, data = null) {
let event = Cu.cloneInto({
detail: {
type,
data,
},
}, this.content);
this.content.dispatchEvent(new this.content.CustomEvent("ContentSearchService",
event));
}
}

View File

@@ -6,11 +6,13 @@
"use strict";
var EXPORTED_SYMBOLS = ["ContextMenu"];
var EXPORTED_SYMBOLS = ["ContextMenuChild"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
XPCOMUtils.defineLazyModuleGetters(this, {
@@ -34,14 +36,14 @@ const messageListeners = {
"ContextMenu:BookmarkFrame": function(aMessage) {
let frame = this.getTarget(aMessage).ownerDocument;
this.global.sendAsyncMessage("ContextMenu:BookmarkFrame:Result",
{ title: frame.title });
this.mm.sendAsyncMessage("ContextMenu:BookmarkFrame:Result",
{ title: frame.title });
},
"ContextMenu:Canvas:ToBlobURL": function(aMessage) {
this.getTarget(aMessage).toBlob((blob) => {
let blobURL = URL.createObjectURL(blob);
this.global.sendAsyncMessage("ContextMenu:Canvas:ToBlobURL:Result", { blobURL });
this.mm.sendAsyncMessage("ContextMenu:Canvas:ToBlobURL:Result", { blobURL });
});
},
@@ -168,8 +170,8 @@ const messageListeners = {
spec += separator + formData.join("&");
}
this.global.sendAsyncMessage("ContextMenu:SearchFieldBookmarkData:Result",
{ spec, title, postData, charset });
this.mm.sendAsyncMessage("ContextMenu:SearchFieldBookmarkData:Result",
{ spec, title, postData, charset });
},
"ContextMenu:SaveVideoFrameAsImage": function(aMessage) {
@@ -182,7 +184,7 @@ const messageListeners = {
let ctxDraw = canvas.getContext("2d");
ctxDraw.drawImage(video, 0, 0);
this.global.sendAsyncMessage("ContextMenu:SaveVideoFrameAsImage:Result", {
this.mm.sendAsyncMessage("ContextMenu:SaveVideoFrameAsImage:Result", {
dataURL: canvas.toDataURL("image/jpeg", ""),
});
},
@@ -206,8 +208,8 @@ const messageListeners = {
let dataUrl = canvas.toDataURL();
let url = (new URL(target.ownerDocument.location.href)).pathname;
let imageName = url.substr(url.lastIndexOf("/") + 1);
this.global.sendAsyncMessage("ContextMenu:SetAsDesktopBackground:Result",
{ dataUrl, imageName });
this.mm.sendAsyncMessage("ContextMenu:SetAsDesktopBackground:Result",
{ dataUrl, imageName });
} catch (e) {
Cu.reportError(e);
disable = true;
@@ -215,19 +217,23 @@ const messageListeners = {
}
if (disable) {
this.global.sendAsyncMessage("ContextMenu:SetAsDesktopBackground:Result",
{ disable });
this.mm.sendAsyncMessage("ContextMenu:SetAsDesktopBackground:Result",
{ disable });
}
},
};
class ContextMenu {
let contextMenus = new WeakMap();
class ContextMenuChild extends ActorChild {
// PUBLIC
constructor(global) {
super(global);
contextMenus.set(global, this);
this.target = null;
this.context = null;
this.global = global;
this.content = global.content;
this.lastMenuTarget = null;
Object.keys(messageListeners).forEach(key =>
@@ -235,6 +241,15 @@ class ContextMenu {
);
}
static getTarget(global, message, key) {
return contextMenus.get(global).getTarget(message, key);
}
static getLastTarget(global) {
let contextMenu = contextMenus.get(global);
return contextMenu && contextMenu.lastMenuTarget;
}
/**
* Returns the event target of the context menu, using a locally stored
* reference if possible. If not, and aMessage.objects is defined,
@@ -489,7 +504,7 @@ class ContextMenu {
let loginFillInfo = LoginManagerContent.getFieldContext(aEvent.composedTarget);
// The same-origin check will be done in nsContextMenu.openLinkInTab.
let parentAllowsMixedContent = !!this.global.docShell.mixedContentChannel;
let parentAllowsMixedContent = !!this.docShell.mixedContentChannel;
// Get referrer attribute from clicked link and parse it
let referrerAttrValue =
@@ -528,7 +543,7 @@ class ContextMenu {
}
let selectionInfo = BrowserUtils.getSelectionDetails(this.content);
let loadContext = this.global.docShell.QueryInterface(Ci.nsILoadContext);
let loadContext = this.docShell.QueryInterface(Ci.nsILoadContext);
let userContextId = loadContext.originAttributes.userContextId;
let popupNodeSelectors = findAllCssSelectors(aEvent.composedTarget);
@@ -552,14 +567,14 @@ class ContextMenu {
editFlags = SpellCheckHelper.isEditable(aEvent.composedTarget, this.content);
if (editFlags & SpellCheckHelper.SPELLCHECKABLE) {
spellInfo = InlineSpellCheckerContent.initContextMenu(aEvent, editFlags, this.global);
spellInfo = InlineSpellCheckerContent.initContextMenu(aEvent, editFlags, this.mm);
}
// Set the event target first as the copy image command needs it to
// determine what was context-clicked on. Then, update the state of the
// commands on the context menu.
this.global.docShell.contentViewer.QueryInterface(Ci.nsIContentViewerEdit)
.setCommandNode(aEvent.composedTarget);
this.docShell.contentViewer.QueryInterface(Ci.nsIContentViewerEdit)
.setCommandNode(aEvent.composedTarget);
aEvent.composedTarget.ownerGlobal.updateCommands("contentcontextmenu");
customMenuItems = PageMenuChild.build(aEvent.composedTarget);
@@ -590,11 +605,11 @@ class ContextMenu {
};
if (isRemote) {
this.global.sendAsyncMessage("contextmenu", data, {
this.mm.sendAsyncMessage("contextmenu", data, {
targetAsCPOW,
});
} else {
let browser = this.global.docShell.chromeEventHandler;
let browser = this.docShell.chromeEventHandler;
let mainWin = browser.ownerGlobal;
data.documentURIObject = doc.documentURIObject;

View File

@@ -0,0 +1,81 @@
/* vim: set ts=2 sw=2 sts=2 et 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["DOMFullscreenChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
class DOMFullscreenChild extends ActorChild {
receiveMessage(aMessage) {
let windowUtils = this.content && this.content.windowUtils;
switch (aMessage.name) {
case "DOMFullscreen:Entered": {
this._lastTransactionId = windowUtils.lastTransactionId;
if (!windowUtils.handleFullscreenRequests() &&
!this.content.document.fullscreenElement) {
// If we don't actually have any pending fullscreen request
// to handle, neither we have been in fullscreen, tell the
// parent to just exit.
this.mm.sendAsyncMessage("DOMFullscreen:Exit");
}
break;
}
case "DOMFullscreen:CleanUp": {
// If we've exited fullscreen at this point, no need to record
// transaction id or call exit fullscreen. This is especially
// important for non-e10s, since in that case, it is possible
// that no more paint would be triggered after this point.
if (this.content.document.fullscreenElement && windowUtils) {
this._lastTransactionId = windowUtils.lastTransactionId;
windowUtils.exitFullscreen();
}
break;
}
}
}
handleEvent(aEvent) {
switch (aEvent.type) {
case "MozDOMFullscreen:Request": {
this.mm.sendAsyncMessage("DOMFullscreen:Request");
break;
}
case "MozDOMFullscreen:NewOrigin": {
this.mm.sendAsyncMessage("DOMFullscreen:NewOrigin", {
originNoSuffix: aEvent.target.nodePrincipal.originNoSuffix,
});
break;
}
case "MozDOMFullscreen:Exit": {
this.mm.sendAsyncMessage("DOMFullscreen:Exit");
break;
}
case "MozDOMFullscreen:Entered":
case "MozDOMFullscreen:Exited": {
this.mm.addEventListener("MozAfterPaint", this);
if (!this.content || !this.content.document.fullscreenElement) {
// If we receive any fullscreen change event, and find we are
// actually not in fullscreen, also ask the parent to exit to
// ensure that the parent always exits fullscreen when we do.
this.mm.sendAsyncMessage("DOMFullscreen:Exit");
}
break;
}
case "MozAfterPaint": {
// Only send Painted signal after we actually finish painting
// the transition for the fullscreen change.
// Note that this._lastTransactionId is not set when in non-e10s
// mode, so we need to check that explicitly.
if (!this._lastTransactionId ||
aEvent.transactionId > this._lastTransactionId) {
this.mm.removeEventListener("MozAfterPaint", this);
this.mm.sendAsyncMessage("DOMFullscreen:Painted");
}
break;
}
}
}
}

View File

@@ -2,13 +2,13 @@
* 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/. */
var EXPORTED_SYMBOLS = ["LightWeightThemeWebInstallListener"];
var EXPORTED_SYMBOLS = ["LightWeightThemeInstallChild"];
var LightWeightThemeWebInstallListener = {
_previewWindow: null,
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
class LightWeightThemeInstallChild extends ActorChild {
handleEvent(event) {
let mm = getMessageManagerForContent(event.target.ownerGlobal);
let {mm} = this;
switch (event.type) {
case "InstallBrowserTheme": {
mm.sendAsyncMessage("LightWeightThemeWebInstaller:Install", {
@@ -42,14 +42,10 @@ var LightWeightThemeWebInstallListener = {
break;
}
}
},
}
_resetPreviewWindow() {
this._previewWindow.removeEventListener("pagehide", this, true);
this._previewWindow = null;
}
};
function getMessageManagerForContent(content) {
return content.docShell.messageManager;
}

View File

@@ -3,10 +3,11 @@
* 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/. */
var EXPORTED_SYMBOLS = ["NetErrorContent"];
var EXPORTED_SYMBOLS = ["NetErrorChild"];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.defineModuleGetter(this, "BrowserUtils",
"resource://gre/modules/BrowserUtils.jsm");
@@ -70,14 +71,14 @@ function getSerializedSecurityInfo(docShell) {
return serhelper.serializeToString(securityInfo);
}
var NetErrorContent = {
class NetErrorChild extends ActorChild {
isAboutNetError(doc) {
return doc.documentURI.startsWith("about:neterror");
},
}
isAboutCertError(doc) {
return doc.documentURI.startsWith("about:certerror");
},
}
_getCertValidityRange(docShell) {
let {securityInfo} = docShell.failedChannel;
@@ -95,7 +96,7 @@ var NetErrorContent = {
notBefore /= 1000;
notAfter /= 1000;
return {notBefore, notAfter};
},
}
_setTechDetails(input, doc) {
// CSS class and error code are set from nsDocShell.
@@ -329,15 +330,15 @@ var NetErrorContent = {
debugInfo.scrollIntoView({block: "start", behavior: "smooth"});
});
}
},
}
onCertErrorDetails(global, msg, docShell) {
onCertErrorDetails(msg, docShell) {
let doc = docShell.document;
function updateContainerPosition() {
let textContainer = doc.getElementById("text-container");
textContainer.style.marginTop = `calc(50vh - ${textContainer.clientHeight / 2}px)`;
}
function updateContainerPosition() {
let textContainer = doc.getElementById("text-container");
textContainer.style.marginTop = `calc(50vh - ${textContainer.clientHeight / 2}px)`;
}
let div = doc.getElementById("certificateErrorText");
div.textContent = msg.data.info;
@@ -484,27 +485,59 @@ var NetErrorContent = {
}
break;
}
},
}
handleEvent(aGlobal, aEvent) {
handleEvent(aEvent) {
// Documents have a null ownerDocument.
let doc = aEvent.originalTarget.ownerDocument || aEvent.originalTarget;
switch (aEvent.type) {
case "AboutNetErrorLoad":
this.onPageLoad(aGlobal, aEvent.originalTarget, doc.defaultView);
this.onPageLoad(aEvent.originalTarget, doc.defaultView);
break;
case "AboutNetErrorOpenCaptivePortal":
this.openCaptivePortalPage(aGlobal, aEvent);
this.openCaptivePortalPage(aEvent);
break;
case "AboutNetErrorSetAutomatic":
this.onSetAutomatic(aGlobal, aEvent);
this.onSetAutomatic(aEvent);
break;
case "AboutNetErrorResetPreferences":
this.onResetPreferences(aGlobal, aEvent);
this.onResetPreferences(aEvent);
break;
case "click":
if (aEvent.button == 0) {
if (this.isAboutCertError(doc)) {
this.onCertError(aEvent.originalTarget, doc.defaultView);
} else {
this.onClick(aEvent);
}
}
}
},
}
receiveMessage(msg) {
if (msg.name == "CertErrorDetails") {
let frameDocShell = WebNavigationFrames.findDocShell(msg.data.frameId, this.docShell);
// We need nsIWebNavigation to access docShell.document.
frameDocShell && frameDocShell.QueryInterface(Ci.nsIWebNavigation);
if (!frameDocShell || !this.isAboutCertError(frameDocShell.document)) {
return;
}
this.onCertErrorDetails(msg, frameDocShell);
} else if (msg.name == "Browser:CaptivePortalFreed") {
// TODO: This check is not correct for frames.
if (!this.isAboutCertError(this.content.document)) {
return;
}
this.onCaptivePortalFreed(msg);
}
}
onCaptivePortalFreed(msg) {
this.content.dispatchEvent(new this.content.CustomEvent("AboutNetErrorCaptivePortalFreed"));
}
changedCertPrefs() {
let prefSSLImpact = PREF_SSL_IMPACT_ROOTS.reduce((prefs, root) => {
@@ -517,58 +550,58 @@ var NetErrorContent = {
}
return false;
},
}
_getErrorMessageFromCode(securityInfo, doc) {
let uri = Services.io.newURI(doc.location);
let hostString = uri.host;
if (uri.port != 443 && uri.port != -1) {
hostString = uri.hostPort;
}
_getErrorMessageFromCode(securityInfo, doc) {
let uri = Services.io.newURI(doc.location);
let hostString = uri.host;
if (uri.port != 443 && uri.port != -1) {
hostString = uri.hostPort;
}
let id_str = "";
switch (securityInfo.errorCode) {
case SSL_ERROR_SSL_DISABLED:
id_str = "PSMERR_SSL_Disabled";
break;
case SSL_ERROR_SSL2_DISABLED:
id_str = "PSMERR_SSL2_Disabled";
break;
case SEC_ERROR_REUSED_ISSUER_AND_SERIAL:
id_str = "PSMERR_HostReusedIssuerSerial";
break;
}
let nss_error_id_str = securityInfo.errorCodeString;
let msg2 = "";
if (id_str) {
msg2 = gPipNSSBundle.GetStringFromName(id_str) + "\n";
} else if (nss_error_id_str) {
msg2 = gNSSErrorsBundle.GetStringFromName(nss_error_id_str) + "\n";
}
let id_str = "";
switch (securityInfo.errorCode) {
case SSL_ERROR_SSL_DISABLED:
id_str = "PSMERR_SSL_Disabled";
break;
case SSL_ERROR_SSL2_DISABLED:
id_str = "PSMERR_SSL2_Disabled";
break;
case SEC_ERROR_REUSED_ISSUER_AND_SERIAL:
id_str = "PSMERR_HostReusedIssuerSerial";
break;
}
let nss_error_id_str = securityInfo.errorCodeString;
let msg2 = "";
if (id_str) {
msg2 = gPipNSSBundle.GetStringFromName(id_str) + "\n";
} else if (nss_error_id_str) {
msg2 = gNSSErrorsBundle.GetStringFromName(nss_error_id_str) + "\n";
}
if (!msg2) {
// We couldn't get an error message. Use the error string.
// Note that this is different from before where we used PR_ErrorToString.
msg2 = nss_error_id_str;
}
let msg = gPipNSSBundle.formatStringFromName("SSLConnectionErrorPrefix2",
[hostString, msg2], 2);
if (!msg2) {
// We couldn't get an error message. Use the error string.
// Note that this is different from before where we used PR_ErrorToString.
msg2 = nss_error_id_str;
}
let msg = gPipNSSBundle.formatStringFromName("SSLConnectionErrorPrefix2",
[hostString, msg2], 2);
if (nss_error_id_str) {
msg += gPipNSSBundle.formatStringFromName("certErrorCodePrefix3",
[nss_error_id_str], 1) + "\n";
}
return msg;
},
if (nss_error_id_str) {
msg += gPipNSSBundle.formatStringFromName("certErrorCodePrefix3",
[nss_error_id_str], 1) + "\n";
}
return msg;
}
onPageLoad(global, originalTarget, win) {
onPageLoad(originalTarget, win) {
// Values for telemtery bins: see TLS_ERROR_REPORT_UI in Histograms.json
const TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN = 0;
let hideAddExceptionButton = false;
if (this.isAboutCertError(win.document)) {
this.onCertError(global, originalTarget, win);
this.onCertError(originalTarget, win);
hideAddExceptionButton =
Services.prefs.getBoolPref("security.certerror.hideAddException", false);
}
@@ -597,21 +630,21 @@ var NetErrorContent = {
})
}));
global.sendAsyncMessage("Browser:SSLErrorReportTelemetry",
this.mm.sendAsyncMessage("Browser:SSLErrorReportTelemetry",
{reportStatus: TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN});
},
}
openCaptivePortalPage(global, evt) {
global.sendAsyncMessage("Browser:OpenCaptivePortalPage");
},
openCaptivePortalPage(evt) {
this.mm.sendAsyncMessage("Browser:OpenCaptivePortalPage");
}
onResetPreferences(global, evt) {
global.sendAsyncMessage("Browser:ResetSSLPreferences");
},
onResetPreferences(evt) {
this.mm.sendAsyncMessage("Browser:ResetSSLPreferences");
}
onSetAutomatic(global, evt) {
global.sendAsyncMessage("Browser:SetSSLErrorReportAuto", {
onSetAutomatic(evt) {
this.mm.sendAsyncMessage("Browser:SetSSLErrorReportAuto", {
automatic: evt.detail
});
@@ -628,23 +661,24 @@ var NetErrorContent = {
.getService(Ci.nsISecurityReporter);
errorReporter.reportTLSError(securityInfo, host, port);
}
},
}
onCertError(global, targetElement, win) {
let docShell = win.docShell;
global.sendAsyncMessage("Browser:CertExceptionError", {
onCertError(target, win) {
this.mm.sendAsyncMessage("Browser:CertExceptionError", {
frameId: WebNavigationFrames.getFrameId(win),
location: win.document.location.href,
elementId: targetElement.getAttribute("id"),
elementId: target.getAttribute("id"),
isTopFrame: (win.parent === win),
securityInfoAsString: getSerializedSecurityInfo(docShell),
securityInfoAsString: getSerializedSecurityInfo(win.docShell),
});
},
}
onClick(event) {
let {documentURI} = event.target.ownerDocument;
onAboutNetError(global, event, documentURI) {
let elmId = event.originalTarget.getAttribute("id");
if (elmId == "returnButton") {
global.sendAsyncMessage("Browser:SSLErrorGoBack", {});
this.mm.sendAsyncMessage("Browser:SSLErrorGoBack", {});
return;
}
if (elmId != "errorTryAgain" || !/e=netOffline/.test(documentURI)) {
@@ -655,7 +689,7 @@ var NetErrorContent = {
// handle the click.
if (Services.io.offline) {
event.preventDefault();
global.sendAsyncMessage("Browser:EnableOnlineMode", {});
this.mm.sendAsyncMessage("Browser:EnableOnlineMode", {});
}
},
};
}
}

View File

@@ -0,0 +1,129 @@
/* vim: set ts=2 sw=2 sts=2 et tw=80: */
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var EXPORTED_SYMBOLS = ["OfflineAppsChild"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
class OfflineAppsChild extends ActorChild {
constructor(mm) {
super(mm);
this._docId = 0;
this._docIdMap = new Map();
this._docManifestSet = new Set();
this._observerAdded = false;
}
registerWindow(aWindow) {
if (!this._observerAdded) {
this._observerAdded = true;
Services.obs.addObserver(this, "offline-cache-update-completed", true);
}
let manifestURI = this._getManifestURI(aWindow);
this._docManifestSet.add(manifestURI.spec);
}
handleEvent(event) {
if (event.type == "MozApplicationManifest") {
let doc = event.target;
let info = {
uri: doc.documentURI,
characterSet: doc.characterSet,
manifest: doc.documentElement.getAttribute("manifest"),
principal: doc.nodePrincipal,
};
this.mm.sendAsyncMessage("MozApplicationManifest", info);
this.offlineAppRequested(event.originalTarget.defaultView);
}
}
_getManifestURI(aWindow) {
if (!aWindow.document.documentElement)
return null;
var attr = aWindow.document.documentElement.getAttribute("manifest");
if (!attr)
return null;
try {
return Services.io.newURI(attr, aWindow.document.characterSet,
Services.io.newURI(aWindow.location.href));
} catch (e) {
return null;
}
}
offlineAppRequested(aContentWindow) {
this.registerWindow(aContentWindow);
if (!Services.prefs.getBoolPref("browser.offline-apps.notify")) {
return;
}
let currentURI = aContentWindow.document.documentURIObject;
// don't bother showing UI if the user has already made a decision
if (Services.perms.testExactPermission(currentURI, "offline-app") != Services.perms.UNKNOWN_ACTION)
return;
try {
if (Services.prefs.getBoolPref("offline-apps.allow_by_default")) {
// all pages can use offline capabilities, no need to ask the user
return;
}
} catch (e) {
// this pref isn't set by default, ignore failures
}
let docId = ++this._docId;
this._docIdMap.set(docId, Cu.getWeakReference(aContentWindow.document));
this.mm.sendAsyncMessage("OfflineApps:RequestPermission", {
uri: currentURI.spec,
docId,
});
}
_startFetching(aDocument) {
if (!aDocument.documentElement)
return;
let manifestURI = this._getManifestURI(aDocument.defaultView);
if (!manifestURI)
return;
var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
getService(Ci.nsIOfflineCacheUpdateService);
updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject,
aDocument.nodePrincipal, aDocument.defaultView);
}
receiveMessage(aMessage) {
if (aMessage.name == "OfflineApps:StartFetching") {
let doc = this._docIdMap.get(aMessage.data.docId);
doc = doc && doc.get();
if (doc) {
this._startFetching(doc);
}
this._docIdMap.delete(aMessage.data.docId);
}
}
observe(aSubject, aTopic, aState) {
if (aTopic == "offline-cache-update-completed") {
let cacheUpdate = aSubject.QueryInterface(Ci.nsIOfflineCacheUpdate);
let uri = cacheUpdate.manifestURI;
if (uri && this._docManifestSet.has(uri.spec)) {
this.mm.sendAsyncMessage("OfflineApps:CheckUsage", {uri: uri.spec});
}
}
}
}
OfflineAppsChild.prototype.QueryInterface =
ChromeUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]);

View File

@@ -2,18 +2,20 @@
* 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/. */
var EXPORTED_SYMBOLS = ["PageInfoListener"];
var EXPORTED_SYMBOLS = ["PageInfoChild"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
Feeds: "resource:///modules/Feeds.jsm",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
setTimeout: "resource://gre/modules/Timer.jsm"
});
var PageInfoListener = {
class PageInfoChild extends ActorChild {
/* nsIMessageListener */
receiveMessage(message) {
let strings = message.data.strings;
@@ -39,7 +41,7 @@ var PageInfoListener = {
// Separate step so page info dialog isn't blank while waiting for this to finish.
this.getMediaInfo(document, window, strings, message.target);
},
}
getMetaInfo(document) {
let metaViewRows = [];
@@ -53,7 +55,7 @@ var PageInfoListener = {
}
return metaViewRows;
},
}
getWindowInfo(window) {
let windowInfo = {};
@@ -66,7 +68,7 @@ var PageInfoListener = {
windowInfo.hostName = hostName;
return windowInfo;
},
}
getDocumentInfo(document) {
let docInfo = {};
@@ -94,7 +96,7 @@ var PageInfoListener = {
docInfo.isContentWindowPrivate = PrivateBrowsingUtils.isContentWindowPrivate(document.ownerGlobal);
return docInfo;
},
}
getFeedsInfo(document, strings) {
let feeds = [];
@@ -124,13 +126,13 @@ var PageInfoListener = {
}
}
return feeds;
},
}
// Only called once to get the media tab's media elements from the content page.
getMediaInfo(document, window, strings, mm) {
let frameList = this.goThroughFrames(document, window);
this.processFrames(document, frameList, strings, mm);
},
}
goThroughFrames(document, window) {
let frameList = [document];
@@ -143,7 +145,7 @@ var PageInfoListener = {
}
}
return frameList;
},
}
async processFrames(document, frameList, strings, mm) {
let nodeCount = 0;
@@ -168,7 +170,7 @@ var PageInfoListener = {
}
// Send that page info media fetching has finished.
mm.sendAsyncMessage("PageInfo:mediaData", {isComplete: true});
},
}
getMediaItems(document, strings, elem) {
// Check for images defined in CSS (e.g. background, borders)
@@ -233,7 +235,7 @@ var PageInfoListener = {
}
return mediaItems;
},
}
/**
* Set up a JSON element object with all the instanceOf and other infomation that
@@ -316,7 +318,7 @@ var PageInfoListener = {
result.baseURI = item.baseURI;
return result;
},
}
// Other Misc Stuff
// Modified from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html
@@ -355,7 +357,7 @@ var PageInfoListener = {
}
return this.stripWS(valueText);
},
}
// Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html.
// Traverse the tree in search of an img or area element and grab its alt tag.
@@ -372,7 +374,7 @@ var PageInfoListener = {
}
}
return "";
},
}
// Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html.
// Strip leading and trailing whitespace, and replace multiple consecutive whitespace characters with a single space.
@@ -383,4 +385,4 @@ var PageInfoListener = {
text = text.replace(middleRE, " ");
return text.replace(endRE, "");
}
};
}

View File

@@ -0,0 +1,33 @@
/* vim: set ts=2 sw=2 sts=2 et 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["PageMetadataChild"];
ChromeUtils.import("resource://gre/actors/ActorChild.jsm");
ChromeUtils.defineModuleGetter(this, "ContextMenuChild",
"resource:///modules/ContextMenuChild.jsm");
ChromeUtils.defineModuleGetter(this, "PageMetadata",
"resource://gre/modules/PageMetadata.jsm");
class PageMetadataChild extends ActorChild {
receiveMessage(message) {
switch (message.name) {
case "PageMetadata:GetPageData": {
let target = ContextMenuChild.getTarget(this.mm, message);
let result = PageMetadata.getData(this.content.document, target);
this.mm.sendAsyncMessage("PageMetadata:PageDataResult", result);
break;
}
case "PageMetadata:GetMicroformats": {
let target = ContextMenuChild.getTarget(this.mm, message);
let result = PageMetadata.getMicroformats(this.content.document, target);
this.mm.sendAsyncMessage("PageMetadata:MicroformatsResult", result);
break;
}
}
}
}

View File

@@ -4,12 +4,14 @@
ChromeUtils.import("resource://gre/modules/Services.jsm");
var EXPORTED_SYMBOLS = ["PageStyleHandler"];
var EXPORTED_SYMBOLS = ["PageStyleChild"];
var PageStyleHandler = {
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
class PageStyleChild extends ActorChild {
getViewer(content) {
return content.docShell.contentViewer;
},
}
sendStyleSheetInfo(mm) {
let content = mm.content;
@@ -20,13 +22,13 @@ var PageStyleHandler = {
authorStyleDisabled: this.getViewer(content).authorStyleDisabled,
preferredStyleSheetSet: content.document.preferredStyleSheetSet
});
},
}
getAllStyleSheets(frameset) {
let selfSheets = Array.slice(frameset.document.styleSheets);
let subSheets = Array.map(frameset.frames, frame => this.getAllStyleSheets(frame));
return selfSheets.concat(...subSheets);
},
}
receiveMessage(msg) {
let content = msg.target.content;
@@ -42,7 +44,7 @@ var PageStyleHandler = {
}
this.sendStyleSheetInfo(msg.target);
},
}
handleEvent(event) {
let win = event.target.ownerGlobal;
@@ -52,7 +54,7 @@ var PageStyleHandler = {
let mm = win.docShell.messageManager;
this.sendStyleSheetInfo(mm);
},
}
_stylesheetSwitchAll(frameset, title) {
if (!title || this._stylesheetInFrame(frameset, title)) {
@@ -63,7 +65,7 @@ var PageStyleHandler = {
// Recurse into sub-frames.
this._stylesheetSwitchAll(frameset.frames[i], title);
}
},
}
_stylesheetSwitchFrame(frame, title) {
var docStyleSheets = frame.document.styleSheets;
@@ -76,11 +78,11 @@ var PageStyleHandler = {
docStyleSheet.disabled = false;
}
}
},
}
_stylesheetInFrame(frame, title) {
return Array.some(frame.document.styleSheets, (styleSheet) => styleSheet.title == title);
},
}
_filterStyleSheets(styleSheets, content) {
let result = [];
@@ -123,5 +125,5 @@ var PageStyleHandler = {
}
return result;
},
};
}
}

View File

@@ -4,13 +4,18 @@
"use strict";
var EXPORTED_SYMBOLS = [ "PluginContent" ];
var EXPORTED_SYMBOLS = ["PluginChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/Timer.jsm");
ChromeUtils.import("resource://gre/modules/BrowserUtils.jsm");
ChromeUtils.defineModuleGetter(this, "ContextMenuChild",
"resource:///actors/ContextMenuChild.jsm");
XPCOMUtils.defineLazyGetter(this, "gNavigatorBundle", function() {
const url = "chrome://browser/locale/browser.properties";
return Services.strings.createBundle(url);
@@ -19,10 +24,6 @@ XPCOMUtils.defineLazyGetter(this, "gNavigatorBundle", function() {
ChromeUtils.defineModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
var PluginContent = function(global) {
this.init(global);
};
const OVERLAY_DISPLAY = {
HIDDEN: 0, // The overlay will be transparent
BLANK: 1, // The overlay will be just a grey box
@@ -32,19 +33,18 @@ const OVERLAY_DISPLAY = {
FULL: 5, // The full overlay: 48x48 plugin icon, close button and label
};
PluginContent.prototype = {
init(global) {
this.global = global;
// Need to hold onto the content window or else it'll get destroyed
this.content = this.global.content;
class PluginChild extends ActorChild {
constructor(mm) {
super(mm);
// Cache of plugin actions for the current page.
this.pluginData = new Map();
// Cache of plugin crash information sent from the parent
this.pluginCrashData = new Map();
global.addEventListener("pagehide", this, true);
global.addEventListener("pageshow", this, true);
},
this.mm.addEventListener("pagehide", this, true);
this.mm.addEventListener("pageshow", this, true);
}
receiveMessage(msg) {
switch (msg.name) {
@@ -55,14 +55,12 @@ PluginContent.prototype = {
setTimeout(() => this.updateNotificationUI(), 0);
break;
case "BrowserPlugins:ContextMenuCommand":
let contextMenu = this.global.contextMenu;
switch (msg.data.command) {
case "play":
this._showClickToPlayNotification(contextMenu.getTarget(msg, "plugin"), true);
this._showClickToPlayNotification(ContextMenuChild.getTarget(this.mm, msg, "plugin"), true);
break;
case "hide":
this.hideClickToPlayOverlay(contextMenu.getTarget(msg, "plugin"));
this.hideClickToPlayOverlay(ContextMenuChild.getTarget(this.mm, msg, "plugin"));
break;
}
break;
@@ -85,9 +83,9 @@ PluginContent.prototype = {
this.pluginCrashData.clear();
}
}
},
}
observe: function observe(aSubject, aTopic, aData) {
observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "decoder-doctor-notification":
let data = JSON.parse(aData);
@@ -96,11 +94,11 @@ PluginContent.prototype = {
this.haveShownNotification &&
aSubject.top.document == this.content.document &&
data.formats.toLowerCase().includes("application/x-mpegurl", 0)) {
this.global.content.pluginRequiresReload = true;
this.content.pluginRequiresReload = true;
this.updateNotificationUI(this.content.document);
}
}
},
}
onPageShow(event) {
// Ignore events that aren't from the main document.
@@ -114,7 +112,7 @@ PluginContent.prototype = {
if (event.persisted) {
this.reshowClickToPlayNotification();
}
},
}
onPageHide(event) {
// Ignore events that aren't from the main document.
@@ -124,12 +122,12 @@ PluginContent.prototype = {
this.clearPluginCaches();
this.haveShownNotification = false;
},
}
getPluginUI(plugin, anonid) {
return plugin.ownerDocument.
getAnonymousElementByAttribute(plugin, "anonid", anonid);
},
}
_getPluginInfo(pluginElement) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
@@ -178,7 +176,7 @@ PluginContent.prototype = {
fallbackType,
blocklistState,
};
},
}
/**
* _getPluginInfoForTag is called when iterating the plugins for a document,
@@ -227,7 +225,7 @@ PluginContent.prototype = {
fallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
blocklistState,
};
},
}
/**
* Update the visibility of the plugin overlay.
@@ -237,7 +235,7 @@ PluginContent.prototype = {
if (overlayDisplayState != OVERLAY_DISPLAY.HIDDEN) {
overlay.removeAttribute("dismissed");
}
},
}
/**
* Adjust the style in which the overlay will be displayed. It might be adjusted
@@ -338,7 +336,7 @@ PluginContent.prototype = {
overlay.setAttribute("sizing", "blank");
return OVERLAY_DISPLAY.BLANK;
},
}
addLinkClickCallback(linkNode, callbackName /* callbackArgs...*/) {
// XXX just doing (callback)(arg) was giving a same-origin error. bug?
@@ -368,7 +366,7 @@ PluginContent.prototype = {
}
},
true);
},
}
// Helper to get the binding handler type from a plugin object
_getBindingType(plugin) {
@@ -395,7 +393,7 @@ PluginContent.prototype = {
// Not all states map to a handler
return null;
}
},
}
handleEvent(event) {
let eventType = event.type;
@@ -538,12 +536,12 @@ PluginContent.prototype = {
if (shouldShowNotification) {
this._showClickToPlayNotification(plugin, false);
}
},
}
isKnownPlugin(objLoadingContent) {
return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) ==
Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
},
}
canActivatePlugin(objLoadingContent) {
// if this isn't a known plugin, we can't activate it
@@ -564,22 +562,22 @@ PluginContent.prototype = {
return !objLoadingContent.activated &&
pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
isFallbackTypeValid;
},
}
hideClickToPlayOverlay(plugin) {
let overlay = this.getPluginUI(plugin, "main");
if (overlay) {
overlay.classList.remove("visible");
}
},
}
// Forward a link click callback to the chrome process.
forwardCallback(name, pluginTag) {
this.global.sendAsyncMessage("PluginContent:LinkClickCallback",
this.mm.sendAsyncMessage("PluginContent:LinkClickCallback",
{ name, pluginTag });
},
}
submitReport: function submitReport(plugin) {
submitReport(plugin) {
if (!AppConstants.MOZ_CRASHREPORTER) {
return;
}
@@ -602,13 +600,13 @@ PluginContent.prototype = {
if (submitURLOptIn)
keyVals.PluginContentURL = plugin.ownerDocument.URL;
this.global.sendAsyncMessage("PluginContent:SubmitReport",
this.mm.sendAsyncMessage("PluginContent:SubmitReport",
{ runID, keyVals, submitURLOptIn });
},
}
reloadPage() {
this.global.content.location.reload();
},
this.content.location.reload();
}
// Event listener for click-to-play plugins.
_handleClickToPlayEvent(plugin) {
@@ -636,7 +634,7 @@ PluginContent.prototype = {
if (overlay) {
overlay.addEventListener("click", this, true);
}
},
}
onOverlayClick(event) {
let document = event.target.ownerDocument;
@@ -652,10 +650,10 @@ PluginContent.prototype = {
event.stopPropagation();
event.preventDefault();
}
},
}
reshowClickToPlayNotification() {
let contentWindow = this.global.content;
let contentWindow = this.content;
let cwu = contentWindow.windowUtils;
let plugins = cwu.plugins;
for (let plugin of plugins) {
@@ -667,13 +665,13 @@ PluginContent.prototype = {
this._handleClickToPlayEvent(plugin);
}
this._showClickToPlayNotification(null, false);
},
}
/**
* Activate the plugins that the user has specified.
*/
activatePlugins(pluginInfo, newState) {
let contentWindow = this.global.content;
let contentWindow = this.content;
let cwu = contentWindow.windowUtils;
let plugins = cwu.plugins;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
@@ -710,7 +708,7 @@ PluginContent.prototype = {
this.reloadPage();
}
this.updateNotificationUI();
},
}
_showClickToPlayNotification(plugin, showNow) {
let plugins = [];
@@ -768,12 +766,12 @@ PluginContent.prototype = {
this.haveShownNotification = true;
this.global.sendAsyncMessage("PluginContent:ShowClickToPlayNotification", {
this.mm.sendAsyncMessage("PluginContent:ShowClickToPlayNotification", {
plugins: [...this.pluginData.values()],
showNow,
location,
}, null, principal);
},
}
/**
* Updates the "hidden plugin" notification bar UI.
@@ -851,25 +849,25 @@ PluginContent.prototype = {
// If there are any items remaining in `actions` now, they are hidden
// plugins that need a notification bar.
this.global.sendAsyncMessage("PluginContent:UpdateHiddenPluginUI", {
this.mm.sendAsyncMessage("PluginContent:UpdateHiddenPluginUI", {
haveInsecure,
actions: [...actions.values()],
location,
}, null, principal);
},
}
removeNotification(name) {
this.global.sendAsyncMessage("PluginContent:RemoveNotification", { name });
},
this.mm.sendAsyncMessage("PluginContent:RemoveNotification", { name });
}
clearPluginCaches() {
this.pluginData.clear();
this.pluginCrashData.clear();
},
}
hideNotificationBar(name) {
this.global.sendAsyncMessage("PluginContent:HideNotificationBar", { name });
},
this.mm.sendAsyncMessage("PluginContent:HideNotificationBar", { name });
}
/**
* Determines whether or not the crashed plugin is contained within current
@@ -910,7 +908,7 @@ PluginContent.prototype = {
return this.isWithinFullScreenElement(fullScreenElement, parentIframe);
}
return false;
},
}
/**
* The PluginCrashed event handler. Note that the PluginCrashed event is
@@ -954,14 +952,14 @@ PluginContent.prototype = {
state: crashData.state,
message: crashData.message,
});
},
}
NPAPIPluginProcessCrashed({pluginName, runID, state}) {
let message =
gNavigatorBundle.formatStringFromName("crashedpluginsMessage.title",
[pluginName], 1);
let contentWindow = this.global.content;
let contentWindow = this.content;
let cwu = contentWindow.windowUtils;
let plugins = cwu.plugins;
@@ -994,7 +992,7 @@ PluginContent.prototype = {
}
}
}
},
}
setCrashedNPAPIPluginState({plugin, state, message}) {
// Force a layout flush so the binding is attached.
@@ -1053,18 +1051,18 @@ PluginContent.prototype = {
} else if (!doc.mozNoPluginCrashedNotification) {
// If another plugin on the page was large enough to show our UI, we don't
// want to show a notification bar.
this.global.sendAsyncMessage("PluginContent:ShowPluginCrashedNotification",
this.mm.sendAsyncMessage("PluginContent:ShowPluginCrashedNotification",
{ messageString: message, pluginID: runID });
// Remove the notification when the page is reloaded.
doc.defaultView.top.addEventListener("unload", event => {
this.hideNotificationBar("plugin-crashed");
});
}
},
}
NPAPIPluginCrashReportSubmitted({ runID, state }) {
this.pluginCrashData.delete(runID);
let contentWindow = this.global.content;
let contentWindow = this.content;
let cwu = contentWindow.windowUtils;
let plugins = cwu.plugins;
@@ -1075,7 +1073,7 @@ PluginContent.prototype = {
statusDiv.setAttribute("status", state);
}
}
},
}
GMPCrashed(aEvent) {
let target = aEvent.target;
@@ -1093,12 +1091,12 @@ PluginContent.prototype = {
gNavigatorBundle.formatStringFromName("crashedpluginsMessage.title",
[pluginName], 1);
this.global.sendAsyncMessage("PluginContent:ShowPluginCrashedNotification",
this.mm.sendAsyncMessage("PluginContent:ShowPluginCrashedNotification",
{ messageString, pluginID });
// Remove the notification when the page is reloaded.
doc.defaultView.top.addEventListener("unload", event => {
this.hideNotificationBar("plugin-crashed");
});
},
};
}
}

View File

@@ -0,0 +1,37 @@
/* vim: set ts=2 sw=2 sts=2 et 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["URIFixupChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
class URIFixupChild extends ActorChild {
observe(subject) {
let fixupInfo = subject.QueryInterface(Ci.nsIURIFixupInfo);
if (!fixupInfo.consumer) {
return;
}
// Ignore info from other docshells
let parent = fixupInfo.consumer.QueryInterface(Ci.nsIDocShellTreeItem).sameTypeRootTreeItem;
if (parent != this.mm.docShell)
return;
let data = {};
for (let f of Object.keys(fixupInfo)) {
if (f == "consumer" || typeof fixupInfo[f] == "function")
continue;
if (fixupInfo[f] && fixupInfo[f] instanceof Ci.nsIURI) {
data[f] = fixupInfo[f].spec;
} else {
data[f] = fixupInfo[f];
}
}
this.mm.sendAsyncMessage("Browser:URIFixup", data);
}
}

View File

@@ -4,10 +4,11 @@
"use strict";
var EXPORTED_SYMBOLS = [ "ContentWebRTC" ];
var EXPORTED_SYMBOLS = ["WebRTCChild"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
"@mozilla.org/mediaManagerService;1",
@@ -15,9 +16,9 @@ XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
const kBrowserURL = AppConstants.BROWSER_CHROME_URL;
var ContentWebRTC = {
class WebRTCChild extends ActorChild {
// Called only for 'unload' to remove pending gUM prompts in reloaded frames.
handleEvent(aEvent) {
static handleEvent(aEvent) {
let contentWindow = aEvent.target.defaultView;
let mm = getMessageManagerForWindow(contentWindow);
for (let key of contentWindow.pendingGetUserMediaRequests.keys()) {
@@ -26,11 +27,11 @@ var ContentWebRTC = {
for (let key of contentWindow.pendingPeerConnectionRequests.keys()) {
mm.sendAsyncMessage("rtcpeer:CancelRequest", key);
}
},
}
// This observer is registered in ContentObservers.js to avoid
// loading this .jsm when WebRTC is not in use.
observe(aSubject, aTopic, aData) {
static observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "getUserMedia:request":
handleGUMRequest(aSubject, aTopic, aData);
@@ -48,7 +49,7 @@ var ContentWebRTC = {
removeBrowserSpecificIndicator(aSubject, aTopic, aData);
break;
}
},
}
receiveMessage(aMessage) {
switch (aMessage.name) {
@@ -84,7 +85,7 @@ var ContentWebRTC = {
break;
}
}
};
}
function handlePCRequest(aSubject, aTopic, aData) {
let { windowID, innerWindowID, callID, isSecure } = aSubject;
@@ -264,7 +265,7 @@ function setupPendingListsInitially(aContentWindow) {
}
aContentWindow.pendingGetUserMediaRequests = new Map();
aContentWindow.pendingPeerConnectionRequests = new Set();
aContentWindow.addEventListener("unload", ContentWebRTC);
aContentWindow.addEventListener("unload", WebRTCChild.handleEvent);
}
function forgetPendingListsEventually(aContentWindow) {
@@ -274,7 +275,7 @@ function forgetPendingListsEventually(aContentWindow) {
}
aContentWindow.pendingGetUserMediaRequests = null;
aContentWindow.pendingPeerConnectionRequests = null;
aContentWindow.removeEventListener("unload", ContentWebRTC);
aContentWindow.removeEventListener("unload", WebRTCChild.handleEvent);
}
function updateIndicators(aSubject, aTopic, aData) {

42
browser/actors/moz.build Normal file
View File

@@ -0,0 +1,42 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("LightWeightThemeInstallChild.jsm"):
BUG_COMPONENT = ("Firefox", "Theme")
with Files("PageInfoChild.jsm"):
BUG_COMPONENT = ("Firefox", "Page Info Window")
with Files("PageStyleChild.jsm"):
BUG_COMPONENT = ("Firefox", "Menus")
with Files("PluginChild.jsm"):
BUG_COMPONENT = ("Core", "Plug-ins")
with Files("WebRTCChild.jsm"):
BUG_COMPONENT = ("Firefox", "Device Permissions")
FINAL_TARGET_FILES.actors += [
'AboutReaderChild.jsm',
'BlockedSiteChild.jsm',
'BrowserTabChild.jsm',
'ClickHandlerChild.jsm',
'ContentSearchChild.jsm',
'ContextMenuChild.jsm',
'DOMFullscreenChild.jsm',
'LightWeightThemeInstallChild.jsm',
'NetErrorChild.jsm',
'OfflineAppsChild.jsm',
'PageInfoChild.jsm',
'PageMetadataChild.jsm',
'PageStyleChild.jsm',
'PluginChild.jsm',
'URIFixupChild.jsm',
'WebRTCChild.jsm',
]

View File

@@ -489,9 +489,6 @@ const gSessionHistoryObserver = {
var fwdCommand = document.getElementById("Browser:Forward");
fwdCommand.setAttribute("disabled", "true");
// Hide session restore button on about:home
window.messageManager.broadcastAsyncMessage("Browser:HideSessionRestoreButton");
// Clear undo history of the URL bar
gURLBar.editor.transactionManager.clear();
}
@@ -1318,8 +1315,8 @@ var gBrowserInit = {
ZoomUI.init(window);
let mm = window.getGroupMessageManager("browsers");
mm.loadFrameScript("chrome://browser/content/tab-content.js", true);
mm.loadFrameScript("chrome://browser/content/content.js", true);
mm.loadFrameScript("chrome://browser/content/tab-content.js", true, true);
mm.loadFrameScript("chrome://browser/content/content.js", true, true);
mm.loadFrameScript("chrome://global/content/content-HybridContentTelemetry.js", true);
window.messageManager.addMessageListener("Browser:LoadURI", RedirectLoad);
@@ -5209,7 +5206,7 @@ const AccessibilityRefreshBlocker = {
if (!this._loaded) {
this._loaded = true;
let mm = window.getGroupMessageManager("browsers");
mm.loadFrameScript("chrome://browser/content/content-refreshblocker.js", true);
mm.loadFrameScript("chrome://browser/content/content-refreshblocker.js", true, true);
}
}
};

View File

@@ -0,0 +1,3 @@
#define BROWSER_XHTML
#include browser.xul
#undef BROWSER_XHTML

View File

@@ -72,7 +72,11 @@
# that they can be shared with macWindow.inc.xul.
#include global-scripts.inc
<script type="application/javascript">
<script type="application/javascript"
#ifdef BROWSER_XHTML
xmlns="http://www.w3.org/1999/xhtml"
#endif
>
Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser.js", this);
</script>

View File

@@ -16,28 +16,12 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
var global = this;
XPCOMUtils.defineLazyModuleGetters(this, {
BlockedSiteContent: "resource:///modules/BlockedSiteContent.jsm",
ContentLinkHandler: "resource:///modules/ContentLinkHandler.jsm",
ContentMetaHandler: "resource:///modules/ContentMetaHandler.jsm",
ContentWebRTC: "resource:///modules/ContentWebRTC.jsm",
LoginFormFactory: "resource://gre/modules/LoginManagerContent.jsm",
InsecurePasswordUtils: "resource://gre/modules/InsecurePasswordUtils.jsm",
PluginContent: "resource:///modules/PluginContent.jsm",
FormSubmitObserver: "resource:///modules/FormSubmitObserver.jsm",
NetErrorContent: "resource:///modules/NetErrorContent.jsm",
PageMetadata: "resource://gre/modules/PageMetadata.jsm",
WebNavigationFrames: "resource://gre/modules/WebNavigationFrames.jsm",
ContextMenu: "resource:///modules/ContextMenu.jsm",
});
XPCOMUtils.defineLazyProxy(this, "contextMenu", () => {
return new ContextMenu(global);
});
XPCOMUtils.defineLazyProxy(this, "ClickEventHandler", () => {
let tmp = {};
ChromeUtils.import("resource:///modules/ClickEventHandler.jsm", tmp);
return new tmp.ClickEventHandler(global);
ContextMenuChild: "resource:///actors/ContextMenuChild.jsm",
});
XPCOMUtils.defineLazyGetter(this, "LoginManagerContent", () => {
@@ -54,22 +38,12 @@ XPCOMUtils.defineLazyProxy(this, "formSubmitObserver", () => {
QueryInterface: ChromeUtils.generateQI([Ci.nsIFormSubmitObserver, Ci.nsISupportsWeakReference])
});
XPCOMUtils.defineLazyProxy(this, "PageInfoListener",
"resource:///modules/PageInfoListener.jsm");
XPCOMUtils.defineLazyProxy(this, "LightWeightThemeWebInstallListener",
"resource:///modules/LightWeightThemeWebInstallListener.jsm");
Services.els.addSystemEventListener(global, "contextmenu", contextMenu, false);
Services.obs.addObserver(formSubmitObserver, "invalidformsubmit", true);
addMessageListener("PageInfo:getData", PageInfoListener);
// NOTE: Much of this logic is duplicated in BrowserCLH.js for Android.
addMessageListener("RemoteLogins:fillForm", function(message) {
// intercept if ContextMenu.jsm had sent a plain object for remote targets
message.objects.inputElement = contextMenu.getTarget(message, "inputElement");
message.objects.inputElement = ContextMenuChild.getTarget(global, message, "inputElement");
LoginManagerContent.receiveMessage(message, content);
});
addEventListener("DOMFormHasPassword", function(event) {
@@ -86,311 +60,12 @@ addEventListener("DOMAutoComplete", function(event) {
LoginManagerContent.onUsernameInput(event);
});
var AboutBlockedSiteListener = {
init(chromeGlobal) {
addMessageListener("DeceptiveBlockedDetails", this);
chromeGlobal.addEventListener("AboutBlockedLoaded", this, false, true);
this.init = null;
},
get isBlockedSite() {
return content.document.documentURI.startsWith("about:blocked");
},
receiveMessage(msg) {
if (!this.isBlockedSite) {
return;
}
BlockedSiteContent.receiveMessage(global, msg);
},
handleEvent(aEvent) {
if (!this.isBlockedSite) {
return;
}
if (aEvent.type != "AboutBlockedLoaded") {
return;
}
BlockedSiteContent.handleEvent(global, aEvent);
},
};
AboutBlockedSiteListener.init(this);
this.AboutNetAndCertErrorListener = {
init(chromeGlobal) {
addMessageListener("CertErrorDetails", this);
addMessageListener("Browser:CaptivePortalFreed", this);
chromeGlobal.addEventListener("AboutNetErrorLoad", this, false, true);
chromeGlobal.addEventListener("AboutNetErrorOpenCaptivePortal", this, false, true);
chromeGlobal.addEventListener("AboutNetErrorSetAutomatic", this, false, true);
chromeGlobal.addEventListener("AboutNetErrorResetPreferences", this, false, true);
this.init = null;
},
isAboutNetError(doc) {
return doc.documentURI.startsWith("about:neterror");
},
isAboutCertError(doc) {
return doc.documentURI.startsWith("about:certerror");
},
receiveMessage(msg) {
if (msg.name == "CertErrorDetails") {
let frameDocShell = WebNavigationFrames.findDocShell(msg.data.frameId, docShell);
// We need nsIWebNavigation to access docShell.document.
frameDocShell && frameDocShell.QueryInterface(Ci.nsIWebNavigation);
if (!frameDocShell || !this.isAboutCertError(frameDocShell.document)) {
return;
}
NetErrorContent.onCertErrorDetails(global, msg, frameDocShell);
} else if (msg.name == "Browser:CaptivePortalFreed") {
// TODO: This check is not correct for frames.
if (!this.isAboutCertError(content.document)) {
return;
}
this.onCaptivePortalFreed(msg);
}
},
onCaptivePortalFreed(msg) {
content.dispatchEvent(new content.CustomEvent("AboutNetErrorCaptivePortalFreed"));
},
handleEvent(aEvent) {
// Documents have a null ownerDocument.
let doc = aEvent.originalTarget.ownerDocument || aEvent.originalTarget;
if (!this.isAboutNetError(doc) && !this.isAboutCertError(doc)) {
return;
}
NetErrorContent.handleEvent(global, aEvent);
},
};
AboutNetAndCertErrorListener.init(this);
Services.els.addSystemEventListener(global, "click", ClickEventHandler, true);
new ContentLinkHandler(this);
ContentMetaHandler.init(this);
var PluginContentStub = {
EVENTS: [
"PluginCrashed",
"PluginOutdated",
"PluginInstantiated",
"PluginRemoved",
"HiddenPlugin",
],
MESSAGES: [
"BrowserPlugins:ActivatePlugins",
"BrowserPlugins:NotificationShown",
"BrowserPlugins:ContextMenuCommand",
"BrowserPlugins:NPAPIPluginProcessCrashed",
"BrowserPlugins:CrashReportSubmitted",
"BrowserPlugins:Test:ClearCrashData",
],
_pluginContent: null,
get pluginContent() {
if (!this._pluginContent) {
this._pluginContent = new PluginContent(global);
}
return this._pluginContent;
},
init() {
addEventListener("unload", this);
addEventListener("PluginBindingAttached", this, true, true);
for (let event of this.EVENTS) {
addEventListener(event, this, true);
}
for (let msg of this.MESSAGES) {
addMessageListener(msg, this);
}
Services.obs.addObserver(this, "decoder-doctor-notification");
this.init = null;
},
uninit() {
Services.obs.removeObserver(this, "decoder-doctor-notification");
},
observe(subject, topic, data) {
return this.pluginContent.observe(subject, topic, data);
},
handleEvent(event) {
if (event.type === "unload") {
return this.uninit();
}
return this.pluginContent.handleEvent(event);
},
receiveMessage(msg) {
return this.pluginContent.receiveMessage(msg);
},
};
PluginContentStub.init();
// This is a temporary hack to prevent regressions (bug 1471327).
void content;
addEventListener("DOMWindowFocus", function(event) {
sendAsyncMessage("DOMWindowFocus", {});
}, false);
// We use this shim so that ContentWebRTC.jsm will not be loaded until
// it is actually needed.
var ContentWebRTCShim = message => ContentWebRTC.receiveMessage(message);
addMessageListener("rtcpeer:Allow", ContentWebRTCShim);
addMessageListener("rtcpeer:Deny", ContentWebRTCShim);
addMessageListener("webrtc:Allow", ContentWebRTCShim);
addMessageListener("webrtc:Deny", ContentWebRTCShim);
addMessageListener("webrtc:StopSharing", ContentWebRTCShim);
var PageMetadataMessenger = {
init() {
addMessageListener("PageMetadata:GetPageData", this);
addMessageListener("PageMetadata:GetMicroformats", this);
this.init = null;
},
receiveMessage(message) {
switch (message.name) {
case "PageMetadata:GetPageData": {
let target = contextMenu.getTarget(message);
let result = PageMetadata.getData(content.document, target);
sendAsyncMessage("PageMetadata:PageDataResult", result);
break;
}
case "PageMetadata:GetMicroformats": {
let target = contextMenu.getTarget(message);
let result = PageMetadata.getMicroformats(content.document, target);
sendAsyncMessage("PageMetadata:MicroformatsResult", result);
break;
}
}
}
};
PageMetadataMessenger.init();
addEventListener("InstallBrowserTheme", LightWeightThemeWebInstallListener, false, true);
addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstallListener, false, true);
addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstallListener, false, true);
let OfflineApps = {
_docId: 0,
_docIdMap: new Map(),
_docManifestSet: new Set(),
_observerAdded: false,
registerWindow(aWindow) {
if (!this._observerAdded) {
this._observerAdded = true;
Services.obs.addObserver(this, "offline-cache-update-completed", true);
}
let manifestURI = this._getManifestURI(aWindow);
this._docManifestSet.add(manifestURI.spec);
},
handleEvent(event) {
if (event.type == "MozApplicationManifest") {
this.offlineAppRequested(event.originalTarget.defaultView);
}
},
_getManifestURI(aWindow) {
if (!aWindow.document.documentElement)
return null;
var attr = aWindow.document.documentElement.getAttribute("manifest");
if (!attr)
return null;
try {
return Services.io.newURI(attr, aWindow.document.characterSet,
Services.io.newURI(aWindow.location.href));
} catch (e) {
return null;
}
},
offlineAppRequested(aContentWindow) {
this.registerWindow(aContentWindow);
if (!Services.prefs.getBoolPref("browser.offline-apps.notify")) {
return;
}
let currentURI = aContentWindow.document.documentURIObject;
// don't bother showing UI if the user has already made a decision
if (Services.perms.testExactPermission(currentURI, "offline-app") != Services.perms.UNKNOWN_ACTION)
return;
try {
if (Services.prefs.getBoolPref("offline-apps.allow_by_default")) {
// all pages can use offline capabilities, no need to ask the user
return;
}
} catch (e) {
// this pref isn't set by default, ignore failures
}
let docId = ++this._docId;
this._docIdMap.set(docId, Cu.getWeakReference(aContentWindow.document));
sendAsyncMessage("OfflineApps:RequestPermission", {
uri: currentURI.spec,
docId,
});
},
_startFetching(aDocument) {
if (!aDocument.documentElement)
return;
let manifestURI = this._getManifestURI(aDocument.defaultView);
if (!manifestURI)
return;
var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
getService(Ci.nsIOfflineCacheUpdateService);
updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject,
aDocument.nodePrincipal, aDocument.defaultView);
},
receiveMessage(aMessage) {
if (aMessage.name == "OfflineApps:StartFetching") {
let doc = this._docIdMap.get(aMessage.data.docId);
doc = doc && doc.get();
if (doc) {
this._startFetching(doc);
}
this._docIdMap.delete(aMessage.data.docId);
}
},
observe(aSubject, aTopic, aState) {
if (aTopic == "offline-cache-update-completed") {
let cacheUpdate = aSubject.QueryInterface(Ci.nsIOfflineCacheUpdate);
let uri = cacheUpdate.manifestURI;
if (uri && this._docManifestSet.has(uri.spec)) {
sendAsyncMessage("OfflineApps:CheckUsage", {uri: uri.spec});
}
}
},
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
};
addEventListener("MozApplicationManifest", OfflineApps, false);
addMessageListener("OfflineApps:StartFetching", OfflineApps);

View File

@@ -7,7 +7,11 @@
# file so that ESLint works correctly:
# tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js
<script type="application/javascript">
<script type="text/javascript"
#ifdef BROWSER_XHTML
xmlns="http://www.w3.org/1999/xhtml"
#endif
>
Components.utils.import("resource://gre/modules/Services.jsm");
for (let script of [

View File

@@ -14,88 +14,17 @@ ChromeUtils.defineModuleGetter(this, "E10SUtils",
"resource://gre/modules/E10SUtils.jsm");
ChromeUtils.defineModuleGetter(this, "BrowserUtils",
"resource://gre/modules/BrowserUtils.jsm");
ChromeUtils.defineModuleGetter(this, "Utils",
"resource://gre/modules/sessionstore/Utils.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
ChromeUtils.defineModuleGetter(this, "AboutReader",
"resource://gre/modules/AboutReader.jsm");
ChromeUtils.defineModuleGetter(this, "ReaderMode",
"resource://gre/modules/ReaderMode.jsm");
ChromeUtils.defineModuleGetter(this, "PageStyleHandler",
"resource:///modules/PageStyleHandler.jsm");
ChromeUtils.import("resource://gre/modules/ActorManagerChild.jsm");
ActorManagerChild.attach(this, "browsers");
// TabChildGlobal
var global = this;
addEventListener("MozDOMPointerLock:Entered", function(aEvent) {
sendAsyncMessage("PointerLock:Entered", {
originNoSuffix: aEvent.target.nodePrincipal.originNoSuffix
});
});
addEventListener("MozDOMPointerLock:Exited", function(aEvent) {
sendAsyncMessage("PointerLock:Exited");
});
addMessageListener("Browser:HideSessionRestoreButton", function(message) {
// Hide session restore button on about:home
let doc = content.document;
let container;
if (doc.documentURI.toLowerCase() == "about:home" &&
(container = doc.getElementById("sessionRestoreContainer"))) {
container.hidden = true;
}
});
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
addMessageListener("Browser:HasSiblings", function(message) {
let tabChild = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsITabChild);
let hasSiblings = message.data;
tabChild.hasSiblings = hasSiblings;
});
}
// XXX(nika): Should we try to call this in the parent process instead?
addMessageListener("Browser:Reload", function(message) {
/* First, we'll try to use the session history object to reload so
* that framesets are handled properly. If we're in a special
* window (such as view-source) that has no session history, fall
* back on using the web navigation's reload method.
*/
let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
try {
if (webNav.sessionHistory) {
webNav = webNav.sessionHistory;
}
} catch (e) {
}
let reloadFlags = message.data.flags;
try {
E10SUtils.wrapHandlingUserInput(content, message.data.handlingUserInput,
() => webNav.reload(reloadFlags));
} catch (e) {
}
});
addMessageListener("MixedContent:ReenableProtection", function() {
docShell.mixedContentChannel = null;
});
XPCOMUtils.defineLazyProxy(this, "LightweightThemeChildHelper",
"resource:///modules/LightweightThemeChildHelper.jsm");
XPCOMUtils.defineLazyProxy(this, "ManifestMessages", () => {
let tmp = {};
ChromeUtils.import("resource://gre/modules/ManifestMessages.jsm", tmp);
return new tmp.ManifestMessages(global);
});
let themeablePagesWhitelist = new Set([
"about:home",
"about:newtab",
@@ -109,213 +38,6 @@ addEventListener("pageshow", function({ originalTarget }) {
}
}, false, true);
var AboutReaderListener = {
_articlePromise: null,
_isLeavingReaderableReaderMode: false,
init() {
addEventListener("AboutReaderContentLoaded", this, false, true);
addEventListener("DOMContentLoaded", this, false);
addEventListener("pageshow", this, false);
addEventListener("pagehide", this, false);
addMessageListener("Reader:ToggleReaderMode", this);
addMessageListener("Reader:PushState", this);
this.init = null;
},
receiveMessage(message) {
switch (message.name) {
case "Reader:ToggleReaderMode":
if (!this.isAboutReader) {
this._articlePromise = ReaderMode.parseDocument(content.document).catch(Cu.reportError);
ReaderMode.enterReaderMode(docShell, content);
} else {
this._isLeavingReaderableReaderMode = this.isReaderableAboutReader;
ReaderMode.leaveReaderMode(docShell, content);
}
break;
case "Reader:PushState":
this.updateReaderButton(!!(message.data && message.data.isArticle));
break;
}
},
get isAboutReader() {
if (!content) {
return false;
}
return content.document.documentURI.startsWith("about:reader");
},
get isReaderableAboutReader() {
return this.isAboutReader &&
!content.document.documentElement.dataset.isError;
},
handleEvent(aEvent) {
if (aEvent.originalTarget.defaultView != content) {
return;
}
switch (aEvent.type) {
case "AboutReaderContentLoaded":
if (!this.isAboutReader) {
return;
}
if (content.document.body) {
// Update the toolbar icon to show the "reader active" icon.
sendAsyncMessage("Reader:UpdateReaderButton");
new AboutReader(global, content, this._articlePromise);
this._articlePromise = null;
}
break;
case "pagehide":
this.cancelPotentialPendingReadabilityCheck();
// this._isLeavingReaderableReaderMode is used here to keep the Reader Mode icon
// visible in the location bar when transitioning from reader-mode page
// back to the readable source page.
sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: this._isLeavingReaderableReaderMode });
if (this._isLeavingReaderableReaderMode) {
this._isLeavingReaderableReaderMode = false;
}
break;
case "pageshow":
// If a page is loaded from the bfcache, we won't get a "DOMContentLoaded"
// event, so we need to rely on "pageshow" in this case.
if (aEvent.persisted) {
this.updateReaderButton();
}
break;
case "DOMContentLoaded":
this.updateReaderButton();
break;
}
},
/**
* NB: this function will update the state of the reader button asynchronously
* after the next mozAfterPaint call (assuming reader mode is enabled and
* this is a suitable document). Calling it on things which won't be
* painted is not going to work.
*/
updateReaderButton(forceNonArticle) {
if (!ReaderMode.isEnabledForParseOnLoad || this.isAboutReader ||
!content || !(content.document instanceof content.HTMLDocument) ||
content.document.mozSyntheticDocument) {
return;
}
this.scheduleReadabilityCheckPostPaint(forceNonArticle);
},
cancelPotentialPendingReadabilityCheck() {
if (this._pendingReadabilityCheck) {
removeEventListener("MozAfterPaint", this._pendingReadabilityCheck);
delete this._pendingReadabilityCheck;
}
},
scheduleReadabilityCheckPostPaint(forceNonArticle) {
if (this._pendingReadabilityCheck) {
// We need to stop this check before we re-add one because we don't know
// if forceNonArticle was true or false last time.
this.cancelPotentialPendingReadabilityCheck();
}
this._pendingReadabilityCheck = this.onPaintWhenWaitedFor.bind(this, forceNonArticle);
addEventListener("MozAfterPaint", this._pendingReadabilityCheck);
},
onPaintWhenWaitedFor(forceNonArticle, event) {
// In non-e10s, we'll get called for paints other than ours, and so it's
// possible that this page hasn't been laid out yet, in which case we
// should wait until we get an event that does relate to our layout. We
// determine whether any of our content got painted by checking if there
// are any painted rects.
if (!event.clientRects.length) {
return;
}
this.cancelPotentialPendingReadabilityCheck();
// Only send updates when there are articles; there's no point updating with
// |false| all the time.
if (ReaderMode.isProbablyReaderable(content.document)) {
sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: true });
} else if (forceNonArticle) {
sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: false });
}
},
};
AboutReaderListener.init();
var ContentSearchMediator = {
whitelist: new Set([
"about:home",
"about:newtab",
"about:welcome",
]),
init(chromeGlobal) {
chromeGlobal.addEventListener("ContentSearchClient", this, true, true);
addMessageListener("ContentSearch", this);
this.init = null;
},
handleEvent(event) {
if (this._contentWhitelisted) {
this._sendMsg(event.detail.type, event.detail.data);
}
},
receiveMessage(msg) {
if (msg.data.type == "AddToWhitelist") {
for (let uri of msg.data.data) {
this.whitelist.add(uri);
}
this._sendMsg("AddToWhitelistAck");
return;
}
if (this._contentWhitelisted) {
this._fireEvent(msg.data.type, msg.data.data);
}
},
get _contentWhitelisted() {
return this.whitelist.has(content.document.documentURI);
},
_sendMsg(type, data = null) {
sendAsyncMessage("ContentSearch", {
type,
data,
});
},
_fireEvent(type, data = null) {
let event = Cu.cloneInto({
detail: {
type,
data,
},
}, content);
content.dispatchEvent(new content.CustomEvent("ContentSearchService",
event));
},
};
ContentSearchMediator.init(this);
addMessageListener("PageStyle:Switch", PageStyleHandler);
addMessageListener("PageStyle:Disable", PageStyleHandler);
addEventListener("pageshow", PageStyleHandler);
// Keep a reference to the translation content handler to avoid it it being GC'ed.
var trHandler = null;
if (Services.prefs.getBoolPref("browser.translation.detectLanguage")) {
@@ -323,42 +45,6 @@ if (Services.prefs.getBoolPref("browser.translation.detectLanguage")) {
trHandler = new TranslationContentHandler(global, docShell);
}
function gKeywordURIFixup(fixupInfo) {
fixupInfo.QueryInterface(Ci.nsIURIFixupInfo);
if (!fixupInfo.consumer) {
return;
}
// Ignore info from other docshells
let parent = fixupInfo.consumer.QueryInterface(Ci.nsIDocShellTreeItem).sameTypeRootTreeItem;
if (parent != docShell)
return;
let data = {};
for (let f of Object.keys(fixupInfo)) {
if (f == "consumer" || typeof fixupInfo[f] == "function")
continue;
if (fixupInfo[f] && fixupInfo[f] instanceof Ci.nsIURI) {
data[f] = fixupInfo[f].spec;
} else {
data[f] = fixupInfo[f];
}
}
sendAsyncMessage("Browser:URIFixup", data);
}
Services.obs.addObserver(gKeywordURIFixup, "keyword-uri-fixup");
addEventListener("unload", () => {
Services.obs.removeObserver(gKeywordURIFixup, "keyword-uri-fixup");
}, false);
addMessageListener("Browser:AppTab", function(message) {
if (docShell) {
docShell.isAppTab = message.data.isAppTab;
}
});
var WebBrowserChrome = {
onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) {
return BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
@@ -391,131 +77,8 @@ if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
tabchild.webBrowserChrome = WebBrowserChrome;
}
var DOMFullscreenHandler = {
init() {
addMessageListener("DOMFullscreen:Entered", this);
addMessageListener("DOMFullscreen:CleanUp", this);
addEventListener("MozDOMFullscreen:Request", this);
addEventListener("MozDOMFullscreen:Entered", this);
addEventListener("MozDOMFullscreen:NewOrigin", this);
addEventListener("MozDOMFullscreen:Exit", this);
addEventListener("MozDOMFullscreen:Exited", this);
this.init = null;
},
receiveMessage(aMessage) {
let windowUtils = content && content.windowUtils;
switch (aMessage.name) {
case "DOMFullscreen:Entered": {
this._lastTransactionId = windowUtils.lastTransactionId;
if (!windowUtils.handleFullscreenRequests() &&
!content.document.fullscreenElement) {
// If we don't actually have any pending fullscreen request
// to handle, neither we have been in fullscreen, tell the
// parent to just exit.
sendAsyncMessage("DOMFullscreen:Exit");
}
break;
}
case "DOMFullscreen:CleanUp": {
// If we've exited fullscreen at this point, no need to record
// transaction id or call exit fullscreen. This is especially
// important for non-e10s, since in that case, it is possible
// that no more paint would be triggered after this point.
if (content.document.fullscreenElement && windowUtils) {
this._lastTransactionId = windowUtils.lastTransactionId;
windowUtils.exitFullscreen();
}
break;
}
}
},
handleEvent(aEvent) {
switch (aEvent.type) {
case "MozDOMFullscreen:Request": {
sendAsyncMessage("DOMFullscreen:Request");
break;
}
case "MozDOMFullscreen:NewOrigin": {
sendAsyncMessage("DOMFullscreen:NewOrigin", {
originNoSuffix: aEvent.target.nodePrincipal.originNoSuffix,
});
break;
}
case "MozDOMFullscreen:Exit": {
sendAsyncMessage("DOMFullscreen:Exit");
break;
}
case "MozDOMFullscreen:Entered":
case "MozDOMFullscreen:Exited": {
addEventListener("MozAfterPaint", this);
if (!content || !content.document.fullscreenElement) {
// If we receive any fullscreen change event, and find we are
// actually not in fullscreen, also ask the parent to exit to
// ensure that the parent always exits fullscreen when we do.
sendAsyncMessage("DOMFullscreen:Exit");
}
break;
}
case "MozAfterPaint": {
// Only send Painted signal after we actually finish painting
// the transition for the fullscreen change.
// Note that this._lastTransactionId is not set when in non-e10s
// mode, so we need to check that explicitly.
if (!this._lastTransactionId ||
aEvent.transactionId > this._lastTransactionId) {
removeEventListener("MozAfterPaint", this);
sendAsyncMessage("DOMFullscreen:Painted");
}
break;
}
}
}
};
DOMFullscreenHandler.init();
var UserContextIdNotifier = {
init() {
addEventListener("DOMWindowCreated", this);
this.init = null;
},
uninit() {
removeEventListener("DOMWindowCreated", this);
},
handleEvent(aEvent) {
// When the window is created, we want to inform the tabbrowser about
// the userContextId in use in order to update the UI correctly.
// Just because we cannot change the userContextId from an active docShell,
// we don't need to check DOMContentLoaded again.
this.uninit();
// We use the docShell because content.document can have been loaded before
// setting the originAttributes.
let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
let userContextId = loadContext.originAttributes.userContextId;
sendAsyncMessage("Browser:WindowCreated", { userContextId });
}
};
UserContextIdNotifier.init();
Services.obs.notifyObservers(this, "tab-content-frameloader-created");
addMessageListener("AllowScriptsToClose", () => {
content.windowUtils.allowScriptsToClose();
});
addEventListener("MozAfterPaint", function onFirstPaint() {
removeEventListener("MozAfterPaint", onFirstPaint);
sendAsyncMessage("Browser:FirstPaint");
});
// Remove this once bug 1397365 is fixed.
addEventListener("MozAfterPaint", function onFirstNonBlankPaint() {
if (content.document.documentURI == "about:blank" && !content.opener)
@@ -523,8 +86,3 @@ addEventListener("MozAfterPaint", function onFirstNonBlankPaint() {
removeEventListener("MozAfterPaint", onFirstNonBlankPaint);
sendAsyncMessage("Browser:FirstNonBlankPaint");
});
addMessageListener("DOM:WebManifest:hasManifestLink", ManifestMessages);
addMessageListener("DOM:ManifestObtainer:Obtain", ManifestMessages);
addMessageListener("DOM:Manifest:FireAppInstalledEvent", ManifestMessages);
addMessageListener("DOM:WebManifest:fetchIcon", ManifestMessages);

View File

@@ -1,7 +1,8 @@
function hideSelectPopup(selectPopup, mode = "enter", win = window) {
let browser = win.gBrowser.selectedBrowser;
let selectClosedPromise = ContentTask.spawn(browser, null, async function() {
ChromeUtils.import("resource://gre/modules/SelectContentHelper.jsm");
let {SelectContentHelper} =
ChromeUtils.import("resource://gre/actors/SelectChild.jsm", {});
return ContentTaskUtils.waitForCondition(() => !SelectContentHelper.open);
});

View File

@@ -712,15 +712,10 @@ async function promiseTab() {
tab.linkedBrowser.addEventListener("load", function onLoad(event) {
tab.linkedBrowser.removeEventListener("load", onLoad, true);
gMsgMan = tab.linkedBrowser.messageManager;
gMsgMan.sendAsyncMessage("ContentSearch", {
type: "AddToWhitelist",
data: [pageURL],
});
promiseMsg("ContentSearch", "AddToWhitelistAck", gMsgMan).then(() => {
let jsURL = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME;
gMsgMan.loadFrameScript(jsURL, false);
deferred.resolve(msg("init"));
});
let jsURL = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME;
gMsgMan.loadFrameScript(jsURL, false);
deferred.resolve(msg("init"));
}, true, true);
openTrustedLinkIn(pageURL, "current");
return deferred.promise;

View File

@@ -35,6 +35,8 @@ const startupPhases = {
]),
modules: new Set([
"resource://gre/modules/AppConstants.jsm",
"resource://gre/modules/ActorManagerParent.jsm",
"resource://gre/modules/ExtensionUtils.jsm",
"resource://gre/modules/XPCOMUtils.jsm",
"resource://gre/modules/Services.jsm",
])

View File

@@ -48,15 +48,17 @@ const whitelist = {
"resource://formautofill/FormAutofillContent.jsm",
// Browser front-end
"resource:///actors/AboutReaderChild.jsm",
"resource:///actors/BrowserTabChild.jsm",
"resource:///modules/ContentLinkHandler.jsm",
"resource:///modules/ContentMetaHandler.jsm",
"resource:///modules/PageStyleHandler.jsm",
"resource://gre/modules/BrowserUtils.jsm",
"resource:///actors/PageStyleChild.jsm",
"resource://gre/modules/ActorChild.jsm",
"resource://gre/modules/ActorManagerChild.jsm",
"resource://gre/modules/E10SUtils.jsm",
"resource://gre/modules/PrivateBrowsingUtils.jsm",
"resource://gre/modules/ReaderMode.jsm",
"resource://gre/modules/WebProgressChild.jsm",
"resource://gre/modules/WebNavigationChild.jsm",
// Pocket
"chrome://pocket/content/AboutPocket.jsm",

View File

@@ -8,6 +8,9 @@
// Slow on asan builds.
requestLongerTimeout(5);
ChromeUtils.defineModuleGetter(this, "ActorManagerParent",
"resource://gre/modules/ActorManagerParent.jsm");
var isDevtools = SimpleTest.harnessParameters.subsuite == "devtools";
var gExceptionPaths = [
@@ -160,6 +163,8 @@ var whitelist = [
// Bug 1463225 (on Mac this is only used by a test)
{file: "chrome://global/content/bindings/toolbar.xml",
platforms: ["macosx"]},
// Bug 1483277 (temporarily unreferenced)
{file: "chrome://browser/content/browser.xhtml"},
];
whitelist = new Set(whitelist.filter(item =>
@@ -415,7 +420,11 @@ function parseCodeFile(fileUri) {
// Make urls like chrome://browser/skin/ point to an actual file,
// and remove the ref if any.
url = Services.io.newURI(url).specIgnoringRef;
try {
url = Services.io.newURI(url).specIgnoringRef;
} catch (e) {
continue;
}
if (isDevtools && line.includes("require(") &&
!/\.(properties|js|jsm|json|css)$/.test(url))
@@ -502,6 +511,17 @@ function findChromeUrlsFromArray(array, prefix) {
}
}
function addActorModules() {
let groups = [...ActorManagerParent.parentGroups.values(),
...ActorManagerParent.childGroups.values(),
...ActorManagerParent.singletons.values()];
for (let group of groups) {
for (let {module} of group.actors.values()) {
gReferencesFromCode.set(module, null);
}
}
}
add_task(async function checkAllTheFiles() {
let libxulPath = OS.Constants.Path.libxul;
if (AppConstants.platform != "macosx")
@@ -539,6 +559,8 @@ add_task(async function checkAllTheFiles() {
// Wait for all manifest to be parsed
await throttledMapPromises(manifestURIs, parseManifest);
addActorModules();
// We build a list of promises that get resolved when their respective
// files have loaded and produced no errors.
let allPromises = [];

View File

@@ -64,12 +64,12 @@ function getBrowser(sidebar) {
document.documentElement.appendChild(stack);
return readyPromise.then(() => {
browser.messageManager.loadFrameScript("chrome://browser/content/content.js", false);
browser.messageManager.loadFrameScript("chrome://browser/content/content.js", false, true);
ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
if (sidebar.browserStyle) {
browser.messageManager.loadFrameScript(
"chrome://extensions/content/ext-browser-content.js", false);
"chrome://extensions/content/ext-browser-content.js", false, true);
browser.messageManager.sendAsyncMessage("Extension:InitBrowser", {
stylesheets: ExtensionParent.extensionStylesheets,

View File

@@ -29,6 +29,9 @@ browser.jar:
content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml)
* content/browser/browser.css (content/browser.css)
content/browser/browser.js (content/browser.js)
#ifdef MOZ_BROWSER_XHTML
* content/browser/browser.xhtml (content/browser.xhtml)
#endif
* content/browser/browser.xul (content/browser.xul)
content/browser/browser-addons.js (content/browser-addons.js)
content/browser/browser-allTabsMenu.js (content/browser-allTabsMenu.js)

View File

@@ -62,6 +62,7 @@ BROWSER_CHROME_MANIFESTS += [
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_VERSION_DISPLAY'] = CONFIG['MOZ_APP_VERSION_DISPLAY']
DEFINES['MOZ_BROWSER_XHTML'] = CONFIG['MOZ_BROWSER_XHTML']
DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR

View File

@@ -36,6 +36,4 @@ component {eab9012e-5f74-4cbc-b2b5-a590235513cc} nsBrowserGlue.js
contract @mozilla.org/browser/browserglue;1 {eab9012e-5f74-4cbc-b2b5-a590235513cc}
category app-startup nsBrowserGlue service,@mozilla.org/browser/browserglue;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110}
component {d8903bf6-68d5-4e97-bcd1-e4d3012f721a} nsBrowserGlue.js
#ifndef MOZ_MULET
contract @mozilla.org/content-permission/prompt;1 {d8903bf6-68d5-4e97-bcd1-e4d3012f721a}
#endif

View File

@@ -1,3 +1,141 @@
/* 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/. */
@import url("chrome://global/skin/in-content/common.css");
html {
height: 100%;
}
body {
display: flex;
align-items: stretch;
height: 100%;
}
#sectionTitle {
float: left;
}
#sectionTitle:dir(rtl) {
float: right;
}
/** Categories **/
.category {
cursor: pointer;
/* Center category names */
display: flex;
align-items: center;
}
.category .category-name {
pointer-events: none;
}
#categories hr {
border-top-color: rgba(255,255,255,0.15);
}
/** Content area **/
.main-content {
flex: 1;
}
.tab {
padding: 0.5em 0;
}
.tab table {
width: 100%;
}
th, td, table {
border-collapse: collapse;
border: none;
text-align: start;
}
th {
padding-bottom: 8px;
font-size: larger;
}
td {
padding-bottom: 8px;
}
.active-policies tr:nth-child(even) {
background-color: white;
}
.errors tr:nth-child(even) {
background-color: white;
}
/*
* In Documentation Tab, this property sets the policies row in an
* alternate color scheme of white and grey as each policy comprises
* of two tbody tags, one for the description and the other for the
* collapsible information block.
*/
tbody:nth-child(4n + 1) {
background-color: white;
}
.lastpolicyrow {
border-bottom: 3px solid #0c0c0d;
}
tr.lastpolicyrow td {
padding-bottom: 16px;
}
.array {
border-bottom: 1px solid var(--in-content-box-border-color);
padding-bottom: 4px;
}
.icon {
background-position: center center;
background-repeat: no-repeat;
background-size: 16px;
-moz-context-properties: fill;
display: inline-block;
fill: var(--newtab-icon-primary-color);
height: 14px;
vertical-align: middle;
width: 14px;
}
.icon.machine-only {
background-image: url("chrome://browser/skin/developer.svg");
}
.collapsible {
cursor: pointer;
border: none;
outline: none;
}
.content {
display: none;
}
.content-style {
background-color: white;
color: var(--in-content-category-text-selected);
}
tbody.collapsible td {
padding-bottom: 8px;
}
.schema {
font-family: monospace;
white-space: pre;
}

View File

@@ -2,3 +2,275 @@
* 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";
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
schema: "resource:///modules/policies/schema.jsm",
});
function col(text, className) {
let column = document.createElement("td");
if (className) {
column.classList.add(className);
}
let content = document.createTextNode(text);
column.appendChild(content);
return column;
}
function machine_only_col(text) {
let icon = document.createElement("span");
icon.classList.add("icon");
icon.classList.add("machine-only");
icon.title = "Machine-only";
let column = document.createElement("td");
let content = document.createTextNode(text);
column.appendChild(content);
column.appendChild(icon);
return column;
}
/*
* This function generates the Active Policies content to be displayed by calling
* a recursive function called generatePolicy() according to the policy schema.
*/
function generateActivePolicies(data) {
let new_cont = document.getElementById("activeContent");
new_cont.classList.add("active-policies");
for (let policyName in data) {
if (schema.properties[policyName].type == "array") {
for (let count in data[policyName]) {
let isFirstRow = (count == 0);
let isLastRow = (count == data[policyName].length - 1);
let row = document.createElement("tr");
row.appendChild(col(isFirstRow ? policyName : ""));
generatePolicy(data[policyName][count], row, 1, new_cont, isLastRow, !isFirstRow);
}
} else if (schema.properties[policyName].type == "object") {
let count = 0;
for (let obj in data[policyName]) {
let isFirstRow = (count == 0);
let isLastRow = (count == data[policyName].length - 1);
let row = document.createElement("tr");
row.appendChild(col(isFirstRow ? policyName : ""));
row.appendChild(col(obj));
generatePolicy(data[policyName][obj], row, 2, new_cont, isLastRow);
count++;
}
} else {
let row = document.createElement("tr");
row.appendChild(col(policyName));
row.appendChild(col(JSON.stringify(data[policyName])));
row.classList.add("lastpolicyrow");
new_cont.appendChild(row);
}
}
}
/*
* This is a helper recursive function that iterates levels of each
* policy and formats the content to be displayed accordingly.
*/
function generatePolicy(data, row, depth, new_cont, islast, arr_sep = false) {
if (Array.isArray(data)) {
for (let count in data) {
if (count == 0) {
if (count == data.length - 1) {
generatePolicy(data[count], row, depth + 1, new_cont, islast ? islast : false, false);
} else {
generatePolicy(data[count], row, depth + 1, new_cont, false, true);
}
} else if (count == data.length - 1) {
let last_row = document.createElement("tr");
for (let i = 0; i < depth; i++) {
last_row.appendChild(col(""));
}
generatePolicy(data[count], last_row, depth + 1, new_cont, islast ? islast : false, arr_sep);
} else {
let new_row = document.createElement("tr");
for (let i = 0; i < depth; i++) {
new_row.appendChild(col(""));
}
generatePolicy(data[count], new_row, depth + 1, new_cont, false, true);
}
}
} else if (typeof data == "object" && Object.keys(data).length > 0) {
let count = 0;
for (let obj in data) {
if (count == 0) {
row.appendChild(col(obj));
if (count == Object.keys(data).length - 1) {
generatePolicy(data[obj], row, depth + 1, new_cont, islast ? islast : false, arr_sep);
} else {
generatePolicy(data[obj], row, depth + 1, new_cont, false, false);
}
} else if (count == Object.keys(data).length - 1) {
let last_row = document.createElement("tr");
for (let i = 0; i < depth; i++) {
last_row.appendChild(col(""));
}
if (arr_sep) {
last_row.appendChild(col(obj, "array"));
} else {
last_row.appendChild(col(obj));
}
generatePolicy(data[obj], last_row, depth + 1, new_cont, islast ? islast : false, arr_sep);
} else {
let new_row = document.createElement("tr");
for (let i = 0; i < depth; i++) {
new_row.appendChild(col(""));
}
new_row.appendChild(col(obj));
generatePolicy(data[obj], new_row, depth + 1, new_cont, false, false);
}
count++;
}
} else {
if (arr_sep) {
row.appendChild(col(JSON.stringify(data), "array"));
} else {
row.appendChild(col(JSON.stringify(data)));
}
if (islast) {
row.classList.add("lastpolicyrow");
}
new_cont.appendChild(row);
}
}
function generateErrors() {
const consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
const storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
const consoleEvents = storage.getEvents();
const prefixes = ["Enterprise Policies",
"JsonSchemaValidator.jsm",
"Policies.jsm",
"GPOParser.jsm",
"Enterprise Policies Child",
"BookmarksPolicies.jsm",
"ProxyPolicies.jsm",
"WebsiteFilter Policy"];
let new_cont = document.getElementById("errorsContent");
new_cont.classList.add("errors");
let flag = false;
for (let err of consoleEvents) {
if (prefixes.includes(err.prefix)) {
flag = true;
let row = document.createElement("tr");
row.appendChild(col(err.arguments[0], "schema"));
new_cont.appendChild(row);
}
}
if (!flag) {
let errors_tab = document.getElementById("category-errors");
errors_tab.style.display = "none";
}
}
function generateDocumentation() {
let new_cont = document.getElementById("documentationContent");
new_cont.setAttribute("id", "documentationContent");
for (let policyName in schema.properties) {
let main_tbody = document.createElement("tbody");
main_tbody.classList.add("collapsible");
main_tbody.addEventListener("click", function() {
let content = this.nextElementSibling;
content.classList.toggle("content");
});
let row = document.createElement("tr");
if (schema.properties[policyName].machine_only) {
row.appendChild(machine_only_col(policyName));
} else {
row.appendChild(col(policyName));
}
row.appendChild(col(schema.properties[policyName].description));
main_tbody.appendChild(row);
let sec_tbody = document.createElement("tbody");
sec_tbody.classList.add("content");
sec_tbody.classList.add("content-style");
let schema_row = document.createElement("tr");
if (schema.properties[policyName].properties) {
let column = col(JSON.stringify(schema.properties[policyName].properties, null, 1), "schema");
column.colSpan = "2";
schema_row.appendChild(column);
sec_tbody.appendChild(schema_row);
} else {
let column = col("type: " + schema.properties[policyName].type, "schema");
column.colSpan = "2";
schema_row.appendChild(column);
sec_tbody.appendChild(schema_row);
if (schema.properties[policyName].enum) {
let enum_row = document.createElement("tr");
column = col("enum: " + JSON.stringify(schema.properties[policyName].enum, null, 1), "schema");
column.colSpan = "2";
enum_row.appendChild(column);
sec_tbody.appendChild(enum_row);
}
}
new_cont.appendChild(main_tbody);
new_cont.appendChild(sec_tbody);
}
}
let gInited = false;
function init() {
if (gInited) {
return;
}
gInited = true;
let data = Services.policies.getActivePolicies();
generateActivePolicies(data);
generateErrors();
generateDocumentation();
// Event delegation on #categories element
let menu = document.getElementById("categories");
menu.addEventListener("click", function click(e) {
if (e.target && e.target.parentNode == menu)
show(e.target);
});
if (location.hash) {
let sectionButton = document.getElementById("category-" + location.hash.substring(1));
if (sectionButton) {
sectionButton.click();
}
}
}
function show(button) {
let current_tab = document.querySelector(".active");
let category = button.getAttribute("id").substring("category-".length);
let content = document.getElementById(category);
if (current_tab == content)
return;
current_tab.classList.remove("active");
current_tab.hidden = true;
content.classList.add("active");
content.hidden = false;
let current_button = document.querySelector("[selected=true]");
current_button.removeAttribute("selected");
button.setAttribute("selected", "true");
let title = document.getElementById("sectionTitle");
title.textContent = button.children[0].textContent;
location.hash = category;
}

View File

@@ -7,11 +7,63 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="chrome://browser/content/policies/aboutPolicies.css" type="text/css" />
<script type="application/javascript" src="chrome://browser/content/policies/aboutPolicies.js" />
</head>
<head>
<title data-l10n-id="about-policies-title"/>
<link rel="stylesheet" href="chrome://browser/content/policies/aboutPolicies.css" type="text/css" />
<link rel="localization" href="browser/aboutPolicies.ftl"/>
<script type="application/javascript" src="chrome://global/content/l10n.js"></script>
<script type="application/javascript" src="chrome://browser/content/policies/aboutPolicies.js" />
</head>
<body id="body" onload="init()">
<div id="categories">
<div class="category" selected="true" id="category-active">
<span class="category-name" data-l10n-id="active-policies-tab"/>
</div>
<div class="category" id="category-documentation">
<span class="category-name" data-l10n-id="documentation-tab"/>
</div>
<div class="category" id="category-errors">
<span class="category-name" data-l10n-id="errors-tab"/>
</div>
</div>
<div class="main-content">
<div class="header">
<div id="sectionTitle" class="header-name" data-l10n-id="active-policies-tab"/>
</div>
<body>
</body>
<div id="active" class="tab active">
<table>
<thead>
<tr>
<th data-l10n-id="policy-name"/>
<th data-l10n-id="policy-value"/>
</tr>
</thead>
<tbody id="activeContent" />
</table>
</div>
<div id="documentation" class="tab" hidden="true">
<table>
<thead>
<tr>
<th data-l10n-id="policy-name"/>
</tr>
</thead>
<tbody id="documentationContent" />
</table>
</div>
<div id="errors" class="tab" hidden="true">
<table>
<thead>
<tr>
<th data-l10n-id="policy-errors"/>
</tr>
</thead>
<tbody id="errorsContent" />
</table>
</div>
</div>
</body>
</html>

View File

@@ -309,10 +309,10 @@ class BasePopup {
let mm = browser.messageManager;
// Sets the context information for context menus.
mm.loadFrameScript("chrome://browser/content/content.js", true);
mm.loadFrameScript("chrome://browser/content/content.js", true, true);
mm.loadFrameScript(
"chrome://extensions/content/ext-browser-content.js", false);
"chrome://extensions/content/ext-browser-content.js", false, true);
mm.sendAsyncMessage("Extension:InitBrowser", {
allowScriptsToClose: true,

View File

@@ -1,18 +1,17 @@
"use strict";
ChromeUtils.defineModuleGetter(this, "ContextMenuChild",
"resource:///actors/ContextMenuChild.jsm");
this.menusChild = class extends ExtensionAPI {
getAPI(context) {
return {
menus: {
getTargetElement(targetElementId) {
let tabChildGlobal = context.messageManager;
let {contextMenu} = tabChildGlobal;
let element;
if (contextMenu) {
let {lastMenuTarget} = contextMenu;
if (lastMenuTarget && Math.floor(lastMenuTarget.timeStamp) === targetElementId) {
element = lastMenuTarget.targetRef.get();
}
let lastMenuTarget = ContextMenuChild.getLastTarget(context.messageManager);
if (lastMenuTarget && Math.floor(lastMenuTarget.timeStamp) === targetElementId) {
element = lastMenuTarget.targetRef.get();
}
if (element && element.getRootNode({composed: true}) === context.contentWindow.document) {
return element;

View File

@@ -2,29 +2,26 @@
"use strict";
function frameScript() {
function getSelectedText() {
let frame = this.content.frames[0].frames[1];
let docShell = frame.docShell;
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
let selection = controller.getSelection(controller.SELECTION_FIND);
let range = selection.getRangeAt(0);
let scope = {};
ChromeUtils.import("resource://gre/modules/FindContent.jsm", scope);
let highlighter = (new scope.FindContent(docShell)).highlighter;
let r1 = frame.parent.frameElement.getBoundingClientRect();
let f1 = highlighter._getFrameElementOffsets(frame.parent);
let r2 = frame.frameElement.getBoundingClientRect();
let f2 = highlighter._getFrameElementOffsets(frame);
let r3 = range.getBoundingClientRect();
let rect = {
top: (r1.top + r2.top + r3.top + f1.y + f2.y),
left: (r1.left + r2.left + r3.left + f1.x + f2.x),
};
this.sendAsyncMessage("test:find:selectionTest", {text: selection.toString(), rect});
}
getSelectedText();
let frame = this.content.frames[0].frames[1];
let docShell = frame.docShell;
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
let selection = controller.getSelection(controller.SELECTION_FIND);
let range = selection.getRangeAt(0);
let scope = {};
ChromeUtils.import("resource://gre/modules/FindContent.jsm", scope);
let highlighter = (new scope.FindContent(docShell)).highlighter;
let r1 = frame.parent.frameElement.getBoundingClientRect();
let f1 = highlighter._getFrameElementOffsets(frame.parent);
let r2 = frame.frameElement.getBoundingClientRect();
let f2 = highlighter._getFrameElementOffsets(frame);
let r3 = range.getBoundingClientRect();
let rect = {
top: (r1.top + r2.top + r3.top + f1.y + f2.y),
left: (r1.left + r2.left + r3.left + f1.x + f2.x),
};
this.sendAsyncMessage("test:find:selectionTest", {text: selection.toString(), rect});
}
function waitForMessage(messageManager, topic) {
@@ -38,10 +35,10 @@ function waitForMessage(messageManager, topic) {
add_task(async function testDuplicatePinnedTab() {
async function background() {
function awaitLoad(tabId) {
function awaitLoad(tabId, url) {
return new Promise(resolve => {
browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
if (tabId == tabId_ && changed.status == "complete") {
if (tabId == tabId_ && changed.status == "complete" && tab.url == url) {
browser.tabs.onUpdated.removeListener(listener);
resolve();
}
@@ -51,7 +48,7 @@ add_task(async function testDuplicatePinnedTab() {
let url = "http://example.com/browser/browser/components/extensions/test/browser/file_find_frames.html";
let tab = await browser.tabs.update({url});
await awaitLoad(tab.id);
await awaitLoad(tab.id, url);
let data = await browser.find.find("banana", {includeRangeData: true});
let rangeData = data.rangeData;
@@ -144,8 +141,8 @@ add_task(async function testDuplicatePinnedTab() {
let {selectedBrowser} = gBrowser;
let frameScriptUrl = `data:,(${frameScript})()`;
selectedBrowser.messageManager.loadFrameScript(frameScriptUrl, false);
let frameScriptUrl = `data:,(${frameScript}).call(this)`;
selectedBrowser.messageManager.loadFrameScript(frameScriptUrl, false, true);
let message = await waitForMessage(selectedBrowser.messageManager, "test:find:selectionTest");
info("Test that text was highlighted properly.");

View File

@@ -407,6 +407,8 @@ add_task(async function test_show_hide_frame() {
},
async doOpenMenu() {
frameId = await ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
ChromeUtils.import("resource://gre/modules/WebNavigationFrames.jsm");
let {contentWindow} = content.document.getElementById("frame");
return WebNavigationFrames.getFrameId(contentWindow);
});

View File

@@ -119,7 +119,7 @@ add_task(async function test_on_created_navigation_target_from_mouse_click_subfr
await runCreatedNavigationTargetTest({
extension,
openNavTarget() {
BrowserTestUtils.synthesizeMouseAtCenter(function() {
BrowserTestUtils.synthesizeMouseAtCenter(() => {
// This code runs as a framescript in the child process and it returns the
// target link in the subframe.
return this.content.frames[0].document
@@ -138,7 +138,7 @@ add_task(async function test_on_created_navigation_target_from_mouse_click_subfr
await runCreatedNavigationTargetTest({
extension,
openNavTarget() {
BrowserTestUtils.synthesizeMouseAtCenter(function() {
BrowserTestUtils.synthesizeMouseAtCenter(() => {
// This code runs as a framescript in the child process and it returns the
// target link in the subframe.
return this.content.frames[0].document
@@ -157,7 +157,7 @@ add_task(async function test_on_created_navigation_target_from_mouse_click_subfr
await runCreatedNavigationTargetTest({
extension,
openNavTarget() {
BrowserTestUtils.synthesizeMouseAtCenter(function() {
BrowserTestUtils.synthesizeMouseAtCenter(() => {
// This code runs as a framescript in the child process and it returns the
// target link in the subframe.
return this.content.frames[0].document

View File

@@ -114,7 +114,7 @@ add_task(async function test_on_created_navigation_target_from_context_menu_subf
extension,
async openNavTarget() {
await clickContextMenuItem({
pageElementSelector: function() {
pageElementSelector: () => {
// This code runs as a framescript in the child process and it returns the
// target link in the subframe.
return this.content.frames[0]
@@ -136,7 +136,7 @@ add_task(async function test_on_created_navigation_target_from_context_menu_subf
extension,
async openNavTarget() {
await clickContextMenuItem({
pageElementSelector: function() {
pageElementSelector: () => {
// This code runs as a framescript in the child process and it returns the
// target link in the subframe.
return this.content.frames[0]

View File

@@ -66,11 +66,8 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'browsercompsbase'
EXTRA_PP_COMPONENTS += [
'BrowserComponents.manifest',
]
EXTRA_COMPONENTS += [
'BrowserComponents.manifest',
'nsBrowserContentHandler.js',
'nsBrowserGlue.js',
'tests/startupRecorder.js',

View File

@@ -8,6 +8,260 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.defineModuleGetter(this, "ActorManagerParent",
"resource://gre/modules/ActorManagerParent.jsm");
let ACTORS = {
AboutReader: {
child: {
module: "resource:///actors/AboutReaderChild.jsm",
group: "browsers",
events: {
"AboutReaderContentLoaded": {wantUntrusted: true},
"DOMContentLoaded": {},
"pageshow": {},
"pagehide": {},
},
messages: [
"Reader:ToggleReaderMode",
"Reader:PushState",
],
},
},
BlockedSite: {
child: {
module: "resource:///actors/BlockedSiteChild.jsm",
events: {
"AboutBlockedLoaded": {wantUntrusted: true},
"click": {},
},
matches: ["about:blocked?*"],
allFrames: true,
messages: [
"DeceptiveBlockedDetails",
],
},
},
BrowserTab: {
child: {
module: "resource:///actors/BrowserTabChild.jsm",
group: "browsers",
events: {
"DOMWindowCreated": {once: true},
"MozAfterPaint": {once: true},
"MozDOMPointerLock:Entered": {},
"MozDOMPointerLock:Exited": {},
},
messages: [
"AllowScriptsToClose",
"Browser:AppTab",
"Browser:HasSiblings",
"Browser:Reload",
"MixedContent:ReenableProtection",
"SwitchDocumentDirection",
"UpdateCharacterSet",
],
},
},
ClickHandler: {
child: {
module: "resource:///actors/ClickHandlerChild.jsm",
group: "browsers",
events: {
"click": {capture: true, mozSystemGroup: true},
}
},
},
ContextMenu: {
child: {
module: "resource:///actors/ContextMenuChild.jsm",
events: {
"contextmenu": {mozSystemGroup: true},
},
},
},
ContentSearch: {
child: {
module: "resource:///actors/ContentSearchChild.jsm",
group: "browsers",
matches: ["about:home", "about:newtab", "about:welcome",
"chrome://mochitests/content/*"],
events: {
"ContentSearchClient": {capture: true, wantUntrusted: true},
},
messages: [
"ContentSearch",
]
},
},
DOMFullscreen: {
child: {
module: "resource:///actors/DOMFullscreenChild.jsm",
group: "browsers",
events: {
"MozDOMFullscreen:Request": {},
"MozDOMFullscreen:Entered": {},
"MozDOMFullscreen:NewOrigin": {},
"MozDOMFullscreen:Exit": {},
"MozDOMFullscreen:Exited": {},
},
messages: [
"DOMFullscreen:Entered",
"DOMFullscreen:CleanUp",
]
},
},
LightWeightThemeInstall: {
child: {
module: "resource:///actors/LightWeightThemeInstallChild.jsm",
events: {
"InstallBrowserTheme": {wantUntrusted: true},
"PreviewBrowserTheme": {wantUntrusted: true},
"ResetBrowserThemePreview": {wantUntrusted: true},
},
},
},
NetError: {
child: {
module: "resource:///actors/NetErrorChild.jsm",
events: {
"AboutNetErrorLoad": {wantUntrusted: true},
"AboutNetErrorOpenCaptivePortal": {wantUntrusted: true},
"AboutNetErrorSetAutomatic": {wantUntrusted: true},
"AboutNetErrorResetPreferences": {wantUntrusted: true},
"click": {},
},
matches: ["about:certerror?*", "about:neterror?*"],
allFrames: true,
messages: [
"Browser:CaptivePortalFreed",
"CertErrorDetails",
],
},
},
OfflineApps: {
child: {
module: "resource:///actors/OfflineAppsChild.jsm",
events: {
"MozApplicationManifest": {},
},
messages: [
"OfflineApps:StartFetching",
],
},
},
PageInfo: {
child: {
module: "resource:///actors/PageInfoChild.jsm",
messages: ["PageInfo:getData"],
},
},
PageMetadata: {
child: {
module: "resource:///actors/PageMetadataChild.jsm",
messages: [
"PageMetadata:GetPageData",
"PageMetadata:GetMicroformats",
],
},
},
PageStyle: {
child: {
module: "resource:///actors/PageStyleChild.jsm",
group: "browsers",
events: {
"pageshow": {},
},
messages: [
"PageStyle:Switch",
"PageStyle:Disable",
]
},
},
Plugin: {
child: {
module: "resource:///actors/PluginChild.jsm",
events: {
"PluginBindingAttached": {capture: true, wantUntrusted: true},
"PluginCrashed": {capture: true},
"PluginOutdated": {capture: true},
"PluginInstantiated": {capture: true},
"PluginRemoved": {capture: true},
"HiddenPlugin": {capture: true},
},
messages: [
"BrowserPlugins:ActivatePlugins",
"BrowserPlugins:NotificationShown",
"BrowserPlugins:ContextMenuCommand",
"BrowserPlugins:NPAPIPluginProcessCrashed",
"BrowserPlugins:CrashReportSubmitted",
"BrowserPlugins:Test:ClearCrashData",
],
observers: [
"decoder-doctor-notification",
],
},
},
ShieldFrame: {
child: {
module: "resource://normandy-content/ShieldFrameChild.jsm",
events: {
"ShieldPageEvent": {wantUntrusted: true},
},
matches: ["about:studies"],
},
},
UITour: {
child: {
module: "resource:///modules/UITourChild.jsm",
events: {
"mozUITour": {wantUntrusted: true},
},
permissions: ["uitour"],
},
},
URIFixup: {
child: {
module: "resource:///actors/URIFixupChild.jsm",
group: "browsers",
observers: ["keyword-uri-fixup"],
},
},
WebRTC: {
child: {
module: "resource:///actors/WebRTCChild.jsm",
messages: [
"rtcpeer:Allow",
"rtcpeer:Deny",
"webrtc:Allow",
"webrtc:Deny",
"webrtc:StopSharing",
],
},
},
};
(function earlyBlankFirstPaint() {
if (!Services.prefs.getBoolPref("browser.startup.blankWindow", false))
return;
@@ -646,6 +900,9 @@ BrowserGlue.prototype = {
os.addObserver(this, "handlersvc-store-initialized");
os.addObserver(this, "shield-init-complete");
ActorManagerParent.addActors(ACTORS);
ActorManagerParent.flush();
this._flashHangCount = 0;
this._firstWindowReady = new Promise(resolve => this._firstWindowLoaded = resolve);
if (AppConstants.platform == "win") {

View File

@@ -17,6 +17,7 @@
]>
<page id="bookmarksPanel"
class="sidebar-panel"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="init();"

View File

@@ -17,6 +17,7 @@
]>
<page id="history-panel"
class="sidebar-panel"
orient="vertical"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="HistorySidebarInit();"

View File

@@ -1101,7 +1101,7 @@ var SessionStoreInternal = {
});
// Load the frame script after registering listeners.
mm.loadFrameScript("chrome://browser/content/content-sessionStore.js", true);
mm.loadFrameScript("chrome://browser/content/content-sessionStore.js", true, true);
// and create its data object
this._windows[aWindow.__SSi] = { tabs: [], selected: 0, _closedTabs: [], busy: false };

View File

@@ -29,8 +29,8 @@ function frameScript() {
};
};
mm.sendAsyncMessage = wrap(mm.sendAsyncMessage);
mm.sendSyncMessage = wrap(mm.sendSyncMessage);
mm.sendAsyncMessage = wrap(mm.sendAsyncMessage.bind(mm));
mm.sendSyncMessage = wrap(mm.sendSyncMessage.bind(mm));
}
add_task(async function() {

View File

@@ -2,18 +2,15 @@
* 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/. */
var EXPORTED_SYMBOLS = ["UITourListener"];
var EXPORTED_SYMBOLS = ["UITourChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
const PREF_TEST_WHITELIST = "browser.uitour.testingOrigins";
const UITOUR_PERMISSION = "uitour";
class UITourListener {
constructor(mm) {
this.mm = mm;
}
class UITourChild extends ActorChild {
handleEvent(event) {
if (!Services.prefs.getBoolPref("browser.uitour.enabled")) {
return;

View File

@@ -3,8 +3,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [
'ContentUITour.jsm',
'UITour.jsm',
'UITourChild.jsm',
]
BROWSER_CHROME_MANIFESTS += [

View File

@@ -40,7 +40,11 @@ MOZ_ENABLE_SIGNMAR=1
MOZ_APP_VERSION=$FIREFOX_VERSION
MOZ_APP_VERSION_DISPLAY=$FIREFOX_VERSION_DISPLAY
BROWSER_CHROME_URL=chrome://browser/content/browser.xul
if [ "${MOZ_BROWSER_XHTML}" = "1" ]; then
BROWSER_CHROME_URL=chrome://browser/content/browser.xhtml
else
BROWSER_CHROME_URL=chrome://browser/content/browser.xul
fi
# MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
# MOZ_BRANDING_DIRECTORY is the default branding directory used when none is

View File

@@ -131,7 +131,7 @@ function startup(data) {
ChromeUtils.import("resource://formautofill/FormAutofillContent.jsm");
}, true);
/* eslint-enable no-unused-vars */
Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillFrameScript.js", true);
Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillFrameScript.js", true, true);
}
function shutdown() {

View File

@@ -174,7 +174,7 @@ function onBrowserReady() {
OnboardingTourType.check();
OnboardingTelemetry.init(startupData);
Services.mm.loadFrameScript("resource://onboarding/onboarding.js", true);
Services.mm.loadFrameScript("resource://onboarding/onboarding.js", true, true);
initContentMessageListener();
}

View File

@@ -381,6 +381,8 @@
; Modules
@RESPATH@/browser/modules/*
@RESPATH@/modules/*
@RESPATH@/browser/actors/*
@RESPATH@/actors/*
; Safe Browsing
@RESPATH@/components/nsURLClassifier.manifest

View File

@@ -0,0 +1,14 @@
# 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/.
about-policies-title = Enterprise Policies
# 'Active' is used to describe the policies that are currently active
active-policies-tab = Active
errors-tab = Errors
documentation-tab = Documentation
policy-name = Policy Name
policy-value = Policy Value
policy-errors = Policy Errors

View File

@@ -17,8 +17,8 @@
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "ContentWebRTC",
"resource:///modules/ContentWebRTC.jsm");
ChromeUtils.defineModuleGetter(this, "WebRTCChild",
"resource:///actors/WebRTCChild.jsm");
var gEMEUIObserver = function(subject, topic, data) {
let win = subject.top;
@@ -44,7 +44,7 @@ Services.obs.addObserver(gEMEUIObserver, "mediakeys-request");
Services.obs.addObserver(gDecoderDoctorObserver, "decoder-doctor-notification");
// ContentWebRTC observer registration.
// WebRTCChild observer registration.
const kWebRTCObserverTopics = ["getUserMedia:request",
"recording-device-stopped",
"PeerConnection:request",
@@ -52,7 +52,7 @@ const kWebRTCObserverTopics = ["getUserMedia:request",
"recording-window-ended"];
function webRTCObserve(aSubject, aTopic, aData) {
ContentWebRTC.observe(aSubject, aTopic, aData);
WebRTCChild.observe(aSubject, aTopic, aData);
}
for (let topic of kWebRTCObserverTopics) {

View File

@@ -55,9 +55,6 @@ with Files("ContentCrashHandlers.jsm"):
with Files("ContentSearch.jsm"):
BUG_COMPONENT = ("Firefox", "Search")
with Files("ContentWebRTC.jsm"):
BUG_COMPONENT = ("Firefox", "Device Permissions")
with Files("ExtensionsUI.jsm"):
BUG_COMPONENT = ("WebExtensions", "General")
@@ -67,24 +64,12 @@ with Files("LaterRun.jsm"):
with Files("LightweightThemeChildHelper.jsm"):
BUG_COMPONENT = ("WebExtensions", "Themes")
with Files("LightWeightThemeWebInstallListener.jsm"):
BUG_COMPONENT = ("Firefox", "Theme")
with Files("OpenInTabsUtils.jsm"):
BUG_COMPONENT = ("Firefox", "Tabbed Browser")
with Files("PageInfoListener.jsm"):
BUG_COMPONENT = ("Firefox", "Page Info Window")
with Files("PageStyleHandler.jsm"):
BUG_COMPONENT = ("Firefox", "Menus")
with Files("PermissionUI.jsm"):
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
with Files("PluginContent.jsm"):
BUG_COMPONENT = ("Core", "Plug-ins")
with Files("ProcessHangMonitor.jsm"):
BUG_COMPONENT = ("Core", "DOM: Content Processes")
@@ -134,19 +119,15 @@ XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
EXTRA_JS_MODULES += [
'AboutNewTab.jsm',
'AsyncTabSwitcher.jsm',
'BlockedSiteContent.jsm',
'BrowserErrorReporter.jsm',
'BrowserUsageTelemetry.jsm',
'BrowserWindowTracker.jsm',
'ClickEventHandler.jsm',
'ContentClick.jsm',
'ContentCrashHandlers.jsm',
'ContentLinkHandler.jsm',
'ContentMetaHandler.jsm',
'ContentObservers.js',
'ContentSearch.jsm',
'ContentWebRTC.jsm',
'ContextMenu.jsm',
'ExtensionsUI.jsm',
'Feeds.jsm',
'FormSubmitObserver.jsm',
@@ -154,15 +135,10 @@ EXTRA_JS_MODULES += [
'HomePage.jsm',
'LaterRun.jsm',
'LightweightThemeChildHelper.jsm',
'LightWeightThemeWebInstallListener.jsm',
'NetErrorContent.jsm',
'OpenInTabsUtils.jsm',
'PageActions.jsm',
'PageInfoListener.jsm',
'PageStyleHandler.jsm',
'PermissionUI.jsm',
'PingCentre.jsm',
'PluginContent.jsm',
'ProcessHangMonitor.jsm',
'ReaderParent.jsm',
'RemotePrompt.jsm',

View File

@@ -15,6 +15,10 @@ Services.scriptloader.loadSubScript(
let originalEngine = Services.search.currentEngine;
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [["browser.newtab.preload", false]],
});
await promiseNewEngine("testEngine.xml", {
setAsCurrent: true,
testPath: "chrome://mochitests/content/browser/browser/components/search/test/",
@@ -346,18 +350,11 @@ function waitForNewEngine(basename, numImages) {
}
async function addTab() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab");
registerCleanupFunction(() => gBrowser.removeTab(tab));
let url = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME;
gMsgMan = tab.linkedBrowser.messageManager;
gMsgMan.sendAsyncMessage(CONTENT_SEARCH_MSG, {
type: "AddToWhitelist",
data: ["about:blank"],
});
await waitForMsg(CONTENT_SEARCH_MSG, "AddToWhitelistAck");
gMsgMan.loadFrameScript(url, false);
}

View File

@@ -12,6 +12,7 @@ with Files('docs/**'):
SCHEDULES.exclusive = ['docs']
DIRS += [
'actors',
'base',
'components',
'fonts',

View File

@@ -4,11 +4,7 @@
/* Sidebars */
#history-panel,
#bookmarksPanel {
-moz-appearance: none;
background-color: transparent;
}
%include ../../shared/places/places.inc.css
#sidebar-search-container {
padding: 8px;
@@ -19,26 +15,14 @@
}
#viewButton {
-moz-appearance: none;
border-radius: 4px;
margin: 1px 0;
margin-inline-start: 4px;
padding: 2px 4px;
color: inherit;
}
#viewButton:-moz-focusring:not(:hover):not([open]) {
outline: 1px dotted -moz-DialogText;
}
#viewButton:hover {
background: hsla(240, 5%, 5%, 0.1);
}
#viewButton[open] {
background: hsla(240, 5%, 5%, 0.15);
}
.sidebar-placesTree {
margin: 0;
color: inherit;

View File

@@ -4,11 +4,7 @@
/* Sidebars */
#bookmarksPanel,
#history-panel {
-moz-appearance: none;
background-color: transparent;
}
%include ../../shared/places/places.inc.css
.sidebar-placesTree,
.sidebar-placesTreechildren::-moz-tree-row {
@@ -57,10 +53,6 @@
font-weight: bold;
}
#sidebar-search-label {
display: none;
}
#sidebar-search-container {
/* Native searchbar styling already adds 4px margin on Mac, so
* adding 4px padding results in 8px of total whitespace. */
@@ -81,9 +73,6 @@
}
#viewButton {
-moz-appearance: none;
border-radius: 4px;
padding: 2px 4px;
margin: 4px 0;
margin-inline-end: 4px;
/* Default font size is 11px on mac, so this is 12px */
@@ -94,21 +83,6 @@
box-shadow: var(--focus-ring-box-shadow);
}
#viewButton:hover {
background: hsla(240, 5%, 5%, 0.1);
}
#viewButton[open] {
background: hsla(240, 5%, 5%, 0.15);
}
#viewButton > .button-box > .button-menu-dropmarker {
display: -moz-box;
list-style-image: url("chrome://global/skin/icons/arrow-dropdown-12.svg");
width: 12px;
height: 12px;
}
/* Trees */
%include ../../shared/places/tree-icons.inc.css

View File

@@ -0,0 +1,33 @@
/* 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/. */
.sidebar-panel {
-moz-appearance: none;
background-color: transparent;
}
#viewButton {
-moz-appearance: none;
border-radius: 4px;
padding: 2px 4px;
color: inherit;
}
#viewButton:hover {
background-color: hsla(240, 5%, 5%, .1);
}
#viewButton[open] {
background-color: hsla(240, 5%, 5%, .15);
}
#viewButton > .button-box > .button-menu-dropmarker {
-moz-appearance: none !important;
display: -moz-box;
list-style-image: url("chrome://global/skin/icons/arrow-dropdown-12.svg");
width: 12px;
height: 12px;
-moz-context-properties: fill;
fill: currentColor;
}

View File

@@ -4,10 +4,7 @@
/* Sidebars */
#history-panel,
#bookmarksPanel {
background-color: transparent;
}
%include ../../shared/places/places.inc.css
.sidebar-placesTree {
-moz-appearance: none;
@@ -55,26 +52,11 @@
/* Default button vert. margins are 1px/2px, and this can cause misalignment */
#viewButton {
-moz-appearance: none;
margin: 0;
margin-inline-start: 4px;
border-radius: 2px;
}
#viewButton:hover {
background-color: hsla(240, 5%, 5%, .1);
}
#viewButton[open] {
background-color: hsla(240, 5%, 5%, .15);
}
#viewButton > .button-box > .button-menu-dropmarker {
height: auto;
width: auto;
margin-inline-end: -3px;
}
#sidebar-search-container {
padding: 8px;
}

View File

@@ -631,6 +631,7 @@ support-files =
examples/doc_rr_basic.html
examples/doc_rr_continuous.html
examples/doc_rr_recovery.html
examples/doc_rr_error.html
[browser_dbg-asm.js]
[browser_dbg-async-stepping.js]
@@ -748,3 +749,5 @@ skip-if = os != "mac" || debug || !nightly_build
skip-if = os != "mac" || debug || !nightly_build
[browser_dbg_rr_replay-03.js]
skip-if = os != "mac" || debug || !nightly_build
[browser_dbg_rr_console_warp-01.js]
skip-if = os != "mac" || debug || !nightly_build

View File

@@ -0,0 +1,83 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var { HUDService } = require("devtools/client/webconsole/hudservice");
// This functionality was copied from devtools/client/webconsole/test/mochitest/head.js,
// since this test straddles both the web console and the debugger. I couldn't
// figure out how to load that script directly here.
function findMessages(hud, text, selector = ".message") {
const messages = hud.ui.outputNode.querySelectorAll(selector);
const elements = Array.prototype.filter.call(
messages,
(el) => el.textContent.includes(text)
);
return elements;
}
async function openContextMenu(hud, element) {
const onConsoleMenuOpened = hud.ui.consoleOutput.once("menu-open");
synthesizeContextMenuEvent(element);
await onConsoleMenuOpened;
const doc = hud.ui.consoleOutput.owner.chromeWindow.document;
return doc.getElementById("webconsole-menu");
}
function hideContextMenu(hud) {
const doc = hud.ui.consoleOutput.owner.chromeWindow.document;
const popup = doc.getElementById("webconsole-menu");
if (!popup) {
return Promise.resolve();
}
const onPopupHidden = once(popup, "popuphidden");
popup.hidePopup();
return onPopupHidden;
}
// Test basic console time warping functionality in web replay.
async function test() {
waitForExplicitFinish();
let tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" });
gBrowser.selectedTab = tab;
openTrustedLinkIn(EXAMPLE_URL + "doc_rr_error.html", "current");
await once(Services.ppmm, "RecordingFinished");
let console = await openToolboxForTab(tab, "webconsole");
let hud = console.getCurrentPanel().hud;
let messages = findMessages(hud, "Number 5");
ok(messages.length == 1, "Found one message");
let message = messages.pop();
let menuPopup = await openContextMenu(hud, message);
let timeWarpItem = menuPopup.querySelector("#console-menu-time-warp");
ok(timeWarpItem, "Time warp menu item is available");
timeWarpItem.click();
await hideContextMenu(hud);
await once(Services.ppmm, "TimeWarpFinished");
let toolbox = await attachDebugger(tab), client = toolbox.threadClient;
await client.interrupt();
await checkEvaluateInTopFrame(client, "number", 5);
// Initially we are paused inside the 'new Error()' call on line 19. The
// first reverse step takes us to the start of that line.
await reverseStepOverToLine(client, 19);
await reverseStepOverToLine(client, 18);
await setBreakpoint(client, "doc_rr_error.html", 12);
await rewindToLine(client, 12);
await checkEvaluateInTopFrame(client, "number", 4);
await resumeToLine(client, 12);
await checkEvaluateInTopFrame(client, "number", 5);
await toolbox.destroy();
await gBrowser.removeTab(tab);
finish();
}

View File

@@ -0,0 +1,23 @@
<html lang="en" dir="ltr">
<body>
<div id="maindiv">Hello World!</div>
</body>
<script>
const cpmm = SpecialPowers.Services.cpmm;
function recordingFinished() {
cpmm.sendAsyncMessage("RecordingFinished");
}
var number = 0;
function f() {
number++;
document.getElementById("maindiv").innerHTML = "Number: " + number;
if (number >= 10) {
window.setTimeout(recordingFinished);
return;
}
window.setTimeout(f, 1);
throw new Error("Number " + number);
}
window.setTimeout(f, 1);
</script>
</html>

View File

@@ -132,7 +132,7 @@ ChildSHistory::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
nsISupports*
ChildSHistory::GetParentObject() const
{
// We want to get the TabChildGlobal, which is the
// We want to get the TabChildMessageManager, which is the
// messageManager on mDocShell.
RefPtr<ContentFrameMessageManager> mm;
if (mDocShell) {

View File

@@ -0,0 +1,25 @@
/* -*- 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 "ContentFrameMessageManager.h"
#include "mozilla/dom/ScriptSettings.h"
using namespace mozilla;
using namespace mozilla::dom;
JSObject*
ContentFrameMessageManager::GetOrCreateWrapper()
{
AutoJSAPI jsapi;
jsapi.Init();
JS::RootedValue val(jsapi.cx());
if (!GetOrCreateDOMReflectorNoWrap(jsapi.cx(), this, &val)) {
return nullptr;
}
MOZ_ASSERT(val.isObject());
return &val.toObject();
}

View File

@@ -11,6 +11,7 @@
#include "mozilla/dom/MessageManagerGlobal.h"
#include "mozilla/dom/ResolveSystemBinding.h"
#include "nsContentUtils.h"
#include "xpcpublic.h"
namespace mozilla {
namespace dom {
@@ -25,30 +26,6 @@ public:
using DOMEventTargetHelper::AddRef;
using DOMEventTargetHelper::Release;
bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
JS::Handle<jsid> aId,
JS::MutableHandle<JS::PropertyDescriptor> aDesc)
{
bool found;
if (!SystemGlobalResolve(aCx, aObj, aId, &found)) {
return false;
}
if (found) {
FillPropertyDescriptor(aDesc, aObj, JS::UndefinedValue(), false);
}
return true;
}
static bool MayResolve(jsid aId)
{
return MayResolveAsSystemBindingName(aId);
}
void GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames,
bool aEnumerableOnly, mozilla::ErrorResult& aRv)
{
JS::Rooted<JSObject*> thisObj(aCx, GetWrapper());
GetSystemBindingNames(aCx, thisObj, aNames, aEnumerableOnly, aRv);
}
virtual already_AddRefed<nsPIDOMWindowOuter> GetContent(ErrorResult& aError) = 0;
virtual already_AddRefed<nsIDocShell> GetDocShell(ErrorResult& aError) = 0;
virtual already_AddRefed<nsIEventTarget> GetTabEventTarget() = 0;
@@ -64,9 +41,12 @@ public:
mMessageManager = nullptr;
}
JSObject* GetOrCreateWrapper();
protected:
explicit ContentFrameMessageManager(nsFrameMessageManager* aMessageManager)
: MessageManagerGlobal(aMessageManager)
: DOMEventTargetHelper(xpc::NativeGlobal(xpc::PrivilegedJunkScope()))
, MessageManagerGlobal(aMessageManager)
{}
};

View File

@@ -0,0 +1,139 @@
/* -*- 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 "ContentProcessMessageManager.h"
#include "nsContentCID.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/MessageManagerBinding.h"
#include "mozilla/dom/ParentProcessMessageManager.h"
#include "mozilla/dom/ResolveSystemBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/ipc/SharedMap.h"
using namespace mozilla;
using namespace mozilla::dom;
bool ContentProcessMessageManager::sWasCreated = false;
ContentProcessMessageManager::ContentProcessMessageManager(nsFrameMessageManager* aMessageManager)
: MessageManagerGlobal(aMessageManager),
mInitialized(false)
{
mozilla::HoldJSObjects(this);
}
ContentProcessMessageManager::~ContentProcessMessageManager()
{
mAnonymousGlobalScopes.Clear();
mozilla::DropJSObjects(this);
}
ContentProcessMessageManager*
ContentProcessMessageManager::Get()
{
nsCOMPtr<nsIMessageSender> service = do_GetService(NS_CHILDPROCESSMESSAGEMANAGER_CONTRACTID);
if (!service) {
return nullptr;
}
sWasCreated = true;
return static_cast<ContentProcessMessageManager*>(service.get());
}
already_AddRefed<mozilla::dom::ipc::SharedMap>
ContentProcessMessageManager::SharedData()
{
if (ContentChild* child = ContentChild::GetSingleton()) {
return do_AddRef(child->SharedData());
}
auto* ppmm = nsFrameMessageManager::sParentProcessManager;
return do_AddRef(ppmm->SharedData()->GetReadOnly());
}
bool
ContentProcessMessageManager::WasCreated()
{
return sWasCreated;
}
void
ContentProcessMessageManager::MarkForCC()
{
MarkScopesForCC();
MessageManagerGlobal::MarkForCC();
}
NS_IMPL_CYCLE_COLLECTION_CLASS(ContentProcessMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ContentProcessMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ContentProcessMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ContentProcessMessageManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
tmp->nsMessageManagerScriptExecutor::Unlink();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentProcessMessageManager)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMessageSender)
NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(ContentProcessMessageManager)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ContentProcessMessageManager)
bool
ContentProcessMessageManager::Init()
{
if (mInitialized) {
return true;
}
mInitialized = true;
return nsMessageManagerScriptExecutor::Init();
}
JSObject*
ContentProcessMessageManager::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return ContentProcessMessageManager_Binding::Wrap(aCx, this, aGivenProto);
}
JSObject*
ContentProcessMessageManager::GetOrCreateWrapper()
{
AutoJSAPI jsapi;
jsapi.Init();
JS::RootedValue val(jsapi.cx());
if (!GetOrCreateDOMReflectorNoWrap(jsapi.cx(), this, &val)) {
return nullptr;
}
return &val.toObject();
}
void
ContentProcessMessageManager::LoadScript(const nsAString& aURL)
{
Init();
JS::Rooted<JSObject*> messageManager(mozilla::dom::RootingCx(), GetOrCreateWrapper());
LoadScriptInternal(messageManager, aURL, true);
}
void
ContentProcessMessageManager::SetInitialProcessData(JS::HandleValue aInitialData)
{
mMessageManager->SetInitialProcessData(aInitialData);
}

View File

@@ -4,23 +4,21 @@
* 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_ProcessGlobal_h
#define mozilla_dom_ProcessGlobal_h
#ifndef mozilla_dom_ContentProcessMessageManager_h
#define mozilla_dom_ContentProcessMessageManager_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/MessageManagerGlobal.h"
#include "nsCOMPtr.h"
#include "nsFrameMessageManager.h"
#include "nsIScriptContext.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIScriptContext.h"
#include "nsIClassInfo.h"
#include "nsIRunnable.h"
#include "nsIGlobalObject.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsServiceManagerUtils.h"
#include "nsWeakReference.h"
#include "nsWrapperCache.h"
#include "xpcpublic.h"
namespace mozilla {
namespace dom {
@@ -29,47 +27,41 @@ namespace ipc {
class SharedMap;
}
class ProcessGlobal :
/**
* This class implements a singleton process message manager for content
* processes. Each child process has exactly one instance of this class, which
* hosts the process's process scripts, and may exchange messages with its
* corresponding ParentProcessMessageManager on the parent side.
*/
class ContentProcessMessageManager :
public nsIMessageSender,
public nsMessageManagerScriptExecutor,
public nsIGlobalObject,
public nsIScriptObjectPrincipal,
public nsSupportsWeakReference,
public ipc::MessageManagerCallback,
public MessageManagerGlobal,
public nsWrapperCache
{
public:
explicit ProcessGlobal(nsFrameMessageManager* aMessageManager);
bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
JS::Handle<jsid> aId,
JS::MutableHandle<JS::PropertyDescriptor> aDesc);
static bool MayResolve(jsid aId);
void GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames,
bool aEnumerableOnly, ErrorResult& aRv);
explicit ContentProcessMessageManager(nsFrameMessageManager* aMessageManager);
using ipc::MessageManagerCallback::GetProcessMessageManager;
using MessageManagerGlobal::GetProcessMessageManager;
bool Init();
static ProcessGlobal* Get();
static ContentProcessMessageManager* Get();
static bool WasCreated();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(ProcessGlobal, nsIMessageSender)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(ContentProcessMessageManager, nsIMessageSender)
void MarkForCC();
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override
{
MOZ_CRASH("We should never get here!");
}
virtual bool WrapGlobalObject(JSContext* aCx,
JS::RealmOptions& aOptions,
JS::MutableHandle<JSObject*> aReflector) override;
JS::Handle<JSObject*> aGivenProto) override;
JSObject* GetOrCreateWrapper();
using MessageManagerGlobal::AddMessageListener;
using MessageManagerGlobal::RemoveMessageListener;
@@ -92,13 +84,9 @@ public:
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
virtual void LoadScript(const nsAString& aURL);
nsIGlobalObject* GetParentObject() const { return xpc::NativeGlobal(xpc::PrivilegedJunkScope()); }
virtual JSObject* GetGlobalJSObject() override
{
return GetWrapper();
}
virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; }
virtual void LoadScript(const nsAString& aURL);
bool IsProcessScoped() const override
{
@@ -108,7 +96,7 @@ public:
void SetInitialProcessData(JS::HandleValue aInitialData);
protected:
virtual ~ProcessGlobal();
virtual ~ContentProcessMessageManager();
private:
bool mInitialized;
@@ -119,4 +107,4 @@ private:
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ProcessGlobal_h
#endif // mozilla_dom_ContentProcessMessageManager_h

View File

@@ -14,6 +14,7 @@
#include "mozilla/dom/WebComponentsBinding.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/CustomEvent.h"
#include "mozilla/dom/ShadowRoot.h"
#include "nsHTMLTags.h"
#include "jsapi.h"
#include "xpcprivate.h"

View File

@@ -6,6 +6,7 @@
#include "DocumentOrShadowRoot.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/StyleSheetList.h"
#include "nsDocument.h"
#include "nsFocusManager.h"

View File

@@ -4,7 +4,7 @@
* 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 "nsInProcessTabChildGlobal.h"
#include "InProcessTabChildMessageManager.h"
#include "nsContentUtils.h"
#include "nsIScriptSecurityManager.h"
#include "nsIInterfaceRequestorUtils.h"
@@ -25,13 +25,13 @@ using namespace mozilla::dom;
using namespace mozilla::dom::ipc;
bool
nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
bool aIsSync)
InProcessTabChildMessageManager::DoSendBlockingMessage(JSContext* aCx,
const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
bool aIsSync)
{
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
queue->Flush();
@@ -52,7 +52,7 @@ class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase,
public:
nsAsyncMessageToParent(JS::RootingContext* aRootingCx,
JS::Handle<JSObject*> aCpows,
nsInProcessTabChildGlobal* aTabChild)
InProcessTabChildMessageManager* aTabChild)
: nsSameProcessAsyncMessageBase(aRootingCx, aCpows)
, mTabChild(aTabChild)
{ }
@@ -63,15 +63,15 @@ public:
ReceiveMessage(mTabChild->mOwner, fl, mTabChild->mChromeMessageManager);
return NS_OK;
}
RefPtr<nsInProcessTabChildGlobal> mTabChild;
RefPtr<InProcessTabChildMessageManager> mTabChild;
};
nsresult
nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal)
InProcessTabChildMessageManager::DoSendAsyncMessage(JSContext* aCx,
const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal)
{
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
JS::RootingContext* rcx = JS::RootingContext::get(aCx);
@@ -87,9 +87,9 @@ nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
return NS_OK;
}
nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
nsIContent* aOwner,
nsFrameMessageManager* aChrome)
InProcessTabChildMessageManager::InProcessTabChildMessageManager(nsIDocShell* aShell,
nsIContent* aOwner,
nsFrameMessageManager* aChrome)
: ContentFrameMessageManager(new nsFrameMessageManager(this)),
mDocShell(aShell), mLoadingScript(false),
mPreventEventsEscaping(false),
@@ -108,7 +108,7 @@ nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
}
}
nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal()
InProcessTabChildMessageManager::~InProcessTabChildMessageManager()
{
mAnonymousGlobalScopes.Clear();
mozilla::DropJSObjects(this);
@@ -117,87 +117,57 @@ nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal()
// This method isn't automatically forwarded safely because it's notxpcom, so
// the IDL binding doesn't know what value to return.
void
nsInProcessTabChildGlobal::MarkForCC()
InProcessTabChildMessageManager::MarkForCC()
{
MarkScopesForCC();
MessageManagerGlobal::MarkForCC();
}
bool
nsInProcessTabChildGlobal::Init()
{
// If you change this, please change GetCompartmentName() in XPCJSContext.cpp
// accordingly.
nsAutoCString id;
id.AssignLiteral("inProcessTabChildGlobal");
nsIURI* uri = mOwner->OwnerDoc()->GetDocumentURI();
if (uri) {
nsAutoCString u;
nsresult rv = uri->GetSpec(u);
NS_ENSURE_SUCCESS(rv, false);
id.AppendLiteral("?ownedBy=");
id.Append(u);
}
return InitChildGlobalInternal(id);
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsInProcessTabChildGlobal)
NS_IMPL_CYCLE_COLLECTION_CLASS(InProcessTabChildMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(InProcessTabChildMessageManager,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell)
tmp->TraverseHostObjectURIs(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(InProcessTabChildMessageManager,
DOMEventTargetHelper)
tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal,
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(InProcessTabChildMessageManager,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell)
tmp->nsMessageManagerScriptExecutor::Unlink();
tmp->UnlinkHostObjectURIs();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsInProcessTabChildGlobal)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InProcessTabChildMessageManager)
NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(InProcessTabChildMessageManager, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(InProcessTabChildMessageManager, DOMEventTargetHelper)
bool
nsInProcessTabChildGlobal::WrapGlobalObject(JSContext* aCx,
JS::RealmOptions& aOptions,
JS::MutableHandle<JSObject*> aReflector)
JSObject*
InProcessTabChildMessageManager::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
bool ok = ContentFrameMessageManager_Binding::Wrap(aCx, this, this, aOptions,
nsJSPrincipals::get(mPrincipal),
true, aReflector);
if (ok) {
// Since we can't rewrap we have to preserve the global's wrapper here.
PreserveWrapper(ToSupports(this));
}
return ok;
return ContentFrameMessageManager_Binding::Wrap(aCx, this, aGivenProto);
}
void
nsInProcessTabChildGlobal::CacheFrameLoader(nsFrameLoader* aFrameLoader)
InProcessTabChildMessageManager::CacheFrameLoader(nsFrameLoader* aFrameLoader)
{
mFrameLoader = aFrameLoader;
}
already_AddRefed<nsPIDOMWindowOuter>
nsInProcessTabChildGlobal::GetContent(ErrorResult& aError)
InProcessTabChildMessageManager::GetContent(ErrorResult& aError)
{
nsCOMPtr<nsPIDOMWindowOuter> content;
if (mDocShell) {
@@ -207,14 +177,14 @@ nsInProcessTabChildGlobal::GetContent(ErrorResult& aError)
}
already_AddRefed<nsIEventTarget>
nsInProcessTabChildGlobal::GetTabEventTarget()
InProcessTabChildMessageManager::GetTabEventTarget()
{
nsCOMPtr<nsIEventTarget> target = GetMainThreadEventTarget();
return target.forget();
}
uint64_t
nsInProcessTabChildGlobal::ChromeOuterWindowID()
InProcessTabChildMessageManager::ChromeOuterWindowID()
{
if (!mDocShell) {
return 0;
@@ -236,7 +206,7 @@ nsInProcessTabChildGlobal::ChromeOuterWindowID()
}
void
nsInProcessTabChildGlobal::FireUnloadEvent()
InProcessTabChildMessageManager::FireUnloadEvent()
{
// We're called from nsDocument::MaybeInitializeFinalizeFrameLoaders, so it
// should be safe to run script.
@@ -252,7 +222,7 @@ nsInProcessTabChildGlobal::FireUnloadEvent()
}
void
nsInProcessTabChildGlobal::DisconnectEventListeners()
InProcessTabChildMessageManager::DisconnectEventListeners()
{
if (mDocShell) {
if (nsCOMPtr<nsPIDOMWindowOuter> win = mDocShell->GetWindow()) {
@@ -267,7 +237,7 @@ nsInProcessTabChildGlobal::DisconnectEventListeners()
}
void
nsInProcessTabChildGlobal::Disconnect()
InProcessTabChildMessageManager::Disconnect()
{
mChromeMessageManager = nullptr;
mOwner = nullptr;
@@ -278,13 +248,13 @@ nsInProcessTabChildGlobal::Disconnect()
}
NS_IMETHODIMP_(nsIContent *)
nsInProcessTabChildGlobal::GetOwnerContent()
InProcessTabChildMessageManager::GetOwnerContent()
{
return mOwner;
}
void
nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
InProcessTabChildMessageManager::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mForceContentDispatch = true;
aVisitor.mCanHandle = true;
@@ -294,7 +264,7 @@ nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
RefPtr<nsFrameLoader> fl = owner->GetFrameLoader();
if (fl) {
NS_ASSERTION(this == fl->GetTabChildGlobal(),
NS_ASSERTION(this == fl->GetTabChildMessageManager(),
"Wrong event target!");
NS_ASSERTION(fl->mMessageManager == mChromeMessageManager,
"Wrong message manager!");
@@ -324,7 +294,7 @@ nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
class nsAsyncScriptLoad : public Runnable
{
public:
nsAsyncScriptLoad(nsInProcessTabChildGlobal* aTabChild,
nsAsyncScriptLoad(InProcessTabChildMessageManager* aTabChild,
const nsAString& aURL,
bool aRunInGlobalScope)
: mozilla::Runnable("nsAsyncScriptLoad")
@@ -339,13 +309,13 @@ public:
mTabChild->LoadFrameScript(mURL, mRunInGlobalScope);
return NS_OK;
}
RefPtr<nsInProcessTabChildGlobal> mTabChild;
RefPtr<InProcessTabChildMessageManager> mTabChild;
nsString mURL;
bool mRunInGlobalScope;
};
void
nsInProcessTabChildGlobal::LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope)
InProcessTabChildMessageManager::LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope)
{
if (!nsContentUtils::IsSafeToRunScript()) {
nsContentUtils::AddScriptRunner(new nsAsyncScriptLoad(this, aURL, aRunInGlobalScope));
@@ -353,13 +323,13 @@ nsInProcessTabChildGlobal::LoadFrameScript(const nsAString& aURL, bool aRunInGlo
}
bool tmp = mLoadingScript;
mLoadingScript = true;
JS::Rooted<JSObject*> global(mozilla::dom::RootingCx(), GetWrapper());
LoadScriptInternal(global, aURL, aRunInGlobalScope);
JS::Rooted<JSObject*> mm(mozilla::dom::RootingCx(), GetOrCreateWrapper());
LoadScriptInternal(mm, aURL, !aRunInGlobalScope);
mLoadingScript = tmp;
}
already_AddRefed<nsFrameLoader>
nsInProcessTabChildGlobal::GetFrameLoader()
InProcessTabChildMessageManager::GetFrameLoader()
{
nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
RefPtr<nsFrameLoader> fl = owner ? owner->GetFrameLoader() : nullptr;

View File

@@ -20,62 +20,57 @@
#include "nsIDocShell.h"
#include "nsCOMArray.h"
#include "nsIRunnable.h"
#include "nsIGlobalObject.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsWeakReference.h"
namespace mozilla {
class EventChainPreVisitor;
} // namespace mozilla
class nsInProcessTabChildGlobal final : public mozilla::dom::ContentFrameMessageManager,
public nsMessageManagerScriptExecutor,
public nsIInProcessContentFrameMessageManager,
public nsIGlobalObject,
public nsIScriptObjectPrincipal,
public nsSupportsWeakReference,
public mozilla::dom::ipc::MessageManagerCallback
namespace dom {
/**
* This class implements a ContentFrameMessageManager for use by frame loaders
* in the parent process. It is bound to a DocShell rather than a TabChild, and
* does not use any IPC infrastructure for its message passing.
*/
class InProcessTabChildMessageManager final : public ContentFrameMessageManager,
public nsMessageManagerScriptExecutor,
public nsIInProcessContentFrameMessageManager,
public nsSupportsWeakReference,
public mozilla::dom::ipc::MessageManagerCallback
{
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
private:
nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner,
nsFrameMessageManager* aChrome);
bool Init();
InProcessTabChildMessageManager(nsIDocShell* aShell, nsIContent* aOwner,
nsFrameMessageManager* aChrome);
public:
static already_AddRefed<nsInProcessTabChildGlobal> Create(nsIDocShell* aShell,
nsIContent* aOwner,
nsFrameMessageManager* aChrome)
static already_AddRefed<InProcessTabChildMessageManager> Create(nsIDocShell* aShell,
nsIContent* aOwner,
nsFrameMessageManager* aChrome)
{
RefPtr<nsInProcessTabChildGlobal> global =
new nsInProcessTabChildGlobal(aShell, aOwner, aChrome);
RefPtr<InProcessTabChildMessageManager> mm =
new InProcessTabChildMessageManager(aShell, aOwner, aChrome);
NS_ENSURE_TRUE(global->Init(), nullptr);
NS_ENSURE_TRUE(mm->Init(), nullptr);
return global.forget();
return mm.forget();
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsInProcessTabChildGlobal,
mozilla::DOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(InProcessTabChildMessageManager,
DOMEventTargetHelper)
void MarkForCC();
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override
{
MOZ_CRASH("We should never get here!");
}
virtual bool WrapGlobalObject(JSContext* aCx,
JS::RealmOptions& aOptions,
JS::MutableHandle<JSObject*> aReflector) override;
JS::Handle<JSObject*> aGivenProto) override;
virtual already_AddRefed<nsPIDOMWindowOuter>
GetContent(mozilla::ErrorResult& aError) override;
GetContent(ErrorResult& aError) override;
virtual already_AddRefed<nsIDocShell>
GetDocShell(mozilla::ErrorResult& aError) override
GetDocShell(ErrorResult& aError) override
{
nsCOMPtr<nsIDocShell> docShell(mDocShell);
return docShell.forget();
@@ -105,9 +100,8 @@ public:
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal) override;
void GetEventTargetParent(mozilla::EventChainPreVisitor& aVisitor) override;
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; }
void LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope);
void FireUnloadEvent();
void DisconnectEventListeners();
@@ -130,15 +124,10 @@ public:
mChromeMessageManager = aParent;
}
virtual JSObject* GetGlobalJSObject() override
{
return GetWrapper();
}
already_AddRefed<nsFrameLoader> GetFrameLoader();
protected:
virtual ~nsInProcessTabChildGlobal();
virtual ~InProcessTabChildMessageManager();
nsCOMPtr<nsIDocShell> mDocShell;
bool mLoadingScript;
@@ -157,4 +146,7 @@ public:
nsFrameMessageManager* mChromeMessageManager;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/MessageListenerManager.h"
#include "mozilla/dom/MessageBroadcaster.h"
namespace mozilla {
namespace dom {

View File

@@ -7,7 +7,7 @@
#include "mozilla/dom/PlacesWeakCallbackWrapper.h"
#include "mozilla/HoldDropJSObjects.h"
#include "mozilla/dom/ProcessGlobal.h"
#include "mozilla/dom/ContentProcessMessageManager.h"
namespace mozilla {
namespace dom {

View File

@@ -1,169 +0,0 @@
/* -*- 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 "ProcessGlobal.h"
#include "nsContentCID.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/MessageManagerBinding.h"
#include "mozilla/dom/ResolveSystemBinding.h"
#include "mozilla/dom/ipc/SharedMap.h"
using namespace mozilla;
using namespace mozilla::dom;
bool ProcessGlobal::sWasCreated = false;
ProcessGlobal::ProcessGlobal(nsFrameMessageManager* aMessageManager)
: MessageManagerGlobal(aMessageManager),
mInitialized(false)
{
mozilla::HoldJSObjects(this);
}
ProcessGlobal::~ProcessGlobal()
{
mAnonymousGlobalScopes.Clear();
mozilla::DropJSObjects(this);
}
bool
ProcessGlobal::DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
JS::Handle<jsid> aId,
JS::MutableHandle<JS::PropertyDescriptor> aDesc)
{
bool found;
if (!SystemGlobalResolve(aCx, aObj, aId, &found)) {
return false;
}
if (found) {
FillPropertyDescriptor(aDesc, aObj, JS::UndefinedValue(), false);
}
return true;
}
/* static */
bool
ProcessGlobal::MayResolve(jsid aId)
{
return MayResolveAsSystemBindingName(aId);
}
void
ProcessGlobal::GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames,
bool aEnumerableOnly, ErrorResult& aRv)
{
JS::Rooted<JSObject*> thisObj(aCx, GetWrapper());
GetSystemBindingNames(aCx, thisObj, aNames, aEnumerableOnly, aRv);
}
ProcessGlobal*
ProcessGlobal::Get()
{
nsCOMPtr<nsIGlobalObject> service = do_GetService(NS_CHILDPROCESSMESSAGEMANAGER_CONTRACTID);
if (!service) {
return nullptr;
}
ProcessGlobal* global = static_cast<ProcessGlobal*>(service.get());
if (global) {
sWasCreated = true;
}
return global;
}
already_AddRefed<mozilla::dom::ipc::SharedMap>
ProcessGlobal::SharedData()
{
if (ContentChild* child = ContentChild::GetSingleton()) {
return do_AddRef(child->SharedData());
}
auto* ppmm = nsFrameMessageManager::sParentProcessManager;
return do_AddRef(ppmm->SharedData()->GetReadOnly());
}
bool
ProcessGlobal::WasCreated()
{
return sWasCreated;
}
void
ProcessGlobal::MarkForCC()
{
MarkScopesForCC();
MessageManagerGlobal::MarkForCC();
}
NS_IMPL_CYCLE_COLLECTION_CLASS(ProcessGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ProcessGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
tmp->TraverseHostObjectURIs(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ProcessGlobal)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ProcessGlobal)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
tmp->nsMessageManagerScriptExecutor::Unlink();
tmp->UnlinkHostObjectURIs();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ProcessGlobal)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMessageSender)
NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(ProcessGlobal)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ProcessGlobal)
bool
ProcessGlobal::Init()
{
if (mInitialized) {
return true;
}
mInitialized = true;
return InitChildGlobalInternal(NS_LITERAL_CSTRING("processChildGlobal"));
}
bool
ProcessGlobal::WrapGlobalObject(JSContext* aCx,
JS::RealmOptions& aOptions,
JS::MutableHandle<JSObject*> aReflector)
{
bool ok = ContentProcessMessageManager_Binding::Wrap(aCx, this, this, aOptions,
nsJSPrincipals::get(mPrincipal),
true, aReflector);
if (ok) {
// Since we can't rewrap we have to preserve the global's wrapper here.
PreserveWrapper(ToSupports(this));
}
return ok;
}
void
ProcessGlobal::LoadScript(const nsAString& aURL)
{
Init();
JS::Rooted<JSObject*> global(mozilla::dom::RootingCx(), GetWrapper());
LoadScriptInternal(global, aURL, false);
}
void
ProcessGlobal::SetInitialProcessData(JS::HandleValue aInitialData)
{
mMessageManager->SetInitialProcessData(aInitialData);
}

View File

@@ -4,8 +4,10 @@
* 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/ParentProcessMessageManager.h"
#include "mozilla/dom/ProcessMessageManager.h"
#include "mozilla/dom/MessageManagerBinding.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {

View File

@@ -152,6 +152,7 @@ EXPORTS.mozilla.dom += [
'ChromeUtils.h',
'Comment.h',
'ContentFrameMessageManager.h',
'ContentProcessMessageManager.h',
'CustomElementRegistry.h',
'DirectionalityUtils.h',
'DispatcherTrait.h',
@@ -205,7 +206,6 @@ EXPORTS.mozilla.dom += [
'PlacesVisit.h',
'PlacesWeakCallbackWrapper.h',
'Pose.h',
'ProcessGlobal.h',
'ProcessMessageManager.h',
'ResponsiveImageSelector.h',
'SameProcessMessageQueue.h',
@@ -249,6 +249,8 @@ UNIFIED_SOURCES += [
'ChromeNodeList.cpp',
'ChromeUtils.cpp',
'Comment.cpp',
'ContentFrameMessageManager.cpp',
'ContentProcessMessageManager.cpp',
'Crypto.cpp',
'CustomElementRegistry.cpp',
'DirectionalityUtils.cpp',
@@ -278,6 +280,7 @@ UNIFIED_SOURCES += [
'IDTracker.cpp',
'ImageEncoder.cpp',
'ImageTracker.cpp',
'InProcessTabChildMessageManager.cpp',
'IntlUtils.cpp',
'Link.cpp',
'Location.cpp',
@@ -318,7 +321,6 @@ UNIFIED_SOURCES += [
'nsHTMLContentSerializer.cpp',
'nsIGlobalObject.cpp',
'nsINode.cpp',
'nsInProcessTabChildGlobal.cpp',
'nsJSEnvironment.cpp',
'nsJSTimeoutHandler.cpp',
'nsJSUtils.cpp',
@@ -357,7 +359,6 @@ UNIFIED_SOURCES += [
'ParentProcessMessageManager.cpp',
'Pose.cpp',
'PostMessageEvent.cpp',
'ProcessGlobal.cpp',
'ProcessMessageManager.cpp',
'ResponsiveImageSelector.cpp',
'SameProcessMessageQueue.cpp',

View File

@@ -11,6 +11,7 @@
#include "nsIContentViewer.h"
#include "nsIDocument.h"
#include "XULDocument.h"
#include "InProcessTabChildMessageManager.h"
#include "nsIWindowMediator.h"
#include "nsPIDOMWindow.h"
#include "nsIWebNavigation.h"
@@ -25,16 +26,15 @@
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
#include "nsJSEnvironment.h"
#include "nsInProcessTabChildGlobal.h"
#include "nsFrameLoader.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/dom/ChromeMessageBroadcaster.h"
#include "mozilla/dom/ContentFrameMessageManager.h"
#include "mozilla/dom/ContentProcessMessageManager.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ParentProcessMessageManager.h"
#include "mozilla/dom/ProcessGlobal.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/TimeoutManager.h"
#include "xpcpublic.h"
@@ -120,7 +120,7 @@ MarkChildMessageManagers(MessageBroadcaster* aMM)
mozilla::dom::ipc::MessageManagerCallback* cb = tabMM->GetCallback();
if (cb) {
nsFrameLoader* fl = static_cast<nsFrameLoader*>(cb);
nsInProcessTabChildGlobal* et = fl->GetTabChildGlobal();
InProcessTabChildMessageManager* et = fl->GetTabChildMessageManager();
if (!et) {
continue;
}
@@ -137,8 +137,8 @@ static void
MarkMessageManagers()
{
if (nsFrameMessageManager::GetChildProcessManager()) {
// ProcessGlobal's MarkForCC marks also ChildProcessManager.
ProcessGlobal* pg = ProcessGlobal::Get();
// ContentProcessMessageManager's MarkForCC also marks ChildProcessManager.
ContentProcessMessageManager* pg = ContentProcessMessageManager::Get();
if (pg) {
pg->MarkForCC();
}
@@ -291,7 +291,7 @@ MarkWindowList(nsISimpleEnumerator* aWindowList, bool aCleanupJS)
RefPtr<TabChild> tabChild = TabChild::GetFrom(rootDocShell);
if (tabChild) {
RefPtr<TabChildGlobal> mm = tabChild->GetMessageManager();
RefPtr<TabChildMessageManager> mm = tabChild->GetMessageManager();
if (mm) {
// MarkForCC ends up calling UnmarkGray on message listeners, which
// TraceBlackJS can't do yet.
@@ -471,8 +471,9 @@ mozilla::dom::TraceBlackJS(JSTracer* aTrc, bool aIsShutdownGC)
return;
}
if (ProcessGlobal::WasCreated() && nsFrameMessageManager::GetChildProcessManager()) {
ProcessGlobal* pg = ProcessGlobal::Get();
if (ContentProcessMessageManager::WasCreated() &&
nsFrameMessageManager::GetChildProcessManager()) {
auto* pg = ContentProcessMessageManager::Get();
if (pg) {
mozilla::TraceScriptHolder(ToSupports(pg), aTrc);
}
@@ -502,8 +503,8 @@ mozilla::dom::TraceBlackJS(JSTracer* aTrc, bool aIsShutdownGC)
}
if (window->IsRootOuterWindow()) {
// In child process trace all the TabChildGlobals.
// Since there is one root outer window per TabChildGlobal, we need
// In child process trace all the TabChildMessageManagers.
// Since there is one root outer window per TabChildMessageManager, we need
// to look for only those windows, not all.
nsIDocShell* ds = window->GetDocShell();
if (ds) {

View File

@@ -5,8 +5,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsContentTypeParser.h"
#include "nsContentUtils.h"
#include "nsNetUtil.h"
using namespace mozilla;
nsContentTypeParser::nsContentTypeParser(const nsAString& aString)
: mString(aString)
{

View File

@@ -7,7 +7,7 @@
#ifndef nsContentTypeParser_h
#define nsContentTypeParser_h
#include "nsAString.h"
#include "nsString.h"
class nsContentTypeParser
{

View File

@@ -121,7 +121,6 @@
#include "nsHtml5StringParser.h"
#include "nsHTMLDocument.h"
#include "nsHTMLTags.h"
#include "nsInProcessTabChildGlobal.h"
#include "nsIAddonPolicyService.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIAsyncVerifyRedirectCallback.h"
@@ -215,6 +214,7 @@
#include "nsXULPopupManager.h"
#include "xpcprivate.h" // nsXPConnect
#include "HTMLSplitOnSpacesTokenizer.h"
#include "InProcessTabChildMessageManager.h"
#include "nsContentTypeParser.h"
#include "nsICookiePermission.h"
#include "nsICookieService.h"
@@ -11029,7 +11029,7 @@ nsContentUtils::TryGetTabChildGlobal(nsISupports* aFrom)
return nullptr;
}
RefPtr<ContentFrameMessageManager> manager = frameLoader->GetTabChildGlobal();
RefPtr<ContentFrameMessageManager> manager = frameLoader->GetTabChildMessageManager();
return manager.forget();
}

View File

@@ -64,7 +64,7 @@
#include "nsThreadUtils.h"
#include "nsIDOMChromeWindow.h"
#include "nsInProcessTabChildGlobal.h"
#include "InProcessTabChildMessageManager.h"
#include "Layers.h"
#include "ClientLayerManager.h"
@@ -1599,12 +1599,12 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
RefPtr<nsFrameMessageManager> otherMessageManager = aOther->mMessageManager;
// Swap pointers in child message managers.
if (mChildMessageManager) {
nsInProcessTabChildGlobal* tabChild = mChildMessageManager;
InProcessTabChildMessageManager* tabChild = mChildMessageManager;
tabChild->SetOwner(otherContent);
tabChild->SetChromeMessageManager(otherMessageManager);
}
if (aOther->mChildMessageManager) {
nsInProcessTabChildGlobal* otherTabChild = aOther->mChildMessageManager;
InProcessTabChildMessageManager* otherTabChild = aOther->mChildMessageManager;
otherTabChild->SetOwner(ourContent);
otherTabChild->SetChromeMessageManager(ourMessageManager);
}
@@ -2822,7 +2822,7 @@ nsFrameLoader::DoLoadMessageManagerScript(const nsAString& aURL, bool aRunInGlob
if (tabParent) {
return tabParent->SendLoadRemoteScript(nsString(aURL), aRunInGlobalScope);
}
RefPtr<nsInProcessTabChildGlobal> tabChild = GetTabChildGlobal();
RefPtr<InProcessTabChildMessageManager> tabChild = GetTabChildMessageManager();
if (tabChild) {
tabChild->LoadFrameScript(aURL, aRunInGlobalScope);
}
@@ -2844,7 +2844,7 @@ public:
NS_IMETHOD Run() override
{
nsInProcessTabChildGlobal* tabChild = mFrameLoader->mChildMessageManager;
InProcessTabChildMessageManager* tabChild = mFrameLoader->mChildMessageManager;
// Since bug 1126089, messages can arrive even when the docShell is destroyed.
// Here we make sure that those messages are not delivered.
if (tabChild && tabChild->GetInnerManager() && mFrameLoader->GetExistingDocShell()) {
@@ -2961,7 +2961,7 @@ nsFrameLoader::EnsureMessageManager()
return NS_ERROR_FAILURE;
}
mChildMessageManager =
nsInProcessTabChildGlobal::Create(mDocShell, mOwnerContent, mMessageManager);
InProcessTabChildMessageManager::Create(mDocShell, mOwnerContent, mMessageManager);
NS_ENSURE_TRUE(mChildMessageManager, NS_ERROR_UNEXPECTED);
}
return NS_OK;

View File

@@ -32,7 +32,6 @@
class nsIURI;
class nsSubDocumentFrame;
class nsView;
class nsInProcessTabChildGlobal;
class AutoResetInShow;
class AutoResetInFrameSwap;
class nsITabParent;
@@ -51,6 +50,7 @@ class OriginAttributes;
namespace dom {
class ChromeMessageSender;
class ContentParent;
class InProcessTabChildMessageManager;
class MessageSender;
class PBrowserParent;
class ProcessMessageManager;
@@ -106,7 +106,7 @@ public:
void DestroyDocShell();
void DestroyComplete();
nsIDocShell* GetExistingDocShell() { return mDocShell; }
nsInProcessTabChildGlobal* GetTabChildGlobal() const
mozilla::dom::InProcessTabChildMessageManager* GetTabChildMessageManager() const
{
return mChildMessageManager;
}
@@ -341,7 +341,7 @@ public:
// public because a callback needs these.
RefPtr<mozilla::dom::ChromeMessageSender> mMessageManager;
RefPtr<nsInProcessTabChildGlobal> mChildMessageManager;
RefPtr<mozilla::dom::InProcessTabChildMessageManager> mChildMessageManager;
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;

View File

@@ -40,9 +40,9 @@
#include "mozilla/dom/MessageManagerBinding.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentProcessMessageManager.h"
#include "mozilla/dom/ParentProcessMessageManager.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/ProcessGlobal.h"
#include "mozilla/dom/ProcessMessageManager.h"
#include "mozilla/dom/ResolveSystemBinding.h"
#include "mozilla/dom/SameProcessMessageQueue.h"
@@ -797,7 +797,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
if (JS::IsCallable(object)) {
// A small hack to get 'this' value right on content side where
// messageManager is wrapped in TabChildGlobal.
// messageManager is wrapped in TabChildMessageManager's global.
nsCOMPtr<nsISupports> defaultThisValue;
if (mChrome) {
defaultThisValue = do_QueryObject(this);
@@ -1235,7 +1235,7 @@ nsDataHashtable<nsStringHashKey, nsMessageManagerScriptHolder*>*
StaticRefPtr<nsScriptCacheCleaner> nsMessageManagerScriptExecutor::sScriptCacheCleaner;
void
nsMessageManagerScriptExecutor::DidCreateGlobal()
nsMessageManagerScriptExecutor::DidCreateScriptLoader()
{
if (!sCachedScripts) {
sCachedScripts =
@@ -1271,9 +1271,9 @@ nsMessageManagerScriptExecutor::Shutdown()
}
void
nsMessageManagerScriptExecutor::LoadScriptInternal(JS::Handle<JSObject*> aGlobal,
nsMessageManagerScriptExecutor::LoadScriptInternal(JS::Handle<JSObject*> aMessageManager,
const nsAString& aURL,
bool aRunInGlobalScope)
bool aRunInUniqueScope)
{
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(
"nsMessageManagerScriptExecutor::LoadScriptInternal", OTHER, aURL);
@@ -1286,29 +1286,30 @@ nsMessageManagerScriptExecutor::LoadScriptInternal(JS::Handle<JSObject*> aGlobal
JS::Rooted<JSScript*> script(rcx);
nsMessageManagerScriptHolder* holder = sCachedScripts->Get(aURL);
if (holder && holder->WillRunInGlobalScope() == aRunInGlobalScope) {
if (holder) {
script = holder->mScript;
} else {
// Don't put anything in the cache if we already have an entry
// with a different WillRunInGlobalScope() value.
bool shouldCache = !holder;
TryCacheLoadAndCompileScript(aURL, aRunInGlobalScope,
shouldCache, aGlobal, &script);
TryCacheLoadAndCompileScript(aURL, aRunInUniqueScope, true,
aMessageManager, &script);
}
AutoEntryScript aes(aGlobal, "message manager script load");
AutoEntryScript aes(aMessageManager, "message manager script load");
JSContext* cx = aes.cx();
if (script) {
if (aRunInGlobalScope) {
JS::RootedValue rval(cx);
JS::CloneAndExecuteScript(cx, script, &rval);
} else {
if (aRunInUniqueScope) {
JS::Rooted<JSObject*> scope(cx);
bool ok = js::ExecuteInGlobalAndReturnScope(cx, aGlobal, script, &scope);
bool ok = js::ExecuteInFrameScriptEnvironment(cx, aMessageManager, script, &scope);
if (ok) {
// Force the scope to stay alive.
mAnonymousGlobalScopes.AppendElement(scope);
}
} else {
JS::RootedValue rval(cx);
JS::AutoObjectVector envChain(cx);
if (!envChain.append(aMessageManager)) {
return;
}
JS::CloneAndExecuteScript(cx, envChain, script, &rval);
}
}
}
@@ -1316,9 +1317,9 @@ nsMessageManagerScriptExecutor::LoadScriptInternal(JS::Handle<JSObject*> aGlobal
void
nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
const nsAString& aURL,
bool aRunInGlobalScope,
bool aRunInUniqueScope,
bool aShouldCache,
JS::Handle<JSObject*> aGlobal,
JS::Handle<JSObject*> aMessageManager,
JS::MutableHandle<JSScript*> aScriptp)
{
nsCString url = NS_ConvertUTF16toUTF8(aURL);
@@ -1347,7 +1348,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
// scope instead of the current global to avoid keeping the current
// compartment alive.
AutoJSAPI jsapi;
if (!jsapi.Init(isRunOnce ? aGlobal : xpc::CompilationScope())) {
if (!jsapi.Init(isRunOnce ? aMessageManager : xpc::CompilationScope())) {
return;
}
JSContext* cx = jsapi.cx();
@@ -1397,12 +1398,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
options.setFileAndLine(url.get(), 1);
options.setNoScriptRval(true);
if (aRunInGlobalScope) {
if (!JS::Compile(cx, options, srcBuf, &script)) {
return;
}
// We're going to run these against some non-global scope.
} else if (!JS::CompileForNonSyntacticScope(cx, options, srcBuf, &script)) {
if (!JS::CompileForNonSyntacticScope(cx, options, srcBuf, &script)) {
return;
}
}
@@ -1420,7 +1416,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
// preloader cache, not the session cache.
if (!isRunOnce) {
// Root the object also for caching.
auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope);
auto* holder = new nsMessageManagerScriptHolder(cx, script);
sCachedScripts->Put(aURL, holder);
}
}
@@ -1441,31 +1437,9 @@ nsMessageManagerScriptExecutor::Unlink()
}
bool
nsMessageManagerScriptExecutor::InitChildGlobalInternal(const nsACString& aID)
nsMessageManagerScriptExecutor::Init()
{
AutoSafeJSContext cx;
if (!SystemBindingInitIds(cx)) {
return false;
}
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
JS::RealmOptions options;
options.creationOptions().setNewCompartmentInSystemZone();
xpc::InitGlobalObjectOptions(options, mPrincipal);
JS::Rooted<JSObject*> global(cx);
if (!WrapGlobalObject(cx, options, &global)) {
return false;
}
xpc::InitGlobalObject(cx, global, 0);
// Set the location information for the new global, so that tools like
// about:memory may use that information.
xpc::SetLocationForGlobal(global, aID);
DidCreateGlobal();
DidCreateScriptLoader();
return true;
}
@@ -1519,7 +1493,7 @@ public:
bool DoLoadMessageManagerScript(const nsAString& aURL,
bool aRunInGlobalScope) override
{
ProcessGlobal* global = ProcessGlobal::Get();
auto* global = ContentProcessMessageManager::Get();
MOZ_ASSERT(!aRunInGlobalScope);
global->LoadScript(aURL);
return true;
@@ -1748,7 +1722,7 @@ NS_NewChildProcessMessageManager(nsISupports** aResult)
}
auto* mm = new ChildProcessMessageManager(cb);
nsFrameMessageManager::SetChildProcessManager(mm);
RefPtr<ProcessGlobal> global = new ProcessGlobal(mm);
auto global = MakeRefPtr<ContentProcessMessageManager>(mm);
NS_ENSURE_TRUE(global->Init(), NS_ERROR_UNEXPECTED);
return CallQueryInterface(global, aResult);
}

View File

@@ -407,18 +407,14 @@ class nsScriptCacheCleaner;
struct nsMessageManagerScriptHolder
{
nsMessageManagerScriptHolder(JSContext* aCx,
JSScript* aScript,
bool aRunInGlobalScope)
: mScript(aCx, aScript), mRunInGlobalScope(aRunInGlobalScope)
JSScript* aScript)
: mScript(aCx, aScript)
{ MOZ_COUNT_CTOR(nsMessageManagerScriptHolder); }
~nsMessageManagerScriptHolder()
{ MOZ_COUNT_DTOR(nsMessageManagerScriptHolder); }
bool WillRunInGlobalScope() { return mRunInGlobalScope; }
JS::PersistentRooted<JSScript*> mScript;
bool mRunInGlobalScope;
};
class nsMessageManagerScriptExecutor
@@ -433,18 +429,15 @@ protected:
nsMessageManagerScriptExecutor() { MOZ_COUNT_CTOR(nsMessageManagerScriptExecutor); }
~nsMessageManagerScriptExecutor() { MOZ_COUNT_DTOR(nsMessageManagerScriptExecutor); }
void DidCreateGlobal();
void LoadScriptInternal(JS::Handle<JSObject*> aGlobal, const nsAString& aURL,
bool aRunInGlobalScope);
void DidCreateScriptLoader();
void LoadScriptInternal(JS::Handle<JSObject*> aMessageManager, const nsAString& aURL,
bool aRunInUniqueScope);
void TryCacheLoadAndCompileScript(const nsAString& aURL,
bool aRunInGlobalScope,
bool aRunInUniqueScope,
bool aShouldCache,
JS::Handle<JSObject*> aGlobal,
JS::Handle<JSObject*> aMessageManager,
JS::MutableHandle<JSScript*> aScriptp);
bool InitChildGlobalInternal(const nsACString& aID);
virtual bool WrapGlobalObject(JSContext* aCx,
JS::RealmOptions& aOptions,
JS::MutableHandle<JSObject*> aReflector) = 0;
bool Init();
void Trace(const TraceCallbacks& aCallbacks, void* aClosure);
void Unlink();
nsCOMPtr<nsIPrincipal> mPrincipal;

View File

@@ -30,7 +30,7 @@ using namespace mozilla::dom;
static const char* kPrefSVGDisabled = "svg.disabled";
static const char* kPrefMathMLDisabled = "mathml.disabled";
static const char* kObservedPrefs[] = {
static const char* kObservedNSPrefs[] = {
kPrefMathMLDisabled,
kPrefSVGDisabled,
nullptr
@@ -65,7 +65,7 @@ bool nsNameSpaceManager::Init()
mozilla::Preferences::RegisterCallbacks(
PREF_CHANGE_METHOD(nsNameSpaceManager::PrefChanged),
kObservedPrefs, this);
kObservedNSPrefs, this);
PrefChanged(nullptr);

View File

@@ -30,7 +30,7 @@ static char* sSpaceSharedString[TEXTFRAG_MAX_NEWLINES + 1];
static char* sTabSharedString[TEXTFRAG_MAX_NEWLINES + 1];
static char sSingleCharSharedString[256];
using mozilla::CheckedUint32;
using namespace mozilla;
// static
nsresult

View File

@@ -16,12 +16,12 @@
namespace mozilla {
namespace dom {
class TabChildGlobal;
class ProcessGlobal;
class ContentProcessMessageManager;
class InProcessTabChildMessageManager;
class TabChildMessageManager;
} // namespace dom
} // namespace mozilla
class SandboxPrivate;
class nsInProcessTabChildGlobal;
class nsWindowRoot;
#define NS_WRAPPERCACHE_IID \

View File

@@ -38,7 +38,7 @@ function processScript() {
});
sendSyncMessage("ProcessTest:Loaded");
}
var processScriptURL = "data:,(" + processScript.toString() + ")()";
var processScriptURL = "data:,(" + processScript.toString() + ").call(this)";
function initTestScript() {
let init = initialProcessData;

View File

@@ -155,10 +155,6 @@ DOMInterfaces = {
'implicitJSContext': ['clear', 'count', 'countReset', 'groupEnd', 'time', 'timeEnd'],
},
'ContentProcessMessageManager': {
'nativeType': 'mozilla::dom::ProcessGlobal'
},
'ConvolverNode': {
'implicitJSContext': [ 'buffer' ],
},
@@ -581,6 +577,15 @@ DOMInterfaces = {
'notflattened': True
},
'MozDocumentMatcher': {
'nativeType': 'mozilla::extensions::MozDocumentMatcher',
'headerFile': 'mozilla/extensions/WebExtensionContentScript.h',
},
'MozDocumentObserver': {
'nativeType': 'mozilla::extensions::DocumentObserver',
},
'MozSharedMap': {
'nativeType': 'mozilla::dom::ipc::SharedMap',
},

View File

@@ -203,9 +203,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
}
}
// Bail out if there's no useful global. This seems to happen intermittently
// on gaia-ui tests, probably because nsInProcessTabChildGlobal is returning
// null in some kind of teardown state.
// Bail out if there's no useful global.
if (!globalObject->GetGlobalJSObject()) {
aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
NS_LITERAL_CSTRING("Refusing to execute function from global which is "

View File

@@ -41,14 +41,14 @@ if (!BrowserElementIsReady) {
if(Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
// general content apps
if (isTopBrowserElement(docShell)) {
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementCopyPaste.js");
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementCopyPaste.js", this);
}
} else {
// rocketbar in system app and other in-process case (ex. B2G desktop client)
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementCopyPaste.js");
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementCopyPaste.js", this);
}
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js");
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js", this);
}
function onDestroy() {

View File

@@ -461,7 +461,7 @@ interface GlobalProcessScriptLoader : ProcessScriptLoader
readonly attribute MozWritableSharedMap sharedData;
};
[ChromeOnly, Global, NeedResolve]
[ChromeOnly]
interface ContentFrameMessageManager : EventTarget
{
/**
@@ -495,7 +495,7 @@ interface ContentFrameMessageManager : EventTarget
// WebIDL spec.
ContentFrameMessageManager implements MessageManagerGlobal;
[ChromeOnly, Global, NeedResolve]
[ChromeOnly]
interface ContentProcessMessageManager
{
/**

View File

@@ -0,0 +1,17 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
callback interface MozDocumentCallback {
void onNewDocument(MozDocumentMatcher matcher, WindowProxy window);
void onPreloadDocument(MozDocumentMatcher matcher, LoadInfo loadInfo);
};
[ChromeOnly, Constructor(MozDocumentCallback callbacks), Exposed=System]
interface MozDocumentObserver {
[Throws]
void observe(sequence<MozDocumentMatcher> matchers);
void disconnect();
};

View File

@@ -6,32 +6,8 @@ interface LoadInfo;
interface URI;
interface WindowProxy;
/**
* Describes the earliest point in the load cycle at which a script should
* run.
*/
enum ContentScriptRunAt {
/**
* The point in the load cycle just after the document element has been
* inserted, before any page scripts have been allowed to run.
*/
"document_start",
/**
* The point after which the page DOM has fully loaded, but before all page
* resources have necessarily been loaded. Corresponds approximately to the
* DOMContentLoaded event.
*/
"document_end",
/**
* The first point after the page and all of its resources has fully loaded
* when the event loop is idle, and can run scripts without delaying a paint
* event.
*/
"document_idle",
};
[Constructor(WebExtensionPolicy extension, WebExtensionContentScriptInit options), ChromeOnly, Exposed=System]
interface WebExtensionContentScript {
[Constructor(MozDocumentMatcherInit options), ChromeOnly, Exposed=System]
interface MozDocumentMatcher {
/**
* Returns true if the script's match and exclude patterns match the given
* URI, without reference to attributes such as `allFrames`.
@@ -39,52 +15,33 @@ interface WebExtensionContentScript {
boolean matchesURI(URI uri);
/**
* Returns true if the script matches the given URI and LoadInfo objects.
* Returns true if the the given URI and LoadInfo objects match.
* This should be used to determine whether to begin pre-loading a content
* script based on network events.
*/
boolean matchesLoadInfo(URI uri, LoadInfo loadInfo);
/**
* Returns true if the script matches the given window. This should be used
* Returns true if the given window matches. This should be used
* to determine whether to run a script in a window at load time.
*/
boolean matchesWindow(WindowProxy window);
/**
* The policy object for the extension that this script belongs to.
*/
[Constant]
readonly attribute WebExtensionPolicy extension;
/**
* If true, this script runs in all frames. If false, it only runs in
* top-level frames.
* If true, match all frames. If false, match only top-level frames.
*/
[Constant]
readonly attribute boolean allFrames;
/**
* If true, this (misleadingly-named, but inherited from Chrome) attribute
* causes the script to run in frames with URLs which inherit a principal
* that matches one of the match patterns, such as about:blank or
* about:srcdoc. If false, the script only runs in frames with an explicit
* matching URL.
* causes us to match frames with URLs which inherit a principal that
* matches one of the match patterns, such as about:blank or about:srcdoc.
* If false, we only match frames with an explicit matching URL.
*/
[Constant]
readonly attribute boolean matchAboutBlank;
/**
* The earliest point in the load cycle at which this script should run. For
* static content scripts, in extensions which were present at browser
* startup, the browser makes every effort to make sure that the script runs
* no later than this point in the load cycle. For dynamic content scripts,
* and scripts from extensions installed during this session, the scripts
* may run at a later point.
*/
[Constant]
readonly attribute ContentScriptRunAt runAt;
/**
* The outer window ID of the frame in which to run the script, or 0 if it
* should run in the top-level frame. Should only be used for
@@ -123,6 +80,68 @@ interface WebExtensionContentScript {
[Cached, Constant, Frozen]
readonly attribute sequence<MatchGlob>? excludeGlobs;
/**
* The policy object for the extension that this matcher belongs to.
*/
[Constant]
readonly attribute WebExtensionPolicy? extension;
};
dictionary MozDocumentMatcherInit {
boolean allFrames = false;
boolean matchAboutBlank = false;
unsigned long long? frameID = null;
required MatchPatternSet matches;
MatchPatternSet? excludeMatches = null;
sequence<MatchGlob>? includeGlobs = null;
sequence<MatchGlob>? excludeGlobs = null;
boolean hasActiveTabPermission = false;
};
/**
* Describes the earliest point in the load cycle at which a script should
* run.
*/
enum ContentScriptRunAt {
/**
* The point in the load cycle just after the document element has been
* inserted, before any page scripts have been allowed to run.
*/
"document_start",
/**
* The point after which the page DOM has fully loaded, but before all page
* resources have necessarily been loaded. Corresponds approximately to the
* DOMContentLoaded event.
*/
"document_end",
/**
* The first point after the page and all of its resources has fully loaded
* when the event loop is idle, and can run scripts without delaying a paint
* event.
*/
"document_idle",
};
[Constructor(WebExtensionPolicy extension, WebExtensionContentScriptInit options), ChromeOnly, Exposed=System]
interface WebExtensionContentScript : MozDocumentMatcher {
/**
* The earliest point in the load cycle at which this script should run. For
* static content scripts, in extensions which were present at browser
* startup, the browser makes every effort to make sure that the script runs
* no later than this point in the load cycle. For dynamic content scripts,
* and scripts from extensions installed during this session, the scripts
* may run at a later point.
*/
[Constant]
readonly attribute ContentScriptRunAt runAt;
/**
* A set of paths, relative to the extension root, of CSS sheets to inject
* into matching pages.
@@ -138,25 +157,9 @@ interface WebExtensionContentScript {
readonly attribute sequence<DOMString> jsPaths;
};
dictionary WebExtensionContentScriptInit {
boolean allFrames = false;
boolean matchAboutBlank = false;
dictionary WebExtensionContentScriptInit : MozDocumentMatcherInit {
ContentScriptRunAt runAt = "document_idle";
unsigned long long? frameID = null;
boolean hasActiveTabPermission = false;
required MatchPatternSet matches;
MatchPatternSet? excludeMatches = null;
sequence<MatchGlob>? includeGlobs = null;
sequence<MatchGlob>? excludeGlobs = null;
sequence<DOMString> cssPaths = [];
sequence<DOMString> jsPaths = [];

View File

@@ -37,6 +37,7 @@ WEBIDL_FILES = [
'MatchGlob.webidl',
'MatchPattern.webidl',
'MessageManager.webidl',
'MozDocumentObserver.webidl',
'MozSharedMap.webidl',
'MozStorageAsyncStatementParams.webidl',
'MozStorageStatementParams.webidl',

View File

@@ -886,7 +886,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
// Set the target to be the original dispatch target,
aEvent->mTarget = target;
// but use chrome event handler or TabChildGlobal for event target chain.
// but use chrome event handler or TabChildMessageManager for event target chain.
target = piTarget;
} else if (NS_WARN_IF(!doc)) {
return NS_ERROR_UNEXPECTED;

Some files were not shown because too many files have changed in this diff Show More