зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
f042b243a8
|
@ -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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче