Merge inbound to mozilla-central. a=merge

This commit is contained in:
Tiberius Oros 2018-03-01 19:29:00 +02:00
Родитель 1a3b814e9c 1fd0486e23
Коммит 61d400da1c
240 изменённых файлов: 2340 добавлений и 2862 удалений

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

@ -6,6 +6,7 @@
#include "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"

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

@ -104,6 +104,15 @@ Accessible::HasNumericValue() const
return true;
}
inline bool
Accessible::IsDefunct() const
{
MOZ_ASSERT(mStateFlags & eIsDefunct || IsApplication() || IsDoc() ||
mStateFlags & eSharedNode || mContent,
"No content");
return mStateFlags & eIsDefunct;
}
inline void
Accessible::ScrollTo(uint32_t aHow) const
{

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

@ -861,7 +861,7 @@ public:
/**
* Return true if the accessible is defunct.
*/
bool IsDefunct() const { return mStateFlags & eIsDefunct; }
bool IsDefunct() const;
/**
* Return false if the accessible is no longer in the document.

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

@ -5,6 +5,8 @@
#include "XULListboxAccessibleWrap.h"
#include "Accessible-inl.h"
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////

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

@ -6,6 +6,7 @@
#include "sdnDocAccessible.h"
#include "Accessible-inl.h"
#include "ISimpleDOM.h"
#include "nsNameSpaceManager.h"

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

@ -6,6 +6,7 @@
#include "uiaRawElmProvider.h"
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "ARIAMap.h"
#include "nsIPersistentProperties2.h"

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

@ -1659,17 +1659,9 @@ pref("extensions.pocket.enabled", true);
pref("signon.schemeUpgrades", true);
// "Simplify Page" feature in Print Preview. This feature is disabled by default
// in toolkit.
//
// This feature is only enabled on Nightly for Linux until bug 1306295 is fixed.
#ifdef UNIX_BUT_NOT_MAC
#if defined(NIGHTLY_BUILD)
// Enable the "Simplify Page" feature in Print Preview. This feature
// is disabled by default in toolkit.
pref("print.use_simplify_page", true);
#endif
#else
pref("print.use_simplify_page", true);
#endif
// Space separated list of URLS that are allowed to send objects (instead of
// only strings) through webchannels. This list is duplicated in mobile/android/app/mobile.js

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

@ -360,6 +360,15 @@ var SidebarUI = {
return this.show(commandID, triggerNode);
},
_loadSidebarExtension(sidebarBroadcaster) {
let extensionId = sidebarBroadcaster.getAttribute("extensionId");
if (extensionId) {
let extensionUrl = sidebarBroadcaster.getAttribute("panel");
let browserStyle = sidebarBroadcaster.getAttribute("browserStyle");
SidebarUI.browser.contentWindow.loadPanel(extensionId, extensionUrl, browserStyle);
}
},
/**
* Show the sidebar, using the parameters from the specified broadcaster.
* @see SidebarUI note.
@ -371,7 +380,9 @@ var SidebarUI = {
* showing of the sidebar.
*/
show(commandID, triggerNode) {
return this._show(commandID).then(() => {
return this._show(commandID).then((sidebarBroadcaster) => {
this._loadSidebarExtension(sidebarBroadcaster);
if (triggerNode) {
updateToggleControlLabel(triggerNode);
}
@ -388,9 +399,11 @@ var SidebarUI = {
*
* @param {string} commandID ID of the xul:broadcaster element to use.
*/
showInitially(commandID) {
return this._show(commandID);
},
showInitially(commandID) {
return this._show(commandID).then((sidebarBroadcaster) => {
this._loadSidebarExtension(sidebarBroadcaster);
});
},
/**
* Implementation for show. Also used internally for sidebars that are shown
@ -446,14 +459,14 @@ var SidebarUI = {
// We're handling the 'load' event before it bubbles up to the usual
// (non-capturing) event handlers. Let it bubble up before resolving.
setTimeout(() => {
resolve();
resolve(sidebarBroadcaster);
// Now that the currentId is updated, fire a show event.
this._fireShowEvent();
}, 0);
}, {capture: true, once: true});
} else {
resolve();
resolve(sidebarBroadcaster);
// Now that the currentId is updated, fire a show event.
this._fireShowEvent();

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

@ -44,31 +44,6 @@ const EXPECTED_APPMENU_OPEN_REFLOWS = [
},
];
const EXPECTED_APPMENU_SUBVIEW_REFLOWS = [
/**
* The synced tabs view has labels that are multiline. Because of bugs in
* XUL layout relating to multiline text in scrollable containers, we need
* to manually read their height in order to ensure container heights are
* correct. Unfortunately this requires 2 sync reflows.
*
* If we add more views where this is necessary, we may need to duplicate
* these expected reflows further. Bug 1392340 is on file to remove the
* reflows completely when opening subviews.
*/
{
stack: [
"descriptionHeightWorkaround@resource:///modules/PanelMultiView.jsm",
"_transitionViews@resource:///modules/PanelMultiView.jsm",
],
maxCount: 4, // This number should only ever go down - never up.
},
/**
* Please don't add anything new!
*/
];
add_task(async function() {
await ensureNoPreloadedBrowser();
@ -96,8 +71,10 @@ add_task(async function() {
for (let button of navButtons) {
info("Click " + button.id);
let promiseViewShown = BrowserTestUtils.waitForEvent(PanelUI.panel,
"ViewShown");
button.click();
await BrowserTestUtils.waitForEvent(PanelUI.panel, "ViewShown");
let viewShownEvent = await promiseViewShown;
// Workaround until bug 1363756 is fixed, then this can be removed.
let container = PanelUI.multiView.querySelector(".panel-viewcontainer");
@ -105,10 +82,12 @@ add_task(async function() {
return !container.hasAttribute("width");
});
info("Shown " + PanelUI.multiView.current.id);
await openSubViewsRecursively(PanelUI.multiView.current);
info("Shown " + viewShownEvent.originalTarget.id);
await openSubViewsRecursively(viewShownEvent.originalTarget);
promiseViewShown = BrowserTestUtils.waitForEvent(currentView,
"ViewShown");
PanelUI.multiView.goBack();
await BrowserTestUtils.waitForEvent(PanelUI.panel, "ViewShown");
await promiseViewShown;
// Workaround until bug 1363756 is fixed, then this can be removed.
await BrowserTestUtils.waitForCondition(() => {
@ -122,5 +101,5 @@ add_task(async function() {
let hidden = BrowserTestUtils.waitForEvent(PanelUI.panel, "popuphidden");
PanelUI.hide();
await hidden;
}, EXPECTED_APPMENU_SUBVIEW_REFLOWS);
}, []);
});

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

@ -97,4 +97,8 @@ tags = mcb
support-files =
../general/moz.png
test_no_mcb_for_loopback.html
[browser_no_mcb_for_onions.js]
tags = mcb
support-files =
test_no_mcb_for_onions.html
[browser_check_identity_state.js]

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

@ -0,0 +1,39 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// The test loads a HTTPS web page with active content from HTTP .onion URLs
// and makes sure that the mixed content flags on the docshell are not set.
//
// Note that the URLs referenced within the test page intentionally use the
// unassigned port 8 because we don't want to actually load anything, we just
// want to check that the URLs are not blocked.
const TEST_URL = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "test_no_mcb_for_onions.html";
const PREF_BLOCK_DISPLAY = "security.mixed_content.block_display_content";
const PREF_BLOCK_ACTIVE = "security.mixed_content.block_active_content";
const PREF_ONION_WHITELIST = "dom.securecontext.whitelist_onions";
add_task(async function allowOnionMixedContent() {
registerCleanupFunction(function() {
gBrowser.removeCurrentTab();
});
await SpecialPowers.pushPrefEnv({set: [[PREF_BLOCK_DISPLAY, true]]});
await SpecialPowers.pushPrefEnv({set: [[PREF_BLOCK_ACTIVE, true]]});
await SpecialPowers.pushPrefEnv({set: [[PREF_ONION_WHITELIST, true]]});
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
const browser = gBrowser.getBrowserForTab(tab);
await ContentTask.spawn(browser, null, function() {
is(docShell.hasMixedDisplayContentBlocked, false, "hasMixedDisplayContentBlocked not set");
is(docShell.hasMixedActiveContentBlocked, false, "hasMixedActiveContentBlocked not set");
});
await assertMixedContentBlockingState(browser, {
activeBlocked: false,
activeLoaded: false,
passiveLoaded: false,
});
});

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

@ -0,0 +1,28 @@
<!-- See browser_no_mcb_for_onions.js -->
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf8">
<title>Bug 1382359</title>
</head>
<style>
@font-face {
src: url("http://123456789abcdef.onion:8/test.ttf");
}
</style>
<body>
<img src="http://123456789abcdef.onion:8/test.png">
<iframe src="http://123456789abcdef.onion:8/test.html"></iframe>
</body>
<script src="http://123456789abcdef.onion:8/test.js"></script>
<link href="http://123456789abcdef.onion:8/test.css" rel="stylesheet"></link>
<script>
fetch("http://123456789abcdef.onion:8");
</script>
</html>

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

@ -90,10 +90,6 @@ var whitelist = [
// browser/extensions/pdfjs/content/web/viewer.js
{file: "resource://pdf.js/build/pdf.worker.js"},
// browser/components/newtab bug 1355166
{file: "resource://app/modules/NewTabSearchProvider.jsm"},
{file: "resource://app/modules/NewTabWebChannel.jsm"},
// layout/mathml/nsMathMLChar.cpp
{file: "resource://gre/res/fonts/mathfontSTIXGeneral.properties"},
{file: "resource://gre/res/fonts/mathfontUnicode.properties"},

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

@ -10,6 +10,7 @@
ChromeUtils.defineModuleGetter(this, "ExtensionParent",
"resource://gre/modules/ExtensionParent.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
var {
@ -88,18 +89,16 @@ var gBrowser = {
},
};
function loadWebPanel() {
let sidebarURI = new URL(location);
async function loadPanel(extensionId, extensionUrl, browserStyle) {
let policy = WebExtensionPolicy.getByID(extensionId);
let sidebar = {
uri: sidebarURI.searchParams.get("panel"),
remote: sidebarURI.searchParams.get("remote"),
browserStyle: sidebarURI.searchParams.get("browser-style"),
uri: extensionUrl,
remote: policy.extension.remote,
browserStyle,
};
getBrowser(sidebar).then(browser => {
browser.loadURI(sidebar.uri);
let uri = Services.io.newURI(policy.getURL());
let triggeringPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
browser.loadURIWithFlags(extensionUrl, {triggeringPrincipal});
});
}
function load() {
this.loadWebPanel();
}

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

@ -18,8 +18,7 @@
<page id="webextpanels-window"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="load()">
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
<script type="application/javascript" src="chrome://browser/content/browser.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-places.js"/>

Двоичные данные
browser/branding/nightly/dsstore

Двоичный файл не отображается.

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

@ -1802,34 +1802,18 @@ var CustomizableUIInternal = {
}
}
// We can't use event.target because we might have passed a panelview
// anonymous content boundary as well, and so target points to the
// panelmultiview in that case. Unfortunately, this means we get
// anonymous child nodes instead of the real ones, so looking for the
// 'stoooop, don't close me' attributes is more involved.
// We can't use event.target because we might have passed an anonymous
// content boundary as well, and so target points to the outer element in
// that case. Unfortunately, this means we get anonymous child nodes instead
// of the real ones, so looking for the 'stoooop, don't close me' attributes
// is more involved.
let target = aEvent.originalTarget;
let closemenu = "auto";
let widgetType = "button";
while (target.parentNode && target.localName != "panel") {
closemenu = target.getAttribute("closemenu");
widgetType = target.getAttribute("widget-type");
if (closemenu == "none" || closemenu == "single" ||
widgetType == "view") {
break;
}
target = target.parentNode;
}
if (closemenu == "none" || widgetType == "view") {
return;
}
if (closemenu == "single") {
let panel = this._getPanelForNode(target);
let multiview = panel.querySelector("panelmultiview");
if (multiview.showingSubView) {
multiview.goBack();
if (target.getAttribute("closemenu") == "none" ||
target.getAttribute("widget-type") == "view") {
return;
}
target = target.parentNode;
}
// If we get here, we can actually hide the popup:

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

@ -62,12 +62,14 @@
* visible, but a visible view may be inactive. For example, during a scroll
* transition, both views will be inactive.
*
* When a view becomes active, the ViewShown event is fired synchronously.
* For the main view of the panel, this happens during the "popupshown"
* event, which means that other "popupshown" handlers may be called before
* the view is active. However, the main view can already receive mouse and
* keyboard events at this point, only because this allows regression tests
* to use the "popupshown" event to simulate interaction.
* When a view becomes active, the ViewShown event is fired synchronously,
* and the showSubView and goBack methods can be called for navigation.
*
* For the main view of the panel, the ViewShown event is dispatched during
* the "popupshown" event, which means that other "popupshown" handlers may
* be called before the view is active. Thus, code that needs to perform
* further navigation automatically should either use the ViewShown event or
* wait for an event loop tick, like BrowserTestUtils.waitForEvent does.
*
* -- Navigating with the keyboard
*
@ -93,10 +95,6 @@
* Currently visible view
*
* Open views
*
* If the <panelmultiview> element is "ephemeral", imported subviews will be
* moved out again to the element specified by the viewCacheId attribute, so
* that the panel element can be removed safely.
*/
"use strict";
@ -128,7 +126,6 @@ const TRANSITION_PHASES = Object.freeze({
START: 1,
PREPARE: 2,
TRANSITION: 3,
END: 4
});
let gNodeToObjectMap = new WeakMap();
@ -307,6 +304,10 @@ var PanelMultiView = class extends this.AssociatedToNode {
* Removes the specified <panel> from the document, ensuring that any
* <panelmultiview> node it contains is destroyed properly.
*
* If the viewCacheId attribute is present on the <panelmultiview> element,
* imported subviews will be moved out again to the element it specifies, so
* that the panel element can be removed safely.
*
* If the panel does not contain a <panelmultiview>, it is removed directly.
* This allows consumers like page actions to accept different panel types.
*/
@ -314,7 +315,9 @@ var PanelMultiView = class extends this.AssociatedToNode {
try {
let panelMultiViewNode = panelNode.querySelector("panelmultiview");
if (panelMultiViewNode) {
this.forNode(panelMultiViewNode).disconnect();
let panelMultiView = this.forNode(panelMultiViewNode);
panelMultiView._moveOutKids();
panelMultiView.disconnect();
}
} finally {
// Make sure to remove the panel element even if disconnecting fails.
@ -345,18 +348,7 @@ var PanelMultiView = class extends this.AssociatedToNode {
return this.node.parentNode;
}
get _mainViewId() {
return this.node.getAttribute("mainViewId");
}
get _mainView() {
return this.document.getElementById(this._mainViewId);
}
get _transitioning() {
return this.__transitioning;
}
set _transitioning(val) {
this.__transitioning = val;
if (val) {
this.node.setAttribute("transitioning", "true");
} else {
@ -364,38 +356,12 @@ var PanelMultiView = class extends this.AssociatedToNode {
}
}
/**
* @return {Boolean} |true| when the 'ephemeral' attribute is set, which means
* that this instance should be ready to be thrown away at
* any time.
*/
get _ephemeral() {
return this.node.hasAttribute("ephemeral");
}
get _screenManager() {
if (this.__screenManager)
return this.__screenManager;
return this.__screenManager = Cc["@mozilla.org/gfx/screenmanager;1"]
.getService(Ci.nsIScreenManager);
}
/**
* @return {panelview} the currently visible subview OR the subview that is
* about to be shown whilst a 'ViewShowing' event is being
* dispatched.
*/
get current() {
return this.node && this._currentSubView;
}
get _currentSubView() {
// Peek the top of the stack, but fall back to the main view if the list of
// opened views is currently empty.
let panelView = this.openViews[this.openViews.length - 1];
return (panelView && panelView.node) || this._mainView;
}
get showingSubView() {
return this.openViews.length > 1;
}
constructor(node) {
super(node);
@ -428,12 +394,6 @@ var PanelMultiView = class extends this.AssociatedToNode {
this.node.prepend(viewContainer);
this.openViews = [];
this.__transitioning = false;
XPCOMUtils.defineLazyGetter(this, "_panelViewCache", () => {
let viewCacheId = this.node.getAttribute("viewCacheId");
return viewCacheId ? this.document.getElementById(viewCacheId) : null;
});
this._panel.addEventListener("popupshowing", this);
this._panel.addEventListener("popuppositioned", this);
@ -452,12 +412,6 @@ var PanelMultiView = class extends this.AssociatedToNode {
value: (...args) => this[method](...args)
});
});
["current", "showingSubView"].forEach(property => {
Object.defineProperty(this.node, property, {
enumerable: true,
get: () => this[property]
});
});
}
disconnect() {
@ -465,15 +419,6 @@ var PanelMultiView = class extends this.AssociatedToNode {
if (!this.node || !this.connected)
return;
this._cleanupTransitionPhase();
let mainView = this._mainView;
if (mainView) {
if (this._panelViewCache)
this._panelViewCache.appendChild(mainView);
mainView.removeAttribute("mainview");
}
this._moveOutKids(this._viewStack);
this._panel.removeEventListener("mousemove", this);
this._panel.removeEventListener("popupshowing", this);
this._panel.removeEventListener("popuppositioned", this);
@ -482,7 +427,7 @@ var PanelMultiView = class extends this.AssociatedToNode {
this.window.removeEventListener("keydown", this);
this.node = this._openPopupPromise = this._openPopupCancelCallback =
this._viewContainer = this._viewStack = this.__dwu =
this._panelViewCache = this._transitionDetails = null;
this._transitionDetails = null;
}
/**
@ -621,22 +566,21 @@ var PanelMultiView = class extends this.AssociatedToNode {
}
/**
* Remove any child subviews into the panelViewCache, to ensure
* they remain usable even if this panelmultiview instance is removed
* from the DOM.
* @param viewNodeContainer the container from which to remove subviews
* Move any child subviews into the element defined by "viewCacheId" to make
* sure they will not be removed together with the <panelmultiview> element.
*/
_moveOutKids(viewNodeContainer) {
if (!this._panelViewCache)
_moveOutKids() {
let viewCacheId = this.node.getAttribute("viewCacheId");
if (!viewCacheId) {
return;
}
// Node.children and Node.childNodes is live to DOM changes like the
// ones we're about to do, so iterate over a static copy:
let subviews = Array.from(viewNodeContainer.childNodes);
let subviews = Array.from(this._viewStack.childNodes);
let viewCache = this.document.getElementById(viewCacheId);
for (let subview of subviews) {
// XBL lists the 'children' XBL element explicitly. :-(
if (subview.nodeName != "children")
this._panelViewCache.appendChild(subview);
viewCache.appendChild(subview);
}
}
@ -661,32 +605,73 @@ var PanelMultiView = class extends this.AssociatedToNode {
return;
}
if (!this.openViews.length) {
Cu.reportError(new Error(`Cannot show a subview in a closed panel.`));
return;
}
let prevPanelView = this.openViews[this.openViews.length - 1];
let nextPanelView = PanelView.forNode(viewNode);
if (this.openViews.includes(nextPanelView)) {
Cu.reportError(new Error(`Subview ${viewNode.id} is already open.`));
return;
}
if (!(await this._openView(nextPanelView))) {
// Do not re-enter the process if navigation is already in progress. Since
// there is only one active view at any given time, we can do this check
// safely, even considering that during the navigation process the actual
// view to which prevPanelView refers will change.
if (!prevPanelView.active) {
return;
}
// Marking the view that is about to scrolled out of the visible area as
// inactive will prevent re-entrancy and also disable keyboard navigation.
// From this point onwards, "await" statements can be used safely.
prevPanelView.active = false;
prevPanelView.captureKnownSize();
// The main view of a panel can be a subview in another one. Make sure to
// reset all the properties that may be set on a subview.
nextPanelView.mainview = false;
// The header may change based on how the subview was opened.
nextPanelView.headerText = viewNode.getAttribute("title") ||
(anchor && anchor.getAttribute("label"));
// The constrained width of subviews may also vary between panels.
nextPanelView.minMaxWidth = prevPanelView.knownWidth;
// Provide visual feedback while navigation is in progress, starting before
// the transition starts and ending when the previous view is invisible.
if (anchor) {
viewNode.classList.add("PanelUI-subView");
anchor.setAttribute("open", "true");
}
try {
// If the ViewShowing event cancels the operation we have to re-enable
// keyboard navigation, but this must be avoided if the panel was closed.
if (!(await this._openView(nextPanelView))) {
if (prevPanelView.isOpenIn(this)) {
// We don't raise a ViewShown event because nothing actually changed.
// Technically we should use a different state flag just because there
// is code that could check the "active" property to determine whether
// to wait for a ViewShown event later, but this only happens in
// regression tests and is less likely to be a technique used in
// production code, where use of ViewShown is less common.
prevPanelView.active = true;
}
return;
}
prevPanelView.captureKnownSize();
// The main view of a panel can be a subview in another one. Make sure to
// reset all the properties that may be set on a subview.
nextPanelView.mainview = false;
// The header may change based on how the subview was opened.
nextPanelView.headerText = viewNode.getAttribute("title") ||
(anchor && anchor.getAttribute("label"));
// The constrained width of subviews may also vary between panels.
nextPanelView.minMaxWidth = prevPanelView.knownWidth;
if (anchor) {
viewNode.classList.add("PanelUI-subView");
}
await this._transitionViews(prevPanelView.node, viewNode, false, anchor);
} finally {
if (anchor) {
anchor.removeAttribute("open");
}
}
await this._transitionViews(prevPanelView.node, viewNode, false, anchor);
this._activateView(nextPanelView);
}
@ -706,6 +691,14 @@ var PanelMultiView = class extends this.AssociatedToNode {
let prevPanelView = this.openViews[this.openViews.length - 1];
let nextPanelView = this.openViews[this.openViews.length - 2];
// Like in the showSubView method, do not re-enter navigation while it is
// in progress, and make the view inactive immediately. From this point
// onwards, "await" statements can be used safely.
if (!prevPanelView.active) {
return;
}
prevPanelView.active = false;
prevPanelView.captureKnownSize();
await this._transitionViews(prevPanelView.node, nextPanelView.node, true);
@ -718,11 +711,8 @@ var PanelMultiView = class extends this.AssociatedToNode {
* Prepares the main view before showing the panel.
*/
async _showMainView() {
if (!this.node || !this._mainViewId) {
return false;
}
let nextPanelView = PanelView.forNode(this._mainView);
let nextPanelView = PanelView.forNode(this.document.getElementById(
this.node.getAttribute("mainViewId")));
// If the view is already open in another panel, close the panel first.
let oldPanelMultiViewNode = nextPanelView.node.panelMultiView;
@ -744,7 +734,7 @@ var PanelMultiView = class extends this.AssociatedToNode {
nextPanelView.headerText = "";
nextPanelView.minMaxWidth = 0;
await this._cleanupTransitionPhase();
// Ensure the view will be visible once the panel is opened.
nextPanelView.visible = true;
nextPanelView.descriptionHeightWorkaround();
@ -755,6 +745,9 @@ var PanelMultiView = class extends this.AssociatedToNode {
* Opens the specified PanelView and dispatches the ViewShowing event, which
* can be used to populate the subview or cancel the operation.
*
* This also clears all the attributes and styles that may be left by a
* transition that was interrupted.
*
* @resolves With true if the view was opened, false otherwise.
*/
async _openView(panelView) {
@ -783,6 +776,13 @@ var PanelMultiView = class extends this.AssociatedToNode {
return false;
}
// Clean up all the attributes and styles related to transitions. We do this
// here rather than when the view is closed because we are likely to make
// other DOM modifications soon, which isn't the case when closing.
let { style } = panelView.node;
style.removeProperty("outline");
style.removeProperty("width");
return true;
}
@ -791,7 +791,7 @@ var PanelMultiView = class extends this.AssociatedToNode {
* view was closed in the meantime.
*/
_activateView(panelView) {
if (panelView.node.panelMultiView == this.node) {
if (panelView.isOpenIn(this)) {
panelView.active = true;
panelView.dispatchCustomEvent("ViewShown");
}
@ -809,7 +809,8 @@ var PanelMultiView = class extends this.AssociatedToNode {
panelView.dispatchCustomEvent("ViewHiding");
panelView.node.panelMultiView = null;
// Views become invisible synchronously when they are closed, and they won't
// become visible again until they are opened.
// become visible again until they are opened. When this is called at the
// end of backwards navigation, the view is already invisible.
panelView.visible = false;
}
@ -830,41 +831,24 @@ var PanelMultiView = class extends this.AssociatedToNode {
* is and the active panelview slides in from the left in LTR mode, right in
* RTL mode.
*
* @param {panelview} previousViewNode Node that is currently shown as active,
* but is about to be transitioned away.
* @param {panelview} previousViewNode Node that is currently displayed, but
* is about to be transitioned away. This
* must be already inactive at this point.
* @param {panelview} viewNode Node that will becode the active view,
* after the transition has finished.
* @param {Boolean} reverse Whether we're navigation back to a
* previous view or forward to a next view.
* @param {Element} anchor the anchor for which we're opening
* a new panelview, if any
*/
async _transitionViews(previousViewNode, viewNode, reverse, anchor) {
// Clean up any previous transition that may be active at this point.
await this._cleanupTransitionPhase();
// There's absolutely no need to show off our epic animation skillz when
// the panel's not even open.
if (this._panel.state != "open") {
return;
}
async _transitionViews(previousViewNode, viewNode, reverse) {
const { window } = this;
let nextPanelView = PanelView.forNode(viewNode);
let prevPanelView = PanelView.forNode(previousViewNode);
if (this._autoResizeWorkaroundTimer)
window.clearTimeout(this._autoResizeWorkaroundTimer);
let details = this._transitionDetails = {
phase: TRANSITION_PHASES.START,
previousViewNode, viewNode, reverse, anchor
};
if (anchor)
anchor.setAttribute("open", "true");
// Set the viewContainer dimensions to make sure only the current view is
// visible.
let olderView = reverse ? nextPanelView : prevPanelView;
@ -884,8 +868,10 @@ var PanelMultiView = class extends this.AssociatedToNode {
height: nextPanelView.knownHeight };
nextPanelView.visible = true;
} else if (viewNode.customRectGetter) {
// Can't use Object.assign directly with a DOM Rect object because its properties
// aren't enumerable.
// We use a customRectGetter for WebExtensions panels, because they need
// to query the size from an embedded browser. The presence of this
// getter also provides an indication that the view node shouldn't be
// moved around, otherwise the state of the browser would get disrupted.
let width = prevPanelView.knownWidth;
let height = prevPanelView.knownHeight;
viewRect = Object.assign({height, width}, viewNode.customRectGetter());
@ -894,27 +880,28 @@ var PanelMultiView = class extends this.AssociatedToNode {
viewRect.height += this._dwu.getBoundsWithoutFlushing(header).height;
}
nextPanelView.visible = true;
nextPanelView.descriptionHeightWorkaround();
await nextPanelView.descriptionHeightWorkaround();
} else {
let oldSibling = viewNode.nextSibling || null;
this._offscreenViewStack.style.minHeight = olderView.knownHeight + "px";
this._offscreenViewStack.appendChild(viewNode);
nextPanelView.visible = true;
// Now that the subview is visible, we can check the height of the
// description elements it contains.
nextPanelView.descriptionHeightWorkaround();
await nextPanelView.descriptionHeightWorkaround();
viewRect = await window.promiseDocumentFlushed(() => {
return this._dwu.getBoundsWithoutFlushing(viewNode);
});
try {
this._viewStack.insertBefore(viewNode, oldSibling);
} catch (ex) {
this._viewStack.appendChild(viewNode);
// Bail out if the panel was closed in the meantime.
if (!nextPanelView.isOpenIn(this)) {
return;
}
// Place back the view after all the other views that are already open in
// order for the transition to work as expected.
this._viewStack.appendChild(viewNode);
this._offscreenViewStack.style.removeProperty("min-height");
}
@ -945,6 +932,10 @@ var PanelMultiView = class extends this.AssociatedToNode {
// Now that all the elements are in place for the start of the transition,
// give the layout code a chance to set the initial values.
await window.promiseDocumentFlushed(() => {});
// Bail out if the panel was closed in the meantime.
if (!nextPanelView.isOpenIn(this)) {
return;
}
// Now set the viewContainer dimensions to that of the new view, which
// kicks of the height animation.
@ -956,14 +947,6 @@ var PanelMultiView = class extends this.AssociatedToNode {
// sliding animation with smaller views.
viewNode.style.width = viewRect.width + "px";
// For proper bookkeeping, mark the view that is about to scrolled out of
// the visible area as inactive, because it won't be possible to simulate
// mouse events on it properly. In practice this isn't important, because we
// use the separate "transitioning" attribute on the panel to suppress
// pointer events. This allows mouse events to be available for the main
// view in regression tests that wait for the "popupshown" event.
prevPanelView.active = false;
// Kick off the transition!
details.phase = TRANSITION_PHASES.TRANSITION;
this._viewStack.style.transform = "translateX(" + (moveToLeft ? "" : "-") + deltaX + "px)";
@ -989,69 +972,46 @@ var PanelMultiView = class extends this.AssociatedToNode {
});
});
details.phase = TRANSITION_PHASES.END;
// Apply the final visibility, unless the view was closed in the meantime.
if (nextPanelView.node.panelMultiView == this.node) {
prevPanelView.visible = false;
// Bail out if the panel was closed during the transition.
if (!nextPanelView.isOpenIn(this)) {
return;
}
prevPanelView.visible = false;
// This will complete the operation by removing any transition properties.
await this._cleanupTransitionPhase(details);
nextPanelView.node.style.removeProperty("width");
deepestNode.style.removeProperty("outline");
this._cleanupTransitionPhase();
// Focus the correct element, unless the view was closed in the meantime.
if (nextPanelView.node.panelMultiView == this.node) {
nextPanelView.focusSelectedElement();
}
nextPanelView.focusSelectedElement();
}
/**
* Attempt to clean up the attributes and properties set by `_transitionViews`
* above. Which attributes and properties depends on the phase the transition
* was left from - normally that'd be `TRANSITION_PHASES.END`.
*
* @param {Object} details Dictionary object containing details of the transition
* that should be cleaned up after. Defaults to the most
* recent details.
* was left from.
*/
async _cleanupTransitionPhase(details = this._transitionDetails) {
if (!details || !this.node)
_cleanupTransitionPhase() {
if (!this._transitionDetails) {
return;
}
let {phase, previousViewNode, viewNode, reverse, resolve, listener, cancelListener, anchor} = details;
if (details == this._transitionDetails)
this._transitionDetails = null;
// Do the things we _always_ need to do whenever the transition ends or is
// interrupted.
if (anchor)
anchor.removeAttribute("open");
let {phase, resolve, listener, cancelListener} = this._transitionDetails;
this._transitionDetails = null;
if (phase >= TRANSITION_PHASES.START) {
this._panel.removeAttribute("width");
this._panel.removeAttribute("height");
// Myeah, panel layout auto-resizing is a funky thing. We'll wait
// another few milliseconds to remove the width and height 'fixtures',
// to be sure we don't flicker annoyingly.
// NB: HACK! Bug 1363756 is there to fix this.
this._autoResizeWorkaroundTimer = this.window.setTimeout(() => {
if (!this._viewContainer)
return;
this._viewContainer.style.removeProperty("height");
this._viewContainer.style.removeProperty("width");
}, 500);
this._viewContainer.style.removeProperty("height");
this._viewContainer.style.removeProperty("width");
}
if (phase >= TRANSITION_PHASES.PREPARE) {
this._transitioning = false;
if (reverse)
this._viewStack.style.removeProperty("margin-inline-start");
let deepestNode = reverse ? previousViewNode : viewNode;
deepestNode.style.removeProperty("outline");
this._viewStack.style.removeProperty("margin-inline-start");
this._viewStack.style.removeProperty("transition");
}
if (phase >= TRANSITION_PHASES.TRANSITION) {
this._viewStack.style.removeProperty("transform");
viewNode.style.removeProperty("width");
if (listener)
this._viewContainer.removeEventListener("transitionend", listener);
if (cancelListener)
@ -1059,13 +1019,6 @@ var PanelMultiView = class extends this.AssociatedToNode {
if (resolve)
resolve();
}
if (phase >= TRANSITION_PHASES.END) {
// We force 'display: none' on the previous view node to make sure that it
// doesn't cause an annoying flicker whilst resetting the styles above.
previousViewNode.style.display = "none";
await this.window.promiseDocumentFlushed(() => {});
previousViewNode.style.removeProperty("display");
}
}
_calculateMaxHeight() {
@ -1114,10 +1067,11 @@ var PanelMultiView = class extends this.AssociatedToNode {
}
switch (aEvent.type) {
case "keydown":
if (!this._transitioning) {
PanelView.forNode(this._currentSubView)
.keyNavigation(aEvent, this._dir);
}
// Since we start listening for the "keydown" event when the popup is
// already showing and stop listening when the panel is hidden, we
// always have at least one view open.
let currentView = this.openViews[this.openViews.length - 1];
currentView.keyNavigation(aEvent, this._dir);
break;
case "mousemove":
this.openViews.forEach(panelView => panelView.clearNavigation());
@ -1148,10 +1102,13 @@ var PanelMultiView = class extends this.AssociatedToNode {
break;
}
case "popupshown":
let mainPanelView = PanelView.forNode(this._mainView);
// Now that the main view is visible, we can check the height of the
// description elements it contains.
mainPanelView.descriptionHeightWorkaround();
// The main view is always open and visible when the panel is first
// shown, so we can check the height of the description elements it
// contains and notify consumers using the ViewShown event. In order to
// minimize flicker we need to allow synchronous reflows, and we still
// make sure the ViewShown event is dispatched synchronously.
let mainPanelView = this.openViews[0];
mainPanelView.descriptionHeightWorkaround(true).catch(Cu.reportError);
this._activateView(mainPanelView);
break;
case "popuphidden": {
@ -1192,6 +1149,13 @@ var PanelView = class extends this.AssociatedToNode {
this.active = false;
}
/**
* Indicates whether the view is open in the specified PanelMultiView object.
*/
isOpenIn(panelMultiView) {
return this.node.panelMultiView == panelMultiView.node;
}
/**
* The "mainview" attribute is set before the panel is opened when this view
* is displayed as the main view, and is removed before the <panelview> is
@ -1305,9 +1269,12 @@ var PanelView = class extends this.AssociatedToNode {
* of any of these elements changes, this function should be called to
* refresh the calculated heights.
*
* This may trigger a synchronous layout.
* @param allowSyncReflows
* If set to true, the function takes a path that allows synchronous
* reflows, but minimizes flickering. This is used for the main view
* because we cannot use the workaround off-screen.
*/
descriptionHeightWorkaround() {
async descriptionHeightWorkaround(allowSyncReflows = false) {
if (!this.node.hasAttribute("descriptionheightworkaround")) {
// This view does not require the workaround.
return;
@ -1317,34 +1284,41 @@ var PanelView = class extends this.AssociatedToNode {
// First we reset any change we may have made previously. The first time
// this is called, and in the best case scenario, this has no effect.
let items = [];
// Non-hidden <label> or <description> elements that also aren't empty
// and also don't have a value attribute can be multiline (if their
// text content is long enough).
let isMultiline = ":not(:-moz-any([hidden],[value],:empty))";
let selector = [
"description" + isMultiline,
"label" + isMultiline,
"toolbarbutton[wrap]:not([hidden])",
].join(",");
for (let element of this.node.querySelectorAll(selector)) {
// Ignore items in hidden containers.
if (element.closest("[hidden]")) {
continue;
}
// Take the label for toolbarbuttons; it only exists on those elements.
element = element.labelElement || element;
let collectItems = () => {
// Non-hidden <label> or <description> elements that also aren't empty
// and also don't have a value attribute can be multiline (if their
// text content is long enough).
let isMultiline = ":not(:-moz-any([hidden],[value],:empty))";
let selector = [
"description" + isMultiline,
"label" + isMultiline,
"toolbarbutton[wrap]:not([hidden])",
].join(",");
for (let element of this.node.querySelectorAll(selector)) {
// Ignore items in hidden containers.
if (element.closest("[hidden]")) {
continue;
}
// Take the label for toolbarbuttons; it only exists on those elements.
element = element.labelElement || element;
let bounds = element.getBoundingClientRect();
let previous = gMultiLineElementsMap.get(element);
// We don't need to (re-)apply the workaround for invisible elements or
// on elements we've seen before and haven't changed in the meantime.
if (!bounds.width || !bounds.height ||
(previous && element.textContent == previous.textContent &&
bounds.width == previous.bounds.width)) {
continue;
}
let bounds = element.getBoundingClientRect();
let previous = gMultiLineElementsMap.get(element);
// We don't need to (re-)apply the workaround for invisible elements or
// on elements we've seen before and haven't changed in the meantime.
if (!bounds.width || !bounds.height ||
(previous && element.textContent == previous.textContent &&
bounds.width == previous.bounds.width)) {
continue;
}
items.push({ element });
items.push({ element });
}
};
if (allowSyncReflows) {
collectItems();
} else {
await this.window.promiseDocumentFlushed(collectItems);
}
// Removing the 'height' property will only cause a layout flush in the next
@ -1355,8 +1329,15 @@ var PanelView = class extends this.AssociatedToNode {
// We now read the computed style to store the height of any element that
// may contain wrapping text.
for (let item of items) {
item.bounds = item.element.getBoundingClientRect();
let measureItems = () => {
for (let item of items) {
item.bounds = item.element.getBoundingClientRect();
}
};
if (allowSyncReflows) {
measureItems();
} else {
await this.window.promiseDocumentFlushed(measureItems);
}
// Now we can make all the necessary DOM changes at once.
@ -1466,11 +1447,18 @@ var PanelView = class extends this.AssociatedToNode {
* - The Right key functions the same as the Enter key, simulating a click
* - The Left key triggers a navigation back to the previous view.
*
* Key navigation is only enabled while the view is active, meaning that this
* method will return early if it is invoked during a sliding transition.
*
* @param {KeyEvent} event
* @param {String} dir
* Direction for arrow navigation, either "ltr" or "rtl".
*/
keyNavigation(event, dir) {
if (!this.active) {
return;
}
let buttons = this.buttons;
if (!buttons || !buttons.length) {
buttons = this.buttons = this.getNavigableElements();

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

@ -410,7 +410,6 @@ const PanelUI = {
multiView.setAttribute("id", "customizationui-widget-multiview");
multiView.setAttribute("viewCacheId", "appMenu-viewCache");
multiView.setAttribute("mainViewId", viewNode.id);
multiView.setAttribute("ephemeral", true);
tempPanel.appendChild(multiView);
viewNode.classList.add("cui-widget-panelview");

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

@ -61,12 +61,13 @@ async function openPopup(panelIndex, viewIndex) {
gPanelMultiViews[panelIndex].setAttribute("mainViewId",
gPanelViews[viewIndex].id);
let promiseShown = BrowserTestUtils.waitForEvent(gPanels[panelIndex],
"popupshown");
let promiseShown = BrowserTestUtils.waitForEvent(gPanelViews[viewIndex],
"ViewShown");
PanelMultiView.openPopup(gPanels[panelIndex], gPanelAnchors[panelIndex],
"bottomcenter topright");
await promiseShown;
Assert.ok(PanelView.forNode(gPanelViews[viewIndex]).active);
assertLabelVisible(viewIndex, true);
}
@ -92,6 +93,7 @@ async function showSubView(panelIndex, viewIndex) {
gPanelMultiViews[panelIndex].showSubView(gPanelViews[viewIndex]);
await promiseShown;
Assert.ok(PanelView.forNode(gPanelViews[viewIndex]).active);
assertLabelVisible(viewIndex, true);
}
@ -104,6 +106,7 @@ async function goBack(panelIndex, viewIndex) {
gPanelMultiViews[panelIndex].goBack();
await promiseShown;
Assert.ok(PanelView.forNode(gPanelViews[viewIndex]).active);
assertLabelVisible(viewIndex, true);
}
@ -278,6 +281,38 @@ add_task(async function test_simple_event_sequence() {
]);
});
/**
* Tests that further navigation is suppressed until the new view is shown.
*/
add_task(async function test_navigation_suppression() {
await openPopup(0, 0);
// Test re-entering the "showSubView" method.
let promiseShown = BrowserTestUtils.waitForEvent(gPanelViews[1], "ViewShown");
gPanelMultiViews[0].showSubView(gPanelViews[1]);
Assert.ok(!PanelView.forNode(gPanelViews[0]).active,
"The previous view should become inactive synchronously.");
// The following call will have no effect.
gPanelMultiViews[0].showSubView(gPanelViews[2]);
await promiseShown;
// Test re-entering the "goBack" method.
promiseShown = BrowserTestUtils.waitForEvent(gPanelViews[0], "ViewShown");
gPanelMultiViews[0].goBack();
Assert.ok(!PanelView.forNode(gPanelViews[1]).active,
"The previous view should become inactive synchronously.");
// The following call will have no effect.
gPanelMultiViews[0].goBack();
await promiseShown;
// Main view 0 should be displayed.
assertLabelVisible(0, true);
await hidePopup(0);
});
/**
* Tests reusing views that are already open in another panel. In this test, the
* structure of the first panel will change dynamically:

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

@ -316,7 +316,7 @@ class BasePopup {
stylesheets: this.STYLESHEETS,
});
browser.loadURI(popupURL);
browser.loadURIWithFlags(popupURL, {triggeringPrincipal: this.extension.principal});
});
}

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

@ -264,7 +264,9 @@ class ParentDevToolsPanel {
},
});
browser.loadURI(url);
browser.loadURIWithFlags(url, {
triggeringPrincipal: extension.principal,
});
}
destroyBrowserElement() {

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

@ -176,7 +176,9 @@ class DevToolsPage extends HiddenExtensionPage {
},
});
this.browser.loadURI(this.url);
this.browser.loadURIWithFlags(this.url, {
triggeringPrincipal: this.extension.principal,
});
await this.waitForTopLevelContext;
}

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

@ -136,20 +136,6 @@ this.sidebarAction = class extends ExtensionAPI {
}
}
sidebarUrl(panel) {
let url = `${sidebarURL}?panel=${encodeURIComponent(panel)}`;
if (this.extension.remote) {
url += "&remote=1";
}
if (this.browserStyle) {
url += "&browser-style=1";
}
return url;
}
createMenuItem(window, details) {
let {document, SidebarUI} = window;
@ -161,7 +147,12 @@ this.sidebarAction = class extends ExtensionAPI {
broadcaster.setAttribute("type", "checkbox");
broadcaster.setAttribute("group", "sidebar");
broadcaster.setAttribute("label", details.title);
broadcaster.setAttribute("sidebarurl", this.sidebarUrl(details.panel));
broadcaster.setAttribute("sidebarurl", sidebarURL);
broadcaster.setAttribute("panel", details.panel);
if (this.browserStyle) {
broadcaster.setAttribute("browserStyle", "true");
}
broadcaster.setAttribute("extensionId", this.extension.id);
let id = `ext-key-id-${this.id}`;
broadcaster.setAttribute("key", id);
@ -227,10 +218,9 @@ this.sidebarAction = class extends ExtensionAPI {
broadcaster.setAttribute("tooltiptext", title);
broadcaster.setAttribute("label", title);
let url = this.sidebarUrl(tabData.panel);
let urlChanged = url !== broadcaster.getAttribute("sidebarurl");
let urlChanged = tabData.panel !== broadcaster.getAttribute("panel");
if (urlChanged) {
broadcaster.setAttribute("sidebarurl", url);
broadcaster.setAttribute("panel", tabData.panel);
}
this.setMenuIcon(menu, tabData);

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

@ -507,10 +507,13 @@ this.tabs = class extends ExtensionAPI {
return Promise.reject({message: `Illegal URL: ${url}`});
}
let flags = updateProperties.loadReplace
? Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY
: Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
nativeTab.linkedBrowser.loadURIWithFlags(url, {flags});
let options = {
flags: updateProperties.loadReplace
? Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY
: Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
triggeringPrincipal: context.principal,
};
nativeTab.linkedBrowser.loadURIWithFlags(url, options);
}
if (updateProperties.active !== null) {

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

@ -24,7 +24,7 @@
},
{
"namespace": "devtools",
"permissions": ["devtools"],
"permissions": ["manifest:devtools_page"],
"allowedContexts": ["devtools", "devtools_only"],
"defaultContexts": ["devtools", "devtools_only"]
}

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

@ -15,7 +15,7 @@
* openTabContextMenu closeTabContextMenu
* openToolsMenu closeToolsMenu
* imageBuffer imageBufferFromDataURI
* getListStyleImage getPanelForNode
* getListStyleImage getPanelForNode getPanelViewForNode
* awaitExtensionPanel awaitPopupResize
* promiseContentDimensions alterContent
* promisePrefChangeObserved openContextMenuInFrame
@ -201,6 +201,13 @@ function getPanelForNode(node) {
return node;
}
function getPanelViewForNode(node) {
while (node && node.localName != "panelview") {
node = node.parentNode;
}
return node;
}
var awaitBrowserLoaded = browser => ContentTask.spawn(browser, null, () => {
if (content.document.readyState !== "complete" ||
content.document.documentURI === "about:blank") {
@ -215,9 +222,20 @@ var awaitExtensionPanel = async function(extension, win = window, awaitLoad = tr
win.document, "WebExtPopupLoaded", true,
event => event.detail.extension.id === extension.id);
let panelview = getPanelViewForNode(browser);
let viewShownPromise = null;
if (panelview) {
let view = PanelView.forNode(panelview);
if (!view.active) {
viewShownPromise = BrowserTestUtils.waitForEvent(panelview, "ViewShown");
}
}
await Promise.all([
promisePopupShown(getPanelForNode(browser)),
viewShownPromise,
awaitLoad && awaitBrowserLoaded(browser),
]);

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

@ -1,126 +0,0 @@
"use strict";
var EXPORTED_SYMBOLS = ["NewTabPrefsProvider"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm", {});
return EventEmitter;
});
// Supported prefs and data type
const gPrefsMap = new Map([
["browser.newtabpage.enabled", "bool"],
["browser.newtabpage.enhanced", "bool"],
["browser.newtabpage.introShown", "bool"],
["browser.newtabpage.updateIntroShown", "bool"],
["browser.newtabpage.pinned", "str"],
["browser.newtabpage.blocked", "str"],
["browser.search.hiddenOneOffs", "str"],
]);
// prefs that are important for the newtab page
const gNewtabPagePrefs = new Set([
"browser.newtabpage.enabled",
"browser.newtabpage.enhanced",
"browser.newtabpage.pinned",
"browser.newtabpage.blocked",
"browser.newtabpage.introShown",
"browser.newtabpage.updateIntroShown",
"browser.search.hiddenOneOffs",
]);
let PrefsProvider = function PrefsProvider() {
EventEmitter.decorate(this);
};
PrefsProvider.prototype = {
observe(subject, topic, data) { // jshint ignore:line
if (topic === "nsPref:changed") {
if (gPrefsMap.has(data)) {
switch (gPrefsMap.get(data)) {
case "bool":
this.emit(data, Services.prefs.getBoolPref(data, false));
break;
case "str":
this.emit(data, Services.prefs.getStringPref(data, ""));
break;
case "localized":
if (Services.prefs.getPrefType(data) == Ci.nsIPrefBranch.PREF_INVALID) {
this.emit(data, "");
} else {
try {
this.emit(data, Services.prefs.getComplexValue(data, Ci.nsIPrefLocalizedString));
} catch (e) {
this.emit(data, Services.prefs.getStringPref(data));
}
}
break;
default:
this.emit(data);
break;
}
}
} else {
Cu.reportError(new Error("NewTabPrefsProvider observing unknown topic"));
}
},
/*
* Return the preferences that are important to the newtab page
*/
get newtabPagePrefs() {
let results = {};
for (let pref of gNewtabPagePrefs) {
results[pref] = null;
if (Services.prefs.getPrefType(pref) != Ci.nsIPrefBranch.PREF_INVALID) {
switch (gPrefsMap.get(pref)) {
case "bool":
results[pref] = Services.prefs.getBoolPref(pref);
break;
case "str":
results[pref] = Services.prefs.getStringPref(pref);
break;
case "localized":
try {
results[pref] = Services.prefs.getComplexValue(pref, Ci.nsIPrefLocalizedString);
} catch (e) {
results[pref] = Services.prefs.getStringPref(pref);
}
break;
}
}
}
return results;
},
get prefsMap() {
return gPrefsMap;
},
init() {
for (let pref of gPrefsMap.keys()) {
Services.prefs.addObserver(pref, this);
}
},
uninit() {
for (let pref of gPrefsMap.keys()) {
Services.prefs.removeObserver(pref, this);
}
}
};
/**
* Singleton that serves as the default new tab pref provider for the grid.
*/
const gPrefs = new PrefsProvider();
let NewTabPrefsProvider = {
prefs: gPrefs,
newtabPagePrefSet: gNewtabPagePrefs,
};

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

@ -1,15 +0,0 @@
/* exported NewTabRemoteResources */
"use strict";
var EXPORTED_SYMBOLS = ["NewTabRemoteResources"];
const NewTabRemoteResources = {
MODE_CHANNEL_MAP: {
production: {origin: "https://content.cdn.mozilla.net"},
staging: {origin: "https://s3_proxy_tiles.stage.mozaws.net"},
test: {origin: "https://example.com"},
test2: {origin: "http://mochi.test:8888"},
dev: {origin: "http://localhost:8888"}
}
};

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

@ -1,98 +0,0 @@
"use strict";
var EXPORTED_SYMBOLS = ["NewTabSearchProvider"];
const CURRENT_ENGINE = "browser-search-engine-modified";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "ContentSearch",
"resource:///modules/ContentSearch.jsm");
XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm", {});
return EventEmitter;
});
function SearchProvider() {
EventEmitter.decorate(this);
}
SearchProvider.prototype = {
observe(subject, topic, data) { // jshint unused:false
// all other topics are not relevant to content searches and can be
// ignored by NewTabSearchProvider
if (data === "engine-current" && topic === CURRENT_ENGINE) {
(async () => {
try {
let state = await ContentSearch.currentStateObj(true);
let engine = state.currentEngine;
this.emit(CURRENT_ENGINE, engine);
} catch (e) {
Cu.reportError(e);
}
})();
}
},
init() {
try {
Services.obs.addObserver(this, CURRENT_ENGINE, true);
} catch (e) {
Cu.reportError(e);
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference
]),
uninit() {
try {
Services.obs.removeObserver(this, CURRENT_ENGINE);
} catch (e) {
Cu.reportError(e);
}
},
get searchSuggestionUIStrings() {
return ContentSearch.searchSuggestionUIStrings;
},
removeFormHistory({browser}, suggestion) {
ContentSearch.removeFormHistoryEntry({target: browser}, suggestion);
},
manageEngines(browser) {
const browserWin = browser.ownerGlobal;
browserWin.openPreferences("paneSearch", { origin: "contentSearch" });
},
async asyncGetState() {
let state = await ContentSearch.currentStateObj(true);
return state;
},
async asyncPerformSearch({browser}, searchData) {
ContentSearch.performSearch({target: browser}, searchData);
await ContentSearch.addFormHistoryEntry({target: browser}, searchData.searchString);
},
async asyncCycleEngine(engineName) {
Services.search.currentEngine = Services.search.getEngineByName(engineName);
let state = await ContentSearch.currentStateObj(true);
let newEngine = state.currentEngine;
this.emit(CURRENT_ENGINE, newEngine);
},
async asyncGetSuggestions(engineName, searchString, target) {
let suggestions = ContentSearch.getSuggestions(engineName, searchString, target.browser);
return suggestions;
},
};
const NewTabSearchProvider = {
search: new SearchProvider(),
};

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

@ -1,286 +0,0 @@
"use strict";
var EXPORTED_SYMBOLS = ["NewTabWebChannel"];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "NewTabPrefsProvider",
"resource:///modules/NewTabPrefsProvider.jsm");
ChromeUtils.defineModuleGetter(this, "NewTabRemoteResources",
"resource:///modules/NewTabRemoteResources.jsm");
ChromeUtils.defineModuleGetter(this, "WebChannel",
"resource://gre/modules/WebChannel.jsm");
XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm", {});
return EventEmitter;
});
const CHAN_ID = "newtab";
const PREF_ENABLED = "browser.newtabpage.remote";
const PREF_MODE = "browser.newtabpage.remote.mode";
/**
* NewTabWebChannel is the conduit for all communication with unprivileged newtab instances.
*
* It allows for the ability to broadcast to all newtab browsers.
* If the browser.newtab.remote pref is false, the object will be in an uninitialized state.
*
* Mode choices:
* 'production': pages from our production CDN
* 'staging': pages from our staging CDN
* 'test': intended for tests
* 'test2': intended for tests
* 'dev': intended for development
*
* An unknown mode will result in 'production' mode, which is the default
*
* Incoming messages are expected to be JSON-serialized and in the format:
*
* {
* type: "REQUEST_SCREENSHOT",
* data: {
* url: "https://example.com"
* }
* }
*
* Or:
*
* {
* type: "REQUEST_SCREENSHOT",
* }
*
* Outgoing messages are expected to be objects serializable by structured cloning, in a similar format:
* {
* type: "RECEIVE_SCREENSHOT",
* data: {
* "url": "https://example.com",
* "image": "dataURi:....."
* }
* }
*/
let NewTabWebChannelImpl = function NewTabWebChannelImpl() {
EventEmitter.decorate(this);
this._handlePrefChange = this._handlePrefChange.bind(this);
this._incomingMessage = this._incomingMessage.bind(this);
};
NewTabWebChannelImpl.prototype = {
_prefs: {},
_channel: null,
// a WeakMap containing browsers as keys and a weak ref to their principal
// as value
_principals: null,
// a Set containing weak refs to browsers
_browsers: null,
/*
* Returns current channel's ID
*/
get chanId() {
return CHAN_ID;
},
/*
* Returns the number of browsers currently tracking
*/
get numBrowsers() {
return this._getBrowserRefs().length;
},
/*
* Returns current channel's origin
*/
get origin() {
if (!(this._prefs.mode in NewTabRemoteResources.MODE_CHANNEL_MAP)) {
this._prefs.mode = "production";
}
return NewTabRemoteResources.MODE_CHANNEL_MAP[this._prefs.mode].origin;
},
/*
* Unloads all browsers and principals
*/
_unloadAll() {
if (this._principals != null) {
this._principals = new WeakMap();
}
this._browsers = new Set();
this.emit("targetUnloadAll");
},
/*
* Checks if a browser is known
*
* This will cause an iteration through all known browsers.
* That's ok, we don't expect a lot of browsers
*/
_isBrowserKnown(browser) {
for (let bRef of this._getBrowserRefs()) {
let b = bRef.get();
if (b && b.permanentKey === browser.permanentKey) {
return true;
}
}
return false;
},
/*
* Obtains all known browser refs
*/
_getBrowserRefs() {
// Some code may try to emit messages after teardown.
if (!this._browsers) {
return [];
}
let refs = [];
for (let bRef of this._browsers) {
/*
* even though we hold a weak ref to browser, it seems that browser
* objects aren't gc'd immediately after a tab closes. They stick around
* in memory, but thankfully they don't have a documentURI in that case
*/
let browser = bRef.get();
if (browser && browser.documentURI) {
refs.push(bRef);
} else {
// need to clean up principals because the browser object is not gc'ed
// immediately
this._principals.delete(browser);
this._browsers.delete(bRef);
this.emit("targetUnload");
}
}
return refs;
},
/*
* Receives a message from content.
*
* Keeps track of browsers for broadcast, relays messages to listeners.
*/
_incomingMessage(id, message, target) {
if (this.chanId !== id) {
Cu.reportError(new Error("NewTabWebChannel unexpected message destination"));
}
/*
* need to differentiate by browser, because event targets are created each
* time a message is sent.
*/
if (!this._isBrowserKnown(target.browser)) {
this._browsers.add(Cu.getWeakReference(target.browser));
this._principals.set(target.browser, Cu.getWeakReference(target.principal));
this.emit("targetAdd");
}
try {
let msg = JSON.parse(message);
this.emit(msg.type, {data: msg.data, target});
} catch (err) {
Cu.reportError(err);
}
},
/*
* Sends a message to all known browsers
*/
broadcast(actionType, message) {
for (let bRef of this._getBrowserRefs()) {
let browser = bRef.get();
try {
let principal = this._principals.get(browser).get();
if (principal && browser && browser.documentURI) {
this._channel.send({type: actionType, data: message}, {browser, principal});
}
} catch (e) {
Cu.reportError(new Error("NewTabWebChannel WeakRef is dead"));
this._principals.delete(browser);
}
}
},
/*
* Sends a message to a specific target
*/
send(actionType, message, target) {
try {
this._channel.send({type: actionType, data: message}, target);
} catch (e) {
// Web Channel might be dead
Cu.reportError(e);
}
},
/*
* Pref change observer callback
*/
_handlePrefChange(prefName, newState, forceState) { // eslint-disable-line no-unused-vars
switch (prefName) {
case PREF_ENABLED:
if (!this._prefs.enabled && newState) {
// changing state from disabled to enabled
this.setupState();
} else if (this._prefs.enabled && !newState) {
// changing state from enabled to disabled
this.tearDownState();
}
break;
case PREF_MODE:
if (this._prefs.mode !== newState) {
// changing modes
this.tearDownState();
this.setupState();
}
break;
}
},
/*
* Sets up the internal state
*/
setupState() {
this._prefs.enabled = Services.prefs.getBoolPref(PREF_ENABLED, false);
let mode = Services.prefs.getStringPref(PREF_MODE, "production");
if (!(mode in NewTabRemoteResources.MODE_CHANNEL_MAP)) {
mode = "production";
}
this._prefs.mode = mode;
this._principals = new WeakMap();
this._browsers = new Set();
if (this._prefs.enabled) {
this._channel = new WebChannel(this.chanId, Services.io.newURI(this.origin));
this._channel.listen(this._incomingMessage);
}
},
tearDownState() {
if (this._channel) {
this._channel.stopListening();
}
this._prefs = {};
this._unloadAll();
this._channel = null;
this._principals = null;
this._browsers = null;
},
init() {
this.setupState();
NewTabPrefsProvider.prefs.on(PREF_ENABLED, this._handlePrefChange);
NewTabPrefsProvider.prefs.on(PREF_MODE, this._handlePrefChange);
},
uninit() {
this.tearDownState();
NewTabPrefsProvider.prefs.off(PREF_ENABLED, this._handlePrefChange);
NewTabPrefsProvider.prefs.off(PREF_MODE, this._handlePrefChange);
}
};
let NewTabWebChannel = new NewTabWebChannelImpl();

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

@ -13,13 +13,6 @@ XPCSHELL_TESTS_MANIFESTS += [
'tests/xpcshell/xpcshell.ini',
]
EXTRA_JS_MODULES += [
'NewTabPrefsProvider.jsm',
'NewTabRemoteResources.jsm',
'NewTabSearchProvider.jsm',
'NewTabWebChannel.jsm'
]
XPIDL_SOURCES += [
'nsIAboutNewTabService.idl',
]

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

@ -1,42 +0,0 @@
"use strict";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Preferences.jsm");
ChromeUtils.defineModuleGetter(this, "NewTabPrefsProvider",
"resource:///modules/NewTabPrefsProvider.jsm");
add_task(async function test_observe() {
let prefsMap = NewTabPrefsProvider.prefs.prefsMap;
for (let prefName of prefsMap.keys()) {
let prefValueType = prefsMap.get(prefName);
let beforeVal;
let afterVal;
switch (prefValueType) {
case "bool":
beforeVal = false;
afterVal = true;
Preferences.set(prefName, beforeVal);
break;
case "localized":
case "str":
beforeVal = "";
afterVal = "someStr";
Preferences.set(prefName, beforeVal);
break;
}
NewTabPrefsProvider.prefs.init();
let promise = new Promise(resolve => {
NewTabPrefsProvider.prefs.once(prefName, (name, data) => { // jshint ignore:line
resolve([name, data]);
});
});
Preferences.set(prefName, afterVal);
let [actualName, actualData] = await promise;
equal(prefName, actualName, `emitter sent the correct pref: ${prefName}`);
equal(afterVal, actualData, `emitter collected correct pref data for ${prefName}`);
NewTabPrefsProvider.prefs.uninit();
}
});

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

@ -1,74 +0,0 @@
"use strict";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "NewTabSearchProvider",
"resource:///modules/NewTabSearchProvider.jsm");
ChromeUtils.defineModuleGetter(this, "ContentSearch",
"resource:///modules/ContentSearch.jsm");
// ensure a profile exists
do_get_profile();
function hasProp(obj) {
return function(aProp) {
ok(obj.hasOwnProperty(aProp), `expect to have property ${aProp}`);
};
}
add_task(async function test_search() {
ContentSearch.init();
let observerPromise = new Promise(resolve => {
Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
if (aData === "init-complete" && aTopic === "browser-search-service") {
Services.obs.removeObserver(observer, "browser-search-service");
resolve();
}
}, "browser-search-service");
});
Services.search.init();
await observerPromise;
Assert.ok(Services.search.isInitialized);
// get initial state of search and check it has correct properties
let state = await NewTabSearchProvider.search.asyncGetState();
let stateProps = hasProp(state);
["engines", "currentEngine"].forEach(stateProps);
// check that the current engine is correct and has correct properties
let {currentEngine} = state;
equal(currentEngine.name, Services.search.currentEngine.name, "Current engine has been correctly set");
var engineProps = hasProp(currentEngine);
["name", "placeholder", "iconBuffer"].forEach(engineProps);
// create dummy test engines to test observer
Services.search.addEngineWithDetails("TestSearch1", "", "", "", "GET",
"http://example.com/?q={searchTerms}");
Services.search.addEngineWithDetails("TestSearch2", "", "", "", "GET",
"http://example.com/?q={searchTerms}");
// set one of the dummy test engines to the default engine
Services.search.defaultEngine = Services.search.getEngineByName("TestSearch1");
// test that the event emitter is working by setting a new current engine "TestSearch2"
let engineName = "TestSearch2";
NewTabSearchProvider.search.init();
// event emitter will fire when current engine is changed
let promise = new Promise(resolve => {
NewTabSearchProvider.search.once("browser-search-engine-modified", (name, data) => { // jshint ignore:line
resolve([name, data.name]);
});
});
// set a new current engine
Services.search.currentEngine = Services.search.getEngineByName(engineName);
let expectedEngineName = Services.search.currentEngine.name;
// emitter should fire and return the new engine
let [eventName, actualEngineName] = await promise;
equal(eventName, "browser-search-engine-modified", `emitter sent the correct event ${eventName}`);
equal(expectedEngineName, actualEngineName, `emitter set the correct engine ${expectedEngineName}`);
NewTabSearchProvider.search.uninit();
});

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

@ -4,5 +4,3 @@ firefox-appdir = browser
skip-if = toolkit == 'android'
[test_AboutNewTabService.js]
[test_NewTabPrefsProvider.js]
[test_NewTabSearchProvider.js]

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

@ -146,7 +146,7 @@ add_task(async function testStayopenBookmarksClicks() {
newTab = await promiseTabOpened;
ok(true, "Bookmark middle-click opened new tab.");
await BrowserTestUtils.removeTab(newTab);
is(PanelUI.multiView.current.id, "PanelUI-bookmarks", "Should still show the bookmarks subview");
ok(PanelView.forNode(BMview).active, "Should still show the bookmarks subview");
ok(appMenu.open, "Menu should remain open.");
// Close the App Menu

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

@ -34,6 +34,8 @@
<!ENTITY % connectionDTD SYSTEM "chrome://browser/locale/preferences/connection.dtd">
<!ENTITY % siteDataSettingsDTD SYSTEM
"chrome://browser/locale/preferences/siteDataSettings.dtd" >
<!ENTITY % clearSiteDataDTD SYSTEM
"chrome://browser/locale/preferences/clearSiteData.dtd" >
<!ENTITY % privacyDTD SYSTEM "chrome://browser/locale/preferences/privacy.dtd">
<!ENTITY % searchDTD SYSTEM "chrome://browser/locale/preferences/search.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
@ -64,6 +66,7 @@
%deviceManangerDTD;
%connectionDTD;
%siteDataSettingsDTD;
%clearSiteDataDTD;
%privacyDTD;
%searchDTD;
%syncBrandDTD;

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

@ -408,7 +408,7 @@ var gPrivacyPane = {
signonBundle.getString("loginsDescriptionAll2"),
]);
appendSearchKeywords("cookieExceptions", [
bundlePrefs.getString("cookiepermissionstext"),
bundlePrefs.getString("cookiepermissionstext1"),
]);
appendSearchKeywords("trackingProtectionExceptions", [
bundlePrefs.getString("trackingprotectionpermissionstitle"),
@ -454,7 +454,7 @@ var gPrivacyPane = {
pkiBundle.getString("enable_fips"),
]);
appendSearchKeywords("siteDataSettings", [
bundlePrefs.getString("siteDataSettings2.description"),
bundlePrefs.getString("siteDataSettings3.description"),
bundlePrefs.getString("removeAllCookies.label"),
bundlePrefs.getString("removeSelectedCookies.label"),
]);
@ -881,8 +881,8 @@ var gPrivacyPane = {
allowVisible: true,
prefilledHost: "",
permissionType: "cookie",
windowTitle: bundlePreferences.getString("cookiepermissionstitle"),
introText: bundlePreferences.getString("cookiepermissionstext")
windowTitle: bundlePreferences.getString("cookiepermissionstitle1"),
introText: bundlePreferences.getString("cookiepermissionstext1")
};
gSubDialog.open("chrome://browser/content/preferences/permissions.xul",
null, params);
@ -1405,7 +1405,7 @@ var gPrivacyPane = {
let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
let totalUsage = siteDataUsage + cacheUsage;
let size = DownloadUtils.convertByteUnits(totalUsage);
totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize1", size);
totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize2", size);
});
},

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

@ -75,20 +75,11 @@
<hbox>
<menulist id="historyMode">
<menupopup>
<menuitem label="&historyHeader.remember.label;" value="remember" searchkeywords="&rememberDescription.label;"/>
<menuitem label="&historyHeader.remember.label;" value="remember" searchkeywords="&rememberDescription1.label;"/>
<menuitem label="&historyHeader.dontremember.label;" value="dontremember" searchkeywords="&dontrememberDescription.label;"/>
<menuitem label="&historyHeader.custom.label;" value="custom" searchkeywords="&privateBrowsingPermanent2.label;
&rememberHistory2.label;
&rememberSearchForm.label;
&acceptCookies3.label;
&cookieExceptions.label;
&acceptThirdParty3.pre.label;
&acceptThirdParty.always.label;
&acceptThirdParty.visited.label;
&acceptThirdParty.never.label;
&keepUntil2.label;
&expire.label;
&close.label;
&clearOnClose.label;
&clearOnCloseSettings.label;"/>
</menupopup>
@ -101,14 +92,14 @@
<vbox id="historyRememberPane">
<hbox align="center" flex="1">
<vbox flex="1">
<description>&rememberDescription.label;</description>
<description class="description-with-side-element">&rememberDescription1.label;</description>
</vbox>
</hbox>
</vbox>
<vbox id="historyDontRememberPane">
<hbox align="center" flex="1">
<vbox flex="1">
<description>&dontrememberDescription.label;</description>
<description class="description-with-side-element">&dontrememberDescription.label;</description>
</vbox>
</hbox>
</vbox>
@ -172,86 +163,95 @@
<hbox data-subcategory="sitedata" align="baseline">
<vbox flex="1">
<description class="description-with-side-element" flex="1">
<html:span id="totalSiteDataSize" class="tail-with-learn-more"></html:span>
<label id="siteDataLearnMoreLink" class="learnMore text-link">&siteDataLearnMoreLink.label;</label>
</description>
<radiogroup id="acceptCookies"
preference="network.cookie.cookieBehavior"
onsyncfrompreference="return gPrivacyPane.readAcceptCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptCookies();">
<description flex="1">
<label id="totalSiteDataSize" class="tail-with-learn-more"></label>
<label id="siteDataLearnMoreLink" class="learnMore text-link">&siteDataLearnMoreLink.label;</label>
</description>
<hbox id="cookiesBox">
<radio label="&acceptCookies3.label;"
value="0"
accesskey="&acceptCookies3.accesskey;"
<hbox id="cookiesBox">
<radio label="&acceptCookies4.label;"
value="0"
accesskey="&acceptCookies4.accesskey;"
flex="1" />
</hbox>
<hbox id="keepRow"
class="indent"
align="center">
<label id="keepUntil"
control="keepCookiesUntil"
accesskey="&keepUntil2.accesskey;">&keepUntil2.label;</label>
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<menulist id="keepCookiesUntil"
preference="network.cookie.lifetimePolicy">
<menupopup>
<menuitem label="&expire.label;" value="0"/>
<menuitem label="&close.label;" value="2"/>
</menupopup>
</menulist>
</hbox>
</hbox>
<hbox id="acceptThirdPartyRow"
class="indent"
align="center">
<label id="acceptThirdPartyLabel" control="acceptThirdPartyMenu"
accesskey="&acceptThirdParty3.pre.accesskey;">&acceptThirdParty3.pre.label;</label>
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();">
<menupopup>
<menuitem label="&acceptThirdParty.always.label;" value="always"/>
<menuitem label="&acceptThirdParty.visited.label;" value="visited"/>
<menuitem label="&acceptThirdParty.never.label;" value="never"/>
</menupopup>
</menulist>
</hbox>
</hbox>
<radio label="&blockCookies.label;"
value="2"
accesskey="&blockCookies.accesskey;"
flex="1" />
</hbox>
<hbox id="keepRow"
class="indent"
align="center">
<label id="keepUntil"
control="keepCookiesUntil"
accesskey="&keepUntil2.accesskey;">&keepUntil2.label;</label>
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<menulist id="keepCookiesUntil"
preference="network.cookie.lifetimePolicy">
<menupopup>
<menuitem label="&expire.label;" value="0"/>
<menuitem label="&close.label;" value="2"/>
</menupopup>
</menulist>
</hbox>
</hbox>
<hbox id="acceptThirdPartyRow"
class="indent"
align="center">
<label id="acceptThirdPartyLabel" control="acceptThirdPartyMenu"
accesskey="&acceptThirdParty3.pre.accesskey;">&acceptThirdParty3.pre.label;</label>
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();">
<menupopup>
<menuitem label="&acceptThirdParty.always.label;" value="always"/>
<menuitem label="&acceptThirdParty.visited.label;" value="visited"/>
<menuitem label="&acceptThirdParty.never.label;" value="never"/>
</menupopup>
</menulist>
</hbox>
</hbox>
<radio label="&blockCookies.label;"
value="2"
accesskey="&blockCookies.accesskey;"
flex="1" />
</radiogroup>
</radiogroup>
</vbox>
<vbox align="end">
<button id="clearSiteDataButton"
class="accessory-button"
icon="clear"
label="&clearSiteData1.label;" accesskey="&clearSiteData1.accesskey;"/>
<button id="siteDataSettings"
class="accessory-button"
label="&siteDataSettings.label;"
accesskey="&siteDataSettings.accesskey;"
searchkeywords="&window.title;
&hostCol.label;
&statusCol.label;
&usageCol.label;"/>
<button id="cookieExceptions"
class="accessory-button"
label="&cookieExceptions.label;" accesskey="&cookieExceptions.accesskey;"
preference="pref.privacy.disable_button.cookie_exceptions"
searchkeywords="&address2.label;
&block.label;
&session.label;
&allow.label;
&removepermission2.label;
&removeallpermissions2.label;
&button.cancel.label;
&button.ok.label;"/>
<vbox>
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="clearSiteDataButton"
class="accessory-button"
icon="clear"
searchkeywords="&clearSiteData.label;
&clearCache.label;"
label="&clearSiteData1.label;" accesskey="&clearSiteData1.accesskey;"/>
</hbox>
<hbox>
<button id="siteDataSettings"
class="accessory-button"
label="&siteDataSettings.label;"
accesskey="&siteDataSettings.accesskey;"
searchkeywords="&window1.title;
&hostCol.label;
&cookiesCol.label;
&usageCol.label;"/>
</hbox>
<hbox>
<button id="cookieExceptions"
class="accessory-button"
label="&cookieExceptions.label;" accesskey="&cookieExceptions.accesskey;"
preference="pref.privacy.disable_button.cookie_exceptions"
searchkeywords="&address2.label;
&block.label;
&session.label;
&allow.label;
&removepermission2.label;
&removeallpermissions2.label;
&button.cancel.label;
&button.ok.label;"/>
</hbox>
</vbox>
</hbox>
</groupbox>

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

@ -32,6 +32,7 @@ skip-if = !updater
[browser_search_subdialogs_within_preferences_6.js]
[browser_search_subdialogs_within_preferences_7.js]
[browser_search_subdialogs_within_preferences_8.js]
[browser_search_subdialogs_within_preferences_site_data.js]
[browser_bug795764_cachedisabled.js]
[browser_bug1018066_resetScrollPosition.js]
[browser_bug1020245_openPreferences_to_paneContent.js]

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

@ -30,11 +30,3 @@ add_task(async function() {
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
/**
* Test for searching for the "Settings - Site Data" subdialog.
*/
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("store site data on your computer", "siteDataGroup");
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

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

@ -0,0 +1,35 @@
/*
* This file contains tests for the Preferences search bar.
*/
// Enabling Searching functionatily. Will display search bar form this testcase forward.
add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["browser.preferences.search", true]]});
});
/**
* Test for searching for the "Settings - Site Data" subdialog.
*/
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("cookies", ["siteDataGroup", "historyGroup"]);
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("site data", ["siteDataGroup", "historyGroup"]);
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("cache", ["siteDataGroup", "historyGroup"]);
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("third-party", "siteDataGroup");
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

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

@ -90,7 +90,7 @@ add_task(async function() {
.then(usage => {
actual = totalSiteDataSizeLabel.textContent;
expected = prefStrBundle.getFormattedString(
"totalSiteDataSize1", DownloadUtils.convertByteUnits(usage + cacheSize));
"totalSiteDataSize2", DownloadUtils.convertByteUnits(usage + cacheSize));
is(actual, expected, "Should show the right total site data size");
});
@ -109,7 +109,7 @@ add_task(async function() {
.then(usage => {
actual = totalSiteDataSizeLabel.textContent;
expected = prefStrBundle.getFormattedString(
"totalSiteDataSize1", DownloadUtils.convertByteUnits(usage + cacheSize));
"totalSiteDataSize2", DownloadUtils.convertByteUnits(usage + cacheSize));
is(actual, expected, "Should show the right total site data size");
});

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

@ -93,7 +93,7 @@ let gSiteDataSettings = {
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
let settingsDescription = document.getElementById("settingsDescription");
settingsDescription.textContent = this._prefStrBundle.getFormattedString("siteDataSettings2.description", [brandShortName]);
settingsDescription.textContent = this._prefStrBundle.getFormattedString("siteDataSettings3.description", [brandShortName]);
setEventListener("sitesList", "select", this.onSelect);
setEventListener("hostCol", "click", this.onClickTreeCol);

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

@ -29,7 +29,8 @@ add_UITour_task(async function test_highlight_library_and_show_library_subview()
libraryBtn.dispatchEvent(new Event("command"));
await highlightHiddenPromise;
await ViewShownPromise;
is(PanelUI.multiView.current.id, "appMenu-libraryView", "Should show the library subview");
let libView = document.getElementById("appMenu-libraryView");
ok(PanelView.forNode(libView).active, "Should show the library subview");
is(appMenu.state, "open", "Should still open the app menu for the library subview");
// Clean up

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

@ -22,8 +22,8 @@ acceptVeryLargeMinimumFont=Keep my changes anyway
trackingprotectionpermissionstext2=You have disabled Tracking Protection on these websites.
trackingprotectionpermissionstitle=Exceptions - Tracking Protection
cookiepermissionstext=You can specify which websites are always or never allowed to use cookies. Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow.
cookiepermissionstitle=Exceptions - Cookies
cookiepermissionstext1=You can specify which websites are always or never allowed to use cookies and site data. Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow.
cookiepermissionstitle1=Exceptions - Cookies and Site Data
addonspermissionstext=You can specify which websites are allowed to install add-ons. Type the exact address of the site you want to allow and then click Allow.
addons_permissions_title2=Allowed Websites - Add-ons Installation
popuppermissionstext=You can specify which websites are allowed to open pop-up windows. Type the exact address of the site you want to allow and then click Allow.
@ -166,19 +166,19 @@ removeSelectedCookies.accesskey=R
defaultUserContextLabel=None
# LOCALIZATION NOTE (totalSiteDataSize1, siteUsage, siteUsagePersistent):
# LOCALIZATION NOTE (totalSiteDataSize2, siteUsage, siteUsagePersistent):
# This is the total usage of site data, where we insert storage size and unit.
# e.g., "The total usage is currently 200 MB"
# %1$S = size
# %2$S = unit (MB, KB, etc.)
totalSiteDataSize1=Your stored site data and cache are currently using %1$S %2$S of disk space
totalSiteDataSize2=Your stored cookies, site data and cache are currently using %1$S %2$S of disk space.
siteUsage=%1$S %2$S
siteUsagePersistent=%1$S %2$S (Persistent)
loadingSiteDataSize1=Calculating site data and cache size…
acceptRemove=Remove
# LOCALIZATION NOTE (siteDataSettings2.description): %S = brandShortName
siteDataSettings2.description=The following websites store site data on your computer. %S keeps data from websites with persistent storage until you delete it, and deletes data from websites with non-persistent storage as space is needed.
# LOCALIZATION NOTE (siteDataSettings3.description): %S = brandShortName
siteDataSettings3.description=The following websites store cookies and site data on your computer. %S keeps data from websites with persistent storage until you delete it, and deletes data from websites with non-persistent storage as space is needed.
# LOCALIZATION NOTE (removeAllSiteData, removeAllSiteDataShown):
# removeAllSiteData and removeAllSiteDataShown are both used on the same one button,
# never displayed together and can share the same accesskey.

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

@ -38,8 +38,8 @@
<!ENTITY suggestionSettings2.label "Change preferences for search engine suggestions">
<!ENTITY acceptCookies3.label "Accept cookies and site data from websites">
<!ENTITY acceptCookies3.accesskey "A">
<!ENTITY acceptCookies4.label "Accept cookies and site data from websites (recommended)">
<!ENTITY acceptCookies4.accesskey "A">
<!ENTITY blockCookies.label "Block cookies and site data (may cause websites to break)">
<!ENTITY blockCookies.accesskey "B">
@ -66,7 +66,7 @@
<!ENTITY historyHeader.custom.label "Use custom settings for history">
<!ENTITY historyHeader.post.label "">
<!ENTITY rememberDescription.label "&brandShortName; will remember your browsing, download, form and search history, and keep cookies from websites you visit.">
<!ENTITY rememberDescription1.label "&brandShortName; will remember your browsing, download, form and search history.">
<!ENTITY dontrememberDescription.label "&brandShortName; will use the same settings as private browsing, and will not remember any history as you browse the Web.">

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

@ -4,7 +4,6 @@
<!ENTITY window1.title "Settings - Cookies and Site Data">
<!ENTITY hostCol.label "Site">
<!ENTITY statusCol.label "Status">
<!ENTITY cookiesCol.label "Cookies">
<!ENTITY usageCol.label "Storage">
<!ENTITY lastAccessedCol.label "Last Used">

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

@ -85,6 +85,12 @@ button > hbox > label {
margin-inline-end: 10px;
}
/* Add a bit of space to the end of descriptions to
* leave margin with e.g. additional buttons on the side. */
.description-with-side-element {
margin-inline-end: 10px !important;
}
.learnMore {
margin-inline-start: 0px;
font-weight: normal;
@ -383,6 +389,10 @@ button > hbox > label {
margin-top: 4px;
}
#acceptCookies {
margin-top: 1.5em;
}
/* Collapse the non-active vboxes in decks to use only the height the
active vbox needs */
#historyPane:not([selectedIndex="1"]) > #historyDontRememberPane,

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

@ -339,7 +339,7 @@ sysinstall_cmd = install_cmd
# overridden by the command line. (Besides, AB_CD is prettier).
AB_CD = $(MOZ_UI_LOCALE)
include $(topsrcdir)/config/AB_rCD.mk
include $(MOZILLA_DIR)/config/AB_rCD.mk
# Many locales directories want this definition.
ACDEFINES += -DAB_CD=$(AB_CD)

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

@ -9643,14 +9643,16 @@ nsDocShell::InternalLoad(nsIURI* aURI,
// outside of Gecko.
const int where = (aWindowTarget.IsEmpty() || targetDocShell)
? nsIBrowserDOMWindow::OPEN_CURRENTWINDOW
: nsIBrowserDOMWindow::OPEN_NEW;
: nsIBrowserDOMWindow::OPEN_NEWWINDOW;
if (where == nsIBrowserDOMWindow::OPEN_NEW && isDocumentAuxSandboxed) {
if (where == nsIBrowserDOMWindow::OPEN_NEWWINDOW && isDocumentAuxSandboxed) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
if (NS_SUCCEEDED(mLoadURIDelegate->LoadURI(aURI, where, aFlags,
aTriggeringPrincipal))) {
bool loadURIHandled = false;
rv = mLoadURIDelegate->LoadURI(aURI, where, aFlags, aTriggeringPrincipal,
&loadURIHandled);
if (NS_SUCCEEDED(rv) && loadURIHandled) {
// The request has been handled, nothing to do here.
return NS_OK;
}

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

@ -16,5 +16,6 @@ support-files =
[chrome/test_cssanimation_missing_keyframes.html]
[chrome/test_generated_content_getAnimations.html]
[chrome/test_running_on_compositor.html]
skip-if = os == 'android' # bug 1442150
[chrome/test_simulate_compute_values_failure.html]
skip-if = !debug

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

@ -516,7 +516,7 @@ nsDocumentEncoder::SerializeToStringRecursive(nsINode* aNode,
}
if (!aDontSerializeRoot) {
rv = SerializeNodeEnd(node, aStr);
rv = SerializeNodeEnd(maybeFixedNode, aStr);
NS_ENSURE_SUCCESS(rv, rv);
}

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

@ -867,6 +867,10 @@ HTMLFormElement::DoSecureToInsecureSubmitCheck(nsIURI* aActionURL,
return NS_OK;
}
if (nsMixedContentBlocker::IsPotentiallyTrustworthyOnion(aActionURL)) {
return NS_OK;
}
nsCOMPtr<nsPIDOMWindowOuter> window = OwnerDoc()->GetWindow();
if (!window) {
return NS_ERROR_FAILURE;

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

@ -688,7 +688,8 @@ skip-if = android_version == '15' || android_version == '17' || android_version
[test_autoplay_policy.html]
skip-if = android_version == '23' # bug 1424903
[test_autoplay_policy_activation.html]
skip-if = android_version == '23' # bug 1424903
#skip-if = android_version == '23' # bug 1424903
skip-if = true # bug 1441424 - temporarily disabled to land bug 1193394
[test_buffered.html]
skip-if = android_version == '15' || android_version == '22' # bug 1308388, android(bug 1232305)
[test_bug448534.html]

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

@ -21,6 +21,7 @@
#include "nsIImageLoadingContent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/nsMixedContentBlocker.h"
#include "mozilla/dom/TabChild.h"
NS_IMPL_ISUPPORTS(nsContentSecurityManager,
@ -879,6 +880,12 @@ nsContentSecurityManager::IsOriginPotentiallyTrustworthy(nsIPrincipal* aPrincipa
}
}
}
// Maybe we have a .onion URL. Treat it as whitelisted as well if
// `dom.securecontext.whitelist_onions` is `true`.
if (nsMixedContentBlocker::IsPotentiallyTrustworthyOnion(uri)) {
*aIsTrustWorthy = true;
return NS_OK;
}
}
return NS_OK;

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

@ -395,6 +395,28 @@ nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL) {
return host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1");
}
/* Maybe we have a .onion URL. Treat it as whitelisted as well if
* `dom.securecontext.whitelist_onions` is `true`.
*/
bool
nsMixedContentBlocker::IsPotentiallyTrustworthyOnion(nsIURI* aURL) {
static bool sInited = false;
static bool sWhiteListOnions = false;
if (!sInited) {
Preferences::AddBoolVarCache(&sWhiteListOnions,
"dom.securecontext.whitelist_onions");
sInited = true;
}
if (!sWhiteListOnions) {
return false;
}
nsAutoCString host;
nsresult rv = aURL->GetHost(host);
NS_ENSURE_SUCCESS(rv, false);
return StringEndsWith(host, NS_LITERAL_CSTRING(".onion"));
}
/* Static version of ShouldLoad() that contains all the Mixed Content Blocker
* logic. Called from non-static ShouldLoad().
*/
@ -725,6 +747,13 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
return NS_OK;
}
// .onion URLs are encrypted and authenticated. Don't treat them as mixed
// content if potentially trustworthy (i.e. whitelisted).
if (isHttpScheme && IsPotentiallyTrustworthyOnion(innerContentLocation)) {
*aDecision = ACCEPT;
return NS_OK;
}
// The page might have set the CSP directive 'upgrade-insecure-requests'. In such
// a case allow the http: load to succeed with the promise that the channel will
// get upgraded to https before fetching any data from the netwerk.

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

@ -48,6 +48,7 @@ public:
// See:
// https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
static bool IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL);
static bool IsPotentiallyTrustworthyOnion(nsIURI* aURL);
/* Static version of ShouldLoad() that contains all the Mixed Content Blocker
* logic. Called from non-static ShouldLoad().

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

@ -1,19 +0,0 @@
[DEFAULT]
support-files =
file_contentserver.sjs
file_about_newtab.html
file_about_newtab_bad.html
file_about_newtab_bad_csp.html
file_about_newtab_bad_csp_signature
file_about_newtab_good_signature
file_about_newtab_bad_signature
file_about_newtab_broken_signature
file_about_newtab_sri.html
file_about_newtab_sri_signature
goodChain.pem
head.js
script.js
style.css
[browser_verify_content_about_newtab.js]
[browser_verify_content_about_newtab2.js]

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

@ -1,20 +0,0 @@
const TESTS = [
// { newtab (aboutURI) or regular load (url) : url,
// testStrings : expected strings in the loaded page }
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
{ "aboutURI" : URI_ERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
{ "url" : URI_BAD_FILE_CACHED, "testStrings" : [BAD_ABOUT_STRING] },
{ "aboutURI" : URI_BAD_FILE_CACHED, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
{ "aboutURI" : URI_SRI, "testStrings" : [
STYLESHEET_WITHOUT_SRI_BLOCKED,
STYLESHEET_WITH_SRI_LOADED,
SCRIPT_WITHOUT_SRI_BLOCKED,
SCRIPT_WITH_SRI_LOADED,
]},
{ "aboutURI" : URI_BAD_CSP, "testStrings" : [CSP_TEST_SUCCESS_STRING] },
{ "url" : URI_CLEANUP, "testStrings" : [CLEANUP_DONE] },
];
add_task(runTests);

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

@ -1,19 +0,0 @@
const TESTS = [
// { newtab (aboutURI) or regular load (url) : url,
// testStrings : expected strings in the loaded page }
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
{ "aboutURI" : URI_ERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_KEYERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_SIGERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_NO_HEADER, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_BAD_SIG, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_BROKEN_SIG, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_BAD_X5U, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_HTTP_X5U, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_BAD_FILE, "testStrings" : [ABOUT_BLANK] },
{ "aboutURI" : URI_BAD_ALL, "testStrings" : [ABOUT_BLANK] },
{ "url" : URI_CLEANUP, "testStrings" : [CLEANUP_DONE] },
];
add_task(runTests);

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

@ -1,11 +0,0 @@
<!DOCTYPE HTML>
<html>
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1226928 -->
<head>
<meta charset="utf-8">
<title>Testpage for bug 1226928</title>
</head>
<body>
Just a fully good testpage for Bug 1226928<br/>
</body>
</html>

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

@ -1,11 +0,0 @@
<!DOCTYPE HTML>
<html>
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1226928 -->
<head>
<meta charset="utf-8">
<title>Testpage for bug 1226928</title>
</head>
<body>
Just a bad testpage for Bug 1226928<br/>
</body>
</html>

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

@ -1,14 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Testpage for CSP violation (inline script)</title>
</head>
<body>
CSP violation test succeeded.
<script>
// This inline script would override the success string if loaded.
document.body.innerHTML = "CSP violation test failed.";
</script>
</body>
</html>

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

@ -1 +0,0 @@
oiypz3lb-IyJsmKNsnlp2zDrqncste8yONn9WUE6ksgJWMhSEQ9lp8vRqN0W3JPwJb6uSk16RI-tDv7uy0jxon5jL1BZpqlqIpvimg7FCQEedMKoHZwtE9an-e95sOTd

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

@ -1 +0,0 @@
KirX94omQL7lKfWGhc777t8U29enDg0O0UcJLH3PRXcvWGO8KA6mmLS3yNCFnGiTjP3vNnVtm-sUkXr4ix8WTkKABkU4fEAi77sNOkLCKw40M9sDJOesmYInS_J2AuXX

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

@ -1 +0,0 @@
MGUCMFwSs3o95ukwBWXN1WbLgnpJ_uHWFiQROPm9zjrSqzlfiSMyLwJwIZzldWo_pBJtOwIxAJIfhXIiMVfl5NkFEJUUMxzu6FuxOJl5DCpG2wHLy9AhayLUzm4X4SpwZ6QBPapdTg

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

@ -1 +0,0 @@
HUndgHvxHNMiAe1SXoeyOOraUJCdxHqWkAYTu0Cq1KpAHcWZEVelNTvyXGbTLWj8btsmqNLAm08UlyK43q_2oO9DQfez3Fo8DhsKvm7TqgSXCkhUoxsYNanxWXhqw-Jw

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

@ -1,36 +0,0 @@
<!DOCTYPE HTML>
<html>
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1235572 -->
<head>
<meta charset="utf-8">
<title>Testpage for bug 1235572</title>
<script>
function loaded(resource) {
document.getElementById("result").innerHTML += resource + " loaded\n";
}
function blocked(resource) {
document.getElementById("result").innerHTML += resource + " blocked\n";
}
</script>
</head>
<body>
Testing script loading without SRI for Bug 1235572<br/>
<div id="result"></div>
<!-- use css1 and css2 to make urls different to avoid the resource being cached-->
<link rel="stylesheet" href="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=css1"
onload="loaded('Stylesheet without SRI')"
onerror="blocked('Stylesheet without SRI')">
<link rel="stylesheet" href="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=css2"
integrity="sha384-/6Tvxh7SX39y62qePcvYoi5Vrf0lK8Ix3wJFLCYKI5KNJ5wIlCR8UsFC1OXwmwgd"
onload="loaded('Stylesheet with SRI')"
onerror="blocked('Stylesheet with SRI')">
<script src="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=script"
onload="loaded('Script without SRI')"
onerror="blocked('Script without SRI')"></script>
<script src="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=script"
integrity="sha384-zDCkvKOHXk8mM6Nk07oOGXGME17PA4+ydFw+hq0r9kgF6ZDYFWK3fLGPEy7FoOAo"
onload="loaded('Script with SRI')"
onerror="blocked('Script with SRI')"></script>
</body>
</html>

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

@ -1 +0,0 @@
yoIyAYiiEzdP1zpkRy3KaqdsjUy62Notku89cytwVwcH0x6fKsMCdM-df1wbk9N28CSTaIOW5kcSenFy5K3nU-zPIoqZDjQo6aSjF8hF6lrw1a1xbhfl9K3g4YJsuWsO

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

@ -1,260 +0,0 @@
/* -*- 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/. */
// sjs for remote about:newtab (bug 1226928)
"use strict";
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.importGlobalProperties(["URLSearchParams"]);
const path = "browser/dom/security/test/contentverifier/";
const goodFileName = "file_about_newtab.html";
const goodFileBase = path + goodFileName;
const goodFile = FileUtils.getDir("TmpD", [], true);
goodFile.append(goodFileName);
const goodSignature = path + "file_about_newtab_good_signature";
const goodX5UString = "\"https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=default\"";
const scriptFileName = "script.js";
const cssFileName = "style.css";
const badFile = path + "file_about_newtab_bad.html";
const brokenSignature = path + "file_about_newtab_broken_signature";
const badSignature = path + "file_about_newtab_bad_signature";
const badX5UString = "\"https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=bad\"";
const httpX5UString = "\"http://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=default\"";
const sriFile = path + "file_about_newtab_sri.html";
const sriSignature = path + "file_about_newtab_sri_signature";
const badCspFile = path + "file_about_newtab_bad_csp.html";
const badCspSignature = path + "file_about_newtab_bad_csp_signature";
// This cert chain is copied from
// security/manager/ssl/tests/unit/test_content_signing/
// using the certificates
// * content_signing_remote_newtab_ee.pem
// * content_signing_int.pem
// * content_signing_root.pem
const goodCertChainPath = path + "goodChain.pem";
const tempFileNames = [goodFileName, scriptFileName, cssFileName];
// we copy the file to serve as newtab to a temp directory because
// we modify it during tests.
setupTestFiles();
function setupTestFiles() {
for (let fileName of tempFileNames) {
let tempFile = FileUtils.getDir("TmpD", [], true);
tempFile.append(fileName);
if (!tempFile.exists()) {
let fileIn = getFileName(path + fileName, "CurWorkD");
fileIn.copyTo(FileUtils.getDir("TmpD", [], true), "");
}
}
}
function getFileName(filePath, dir) {
// Since it's relative to the cwd of the test runner, we start there and
// append to get to the actual path of the file.
let testFile =
Cc["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get(dir, Components.interfaces.nsIFile);
let dirs = filePath.split("/");
for (let i = 0; i < dirs.length; i++) {
testFile.append(dirs[i]);
}
return testFile;
}
function loadFile(file) {
// Load a file to return it.
let testFileStream =
Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
testFileStream.init(file, -1, 0, 0);
return NetUtil.readInputStreamToString(testFileStream,
testFileStream.available());
}
function appendToFile(aFile, content) {
try {
let file = FileUtils.openFileOutputStream(aFile, FileUtils.MODE_APPEND |
FileUtils.MODE_WRONLY);
file.write(content, content.length);
file.close();
} catch (e) {
dump(">>> Error in appendToFile "+e);
return "Error";
}
return "Done";
}
function truncateFile(aFile, length) {
let fileIn = loadFile(aFile);
fileIn = fileIn.slice(0, -length);
try {
let file = FileUtils.openFileOutputStream(aFile, FileUtils.MODE_WRONLY |
FileUtils.MODE_TRUNCATE);
file.write(fileIn, fileIn.length);
file.close();
} catch (e) {
dump(">>> Error in truncateFile "+e);
return "Error";
}
return "Done";
}
function cleanupTestFiles() {
for (let fileName of tempFileNames) {
let tempFile = FileUtils.getDir("TmpD", [], true);
tempFile.append(fileName);
tempFile.remove(true);
}
}
/*
* handle requests of the following form:
* sig=good&key=good&file=good&header=good&cached=no to serve pages with
* content signatures
*
* it further handles invalidateFile=yep and validateFile=yep to change the
* served file
*/
function handleRequest(request, response) {
let params = new URLSearchParams(request.queryString);
let x5uType = params.get("x5u");
let signatureType = params.get("sig");
let fileType = params.get("file");
let headerType = params.get("header");
let cached = params.get("cached");
let invalidateFile = params.get("invalidateFile");
let validateFile = params.get("validateFile");
let resource = params.get("resource");
let x5uParam = params.get("x5u");
if (params.get("cleanup")) {
cleanupTestFiles();
response.setHeader("Content-Type", "text/html", false);
response.write("Done");
return;
}
if (resource) {
if (resource == "script") {
response.setHeader("Content-Type", "application/javascript", false);
response.write(loadFile(getFileName(scriptFileName, "TmpD")));
} else { // resource == "css1" || resource == "css2"
response.setHeader("Content-Type", "text/css", false);
response.write(loadFile(getFileName(cssFileName, "TmpD")));
}
return;
}
// if invalidateFile is set, this doesn't actually return a newtab page
// but changes the served file to invalidate the signature
// NOTE: make sure to make the file valid again afterwards!
if (invalidateFile) {
let r = "Done";
for (let fileName of tempFileNames) {
if (appendToFile(getFileName(fileName, "TmpD"), "!") != "Done") {
r = "Error";
}
}
response.setHeader("Content-Type", "text/html", false);
response.write(r);
return;
}
// if validateFile is set, this doesn't actually return a newtab page
// but changes the served file to make the signature valid again
if (validateFile) {
let r = "Done";
for (let fileName of tempFileNames) {
if (truncateFile(getFileName(fileName, "TmpD"), 1) != "Done") {
r = "Error";
}
}
response.setHeader("Content-Type", "text/html", false);
response.write(r);
return;
}
// we have to return the certificate chain on request for the x5u parameter
if (x5uParam && x5uParam == "default") {
response.setHeader("Cache-Control", "max-age=216000", false);
response.setHeader("Content-Type", "text/plain", false);
response.write(loadFile(getFileName(goodCertChainPath, "CurWorkD")));
return;
}
// avoid confusing cache behaviours
if (!cached) {
response.setHeader("Cache-Control", "no-cache", false);
} else {
response.setHeader("Cache-Control", "max-age=3600", false);
}
// send HTML to test allowed/blocked behaviours
response.setHeader("Content-Type", "text/html", false);
// set signature header and key for Content-Signature header
/* By default a good content-signature header is returned. Any broken return
* value has to be indicated in the url.
*/
let csHeader = "";
let x5uString = goodX5UString;
let signature = goodSignature;
let file = goodFile;
if (x5uType == "bad") {
x5uString = badX5UString;
} else if (x5uType == "http") {
x5uString = httpX5UString;
}
if (signatureType == "bad") {
signature = badSignature;
} else if (signatureType == "broken") {
signature = brokenSignature;
} else if (signatureType == "sri") {
signature = sriSignature;
} else if (signatureType == "bad-csp") {
signature = badCspSignature;
}
if (fileType == "bad") {
file = getFileName(badFile, "CurWorkD");
} else if (fileType == "sri") {
file = getFileName(sriFile, "CurWorkD");
} else if (fileType == "bad-csp") {
file = getFileName(badCspFile, "CurWorkD");
}
if (headerType == "good") {
// a valid content-signature header
csHeader = "x5u=" + x5uString + ";p384ecdsa=" +
loadFile(getFileName(signature, "CurWorkD"));
} else if (headerType == "error") {
// this content-signature header is missing ; before p384ecdsa
csHeader = "x5u=" + x5uString + "p384ecdsa=" +
loadFile(getFileName(signature, "CurWorkD"));
} else if (headerType == "errorInX5U") {
// this content-signature header is missing the keyid directive
csHeader = "x6u=" + x5uString + ";p384ecdsa=" +
loadFile(getFileName(signature, "CurWorkD"));
} else if (headerType == "errorInSignature") {
// this content-signature header is missing the p384ecdsa directive
csHeader = "x5u=" + x5uString + ";p385ecdsa=" +
loadFile(getFileName(signature, "CurWorkD"));
}
if (csHeader) {
response.setHeader("Content-Signature", csHeader, false);
}
let result = loadFile(file);
response.write(result);
}

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

@ -1,51 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICUzCCAT2gAwIBAgIUJ1BtYqWRwUsVaZCGPp9eTHIC04QwCwYJKoZIhvcNAQEL
MBExDzANBgNVBAMMBmludC1DQTAiGA8yMDE1MTEyODAwMDAwMFoYDzIwMTgwMjA1
MDAwMDAwWjAUMRIwEAYDVQQDDAllZS1pbnQtQ0EwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcTLajOmOgxU05q
nAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/wAvBa9xof3cyD
dKpuqc6jTjBMMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDUGA1UdEQQuMCyCKnJlbW90
ZW5ld3RhYi5jb250ZW50LXNpZ25hdHVyZS5tb3ppbGxhLm9yZzALBgkqhkiG9w0B
AQsDggEBALiLck6k50ok9ahVq45P3feY1PeUXcIYZkJd8aPDYM+0kfg5+JyJBykA
mtHWPE1QQjs7VRMfaLfu04E4UJMI2V1AON1qtgR9BQLctW85KFACg2omfiCKwJh0
5Q8cxBFx9BpNMayqLJwHttB6oluxZFTB8CL/hfpbYpHz1bMEDCVSRP588YBrc8mV
OLqzQK+k3ewwGvfD6SvXmTny37MxqwxdTPFJNnpqzKAsQIvz8Skic9BkA1NFk0Oq
lsKKoiibbOCmwS9XY/laAkBaC3winuhciYAC0ImAopZ4PBCU0AOHGrNbhZXWYQxt
uHBj34FqvIRCqgM06JCEwN0ULgix4kI=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIC0TCCAbugAwIBAgIUPcKbBQpKwTzrrlqzM+d3z5DWiNUwCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
MDBaMBExDzANBgNVBAMMBmludC1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x
nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM
wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF
4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20
yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx
j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMlMCMwDAYDVR0TBAUwAwEB/zAT
BgNVHSUEDDAKBggrBgEFBQcDAzALBgkqhkiG9w0BAQsDggEBADDPjITgz8joxLRW
wpLxELKSgO/KQ6iAXztjMHq9ovT7Fy0fqBnQ1mMVFr+sBXLgtUCM45aip6PjhUXc
zs5Dq5STg+kz7qtmAjEQvOPcyictbgdu/K7+uMhXQhlzhOgyW88Uk5vrAezNTc/e
TvSmWp1FcgVAfaeMN/90nzD1KIHoUt7zqZIz9ub8jXPVzQNZq4vh33smZhmbdTdV
DaHUyef5cR1VTEGB+L1qzUIQqpHmD4UkMNP1nYedWfauiQhRt6Ql3rJSCRuEvsOA
iBTJlwai/EFwfyfHkOV2GNgv+A5wHHEjBtF5c4PCxQEL5Vw+mfZHLsDVqF3279ZY
lQ6jQ9g=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICzTCCAbegAwIBAgIUKRLJoCmk0A6PHrNc8CxFn//4BYcwCwYJKoZIhvcNAQEL
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
MDBaMA0xCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu
Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO
7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf
qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt
HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx
uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/MBMGA1Ud
JQQMMAoGCCsGAQUFBwMDMAsGCSqGSIb3DQEBCwOCAQEAABgMK6EyVIXTjD5qaxPO
DWz6yREACmAQBcowKWvfhwgi27DPSXyFGDbzTPEo+7RrIcXJkVAhLouGT51fCwTZ
zb6Sgf6ztX7VSppY9AT4utvlZKP1xQ5WhIYsMtdHCHLHIkRjeWyoBEfUx50UXNLK
Snl+A02GKYWiX+TLLg2DPN2s7v/mm8NLMQNgUlL7KakB2FHFyPa8otPpL4llg7UJ
iBTVQ0c3JoiVbwZaY1Z8QinfMXUrTK9egUC4BAcId1dE8glzA5RRlw1fTLWpGApt
hUmbDnl9N2a9NhGX323ypNzIATexafipzWe7bc4u/+bFdrUqnKUoEka73pZBdHdA
FQ==
-----END CERTIFICATE-----

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

@ -1,208 +0,0 @@
/*
* Test Content-Signature for remote about:newtab
* - Bug 1226928 - allow about:newtab to load remote content
*
* This tests content-signature verification on remote about:newtab in the
* following cases (see TESTS, all failed loads display about:blank fallback):
* - good case (signature should verify and correct page is displayed)
* - reload of newtab when the siganture was invalidated after the last correct
* load
* - malformed content-signature header
* - malformed keyid directive
* - malformed p384ecdsa directive
* - wrong signature (this is not a siganture for the delivered document)
* - invalid signature (this is not even a signature)
* - loading a file that doesn't fit the key or signature
* - cache poisoning (load a malicious remote page not in newtab, subsequent
* newtab load has to load the fallback)
*/
const ABOUT_NEWTAB_URI = "about:newtab";
const BASE = "https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?";
const URI_GOOD = BASE + "sig=good&x5u=good&file=good&header=good";
const INVALIDATE_FILE = BASE + "invalidateFile=yep";
const VALIDATE_FILE = BASE + "validateFile=yep";
const URI_HEADER_BASE = BASE + "sig=good&x5u=good&file=good&header=";
const URI_ERROR_HEADER = URI_HEADER_BASE + "error";
const URI_KEYERROR_HEADER = URI_HEADER_BASE + "errorInX5U";
const URI_SIGERROR_HEADER = URI_HEADER_BASE + "errorInSignature";
const URI_NO_HEADER = URI_HEADER_BASE + "noHeader";
const URI_BAD_SIG = BASE + "sig=bad&x5u=good&file=good&header=good";
const URI_BROKEN_SIG = BASE + "sig=broken&x5u=good&file=good&header=good";
const URI_BAD_X5U = BASE + "sig=good&x5u=bad&file=good&header=good";
const URI_HTTP_X5U = BASE + "sig=good&x5u=http&file=good&header=good";
const URI_BAD_FILE = BASE + "sig=good&x5u=good&file=bad&header=good";
const URI_BAD_ALL = BASE + "sig=bad&x5u=bad&file=bad&header=bad";
const URI_BAD_CSP = BASE + "sig=bad-csp&x5u=good&file=bad-csp&header=good";
const URI_BAD_FILE_CACHED = BASE + "sig=good&x5u=good&file=bad&header=good&cached=true";
const GOOD_ABOUT_STRING = "Just a fully good testpage for Bug 1226928";
const BAD_ABOUT_STRING = "Just a bad testpage for Bug 1226928";
const ABOUT_BLANK = "<head></head><body></body>";
const URI_CLEANUP = BASE + "cleanup=true";
const CLEANUP_DONE = "Done";
const URI_SRI = BASE + "sig=sri&x5u=good&file=sri&header=good";
const STYLESHEET_WITHOUT_SRI_BLOCKED = "Stylesheet without SRI blocked";
const STYLESHEET_WITH_SRI_BLOCKED = "Stylesheet with SRI blocked";
const STYLESHEET_WITH_SRI_LOADED = "Stylesheet with SRI loaded";
const SCRIPT_WITHOUT_SRI_BLOCKED = "Script without SRI blocked";
const SCRIPT_WITH_SRI_BLOCKED = "Script with SRI blocked";
const SCRIPT_WITH_SRI_LOADED = "Script with SRI loaded";
const CSP_TEST_SUCCESS_STRING = "CSP violation test succeeded.";
// Needs to sync with pref "security.signed_content.CSP.default".
const SIGNED_CONTENT_CSP = `{"csp-policies":[{"report-only":false,"script-src":["https://example.com","'unsafe-inline'"],"style-src":["https://example.com"]}]}`;
var browser = null;
var aboutNewTabService = Cc["@mozilla.org/browser/aboutnewtab-service;1"]
.getService(Ci.nsIAboutNewTabService);
function pushPrefs(...aPrefs) {
return SpecialPowers.pushPrefEnv({"set": aPrefs});
}
/*
* run tests with input from TESTS
*/
async function doTest(aExpectedStrings, reload, aUrl, aNewTabPref) {
// set about:newtab location for this test if it's a newtab test
if (aNewTabPref) {
aboutNewTabService.newTabURL = aNewTabPref;
}
// set prefs
await pushPrefs(
["browser.newtabpage.remote.content-signing-test", true],
["browser.newtabpage.remote", true],
["security.content.signature.root_hash",
"CC:BE:04:87:74:B2:98:24:4A:C6:7A:71:BC:6F:DB:D6:C0:48:17:29:57:51:96:47:38:CC:24:C8:E4:F9:DD:CB"]);
if (aNewTabPref === URI_BAD_CSP) {
// Use stricter CSP to test CSP violation.
await pushPrefs(["security.signed_content.CSP.default", "script-src 'self'; style-src 'self'"]);
} else {
// Use weaker CSP to test normal content.
await pushPrefs(["security.signed_content.CSP.default", "script-src 'self' 'unsafe-inline'; style-src 'self'"]);
}
// start the test
await BrowserTestUtils.withNewTab({
gBrowser,
url: aUrl,
},
async function(browser) {
// check if everything's set correct for testing
ok(Services.prefs.getBoolPref(
"browser.newtabpage.remote.content-signing-test"),
"sanity check: remote newtab signing test should be used");
ok(Services.prefs.getBoolPref("browser.newtabpage.remote"),
"sanity check: remote newtab should be used");
// we only check this if we really do a newtab test
if (aNewTabPref) {
ok(aboutNewTabService.overridden,
"sanity check: default URL for about:newtab should be overriden");
is(aboutNewTabService.newTabURL, aNewTabPref,
"sanity check: default URL for about:newtab should return the new URL");
}
// Every valid remote newtab page must have built-in CSP.
let shouldHaveCSP = ((aUrl === ABOUT_NEWTAB_URI) &&
(aNewTabPref === URI_GOOD || aNewTabPref === URI_SRI));
if (shouldHaveCSP) {
is(browser.contentDocument.nodePrincipal.cspJSON, SIGNED_CONTENT_CSP,
"Valid remote newtab page must have built-in CSP.");
}
await ContentTask.spawn(
browser, aExpectedStrings, async function(aExpectedStrings) {
for (let expectedString of aExpectedStrings) {
ok(content.document.documentElement.innerHTML.includes(expectedString),
"Expect the following value in the result\n" + expectedString +
"\nand got " + content.document.documentElement.innerHTML);
}
});
// for good test cases we check if a reload fails if the remote page
// changed from valid to invalid in the meantime
if (reload) {
await BrowserTestUtils.withNewTab({
gBrowser,
url: INVALIDATE_FILE,
},
async function(browser2) {
await ContentTask.spawn(browser2, null, async function() {
ok(content.document.documentElement.innerHTML.includes("Done"),
"Expect the following value in the result\n" + "Done" +
"\nand got " + content.document.documentElement.innerHTML);
});
}
);
browser.reload();
await BrowserTestUtils.browserLoaded(browser);
let expectedStrings = [ABOUT_BLANK];
if (aNewTabPref == URI_SRI) {
expectedStrings = [
STYLESHEET_WITHOUT_SRI_BLOCKED,
STYLESHEET_WITH_SRI_BLOCKED,
SCRIPT_WITHOUT_SRI_BLOCKED,
SCRIPT_WITH_SRI_BLOCKED
];
}
await ContentTask.spawn(browser, expectedStrings,
async function(expectedStrings) {
for (let expectedString of expectedStrings) {
ok(content.document.documentElement.innerHTML.includes(expectedString),
"Expect the following value in the result\n" + expectedString +
"\nand got " + content.document.documentElement.innerHTML);
}
}
);
await BrowserTestUtils.withNewTab({
gBrowser,
url: VALIDATE_FILE,
},
async function(browser2) {
await ContentTask.spawn(browser2, null, async function() {
ok(content.document.documentElement.innerHTML.includes("Done"),
"Expect the following value in the result\n" + "Done" +
"\nand got " + content.document.documentElement.innerHTML);
});
}
);
}
}
);
}
async function runTests() {
// run tests from TESTS
for (let i = 0; i < TESTS.length; i++) {
let testCase = TESTS[i];
let url = "", aNewTabPref = "";
let reload = false;
var aExpectedStrings = testCase.testStrings;
if (testCase.aboutURI) {
url = ABOUT_NEWTAB_URI;
aNewTabPref = testCase.aboutURI;
if (aNewTabPref == URI_GOOD || aNewTabPref == URI_SRI) {
reload = true;
}
} else {
url = testCase.url;
}
await doTest(aExpectedStrings, reload, url, aNewTabPref);
}
}

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

@ -1 +0,0 @@
var load=true;

Двоичные данные
dom/security/test/contentverifier/signature.der

Двоичный файл не отображается.

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

@ -1,9 +0,0 @@
-----BEGIN EC PARAMETERS-----
BgUrgQQAIg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDAzX2TrGOr0WE92AbAl+nqnpqh25pKCLYNMTV2hJHztrkVPWOp8w0mh
scIodK8RMpagBwYFK4EEACKhZANiAATiTcWYbt0Wg63dO7OXvpptNG0ryxv+v+Js
JJ5Upr3pFus5fZyKxzP9NPzB+oFhL/xw3jMx7X5/vBGaQ2sJSiNlHVkqZgzYF6JQ
4yUyiqTY7v67CyfUPA1BJg/nxOS9m3o=
-----END EC PRIVATE KEY-----

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

@ -1,3 +0,0 @@
#red-text {
color: red;
}

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

@ -34,10 +34,18 @@ add_task(async function test_isOriginPotentiallyTrustworthy() {
["http://example.net/", true],
["ws://example.org/", true],
["chrome://example.net/content/messenger.xul", false],
["http://1234567890abcdef.onion/", false],
]) {
let uri = NetUtil.newURI(uriSpec);
let principal = gScriptSecurityManager.createCodebasePrincipal(uri, {});
Assert.equal(gContentSecurityManager.isOriginPotentiallyTrustworthy(principal),
expectedResult);
}
// And now let's test whether .onion sites are properly treated when
// whitelisted, see bug 1382359.
prefs.setBoolPref("dom.securecontext.whitelist_onions", true);
let uri = NetUtil.newURI("http://1234567890abcdef.onion/");
let principal = gScriptSecurityManager.createCodebasePrincipal(uri, {});
Assert.equal(gContentSecurityManager.isOriginPotentiallyTrustworthy(principal),
true);
});

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

@ -175,7 +175,7 @@ class StringifyContext
static bool Str(JSContext* cx, const Value& v, StringifyContext* scx);
static bool
WriteIndent(JSContext* cx, StringifyContext* scx, uint32_t limit)
WriteIndent(StringifyContext* scx, uint32_t limit)
{
if (!scx->gap.empty()) {
if (!scx->sb.append('\n'))
@ -423,7 +423,7 @@ JO(JSContext* cx, HandleObject obj, StringifyContext* scx)
return false;
wroteMember = true;
if (!WriteIndent(cx, scx, scx->depth))
if (!WriteIndent(scx, scx->depth))
return false;
JSString* s = IdToString(cx, id);
@ -439,7 +439,7 @@ JO(JSContext* cx, HandleObject obj, StringifyContext* scx)
}
}
if (wroteMember && !WriteIndent(cx, scx, scx->depth - 1))
if (wroteMember && !WriteIndent(scx, scx->depth - 1))
return false;
return scx->sb.append('}');
@ -475,7 +475,7 @@ JA(JSContext* cx, HandleObject obj, StringifyContext* scx)
/* Steps 7-10. */
if (length != 0) {
/* Steps 4, 10b(i). */
if (!WriteIndent(cx, scx, scx->depth))
if (!WriteIndent(scx, scx->depth))
return false;
/* Steps 7-10. */
@ -527,13 +527,13 @@ JA(JSContext* cx, HandleObject obj, StringifyContext* scx)
if (i < length - 1) {
if (!scx->sb.append(','))
return false;
if (!WriteIndent(cx, scx, scx->depth))
if (!WriteIndent(scx, scx->depth))
return false;
}
}
/* Step 10(b)(iii). */
if (!WriteIndent(cx, scx, scx->depth - 1))
if (!WriteIndent(scx, scx->depth - 1))
return false;
}

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

@ -549,7 +549,7 @@ class js::OrderedHashTableRef : public gc::BufferableRef
template <typename ObjectT>
inline static MOZ_MUST_USE bool
WriteBarrierPostImpl(JSRuntime* rt, ObjectT* obj, const Value& keyValue)
WriteBarrierPostImpl(ObjectT* obj, const Value& keyValue)
{
if (MOZ_LIKELY(!keyValue.isObject()))
return true;
@ -577,15 +577,15 @@ WriteBarrierPostImpl(JSRuntime* rt, ObjectT* obj, const Value& keyValue)
}
inline static MOZ_MUST_USE bool
WriteBarrierPost(JSRuntime* rt, MapObject* map, const Value& key)
WriteBarrierPost(MapObject* map, const Value& key)
{
return WriteBarrierPostImpl(rt, map, key);
return WriteBarrierPostImpl(map, key);
}
inline static MOZ_MUST_USE bool
WriteBarrierPost(JSRuntime* rt, SetObject* set, const Value& key)
WriteBarrierPost(SetObject* set, const Value& key)
{
return WriteBarrierPostImpl(rt, set, key);
return WriteBarrierPostImpl(set, key);
}
bool
@ -618,7 +618,7 @@ MapObject::set(JSContext* cx, HandleObject obj, HandleValue k, HandleValue v)
if (!key.setValue(cx, k))
return false;
if (!WriteBarrierPost(cx->runtime(), &obj->as<MapObject>(), key.value()) ||
if (!WriteBarrierPost(&obj->as<MapObject>(), key.value()) ||
!map->put(key, v))
{
ReportOutOfMemory(cx);
@ -831,7 +831,7 @@ MapObject::set_impl(JSContext* cx, const CallArgs& args)
ValueMap& map = extract(args);
ARG0_KEY(cx, args, key);
if (!WriteBarrierPost(cx->runtime(), &args.thisv().toObject().as<MapObject>(), key.value()) ||
if (!WriteBarrierPost(&args.thisv().toObject().as<MapObject>(), key.value()) ||
!map.put(key, args.get(1)))
{
ReportOutOfMemory(cx);
@ -1302,7 +1302,7 @@ SetObject::add(JSContext* cx, HandleObject obj, HandleValue k)
if (!key.setValue(cx, k))
return false;
if (!WriteBarrierPost(cx->runtime(), &obj->as<SetObject>(), key.value()) ||
if (!WriteBarrierPost(&obj->as<SetObject>(), key.value()) ||
!set->put(key))
{
ReportOutOfMemory(cx);
@ -1408,7 +1408,7 @@ SetObject::construct(JSContext* cx, unsigned argc, Value* vp)
if (!key.setValue(cx, keyVal))
return false;
if (!WriteBarrierPost(cx->runtime(), obj, keyVal) ||
if (!WriteBarrierPost(obj, keyVal) ||
!set->put(key))
{
ReportOutOfMemory(cx);
@ -1525,7 +1525,7 @@ SetObject::add_impl(JSContext* cx, const CallArgs& args)
ValueSet& set = extract(args);
ARG0_KEY(cx, args, key);
if (!WriteBarrierPost(cx->runtime(), &args.thisv().toObject().as<SetObject>(), key.value()) ||
if (!WriteBarrierPost(&args.thisv().toObject().as<SetObject>(), key.value()) ||
!set.put(key))
{
ReportOutOfMemory(cx);

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

@ -2880,7 +2880,7 @@ AsyncGeneratorResumeNext(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenOb
// Steps 7-8.
Rooted<AsyncGeneratorRequest*> request(
cx, AsyncGeneratorObject::peekRequest(cx, asyncGenObj));
cx, AsyncGeneratorObject::peekRequest(asyncGenObj));
if (!request)
return false;

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

@ -550,8 +550,7 @@ class BytecodeEmitter::EmitterScope : public Nestable<BytecodeEmitter::EmitterSc
return searchAndCache(bce, name);
}
Maybe<NameLocation> locationBoundInScope(BytecodeEmitter* bce, JSAtom* name,
EmitterScope* target);
Maybe<NameLocation> locationBoundInScope(JSAtom* name, EmitterScope* target);
};
void
@ -829,8 +828,7 @@ BytecodeEmitter::EmitterScope::searchAndCache(BytecodeEmitter* bce, JSAtom* name
}
Maybe<NameLocation>
BytecodeEmitter::EmitterScope::locationBoundInScope(BytecodeEmitter* bce, JSAtom* name,
EmitterScope* target)
BytecodeEmitter::EmitterScope::locationBoundInScope(JSAtom* name, EmitterScope* target)
{
// The target scope must be an intra-frame enclosing scope of this
// one. Count the number of extra hops to reach it.
@ -1669,7 +1667,7 @@ class MOZ_STACK_CLASS TryEmitter
}
private:
bool emitCatchEnd(bool hasNext) {
bool emitCatchEnd() {
MOZ_ASSERT(state_ == Catch);
if (!controlInfo_)
@ -1708,7 +1706,7 @@ class MOZ_STACK_CLASS TryEmitter
return false;
} else {
MOZ_ASSERT(state_ == Catch);
if (!emitCatchEnd(false))
if (!emitCatchEnd())
return false;
}
@ -1770,7 +1768,7 @@ class MOZ_STACK_CLASS TryEmitter
bool emitEnd() {
if (state_ == Catch) {
MOZ_ASSERT(!hasFinally());
if (!emitCatchEnd(false))
if (!emitCatchEnd())
return false;
} else {
MOZ_ASSERT(state_ == Finally);
@ -2229,7 +2227,7 @@ BytecodeEmitter::lookupName(JSAtom* name)
Maybe<NameLocation>
BytecodeEmitter::locationOfNameBoundInScope(JSAtom* name, EmitterScope* target)
{
return innermostEmitterScope->locationBoundInScope(this, name, target);
return innermostEmitterScope->locationBoundInScope(name, target);
}
Maybe<NameLocation>
@ -2238,7 +2236,7 @@ BytecodeEmitter::locationOfNameBoundInFunctionScope(JSAtom* name, EmitterScope*
EmitterScope* funScope = source;
while (!funScope->scope(this)->is<FunctionScope>())
funScope = funScope->enclosingInFrame();
return source->locationBoundInScope(this, name, funScope);
return source->locationBoundInScope(name, funScope);
}
bool
@ -8992,7 +8990,7 @@ BytecodeEmitter::emitSelfHostedResumeGenerator(ParseNode* pn)
}
bool
BytecodeEmitter::emitSelfHostedForceInterpreter(ParseNode* pn)
BytecodeEmitter::emitSelfHostedForceInterpreter()
{
if (!emit1(JSOP_FORCEINTERPRETER))
return false;
@ -9125,7 +9123,7 @@ BytecodeEmitter::isRestParameter(ParseNode* pn)
}
bool
BytecodeEmitter::emitCallee(ParseNode* callee, ParseNode* call, bool spread, bool* callop)
BytecodeEmitter::emitCallee(ParseNode* callee, ParseNode* call, bool* callop)
{
switch (callee->getKind()) {
case ParseNodeKind::Name:
@ -9210,7 +9208,7 @@ BytecodeEmitter::emitPipeline(ParseNode* pn)
do {
bool callop = true;
if (!emitCallee(callee, pn, false, &callop))
if (!emitCallee(callee, pn, &callop))
return false;
// Emit room for |this|
@ -9274,7 +9272,7 @@ BytecodeEmitter::emitCallOrNew(ParseNode* pn, ValueUsage valueUsage /* = ValueUs
if (pn2->name() == cx->names().resumeGenerator)
return emitSelfHostedResumeGenerator(pn);
if (pn2->name() == cx->names().forceInterpreter)
return emitSelfHostedForceInterpreter(pn);
return emitSelfHostedForceInterpreter();
if (pn2->name() == cx->names().allowContentIter)
return emitSelfHostedAllowContentIter(pn);
if (pn2->name() == cx->names().defineDataPropertyIntrinsic && pn->pn_count == 4)
@ -9286,7 +9284,7 @@ BytecodeEmitter::emitCallOrNew(ParseNode* pn, ValueUsage valueUsage /* = ValueUs
// Fall through
}
if (!emitCallee(pn2, pn, spread, &callop))
if (!emitCallee(pn2, pn, &callop))
return false;
bool isNewOp = pn->getOp() == JSOP_NEW || pn->getOp() == JSOP_SPREADNEW ||

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

@ -794,7 +794,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitCallOrNew(ParseNode* pn, ValueUsage valueUsage = ValueUsage::WantValue);
MOZ_MUST_USE bool emitSelfHostedCallFunction(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedResumeGenerator(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedForceInterpreter(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedForceInterpreter();
MOZ_MUST_USE bool emitSelfHostedAllowContentIter(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedDefineDataProperty(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedGetPropertySuper(ParseNode* pn);
@ -836,7 +836,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
EmitElemOption opts = EmitElemOption::Get);
MOZ_MUST_USE bool emitSuperElemOp(ParseNode* pn, JSOp op, bool isCall = false);
MOZ_MUST_USE bool emitCallee(ParseNode* callee, ParseNode* call, bool spread, bool* callop);
MOZ_MUST_USE bool emitCallee(ParseNode* callee, ParseNode* call, bool* callop);
MOZ_MUST_USE bool emitPipeline(ParseNode* pn);

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

@ -143,7 +143,7 @@ GCRuntime::tryNewNurseryString(JSContext* cx, size_t thingSize, AllocKind kind)
MOZ_ASSERT(!cx->isNurseryAllocSuppressed());
MOZ_ASSERT(!IsAtomsCompartment(cx->compartment()));
Cell* cell = cx->nursery().allocateString(cx, cx->zone(), thingSize, kind);
Cell* cell = cx->nursery().allocateString(cx->zone(), thingSize, kind);
if (cell)
return static_cast<JSString*>(cell);
@ -152,7 +152,7 @@ GCRuntime::tryNewNurseryString(JSContext* cx, size_t thingSize, AllocKind kind)
// Exceeding gcMaxBytes while tenuring can disable the Nursery.
if (cx->nursery().isEnabled()) {
cell = cx->nursery().allocateString(cx, cx->zone(), thingSize, kind);
cell = cx->nursery().allocateString(cx->zone(), thingSize, kind);
MOZ_ASSERT(cell);
return static_cast<JSString*>(cell);
}
@ -242,7 +242,7 @@ GCRuntime::tryNewTenuredThing(JSContext* cx, AllocKind kind, size_t thingSize)
// Get the next available free list and allocate out of it. This may
// acquire a new arena, which will lock the chunk list. If there are no
// chunks available it may also allocate new memory directly.
t = reinterpret_cast<T*>(refillFreeListFromAnyThread(cx, kind, thingSize));
t = reinterpret_cast<T*>(refillFreeListFromAnyThread(cx, kind));
if (MOZ_UNLIKELY(!t && allowGC && !cx->helperThread())) {
// We have no memory available for a new chunk; perform an
@ -362,18 +362,18 @@ GCRuntime::startBackgroundAllocTaskIfIdle()
}
/* static */ TenuredCell*
GCRuntime::refillFreeListFromAnyThread(JSContext* cx, AllocKind thingKind, size_t thingSize)
GCRuntime::refillFreeListFromAnyThread(JSContext* cx, AllocKind thingKind)
{
cx->arenas()->checkEmptyFreeList(thingKind);
if (!cx->helperThread())
return refillFreeListFromActiveCooperatingThread(cx, thingKind, thingSize);
return refillFreeListFromActiveCooperatingThread(cx, thingKind);
return refillFreeListFromHelperThread(cx, thingKind);
}
/* static */ TenuredCell*
GCRuntime::refillFreeListFromActiveCooperatingThread(JSContext* cx, AllocKind thingKind, size_t thingSize)
GCRuntime::refillFreeListFromActiveCooperatingThread(JSContext* cx, AllocKind thingKind)
{
// It should not be possible to allocate on the active thread while we are
// inside a GC.
@ -690,7 +690,7 @@ Chunk::init(JSRuntime* rt)
* Decommit the arenas. We do this after poisoning so that if the OS does
* not have to recycle the pages, we still get the benefit of poisoning.
*/
decommitAllArenas(rt);
decommitAllArenas();
/* Initialize the chunk info. */
info.init();
@ -699,7 +699,7 @@ Chunk::init(JSRuntime* rt)
/* The rest of info fields are initialized in pickChunk. */
}
void Chunk::decommitAllArenas(JSRuntime* rt)
void Chunk::decommitAllArenas()
{
decommittedArenas.clear(true);
MarkPagesUnused(&arenas[0], ArenasPerChunk * ArenaSize);

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

@ -316,7 +316,7 @@ class ArenaLists
js::SliceBudget& sliceBudget, gcstats::Statistics& stats);
void queueForegroundObjectsForSweep(FreeOp* fop);
void queueForegroundThingsForSweep(FreeOp* fop);
void queueForegroundThingsForSweep();
void releaseForegroundSweptEmptyArenas();
@ -334,8 +334,8 @@ class ArenaLists
private:
inline void queueForForegroundSweep(FreeOp* fop, const FinalizePhase& phase);
inline void queueForBackgroundSweep(FreeOp* fop, const FinalizePhase& phase);
inline void queueForForegroundSweep(FreeOp* fop, AllocKind thingKind);
inline void queueForBackgroundSweep(FreeOp* fop, AllocKind thingKind);
inline void queueForForegroundSweep(AllocKind thingKind);
inline void queueForBackgroundSweep(AllocKind thingKind);
TenuredCell* allocateFromArena(JS::Zone* zone, AllocKind thingKind,
ShouldCheckThresholds checkThresholds);

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

@ -784,7 +784,7 @@ GCRuntime::expireEmptyChunkPool(const AutoLockGC& lock)
}
static void
FreeChunkPool(JSRuntime* rt, ChunkPool& pool)
FreeChunkPool(ChunkPool& pool)
{
for (ChunkPool::Iter iter(pool); !iter.done();) {
Chunk* chunk = iter.get();
@ -797,9 +797,9 @@ FreeChunkPool(JSRuntime* rt, ChunkPool& pool)
}
void
GCRuntime::freeEmptyChunks(JSRuntime* rt, const AutoLockGC& lock)
GCRuntime::freeEmptyChunks(const AutoLockGC& lock)
{
FreeChunkPool(rt, emptyChunks(lock));
FreeChunkPool(emptyChunks(lock));
}
inline void
@ -818,7 +818,7 @@ GCRuntime::prepareToFreeChunk(ChunkInfo& info)
}
inline void
GCRuntime::updateOnArenaFree(const ChunkInfo& info)
GCRuntime::updateOnArenaFree()
{
++numArenasFreeCommitted;
}
@ -831,11 +831,11 @@ Chunk::addArenaToFreeList(JSRuntime* rt, Arena* arena)
info.freeArenasHead = arena;
++info.numArenasFreeCommitted;
++info.numArenasFree;
rt->gc.updateOnArenaFree(info);
rt->gc.updateOnArenaFree();
}
void
Chunk::addArenaToDecommittedList(JSRuntime* rt, const Arena* arena)
Chunk::addArenaToDecommittedList(const Arena* arena)
{
++info.numArenasFree;
decommittedArenas.set(Chunk::arenaIndex(arena->address()));
@ -873,7 +873,7 @@ Chunk::decommitOneFreeArena(JSRuntime* rt, AutoLockGC& lock)
}
if (ok)
addArenaToDecommittedList(rt, arena);
addArenaToDecommittedList(arena);
else
addArenaToFreeList(rt, arena);
updateChunkListAfterFree(rt, lock);
@ -917,7 +917,7 @@ Chunk::updateChunkListAfterFree(JSRuntime* rt, const AutoLockGC& lock)
} else {
MOZ_ASSERT(unused());
rt->gc.availableChunks(lock).remove(this);
decommitAllArenas(rt);
decommitAllArenas();
MOZ_ASSERT(info.numArenasFreeCommitted == 0);
rt->gc.recycleChunk(this, lock);
}
@ -1276,9 +1276,9 @@ GCRuntime::finish()
groups().clear();
FreeChunkPool(rt, fullChunks_.ref());
FreeChunkPool(rt, availableChunks_.ref());
FreeChunkPool(rt, emptyChunks_.ref());
FreeChunkPool(fullChunks_.ref());
FreeChunkPool(availableChunks_.ref());
FreeChunkPool(emptyChunks_.ref());
FinishTrace();
@ -2468,8 +2468,7 @@ Zone::prepareForCompacting()
void
GCRuntime::sweepTypesAfterCompacting(Zone* zone)
{
FreeOp* fop = rt->defaultFreeOp();
zone->beginSweepTypes(fop, rt->gc.releaseObservedTypes && !zone->isPreservingCode());
zone->beginSweepTypes(rt->gc.releaseObservedTypes && !zone->isPreservingCode());
AutoClearTypeInferenceStateOnOOM oom(zone);
@ -2493,17 +2492,17 @@ GCRuntime::sweepZoneAfterCompacting(Zone* zone)
cache->sweep();
if (jit::JitZone* jitZone = zone->jitZone())
jitZone->sweep(fop);
jitZone->sweep();
for (CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
c->objectGroups.sweep(fop);
c->objectGroups.sweep();
c->sweepRegExps();
c->sweepSavedStacks();
c->sweepVarNames();
c->sweepGlobalObject();
c->sweepSelfHostingScriptSource();
c->sweepDebugEnvironments();
c->sweepJitCompartment(fop);
c->sweepJitCompartment();
c->sweepNativeIterators();
c->sweepTemplateObjects();
}
@ -2519,7 +2518,7 @@ UpdateCellPointers(MovingTracer* trc, T* cell)
template <typename T>
static void
UpdateArenaPointersTyped(MovingTracer* trc, Arena* arena, JS::TraceKind traceKind)
UpdateArenaPointersTyped(MovingTracer* trc, Arena* arena)
{
for (ArenaCellIterUnderGC i(arena); !i.done(); i.next())
UpdateCellPointers(trc, reinterpret_cast<T*>(i.getCell()));
@ -2536,7 +2535,7 @@ UpdateArenaPointers(MovingTracer* trc, Arena* arena)
switch (kind) {
#define EXPAND_CASE(allocKind, traceKind, type, sizedType, bgFinal, nursery) \
case AllocKind::allocKind: \
UpdateArenaPointersTyped<type>(trc, arena, JS::TraceKind::traceKind); \
UpdateArenaPointersTyped<type>(trc, arena); \
return;
FOR_EACH_ALLOCKIND(EXPAND_CASE)
#undef EXPAND_CASE
@ -2723,7 +2722,7 @@ GCRuntime::updateTypeDescrObjects(MovingTracer* trc, Zone* zone)
}
void
GCRuntime::updateCellPointers(MovingTracer* trc, Zone* zone, AllocKinds kinds, size_t bgTaskCount)
GCRuntime::updateCellPointers(Zone* zone, AllocKinds kinds, size_t bgTaskCount)
{
AllocKinds fgKinds = bgTaskCount == 0 ? kinds : ForegroundUpdateKinds(kinds);
AllocKinds bgKinds = kinds - fgKinds;
@ -2815,13 +2814,13 @@ GCRuntime::updateAllCellPointers(MovingTracer* trc, Zone* zone)
{
size_t bgTaskCount = CellUpdateBackgroundTaskCount();
updateCellPointers(trc, zone, UpdatePhaseMisc, bgTaskCount);
updateCellPointers(zone, UpdatePhaseMisc, bgTaskCount);
// Update TypeDescrs before all other objects as typed objects access these
// objects when we trace them.
updateTypeDescrObjects(trc, zone);
updateCellPointers(trc, zone, UpdatePhaseObjects, bgTaskCount);
updateCellPointers(zone, UpdatePhaseObjects, bgTaskCount);
}
/*
@ -3048,11 +3047,11 @@ ArenaLists::queueForForegroundSweep(FreeOp* fop, const FinalizePhase& phase)
{
gcstats::AutoPhase ap(fop->runtime()->gc.stats(), phase.statsPhase);
for (auto kind : phase.kinds)
queueForForegroundSweep(fop, kind);
queueForForegroundSweep(kind);
}
void
ArenaLists::queueForForegroundSweep(FreeOp* fop, AllocKind thingKind)
ArenaLists::queueForForegroundSweep(AllocKind thingKind)
{
MOZ_ASSERT(!IsBackgroundFinalized(thingKind));
MOZ_ASSERT(backgroundFinalizeState(thingKind) == BFS_DONE);
@ -3067,11 +3066,11 @@ ArenaLists::queueForBackgroundSweep(FreeOp* fop, const FinalizePhase& phase)
{
gcstats::AutoPhase ap(fop->runtime()->gc.stats(), phase.statsPhase);
for (auto kind : phase.kinds)
queueForBackgroundSweep(fop, kind);
queueForBackgroundSweep(kind);
}
inline void
ArenaLists::queueForBackgroundSweep(FreeOp* fop, AllocKind thingKind)
ArenaLists::queueForBackgroundSweep(AllocKind thingKind)
{
MOZ_ASSERT(IsBackgroundFinalized(thingKind));
@ -3143,7 +3142,7 @@ ArenaLists::releaseForegroundSweptEmptyArenas()
}
void
ArenaLists::queueForegroundThingsForSweep(FreeOp* fop)
ArenaLists::queueForegroundThingsForSweep()
{
gcShapeArenasToUpdate = arenaListsToSweep(AllocKind::SHAPE);
gcAccessorShapeArenasToUpdate = arenaListsToSweep(AllocKind::ACCESSOR_SHAPE);
@ -3456,7 +3455,7 @@ js::gc::BackgroundDecommitTask::run()
ChunkPool toFree = runtime()->gc.expireEmptyChunkPool(lock);
if (toFree.count()) {
AutoUnlockGC unlock(lock);
FreeChunkPool(runtime(), toFree);
FreeChunkPool(toFree);
}
}
@ -3726,7 +3725,7 @@ UniqueIdGCPolicy::needsSweep(Cell** cell, uint64_t*)
}
void
JS::Zone::sweepUniqueIds(js::FreeOp* fop)
JS::Zone::sweepUniqueIds()
{
uniqueIds().sweep();
}
@ -5363,7 +5362,7 @@ static void
SweepObjectGroups(JSRuntime* runtime)
{
for (SweepGroupCompartmentsIter c(runtime); !c.done(); c.next())
c->objectGroups.sweep(runtime->defaultFreeOp());
c->objectGroups.sweep();
}
static void
@ -5432,9 +5431,8 @@ SweepWeakMaps(JSRuntime* runtime)
static void
SweepUniqueIds(JSRuntime* runtime)
{
FreeOp fop(nullptr);
for (SweepGroupZonesIter zone(runtime); !zone.done(); zone.next())
zone->sweepUniqueIds(&fop);
zone->sweepUniqueIds();
}
void
@ -5494,11 +5492,11 @@ GCRuntime::sweepJitDataOnMainThread(FreeOp* fop)
js::CancelOffThreadIonCompile(rt, JS::Zone::Sweep);
for (SweepGroupCompartmentsIter c(rt); !c.done(); c.next())
c->sweepJitCompartment(fop);
c->sweepJitCompartment();
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next()) {
if (jit::JitZone* jitZone = zone->jitZone())
jitZone->sweep(fop);
jitZone->sweep();
}
// Bug 1071218: the following method has not yet been refactored to
@ -5519,7 +5517,7 @@ GCRuntime::sweepJitDataOnMainThread(FreeOp* fop)
gcstats::AutoPhase ap1(stats(), gcstats::PhaseKind::SWEEP_TYPES);
gcstats::AutoPhase ap2(stats(), gcstats::PhaseKind::SWEEP_TYPES_BEGIN);
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next())
zone->beginSweepTypes(fop, releaseObservedTypes && !zone->isPreservingCode());
zone->beginSweepTypes(releaseObservedTypes && !zone->isPreservingCode());
}
}
@ -5689,7 +5687,7 @@ GCRuntime::beginSweepingSweepGroup(FreeOp* fop, SliceBudget& budget)
for (unsigned i = 0; i < ArrayLength(BackgroundFinalizePhases); ++i)
zone->arenas.queueForBackgroundSweep(fop, BackgroundFinalizePhases[i]);
zone->arenas.queueForegroundThingsForSweep(fop);
zone->arenas.queueForegroundThingsForSweep();
}
sweepCache = nullptr;
@ -6651,13 +6649,13 @@ GCRuntime::compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget,
}
void
GCRuntime::endCompactPhase(JS::gcreason::Reason reason)
GCRuntime::endCompactPhase()
{
startedCompacting = false;
}
void
GCRuntime::finishCollection(JS::gcreason::Reason reason)
GCRuntime::finishCollection()
{
assertBackgroundSweepingFinished();
MOZ_ASSERT(marker.isDrained());
@ -7116,7 +7114,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
if (compactPhase(reason, budget, session) == NotFinished)
break;
endCompactPhase(reason);
endCompactPhase();
}
startDecommit();
@ -7135,7 +7133,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
decommitTask.join();
}
finishCollection(reason);
finishCollection();
incrementalState = State::NotActive;
break;
}
@ -7721,7 +7719,7 @@ GCRuntime::onOutOfMallocMemory(const AutoLockGC& lock)
releaseHeldRelocatedArenasWithoutUnlocking(lock);
// Throw away any excess chunks we have lying around.
freeEmptyChunks(rt, lock);
freeEmptyChunks(lock);
// Immediately decommit as many arenas as possible in the hopes that this
// might let the OS scrape together enough pages to satisfy the failing
@ -8470,7 +8468,7 @@ js::gc::CheckHashTablesAfterMovingGC(JSRuntime* rt)
c->checkWrapperMapAfterMovingGC();
c->checkScriptMapsAfterMovingGC();
if (c->debugEnvs)
c->debugEnvs->checkHashTablesAfterMovingGC(rt);
c->debugEnvs->checkHashTablesAfterMovingGC();
}
}
#endif

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

@ -426,7 +426,7 @@ class GCRuntime
}
inline void updateOnFreeArenaAlloc(const ChunkInfo& info);
inline void updateOnArenaFree(const ChunkInfo& info);
inline void updateOnArenaFree();
ChunkPool& fullChunks(const AutoLockGC& lock) { return fullChunks_.ref(); }
ChunkPool& availableChunks(const AutoLockGC& lock) { return availableChunks_.ref(); }
@ -510,10 +510,9 @@ class GCRuntime
MOZ_MUST_USE bool gcIfNeededAtAllocation(JSContext* cx);
template <typename T>
static void checkIncrementalZoneState(JSContext* cx, T* t);
static TenuredCell* refillFreeListFromAnyThread(JSContext* cx, AllocKind thingKind,
size_t thingSize);
static TenuredCell* refillFreeListFromActiveCooperatingThread(JSContext* cx, AllocKind thingKind,
size_t thingSize);
static TenuredCell* refillFreeListFromAnyThread(JSContext* cx, AllocKind thingKind);
static TenuredCell* refillFreeListFromActiveCooperatingThread(JSContext* cx,
AllocKind thingKind);
static TenuredCell* refillFreeListFromHelperThread(JSContext* cx, AllocKind thingKind);
/*
@ -522,7 +521,7 @@ class GCRuntime
*/
friend class BackgroundDecommitTask;
ChunkPool expireEmptyChunkPool(const AutoLockGC& lock);
void freeEmptyChunks(JSRuntime* rt, const AutoLockGC& lock);
void freeEmptyChunks(const AutoLockGC& lock);
void prepareToFreeChunk(ChunkInfo& info);
friend class BackgroundAllocTask;
@ -612,13 +611,13 @@ class GCRuntime
void beginCompactPhase();
IncrementalProgress compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget,
AutoTraceSession& session);
void endCompactPhase(JS::gcreason::Reason reason);
void endCompactPhase();
void sweepTypesAfterCompacting(Zone* zone);
void sweepZoneAfterCompacting(Zone* zone);
MOZ_MUST_USE bool relocateArenas(Zone* zone, JS::gcreason::Reason reason,
Arena*& relocatedListOut, SliceBudget& sliceBudget);
void updateTypeDescrObjects(MovingTracer* trc, Zone* zone);
void updateCellPointers(MovingTracer* trc, Zone* zone, AllocKinds kinds, size_t bgTaskCount);
void updateCellPointers(Zone* zone, AllocKinds kinds, size_t bgTaskCount);
void updateAllCellPointers(MovingTracer* trc, Zone* zone);
void updateZonePointersToRelocatedCells(Zone* zone);
void updateRuntimePointersToRelocatedCells(AutoTraceSession& session);
@ -626,7 +625,7 @@ class GCRuntime
void unprotectHeldRelocatedArenas();
void releaseRelocatedArenas(Arena* arenaList);
void releaseRelocatedArenasWithoutUnlocking(Arena* arenaList, const AutoLockGC& lock);
void finishCollection(JS::gcreason::Reason reason);
void finishCollection();
void computeNonIncrementalMarkingForValidation(AutoTraceSession& session);
void validateIncrementalMarking();

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

@ -766,14 +766,14 @@ struct Chunk
void init(JSRuntime* rt);
private:
void decommitAllArenas(JSRuntime* rt);
void decommitAllArenas();
/* Search for a decommitted arena to allocate. */
unsigned findDecommittedArenaOffset();
Arena* fetchNextDecommittedArena();
void addArenaToFreeList(JSRuntime* rt, Arena* arena);
void addArenaToDecommittedList(JSRuntime* rt, const Arena* arena);
void addArenaToDecommittedList(const Arena* arena);
void updateChunkListAfterAlloc(JSRuntime* rt, const AutoLockGC& lock);
void updateChunkListAfterFree(JSRuntime* rt, const AutoLockGC& lock);

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

@ -3049,7 +3049,7 @@ js::TenuringTracer::moveToTenuredSlow(JSObject* src)
if (src->isNative()) {
NativeObject* ndst = &dst->as<NativeObject>();
NativeObject* nsrc = &src->as<NativeObject>();
tenuredSize += moveSlotsToTenured(ndst, nsrc, dstKind);
tenuredSize += moveSlotsToTenured(ndst, nsrc);
tenuredSize += moveElementsToTenured(ndst, nsrc, dstKind);
// There is a pointer into a dictionary mode object from the head of its
@ -3094,7 +3094,7 @@ js::TenuringTracer::movePlainObjectToTenured(PlainObject* src)
js_memcpy(dst, src, srcSize);
// Move the slots and elements.
tenuredSize += moveSlotsToTenured(dst, src, dstKind);
tenuredSize += moveSlotsToTenured(dst, src);
tenuredSize += moveElementsToTenured(dst, src, dstKind);
MOZ_ASSERT(!dst->getClass()->extObjectMovedOp());
@ -3108,7 +3108,7 @@ js::TenuringTracer::movePlainObjectToTenured(PlainObject* src)
}
size_t
js::TenuringTracer::moveSlotsToTenured(NativeObject* dst, NativeObject* src, AllocKind dstKind)
js::TenuringTracer::moveSlotsToTenured(NativeObject* dst, NativeObject* src)
{
/* Fixed slots have already been copied over. */
if (!src->hasDynamicSlots())

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

@ -326,7 +326,7 @@ js::Nursery::allocateObject(JSContext* cx, size_t size, size_t nDynamicSlots, co
}
Cell*
js::Nursery::allocateString(JSContext* cx, Zone* zone, size_t size, AllocKind kind)
js::Nursery::allocateString(Zone* zone, size_t size, AllocKind kind)
{
/* Ensure there's enough space to replace the contents with a RelocationOverlay. */
MOZ_ASSERT(size >= sizeof(RelocationOverlay));
@ -880,7 +880,7 @@ js::Nursery::doCollection(JS::gcreason::Reason reason,
// Update any slot or element pointers whose destination has been tenured.
startProfile(ProfileKey::UpdateJitActivations);
js::jit::UpdateJitActivationsForMinorGC(rt, &mover);
js::jit::UpdateJitActivationsForMinorGC(rt);
forwardedBuffers.finish();
endProfile(ProfileKey::UpdateJitActivations);

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

@ -110,7 +110,7 @@ class TenuringTracer : public JSTracer
JSString* moveToTenured(JSString* src);
size_t moveElementsToTenured(NativeObject* dst, NativeObject* src, gc::AllocKind dstKind);
size_t moveSlotsToTenured(NativeObject* dst, NativeObject* src, gc::AllocKind dstKind);
size_t moveSlotsToTenured(NativeObject* dst, NativeObject* src);
size_t moveStringToTenured(JSString* dst, JSString* src, gc::AllocKind dstKind);
void traceSlots(JS::Value* vp, JS::Value* end);
@ -200,7 +200,7 @@ class Nursery
* Allocate and return a pointer to a new string. Returns nullptr if the
* Nursery is full.
*/
gc::Cell* allocateString(JSContext* cx, JS::Zone* zone, size_t size, gc::AllocKind kind);
gc::Cell* allocateString(JS::Zone* zone, size_t size, gc::AllocKind kind);
/*
* String zones are stored just before the string in nursery memory.

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

@ -112,10 +112,10 @@ Zone::setNeedsIncrementalBarrier(bool needs)
}
void
Zone::beginSweepTypes(FreeOp* fop, bool releaseTypes)
Zone::beginSweepTypes(bool releaseTypes)
{
AutoClearTypeInferenceStateOnOOM oom(this);
types.beginSweep(fop, releaseTypes, oom);
types.beginSweep(releaseTypes, oom);
}
Zone::DebuggerVector*

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

@ -192,7 +192,7 @@ struct Zone : public JS::shadow::Zone,
}
void reportAllocationOverflow() { js::ReportAllocationOverflow(nullptr); }
void beginSweepTypes(js::FreeOp* fop, bool releaseTypes);
void beginSweepTypes(bool releaseTypes);
bool hasMarkedCompartments();
@ -265,7 +265,7 @@ struct Zone : public JS::shadow::Zone,
#endif
void sweepBreakpoints(js::FreeOp* fop);
void sweepUniqueIds(js::FreeOp* fop);
void sweepUniqueIds();
void sweepWeakMaps();
void sweepCompartments(js::FreeOp* fop, bool keepAtleastOne, bool lastGC);

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

@ -0,0 +1,16 @@
function warmup(fun, input, expected) {
assertEq(input.length, expected.length);
for (var i = 0; i < 30; i++) {
for (var j = 0; j < input.length; j++) {
lhs = input[j][0];
rhs = input[j][1];
assertEq(fun(lhs,rhs), expected[j]);
}
}
}
var strictCompare = function(a,b) { return a === b; }
warmup(strictCompare, [[1,1], [3,3], [3,strictCompare],[strictCompare, {}], [3.2, 1],
[0, -0]],
[true, true, false, false, false,
true]);

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

@ -18,9 +18,9 @@ var code = `(module
try {
wasmFullPass(code, Math.fround(13.37), {}, 13.37);
} catch (e) {
// ASAN will fail these tests because its stack frames are much bigger than
// usual ones and the parser will bail out during its recursive descent.
// Some configurations, like e.g. ASAN, will fail these tests because its
// stack frames are much bigger than usual ones and the parser will bail
// out during its recursive descent.
// Ignore those errors specifically.
assertEq(e.message.includes('out of memory'), true);
assertEq(getBuildConfiguration().asan, true);
}

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

@ -627,8 +627,8 @@ IsPrologueBailout(const SnapshotIterator& iter, const ExceptionBailoutInfo* excI
// +===============+
//
static bool
InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC,
HandleFunction fun, HandleScript script, IonScript* ionScript,
InitFromBailout(JSContext* cx, jsbytecode* callerPC,
HandleFunction fun, HandleScript script,
SnapshotIterator& iter, bool invalidate, BaselineStackBuilder& builder,
MutableHandle<GCVector<Value>> startFrameFormals, MutableHandleFunction nextCallee,
jsbytecode** callPC, const ExceptionBailoutInfo* excInfo)
@ -1665,7 +1665,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation,
jsbytecode* callPC = nullptr;
RootedFunction nextCallee(cx, nullptr);
if (!InitFromBailout(cx, caller, callerPC, fun, scr, iter.ionScript(),
if (!InitFromBailout(cx, callerPC, fun, scr,
snapIter, invalidate, builder, &startFrameFormals,
&nextCallee, &callPC, passExcInfo ? excInfo : nullptr))
{

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

@ -234,7 +234,7 @@ BaselineCompiler::compile()
// Copy IC entries
if (icEntries_.length())
baselineScript->copyICEntries(script, &icEntries_[0], masm);
baselineScript->copyICEntries(script, &icEntries_[0]);
// Adopt fallback stubs from the compiler into the baseline script.
baselineScript->adoptFallbackStubs(&stubSpace_);
@ -260,7 +260,7 @@ BaselineCompiler::compile()
#ifdef JS_TRACE_LOGGING
// Initialize the tracelogger instrumentation.
baselineScript->initTraceLogger(cx->runtime(), script, traceLoggerToggleOffsets_);
baselineScript->initTraceLogger(script, traceLoggerToggleOffsets_);
#endif
uint32_t* bytecodeMap = baselineScript->bytecodeTypeMap();
@ -290,7 +290,7 @@ BaselineCompiler::compile()
entry.init(code, code->raw(), code->rawEnd(), script, str);
JitcodeGlobalTable* globalTable = cx->runtime()->jitRuntime()->getJitcodeGlobalTable();
if (!globalTable->addEntry(entry, cx->runtime())) {
if (!globalTable->addEntry(entry)) {
entry.destroy();
ReportOutOfMemory(cx);
return Method_Error;
@ -4636,21 +4636,19 @@ BaselineCompiler::emit_JSOP_DEBUGAFTERYIELD()
return callVM(DebugAfterYieldInfo);
}
typedef bool (*FinalSuspendFn)(JSContext*, HandleObject, BaselineFrame*, jsbytecode*);
typedef bool (*FinalSuspendFn)(JSContext*, HandleObject, jsbytecode*);
static const VMFunction FinalSuspendInfo =
FunctionInfo<FinalSuspendFn>(jit::FinalSuspend, "FinalSuspend");
bool
BaselineCompiler::emit_JSOP_FINALYIELDRVAL()
{
// Store generator in R0, BaselineFrame pointer in R1.
// Store generator in R0.
frame.popRegsAndSync(1);
masm.unboxObject(R0, R0.scratchReg());
masm.loadBaselineFramePtr(BaselineFrameReg, R1.scratchReg());
prepareVMCall();
pushArg(ImmPtr(pc));
pushArg(R1.scratchReg());
pushArg(R0.scratchReg());
if (!callVM(FinalSuspendInfo))

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

@ -642,7 +642,7 @@ PatchBaselineFramesForDebugMode(JSContext* cx, const CooperatingContext& target,
static void
SkipInterpreterFrameEntries(const Debugger::ExecutionObservableSet& obs,
const ActivationIterator& activation,
DebugModeOSREntryVector& entries, size_t* start)
size_t* start)
{
size_t entryIndex = *start;
@ -912,7 +912,7 @@ jit::RecompileOnStackBaselineScriptsForDebugMode(JSContext* cx,
if (iter->isJit())
PatchBaselineFramesForDebugMode(cx, target, obs, iter, entries, &processed);
else if (iter->isInterpreter())
SkipInterpreterFrameEntries(obs, iter, entries, &processed);
SkipInterpreterFrameEntries(obs, iter, &processed);
}
}
MOZ_ASSERT(processed == entries.length());

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

@ -85,8 +85,7 @@ struct IonOsrTempData
};
static IonOsrTempData*
PrepareOsrTempData(JSContext* cx, ICWarmUpCounter_Fallback* stub, BaselineFrame* frame,
HandleScript script, jsbytecode* pc, void* jitcode)
PrepareOsrTempData(JSContext* cx, BaselineFrame* frame, void* jitcode)
{
size_t numLocalsAndStackVals = frame->numValueSlots();
@ -163,7 +162,7 @@ DoWarmUpCounterFallbackOSR(JSContext* cx, BaselineFrame* frame, ICWarmUpCounter_
// Prepare the temporary heap copy of the fake InterpreterFrame and actual args list.
JitSpew(JitSpew_BaselineOSR, "Got jitcode. Preparing for OSR into ion.");
IonOsrTempData* info = PrepareOsrTempData(cx, stub, frame, script, pc, jitcode);
IonOsrTempData* info = PrepareOsrTempData(cx, frame, jitcode);
if (!info)
return false;
*infoPtr = info;
@ -1635,7 +1634,7 @@ ICSetProp_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
// This is the resume point used when bailout rewrites call stack to undo
// Ion inlined frames. The return address pushed onto reconstructed stack
// will point here.
assumeStubFrame(masm);
assumeStubFrame();
bailoutReturnOffset_.bind(masm.currentOffset());
leaveStubFrame(masm, true);
@ -2327,7 +2326,7 @@ DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, uint
// Only bother to try optimizing JSOP_CALL with CacheIR if the chain is still
// allowed to attach stubs.
if (canAttachStub) {
CallIRGenerator gen(cx, script, pc, op, stub, stub->state().mode(), argc,
CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), argc,
callee, callArgs.thisv(),
HandleValueArray::fromMarkedLocation(argc, vp+2));
if (gen.tryAttachStub()) {
@ -2844,7 +2843,7 @@ ICCall_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
// This is the resume point used when bailout rewrites call stack to undo
// Ion inlined frames. The return address pushed onto reconstructed stack
// will point here.
assumeStubFrame(masm);
assumeStubFrame();
bailoutReturnOffset_.bind(masm.currentOffset());
// Load passed-in ThisV into R1 just in case it's needed. Need to do this before

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

@ -300,7 +300,7 @@ CanEnterBaselineJIT(JSContext* cx, HandleScript script, InterpreterFrame* osrFra
}
MethodStatus
jit::CanEnterBaselineAtBranch(JSContext* cx, InterpreterFrame* fp, bool newType)
jit::CanEnterBaselineAtBranch(JSContext* cx, InterpreterFrame* fp)
{
if (!CheckFrame(fp))
return Method_CantCompile;
@ -744,7 +744,7 @@ BaselineScript::copyYieldAndAwaitEntries(JSScript* script, Vector<uint32_t>& yie
}
void
BaselineScript::copyICEntries(JSScript* script, const BaselineICEntry* entries, MacroAssembler& masm)
BaselineScript::copyICEntries(JSScript* script, const BaselineICEntry* entries)
{
// Fix up the return offset in the IC entries and copy them in.
// Also write out the IC entry ptrs in any fallback stubs that were added.
@ -949,8 +949,7 @@ BaselineScript::toggleDebugTraps(JSScript* script, jsbytecode* pc)
#ifdef JS_TRACE_LOGGING
void
BaselineScript::initTraceLogger(JSRuntime* runtime, JSScript* script,
const Vector<CodeOffset>& offsets)
BaselineScript::initTraceLogger(JSScript* script, const Vector<CodeOffset>& offsets)
{
#ifdef DEBUG
traceLoggerScriptsEnabled_ = TraceLogTextIdEnabled(TraceLogger_Scripts);
@ -971,7 +970,7 @@ BaselineScript::initTraceLogger(JSRuntime* runtime, JSScript* script,
}
void
BaselineScript::toggleTraceLoggerScripts(JSRuntime* runtime, JSScript* script, bool enable)
BaselineScript::toggleTraceLoggerScripts(JSScript* script, bool enable)
{
DebugOnly<bool> engineEnabled = TraceLogTextIdEnabled(TraceLogger_Engine);
MOZ_ASSERT(enable == !traceLoggerScriptsEnabled_);
@ -1165,7 +1164,7 @@ jit::ToggleBaselineTraceLoggerScripts(JSRuntime* runtime, bool enable)
for (auto script = zone->cellIter<JSScript>(); !script.done(); script.next()) {
if (!script->hasBaselineScript())
continue;
script->baselineScript()->toggleTraceLoggerScripts(runtime, script, enable);
script->baselineScript()->toggleTraceLoggerScripts(script, enable);
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше