Merge mozilla-inbound to mozilla-central. a=merge
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -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",
|
||||
|
||||
150
browser/actors/AboutReaderChild.jsm
Normal file
150
browser/actors/AboutReaderChild.jsm
Normal 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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
112
browser/actors/BrowserTabChild.jsm
Normal file
112
browser/actors/BrowserTabChild.jsm
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
37
browser/actors/ContentSearchChild.jsm
Normal file
37
browser/actors/ContentSearchChild.jsm
Normal 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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
81
browser/actors/DOMFullscreenChild.jsm
Normal file
81
browser/actors/DOMFullscreenChild.jsm
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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", {});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
129
browser/actors/OfflineAppsChild.jsm
Normal file
129
browser/actors/OfflineAppsChild.jsm
Normal 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]);
|
||||
@@ -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, "");
|
||||
}
|
||||
};
|
||||
}
|
||||
33
browser/actors/PageMetadataChild.jsm
Normal file
33
browser/actors/PageMetadataChild.jsm
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
37
browser/actors/URIFixupChild.jsm
Normal file
37
browser/actors/URIFixupChild.jsm
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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
42
browser/actors/moz.build
Normal 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',
|
||||
]
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
3
browser/base/content/browser.xhtml
Normal file
3
browser/base/content/browser.xhtml
Normal file
@@ -0,0 +1,3 @@
|
||||
#define BROWSER_XHTML
|
||||
#include browser.xul
|
||||
#undef BROWSER_XHTML
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 [
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
])
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 = [];
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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();"
|
||||
|
||||
@@ -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();"
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
@@ -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 += [
|
||||
|
||||
@@ -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
|
||||
|
||||
2
browser/extensions/formautofill/bootstrap.js
vendored
2
browser/extensions/formautofill/bootstrap.js
vendored
@@ -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() {
|
||||
|
||||
2
browser/extensions/onboarding/bootstrap.js
vendored
2
browser/extensions/onboarding/bootstrap.js
vendored
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -381,6 +381,8 @@
|
||||
; Modules
|
||||
@RESPATH@/browser/modules/*
|
||||
@RESPATH@/modules/*
|
||||
@RESPATH@/browser/actors/*
|
||||
@RESPATH@/actors/*
|
||||
|
||||
; Safe Browsing
|
||||
@RESPATH@/components/nsURLClassifier.manifest
|
||||
|
||||
14
browser/locales/en-US/browser/aboutPolicies.ftl
Normal file
14
browser/locales/en-US/browser/aboutPolicies.ftl
Normal 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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ with Files('docs/**'):
|
||||
SCHEDULES.exclusive = ['docs']
|
||||
|
||||
DIRS += [
|
||||
'actors',
|
||||
'base',
|
||||
'components',
|
||||
'fonts',
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
33
browser/themes/shared/places/places.inc.css
Normal file
33
browser/themes/shared/places/places.inc.css
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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) {
|
||||
|
||||
25
dom/base/ContentFrameMessageManager.cpp
Normal file
25
dom/base/ContentFrameMessageManager.cpp
Normal 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();
|
||||
}
|
||||
@@ -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)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
139
dom/base/ContentProcessMessageManager.cpp
Normal file
139
dom/base/ContentProcessMessageManager.cpp
Normal 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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#ifndef nsContentTypeParser_h
|
||||
#define nsContentTypeParser_h
|
||||
|
||||
#include "nsAString.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsContentTypeParser
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/**
|
||||
|
||||
17
dom/chrome-webidl/MozDocumentObserver.webidl
Normal file
17
dom/chrome-webidl/MozDocumentObserver.webidl
Normal 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();
|
||||
};
|
||||
@@ -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 = [];
|
||||
|
||||
@@ -37,6 +37,7 @@ WEBIDL_FILES = [
|
||||
'MatchGlob.webidl',
|
||||
'MatchPattern.webidl',
|
||||
'MessageManager.webidl',
|
||||
'MozDocumentObserver.webidl',
|
||||
'MozSharedMap.webidl',
|
||||
'MozStorageAsyncStatementParams.webidl',
|
||||
'MozStorageStatementParams.webidl',
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user