Merge inbound to mozilla-central. a=merge

This commit is contained in:
shindli 2018-02-23 11:40:37 +02:00
Родитель d611a1c062 49f4a46acf
Коммит f042b243a8
132 изменённых файлов: 1243 добавлений и 934 удалений

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

@ -40,7 +40,7 @@ const EXPECTED_APPMENU_OPEN_REFLOWS = [
"handleEvent@resource:///modules/PanelMultiView.jsm",
],
times: 6, // This number should only ever go down - never up.
maxCount: 6, // This number should only ever go down - never up.
},
];
@ -55,23 +55,13 @@ const EXPECTED_APPMENU_SUBVIEW_REFLOWS = [
* these expected reflows further. Bug 1392340 is on file to remove the
* reflows completely when opening subviews.
*/
{
stack: [
"descriptionHeightWorkaround@resource:///modules/PanelMultiView.jsm",
"set current@resource:///modules/PanelMultiView.jsm",
"hideAllViewsExcept@resource:///modules/PanelMultiView.jsm",
],
times: 1, // This number should only ever go down - never up.
},
{
stack: [
"descriptionHeightWorkaround@resource:///modules/PanelMultiView.jsm",
"_transitionViews@resource:///modules/PanelMultiView.jsm",
],
times: 3, // This number should only ever go down - never up.
maxCount: 4, // This number should only ever go down - never up.
},
/**

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

@ -29,7 +29,6 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"openPopup@chrome://global/content/bindings/autocomplete.xml",
"set_popupOpen@chrome://global/content/bindings/autocomplete.xml"
],
times: 1, // This number should only ever go down - never up.
},
{
@ -37,7 +36,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
"onxblpopupshown@chrome://global/content/bindings/autocomplete.xml"
],
times: 5, // This number should only ever go down - never up.
maxCount: 5, // This number should only ever go down - never up.
},
{
@ -45,8 +44,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
"_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
],
minTimes: 39, // This number should only ever go down - never up.
times: 51, // This number should only ever go down - never up.
maxCount: 51, // This number should only ever go down - never up.
},
{
@ -58,7 +56,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"_invalidate@chrome://global/content/bindings/autocomplete.xml",
"invalidate@chrome://global/content/bindings/autocomplete.xml"
],
times: 60, // This number should only ever go down - never up.
maxCount: 60, // This number should only ever go down - never up.
},
{
@ -70,7 +68,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"openPopup@chrome://global/content/bindings/autocomplete.xml",
"set_popupOpen@chrome://global/content/bindings/autocomplete.xml",
],
times: 6, // This number should only ever go down - never up.
maxCount: 6, // This number should only ever go down - never up.
},
// Bug 1359989

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

@ -29,7 +29,6 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"openPopup@chrome://global/content/bindings/autocomplete.xml",
"set_popupOpen@chrome://global/content/bindings/autocomplete.xml"
],
times: 1, // This number should only ever go down - never up.
},
{
@ -37,7 +36,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
"onxblpopupshown@chrome://global/content/bindings/autocomplete.xml"
],
times: 5, // This number should only ever go down - never up.
maxCount: 5, // This number should only ever go down - never up.
},
{
@ -45,7 +44,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
"_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
],
times: 3, // This number should only ever go down - never up.
maxCount: 3, // This number should only ever go down - never up.
},
{
@ -57,7 +56,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"_invalidate@chrome://global/content/bindings/autocomplete.xml",
"invalidate@chrome://global/content/bindings/autocomplete.xml"
],
times: 36, // This number should only ever go down - never up.
maxCount: 36, // This number should only ever go down - never up.
},
{
@ -69,7 +68,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
"openPopup@chrome://global/content/bindings/autocomplete.xml",
"set_popupOpen@chrome://global/content/bindings/autocomplete.xml",
],
times: 6, // This number should only ever go down - never up.
maxCount: 6, // This number should only ever go down - never up.
},
// Bug 1359989
@ -91,7 +90,7 @@ const EXPECTED_REFLOWS_SECOND_OPEN = [
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
"onxblpopupshown@chrome://global/content/bindings/autocomplete.xml"
],
times: 3, // This number should only ever go down - never up.
maxCount: 3, // This number should only ever go down - never up.
},
{
@ -99,7 +98,7 @@ const EXPECTED_REFLOWS_SECOND_OPEN = [
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
"_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
],
times: 3, // This number should only ever go down - never up.
maxCount: 3, // This number should only ever go down - never up.
},
{
@ -111,7 +110,7 @@ const EXPECTED_REFLOWS_SECOND_OPEN = [
"_invalidate@chrome://global/content/bindings/autocomplete.xml",
"invalidate@chrome://global/content/bindings/autocomplete.xml"
],
times: 24, // This number should only ever go down - never up.
maxCount: 24, // This number should only ever go down - never up.
},
// Bug 1359989

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

@ -27,7 +27,7 @@ if (Services.appinfo.OS == "WINNT") {
"init@chrome://browser/content/browser-tabsintitlebar.js",
"handleEvent@chrome://browser/content/tabbrowser.xml",
],
times: 2, // This number should only ever go down - never up.
maxCount: 2, // This number should only ever go down - never up.
},
);
}
@ -42,7 +42,7 @@ if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
"handleEvent@chrome://browser/content/tabbrowser.xml",
],
// These numbers should only ever go down - never up.
times: Services.appinfo.OS == "WINNT" ? 5 : 4,
maxCount: Services.appinfo.OS == "WINNT" ? 5 : 4,
},
);
}

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

@ -25,8 +25,7 @@ ChromeUtils.defineModuleGetter(this, "PlacesTestUtils",
* {
* // This reflow is caused by lorem ipsum.
* // Sometimes, due to unpredictable timings, the reflow may be hit
* // less times, or not hit at all; in such a case a minTimes
* // property can be provided to avoid intermittent failures.
* // less times.
* stack: [
* "select@chrome://global/content/bindings/textbox.xml",
* "focusAndSelectUrlBar@chrome://browser/content/browser.js",
@ -34,15 +33,13 @@ ChromeUtils.defineModuleGetter(this, "PlacesTestUtils",
* "openUILinkIn@chrome://browser/content/utilityOverlay.js",
* "BrowserOpenTab@chrome://browser/content/browser.js",
* ],
* // We expect this particular reflow to happen 2 times
* times: 2,
* // Sometimes this is not hit.
* minTimes: 0
* // We expect this particular reflow to happen up to 2 times.
* maxCount: 2,
* },
*
* {
* // This reflow is caused by lorem ipsum. We expect this reflow
* // to only happen once, so we can omit the "times" property.
* // to only happen once, so we can omit the "maxCount" property.
* stack: [
* "get_scrollPosition@chrome://global/content/bindings/scrollbox.xml",
* "_fillTrailingGap@chrome://browser/content/tabbrowser.xml",
@ -72,55 +69,16 @@ async function withReflowObserver(testFn, expectedReflows = [], win = window) {
}
};
// We're going to remove the reflows one by one as we see them so that
// we can check for expected, unseen reflows, so let's clone the array.
// While we're at it, for reflows that omit the "times" property, default
// it to 1.
expectedReflows = expectedReflows.slice(0);
expectedReflows.forEach(r => {
r.times = r.times || 1;
});
// Collect all reflow stacks, we'll process them later.
let reflows = [];
let observer = {
reflow(start, end) {
// Gather information about the current code path, slicing out the current
// frame.
let path = (new Error().stack).split("\n").slice(1).map(line => {
return line.replace(/:\d+:\d+$/, "");
}).join("|");
let pathWithLineNumbers = (new Error().stack).split("\n").slice(1);
// Gather information about the current code path.
reflows.push(new Error().stack);
// Just in case, dirty the frame now that we've reflowed.
dirtyFrameFn();
// Stack trace is empty. Reflow was triggered by native code, which
// we ignore.
if (path === "") {
return;
}
// synthesizeKey from EventUtils.js causes us to reflow. That's the test
// harness and we don't care about that, so we'll filter that out.
if (path.startsWith("synthesizeKey@chrome://mochikit/content/tests/SimpleTest/EventUtils.js")) {
return;
}
let index = expectedReflows.findIndex(reflow => path.startsWith(reflow.stack.join("|")));
if (index != -1) {
Assert.ok(true, "expected uninterruptible reflow: '" +
JSON.stringify(pathWithLineNumbers, null, "\t") + "'");
if (expectedReflows[index].minTimes) {
expectedReflows[index].minTimes--;
}
if (--expectedReflows[index].times == 0) {
expectedReflows.splice(index, 1);
}
} else {
Assert.ok(false, "unexpected uninterruptible reflow \n" +
JSON.stringify(pathWithLineNumbers, null, "\t") + "\n");
}
},
reflowInterruptible(start, end) {
@ -144,20 +102,75 @@ async function withReflowObserver(testFn, expectedReflows = [], win = window) {
dirtyFrameFn();
await testFn(dirtyFrameFn);
} finally {
if (expectedReflows.length != 0) {
for (let remainder of expectedReflows) {
if (!Number.isInteger(remainder.minTimes) || remainder.minTimes > 0) {
let knownReflows = expectedReflows.map(r => {
return {stack: r.stack, path: r.stack.join("|"),
count: 0, maxCount: r.maxCount || 1,
actualStacks: new Map()};
});
let unexpectedReflows = new Map();
for (let stack of reflows) {
let path =
stack.split("\n").slice(1) // the first frame which is our test code.
.map(line => line.replace(/:\d+:\d+$/, "")) // strip line numbers.
.join("|");
// Stack trace is empty. Reflow was triggered by native code, which
// we ignore.
if (path === "") {
continue;
}
// synthesizeKey from EventUtils.js causes us to reflow. That's the test
// harness and we don't care about that, so we'll filter that out.
if (path.startsWith("synthesizeKey@chrome://mochikit/content/tests/SimpleTest/EventUtils.js")) {
continue;
}
let index = knownReflows.findIndex(reflow => path.startsWith(reflow.path));
if (index != -1) {
let reflow = knownReflows[index];
++reflow.count;
reflow.actualStacks.set(stack, (reflow.actualStacks.get(stack) || 0) + 1);
} else {
unexpectedReflows.set(stack, (unexpectedReflows.get(stack) || 0) + 1);
}
}
let formatStack = stack =>
stack.split("\n").slice(1).map(frame => " " + frame).join("\n");
for (let reflow of knownReflows) {
let firstFrame = reflow.stack[0];
if (!reflow.count) {
Assert.ok(false,
`Unused expected reflow at ${firstFrame}:\nStack:\n` +
reflow.stack.map(frame => " " + frame).join("\n") + "\n" +
"This is probably a good thing - just remove it from the whitelist.");
} else {
if (reflow.count > reflow.maxCount) {
Assert.ok(false,
`Unused expected reflow: ${JSON.stringify(remainder.stack, null, "\t")}\n` +
`This reflow was supposed to be hit ${remainder.minTimes || remainder.times} more time(s).\n` +
"This is probably a good thing - just remove it from the " +
"expected list.");
`reflow at ${firstFrame} was encountered ${reflow.count} times,\n` +
`it was expected to happen up to ${reflow.maxCount} times.`);
} else {
todo(false, `known reflow at ${firstFrame} was encountered ${reflow.count} times`);
}
for (let [stack, count] of reflow.actualStacks) {
info("Full stack" + (count > 1 ? ` (hit ${count} times)` : "") + ":\n" +
formatStack(stack));
}
}
} else {
Assert.ok(true, "All expected reflows were observed");
}
for (let [stack, count] of unexpectedReflows) {
let location = stack.split("\n")[1].replace(/:\d+:\d+$/, "");
Assert.ok(false,
`unexpected reflow at ${location} hit ${count} times\n` +
"Stack:\n" +
formatStack(stack));
}
Assert.ok(!unexpectedReflows.size,
unexpectedReflows.size + " unexpected reflows");
Services.els.removeListenerForAllEvents(win, dirtyFrameFn, true);
docShell.removeWeakReflowObserver(observer);
}

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

@ -20,6 +20,46 @@
* navigation can be done using the goBack method or through a button in the
* subview headers.
*
* The process of displaying the main view or a new subview requires multiple
* steps to be completed, hence at any given time the <panelview> element may
* be in different states:
*
* -- Open or closed
*
* All the <panelview> elements start "closed", meaning that they are not
* associated to a <panelmultiview> element and can be located anywhere in
* the document. When the openPopup or showSubView methods are called, the
* relevant view becomes "open" and the <panelview> element may be moved to
* ensure it is a descendant of the <panelmultiview> element.
*
* The "ViewShowing" event is fired at this point, when the view is not
* visible yet. The event is allowed to cancel the operation, in which case
* the view is closed immediately.
*
* Closing the view does not move the node back to its original position.
*
* -- Visible or invisible
*
* This indicates whether the view is visible in the document from a layout
* perspective, regardless of whether it is currently scrolled into view. In
* fact, all subviews are already visible before they start sliding in.
*
* Before scrolling into view, a view may become visible but be placed in a
* special off-screen area of the document where layout and measurements can
* take place asyncronously.
*
* When navigating forward, an open view may become invisible but stay open
* after sliding out of view. The last known size of these views is still
* taken into account for determining the overall panel size.
*
* When navigating backwards, an open subview will first become invisible and
* then will be closed.
*
* -- Navigating with the keyboard
*
* An open view may keep state related to keyboard navigation, even if it is
* invisible. When a view is closed, keyboard navigation state is cleared.
*
* This diagram shows how <panelview> nodes move during navigation:
*
* In this <panelmultiview> In other panels Action
@ -27,16 +67,18 @@
* (A) B C D E Open panel
*
*
* A (C) B D E Show subview C
* {A}(C) B D E Show subview C
*
*
* A C (D) B E Show subview D
* {A}{C}(D) B E Show subview D
*
*
* A (C) D B E Go back
*
*
* Currently visible view
*
* {A}(C) D B E Go back
*
*
* 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
@ -287,7 +329,7 @@ this.PanelMultiView = class extends this.AssociatedToNode {
* dispatched.
*/
get current() {
return this.node && (this._viewShowing || this._currentSubView);
return this.node && this._currentSubView;
}
get _currentSubView() {
// Peek the top of the stack, but fall back to the main view if the list of
@ -295,6 +337,9 @@ this.PanelMultiView = class extends this.AssociatedToNode {
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);
@ -304,12 +349,8 @@ this.PanelMultiView = class extends this.AssociatedToNode {
connect() {
this.connected = true;
this.knownViews = new Set(Array.from(
this.node.getElementsByTagName("panelview"),
node => PanelView.forNode(node)));
this.openViews = [];
this.__transitioning = false;
this.showingSubView = false;
const {document, window} = this;
@ -336,7 +377,7 @@ this.PanelMultiView = class extends this.AssociatedToNode {
// Proxy these public properties and methods, as used elsewhere by various
// parts of the browser, to this instance.
["goBack", "showMainView", "showSubView"].forEach(method => {
["goBack", "showSubView"].forEach(method => {
Object.defineProperty(this.node, method, {
enumerable: true,
value: (...args) => this[method](...args)
@ -356,8 +397,6 @@ this.PanelMultiView = class extends this.AssociatedToNode {
return;
this._cleanupTransitionPhase();
if (this._ephemeral)
this.hideAllViewsExcept(null);
let mainView = this._mainView;
if (mainView) {
if (this._panelViewCache)
@ -467,7 +506,7 @@ this.PanelMultiView = class extends this.AssociatedToNode {
}
}
// Allow any of the ViewShowing handlers to prevent showing the main view.
if (!(await this.showMainView())) {
if (!(await this._showMainView())) {
cancelCallback();
}
} catch (ex) {
@ -505,7 +544,7 @@ this.PanelMultiView = class extends this.AssociatedToNode {
* state of the anchor, and the panel is already invisible.
*/
hidePopup() {
if (!this.node) {
if (!this.node || !this.connected) {
return;
}
@ -518,6 +557,11 @@ this.PanelMultiView = class extends this.AssociatedToNode {
} else {
this._openPopupCancelCallback();
}
// We close all the views synchronously, so that they are ready to be opened
// in other PanelMultiView instances. The "popuphidden" handler may also
// call this function, but the second time openViews will be empty.
this.closeAllViews();
}
/**
@ -540,126 +584,182 @@ this.PanelMultiView = class extends this.AssociatedToNode {
}
}
/**
* Slides in the specified view as a subview.
*
* @param viewIdOrNode
* DOM element or string ID of the <panelview> to display.
* @param anchor
* DOM element that triggered the subview, which will be highlighted
* and whose "label" attribute will be used for the title of the
* subview when a "title" attribute is not specified.
*/
showSubView(viewIdOrNode, anchor) {
this._showSubView(viewIdOrNode, anchor).catch(Cu.reportError);
}
async _showSubView(viewIdOrNode, anchor) {
let viewNode = typeof viewIdOrNode == "string" ?
this.document.getElementById(viewIdOrNode) : viewIdOrNode;
if (!viewNode) {
Cu.reportError(new Error(`Subview ${viewIdOrNode} doesn't exist.`));
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))) {
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);
this._viewShown(nextPanelView);
}
/**
* Navigates backwards by sliding out the most recent subview.
*/
goBack() {
this._goBack().catch(Cu.reportError);
}
async _goBack() {
if (this.openViews.length < 2) {
// This may be called by keyboard navigation or external code when only
// the main view is open.
return;
}
let previous = this.openViews.pop().node;
let current = this._currentSubView;
this.showSubView(current, null, previous);
}
let prevPanelView = this.openViews[this.openViews.length - 1];
let nextPanelView = this.openViews[this.openViews.length - 2];
async showMainView() {
if (!this.node || !this._mainViewId)
return false;
prevPanelView.captureKnownSize();
await this._transitionViews(prevPanelView.node, nextPanelView.node, true);
return this.showSubView(this._mainView);
this._closeLatestView();
this._viewShown(nextPanelView);
}
/**
* Ensures that all the panelviews, that are currently part of this instance,
* are hidden, except one specifically.
*
* @param {panelview} [nextPanelView]
* The PanelView object to ensure is visible. Optional.
* Prepares the main view before showing the panel.
*/
hideAllViewsExcept(nextPanelView = null) {
for (let panelView of this.knownViews) {
// When the panelview was already reparented, don't interfere any more.
if (panelView == nextPanelView || !this.node || panelView.node.panelMultiView != this.node)
continue;
panelView.current = false;
async _showMainView() {
if (!this.node || !this._mainViewId) {
return false;
}
this._viewShowing = null;
let nextPanelView = PanelView.forNode(this._mainView);
if (!this.node || !nextPanelView)
return;
// If the view is already open in another panel, close the panel first.
let oldPanelMultiViewNode = nextPanelView.node.panelMultiView;
if (oldPanelMultiViewNode) {
PanelMultiView.forNode(oldPanelMultiViewNode).hidePopup();
}
if (!this.openViews.includes(nextPanelView))
this.openViews.push(nextPanelView);
if (!(await this._openView(nextPanelView))) {
return false;
}
nextPanelView.current = true;
this.showingSubView = nextPanelView.node.id != this._mainViewId;
// 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 = true;
nextPanelView.headerText = "";
nextPanelView.minMaxWidth = 0;
await this._cleanupTransitionPhase();
nextPanelView.visible = true;
nextPanelView.descriptionHeightWorkaround();
this._viewShown(nextPanelView);
return true;
}
async showSubView(aViewId, aAnchor, aPreviousView) {
try {
// Support passing in the node directly.
let viewNode = typeof aViewId == "string" ? this.node.querySelector("#" + aViewId) : aViewId;
if (!viewNode) {
viewNode = this.document.getElementById(aViewId);
if (viewNode) {
this._viewStack.appendChild(viewNode);
} else {
throw new Error(`Subview ${aViewId} doesn't exist!`);
}
} else if (viewNode.parentNode == this._panelViewCache) {
this._viewStack.appendChild(viewNode);
}
/**
* Opens the specified PanelView and dispatches the ViewShowing event, which
* can be used to populate the subview or cancel the operation.
*
* @resolves With true if the view was opened, false otherwise.
*/
async _openView(panelView) {
if (panelView.node.parentNode != this._viewStack) {
this._viewStack.appendChild(panelView.node);
}
let nextPanelView = PanelView.forNode(viewNode);
this.knownViews.add(nextPanelView);
panelView.node.panelMultiView = this.node;
this.openViews.push(panelView);
viewNode.panelMultiView = this.node;
let canceled = await panelView.dispatchAsyncEvent("ViewShowing");
let previousViewNode = aPreviousView || this._currentSubView;
// If the panelview to show is the same as the previous one, the 'ViewShowing'
// event has already been dispatched. Don't do it twice.
let showingSameView = viewNode == previousViewNode;
let prevPanelView = PanelView.forNode(previousViewNode);
prevPanelView.captureKnownSize();
this._viewShowing = viewNode;
let reverse = !!aPreviousView;
if (!reverse) {
// We are opening a new view, either because we are navigating forward
// or because we are showing the main view. Some properties of the view
// may vary between panels, so we make sure to update them every time.
// Firstly, make sure that the header matches how the view was opened.
nextPanelView.headerText = viewNode.getAttribute("title") ||
(aAnchor && aAnchor.getAttribute("label"));
// The main view of a panel can be a subview in another one.
let isMainView = viewNode.id == this._mainViewId;
nextPanelView.mainview = isMainView;
// The constrained width of subviews may also vary between panels.
nextPanelView.minMaxWidth = isMainView ? 0 : prevPanelView.knownWidth;
}
if (aAnchor) {
viewNode.classList.add("PanelUI-subView");
}
if (!showingSameView || !viewNode.hasAttribute("current")) {
// Emit the ViewShowing event so that the widget definition has a chance
// to lazily populate the subview with things or perhaps even cancel this
// whole operation.
if (await nextPanelView.dispatchAsyncEvent("ViewShowing")) {
this._viewShowing = null;
return false;
}
}
// Now we have to transition the panel. If we've got an older transition
// still running, make sure to clean it up.
await this._cleanupTransitionPhase();
if (!showingSameView && this._panel.state == "open") {
await this._transitionViews(previousViewNode, viewNode, reverse, aAnchor);
nextPanelView.focusSelectedElement();
} else {
this.hideAllViewsExcept(nextPanelView);
}
return true;
} catch (ex) {
Cu.reportError(ex);
// The panel can be hidden while we are processing the ViewShowing event.
// This results in all the views being closed synchronously, and at this
// point the ViewHiding event has already been dispatched for all of them.
if (!this.openViews.length) {
return false;
}
// Check if the event requested cancellation but the panel is still open.
if (canceled) {
// Handlers for ViewShowing can't know if a different handler requested
// cancellation, so this will dispatch a ViewHiding event to give a chance
// to clean up.
this._closeLatestView();
return false;
}
return true;
}
/**
* Raises the ViewShown event if the specified view is still open.
*/
_viewShown(panelView) {
if (panelView.node.panelMultiView == this.node) {
panelView.dispatchCustomEvent("ViewShown");
}
}
/**
* Closes the most recent PanelView and raises the ViewHiding event.
*
* @note The ViewHiding event is not cancelable and should probably be renamed
* to ViewHidden or ViewClosed instead, see bug 1438507.
*/
_closeLatestView() {
let panelView = this.openViews.pop();
panelView.clearNavigation();
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.
panelView.visible = false;
}
/**
* Closes all the views that are currently open.
*/
closeAllViews() {
// Raise ViewHiding events for open views in reverse order.
while (this.openViews.length) {
this._closeLatestView();
}
}
/**
@ -679,6 +779,9 @@ this.PanelMultiView = class extends this.AssociatedToNode {
* 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") {
@ -820,7 +923,20 @@ this.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;
nextPanelView.visible = true;
nextPanelView.descriptionHeightWorkaround();
}
// This will complete the operation by removing any transition properties.
await this._cleanupTransitionPhase(details);
// Focus the correct element, unless the view was closed in the meantime.
if (nextPanelView.node.panelMultiView == this.node) {
nextPanelView.focusSelectedElement();
}
}
/**
@ -840,16 +956,10 @@ this.PanelMultiView = class extends this.AssociatedToNode {
if (details == this._transitionDetails)
this._transitionDetails = null;
let nextPanelView = PanelView.forNode(viewNode);
let prevPanelView = PanelView.forNode(previousViewNode);
// Do the things we _always_ need to do whenever the transition ends or is
// interrupted.
this.hideAllViewsExcept(nextPanelView);
previousViewNode.removeAttribute("in-transition");
viewNode.removeAttribute("in-transition");
if (reverse)
prevPanelView.clearNavigation();
if (anchor)
anchor.removeAttribute("open");
@ -982,16 +1092,12 @@ this.PanelMultiView = class extends this.AssociatedToNode {
case "popuphidden": {
// WebExtensions consumers can hide the popup from viewshowing, or
// mid-transition, which disrupts our state:
this._viewShowing = null;
this._transitioning = false;
this.node.removeAttribute("panelopen");
// Raise the ViewHiding event for the current view.
this._cleanupTransitionPhase();
this.hideAllViewsExcept(null);
this.window.removeEventListener("keydown", this);
this._panel.removeEventListener("mousemove", this);
this.openViews.forEach(panelView => panelView.clearNavigation());
this.openViews = [];
this.closeAllViews();
// Clear the main view size caches. The dimensions could be different
// when the popup is opened again, e.g. through touch mode sizing.
@ -1025,15 +1131,10 @@ this.PanelView = class extends this.AssociatedToNode {
}
}
set current(value) {
set visible(value) {
if (value) {
if (!this.node.hasAttribute("current")) {
this.node.setAttribute("current", true);
this.descriptionHeightWorkaround();
this.dispatchCustomEvent("ViewShown");
}
} else if (this.node.hasAttribute("current")) {
this.dispatchCustomEvent("ViewHiding");
this.node.setAttribute("current", true);
} else {
this.node.removeAttribute("current");
}
}

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

@ -336,15 +336,6 @@ const PanelUI = {
this._isReady = true;
},
/**
* Switch the panel to the main view if it's not already
* in that view.
*/
showMainView() {
this._ensureEventListenersAdded();
this.multiView.showMainView();
},
/**
* Switch the panel to the help view if it's not already
* in that view.
@ -415,19 +406,11 @@ const PanelUI = {
tempPanel.classList.toggle("cui-widget-panelWithFooter",
viewNode.querySelector(".panel-subview-footer"));
// If the panelview is already selected in another PanelMultiView instance
// as a subview, make sure to properly hide it there.
let oldMultiView = viewNode.panelMultiView;
if (oldMultiView && oldMultiView.current == viewNode) {
await oldMultiView.showMainView();
}
let multiView = document.createElement("panelmultiview");
multiView.setAttribute("id", "customizationui-widget-multiview");
multiView.setAttribute("viewCacheId", "appMenu-viewCache");
multiView.setAttribute("mainViewId", viewNode.id);
multiView.setAttribute("ephemeral", true);
document.getElementById("appMenu-viewCache").appendChild(viewNode);
tempPanel.appendChild(multiView);
viewNode.classList.add("cui-widget-panelview");

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

@ -1095,7 +1095,7 @@ var DownloadsViewController = {
}
// The currently supported commands depend on whether the blocked subview is
// showing. If it is, then take the following path.
if (DownloadsBlockedSubview.view.showingSubView) {
if (DownloadsView.subViewOpen) {
let blockedSubviewCmds = [
"downloadsCmd_unblockAndOpen",
"cmd_delete",
@ -1410,13 +1410,6 @@ XPCOMUtils.defineConstant(this, "DownloadsFooter", DownloadsFooter);
* Manages the blocked subview that slides in when you click a blocked download.
*/
var DownloadsBlockedSubview = {
get subview() {
let subview = document.getElementById("downloadsPanel-blockedSubview");
delete this.subview;
return this.subview = subview;
},
/**
* Elements in the subview.
*/
@ -1436,15 +1429,6 @@ var DownloadsBlockedSubview = {
return this.elements = elements;
},
/**
* The multiview that contains both the main view and the subview.
*/
get view() {
let view = document.getElementById("downloadsPanel-multiView");
delete this.view;
return this.view = view;
},
/**
* The blocked-download richlistitem element that was clicked to show the
* subview. If the subview is not showing, this is undefined.
@ -1475,31 +1459,24 @@ var DownloadsBlockedSubview = {
let verdict = element.getAttribute("verdict");
this.subview.setAttribute("verdict", verdict);
this.subview.addEventListener("ViewHiding", this);
this.view.showSubView(this.subview.id);
this.mainView.addEventListener("ViewShown", this);
DownloadsPanel.panel.addEventListener("popuphidden", this);
this.panelMultiView.showSubView(this.subview);
// Without this, the mainView is more narrow than the panel once all
// downloads are removed from the panel.
document.getElementById("downloadsPanel-mainView").style.minWidth =
window.getComputedStyle(this.subview).width;
this.mainView.style.minWidth = window.getComputedStyle(this.subview).width;
},
handleEvent(event) {
switch (event.type) {
case "ViewHiding":
this.subview.removeEventListener(event.type, this);
DownloadsView.subViewOpen = false;
// If we're going back to the main panel, use showPanel to
// focus the proper element.
if (this.view.current !== this.subview) {
DownloadsPanel.showPanel();
}
break;
default:
DownloadsCommon.log("Unhandled DownloadsBlockedSubview event: " +
event.type);
break;
// This is called when the main view is shown or the panel is hidden.
DownloadsView.subViewOpen = false;
this.mainView.removeEventListener("ViewShown", this);
DownloadsPanel.panel.removeEventListener("popuphidden", this);
// Focus the proper element if we're going back to the main panel.
if (event.type == "ViewShown") {
DownloadsPanel.showPanel();
}
},
@ -1512,5 +1489,12 @@ var DownloadsBlockedSubview = {
},
};
XPCOMUtils.defineLazyGetter(DownloadsBlockedSubview, "panelMultiView",
() => document.getElementById("downloadsPanel-multiView"));
XPCOMUtils.defineLazyGetter(DownloadsBlockedSubview, "mainView",
() => document.getElementById("downloadsPanel-mainView"));
XPCOMUtils.defineLazyGetter(DownloadsBlockedSubview, "subview",
() => document.getElementById("downloadsPanel-blockedSubview"));
XPCOMUtils.defineConstant(this, "DownloadsBlockedSubview",
DownloadsBlockedSubview);

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

@ -20,22 +20,24 @@ add_task(async function mainTest() {
let item = DownloadsView.richListBox.firstChild;
// Open the panel and click the item to show the subview.
let viewPromise = promiseViewShown(DownloadsBlockedSubview.subview);
EventUtils.sendMouseEvent({ type: "click" }, item);
await promiseSubviewShown(true);
await viewPromise;
// Items are listed in newest-to-oldest order, so e.g. the first item's
// verdict is the last element in the verdicts array.
Assert.ok(DownloadsBlockedSubview.subview.getAttribute("verdict"),
verdicts[verdicts.count - i - 1]);
// Click the sliver of the main view that's still showing on the left to go
// back to it.
EventUtils.synthesizeMouse(DownloadsPanel.panel, 10, 10, {}, window);
await promiseSubviewShown(false);
// Go back to the main view.
viewPromise = promiseViewShown(DownloadsBlockedSubview.mainView);
DownloadsBlockedSubview.panelMultiView.goBack();
await viewPromise;
// Show the subview again.
viewPromise = promiseViewShown(DownloadsBlockedSubview.subview);
EventUtils.sendMouseEvent({ type: "click" }, item);
await promiseSubviewShown(true);
await viewPromise;
// Click the Open button. The download should be unblocked and then opened,
// i.e., unblockAndOpenDownload() should be called on the item. The panel
@ -53,19 +55,23 @@ add_task(async function mainTest() {
// Reopen the panel and show the subview again.
await openPanel();
viewPromise = promiseViewShown(DownloadsBlockedSubview.subview);
EventUtils.sendMouseEvent({ type: "click" }, item);
await promiseSubviewShown(true);
await viewPromise;
// Click the Remove button. The panel should close and the item should be
// removed from it.
hidePromise = promisePanelHidden();
EventUtils.synthesizeMouse(DownloadsBlockedSubview.elements.deleteButton,
10, 10, {}, window);
await promisePanelHidden();
await openPanel();
await hidePromise;
await openPanel();
Assert.ok(!item.parentNode);
hidePromise = promisePanelHidden();
DownloadsPanel.hidePanel();
await promisePanelHidden();
await hidePromise;
}
await task_resetState();
@ -127,15 +133,7 @@ async function openPanel() {
}
function promisePanelHidden() {
return new Promise(resolve => {
if (!DownloadsPanel.panel || DownloadsPanel.panel.state == "closed") {
resolve();
return;
}
DownloadsPanel.panel.addEventListener("popuphidden", function() {
setTimeout(resolve, 0);
}, {once: true});
});
return BrowserTestUtils.waitForEvent(DownloadsPanel.panel, "popuphidden");
}
function makeDownload(verdict) {
@ -152,18 +150,8 @@ function makeDownload(verdict) {
};
}
function promiseSubviewShown(shown) {
// More terribleness, but I'm tired of fighting intermittent timeouts on try.
// Just poll for the subview and wait a second before resolving the promise.
return new Promise(resolve => {
let interval = setInterval(() => {
if (shown == DownloadsBlockedSubview.view.showingSubView &&
!DownloadsBlockedSubview.view._transitioning) {
clearInterval(interval);
setTimeout(resolve, 1000);
}
}, 0);
});
function promiseViewShown(view) {
return BrowserTestUtils.waitForEvent(view, "ViewShown");
}
function promiseUnblockAndOpenDownloadCalled(item) {

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

@ -2117,14 +2117,6 @@ this.PlacesPanelview = class extends PlacesViewBase {
return this._events = ["click", "command", "dragend", "dragstart", "ViewHiding", "ViewShown"];
}
get panel() {
return this.panelMultiView.parentNode;
}
get panelMultiView() {
return this._viewElt.panelMultiView;
}
handleEvent(event) {
switch (event.type) {
case "click":
@ -2196,6 +2188,7 @@ this.PlacesPanelview = class extends PlacesViewBase {
uninit(event) {
this._removeEventListeners(this.panelMultiView, this.events);
this._removeEventListeners(window, ["unload"]);
delete this.panelMultiView;
super.uninit(event);
}
@ -2255,10 +2248,6 @@ this.PlacesPanelview = class extends PlacesViewBase {
}
}
_isPopupOpen() {
return this.panel.state == "open" && this.panelMultiView.current == this._viewElt;
}
_onPopupHidden(event) {
let panelview = event.originalTarget;
let placesNode = panelview._placesNode;
@ -2280,6 +2269,7 @@ this.PlacesPanelview = class extends PlacesViewBase {
// we ever get here.
if (event.originalTarget == this._rootElt) {
// Start listening for events from all panels inside the panelmultiview.
this.panelMultiView = this._viewElt.panelMultiView;
this._addEventListeners(this.panelMultiView, this.events);
}
super._onPopupShowing(event);

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

@ -7,4 +7,5 @@ support-files =
[browser_as_render.js]
[browser_getScreenshots.js]
[browser_highlights_section.js]
[browser_topsites_contextMenu_options.js]
[browser_topsites_section.js]

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

@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Test verifies the menu options for a default top site.
*/
test_newtab({
before: setDefaultTopSites,
test: async function defaultTopSites_menuOptions() {
await ContentTaskUtils.waitForCondition(() => content.document.querySelector(".top-site-icon"),
"Topsite tippytop icon not found");
let contextMenuItems = content.openContextMenuAndGetOptions(".top-sites-list li:first-child").map(v => v.textContent);
Assert.equal(contextMenuItems.length, 5, "Number of options is correct");
const expectedItemsText = ["Pin", "Edit", "Open in a New Window", "Open in a New Private Window", "Dismiss"];
for (let i = 0; i < contextMenuItems.length; i++) {
Assert.equal(contextMenuItems[i], expectedItemsText[i], "Name option is correct");
}
}
});

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

@ -17,13 +17,7 @@ test_newtab(
// Test pin/unpin context menu options.
test_newtab({
async before({pushPrefs}) {
// The pref for TopSites is empty by default.
await pushPrefs(["browser.newtabpage.activity-stream.default.sites", "https://www.youtube.com/,https://www.facebook.com/,https://www.amazon.com/,https://www.reddit.com/,https://www.wikipedia.org/,https://twitter.com/"]);
// Toggle the feed off and on as a workaround to read the new prefs.
await pushPrefs(["browser.newtabpage.activity-stream.feeds.topsites", false]);
await pushPrefs(["browser.newtabpage.activity-stream.feeds.topsites", true]);
},
before: setDefaultTopSites,
// it should pin the website when we click the first option of the topsite context menu.
test: async function topsites_pin_unpin() {
await ContentTaskUtils.waitForCondition(() => content.document.querySelector(".top-site-icon"),

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

@ -10,6 +10,15 @@ function pushPrefs(...prefs) {
return SpecialPowers.pushPrefEnv({set: prefs});
}
async function setDefaultTopSites() {
// The pref for TopSites is empty by default.
await pushPrefs(["browser.newtabpage.activity-stream.default.sites",
"https://www.youtube.com/,https://www.facebook.com/,https://www.amazon.com/,https://www.reddit.com/,https://www.wikipedia.org/,https://twitter.com/"]);
// Toggle the feed off and on as a workaround to read the new prefs.
await pushPrefs(["browser.newtabpage.activity-stream.feeds.topsites", false]);
await pushPrefs(["browser.newtabpage.activity-stream.feeds.topsites", true]);
}
async function clearHistoryAndBookmarks() { // eslint-disable-line no-unused-vars
await PlacesUtils.bookmarks.eraseEverything();
await PlacesUtils.history.clear();
@ -57,6 +66,31 @@ async function addHighlightsBookmarks(count) { // eslint-disable-line no-unused-
refreshHighlightsFeed();
}
/**
* Helper to add various helpers to the content process by injecting variables
* and functions to the `content` global.
*/
function addContentHelpers() {
const {document} = content;
Object.assign(content, {
/**
* Click the context menu button for an item and get its options list.
*
* @param selector {String} Selector to get an item (e.g., top site, card)
* @return {Array} The nodes for the options.
*/
openContextMenuAndGetOptions(selector) {
const item = document.querySelector(selector);
const contextButton = item.querySelector(".context-menu-button");
contextButton.click();
const contextMenu = item.querySelector(".context-menu");
const contextMenuList = contextMenu.querySelector(".context-menu-list");
return [...contextMenuList.getElementsByClassName("context-menu-item")];
}
});
}
/**
* Helper to run Activity Stream about:newtab test tasks in content.
*
@ -104,6 +138,9 @@ function test_newtab(testInfo) { // eslint-disable-line no-unused-vars
let browser = tab.linkedBrowser;
await waitForPreloaded(browser);
// Add shared helpers to the content process
ContentTask.spawn(browser, {}, addContentHelpers);
// Wait for React to render something
await BrowserTestUtils.waitForCondition(() => ContentTask.spawn(browser, {},
() => content.document.getElementById("root").children.length),

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

@ -7,43 +7,31 @@
this.EXPORTED_SYMBOLS = ["AppMenu"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
this.AppMenu = {
init(libDir) {},
configurations: {
appMenuClosed: {
appMenuMainView: {
selectors: ["#appMenu-popup"],
async applyConfig() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
browserWindow.PanelUI.hide();
},
},
appMenuMainView: {
selectors: ["#appMenu-popup"],
applyConfig() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let promise = browserWindow.PanelUI.show();
browserWindow.PanelUI.showMainView();
return promise;
await reopenAppMenu(browserWindow);
},
},
appMenuHistorySubview: {
selectors: ["#appMenu-popup"],
async applyConfig() {
// History has a footer
if (isCustomizing()) {
return "Can't show subviews while customizing";
}
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
await browserWindow.PanelUI.show();
browserWindow.PanelUI.showMainView();
browserWindow.document.getElementById("history-panelmenu").click();
await reopenAppMenu(browserWindow);
return undefined;
let view = browserWindow.document.getElementById("appMenu-libraryView");
let promiseViewShown = BrowserTestUtils.waitForEvent(view, "ViewShown");
browserWindow.document.getElementById("appMenu-library-button").click();
await promiseViewShown;
},
verifyConfig: verifyConfigHelper,
@ -52,15 +40,13 @@ this.AppMenu = {
appMenuHelpSubview: {
selectors: ["#appMenu-popup"],
async applyConfig() {
if (isCustomizing()) {
return "Can't show subviews while customizing";
}
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
await browserWindow.PanelUI.show();
browserWindow.PanelUI.showMainView();
browserWindow.document.getElementById("PanelUI-help").click();
await reopenAppMenu(browserWindow);
return undefined;
let view = browserWindow.document.getElementById("PanelUI-helpView");
let promiseViewShown = BrowserTestUtils.waitForEvent(view, "ViewShown");
browserWindow.document.getElementById("appMenu-help-button").click();
await promiseViewShown;
},
verifyConfig: verifyConfigHelper,
@ -69,6 +55,14 @@ this.AppMenu = {
},
};
async function reopenAppMenu(browserWindow) {
browserWindow.PanelUI.hide();
let view = browserWindow.document.getElementById("appMenu-mainView");
let promiseViewShown = BrowserTestUtils.waitForEvent(view, "ViewShown");
await browserWindow.PanelUI.show();
await promiseViewShown;
}
function verifyConfigHelper() {
if (isCustomizing()) {
return "navigator:browser has the customizing attribute";

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

@ -200,8 +200,8 @@ class FirefoxConnector {
"dom-interactive" : "dom-complete",
time: marker.unixTime / 1000
};
window.emit(EVENTS.TIMELINE_EVENT, event);
this.actions.addTimingMarker(event);
window.emit(EVENTS.TIMELINE_EVENT, event);
}
/**
@ -212,8 +212,8 @@ class FirefoxConnector {
* @param {object} marker
*/
onDocEvent(type, event) {
window.emit(EVENTS.TIMELINE_EVENT, event);
this.actions.addTimingMarker(event);
window.emit(EVENTS.TIMELINE_EVENT, event);
}
/**

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

@ -66,7 +66,11 @@ function onProperties(aState, aResponse)
is(keys.length, 0, "number of properties");
keys = Object.keys(aResponse.safeGetterValues);
is(keys.length, 0, "number of safe getters");
// There is one "safe getter" as far as the code in _findSafeGetterValues is
// concerned, because it treats any Promise-returning attribute as a "safe
// getter". See bug 1438015.
is(keys.length, 1, "number of safe getters");
is(keys[0], "documentReadyForIdle", "Unexpected safe getter");
closeDebugger(aState, function() {
SimpleTest.finish();

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

@ -548,10 +548,7 @@ Navigator::Storage()
MOZ_ASSERT(mWindow);
if(!mStorageManager) {
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
MOZ_ASSERT(global);
mStorageManager = new StorageManager(global);
mStorageManager = new StorageManager(mWindow->AsGlobal());
}
return mStorageManager;
@ -1317,8 +1314,7 @@ Navigator::GetBattery(ErrorResult& aRv)
return nullptr;
}
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> batteryPromise = Promise::Create(go, aRv);
RefPtr<Promise> batteryPromise = Promise::Create(mWindow->AsGlobal(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -1375,8 +1371,7 @@ Navigator::GetVRDisplays(ErrorResult& aRv)
nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow);
win->NotifyVREventListenerAdded();
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> p = Promise::Create(go, aRv);
RefPtr<Promise> p = Promise::Create(mWindow->AsGlobal(), aRv);
if (aRv.Failed()) {
return nullptr;
}
@ -1850,9 +1845,8 @@ Navigator::RequestMediaKeySystemAccess(const nsAString& aKeySystem,
ArrayLength(params));
}
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<DetailedPromise> promise =
DetailedPromise::Create(go, aRv,
DetailedPromise::Create(mWindow->AsGlobal(), aRv,
NS_LITERAL_CSTRING("navigator.requestMediaKeySystemAccess"),
Telemetry::VIDEO_EME_REQUEST_SUCCESS_LATENCY_MS,
Telemetry::VIDEO_EME_REQUEST_FAILURE_LATENCY_MS);

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

@ -1924,6 +1924,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSecurityInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDisplayDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFontFaceSet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReadyForIdle)
// Traverse all nsDocument nsCOMPtrs.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParser)
@ -2065,6 +2066,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildrenCollection)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOrientationPendingPromise)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFontFaceSet)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReadyForIdle);
tmp->mParentDocument = nullptr;
@ -2735,6 +2737,7 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
}
mMayStartLayout = false;
MOZ_ASSERT(!mReadyForIdle, "We should never hit DOMContentLoaded before this point");
if (aReset) {
Reset(aChannel, aLoadGroup);
@ -5266,6 +5269,10 @@ nsDocument::DispatchContentLoadedEvents()
NS_LITERAL_STRING("DOMContentLoaded"),
true, false);
if (MayStartLayout()) {
MaybeResolveReadyForIdle();
}
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
nsIDocShell* docShell = this->GetDocShell();
@ -6592,6 +6599,19 @@ nsDocument::FlushSkinBindings()
BindingManager()->FlushSkinBindings();
}
void
nsIDocument::SetMayStartLayout(bool aMayStartLayout)
{
mMayStartLayout = aMayStartLayout;
if (MayStartLayout()) {
ReadyState state = GetReadyStateEnum();
if (state >= READYSTATE_INTERACTIVE) {
// DOMContentLoaded has fired already.
MaybeResolveReadyForIdle();
}
}
}
nsresult
nsDocument::InitializeFrameLoader(nsFrameLoader* aLoader)
{
@ -10317,6 +10337,35 @@ nsIDocument::GetMozDocumentURIIfNotForErrorPages()
return uri.forget();
}
Promise*
nsIDocument::GetDocumentReadyForIdle(ErrorResult& aRv)
{
if (!mReadyForIdle) {
nsIGlobalObject* global = GetScopeObject();
if (!global) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
mReadyForIdle = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
}
return mReadyForIdle;
}
void
nsIDocument::MaybeResolveReadyForIdle()
{
IgnoredErrorResult rv;
Promise* readyPromise = GetDocumentReadyForIdle(rv);
if (readyPromise) {
readyPromise->MaybeResolve(this);
}
}
nsIHTMLCollection*
nsIDocument::Children()
{

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

@ -7937,6 +7937,18 @@ nsPIDOMWindowInner::GetDocGroup() const
return nullptr;
}
nsIGlobalObject*
nsPIDOMWindowInner::AsGlobal()
{
return nsGlobalWindowInner::Cast(this);
}
const nsIGlobalObject*
nsPIDOMWindowInner::AsGlobal() const
{
return nsGlobalWindowInner::Cast(this);
}
// XXX: Can we define this in a header instead of here?
namespace mozilla {
namespace dom {

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

@ -2188,10 +2188,7 @@ public:
return mMayStartLayout;
}
virtual void SetMayStartLayout(bool aMayStartLayout)
{
mMayStartLayout = aMayStartLayout;
}
virtual void SetMayStartLayout(bool aMayStartLayout);
already_AddRefed<nsIDocumentEncoder> GetCachedEncoder();
@ -3013,6 +3010,8 @@ public:
already_AddRefed<nsIURI> GetMozDocumentURIIfNotForErrorPages();
mozilla::dom::Promise* GetDocumentReadyForIdle(mozilla::ErrorResult& aRv);
// ParentNode
nsIHTMLCollection* Children();
uint32_t ChildElementCount();
@ -3296,6 +3295,8 @@ protected:
nsAtom* aAtom, void* aData);
static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
void MaybeResolveReadyForIdle();
nsCString mReferrer;
nsString mLastModified;
@ -3377,6 +3378,8 @@ protected:
mozilla::EventStates mDocumentState;
RefPtr<mozilla::dom::Promise> mReadyForIdle;
// True if BIDI is enabled.
bool mBidiEnabled : 1;
// True if a MathML element has ever been owned by this document.

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

@ -155,6 +155,9 @@ public:
return this;
}
nsIGlobalObject* AsGlobal();
const nsIGlobalObject* AsGlobal() const;
nsPIDOMWindowOuter* GetOuterWindow() const {
return mOuterWindow;
}

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

@ -101,8 +101,7 @@ DOMEventTargetHelper::~DOMEventTargetHelper()
void
DOMEventTargetHelper::BindToOwner(nsPIDOMWindowInner* aOwner)
{
nsCOMPtr<nsIGlobalObject> glob = do_QueryInterface(aOwner);
BindToOwner(glob);
BindToOwner(aOwner ? aOwner->AsGlobal() : nullptr);
}
void

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

@ -113,9 +113,8 @@ GamepadServiceTest::AddGamepad(const nsAString& aID,
aNumButtons, aNumAxes, aNumHaptics);
GamepadChangeEventBody body(a);
GamepadChangeEvent e(0, GamepadServiceType::Standard, body);
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> p = Promise::Create(go, aRv);
RefPtr<Promise> p = Promise::Create(mWindow->AsGlobal(), aRv);
if (aRv.Failed()) {
return nullptr;
}

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

@ -920,9 +920,13 @@ HTMLCanvasElement::TransferControlToOffscreen(ErrorResult& aRv)
renderer->SetWidth(sz.width);
renderer->SetHeight(sz.height);
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(OwnerDoc()->GetInnerWindow());
mOffscreenCanvas = new OffscreenCanvas(global,
nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow();
if (!win) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
mOffscreenCanvas = new OffscreenCanvas(win->AsGlobal(),
sz.width,
sz.height,
GetCompositorBackendType(),
@ -1129,11 +1133,10 @@ HTMLCanvasElement::InvalidateCanvasContent(const gfx::Rect* damageRect)
* invalidating a canvas will feed into heuristics and cause JIT code to be
* kept around longer, for smoother animations.
*/
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(OwnerDoc()->GetInnerWindow());
nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow();
if (global) {
if (JSObject *obj = global->GetGlobalJSObject()) {
if (win) {
if (JSObject *obj = win->AsGlobal()->GetGlobalJSObject()) {
js::NotifyAnimationActivity(obj);
}
}

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

@ -2704,11 +2704,10 @@ HTMLMediaElement::SeekToNextFrame(ErrorResult& aRv)
/* This will cause JIT code to be kept around longer, to help performance
* when using SeekToNextFrame to iterate through every frame of a video.
*/
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(OwnerDoc()->GetInnerWindow());
nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow();
if (global) {
if (JSObject *obj = global->GetGlobalJSObject()) {
if (win) {
if (JSObject *obj = win->AsGlobal()->GetGlobalJSObject()) {
js::NotifyAnimationActivity(obj);
}
}
@ -7110,13 +7109,12 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
return nullptr;
}
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(OwnerDoc()->GetInnerWindow());
if (!global) {
nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow();
if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
RefPtr<DetailedPromise> promise = DetailedPromise::Create(global, aRv,
RefPtr<DetailedPromise> promise = DetailedPromise::Create(win->AsGlobal(), aRv,
NS_LITERAL_CSTRING("HTMLMediaElement.setMediaKeys"));
if (aRv.Failed()) {
return nullptr;
@ -7607,14 +7605,14 @@ HTMLMediaElement::NotifyAboutPlaying()
already_AddRefed<Promise>
HTMLMediaElement::CreateDOMPromise(ErrorResult& aRv) const
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(OwnerDoc()->GetInnerWindow());
nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow();
if (!global) {
if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
return Promise::Create(global, aRv);
return Promise::Create(win->AsGlobal(), aRv);
}
void

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

@ -183,15 +183,13 @@ MediaDevices::GetUserMedia(const MediaStreamConstraints& aConstraints,
CallerType aCallerType,
ErrorResult &aRv)
{
nsPIDOMWindowInner* window = GetOwner();
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
RefPtr<Promise> p = Promise::Create(go, aRv);
RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
RefPtr<GumResolver> resolver = new GumResolver(p);
RefPtr<GumRejecter> rejecter = new GumRejecter(p);
aRv = MediaManager::Get()->GetUserMedia(window, aConstraints,
aRv = MediaManager::Get()->GetUserMedia(GetOwner(), aConstraints,
resolver, rejecter,
aCallerType);
return p.forget();
@ -200,15 +198,13 @@ MediaDevices::GetUserMedia(const MediaStreamConstraints& aConstraints,
already_AddRefed<Promise>
MediaDevices::EnumerateDevices(CallerType aCallerType, ErrorResult &aRv)
{
nsPIDOMWindowInner* window = GetOwner();
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
RefPtr<Promise> p = Promise::Create(go, aRv);
RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
RefPtr<EnumDevResolver> resolver = new EnumDevResolver(p, window->WindowID());
RefPtr<EnumDevResolver> resolver = new EnumDevResolver(p, GetOwner()->WindowID());
RefPtr<GumRejecter> rejecter = new GumRejecter(p);
aRv = MediaManager::Get()->EnumerateDevices(window, resolver, rejecter, aCallerType);
aRv = MediaManager::Get()->EnumerateDevices(GetOwner(), resolver, rejecter, aCallerType);
return p.forget();
}

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

@ -3701,8 +3701,7 @@ MediaStreamGraph::GetInstance(MediaStreamGraph::GraphDriverType aGraphDriverRequ
AbstractThread* mainThread;
if (aWindow) {
nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(aWindow);
mainThread = parentObject->AbstractMainThreadFor(TaskCategory::Other);
mainThread = aWindow->AsGlobal()->AbstractMainThreadFor(TaskCategory::Other);
} else {
// Uncommon case, only for some old configuration of webspeech.
mainThread = AbstractThread::MainThread();
@ -3727,11 +3726,10 @@ MediaStreamGraph::CreateNonRealtimeInstance(TrackRate aSampleRate,
{
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(aWindow);
MediaStreamGraphImpl* graph = new MediaStreamGraphImpl(
OFFLINE_THREAD_DRIVER,
aSampleRate,
parentObject->AbstractMainThreadFor(TaskCategory::Other));
aWindow->AsGlobal()->AbstractMainThreadFor(TaskCategory::Other));
LOG(LogLevel::Debug, ("Starting up Offline MediaStreamGraph %p", graph));

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

@ -294,9 +294,12 @@ MediaStreamTrack::ApplyConstraints(const MediaTrackConstraints& aConstraints,
typedef media::Pledge<bool, MediaStreamError*> PledgeVoid;
nsPIDOMWindowInner* window = mOwningStream->GetParentObject();
nsIGlobalObject* go = window ? window->AsGlobal() : nullptr;
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
RefPtr<Promise> promise = Promise::Create(go, aRv);
if (aRv.Failed()) {
return nullptr;
}
// Forward constraints to the source.
//

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

@ -1793,8 +1793,7 @@ Notification::RequestPermission(const GlobalObject& aGlobal,
}
nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
RefPtr<Promise> promise = Promise::Create(global, aRv);
RefPtr<Promise> promise = Promise::Create(window->AsGlobal(), aRv);
if (aRv.Failed()) {
return nullptr;
}
@ -1806,7 +1805,7 @@ Notification::RequestPermission(const GlobalObject& aGlobal,
nsCOMPtr<nsIRunnable> request = new NotificationPermissionRequest(
principal, isHandlingUserInput, window, promise, permissionCallback);
global->Dispatch(TaskCategory::Other, request.forget());
window->AsGlobal()->Dispatch(TaskCategory::Other, request.forget());
return promise.forget();
}
@ -1991,19 +1990,18 @@ Notification::Get(nsPIDOMWindowInner* aWindow,
return nullptr;
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aWindow);
RefPtr<Promise> promise = Promise::Create(global, aRv);
RefPtr<Promise> promise = Promise::Create(aWindow->AsGlobal(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsCOMPtr<nsINotificationStorageCallback> callback =
new NotificationStorageCallback(global, aScope, promise);
new NotificationStorageCallback(aWindow->AsGlobal(), aScope, promise);
RefPtr<NotificationGetRunnable> r =
new NotificationGetRunnable(origin, aFilter.mTag, callback);
aRv = global->Dispatch(TaskCategory::Other, r.forget());
aRv = aWindow->AsGlobal()->Dispatch(TaskCategory::Other, r.forget());
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}

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

@ -77,8 +77,7 @@ Permissions::Query(JSContext* aCx,
JS::Handle<JSObject*> aPermission,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
if (!global) {
if (!mWindow) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
@ -91,7 +90,7 @@ Permissions::Query(JSContext* aCx,
}
MOZ_ASSERT(status);
RefPtr<Promise> promise = Promise::Create(global, aRv);
RefPtr<Promise> promise = Promise::Create(mWindow->AsGlobal(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -118,8 +117,7 @@ Permissions::Revoke(JSContext* aCx,
JS::Handle<JSObject*> aPermission,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
if (!global) {
if (!mWindow) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
@ -131,7 +129,7 @@ Permissions::Revoke(JSContext* aCx,
return nullptr;
}
RefPtr<Promise> promise = Promise::Create(global, aRv);
RefPtr<Promise> promise = Promise::Create(mWindow->AsGlobal(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}

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

@ -902,9 +902,8 @@ ServiceWorkerManager::Register(mozIDOMWindow* aWindow,
return rv;
}
nsCOMPtr<nsIGlobalObject> sgo = do_QueryInterface(window);
ErrorResult result;
RefPtr<Promise> promise = Promise::Create(sgo, result);
RefPtr<Promise> promise = Promise::Create(window->AsGlobal(), result);
if (result.Failed()) {
return result.StealNSResult();
}
@ -1073,9 +1072,8 @@ ServiceWorkerManager::GetRegistrations(mozIDOMWindow* aWindow,
// now.
MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(window->GetExtantDoc()->NodePrincipal()));
nsCOMPtr<nsIGlobalObject> sgo = do_QueryInterface(window);
ErrorResult result;
RefPtr<Promise> promise = Promise::Create(sgo, result);
RefPtr<Promise> promise = Promise::Create(window->AsGlobal(), result);
if (result.Failed()) {
return result.StealNSResult();
}
@ -1195,9 +1193,8 @@ ServiceWorkerManager::GetRegistration(mozIDOMWindow* aWindow,
// now.
MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(window->GetExtantDoc()->NodePrincipal()));
nsCOMPtr<nsIGlobalObject> sgo = do_QueryInterface(window);
ErrorResult result;
RefPtr<Promise> promise = Promise::Create(sgo, result);
RefPtr<Promise> promise = Promise::Create(window->AsGlobal(), result);
if (result.Failed()) {
return result.StealNSResult();
}
@ -1397,9 +1394,8 @@ ServiceWorkerManager::GetReadyPromise(mozIDOMWindow* aWindow,
MOZ_ASSERT(!mPendingReadyPromises.Contains(window));
nsCOMPtr<nsIGlobalObject> sgo = do_QueryInterface(window);
ErrorResult result;
RefPtr<Promise> promise = Promise::Create(sgo, result);
RefPtr<Promise> promise = Promise::Create(window->AsGlobal(), result);
if (result.Failed()) {
return result.StealNSResult();
}

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

@ -65,12 +65,10 @@ ServiceWorkerRegistration::CreateForMainThread(nsPIDOMWindowInner* aWindow,
MOZ_ASSERT(aWindow);
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(aWindow));
RefPtr<Inner> inner = new ServiceWorkerRegistrationMainThread(aDescriptor);
RefPtr<ServiceWorkerRegistration> registration =
new ServiceWorkerRegistration(global, aDescriptor, inner);
new ServiceWorkerRegistration(aWindow->AsGlobal(), aDescriptor, inner);
return registration.forget();
}

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

@ -517,7 +517,7 @@ already_AddRefed<Promise>
ServiceWorkerRegistrationMainThread::Update(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mOuter->GetOwner());
nsCOMPtr<nsIGlobalObject> go = mOuter->GetParentObject();
if (!go) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
@ -542,7 +542,7 @@ already_AddRefed<Promise>
ServiceWorkerRegistrationMainThread::Unregister(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mOuter->GetOwner());
nsCOMPtr<nsIGlobalObject> go = mOuter->GetParentObject();
if (!go) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
@ -627,10 +627,9 @@ ServiceWorkerRegistrationMainThread::ShowNotification(JSContext* aCx,
return nullptr;
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
RefPtr<Promise> p =
Notification::ShowPersistentNotification(aCx, global, mScope, aTitle,
aOptions, aRv);
Notification::ShowPersistentNotification(aCx, window->AsGlobal(), mScope,
aTitle, aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -656,7 +655,7 @@ ServiceWorkerRegistrationMainThread::GetPushManager(JSContext* aCx,
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(mOuter->GetOwner());
nsCOMPtr<nsIGlobalObject> globalObject = mOuter->GetParentObject();
if (!globalObject) {
aRv.Throw(NS_ERROR_FAILURE);

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

@ -315,9 +315,7 @@ VRServiceTest::AttachVRDisplay(const nsAString& aID, ErrorResult& aRv)
return nullptr;
}
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> p = Promise::Create(go, aRv);
RefPtr<Promise> p = Promise::Create(mWindow->AsGlobal(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -335,9 +333,7 @@ VRServiceTest::AttachVRController(const nsAString& aID, ErrorResult& aRv)
return nullptr;
}
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> p = Promise::Create(go, aRv);
RefPtr<Promise> p = Promise::Create(mWindow->AsGlobal(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}

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

@ -105,38 +105,36 @@ U2FHIDTokenManager::Drop()
// * attestation signature
//
RefPtr<U2FRegisterPromise>
U2FHIDTokenManager::Register(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS)
U2FHIDTokenManager::Register(const WebAuthnMakeCredentialInfo& aInfo)
{
mozilla::ipc::AssertIsOnBackgroundThread();
uint64_t registerFlags = 0;
const WebAuthnAuthenticatorSelection& sel = aInfo.AuthenticatorSelection();
// Set flags for credential creation.
if (aAuthenticatorSelection.requireResidentKey()) {
if (sel.requireResidentKey()) {
registerFlags |= U2F_FLAG_REQUIRE_RESIDENT_KEY;
}
if (aAuthenticatorSelection.requireUserVerification()) {
if (sel.requireUserVerification()) {
registerFlags |= U2F_FLAG_REQUIRE_USER_VERIFICATION;
}
if (aAuthenticatorSelection.requirePlatformAttachment()) {
if (sel.requirePlatformAttachment()) {
registerFlags |= U2F_FLAG_REQUIRE_PLATFORM_ATTACHMENT;
}
ClearPromises();
mCurrentAppId = aApplication;
mCurrentAppId = aInfo.RpIdHash();
mTransactionId = rust_u2f_mgr_register(mU2FManager,
registerFlags,
(uint64_t)aTimeoutMS,
(uint64_t)aInfo.TimeoutMS(),
u2f_register_callback,
aChallenge.Elements(),
aChallenge.Length(),
aApplication.Elements(),
aApplication.Length(),
U2FKeyHandles(aCredentials).Get());
aInfo.ClientDataHash().Elements(),
aInfo.ClientDataHash().Length(),
aInfo.RpIdHash().Elements(),
aInfo.RpIdHash().Length(),
U2FKeyHandles(aInfo.ExcludeList()).Get());
if (mTransactionId == 0) {
return U2FRegisterPromise::CreateAndReject(NS_ERROR_DOM_UNKNOWN_ERR, __func__);
@ -162,42 +160,37 @@ U2FHIDTokenManager::Register(const nsTArray<WebAuthnScopedCredential>& aCredenti
// * Signature
//
RefPtr<U2FSignPromise>
U2FHIDTokenManager::Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
const nsTArray<WebAuthnExtension>& aExtensions,
bool aRequireUserVerification,
uint32_t aTimeoutMS)
U2FHIDTokenManager::Sign(const WebAuthnGetAssertionInfo& aInfo)
{
mozilla::ipc::AssertIsOnBackgroundThread();
uint64_t signFlags = 0;
// Set flags for credential requests.
if (aRequireUserVerification) {
if (aInfo.RequireUserVerification()) {
signFlags |= U2F_FLAG_REQUIRE_USER_VERIFICATION;
}
mCurrentAppId = aInfo.RpIdHash();
nsTArray<nsTArray<uint8_t>> appIds;
appIds.AppendElement(aApplication);
appIds.AppendElement(mCurrentAppId);
// Process extensions.
for (const WebAuthnExtension& ext: aExtensions) {
for (const WebAuthnExtension& ext: aInfo.Extensions()) {
if (ext.type() == WebAuthnExtension::TWebAuthnExtensionAppId) {
appIds.AppendElement(ext.get_WebAuthnExtensionAppId().AppId());
}
}
ClearPromises();
mCurrentAppId = aApplication;
mTransactionId = rust_u2f_mgr_sign(mU2FManager,
signFlags,
(uint64_t)aTimeoutMS,
(uint64_t)aInfo.TimeoutMS(),
u2f_sign_callback,
aChallenge.Elements(),
aChallenge.Length(),
aInfo.ClientDataHash().Elements(),
aInfo.ClientDataHash().Length(),
U2FAppIds(appIds).Get(),
U2FKeyHandles(aCredentials).Get());
U2FKeyHandles(aInfo.AllowList()).Get());
if (mTransactionId == 0) {
return U2FSignPromise::CreateAndReject(NS_ERROR_DOM_UNKNOWN_ERR, __func__);
}

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

@ -118,19 +118,10 @@ public:
explicit U2FHIDTokenManager();
RefPtr<U2FRegisterPromise>
Register(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS) override;
Register(const WebAuthnMakeCredentialInfo& aInfo) override;
RefPtr<U2FSignPromise>
Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
const nsTArray<WebAuthnExtension>& aExtensions,
bool aRequireUserVerification,
uint32_t aTimeoutMS) override;
Sign(const WebAuthnGetAssertionInfo& aInfo) override;
void Cancel() override;
void Drop() override;

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

@ -583,11 +583,7 @@ U2FSoftTokenManager::IsRegistered(const nsTArray<uint8_t>& aKeyHandle,
// * attestation signature
//
RefPtr<U2FRegisterPromise>
U2FSoftTokenManager::Register(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS)
U2FSoftTokenManager::Register(const WebAuthnMakeCredentialInfo& aInfo)
{
if (!mInitialized) {
nsresult rv = Init();
@ -596,18 +592,20 @@ U2FSoftTokenManager::Register(const nsTArray<WebAuthnScopedCredential>& aCredent
}
}
const WebAuthnAuthenticatorSelection& sel = aInfo.AuthenticatorSelection();
// The U2F softtoken neither supports resident keys or
// user verification, nor is it a platform authenticator.
if (aAuthenticatorSelection.requireResidentKey() ||
aAuthenticatorSelection.requireUserVerification() ||
aAuthenticatorSelection.requirePlatformAttachment()) {
if (sel.requireResidentKey() ||
sel.requireUserVerification() ||
sel.requirePlatformAttachment()) {
return U2FRegisterPromise::CreateAndReject(NS_ERROR_DOM_NOT_ALLOWED_ERR, __func__);
}
// Optional exclusion list.
for (auto cred: aCredentials) {
for (const WebAuthnScopedCredential& cred: aInfo.ExcludeList()) {
bool isRegistered = false;
nsresult rv = IsRegistered(cred.id(), aApplication, isRegistered);
nsresult rv = IsRegistered(cred.id(), aInfo.RpIdHash(), isRegistered);
if (NS_FAILED(rv)) {
return U2FRegisterPromise::CreateAndReject(rv, __func__);
}
@ -641,17 +639,18 @@ U2FSoftTokenManager::Register(const nsTArray<WebAuthnScopedCredential>& aCredent
}
// The key handle will be the result of keywrap(privKey, key=mWrappingKey)
UniqueSECItem keyHandleItem = KeyHandleFromPrivateKey(slot, mWrappingKey,
const_cast<uint8_t*>(aApplication.Elements()),
aApplication.Length(),
privKey);
UniqueSECItem keyHandleItem =
KeyHandleFromPrivateKey(slot, mWrappingKey,
const_cast<uint8_t*>(aInfo.RpIdHash().Elements()),
aInfo.RpIdHash().Length(), privKey);
if (NS_WARN_IF(!keyHandleItem.get())) {
return U2FRegisterPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
}
// Sign the challenge using the Attestation privkey (from attestCert)
mozilla::dom::CryptoBuffer signedDataBuf;
if (NS_WARN_IF(!signedDataBuf.SetCapacity(1 + aApplication.Length() + aChallenge.Length() +
if (NS_WARN_IF(!signedDataBuf.SetCapacity(1 + aInfo.RpIdHash().Length() +
aInfo.ClientDataHash().Length() +
keyHandleItem->len + kPublicKeyLen,
mozilla::fallible))) {
return U2FRegisterPromise::CreateAndReject(NS_ERROR_OUT_OF_MEMORY, __func__);
@ -660,8 +659,8 @@ U2FSoftTokenManager::Register(const nsTArray<WebAuthnScopedCredential>& aCredent
// // It's OK to ignore the return values here because we're writing into
// // pre-allocated space
signedDataBuf.AppendElement(0x00, mozilla::fallible);
signedDataBuf.AppendElements(aApplication, mozilla::fallible);
signedDataBuf.AppendElements(aChallenge, mozilla::fallible);
signedDataBuf.AppendElements(aInfo.RpIdHash(), mozilla::fallible);
signedDataBuf.AppendElements(aInfo.ClientDataHash(), mozilla::fallible);
signedDataBuf.AppendSECItem(keyHandleItem.get());
signedDataBuf.AppendSECItem(pubKey->u.ec.publicValue);
@ -731,12 +730,7 @@ U2FSoftTokenManager::FindRegisteredKeyHandle(const nsTArray<nsTArray<uint8_t>>&
// * Signature
//
RefPtr<U2FSignPromise>
U2FSoftTokenManager::Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
const nsTArray<WebAuthnExtension>& aExtensions,
bool aRequireUserVerification,
uint32_t aTimeoutMS)
U2FSoftTokenManager::Sign(const WebAuthnGetAssertionInfo& aInfo)
{
if (!mInitialized) {
nsresult rv = Init();
@ -746,25 +740,25 @@ U2FSoftTokenManager::Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials
}
// The U2F softtoken doesn't support user verification.
if (aRequireUserVerification) {
if (aInfo.RequireUserVerification()) {
return U2FSignPromise::CreateAndReject(NS_ERROR_DOM_NOT_ALLOWED_ERR, __func__);
}
nsTArray<nsTArray<uint8_t>> appIds;
appIds.AppendElement(aApplication);
appIds.AppendElement(aInfo.RpIdHash());
// Process extensions.
for (const WebAuthnExtension& ext: aExtensions) {
for (const WebAuthnExtension& ext: aInfo.Extensions()) {
if (ext.type() == WebAuthnExtension::TWebAuthnExtensionAppId) {
appIds.AppendElement(ext.get_WebAuthnExtensionAppId().AppId());
}
}
nsTArray<uint8_t> chosenAppId(aApplication);
nsTArray<uint8_t> chosenAppId;
nsTArray<uint8_t> keyHandle;
// Fail if we can't find a valid key handle.
if (!FindRegisteredKeyHandle(appIds, aCredentials, keyHandle, chosenAppId)) {
if (!FindRegisteredKeyHandle(appIds, aInfo.AllowList(), keyHandle, chosenAppId)) {
return U2FSignPromise::CreateAndReject(NS_ERROR_DOM_NOT_ALLOWED_ERR, __func__);
}
@ -773,20 +767,23 @@ U2FSoftTokenManager::Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials
UniquePK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get());
if (NS_WARN_IF((aChallenge.Length() != kParamLen) || (chosenAppId.Length() != kParamLen))) {
if (NS_WARN_IF((aInfo.ClientDataHash().Length() != kParamLen) ||
(chosenAppId.Length() != kParamLen))) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Parameter lengths are wrong! challenge=%d app=%d expected=%d",
(uint32_t)aChallenge.Length(), (uint32_t)chosenAppId.Length(), kParamLen));
(uint32_t)aInfo.ClientDataHash().Length(),
(uint32_t)chosenAppId.Length(), kParamLen));
return U2FSignPromise::CreateAndReject(NS_ERROR_ILLEGAL_VALUE, __func__);
}
// Decode the key handle
UniqueSECKEYPrivateKey privKey = PrivateKeyFromKeyHandle(slot, mWrappingKey,
const_cast<uint8_t*>(keyHandle.Elements()),
keyHandle.Length(),
const_cast<uint8_t*>(chosenAppId.Elements()),
chosenAppId.Length());
UniqueSECKEYPrivateKey privKey =
PrivateKeyFromKeyHandle(slot, mWrappingKey,
const_cast<uint8_t*>(keyHandle.Elements()),
keyHandle.Length(),
const_cast<uint8_t*>(chosenAppId.Elements()),
chosenAppId.Length());
if (NS_WARN_IF(!privKey.get())) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Couldn't get the priv key!"));
return U2FSignPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
@ -815,11 +812,13 @@ U2FSoftTokenManager::Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials
// It's OK to ignore the return values here because we're writing into
// pre-allocated space
signedDataBuf.AppendElements(chosenAppId.Elements(), chosenAppId.Length(),
signedDataBuf.AppendElements(chosenAppId.Elements(),
chosenAppId.Length(),
mozilla::fallible);
signedDataBuf.AppendElement(0x01, mozilla::fallible);
signedDataBuf.AppendSECItem(counterItem);
signedDataBuf.AppendElements(aChallenge.Elements(), aChallenge.Length(),
signedDataBuf.AppendElements(aInfo.ClientDataHash().Elements(),
aInfo.ClientDataHash().Length(),
mozilla::fallible);
if (MOZ_LOG_TEST(gNSSTokenLog, LogLevel::Debug)) {
@ -860,7 +859,7 @@ U2FSoftTokenManager::Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials
nsTArray<uint8_t> signature(signatureBuf);
nsTArray<WebAuthnExtensionResult> extensions;
if (chosenAppId != aApplication) {
if (chosenAppId != aInfo.RpIdHash()) {
// Indicate to the RP that we used the FIDO appId.
extensions.AppendElement(WebAuthnExtensionResultAppId(true));
}

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

@ -24,19 +24,10 @@ public:
explicit U2FSoftTokenManager(uint32_t aCounter);
RefPtr<U2FRegisterPromise>
Register(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS) override;
Register(const WebAuthnMakeCredentialInfo& aInfo) override;
RefPtr<U2FSignPromise>
Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
const nsTArray<WebAuthnExtension>& aExtensions,
bool aRequireUserVerification,
uint32_t aTimeoutMS) override;
Sign(const WebAuthnGetAssertionInfo& aInfo) override;
void Cancel() override;

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

@ -248,31 +248,28 @@ U2FTokenManager::Register(PWebAuthnTransactionParent* aTransactionParent,
uint64_t tid = mLastTransactionId = aTransactionId;
mozilla::TimeStamp startTime = mozilla::TimeStamp::Now();
mTokenManagerImpl->Register(aTransactionInfo.ExcludeList(),
aTransactionInfo.AuthenticatorSelection(),
aTransactionInfo.RpIdHash(),
aTransactionInfo.ClientDataHash(),
aTransactionInfo.TimeoutMS())
->Then(GetCurrentThreadSerialEventTarget(), __func__,
[tid, startTime](WebAuthnMakeCredentialResult&& aResult) {
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeConfirmRegister(tid, aResult);
Telemetry::ScalarAdd(
Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
NS_LITERAL_STRING("U2FRegisterFinish"), 1);
Telemetry::AccumulateTimeDelta(
Telemetry::WEBAUTHN_CREATE_CREDENTIAL_MS,
startTime);
},
[tid](nsresult rv) {
MOZ_ASSERT(NS_FAILED(rv));
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeAbortRegister(tid, rv);
Telemetry::ScalarAdd(
Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
NS_LITERAL_STRING("U2FRegisterAbort"), 1);
})
->Track(mRegisterPromise);
mTokenManagerImpl
->Register(aTransactionInfo)
->Then(GetCurrentThreadSerialEventTarget(), __func__,
[tid, startTime](WebAuthnMakeCredentialResult&& aResult) {
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeConfirmRegister(tid, aResult);
Telemetry::ScalarAdd(
Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
NS_LITERAL_STRING("U2FRegisterFinish"), 1);
Telemetry::AccumulateTimeDelta(
Telemetry::WEBAUTHN_CREATE_CREDENTIAL_MS,
startTime);
},
[tid](nsresult rv) {
MOZ_ASSERT(NS_FAILED(rv));
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeAbortRegister(tid, rv);
Telemetry::ScalarAdd(
Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
NS_LITERAL_STRING("U2FRegisterAbort"), 1);
})
->Track(mRegisterPromise);
}
void
@ -319,32 +316,28 @@ U2FTokenManager::Sign(PWebAuthnTransactionParent* aTransactionParent,
uint64_t tid = mLastTransactionId = aTransactionId;
mozilla::TimeStamp startTime = mozilla::TimeStamp::Now();
mTokenManagerImpl->Sign(aTransactionInfo.AllowList(),
aTransactionInfo.RpIdHash(),
aTransactionInfo.ClientDataHash(),
aTransactionInfo.Extensions(),
aTransactionInfo.RequireUserVerification(),
aTransactionInfo.TimeoutMS())
->Then(GetCurrentThreadSerialEventTarget(), __func__,
[tid, startTime](WebAuthnGetAssertionResult&& aResult) {
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeConfirmSign(tid, aResult);
Telemetry::ScalarAdd(
Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
NS_LITERAL_STRING("U2FSignFinish"), 1);
Telemetry::AccumulateTimeDelta(
Telemetry::WEBAUTHN_GET_ASSERTION_MS,
startTime);
},
[tid](nsresult rv) {
MOZ_ASSERT(NS_FAILED(rv));
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeAbortSign(tid, rv);
Telemetry::ScalarAdd(
Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
NS_LITERAL_STRING("U2FSignAbort"), 1);
})
->Track(mSignPromise);
mTokenManagerImpl
->Sign(aTransactionInfo)
->Then(GetCurrentThreadSerialEventTarget(), __func__,
[tid, startTime](WebAuthnGetAssertionResult&& aResult) {
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeConfirmSign(tid, aResult);
Telemetry::ScalarAdd(
Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
NS_LITERAL_STRING("U2FSignFinish"), 1);
Telemetry::AccumulateTimeDelta(
Telemetry::WEBAUTHN_GET_ASSERTION_MS,
startTime);
},
[tid](nsresult rv) {
MOZ_ASSERT(NS_FAILED(rv));
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeAbortSign(tid, rv);
Telemetry::ScalarAdd(
Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
NS_LITERAL_STRING("U2FSignAbort"), 1);
})
->Track(mSignPromise);
}
void

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

@ -28,19 +28,10 @@ public:
U2FTokenTransport() {}
virtual RefPtr<U2FRegisterPromise>
Register(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const WebAuthnAuthenticatorSelection &aAuthenticatorSelection,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
uint32_t aTimeoutMS) = 0;
Register(const WebAuthnMakeCredentialInfo& aInfo) = 0;
virtual RefPtr<U2FSignPromise>
Sign(const nsTArray<WebAuthnScopedCredential>& aCredentials,
const nsTArray<uint8_t>& aApplication,
const nsTArray<uint8_t>& aChallenge,
const nsTArray<WebAuthnExtension>& aExtensions,
bool aRequireUserVerification,
uint32_t aTimeoutMS) = 0;
Sign(const WebAuthnGetAssertionInfo& aInfo) = 0;
virtual void Cancel() = 0;

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

@ -382,6 +382,12 @@ partial interface Document {
// like documentURI, except that for error pages, it returns the URI we were
// trying to load when we hit an error, rather than the error page's own URI.
[ChromeOnly] readonly attribute URI? mozDocumentURIIfNotForErrorPages;
// A promise that is resolved, with this document itself, when we have both
// fired DOMContentLoaded and are ready to start layout. This is used for the
// "document_idle" webextension script injection point.
[ChromeOnly, Throws]
readonly attribute Promise<Document> documentReadyForIdle;
};
dictionary BlockParsingOptions {

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

@ -2393,8 +2393,8 @@ RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx,
// We don't actually care about this MessageChannel, but we use it to 'steal'
// its 2 connected ports.
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
RefPtr<MessageChannel> channel = MessageChannel::Constructor(global, rv);
RefPtr<MessageChannel> channel =
MessageChannel::Constructor(window->AsGlobal(), rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}

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

@ -861,10 +861,9 @@ Proxy::Init()
return false;
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(ownerWindow);
mXHR = new XMLHttpRequestMainThread();
mXHR->Construct(mWorkerPrivate->GetPrincipal(), global,
mXHR->Construct(mWorkerPrivate->GetPrincipal(),
ownerWindow ? ownerWindow->AsGlobal() : nullptr,
mWorkerPrivate->GetBaseURI(),
mWorkerPrivate->GetLoadGroup(),
mWorkerPrivate->GetPerformanceStorage());

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

@ -560,7 +560,8 @@ public:
*/
virtual void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut) const
size_t& aNonHeapSizeOut,
size_t& aExtHandlesOut) const
{
}

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

@ -40,6 +40,7 @@ SourceSurfaceRawData::GuaranteePersistance()
return;
}
MOZ_ASSERT(!mDeallocator);
uint8_t* oldData = mRawData;
mRawData = new uint8_t[mStride * mSize.height];
@ -78,5 +79,14 @@ SourceSurfaceAlignedRawData::Init(const IntSize &aSize,
return mArray != nullptr;
}
void
SourceSurfaceAlignedRawData::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut,
size_t& aExtHandlesOut) const
{
aHeapSizeOut += mArray.HeapSizeOfExcludingThis(aMallocSizeOf);
}
} // namespace gfx
} // namespace mozilla

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

@ -115,6 +115,12 @@ public:
MOZ_ASSERT(mMapCount == 0);
}
bool Init(const IntSize &aSize,
SurfaceFormat aFormat,
bool aClearMem,
uint8_t aClearValue,
int32_t aStride = 0);
virtual uint8_t* GetData() override { return mArray; }
virtual int32_t Stride() override { return mStride; }
@ -122,6 +128,11 @@ public:
virtual IntSize GetSize() const override { return mSize; }
virtual SurfaceFormat GetFormat() const override { return mFormat; }
void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut,
size_t& aExtHandlesOut) const override;
virtual bool Map(MapType, MappedSurface *aMappedSurface) override
{
aMappedSurface->mData = GetData();
@ -142,12 +153,6 @@ public:
private:
friend class Factory;
bool Init(const IntSize &aSize,
SurfaceFormat aFormat,
bool aClearMem,
uint8_t aClearValue,
int32_t aStride = 0);
AlignedArray<uint8_t> mArray;
int32_t mStride;
SurfaceFormat mFormat;

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

@ -8,6 +8,7 @@
#define MOZILLA_GFX_TOOLS_H_
#include "mozilla/CheckedInt.h"
#include "mozilla/MemoryReporting.h" // for MallocSizeOf
#include "mozilla/Move.h"
#include "mozilla/TypeTraits.h"
#include "Types.h"
@ -230,6 +231,12 @@ struct AlignedArray
mozilla::Swap(mCount, aOther.mCount);
}
size_t
HeapSizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
return aMallocSizeOf(mStorage);
}
MOZ_ALWAYS_INLINE operator T*()
{
return mPtr;

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

@ -94,11 +94,16 @@ SourceSurfaceSharedData::GuaranteePersistance()
void
SourceSurfaceSharedData::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut) const
size_t& aNonHeapSizeOut,
size_t& aExtHandlesOut) const
{
MutexAutoLock lock(mMutex);
if (mBuf) {
aNonHeapSizeOut += GetAlignedDataLength();
}
if (!mClosed) {
++aExtHandlesOut;
}
}
uint8_t*

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

@ -163,7 +163,8 @@ public:
void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut) const override;
size_t& aNonHeapSizeOut,
size_t& aExtHandlesOut) const override;
bool OnHeap() const override
{

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

@ -41,11 +41,18 @@ SourceSurfaceVolatileData::GuaranteePersistance()
void
SourceSurfaceVolatileData::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut) const
size_t& aNonHeapSizeOut,
size_t& aExtHandlesOut) const
{
if (mVBuf) {
aHeapSizeOut += mVBuf->HeapSizeOfExcludingThis(aMallocSizeOf);
aNonHeapSizeOut += mVBuf->NonHeapSizeOfExcludingThis();
#ifdef ANDROID
if (!mVBuf->OnHeap()) {
// Volatile buffers keep a file handle open on Android.
++aExtHandlesOut;
}
#endif
}
}

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

@ -52,7 +52,8 @@ public:
void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut) const override;
size_t& aNonHeapSizeOut,
size_t& aExtHandlesOut) const override;
bool OnHeap() const override
{

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

@ -2177,10 +2177,21 @@ gfxPlatform::FlushFontAndWordCaches()
/* static */ void
gfxPlatform::ForceGlobalReflow()
{
// modify a preference that will trigger reflow everywhere
static const char kPrefName[] = "font.internaluseonly.changed";
bool fontInternalChange = Preferences::GetBool(kPrefName, false);
Preferences::SetBool(kPrefName, !fontInternalChange);
MOZ_ASSERT(NS_IsMainThread());
if (XRE_IsParentProcess()) {
// Modify a preference that will trigger reflow everywhere (in all
// content processes, as well as the parent).
static const char kPrefName[] = "font.internaluseonly.changed";
bool fontInternalChange = Preferences::GetBool(kPrefName, false);
Preferences::SetBool(kPrefName, !fontInternalChange);
} else {
// Send a notification that will be observed by PresShells in this
// process only.
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs) {
obs->NotifyObservers(nullptr, "font-info-updated", nullptr);
}
}
}
void

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

@ -95,7 +95,6 @@ const gfxFontEntry::ScriptRange gfxPlatformFontList::sComplexScriptRanges[] = {
};
// prefs for the font info loader
#define FONT_LOADER_FAMILIES_PER_SLICE_PREF "gfx.font_loader.families_per_slice"
#define FONT_LOADER_DELAY_PREF "gfx.font_loader.delay"
#define FONT_LOADER_INTERVAL_PREF "gfx.font_loader.interval"
@ -187,7 +186,7 @@ gfxPlatformFontList::MemoryReporter::CollectReports(
gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
: mFontFamiliesMutex("gfxPlatformFontList::mFontFamiliesMutex"), mFontFamilies(64),
mOtherFamilyNames(16), mBadUnderlineFamilyNames(8), mSharedCmaps(8),
mStartIndex(0), mIncrement(1), mNumFamilies(0), mFontlistInitCount(0),
mStartIndex(0), mNumFamilies(0), mFontlistInitCount(0),
mFontFamilyWhitelistActive(false)
{
mOtherFamilyNamesInitialized = false;
@ -1683,9 +1682,6 @@ gfxPlatformFontList::CleanupLoader()
void
gfxPlatformFontList::GetPrefsAndStartLoader()
{
mIncrement =
std::max(1u, Preferences::GetUint(FONT_LOADER_FAMILIES_PER_SLICE_PREF));
uint32_t delay =
std::max(1u, Preferences::GetUint(FONT_LOADER_DELAY_PREF));
uint32_t interval =

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

@ -589,7 +589,6 @@ protected:
// data used as part of the font cmap loading process
nsTArray<RefPtr<gfxFontFamily> > mFontFamiliesToLoad;
uint32_t mStartIndex;
uint32_t mIncrement;
uint32_t mNumFamilies;
// xxx - info for diagnosing no default font aborts

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

@ -531,11 +531,13 @@ private:
DECL_GFX_PREF(Once, "image.mem.decode_bytes_at_a_time", ImageMemDecodeBytesAtATime, uint32_t, 200000);
DECL_GFX_PREF(Live, "image.mem.discardable", ImageMemDiscardable, bool, false);
DECL_GFX_PREF(Once, "image.mem.animated.discardable", ImageMemAnimatedDiscardable, bool, false);
DECL_GFX_PREF(Live, "image.mem.animated.use_heap", ImageMemAnimatedUseHeap, bool, false);
DECL_OVERRIDE_PREF(Live, "image.mem.shared", ImageMemShared, gfxPrefs::WebRenderAll());
DECL_GFX_PREF(Once, "image.mem.surfacecache.discard_factor", ImageMemSurfaceCacheDiscardFactor, uint32_t, 1);
DECL_GFX_PREF(Once, "image.mem.surfacecache.max_size_kb", ImageMemSurfaceCacheMaxSizeKB, uint32_t, 100 * 1024);
DECL_GFX_PREF(Once, "image.mem.surfacecache.min_expiration_ms", ImageMemSurfaceCacheMinExpirationMS, uint32_t, 60*1000);
DECL_GFX_PREF(Once, "image.mem.surfacecache.size_factor", ImageMemSurfaceCacheSizeFactor, uint32_t, 64);
DECL_GFX_PREF(Live, "image.mem.volatile.min_threshold_kb", ImageMemVolatileMinThresholdKB, int32_t, -1);
DECL_GFX_PREF(Once, "image.multithreaded_decoding.limit", ImageMTDecodingLimit, int32_t, -1);
DECL_GFX_PREF(Once, "image.multithreaded_decoding.idle_timeout", ImageMTDecodingIdleTimeout, int32_t, -1);

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

@ -84,6 +84,12 @@ RendererOGL::GetExternalImageHandler()
void
RendererOGL::Update()
{
uint32_t flags = gfx::gfxVars::WebRenderDebugFlags();
if (mDebugFlags.mBits != flags) {
mDebugFlags.mBits = flags;
wr_renderer_set_debug_flags(mRenderer, mDebugFlags);
}
if (gl()->MakeCurrent()) {
wr_renderer_update(mRenderer);
}

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

@ -114,7 +114,7 @@ void
AnimationSurfaceProvider::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut,
size_t& aSharedHandlesOut)
size_t& aExtHandlesOut)
{
// Note that the surface cache lock is already held here, and then we acquire
// mFramesMutex. For this method, this ordering is unavoidable, which means
@ -123,7 +123,7 @@ AnimationSurfaceProvider::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
for (const RawAccessFrameRef& frame : mFrames) {
frame->AddSizeOfExcludingThis(aMallocSizeOf, aHeapSizeOut,
aNonHeapSizeOut, aSharedHandlesOut);
aNonHeapSizeOut, aExtHandlesOut);
}
}

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

@ -48,7 +48,7 @@ public:
void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut,
size_t& aSharedHandlesOut) override;
size_t& aExtHandlesOut) override;
protected:
DrawableFrameRef DrawableRef(size_t aFrame) override;

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

@ -539,7 +539,7 @@ DoCollectSizeOfCompositingSurfaces(const RawAccessFrameRef& aSurface,
aSurface->AddSizeOfExcludingThis(aMallocSizeOf, heap, nonHeap, handles);
counter.Values().SetDecodedHeap(heap);
counter.Values().SetDecodedNonHeap(nonHeap);
counter.Values().SetSharedHandles(handles);
counter.Values().SetExternalHandles(handles);
// Record it.
aCounters.AppendElement(counter);

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

@ -65,7 +65,7 @@ public:
virtual void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut,
size_t& aSharedHandlesOut)
size_t& aExtHandlesOut)
{
DrawableFrameRef ref = DrawableRef(/* aFrame = */ 0);
if (!ref) {
@ -73,7 +73,7 @@ public:
}
ref->AddSizeOfExcludingThis(aMallocSizeOf, aHeapSizeOut,
aNonHeapSizeOut, aSharedHandlesOut);
aNonHeapSizeOut, aExtHandlesOut);
}
/// @return the availability state of this ISurfaceProvider, which indicates

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

@ -36,7 +36,7 @@ struct MemoryCounter
: mSource(0)
, mDecodedHeap(0)
, mDecodedNonHeap(0)
, mSharedHandles(0)
, mExternalHandles(0)
{ }
void SetSource(size_t aCount) { mSource = aCount; }
@ -45,15 +45,15 @@ struct MemoryCounter
size_t DecodedHeap() const { return mDecodedHeap; }
void SetDecodedNonHeap(size_t aCount) { mDecodedNonHeap = aCount; }
size_t DecodedNonHeap() const { return mDecodedNonHeap; }
void SetSharedHandles(size_t aCount) { mSharedHandles = aCount; }
size_t SharedHandles() const { return mSharedHandles; }
void SetExternalHandles(size_t aCount) { mExternalHandles = aCount; }
size_t ExternalHandles() const { return mExternalHandles; }
MemoryCounter& operator+=(const MemoryCounter& aOther)
{
mSource += aOther.mSource;
mDecodedHeap += aOther.mDecodedHeap;
mDecodedNonHeap += aOther.mDecodedNonHeap;
mSharedHandles += aOther.mSharedHandles;
mExternalHandles += aOther.mExternalHandles;
return *this;
}
@ -61,7 +61,7 @@ private:
size_t mSource;
size_t mDecodedHeap;
size_t mDecodedNonHeap;
size_t mSharedHandles;
size_t mExternalHandles;
};
enum class SurfaceMemoryCounterType

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

@ -207,7 +207,7 @@ public:
->AddSizeOfExcludingThis(mMallocSizeOf, heap, nonHeap, handles);
counter.Values().SetDecodedHeap(heap);
counter.Values().SetDecodedNonHeap(nonHeap);
counter.Values().SetSharedHandles(handles);
counter.Values().SetExternalHandles(handles);
mCounters.AppendElement(counter);
}

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

@ -19,6 +19,7 @@
#include "MainThreadUtils.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/gfx/Tools.h"
#include "mozilla/gfx/SourceSurfaceRawData.h"
#include "mozilla/layers/SourceSurfaceSharedData.h"
#include "mozilla/layers/SourceSurfaceVolatileData.h"
#include "mozilla/Likely.h"
@ -26,10 +27,6 @@
#include "nsMargin.h"
#include "nsThreadUtils.h"
#ifdef ANDROID
#define ANIMATED_FRAMES_USE_HEAP
#endif
namespace mozilla {
using namespace gfx;
@ -80,6 +77,33 @@ CreateLockedSurface(DataSourceSurface *aSurface,
return nullptr;
}
static bool
ShouldUseHeap(const IntSize& aSize,
int32_t aStride,
bool aIsAnimated)
{
// On some platforms (i.e. Android), a volatile buffer actually keeps a file
// handle active. We would like to avoid too many since we could easily
// exhaust the pool. However, other platforms we do not have the file handle
// problem, and additionally we may avoid a superfluous memset since the
// volatile memory starts out as zero-filled. Hence the knobs below.
// For as long as an animated image is retained, its frames will never be
// released to let the OS purge volatile buffers.
if (aIsAnimated && gfxPrefs::ImageMemAnimatedUseHeap()) {
return true;
}
// Lets us avoid too many small images consuming all of the handles. The
// actual allocation checks for overflow.
int32_t bufferSize = (aStride * aSize.width) / 1024;
if (bufferSize < gfxPrefs::ImageMemVolatileMinThresholdKB()) {
return true;
}
return false;
}
static already_AddRefed<DataSourceSurface>
AllocateBufferForImage(const IntSize& size,
SurfaceFormat format,
@ -87,19 +111,13 @@ AllocateBufferForImage(const IntSize& size,
{
int32_t stride = VolatileSurfaceStride(size, format);
#ifdef ANIMATED_FRAMES_USE_HEAP
if (aIsAnimated) {
// For as long as an animated image is retained, its frames will never be
// released to let the OS purge volatile buffers. On Android, a volatile
// buffer actually keeps a file handle active, which we would like to avoid
// since many images and frames could easily exhaust the pool. As such, we
// use the heap. On the other platforms we do not have the file handle
// problem, and additionally we may avoid a superfluous memset since the
// volatile memory starts out as zero-filled.
return Factory::CreateDataSourceSurfaceWithStride(size, format,
stride, false);
if (ShouldUseHeap(size, stride, aIsAnimated)) {
RefPtr<SourceSurfaceAlignedRawData> newSurf =
new SourceSurfaceAlignedRawData();
if (newSurf->Init(size, format, false, 0, stride)) {
return newSurf.forget();
}
}
#endif
if (!aIsAnimated && gfxVars::GetUseWebRenderOrDefault()
&& gfxPrefs::ImageMemShared()) {
@ -932,7 +950,7 @@ void
imgFrame::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut,
size_t& aSharedHandlesOut) const
size_t& aExtHandlesOut) const
{
MonitorAutoLock lock(mMonitor);
@ -948,15 +966,7 @@ imgFrame::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
if (mRawSurface) {
aHeapSizeOut += aMallocSizeOf(mRawSurface);
mRawSurface->AddSizeOfExcludingThis(aMallocSizeOf, aHeapSizeOut,
aNonHeapSizeOut);
if (mRawSurface->GetType() == SurfaceType::DATA_SHARED) {
auto sharedSurface =
static_cast<SourceSurfaceSharedData*>(mRawSurface.get());
if (sharedSurface->CanShare()) {
++aSharedHandlesOut;
}
}
aNonHeapSizeOut, aExtHandlesOut);
}
}

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

@ -250,7 +250,7 @@ public:
void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, size_t& aHeapSizeOut,
size_t& aNonHeapSizeOut,
size_t& aSharedHandlesOut) const;
size_t& aExtHandlesOut) const;
private: // methods

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

@ -297,9 +297,9 @@ private:
surfacePathPrefix.AppendLiteral("x");
surfacePathPrefix.AppendInt(counter.Key().Size().height);
if (counter.Values().SharedHandles() > 0) {
surfacePathPrefix.AppendLiteral(", shared:");
surfacePathPrefix.AppendInt(uint32_t(counter.Values().SharedHandles()));
if (counter.Values().ExternalHandles() > 0) {
surfacePathPrefix.AppendLiteral(", external:");
surfacePathPrefix.AppendInt(uint32_t(counter.Values().ExternalHandles()));
}
if (counter.Type() == SurfaceMemoryCounterType::NORMAL) {

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

@ -116,7 +116,8 @@ MSG_DEF(JSMSG_JSON_CYCLIC_VALUE, 0, JSEXN_TYPEERR, "cyclic object value")
MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}")
MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 0, JSEXN_REFERENCEERR, "invalid assignment left-hand side")
MSG_DEF(JSMSG_BAD_PROTOTYPE, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object")
MSG_DEF(JSMSG_IN_NOT_OBJECT, 2, JSEXN_TYPEERR, "cannot use 'in' operator to search for '{0}' in '{1}'")
MSG_DEF(JSMSG_IN_NOT_OBJECT, 1, JSEXN_TYPEERR, "right-hand side of 'in' should be an object, got {0}")
MSG_DEF(JSMSG_IN_STRING, 2, JSEXN_TYPEERR, "cannot use 'in' operator to search for '{0}' in '{1}'")
MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor arguments")
MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments")
MSG_DEF(JSMSG_UNINITIALIZED_LEXICAL, 1, JSEXN_REFERENCEERR, "can't access lexical declaration `{0}' before initialization")

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

@ -1699,18 +1699,20 @@ js::ReportInNotObjectError(JSContext* cx, HandleValue lref, int lindex,
return UniqueChars(JS_EncodeString(cx, str));
};
UniqueChars lbytes = lref.isString()
? uniqueCharsFromString(cx, lref)
: DecompileValueGenerator(cx, lindex, lref, nullptr);
if (!lbytes)
return;
UniqueChars rbytes = rref.isString()
? uniqueCharsFromString(cx, rref)
: DecompileValueGenerator(cx, rindex, rref, nullptr);
if (!rbytes)
if (lref.isString() && rref.isString()) {
UniqueChars lbytes = uniqueCharsFromString(cx, lref);
if (!lbytes)
return;
UniqueChars rbytes = uniqueCharsFromString(cx, rref);
if (!rbytes)
return;
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_IN_STRING,
lbytes.get(), rbytes.get());
return;
}
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_IN_NOT_OBJECT,
lbytes.get(), rbytes.get());
InformalValueTypeName(rref));
}
static MOZ_NEVER_INLINE bool

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

@ -1023,6 +1023,7 @@ PresShell::Init(nsIDocument* aDocument,
if (XRE_IsParentProcess() && !sProcessInteractable) {
os->AddObserver(this, "sessionstore-one-or-no-tab-restored", false);
}
os->AddObserver(this, "font-info-updated", false);
}
}
@ -1260,6 +1261,7 @@ PresShell::Destroy()
if (XRE_IsParentProcess()) {
os->RemoveObserver(this, "sessionstore-one-or-no-tab-restored");
}
os->RemoveObserver(this, "font-info-updated");
}
}
@ -5217,8 +5219,8 @@ PresShell::AddPrintPreviewBackgroundItem(nsDisplayListBuilder& aBuilder,
nsIFrame* aFrame,
const nsRect& aBounds)
{
aList.AppendToBottom(new (&aBuilder)
nsDisplaySolidColor(&aBuilder, aFrame, aBounds, NS_RGB(115, 115, 115)));
aList.AppendToBottom(
MakeDisplayItem<nsDisplaySolidColor>(&aBuilder, aFrame, aBounds, NS_RGB(115, 115, 115)));
}
static bool
@ -5308,7 +5310,7 @@ PresShell::AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
if (!addedScrollingBackgroundColor || forceUnscrolledItem) {
aList.AppendToBottom(
new (&aBuilder) nsDisplaySolidColor(&aBuilder, aFrame, aBounds, bgcolor));
MakeDisplayItem<nsDisplaySolidColor>(&aBuilder, aFrame, aBounds, bgcolor));
}
}
@ -9326,6 +9328,11 @@ PresShell::Observe(nsISupports* aSubject,
return NS_OK;
}
if (!nsCRT::strcmp(aTopic, "font-info-updated")) {
mPresContext->ForceReflowForFontInfoUpdate();
return NS_OK;
}
NS_WARNING("unrecognized topic in PresShell::Observe");
return NS_ERROR_FAILURE;
}

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

@ -3021,7 +3021,7 @@ nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
builder.BeginFrame();
nsDisplayList list;
nsDisplayTransform* item =
new (&builder) nsDisplayTransform(&builder, aFrame, &list, nsRect());
MakeDisplayItem<nsDisplayTransform>(&builder, aFrame, &list, nsRect());
*aTransform = item->GetTransform();
item->Destroy(&builder);

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

@ -233,6 +233,15 @@ nsPresContext::PrefChangedUpdateTimerCallback(nsITimer *aTimer, void *aClosure)
presContext->UpdateAfterPreferencesChanged();
}
void
nsPresContext::ForceReflowForFontInfoUpdate()
{
// We can trigger reflow by pretending a font.* preference has changed;
// this is the same mechanism as gfxPlatform::ForceGlobalReflow() uses
// if new fonts are installed during the session, for example.
PreferenceChanged("font.internaluseonly.changed");
}
static bool
IsVisualCharset(NotNull<const Encoding*> aCharset)
{

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

@ -1250,6 +1250,10 @@ protected:
static bool NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData);
public:
// Used by the PresShell to force a reflow when some aspect of font info
// has been updated, potentially affecting font selection and layout.
void ForceReflowForFontInfoUpdate();
void DoChangeCharSet(NotNull<const Encoding*> aCharSet);
/**

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

@ -477,8 +477,8 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
nsDisplayList* aForeground)
{
if (mFrame->StyleEffects()->mBoxShadow) {
aBackground->AppendToTop(new (aBuilder)
nsDisplayButtonBoxShadowOuter(aBuilder, this));
aBackground->AppendToTop(
MakeDisplayItem<nsDisplayButtonBoxShadowOuter>(aBuilder, this));
}
nsRect buttonRect = mFrame->GetRectRelativeToSelf();
@ -486,14 +486,14 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
aBuilder, mFrame, buttonRect, aBackground);
aBackground->AppendToTop(new (aBuilder)
nsDisplayButtonBorder(aBuilder, this));
aBackground->AppendToTop(
MakeDisplayItem<nsDisplayButtonBorder>(aBuilder, this));
// Only display focus rings if we actually have them. Since at most one
// button would normally display a focus ring, most buttons won't have them.
if (mInnerFocusStyle && mInnerFocusStyle->StyleBorder()->HasBorder()) {
aForeground->AppendToTop(new (aBuilder)
nsDisplayButtonForeground(aBuilder, this));
aForeground->AppendToTop(
MakeDisplayItem<nsDisplayButtonForeground>(aBuilder, this));
}
return NS_OK;
}

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

@ -1599,7 +1599,7 @@ nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
!presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) &&
mDisplayFrame && IsVisibleForPainting(aBuilder)) {
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayComboboxFocus(aBuilder, this));
MakeDisplayItem<nsDisplayComboboxFocus>(aBuilder, this));
}
}
}

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

@ -196,8 +196,8 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (!(GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) &&
IsVisibleForPainting(aBuilder)) {
if (StyleEffects()->mBoxShadow) {
aLists.BorderBackground()->AppendToTop(new (aBuilder)
nsDisplayBoxShadowOuter(aBuilder, this));
aLists.BorderBackground()->AppendToTop(
MakeDisplayItem<nsDisplayBoxShadowOuter>(aBuilder, this));
}
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
@ -205,8 +205,8 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
aLists.BorderBackground(),
/* aAllowWillPaintBorderOptimization = */ false);
aLists.BorderBackground()->AppendToTop(new (aBuilder)
nsDisplayFieldSetBorder(aBuilder, this));
aLists.BorderBackground()->AppendToTop(
MakeDisplayItem<nsDisplayFieldSetBorder>(aBuilder, this));
DisplayOutlineUnconditional(aBuilder, aLists);

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

@ -185,7 +185,7 @@ nsListControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// this frame as the root of a stacking context we need make sure to draw
// some opaque color over the whole widget. (Bug 511323)
aLists.BorderBackground()->AppendToBottom(
new (aBuilder) nsDisplaySolidColor(aBuilder,
MakeDisplayItem<nsDisplaySolidColor>(aBuilder,
this, nsRect(aBuilder->ToReferenceFrame(this), GetSize()),
mLastDropdownBackstopColor));
}

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

@ -305,7 +305,7 @@ nsRangeFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayRangeFocusRing(aBuilder, this));
MakeDisplayItem<nsDisplayRangeFocusRing>(aBuilder, this));
}
void

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

@ -75,11 +75,11 @@ public:
nsOptionEventGrabberWrapper() {}
virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList) override {
return new (aBuilder) nsDisplayOptionEventGrabber(aBuilder, aFrame, aList);
return MakeDisplayItem<nsDisplayOptionEventGrabber>(aBuilder, aFrame, aList);
}
virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem) override {
return new (aBuilder) nsDisplayOptionEventGrabber(aBuilder, aItem->Frame(), aItem);
return MakeDisplayItem<nsDisplayOptionEventGrabber>(aBuilder, aItem->Frame(), aItem);
}
};
@ -154,8 +154,8 @@ nsSelectsAreaFrame::BuildDisplayListInternal(nsDisplayListBuilder* aBuilder,
// we can't just associate the display item with the list frame,
// because then the list's scrollframe won't clip it (the scrollframe
// only clips contained descendants).
aLists.Outlines()->AppendToTop(new (aBuilder)
nsDisplayListFocus(aBuilder, this));
aLists.Outlines()->AppendToTop(
MakeDisplayItem<nsDisplayListFocus>(aBuilder, this));
}
}

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

@ -861,9 +861,10 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
markerLogicalRect.GetPhysicalRect(mBlockWM, mBlockSize) + offset;
ClipMarker(aContentArea.GetPhysicalRect(mBlockWM, mBlockSize) + offset,
markerRect, clipState);
nsDisplayItem* marker = new (mBuilder)
nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect,
aLine->GetLogicalAscent(), mIStart.mStyle, aLineNumber, 0);
nsDisplayItem* marker =
MakeDisplayItem<nsDisplayTextOverflowMarker>(mBuilder, mBlock, markerRect,
aLine->GetLogicalAscent(), mIStart.mStyle,
aLineNumber, 0);
mMarkerList.AppendToTop(marker);
}
@ -878,9 +879,10 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
markerLogicalRect.GetPhysicalRect(mBlockWM, mBlockSize) + offset;
ClipMarker(aContentArea.GetPhysicalRect(mBlockWM, mBlockSize) + offset,
markerRect, clipState);
nsDisplayItem* marker = new (mBuilder)
nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect,
aLine->GetLogicalAscent(), mIEnd.mStyle, aLineNumber, 1);
nsDisplayItem* marker =
MakeDisplayItem<nsDisplayTextOverflowMarker>(mBuilder, mBlock, markerRect,
aLine->GetLogicalAscent(), mIEnd.mStyle,
aLineNumber, 1);
mMarkerList.AppendToTop(marker);
}
}

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

@ -72,7 +72,7 @@ ViewportFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// Wrap the whole top layer in a single item with maximum z-index,
// and append it at the very end, so that it stays at the topmost.
nsDisplayWrapList* wrapList =
new (aBuilder) nsDisplayWrapList(aBuilder, this, &topLayerList);
MakeDisplayItem<nsDisplayWrapList>(aBuilder, this, &topLayerList);
wrapList->SetOverrideZIndex(
std::numeric_limits<decltype(wrapList->ZIndex())>::max());
aLists.PositionedDescendants()->AppendToTop(wrapList);

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

@ -789,7 +789,7 @@ nsBulletFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
DO_GLOBAL_REFLOW_COUNT_DSP("nsBulletFrame");
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayBullet(aBuilder, this));
MakeDisplayItem<nsDisplayBullet>(aBuilder, this));
}
Maybe<BulletRenderer>

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

@ -470,11 +470,11 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
aLists.BorderBackground()->AppendToTop(
new (aBuilder) nsDisplayCanvasBackgroundColor(aBuilder, this));
MakeDisplayItem<nsDisplayCanvasBackgroundColor>(aBuilder, this));
if (isThemed) {
aLists.BorderBackground()->AppendToTop(
new (aBuilder) nsDisplayCanvasThemedBackground(aBuilder, this));
MakeDisplayItem<nsDisplayCanvasThemedBackground>(aBuilder, this));
return;
}
@ -528,14 +528,14 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
{
DisplayListClipState::AutoSaveRestore bgImageClip(aBuilder);
bgImageClip.Clear();
bgItem = new (aBuilder) nsDisplayCanvasBackgroundImage(bgData);
bgItem = MakeDisplayItem<nsDisplayCanvasBackgroundImage>(aBuilder, bgData);
bgItem->SetDependentFrame(aBuilder, dependentFrame);
}
thisItemList.AppendToTop(
nsDisplayFixedPosition::CreateForFixedBackground(aBuilder, this, bgItem, i));
} else {
nsDisplayCanvasBackgroundImage* bgItem = new (aBuilder) nsDisplayCanvasBackgroundImage(bgData);
nsDisplayCanvasBackgroundImage* bgItem = MakeDisplayItem<nsDisplayCanvasBackgroundImage>(aBuilder, bgData);
bgItem->SetDependentFrame(aBuilder, dependentFrame);
thisItemList.AppendToTop(bgItem);
}
@ -543,9 +543,9 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (layers.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
DisplayListClipState::AutoSaveRestore blendClip(aBuilder);
thisItemList.AppendToTop(
new (aBuilder) nsDisplayBlendMode(aBuilder, this, &thisItemList,
layers.mLayers[i].mBlendMode,
thisItemASR, i + 1));
MakeDisplayItem<nsDisplayBlendMode>(aBuilder, this, &thisItemList,
layers.mLayers[i].mBlendMode,
thisItemASR, i + 1));
}
aLists.BorderBackground()->AppendToTop(&thisItemList);
}
@ -591,8 +591,8 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (!StyleVisibility()->IsVisible())
return;
aLists.Outlines()->AppendToTop(new (aBuilder)
nsDisplayCanvasFocus(aBuilder, this));
aLists.Outlines()->AppendToTop(
MakeDisplayItem<nsDisplayCanvasFocus>(aBuilder, this));
}
void

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

@ -190,8 +190,8 @@ public:
class nsDisplayCanvasBackgroundImage : public nsDisplayBackgroundImage {
public:
explicit nsDisplayCanvasBackgroundImage(const InitData& aInitData)
: nsDisplayBackgroundImage(aInitData)
explicit nsDisplayCanvasBackgroundImage(nsDisplayListBuilder* aBuilder, const InitData& aInitData)
: nsDisplayBackgroundImage(aBuilder, aInitData)
{
}

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

@ -1280,7 +1280,7 @@ nsColumnSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (IsVisibleForPainting(aBuilder)) {
aLists.BorderBackground()->
AppendToTop(new (aBuilder) nsDisplayColumnRule(aBuilder, this));
AppendToTop(MakeDisplayItem<nsDisplayColumnRule>(aBuilder, this));
}
// Our children won't have backgrounds so it doesn't matter where we put them.

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

@ -2318,8 +2318,8 @@ nsFrame::DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
return;
}
aList->AppendToTop(new (aBuilder)
nsDisplaySelectionOverlay(aBuilder, this, selectionValue));
aList->AppendToTop(
MakeDisplayItem<nsDisplaySelectionOverlay>(aBuilder, this, selectionValue));
}
void
@ -2331,7 +2331,7 @@ nsFrame::DisplayOutlineUnconditional(nsDisplayListBuilder* aBuilder,
}
aLists.Outlines()->AppendToTop(
new (aBuilder) nsDisplayOutline(aBuilder, this));
MakeDisplayItem<nsDisplayOutline>(aBuilder, this));
}
void
@ -2351,7 +2351,7 @@ nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder,
if (!IsVisibleForPainting(aBuilder))
return;
aList->AppendToTop(new (aBuilder) nsDisplayCaret(aBuilder, this));
aList->AppendToTop(MakeDisplayItem<nsDisplayCaret>(aBuilder, this));
}
nscolor
@ -2390,23 +2390,23 @@ nsFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
nsCSSShadowArray* shadows = StyleEffects()->mBoxShadow;
if (shadows && shadows->HasShadowWithInset(false)) {
aLists.BorderBackground()->AppendToTop(new (aBuilder)
nsDisplayBoxShadowOuter(aBuilder, this));
aLists.BorderBackground()->AppendToTop(
MakeDisplayItem<nsDisplayBoxShadowOuter>(aBuilder, this));
}
bool bgIsThemed = DisplayBackgroundUnconditional(aBuilder, aLists,
aForceBackground);
if (shadows && shadows->HasShadowWithInset(true)) {
aLists.BorderBackground()->AppendToTop(new (aBuilder)
nsDisplayBoxShadowInner(aBuilder, this));
aLists.BorderBackground()->AppendToTop(
MakeDisplayItem<nsDisplayBoxShadowInner>(aBuilder, this));
}
// If there's a themed background, we should not create a border item.
// It won't be rendered.
if (!bgIsThemed && StyleBorder()->HasBorder()) {
aLists.BorderBackground()->AppendToTop(new (aBuilder)
nsDisplayBorder(aBuilder, this));
aLists.BorderBackground()->AppendToTop(
MakeDisplayItem<nsDisplayBorder>(aBuilder, this));
}
DisplayOutlineUnconditional(aBuilder, aLists);
@ -2541,16 +2541,16 @@ DisplayDebugBorders(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
// Draw a border around the child
// REVIEW: From nsContainerFrame::PaintChild
if (nsFrame::GetShowFrameBorders() && !aFrame->GetRect().IsEmpty()) {
aLists.Outlines()->AppendToTop(new (aBuilder)
nsDisplayGeneric(aBuilder, aFrame, PaintDebugBorder, "DebugBorder",
DisplayItemType::TYPE_DEBUG_BORDER));
aLists.Outlines()->AppendToTop(
MakeDisplayItem<nsDisplayGeneric>(aBuilder, aFrame, PaintDebugBorder, "DebugBorder",
DisplayItemType::TYPE_DEBUG_BORDER));
}
// Draw a border around the current event target
if (nsFrame::GetShowEventTargetFrameBorder() &&
aFrame->PresShell()->GetDrawEventTargetFrame() == aFrame) {
aLists.Outlines()->AppendToTop(new (aBuilder)
nsDisplayGeneric(aBuilder, aFrame, PaintEventTargetBorder, "EventTargetBorder",
DisplayItemType::TYPE_EVENT_TARGET_BORDER));
aLists.Outlines()->AppendToTop(
MakeDisplayItem<nsDisplayGeneric>(aBuilder, aFrame, PaintEventTargetBorder, "EventTargetBorder",
DisplayItemType::TYPE_EVENT_TARGET_BORDER));
}
}
#endif
@ -2654,7 +2654,7 @@ WrapSeparatorTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
int aIndex) {
if (!aSource->IsEmpty()) {
nsDisplayTransform *sepIdItem =
new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aSource,
MakeDisplayItem<nsDisplayTransform>(aBuilder, aFrame, aSource,
aBuilder->GetVisibleRect(), Matrix4x4(), aIndex);
sepIdItem->SetNoExtendContext();
aTarget->AppendToTop(sepIdItem);
@ -3031,7 +3031,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
nsDisplayLayerEventRegions* eventRegions = nullptr;
if (aBuilder->IsBuildingLayerEventRegions()) {
eventRegions = new (aBuilder) nsDisplayLayerEventRegions(aBuilder, this);
eventRegions = MakeDisplayItem<nsDisplayLayerEventRegions>(aBuilder, this);
eventRegions->AddFrame(aBuilder, this);
aBuilder->SetLayerEventRegions(eventRegions);
}
@ -3072,7 +3072,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
if (eventRegions) {
eventRegions->Destroy(aBuilder);
eventRegions = new (aBuilder) nsDisplayLayerEventRegions(aBuilder, this);
eventRegions = MakeDisplayItem<nsDisplayLayerEventRegions>(aBuilder, this);
eventRegions->AddFrame(aBuilder, this);
aBuilder->SetLayerEventRegions(eventRegions);
}
@ -3116,7 +3116,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
if (hasOverrideDirtyRect && gfxPrefs::LayoutDisplayListShowArea()) {
nsDisplaySolidColor* color =
new (aBuilder) nsDisplaySolidColor(aBuilder, this,
MakeDisplayItem<nsDisplaySolidColor>(aBuilder, this,
dirtyRect + aBuilder->GetCurrentFrameOffsetToReferenceFrame(),
NS_RGBA(255, 0, 0, 64), false);
color->SetOverrideZIndex(INT32_MAX);
@ -3219,7 +3219,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
/* List now emptied, so add the new list to the top. */
resultList.AppendToTop(
new (aBuilder) nsDisplayFilter(aBuilder, this, &resultList,
MakeDisplayItem<nsDisplayFilter>(aBuilder, this, &resultList,
handleOpacity));
}
@ -3239,7 +3239,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
: containerItemASR;
/* List now emptied, so add the new list to the top. */
resultList.AppendToTop(
new (aBuilder) nsDisplayMask(aBuilder, this, &resultList, !useOpacity,
MakeDisplayItem<nsDisplayMask>(aBuilder, this, &resultList, !useOpacity,
maskASR));
}
@ -3261,7 +3261,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
// all descendant content, but some should not be clipped.
DisplayListClipState::AutoSaveRestore opacityClipState(aBuilder);
resultList.AppendToTop(
new (aBuilder) nsDisplayOpacity(aBuilder, this, &resultList,
MakeDisplayItem<nsDisplayOpacity>(aBuilder, this, &resultList,
containerItemASR,
opacityItemForEventsAndPluginsOnly));
if (aCreatedContainerItem) {
@ -3327,7 +3327,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
GetOffsetToCrossDoc(outerReferenceFrame));
nsDisplayTransform *transformItem =
new (aBuilder) nsDisplayTransform(aBuilder, this,
MakeDisplayItem<nsDisplayTransform>(aBuilder, this,
&resultList, visibleRect, 0,
allowAsyncAnimation);
resultList.AppendToTop(transformItem);
@ -3337,7 +3337,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
clipState.Restore();
}
resultList.AppendToTop(
new (aBuilder) nsDisplayPerspective(
MakeDisplayItem<nsDisplayPerspective>(
aBuilder, this,
GetContainingBlock(0, disp)->GetContent()->GetPrimaryFrame(),
&resultList));
@ -3351,7 +3351,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
if (clipCapturedBy == ContainerItemType::eOwnLayerForTransformWithRoundedClip) {
clipState.Restore();
resultList.AppendToTop(
new (aBuilder) nsDisplayOwnLayer(aBuilder, this, &resultList,
MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, this, &resultList,
aBuilder->CurrentActiveScrolledRoot(),
nsDisplayOwnLayerFlags::eNone,
mozilla::layers::FrameMetrics::NULL_SCROLL_ID,
@ -3374,7 +3374,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
const ActiveScrolledRoot* fixedASR =
ActiveScrolledRoot::PickAncestor(containerItemASR, aBuilder->CurrentActiveScrolledRoot());
resultList.AppendToTop(
new (aBuilder) nsDisplayFixedPosition(aBuilder, this, &resultList, fixedASR));
MakeDisplayItem<nsDisplayFixedPosition>(aBuilder, this, &resultList, fixedASR));
if (aCreatedContainerItem) {
*aCreatedContainerItem = true;
}
@ -3390,7 +3390,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
const ActiveScrolledRoot* stickyASR =
ActiveScrolledRoot::PickAncestor(containerItemASR, aBuilder->CurrentActiveScrolledRoot());
resultList.AppendToTop(
new (aBuilder) nsDisplayStickyPosition(aBuilder, this, &resultList, stickyASR));
MakeDisplayItem<nsDisplayStickyPosition>(aBuilder, this, &resultList, stickyASR));
if (aCreatedContainerItem) {
*aCreatedContainerItem = true;
}
@ -3404,7 +3404,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
if (useBlendMode) {
DisplayListClipState::AutoSaveRestore blendModeClipState(aBuilder);
resultList.AppendToTop(
new (aBuilder) nsDisplayBlendMode(aBuilder, this, &resultList,
MakeDisplayItem<nsDisplayBlendMode>(aBuilder, this, &resultList,
effects->mMixBlendMode,
containerItemASR));
if (aCreatedContainerItem) {
@ -3436,7 +3436,7 @@ WrapInWrapList(nsDisplayListBuilder* aBuilder,
// Clear clip rect for the construction of the items below. Since we're
// clipping all their contents, they themselves don't need to be clipped.
return new (aBuilder) nsDisplayWrapList(aBuilder, aFrame, aList, aContainerASR, true);
return MakeDisplayItem<nsDisplayWrapList>(aBuilder, aFrame, aList, aContainerASR, true);
}
/**
@ -3777,7 +3777,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
// make sure we accumulate event regions for its layer.
if (buildingForChild.IsAnimatedGeometryRoot() || isPositioned) {
nsDisplayLayerEventRegions* eventRegions =
new (aBuilder) nsDisplayLayerEventRegions(aBuilder, child);
MakeDisplayItem<nsDisplayLayerEventRegions>(aBuilder, child);
eventRegions->AddFrame(aBuilder, child);
aBuilder->SetLayerEventRegions(eventRegions);
@ -10966,8 +10966,8 @@ nsIFrame::CreateOwnLayerIfNeeded(nsDisplayListBuilder* aBuilder,
if (GetContent() &&
GetContent()->IsXULElement() &&
GetContent()->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::layer)) {
aList->AppendToTop(new (aBuilder)
nsDisplayOwnLayer(aBuilder, this, aList, aBuilder->CurrentActiveScrolledRoot()));
aList->AppendToTop(
MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, this, aList, aBuilder->CurrentActiveScrolledRoot()));
if (aCreatedContainerItem) {
*aCreatedContainerItem = true;
}

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

@ -680,7 +680,7 @@ nsHTMLFramesetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (mDragger && aBuilder->IsForEventDelivery()) {
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayEventReceiver(aBuilder, this));
MakeDisplayItem<nsDisplayEventReceiver>(aBuilder, this));
}
}
@ -1425,7 +1425,7 @@ nsHTMLFramesetBorderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists)
{
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayFramesetBorder(aBuilder, this));
MakeDisplayItem<nsDisplayFramesetBorder>(aBuilder, this));
}
void nsHTMLFramesetBorderFrame::PaintBorder(DrawTarget* aDrawTarget,
@ -1636,5 +1636,5 @@ nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists)
{
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayFramesetBlank(aBuilder, this));
MakeDisplayItem<nsDisplayFramesetBlank>(aBuilder, this));
}

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

@ -3072,9 +3072,9 @@ AppendToTop(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists,
flags |= nsDisplayOwnLayerFlags::eScrollbarContainer;
}
newItem = new (aBuilder) nsDisplayOwnLayer(aBuilder, aSourceFrame, aSource, asr, flags, scrollTarget);
newItem = MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, aSourceFrame, aSource, asr, flags, scrollTarget);
} else {
newItem = new (aBuilder) nsDisplayWrapList(aBuilder, aSourceFrame, aSource, asr);
newItem = MakeDisplayItem<nsDisplayWrapList>(aBuilder, aSourceFrame, aSource, asr);
}
if (aFlags & APPEND_POSITIONED) {
@ -3618,9 +3618,9 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (dirtyRectHasBeenOverriden && gfxPrefs::LayoutDisplayListShowArea()) {
nsDisplaySolidColor* color =
new (aBuilder) nsDisplaySolidColor(aBuilder, mOuter,
dirtyRect + aBuilder->GetCurrentFrameOffsetToReferenceFrame(),
NS_RGBA(0, 0, 255, 64), false);
MakeDisplayItem<nsDisplaySolidColor>(aBuilder, mOuter,
dirtyRect + aBuilder->GetCurrentFrameOffsetToReferenceFrame(),
NS_RGBA(0, 0, 255, 64), false);
color->SetOverrideZIndex(INT32_MAX);
scrolledContent.PositionedDescendants()->AppendToTop(color);
}
@ -3695,13 +3695,13 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
info |= CompositorHitTestInfo::eRequiresTargetConfirmation;
}
nsDisplayCompositorHitTestInfo* hitInfo =
new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, mScrolledFrame, info, 1,
MakeDisplayItem<nsDisplayCompositorHitTestInfo>(aBuilder, mScrolledFrame, info, 1,
Some(mScrollPort + aBuilder->ToReferenceFrame(mOuter)));
AppendInternalItemToTop(scrolledContent, hitInfo, zIndex);
}
if (aBuilder->IsBuildingLayerEventRegions()) {
nsDisplayLayerEventRegions* inactiveRegionItem =
new (aBuilder) nsDisplayLayerEventRegions(aBuilder, mScrolledFrame, 1);
MakeDisplayItem<nsDisplayLayerEventRegions>(aBuilder, mScrolledFrame, 1);
inactiveRegionItem->AddInactiveScrollPort(mScrolledFrame, mScrollPort + aBuilder->ToReferenceFrame(mOuter));
AppendInternalItemToTop(scrolledContent, inactiveRegionItem, zIndex);
}
@ -3709,7 +3709,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (aBuilder->ShouldBuildScrollInfoItemsForHoisting()) {
aBuilder->AppendNewScrollInfoItemForHoisting(
new (aBuilder) nsDisplayScrollInfoLayer(aBuilder, mScrolledFrame,
MakeDisplayItem<nsDisplayScrollInfoLayer>(aBuilder, mScrolledFrame,
mOuter));
}
}

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

@ -482,7 +482,7 @@ nsHTMLCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
clip(aBuilder, this, clipFlags);
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayCanvas(aBuilder, this));
MakeDisplayItem<nsDisplayCanvas>(aBuilder, this));
DisplaySelectionOverlay(aBuilder, aLists.Content(),
nsISelectionDisplay::DISPLAY_IMAGES);

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

@ -1849,8 +1849,8 @@ nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (!imageOK || !mImage || !SizeIsAvailable(currentRequest)) {
// No image yet, or image load failed. Draw the alt-text and an icon
// indicating the status
aLists.Content()->AppendToTop(new (aBuilder)
nsDisplayAltFeedback(aBuilder, this));
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayAltFeedback>(aBuilder, this));
// This image is visible (we are being asked to paint it) but it's not
// decoded yet. And we are not going to ask the image to draw, so this
@ -1867,8 +1867,8 @@ nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
} else {
aLists.Content()->AppendToTop(new (aBuilder)
nsDisplayImage(aBuilder, this, mImage, mPrevImage));
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayImage>(aBuilder, this, mImage, mPrevImage));
// If we were previously displaying an icon, we're not anymore
if (mDisplayingIcon) {
@ -1878,9 +1878,9 @@ nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
#ifdef DEBUG
if (GetShowFrameBorders() && GetImageMap()) {
aLists.Outlines()->AppendToTop(new (aBuilder)
nsDisplayGeneric(aBuilder, this, PaintDebugImageMap, "DebugImageMap",
DisplayItemType::TYPE_DEBUG_IMAGE_MAP));
aLists.Outlines()->AppendToTop(
MakeDisplayItem<nsDisplayGeneric>(aBuilder, this, PaintDebugImageMap, "DebugImageMap",
DisplayItemType::TYPE_DEBUG_IMAGE_MAP));
}
#endif
}

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

@ -586,14 +586,14 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
*aBuilder, content, child, backgroundRect, NS_RGBA(0,0,0,0));
}
content.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, child,
content.AppendToTop(MakeDisplayItem<nsDisplayTransform>(aBuilder, child,
&content, content.GetVisibleRect(), ::ComputePageTransform));
set.Content()->AppendToTop(&content);
if (PresContext()->IsRootPaginatedDocument()) {
set.Content()->AppendToTop(new (aBuilder)
nsDisplayHeaderFooter(aBuilder, this));
set.Content()->AppendToTop(
MakeDisplayItem<nsDisplayHeaderFooter>(aBuilder, this));
}
set.MoveTo(aLists);

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

@ -273,9 +273,9 @@ nsPlaceholderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
#ifdef DEBUG
if (GetShowFrameBorders()) {
aLists.Outlines()->AppendToTop(
new (aBuilder) nsDisplayGeneric(aBuilder, this, PaintDebugPlaceholder,
"DebugPlaceholder",
DisplayItemType::TYPE_DEBUG_PLACEHOLDER));
MakeDisplayItem<nsDisplayGeneric>(aBuilder, this, PaintDebugPlaceholder,
"DebugPlaceholder",
DisplayItemType::TYPE_DEBUG_PLACEHOLDER));
}
#endif
}

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

@ -1187,9 +1187,9 @@ nsPluginFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// determine if we are printing
if (type == nsPresContext::eContext_Print) {
aLists.Content()->AppendToTop(new (aBuilder)
nsDisplayGeneric(aBuilder, this, PaintPrintPlugin, "PrintPlugin",
DisplayItemType::TYPE_PRINT_PLUGIN));
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayGeneric>(aBuilder, this, PaintPrintPlugin, "PrintPlugin",
DisplayItemType::TYPE_PRINT_PLUGIN));
} else {
LayerState state = GetLayerState(aBuilder, nullptr);
if (state == LAYER_INACTIVE &&
@ -1199,12 +1199,12 @@ nsPluginFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (aBuilder->IsPaintingToWindow() &&
state == LAYER_ACTIVE &&
IsTransparentMode()) {
aLists.Content()->AppendToTop(new (aBuilder)
nsDisplayPluginReadback(aBuilder, this));
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayPluginReadback>(aBuilder, this));
}
aLists.Content()->AppendToTop(new (aBuilder)
nsDisplayPlugin(aBuilder, this));
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayPlugin>(aBuilder, this));
}
}

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

@ -747,9 +747,9 @@ nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
content.AppendToTop(new (aBuilder)
nsDisplayTransform(aBuilder, this, &content, content.GetVisibleRect(),
::ComputePageSequenceTransform));
content.AppendToTop(
MakeDisplayItem<nsDisplayTransform>(aBuilder, this, &content, content.GetVisibleRect(),
::ComputePageSequenceTransform));
aLists.Content()->AppendToTop(&content);
}

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

@ -318,7 +318,7 @@ WrapBackgroundColorInOwnLayer(nsDisplayListBuilder* aBuilder,
if (item->GetType() == DisplayItemType::TYPE_BACKGROUND_COLOR) {
nsDisplayList tmpList;
tmpList.AppendToTop(item);
item = new (aBuilder) nsDisplayOwnLayer(aBuilder, aFrame, &tmpList, aBuilder->CurrentActiveScrolledRoot());
item = MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, aFrame, &tmpList, aBuilder->CurrentActiveScrolledRoot());
}
tempItems.AppendToTop(item);
}
@ -558,7 +558,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
zoomFlags |= nsDisplayOwnLayerFlags::eGenerateScrollableLayer;
}
nsDisplayZoom* zoomItem =
new (aBuilder) nsDisplayZoom(aBuilder, subdocRootFrame, &childItems,
MakeDisplayItem<nsDisplayZoom>(aBuilder, subdocRootFrame, &childItems,
subdocAPD, parentAPD, zoomFlags);
childItems.AppendToTop(zoomItem);
needsOwnLayer = false;
@ -570,14 +570,14 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
if (constructResolutionItem) {
nsDisplayResolution* resolutionItem =
new (aBuilder) nsDisplayResolution(aBuilder, subdocRootFrame, &childItems,
flags);
MakeDisplayItem<nsDisplayResolution>(aBuilder, subdocRootFrame, &childItems,
flags);
childItems.AppendToTop(resolutionItem);
needsOwnLayer = false;
}
// We always want top level content documents to be in their own layer.
nsDisplaySubDocument* layerItem = new (aBuilder) nsDisplaySubDocument(
nsDisplaySubDocument* layerItem = MakeDisplayItem<nsDisplaySubDocument>(
aBuilder, subdocRootFrame ? subdocRootFrame : this, this,
&childItems, flags);
childItems.AppendToTop(layerItem);

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

@ -5237,7 +5237,7 @@ nsTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayText(aBuilder, this, isSelected));
MakeDisplayItem<nsDisplayText>(aBuilder, this, isSelected));
}
static nsIFrame*

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

@ -570,7 +570,7 @@ nsVideoFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (HasVideoElement() && !shouldDisplayPoster) {
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayVideo(aBuilder, this));
MakeDisplayItem<nsDisplayVideo>(aBuilder, this));
}
// Add child frames to display list. We expect various children,

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

@ -294,7 +294,7 @@ RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
clipState.ClipContentDescendants(bounds);
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayRemote(aBuilder, aFrame, this));
MakeDisplayItem<nsDisplayRemote>(aBuilder, aFrame, this));
}
void

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

@ -1988,8 +1988,8 @@ nsMathMLChar::Display(nsDisplayListBuilder* aBuilder,
// purposes. Normally, users will set the background on the container frame.
// paint the selection background -- beware MathML frames overlap a lot
if (aSelectedRect && !aSelectedRect->IsEmpty()) {
aLists.BorderBackground()->AppendToTop(new (aBuilder)
nsDisplayMathMLSelectionRect(aBuilder, aForFrame, *aSelectedRect));
aLists.BorderBackground()->AppendToTop(
MakeDisplayItem<nsDisplayMathMLSelectionRect>(aBuilder, aForFrame, *aSelectedRect));
}
else if (mRect.width && mRect.height) {
if (styleContext != parentContext &&
@ -2004,15 +2004,15 @@ nsMathMLChar::Display(nsDisplayListBuilder* aBuilder,
#if defined(DEBUG) && defined(SHOW_BOUNDING_BOX)
// for visual debug
aLists.BorderBackground()->AppendToTop(new (aBuilder)
nsDisplayMathMLCharDebug(aBuilder, aForFrame, mRect));
aLists.BorderBackground()->AppendToTop(
MakeDisplayItem<nsDisplayMathMLCharDebug>(aBuilder, aForFrame, mRect));
#endif
}
aLists.Content()->AppendToTop(new (aBuilder)
nsDisplayMathMLCharForeground(aBuilder, aForFrame, this,
aIndex,
aSelectedRect &&
!aSelectedRect->IsEmpty()));
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayMathMLCharForeground>(aBuilder, aForFrame, this,
aIndex,
aSelectedRect &&
!aSelectedRect->IsEmpty()));
}
void

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

@ -625,7 +625,7 @@ nsMathMLContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
return;
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayMathMLError(aBuilder, this));
MakeDisplayItem<nsDisplayMathMLError>(aBuilder, this));
return;
}

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

@ -318,8 +318,8 @@ nsMathMLFrame::DisplayBoundingMetrics(nsDisplayListBuilder* aBuilder,
nscoord w = aMetrics.rightBearing - aMetrics.leftBearing;
nscoord h = aMetrics.ascent + aMetrics.descent;
aLists.Content()->AppendToTop(new (aBuilder)
nsDisplayMathMLBoundingMetrics(aBuilder, aFrame, nsRect(x,y,w,h)));
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayMathMLBoundingMetrics>(aBuilder, aFrame, nsRect(x,y,w,h)));
}
#endif
@ -370,8 +370,8 @@ nsMathMLFrame::DisplayBar(nsDisplayListBuilder* aBuilder,
if (!aFrame->StyleVisibility()->IsVisible() || aRect.IsEmpty())
return;
aLists.Content()->AppendToTop(new (aBuilder)
nsDisplayMathMLBar(aBuilder, aFrame, aRect, aIndex));
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayMathMLBar>(aBuilder, aFrame, aRect, aIndex));
}
void

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