Merge inbound to mozilla-central. a=merge

This commit is contained in:
Bogdan Tara 2018-01-21 11:51:29 +02:00
Родитель 12fd9b7ae9 f3708770fd
Коммит e9a067a401
65 изменённых файлов: 5030 добавлений и 484 удалений

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

@ -261,9 +261,6 @@ function getClipboardHelper() {
}
const gClipboardHelper = getClipboardHelper();
// Interface for image loading content
const nsIImageLoadingContent = Components.interfaces.nsIImageLoadingContent;
// namespaces, don't need all of these yet...
const XLinkNS = "http://www.w3.org/1999/xlink";
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";

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

@ -18,7 +18,6 @@ add_task(async function testSources() {
let tabs = await browser.tabs.query({active: true, currentWindow: true});
await browser.pageAction.show(tabs[0].id);
browser.test.sendMessage("page-action-shown");
browser.pageAction.onClicked.addListener(request);
browser.browserAction.onClicked.addListener(request);
@ -29,6 +28,8 @@ add_task(async function testSources() {
contexts: ["page"],
});
browser.contextMenus.onClicked.addListener(request);
browser.test.sendMessage("actions-ready");
},
manifest: {
@ -49,8 +50,8 @@ add_task(async function testSources() {
CustomizableUI.removeWidgetFromArea("sidebar-button");
await extension.startup();
await extension.awaitMessage("actions-ready");
await extension.awaitMessage("page-action-shown");
clickPageAction(extension);
await check("page action click");

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

@ -454,8 +454,7 @@ class ContextMenu {
return true;
}
let request = aTarget.QueryInterface(Ci.nsIImageLoadingContent)
.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
let request = aTarget.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
if (!request) {
return true;

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

@ -9,32 +9,34 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
Task.spawn(function* () {
let doc = aPanel.panelWin.document;
let panel = doc.getElementById("instruments-pane");
let button = doc.getElementById("instruments-pane-toggle");
ok(panel.classList.contains("pane-collapsed"),
"The instruments panel is initially in collapsed state");
async function test() {
let [aTab,, aPanel] = await initDebugger(TAB_URL);
yield togglePane(button, "Press on the toggle button to expand", panel, "VK_RETURN");
ok(!panel.classList.contains("pane-collapsed"),
"The instruments panel is in the expanded state");
let doc = aPanel.panelWin.document;
let panel = doc.getElementById("instruments-pane");
let button = doc.getElementById("instruments-pane-toggle");
ok(panel.classList.contains("pane-collapsed"),
"The instruments panel is initially in collapsed state");
yield togglePane(button, "Press on the toggle button to collapse", panel, "VK_SPACE");
ok(panel.classList.contains("pane-collapsed"),
"The instruments panel is in the collapsed state");
await togglePane(button, "Press on the toggle button to expand", panel, "VK_RETURN");
ok(!panel.classList.contains("pane-collapsed"),
"The instruments panel is in the expanded state");
closeDebuggerAndFinish(aPanel);
});
});
await togglePane(button, "Press on the toggle button to collapse", panel, "VK_SPACE");
ok(panel.classList.contains("pane-collapsed"),
"The instruments panel is in the collapsed state");
closeDebuggerAndFinish(aPanel);
}
function* togglePane(button, message, pane, keycode) {
async function togglePane(button, message, pane, keycode) {
let onTransitionEnd = once(pane, "transitionend");
info(message);
button.focus();
EventUtils.synthesizeKey(keycode, {});
yield onTransitionEnd;
await onTransitionEnd;
// Wait for the next event tick to make sure all transitionend event
// handlers finish.
await waitForTick();
}

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

@ -11,16 +11,16 @@ const TEST_URI = "data:text/html;charset=utf-8,<head>" +
"ets.css'></head><body><div></div><span></span></body>";
const {TreeWidget} = require("devtools/client/shared/widgets/TreeWidget");
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
add_task(async function () {
await addTab("about:blank");
let [host, win, doc] = await createHost("bottom", TEST_URI);
let tree = new TreeWidget(doc.querySelector("div"), {
defaultType: "store"
});
populateTree(tree, doc);
yield testKeyboardInteraction(tree, win);
await testKeyboardInteraction(tree, win);
tree.destroy();
host.destroy();
@ -83,7 +83,7 @@ function click(node) {
/**
* Tests if pressing navigation keys on the tree items does the expected behavior
*/
function* testKeyboardInteraction(tree, win) {
async function testKeyboardInteraction(tree, win) {
info("Testing keyboard interaction with the tree");
let event;
let pass = (e, d, a) => event.resolve([e, d, a]);
@ -91,9 +91,12 @@ function* testKeyboardInteraction(tree, win) {
info("clicking on first top level item");
let node = tree.root.children.firstChild.firstChild;
event = defer();
// The select event handler will be called before the click event hasn't
// fully finished, so wait for both of them.
let clicked = once(node, "click");
tree.once("select", pass);
click(node);
yield event.promise;
await Promise.all([event.promise, clicked]);
node = tree.root.children.firstChild.nextSibling.firstChild;
// node should not have selected class
ok(!node.classList.contains("theme-selected"), "Node should not have selected class");
@ -103,7 +106,7 @@ function* testKeyboardInteraction(tree, win) {
event = defer();
tree.once("select", pass);
EventUtils.sendKey("DOWN", win);
let [name, data, attachment] = yield event.promise;
let [name, data, attachment] = await event.promise;
is(name, "select", "Select event was fired after pressing down");
is(data[0], "level1", "Correct item was selected after pressing down");
ok(!attachment, "null attachment was emitted");
@ -114,7 +117,7 @@ function* testKeyboardInteraction(tree, win) {
event = defer();
tree.once("select", pass);
EventUtils.sendKey("DOWN", win);
[name, data, attachment] = yield event.promise;
[name, data, attachment] = await event.promise;
is(data.length, 2, "Correct level item was selected after second down keypress");
is(data[0], "level1", "Correct parent level");
is(data[1], "level2", "Correct second level");
@ -123,7 +126,7 @@ function* testKeyboardInteraction(tree, win) {
event = defer();
tree.once("select", pass);
EventUtils.sendKey("DOWN", win);
[name, data, attachment] = yield event.promise;
[name, data, attachment] = await event.promise;
is(data.length, 3, "Correct level item was selected after third down keypress");
is(data[0], "level1", "Correct parent level");
is(data[1], "level2", "Correct second level");
@ -133,7 +136,7 @@ function* testKeyboardInteraction(tree, win) {
event = defer();
tree.once("select", pass);
EventUtils.sendKey("DOWN", win);
[name, data, attachment] = yield event.promise;
[name, data, attachment] = await event.promise;
is(data.length, 2, "Correct level item was selected after fourth down keypress");
is(data[0], "level1", "Correct parent level");
is(data[1], "level2-1", "Correct second level");
@ -149,7 +152,7 @@ function* testKeyboardInteraction(tree, win) {
node = tree._selectedLabel;
ok(node.hasAttribute("expanded"), "Item is expanded before left keypress");
EventUtils.sendKey("LEFT", win);
yield event.promise;
await event.promise;
ok(!node.hasAttribute("expanded"), "Item is not expanded after left keypress");
@ -162,7 +165,7 @@ function* testKeyboardInteraction(tree, win) {
node = tree.root.children.firstChild.nextSibling.firstChild;
ok(node.hasAttribute("expanded"), "Parent is expanded");
EventUtils.sendKey("LEFT", win);
[name, data] = yield event.promise;
[name, data] = await event.promise;
is(data.length, 3, "Correct level item was selected after second left keypress");
is(data[0], "level1", "Correct parent level");
is(data[1], "level2", "Correct second level");
@ -175,7 +178,7 @@ function* testKeyboardInteraction(tree, win) {
event = defer();
tree.once("select", pass);
EventUtils.sendKey("DOWN", win);
[name, data, attachment] = yield event.promise;
[name, data, attachment] = await event.promise;
is(data.length, 2, "Correct level item was selected after fifth down keypress");
is(data[0], "level1", "Correct parent level");
is(data[1], "level2-1", "Correct second level");
@ -190,7 +193,7 @@ function* testKeyboardInteraction(tree, win) {
node = tree._selectedLabel;
ok(node.hasAttribute("expanded"), "Item is expanded before left keypress");
EventUtils.sendKey("LEFT", win);
yield event.promise;
await event.promise;
ok(!node.hasAttribute("expanded"), "Item is collapsed after left keypress");
// pressing right should expand this now.
@ -203,7 +206,7 @@ function* testKeyboardInteraction(tree, win) {
node = tree._selectedLabel;
ok(!node.hasAttribute("expanded"), "Item is collapsed before right keypress");
EventUtils.sendKey("RIGHT", win);
yield event.promise;
await event.promise;
ok(node.hasAttribute("expanded"), "Item is expanded after right keypress");
// selecting last item node to test edge navigation case
@ -217,7 +220,7 @@ function* testKeyboardInteraction(tree, win) {
}, {once: true});
info("Pressing down key on last item of the tree");
EventUtils.sendKey("DOWN", win);
yield event.promise;
await event.promise;
ok(tree.isSelected(["level1.1", "level2", "level3"]),
"Last item is still selected after pressing down on last item of the tree");

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

@ -7,13 +7,13 @@
"use strict";
add_task(function* () {
add_task(async function () {
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
"test/test-console.html";
yield loadTab(TEST_URI);
await loadTab(TEST_URI);
let hud = yield openConsole();
let hud = await openConsole();
ok(hud, "Web Console opened");
info("dump some spew into the console for scrolling");
@ -21,7 +21,7 @@ add_task(function* () {
"console.log('foobarz' + i);" +
"}})();");
yield waitForMessages({
await waitForMessages({
webconsole: hud,
messages: [{
text: "foobarz99",
@ -61,7 +61,11 @@ add_task(function* () {
}
synthesizeKeyShortcut(clearShortcut);
});
yield hud.jsterm.once("messages-cleared");
await hud.jsterm.once("messages-cleared");
// Wait for the next event tick to make sure keyup for the shortcut above
// finishes. Otherwise the 2 shortcuts are mixed.
await new Promise(executeSoon);
is(hud.outputNode.textContent.indexOf("foobarz1"), -1, "output cleared");
is(hud.jsterm.inputNode.getAttribute("focused"), "true",

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

@ -8,16 +8,16 @@
"use strict";
add_task(function* () {
add_task(async function () {
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
"test/test-console-clear.html";
yield loadTab(TEST_URI);
let hud = yield openConsole();
await loadTab(TEST_URI);
let hud = await openConsole();
ok(hud, "Web Console opened");
info("Check the console.clear() done on page load has been processed.");
yield waitForLog("Console was cleared", hud);
await waitForLog("Console was cleared", hud);
ok(hud.outputNode.textContent.includes("Console was cleared"),
"console.clear() message is displayed");
ok(!hud.outputNode.textContent.includes("log1"), "log1 not displayed");
@ -29,8 +29,8 @@ add_task(function* () {
content.wrappedJSObject.console.log("log4");
});
yield waitForLog("log3", hud);
yield waitForLog("log4", hud);
await waitForLog("log3", hud);
await waitForLog("log4", hud);
ok(hud.outputNode.textContent.includes("Console was cleared"),
"console.clear() message is still displayed");
@ -38,7 +38,7 @@ add_task(function* () {
ok(hud.outputNode.textContent.includes("log4"), "log4 is displayed");
info("Open the variables view sidebar for 'objFromPage'");
yield openSidebar("objFromPage", { a: 1 }, hud);
await openSidebar("objFromPage", { a: 1 }, hud);
let sidebarClosed = hud.jsterm.once("sidebar-closed");
info("Call console.clear from the page");
@ -47,9 +47,13 @@ add_task(function* () {
});
// Cannot wait for "Console was cleared" here because such a message is
// already present and would yield immediately.
// already present and would resolve immediately.
info("Wait for variables view sidebar to be closed after console.clear()");
yield sidebarClosed;
await sidebarClosed;
// Wait for the next event tick to make sure the remaining part of the
// test is not executed before the message is actually flushed.
await new Promise(executeSoon);
ok(!hud.outputNode.textContent.includes("log3"), "log3 not displayed");
ok(!hud.outputNode.textContent.includes("log4"), "log4 not displayed");
@ -62,12 +66,12 @@ add_task(function* () {
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
content.wrappedJSObject.console.log("log5");
});
yield waitForLog("log5", hud);
await waitForLog("log5", hud);
info("Close and reopen the webconsole.");
yield closeConsole(gBrowser.selectedTab);
hud = yield openConsole();
yield waitForLog("Console was cleared", hud);
await closeConsole(gBrowser.selectedTab);
hud = await openConsole();
await waitForLog("Console was cleared", hud);
ok(hud.outputNode.textContent.includes("Console was cleared"),
"console.clear() message is still displayed");
@ -87,8 +91,8 @@ add_task(function* () {
* @param {WebConsole} webconsole
* WebConsole instance in which the message should be logged.
*/
function* waitForLog(message, webconsole, options) {
yield waitForMessages({
function waitForLog(message, webconsole, options) {
return waitForMessages({
webconsole: webconsole,
messages: [{
text: message,
@ -110,8 +114,8 @@ function* waitForLog(message, webconsole, options) {
* WebConsole instance in which the message should be logged.
*
*/
function* openSidebar(objName, expectedObj, webconsole) {
let msg = yield webconsole.jsterm.execute(objName);
async function openSidebar(objName, expectedObj, webconsole) {
let msg = await webconsole.jsterm.execute(objName);
ok(msg, "output message found");
let anchor = msg.querySelector("a");
@ -119,13 +123,13 @@ function* openSidebar(objName, expectedObj, webconsole) {
ok(anchor, "object anchor");
ok(body, "message body");
yield EventUtils.synthesizeMouse(anchor, 2, 2, {}, webconsole.iframeWindow);
await EventUtils.synthesizeMouse(anchor, 2, 2, {}, webconsole.iframeWindow);
let vviewVar = yield webconsole.jsterm.once("variablesview-fetched");
let vviewVar = await webconsole.jsterm.once("variablesview-fetched");
let vview = vviewVar._variablesView;
ok(vview, "variables view object exists");
yield findVariableViewProperties(vviewVar, [
await findVariableViewProperties(vviewVar, [
expectedObj,
], { webconsole: webconsole });
}

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

@ -17,6 +17,7 @@ const {
const {
CanvasFrameAnonymousContentHelper,
createNode,
getComputedStyle,
} = require("./utils/markup");
const {
getAdjustedQuads,
@ -26,18 +27,17 @@ const {
const FLEXBOX_LINES_PROPERTIES = {
"edge": {
lineDash: [0, 0],
alpha: 1,
lineDash: [2, 2]
},
"item": {
lineDash: [2, 2],
alpha: 1,
},
lineDash: [0, 0]
}
};
const FLEXBOX_CONTAINER_PATTERN_WIDTH = 14; // px
const FLEXBOX_CONTAINER_PATTERN_HEIGHT = 14; // px
const FLEXBOX_CONTAINER_PATTERN_LINE_DISH = [5, 3]; // px
const BASIS_FILL_COLOR = "rgb(109, 184, 255, 0.4)";
/**
* Cached used by `FlexboxHighlighter.getFlexContainerPattern`.
@ -257,7 +257,31 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
}
}
renderFlexContainer() {
renderFlexContainerBorder() {
if (!this.currentQuads.content || !this.currentQuads.content[0]) {
return;
}
let { devicePixelRatio } = this.win;
let lineWidth = getDisplayPixelRatio(this.win) * 2;
let offset = (lineWidth / 2) % 1;
let canvasX = Math.round(this._canvasPosition.x * devicePixelRatio);
let canvasY = Math.round(this._canvasPosition.y * devicePixelRatio);
this.ctx.save();
this.ctx.translate(offset - canvasX, offset - canvasY);
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.edge.lineDash);
this.ctx.lineWidth = lineWidth;
this.ctx.strokeStyle = DEFAULT_COLOR;
let { bounds } = this.currentQuads.content[0];
drawRect(this.ctx, 0, 0, bounds.width, bounds.height, this.currentMatrix);
this.ctx.stroke();
this.ctx.restore();
}
renderFlexContainerFill() {
if (!this.currentQuads.content || !this.currentQuads.content[0]) {
return;
}
@ -265,15 +289,13 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
let { devicePixelRatio } = this.win;
let lineWidth = getDisplayPixelRatio(this.win);
let offset = (lineWidth / 2) % 1;
let canvasX = Math.round(this._canvasPosition.x * devicePixelRatio);
let canvasY = Math.round(this._canvasPosition.y * devicePixelRatio);
this.ctx.save();
this.ctx.translate(offset - canvasX, offset - canvasY);
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.edge.lineDash);
this.ctx.globalAlpha = FLEXBOX_LINES_PROPERTIES.edge.alpha;
this.ctx.lineWidth = lineWidth;
this.ctx.lineWidth = 0;
this.ctx.strokeStyle = DEFAULT_COLOR;
this.ctx.fillStyle = this.getFlexContainerPattern(devicePixelRatio);
@ -285,6 +307,25 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
this.ctx.restore();
}
/**
* Renders the flex basis for a given flex item.
*/
renderFlexItemBasis(flexItem, left, top, right, bottom, boundsWidth) {
let computedStyle = getComputedStyle(flexItem);
let basis = computedStyle.getPropertyValue("flex-basis");
if (basis.endsWith("px")) {
right = left + parseFloat(basis);
} else if (basis.endsWith("%")) {
basis = parseFloat(basis) / 100 * boundsWidth;
right = left + basis;
}
this.ctx.fillStyle = BASIS_FILL_COLOR;
drawRect(this.ctx, left, top, right, bottom, this.currentMatrix);
this.ctx.fill();
}
renderFlexItems() {
if (!this.currentQuads.content || !this.currentQuads.content[0]) {
return;
@ -293,14 +334,12 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
let { devicePixelRatio } = this.win;
let lineWidth = getDisplayPixelRatio(this.win);
let offset = (lineWidth / 2) % 1;
let canvasX = Math.round(this._canvasPosition.x * devicePixelRatio);
let canvasY = Math.round(this._canvasPosition.y * devicePixelRatio);
this.ctx.save();
this.ctx.translate(offset - canvasX, offset - canvasY);
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.item.lineDash);
this.ctx.globalAlpha = FLEXBOX_LINES_PROPERTIES.item.alpha;
this.ctx.lineWidth = lineWidth;
this.ctx.strokeStyle = DEFAULT_COLOR;
@ -325,6 +364,54 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
clearRect(this.ctx, left, top, right, bottom, this.currentMatrix);
drawRect(this.ctx, left, top, right, bottom, this.currentMatrix);
this.ctx.stroke();
this.renderFlexItemBasis(flexItem, left, top, right, bottom, bounds.width);
}
this.ctx.restore();
}
renderFlexLines() {
if (!this.currentQuads.content || !this.currentQuads.content[0]) {
return;
}
let { devicePixelRatio } = this.win;
let lineWidth = getDisplayPixelRatio(this.win);
let offset = (lineWidth / 2) % 1;
let canvasX = Math.round(this._canvasPosition.x * devicePixelRatio);
let canvasY = Math.round(this._canvasPosition.y * devicePixelRatio);
this.ctx.save();
this.ctx.translate(offset - canvasX, offset - canvasY);
this.ctx.lineWidth = lineWidth;
this.ctx.strokeStyle = DEFAULT_COLOR;
let { bounds } = this.currentQuads.content[0];
let computedStyle = getComputedStyle(this.currentNode);
let flexLines = this.currentNode.getAsFlexContainer().getLines();
for (let flexLine of flexLines) {
let { crossStart, crossSize } = flexLine;
if (computedStyle.getPropertyValue("flex-direction") === "column" ||
computedStyle.getPropertyValue("flex-direction") === "column-reverse") {
clearRect(this.ctx, crossStart, 0, crossStart + crossSize, bounds.height,
this.currentMatrix);
drawRect(this.ctx, crossStart, 0, crossStart, bounds.height, this.currentMatrix);
this.ctx.stroke();
drawRect(this.ctx, crossStart + crossSize, 0, crossStart + crossSize,
bounds.height, this.currentMatrix);
this.ctx.stroke();
} else {
clearRect(this.ctx, 0, crossStart, bounds.width, crossStart + crossSize,
this.currentMatrix);
drawRect(this.ctx, 0, crossStart, bounds.width, crossStart, this.currentMatrix);
this.ctx.stroke();
drawRect(this.ctx, 0, crossStart + crossSize, bounds.width,
crossStart + crossSize, this.currentMatrix);
this.ctx.stroke();
}
}
this.ctx.restore();
@ -352,8 +439,10 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
this.currentMatrix = currentMatrix;
this.hasNodeTransformations = hasNodeTransformations;
this.renderFlexContainer();
this.renderFlexContainerFill();
this.renderFlexLines();
this.renderFlexItems();
this.renderFlexContainerBorder();
this._showFlexbox();

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

@ -81,6 +81,11 @@ add_task(async function () {
content.location = url2;
await loaded;
// Wait for the next event tick to make sure the remaining part of the
// test is not executed in the microtask checkpoint for load event
// itself. Otherwise the synthesizeMouseDown doesn't work.
await new Promise(r => setTimeout(r, 0));
// Update to the new document we just loaded
doc = content.document;

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

@ -40,6 +40,9 @@ native Visibility(mozilla::Visibility);
* interface to mirror this interface when changing it.
*/
// We can't make this interface noscript yet, because there is JS code doing
// "instanceof Ci.nsIImageLoadingContent" and using the nsIImageLoadingContent
// constants.
[scriptable, builtinclass, uuid(0357123d-9224-4d12-a47e-868c32689777)]
interface nsIImageLoadingContent : imgINotificationObserver
{
@ -56,11 +59,11 @@ interface nsIImageLoadingContent : imgINotificationObserver
const long PENDING_REQUEST = 1;
/**
* loadingEnabled is used to enable and disable loading in
* setLoadingEnabled is used to enable and disable loading in
* situations where loading images is unwanted. Note that enabling
* loading will *not* automatically trigger an image load.
*/
attribute boolean loadingEnabled;
[notxpcom, nostdcall] void setLoadingEnabled(in boolean aEnabled);
/**
* Returns the image blocking status (@see nsIContentPolicy). This
@ -68,7 +71,7 @@ interface nsIImageLoadingContent : imgINotificationObserver
* the image was blocked. This status always refers to the
* CURRENT_REQUEST load.
*/
readonly attribute short imageBlockingStatus;
[noscript] readonly attribute short imageBlockingStatus;
/**
* Used to register an image decoder observer. Typically, this will
@ -78,30 +81,16 @@ interface nsIImageLoadingContent : imgINotificationObserver
* current and pending, will be passed through.
*
* @param aObserver the observer to register
*
* @throws NS_ERROR_OUT_OF_MEMORY
*/
[notxpcom] nsresult addNativeObserver(in imgINotificationObserver aObserver);
[notxpcom, nostdcall] void addNativeObserver(in imgINotificationObserver aObserver);
/**
* Used to unregister an image decoder observer.
*
* @param aObserver the observer to unregister
*/
[notxpcom] nsresult removeNativeObserver(in imgINotificationObserver aObserver);
[notxpcom, nostdcall] void removeNativeObserver(in imgINotificationObserver aObserver);
/**
* Same as addNativeObserver but intended for scripted observers or observers
* from another or without a document.
*/
void addObserver(in imgINotificationObserver aObserver);
/**
* Same as removeNativeObserver but intended for scripted observers or
* observers from another or without a document.
*/
void removeObserver(in imgINotificationObserver aObserver);
/**
* Accessor to get the image requests
*
@ -113,7 +102,7 @@ interface nsIImageLoadingContent : imgINotificationObserver
* @throws NS_ERROR_UNEXPECTED if the request type requested is not
* known
*/
imgIRequest getRequest(in long aRequestType);
[noscript] imgIRequest getRequest(in long aRequestType);
/**
* Call this function when the request was blocked by any of the
@ -122,7 +111,7 @@ interface nsIImageLoadingContent : imgINotificationObserver
* @param aContentDecision the decision returned from nsIContentPolicy
* (any of the types REJECT_*)
*/
void setBlockedRequest(in int16_t aContentDecision);
[notxpcom, nostdcall] void setBlockedRequest(in int16_t aContentDecision);
/**
* @return true if the current request's size is available.
@ -152,14 +141,14 @@ interface nsIImageLoadingContent : imgINotificationObserver
*
* @throws NS_ERROR_UNEXPECTED if aRequest is not known
*/
long getRequestType(in imgIRequest aRequest);
[noscript] long getRequestType(in imgIRequest aRequest);
/**
* Gets the URI of the current request, if available.
* Otherwise, returns the last URI that this content tried to load, or
* null if there haven't been any such attempts.
*/
readonly attribute nsIURI currentURI;
[noscript] readonly attribute nsIURI currentURI;
/**
* loadImageWithChannel allows data from an existing channel to be
@ -173,29 +162,21 @@ interface nsIImageLoadingContent : imgINotificationObserver
*
* @throws NS_ERROR_NULL_POINTER if aChannel is null
*/
nsIStreamListener loadImageWithChannel(in nsIChannel aChannel);
[noscript] nsIStreamListener loadImageWithChannel(in nsIChannel aChannel);
/**
* forceReload forces reloading of the image pointed to by currentURI
*
* @param aNotify [optional] request should notify, defaults to true
* @throws NS_ERROR_NOT_AVAILABLE if there is no current URI to reload
*/
[optional_argc] void forceReload([optional] in boolean aNotify /* = true */);
/**
* Enables/disables image state forcing. When |aForce| is PR_TRUE, we force
* Enables/disables image state forcing. When |aForce| is true, we force
* nsImageLoadingContent::ImageState() to return |aState|. Call again with |aForce|
* as PR_FALSE to revert ImageState() to its original behaviour.
* as false to revert ImageState() to its original behaviour.
*/
void forceImageState(in boolean aForce, in unsigned long long aState);
[notxpcom, nostdcall] void forceImageState(in boolean aForce, in unsigned long long aState);
/**
* The intrinsic size and width of this content. May differ from actual image
* size due to things like responsive image density.
*/
readonly attribute unsigned long naturalWidth;
readonly attribute unsigned long naturalHeight;
[noscript] readonly attribute unsigned long naturalWidth;
[noscript] readonly attribute unsigned long naturalHeight;
/**
* Called by layout to announce when the frame associated with this content

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

@ -331,20 +331,12 @@ nsImageLoadingContent::OnImageIsAnimated(imgIRequest *aRequest)
* nsIImageLoadingContent impl
*/
NS_IMETHODIMP
nsImageLoadingContent::GetLoadingEnabled(bool *aLoadingEnabled)
{
*aLoadingEnabled = mLoadingEnabled;
return NS_OK;
}
NS_IMETHODIMP
void
nsImageLoadingContent::SetLoadingEnabled(bool aLoadingEnabled)
{
if (nsContentUtils::GetImgLoaderForChannel(nullptr, nullptr)) {
mLoadingEnabled = aLoadingEnabled;
}
return NS_OK;
}
NS_IMETHODIMP
@ -388,10 +380,12 @@ ReplayImageStatus(imgIRequest* aRequest, imgINotificationObserver* aObserver)
}
}
NS_IMETHODIMP
void
nsImageLoadingContent::AddNativeObserver(imgINotificationObserver* aObserver)
{
NS_ENSURE_ARG_POINTER(aObserver);
if (NS_WARN_IF(!aObserver)) {
return;
}
if (!mObserverList.mObserver) {
// Don't touch the linking of the list!
@ -400,7 +394,7 @@ nsImageLoadingContent::AddNativeObserver(imgINotificationObserver* aObserver)
ReplayImageStatus(mCurrentRequest, aObserver);
ReplayImageStatus(mPendingRequest, aObserver);
return NS_OK;
return;
}
// otherwise we have to create a new entry
@ -413,19 +407,19 @@ nsImageLoadingContent::AddNativeObserver(imgINotificationObserver* aObserver)
observer->mNext = new ImageObserver(aObserver);
ReplayImageStatus(mCurrentRequest, aObserver);
ReplayImageStatus(mPendingRequest, aObserver);
return NS_OK;
}
NS_IMETHODIMP
void
nsImageLoadingContent::RemoveNativeObserver(imgINotificationObserver* aObserver)
{
NS_ENSURE_ARG_POINTER(aObserver);
if (NS_WARN_IF(!aObserver)) {
return;
}
if (mObserverList.mObserver == aObserver) {
mObserverList.mObserver = nullptr;
// Don't touch the linking of the list!
return NS_OK;
return;
}
// otherwise have to find it and splice it out
@ -448,13 +442,14 @@ nsImageLoadingContent::RemoveNativeObserver(imgINotificationObserver* aObserver)
NS_WARNING("Asked to remove nonexistent observer");
}
#endif
return NS_OK;
}
NS_IMETHODIMP
void
nsImageLoadingContent::AddObserver(imgINotificationObserver* aObserver)
{
NS_ENSURE_ARG_POINTER(aObserver);
if (NS_WARN_IF(!aObserver)) {
return;
}
nsresult rv = NS_OK;
RefPtr<imgRequestProxy> currentReq;
@ -464,7 +459,7 @@ nsImageLoadingContent::AddObserver(imgINotificationObserver* aObserver)
// to dispatch notifications from the correct scheduler group.
rv = mCurrentRequest->Clone(aObserver, nullptr, getter_AddRefs(currentReq));
if (NS_FAILED(rv)) {
return rv;
return;
}
}
@ -474,22 +469,23 @@ nsImageLoadingContent::AddObserver(imgINotificationObserver* aObserver)
rv = mPendingRequest->Clone(aObserver, nullptr, getter_AddRefs(pendingReq));
if (NS_FAILED(rv)) {
mCurrentRequest->CancelAndForgetObserver(NS_BINDING_ABORTED);
return rv;
return;
}
}
mScriptedObservers.AppendElement(
new ScriptedImageObserver(aObserver, Move(currentReq), Move(pendingReq)));
return rv;
}
NS_IMETHODIMP
void
nsImageLoadingContent::RemoveObserver(imgINotificationObserver* aObserver)
{
NS_ENSURE_ARG_POINTER(aObserver);
if (NS_WARN_IF(!aObserver)) {
return;
}
if (NS_WARN_IF(mScriptedObservers.IsEmpty())) {
return NS_OK;
return;
}
RefPtr<ScriptedImageObserver> observer;
@ -504,13 +500,12 @@ nsImageLoadingContent::RemoveObserver(imgINotificationObserver* aObserver)
} while(i > 0);
if (NS_WARN_IF(!observer)) {
return NS_OK;
return;
}
// If the cancel causes a mutation, it will be harmless, because we have
// already removed the observer from the list.
observer->CancelRequests();
return NS_OK;
}
void
@ -815,8 +810,7 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
}
void
nsImageLoadingContent::ForceReload(const mozilla::dom::Optional<bool>& aNotify,
mozilla::ErrorResult& aError)
nsImageLoadingContent::ForceReload(bool aNotify, ErrorResult& aError)
{
nsCOMPtr<nsIURI> currentURI;
GetCurrentURI(getter_AddRefs(currentURI));
@ -825,35 +819,18 @@ nsImageLoadingContent::ForceReload(const mozilla::dom::Optional<bool>& aNotify,
return;
}
// defaults to true
bool notify = !aNotify.WasPassed() || aNotify.Value();
// We keep this flag around along with the old URI even for failed requests
// without a live request object
ImageLoadType loadType = \
(mCurrentRequestFlags & REQUEST_IS_IMAGESET) ? eImageLoadType_Imageset
: eImageLoadType_Normal;
nsresult rv = LoadImage(currentURI, true, notify, loadType, true, nullptr,
nsresult rv = LoadImage(currentURI, true, aNotify, loadType, true, nullptr,
nsIRequest::VALIDATE_ALWAYS);
if (NS_FAILED(rv)) {
aError.Throw(rv);
}
}
NS_IMETHODIMP
nsImageLoadingContent::ForceReload(bool aNotify /* = true */,
uint8_t aArgc)
{
mozilla::dom::Optional<bool> notify;
if (aArgc >= 1) {
notify.Construct() = aNotify;
}
ErrorResult result;
ForceReload(notify, result);
return result.StealNSResult();
}
/*
* Non-interface methods
*/
@ -1080,13 +1057,12 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
return NS_OK;
}
nsresult
void
nsImageLoadingContent::ForceImageState(bool aForce,
EventStates::InternalType aState)
{
mIsImageStateForced = aForce;
mForcedImageState = EventStates(aState);
return NS_OK;
}
NS_IMETHODIMP
@ -1356,13 +1332,13 @@ nsImageLoadingContent::PrepareNextRequest(ImageLoadType aImageLoadType)
PrepareCurrentRequest(aImageLoadType);
}
nsresult
void
nsImageLoadingContent::SetBlockedRequest(int16_t aContentDecision)
{
// If this is not calling from LoadImage, for example, from ServiceWorker,
// bail out.
if (!mIsStartingImageLoad) {
return NS_OK;
return;
}
// Sanity
@ -1378,8 +1354,6 @@ nsImageLoadingContent::SetBlockedRequest(int16_t aContentDecision)
} else {
mImageBlockingStatus = aContentDecision;
}
return NS_OK;
}
RefPtr<imgRequestProxy>&

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

@ -56,28 +56,24 @@ public:
NS_DECL_NSIIMAGELOADINGCONTENT
// Web IDL binding methods.
// Note that the XPCOM SetLoadingEnabled, AddObserver, RemoveObserver,
// ForceImageState methods are OK for Web IDL bindings to use as well,
// since none of them throw when called via the Web IDL bindings.
// Note that the XPCOM SetLoadingEnabled, ForceImageState methods are OK for
// Web IDL bindings to use as well, since none of them throw when called via
// the Web IDL bindings.
bool LoadingEnabled() const { return mLoadingEnabled; }
int16_t ImageBlockingStatus() const
{
return mImageBlockingStatus;
}
void AddObserver(imgINotificationObserver* aObserver);
void RemoveObserver(imgINotificationObserver* aObserver);
already_AddRefed<imgIRequest>
GetRequest(int32_t aRequestType, mozilla::ErrorResult& aError);
int32_t
GetRequestType(imgIRequest* aRequest, mozilla::ErrorResult& aError);
already_AddRefed<nsIURI> GetCurrentURI(mozilla::ErrorResult& aError);
already_AddRefed<nsIURI> GetCurrentRequestFinalURI();
void ForceReload(const mozilla::dom::Optional<bool>& aNotify,
mozilla::ErrorResult& aError);
// XPCOM [optional] syntax helper
nsresult ForceReload(bool aNotify = true) {
return ForceReload(aNotify, 1);
}
void ForceReload(bool aNotify, mozilla::ErrorResult& aError);
protected:
enum ImageLoadType {

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

@ -495,7 +495,8 @@ HTMLImageElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName,
// Bug 1076583 - We still use the older synchronous algorithm in
// non-responsive mode. Force a new load of the image with the
// new cross origin policy
ForceReload(aNotify);
IgnoredErrorResult error;
ForceReload(aNotify, error);
}
}
}

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

@ -92,8 +92,16 @@ interface MozImageLoadingContent {
attribute boolean loadingEnabled;
[ChromeOnly]
readonly attribute short imageBlockingStatus;
/**
* Same as addNativeObserver but intended for scripted observers or observers
* from another or without a document.
*/
[ChromeOnly]
void addObserver(imgINotificationObserver aObserver);
/**
* Same as removeNativeObserver but intended for scripted observers or
* observers from another or without a document.
*/
[ChromeOnly]
void removeObserver(imgINotificationObserver aObserver);
[ChromeOnly,Throws]
@ -106,8 +114,14 @@ interface MozImageLoadingContent {
// Otherwise, returns null.
[ChromeOnly]
readonly attribute URI? currentRequestFinalURI;
/**
* forceReload forces reloading of the image pointed to by currentURI
*
* @param aNotify request should notify
* @throws NS_ERROR_NOT_AVAILABLE if there is no current URI to reload
*/
[ChromeOnly,Throws]
void forceReload(optional boolean aNotify);
void forceReload(optional boolean aNotify = true);
[ChromeOnly]
void forceImageState(boolean aForce, unsigned long long aState);
};

151
gfx/thebes/dw-extra.h Normal file
Просмотреть файл

@ -0,0 +1,151 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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/. */
/*
* New DirectWrite interfaces based on Win10 Fall Creators Update versions
* of dwrite_3.h and dcommon.h (from SDK 10.0.17061.0). This particular
* subset of declarations is intended to be just sufficient to compile the
* Gecko DirectWrite font code; it omits many other new interfaces, etc.
*/
#ifndef DWRITE_EXTRA_H
#define DWRITE_EXTRA_H
#pragma once
interface IDWriteFontResource;
interface IDWriteFontFaceReference1;
enum DWRITE_GLYPH_IMAGE_FORMATS {
DWRITE_GLYPH_IMAGE_FORMATS_NONE = 0x00000000,
DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE = 0x00000001,
DWRITE_GLYPH_IMAGE_FORMATS_CFF = 0x00000002,
DWRITE_GLYPH_IMAGE_FORMATS_COLR = 0x00000004,
DWRITE_GLYPH_IMAGE_FORMATS_SVG = 0x00000008,
DWRITE_GLYPH_IMAGE_FORMATS_PNG = 0x00000010,
DWRITE_GLYPH_IMAGE_FORMATS_JPEG = 0x00000020,
DWRITE_GLYPH_IMAGE_FORMATS_TIFF = 0x00000040,
DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8 = 0x00000080,
};
#ifdef DEFINE_ENUM_FLAG_OPERATORS
DEFINE_ENUM_FLAG_OPERATORS(DWRITE_GLYPH_IMAGE_FORMATS);
#endif
#define DWRITE_MAKE_FONT_AXIS_TAG(a,b,c,d) \
(static_cast<DWRITE_FONT_AXIS_TAG>(DWRITE_MAKE_OPENTYPE_TAG(a,b,c,d)))
enum DWRITE_FONT_AXIS_TAG : UINT32 {
DWRITE_FONT_AXIS_TAG_WEIGHT = DWRITE_MAKE_FONT_AXIS_TAG('w', 'g', 'h', 't'),
DWRITE_FONT_AXIS_TAG_WIDTH = DWRITE_MAKE_FONT_AXIS_TAG('w', 'd', 't', 'h'),
DWRITE_FONT_AXIS_TAG_SLANT = DWRITE_MAKE_FONT_AXIS_TAG('s', 'l', 'n', 't'),
DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE = DWRITE_MAKE_FONT_AXIS_TAG('o', 'p', 's', 'z'),
DWRITE_FONT_AXIS_TAG_ITALIC = DWRITE_MAKE_FONT_AXIS_TAG('i', 't', 'a', 'l'),
};
enum DWRITE_FONT_AXIS_ATTRIBUTES {
DWRITE_FONT_AXIS_ATTRIBUTES_NONE = 0x0000,
DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE = 0x0001,
DWRITE_FONT_AXIS_ATTRIBUTES_HIDDEN = 0x0002,
};
struct DWRITE_FONT_AXIS_VALUE {
DWRITE_FONT_AXIS_TAG axisTag;
FLOAT value;
};
struct DWRITE_FONT_AXIS_RANGE {
DWRITE_FONT_AXIS_TAG axisTag;
FLOAT minValue;
FLOAT maxValue;
};
struct DWRITE_GLYPH_IMAGE_DATA;
interface DWRITE_DECLARE_INTERFACE("27F2A904-4EB8-441D-9678-0563F53E3E2F") IDWriteFontFace4
: public IDWriteFontFace3
{
STDMETHOD_(DWRITE_GLYPH_IMAGE_FORMATS, GetGlyphImageFormats)() PURE;
STDMETHOD(GetGlyphImageFormats)(
UINT16 glyphId,
UINT32 pixelsPerEmFirst,
UINT32 pixelsPerEmLast,
_Out_ DWRITE_GLYPH_IMAGE_FORMATS* glyphImageFormats
) PURE;
STDMETHOD(GetGlyphImageData)(
_In_ UINT16 glyphId,
UINT32 pixelsPerEm,
DWRITE_GLYPH_IMAGE_FORMATS glyphImageFormat,
_Out_ DWRITE_GLYPH_IMAGE_DATA* glyphData,
_Outptr_result_maybenull_ void** glyphDataContext
) PURE;
STDMETHOD_(void, ReleaseGlyphImageData)(
void* glyphDataContext
) PURE;
};
interface DWRITE_DECLARE_INTERFACE("98EFF3A5-B667-479A-B145-E2FA5B9FDC29") IDWriteFontFace5
: public IDWriteFontFace4
{
STDMETHOD_(UINT32, GetFontAxisValueCount)() PURE;
STDMETHOD(GetFontAxisValues)(
_Out_writes_(fontAxisValueCount) DWRITE_FONT_AXIS_VALUE* fontAxisValues,
UINT32 fontAxisValueCount
) PURE;
STDMETHOD_(BOOL, HasVariations)() PURE;
STDMETHOD(GetFontResource)(
_COM_Outptr_ IDWriteFontResource** fontResource
) PURE;
STDMETHOD_(BOOL, Equals)(IDWriteFontFace* fontFace) PURE;
};
interface DWRITE_DECLARE_INTERFACE("1F803A76-6871-48E8-987F-B975551C50F2") IDWriteFontResource
: public IUnknown
{
STDMETHOD(GetFontFile)(
_COM_Outptr_ IDWriteFontFile** fontFile
) PURE;
STDMETHOD_(UINT32, GetFontFaceIndex)() PURE;
STDMETHOD_(UINT32, GetFontAxisCount)() PURE;
STDMETHOD(GetDefaultFontAxisValues)(
_Out_writes_(fontAxisValueCount) DWRITE_FONT_AXIS_VALUE* fontAxisValues,
UINT32 fontAxisValueCount
) PURE;
STDMETHOD(GetFontAxisRanges)(
_Out_writes_(fontAxisRangeCount) DWRITE_FONT_AXIS_RANGE* fontAxisRanges,
UINT32 fontAxisRangeCount
) PURE;
STDMETHOD_(DWRITE_FONT_AXIS_ATTRIBUTES, GetFontAxisAttributes)(
UINT32 axisIndex
) PURE;
STDMETHOD(GetAxisNames)(
UINT32 axisIndex,
_COM_Outptr_ IDWriteLocalizedStrings** names
) PURE;
STDMETHOD_(UINT32, GetAxisValueNameCount)(
UINT32 axisIndex
) PURE;
STDMETHOD(GetAxisValueNames)(
UINT32 axisIndex,
UINT32 axisValueIndex,
_Out_ DWRITE_FONT_AXIS_RANGE* fontAxisRange,
_COM_Outptr_ IDWriteLocalizedStrings** names
) PURE;
STDMETHOD_(BOOL, HasVariations)() PURE;
STDMETHOD(CreateFontFace)(
DWRITE_FONT_SIMULATIONS fontSimulations,
_In_reads_(fontAxisValueCount) DWRITE_FONT_AXIS_VALUE const* fontAxisValues,
UINT32 fontAxisValueCount,
_COM_Outptr_ IDWriteFontFace5** fontFace
) PURE;
STDMETHOD(CreateFontFaceReference)(
DWRITE_FONT_SIMULATIONS fontSimulations,
_In_reads_(fontAxisValueCount) DWRITE_FONT_AXIS_VALUE const* fontAxisValues,
UINT32 fontAxisValueCount,
_COM_Outptr_ IDWriteFontFaceReference1** fontFaceReference
) PURE;
};
#endif /* DWRITE_EXTRA_H */

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

@ -587,33 +587,69 @@ gfxDWriteFontEntry::ReadCMAP(FontInfoData *aFontInfoData)
return rv;
}
bool
gfxDWriteFontEntry::HasVariations()
{
if (mHasVariationsInitialized) {
return mHasVariations;
}
mHasVariationsInitialized = true;
if (!mFontFace) {
// CreateFontFace will initialize the mFontFace field, and also
// mFontFace5 if available on the current DWrite version.
RefPtr<IDWriteFontFace> fontFace;
if (NS_FAILED(CreateFontFace(getter_AddRefs(fontFace)))) {
return false;
}
}
if (mFontFace5) {
mHasVariations = mFontFace5->HasVariations();
}
return mHasVariations;
}
gfxFont *
gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle,
bool aNeedsBold)
{
DWRITE_FONT_SIMULATIONS sims =
aNeedsBold ? DWRITE_FONT_SIMULATIONS_BOLD : DWRITE_FONT_SIMULATIONS_NONE;
if (HasVariations() && !aFontStyle->variationSettings.IsEmpty()) {
// If we need to apply variations, we can't use the cached mUnscaledFont
// or mUnscaledFontBold here.
// XXX todo: consider caching a small number of variation instances?
RefPtr<IDWriteFontFace> fontFace;
nsresult rv = CreateFontFace(getter_AddRefs(fontFace),
&aFontStyle->variationSettings,
sims);
if (NS_FAILED(rv)) {
return nullptr;
}
RefPtr<UnscaledFontDWrite> unscaledFont =
new UnscaledFontDWrite(fontFace, mIsSystemFont ? mFont : nullptr, sims);
return new gfxDWriteFont(unscaledFont, this, aFontStyle, aNeedsBold);
}
ThreadSafeWeakPtr<UnscaledFontDWrite>& unscaledFontPtr =
aNeedsBold ? mUnscaledFontBold : mUnscaledFont;
RefPtr<UnscaledFontDWrite> unscaledFont(unscaledFontPtr);
if (!unscaledFont) {
DWRITE_FONT_SIMULATIONS sims = DWRITE_FONT_SIMULATIONS_NONE;
if (aNeedsBold) {
sims |= DWRITE_FONT_SIMULATIONS_BOLD;
}
RefPtr<IDWriteFontFace> fontFace;
nsresult rv = CreateFontFace(getter_AddRefs(fontFace), sims);
nsresult rv = CreateFontFace(getter_AddRefs(fontFace), nullptr, sims);
if (NS_FAILED(rv)) {
return nullptr;
}
unscaledFont = new UnscaledFontDWrite(fontFace, mIsSystemFont ? mFont : nullptr, sims);
unscaledFont =
new UnscaledFontDWrite(fontFace,
mIsSystemFont ? mFont : nullptr, sims);
unscaledFontPtr = unscaledFont;
}
return new gfxDWriteFont(unscaledFont, this, aFontStyle, aNeedsBold);
}
nsresult
gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace,
const nsTArray<gfxFontVariation>* aVariations,
DWRITE_FONT_SIMULATIONS aSimulations)
{
// initialize mFontFace if this hasn't been done before
@ -637,13 +673,55 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace,
if (FAILED(hr)) {
return NS_ERROR_FAILURE;
}
// Also get the IDWriteFontFace5 interface if we're running on a
// sufficiently new DWrite version where it is available.
if (mFontFace) {
mFontFace->QueryInterface(__uuidof(IDWriteFontFace5),
(void**)getter_AddRefs(mFontFace5));
}
}
// check whether we need to add a DWrite simulated style
if ((aSimulations & DWRITE_FONT_SIMULATIONS_BOLD) &&
!(mFontFace->GetSimulations() & DWRITE_FONT_SIMULATIONS_BOLD)) {
// Do we need to modify DWrite simulations from what mFontFace has?
bool needSimulations =
(aSimulations & DWRITE_FONT_SIMULATIONS_BOLD) &&
!(mFontFace->GetSimulations() & DWRITE_FONT_SIMULATIONS_BOLD);
// If the IDWriteFontFace5 interface is available, we can go via
// IDWriteFontResource to create a new modified face.
if (mFontFace5 && (aVariations && !aVariations->IsEmpty() ||
needSimulations)) {
RefPtr<IDWriteFontResource> resource;
HRESULT hr = mFontFace5->GetFontResource(getter_AddRefs(resource));
MOZ_ASSERT(SUCCEEDED(hr));
AutoTArray<DWRITE_FONT_AXIS_VALUE, 4> fontAxisValues;
if (aVariations) {
for (const auto& v : *aVariations) {
DWRITE_FONT_AXIS_VALUE axisValue = {
// let dwrite put the tag bytes in the order it wants
DWRITE_MAKE_FONT_AXIS_TAG((v.mTag >> 24) & 0xff,
(v.mTag >> 16) & 0xff,
(v.mTag >> 8) & 0xff,
v.mTag & 0xff),
v.mValue
};
fontAxisValues.AppendElement(axisValue);
}
}
IDWriteFontFace5* ff5;
resource->CreateFontFace(aSimulations,
fontAxisValues.Elements(),
fontAxisValues.Length(),
&ff5);
if (ff5) {
*aFontFace = ff5;
}
return FAILED(hr) ? NS_ERROR_FAILURE : NS_OK;
}
// Do we need to add DWrite simulations to the face?
if (needSimulations) {
// if so, we need to return not mFontFace itself but a version that
// has the Bold simulation - unfortunately, DWrite doesn't provide
// has the Bold simulation - unfortunately, old DWrite doesn't provide
// a simple API for this
UINT32 numberOfFiles = 0;
if (FAILED(mFontFace->GetFiles(&numberOfFiles, nullptr))) {

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

@ -8,6 +8,19 @@
#include "mozilla/MemoryReporting.h"
#include "gfxDWriteCommon.h"
#include "dwrite_3.h"
// Currently, we build with WINVER=0x601 (Win7), which means newer
// declarations in dwrite_3.h will not be visible. Also, we don't
// yet have the Fall Creators Update SDK available on build machines,
// so even with updated WINVER, some of the interfaces we need would
// not be present.
// To work around this, until the build environment is updated,
// we #include an extra header that contains copies of the relevant
// classes/interfaces we need.
#if WINVER < 0x0A00
#include "dw-extra.h"
#endif
#include "gfxFont.h"
#include "gfxUserFontSet.h"
@ -93,7 +106,8 @@ public:
IDWriteFont *aFont,
bool aIsSystemFont = false)
: gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr),
mIsSystemFont(aIsSystemFont), mForceGDIClassic(false)
mIsSystemFont(aIsSystemFont), mForceGDIClassic(false),
mHasVariations(false), mHasVariationsInitialized(false)
{
DWRITE_FONT_STYLE dwriteStyle = aFont->GetStyle();
mStyle = (dwriteStyle == DWRITE_FONT_STYLE_ITALIC ?
@ -127,7 +141,8 @@ public:
int16_t aStretch,
uint8_t aStyle)
: gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr),
mIsSystemFont(false), mForceGDIClassic(false)
mIsSystemFont(false), mForceGDIClassic(false),
mHasVariations(false), mHasVariationsInitialized(false)
{
mWeight = aWeight;
mStretch = aStretch;
@ -154,7 +169,8 @@ public:
uint8_t aStyle)
: gfxFontEntry(aFaceName), mFont(nullptr),
mFontFile(aFontFile), mFontFileStream(aFontFileStream),
mIsSystemFont(false), mForceGDIClassic(false)
mIsSystemFont(false), mForceGDIClassic(false),
mHasVariations(false), mHasVariationsInitialized(false)
{
mWeight = aWeight;
mStretch = aStretch;
@ -173,6 +189,8 @@ public:
bool IsCJKFont();
bool HasVariations();
void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
bool GetForceGDIClassic() { return mForceGDIClassic; }
@ -193,6 +211,7 @@ protected:
nsresult CreateFontFace(
IDWriteFontFace **aFontFace,
const nsTArray<gfxFontVariation>* aVariations = nullptr,
DWRITE_FONT_SIMULATIONS aSimulations = DWRITE_FONT_SIMULATIONS_NONE);
static bool InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont);
@ -211,12 +230,16 @@ protected:
// font face corresponding to the mFont/mFontFile *without* any DWrite
// style simulations applied
RefPtr<IDWriteFontFace> mFontFace;
// Extended fontface interface if supported, else null
RefPtr<IDWriteFontFace5> mFontFace5;
DWRITE_FONT_FACE_TYPE mFaceType;
int8_t mIsCJK;
bool mIsSystemFont;
bool mForceGDIClassic;
bool mHasVariations;
bool mHasVariationsInitialized;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontDWrite> mUnscaledFont;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontDWrite> mUnscaledFontBold;

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

@ -564,7 +564,9 @@ bool
gfxDWriteFont::ProvidesGlyphWidths() const
{
return !mUseSubpixelPositions ||
(mFontFace->GetSimulations() & DWRITE_FONT_SIMULATIONS_BOLD);
(mFontFace->GetSimulations() & DWRITE_FONT_SIMULATIONS_BOLD) ||
(((gfxDWriteFontEntry*)(GetFontEntry()))->HasVariations() &&
!mStyle.variationSettings.IsEmpty());
}
int32_t

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

@ -1521,6 +1521,40 @@ gfxFont::SupportsSubSuperscript(uint32_t aSubSuperscript,
return origSize == intersectionSize;
}
bool
gfxFont::FeatureWillHandleChar(Script aRunScript, uint32_t aFeature,
uint32_t aUnicode)
{
if (!SupportsFeature(aRunScript, aFeature)) {
return false;
}
// xxx - for graphite, don't really know how to sniff lookups so bail
if (mGraphiteShaper && gfxPlatform::GetPlatform()->UseGraphiteShaping()) {
return true;
}
if (!mHarfBuzzShaper) {
mHarfBuzzShaper = MakeUnique<gfxHarfBuzzShaper>(this);
}
gfxHarfBuzzShaper* shaper =
static_cast<gfxHarfBuzzShaper*>(mHarfBuzzShaper.get());
if (!shaper->Initialize()) {
return false;
}
// get the hbset containing input glyphs for the feature
const hb_set_t *inputGlyphs =
mFontEntry->InputsForOpenTypeFeature(aRunScript, aFeature);
if (aUnicode == 0xa0) {
aUnicode = ' ';
}
hb_codepoint_t gid = shaper->GetNominalGlyph(aUnicode);
return hb_set_has(inputGlyphs, gid);
}
bool
gfxFont::HasFeatureSet(uint32_t aFeature, bool& aFeatureOn)
{

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

@ -1593,6 +1593,10 @@ public:
uint32_t aLength,
Script aRunScript);
// whether the specified feature will apply to the given character
bool FeatureWillHandleChar(Script aRunScript, uint32_t aFeature,
uint32_t aUnicode);
// Subclasses may choose to look up glyph ids for characters.
// If they do not override this, gfxHarfBuzzShaper will fetch the cmap
// table and use that.

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

@ -848,7 +848,8 @@ gfxFontEntry::InputsForOpenTypeFeature(Script aScript, uint32_t aFeatureTag)
}
NS_ASSERTION(aFeatureTag == HB_TAG('s','u','p','s') ||
aFeatureTag == HB_TAG('s','u','b','s'),
aFeatureTag == HB_TAG('s','u','b','s') ||
aFeatureTag == HB_TAG('v','e','r','t'),
"use of unknown feature tag");
uint32_t scriptFeature = SCRIPT_FEATURE(aScript, aFeatureTag);

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

@ -209,8 +209,8 @@ VertFormsGlyphCompare(const void* aKey, const void* aElem)
// Return a vertical presentation-form codepoint corresponding to the
// given Unicode value, or 0 if no such form is available.
static hb_codepoint_t
GetVerticalPresentationForm(hb_codepoint_t unicode)
hb_codepoint_t
gfxHarfBuzzShaper::GetVerticalPresentationForm(hb_codepoint_t aUnicode)
{
static const uint16_t sVerticalForms[][2] = {
{ 0x2013, 0xfe32 }, // EN DASH
@ -248,7 +248,7 @@ GetVerticalPresentationForm(hb_codepoint_t unicode)
{ 0xff5d, 0xfe38 } // FULLWIDTH RIGHT CURLY BRACKET
};
const uint16_t* charPair =
static_cast<const uint16_t*>(bsearch(&unicode,
static_cast<const uint16_t*>(bsearch(&aUnicode,
sVerticalForms,
ArrayLength(sVerticalForms),
sizeof(sVerticalForms[0]),
@ -266,7 +266,8 @@ HBGetNominalGlyph(hb_font_t *font, void *font_data,
static_cast<const gfxHarfBuzzShaper::FontCallbackData*>(font_data);
if (fcd->mShaper->UseVerticalPresentationForms()) {
hb_codepoint_t verticalForm = GetVerticalPresentationForm(unicode);
hb_codepoint_t verticalForm =
gfxHarfBuzzShaper::GetVerticalPresentationForm(unicode);
if (verticalForm) {
*glyph = fcd->mShaper->GetNominalGlyph(verticalForm);
if (*glyph != 0) {
@ -290,7 +291,8 @@ HBGetVariationGlyph(hb_font_t *font, void *font_data,
static_cast<const gfxHarfBuzzShaper::FontCallbackData*>(font_data);
if (fcd->mShaper->UseVerticalPresentationForms()) {
hb_codepoint_t verticalForm = GetVerticalPresentationForm(unicode);
hb_codepoint_t verticalForm =
gfxHarfBuzzShaper::GetVerticalPresentationForm(unicode);
if (verticalForm) {
*glyph = fcd->mShaper->GetVariationGlyph(verticalForm,
variation_selector);

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

@ -97,6 +97,9 @@ public:
return hbScript;
}
static hb_codepoint_t
GetVerticalPresentationForm(hb_codepoint_t aUnicode);
protected:
nsresult SetGlyphsFromRun(gfxShapedText *aShapedText,
uint32_t aOffset,

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

@ -3180,10 +3180,25 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
// on a per-character basis using the UTR50 orientation property.
switch (GetVerticalOrientation(ch)) {
case VERTICAL_ORIENTATION_U:
case VERTICAL_ORIENTATION_Tr:
case VERTICAL_ORIENTATION_Tu:
orient = ShapedTextFlags::TEXT_ORIENT_VERTICAL_UPRIGHT;
break;
case VERTICAL_ORIENTATION_Tr: {
// We check for a vertical presentation form first as that's
// likely to be cheaper than inspecting lookups to see if the
// 'vert' feature is going to handle this character, and if the
// presentation form is available then it will be used as
// fallback if needed, so it's OK if the feature is missing.
uint32_t v = gfxHarfBuzzShaper::GetVerticalPresentationForm(ch);
orient = (!font ||
(v && font->HasCharacter(v)) ||
font->FeatureWillHandleChar(aRunScript,
HB_TAG('v','e','r','t'),
ch))
? ShapedTextFlags::TEXT_ORIENT_VERTICAL_UPRIGHT
: ShapedTextFlags::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT;
break;
}
case VERTICAL_ORIENTATION_R:
orient = ShapedTextFlags::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT;
break;

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

@ -198,6 +198,7 @@ public:
aTag == TRUETYPE_TAG('g', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('H', 'V', 'A', 'R') ||
aTag == TRUETYPE_TAG('M', 'V', 'A', 'R') ||
aTag == TRUETYPE_TAG('S', 'T', 'A', 'T') ||
aTag == TRUETYPE_TAG('V', 'V', 'A', 'R'))) ||
aTag == TRUETYPE_TAG('S', 'V', 'G', ' ') ||
aTag == TRUETYPE_TAG('C', 'O', 'L', 'R') ||

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

@ -35,7 +35,6 @@ function ImageObserver(decodeCallback, discardCallback) {
function currentRequest() {
let img = gBrowser.getBrowserForTab(newTab).contentWindow
.document.getElementById('testImg');
img.QueryInterface(Ci.nsIImageLoadingContent);
return img.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
}

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

@ -6,8 +6,7 @@ var chrome_root = getRootDirectory(gTestPath);
const CHROMEROOT = chrome_root;
function getImageLoading(doc, id) {
var htmlImg = doc.getElementById(id);
return htmlImg.QueryInterface(Ci.nsIImageLoadingContent);
return doc.getElementById(id);
}
// Tries to get the Moz debug image, imgIContainerDebug. Only works

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

@ -27,8 +27,7 @@
observer = SpecialPowers.wrapCallbackObject(observer);
var gObserver = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
.createScriptedObserver(observer);
var imgLoadingContent =
SpecialPowers.wrap(img).QueryInterface(Ci.nsIImageLoadingContent);
var imgLoadingContent = SpecialPowers.wrap(img);
imgLoadingContent.addObserver(gObserver);
function initCF() {
setTimeout(function() { document.adoptNode(tCF0); }, 0);

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

@ -45,9 +45,6 @@ function getImageStatus(id)
// Get the image
var img = SpecialPowers.wrap(document.getElementById(id));
// QI the image to nsImageLoadingContent
img.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent);
// Get the request
var request = img.getRequest(SpecialPowers.Ci
.nsIImageLoadingContent

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

@ -86,7 +86,7 @@ function cleanUpAndFinish() {
if (gIsTestFinished) {
return;
}
let imgLoadingContent = SpecialPowers.wrap(gImg).QueryInterface(Ci.nsIImageLoadingContent);
let imgLoadingContent = SpecialPowers.wrap(gImg);
imgLoadingContent.removeObserver(gMyDecoderObserver);
SimpleTest.finish();
gIsTestFinished = true;
@ -101,7 +101,7 @@ function main() {
gMyDecoderObserver =
Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
.createScriptedObserver(SpecialPowers.wrapCallbackObject(observer));
let imgLoadingContent = SpecialPowers.wrap(gImg).QueryInterface(Ci.nsIImageLoadingContent);
let imgLoadingContent = SpecialPowers.wrap(gImg);
imgLoadingContent.addObserver(gMyDecoderObserver);
// We want to test the cold loading behavior, so clear cache in case an

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

@ -27,8 +27,7 @@ window.onload = function() {
return SpecialPowers.wrap(f.contentDocument.getElementsByTagName("img")[0]);
});
var containers = imgs.map(function (img) {
return img.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent)
.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST)
return img.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST)
.image;
});

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

@ -63,7 +63,6 @@ function runTest() {
if (triggerDiscardingManually) {
var request = SpecialPowers.wrap(image)
.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent)
.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST);
setTimeout(() => request.requestDiscard(), 1000);
}
@ -82,9 +81,7 @@ function addCallbacks(anImage, loadCompleteCallback, discardCallback) {
.getService(SpecialPowers.Ci.imgITools)
.createScriptedObserver(observer);
var imgLoadingContent =
SpecialPowers.wrap(anImage)
.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent);
var imgLoadingContent = SpecialPowers.wrap(anImage);
imgLoadingContent.addObserver(scriptedObserver);
}

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

@ -23,7 +23,6 @@ SimpleTest.waitForExplicitFinish();
window.onload = function() {
var img = SpecialPowers.wrap(document.getElementsByTagName("img")[0]);
var container = img
.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent)
.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST)
.image;

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

@ -179,15 +179,12 @@ function addCallbacks(anImage, arrayIndex) {
.getService(SpecialPowers.Ci.imgITools)
.createScriptedObserver(observer);
var imgLoadingContent =
SpecialPowers.wrap(anImage)
.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent);
var imgLoadingContent = SpecialPowers.wrap(anImage);
imgLoadingContent.addObserver(scriptedObserver);
}
function requestDiscard(anImage) {
var request = SpecialPowers.wrap(anImage)
.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent)
.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST);
setTimeout(() => request.requestDiscard(), 0);
}

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

@ -126,7 +126,7 @@ function cleanUpAndFinish() {
return;
}
gIsTestFinished = true;
let imgLoadingContent = SpecialPowers.wrap(gImg).QueryInterface(Ci.nsIImageLoadingContent);
let imgLoadingContent = SpecialPowers.wrap(gImg);
imgLoadingContent.removeObserver(gMyDecoderObserver);
SimpleTest.finish();
}
@ -146,7 +146,7 @@ function main() {
gMyDecoderObserver =
Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
.createScriptedObserver(SpecialPowers.wrapCallbackObject(observer));
let imgLoadingContent = SpecialPowers.wrap(gImg).QueryInterface(Ci.nsIImageLoadingContent);
let imgLoadingContent = SpecialPowers.wrap(gImg);
imgLoadingContent.addObserver(gMyDecoderObserver);
// We want to test the cold loading behavior, so clear cache in case an

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

@ -114,7 +114,7 @@ function cleanUpAndFinish() {
if (gIsTestFinished) {
return;
}
let imgLoadingContent = SpecialPowers.wrap(gImg).QueryInterface(Ci.nsIImageLoadingContent);
let imgLoadingContent = SpecialPowers.wrap(gImg);
imgLoadingContent.removeObserver(gMyDecoderObserver);
// TODO - this isn't the case until post-bug 716140's refactorings
// ok(gNotifications == gLoads, "Should be notified the same number of times as loads");
@ -136,7 +136,7 @@ function main() {
gMyDecoderObserver =
Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
.createScriptedObserver(SpecialPowers.wrapCallbackObject(observer));
let imgLoadingContent = SpecialPowers.wrap(gImg).QueryInterface(Ci.nsIImageLoadingContent);
let imgLoadingContent = SpecialPowers.wrap(gImg);
imgLoadingContent.addObserver(gMyDecoderObserver);
// We want to test the cold loading behavior, so clear cache in case an

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

@ -97,7 +97,7 @@ function cleanUpAndFinish() {
if (gIsTestFinished) {
return;
}
let imgLoadingContent = SpecialPowers.wrap(gImg).QueryInterface(Ci.nsIImageLoadingContent);
let imgLoadingContent = SpecialPowers.wrap(gImg);
imgLoadingContent.removeObserver(gMyDecoderObserver);
// TODO: this isn't the case until post-bug 716140's refactorings
// ok(gNotifications == gLoads, "Should be notified the same number of times as loads");
@ -119,7 +119,7 @@ function main() {
gMyDecoderObserver =
Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
.createScriptedObserver(SpecialPowers.wrapCallbackObject(observer));
let imgLoadingContent = SpecialPowers.wrap(gImg).QueryInterface(Ci.nsIImageLoadingContent);
let imgLoadingContent = SpecialPowers.wrap(gImg);
imgLoadingContent.addObserver(gMyDecoderObserver);
// We want to test the cold loading behavior, so clear cache in case an

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

@ -23,7 +23,7 @@ SimpleTest.waitForExplicitFinish();
window.onload = function() {
var img = document.getElementById("animated");
var content = SpecialPowers.wrap(img).QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent);
var content = SpecialPowers.wrap(img);
var request = content.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST);

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

@ -42,10 +42,10 @@ function cleanUpAndFinish() {
if (gFinished) {
return;
}
var imgLoadingContent = SpecialPowers.wrap(gImg1).QueryInterface(Ci.nsIImageLoadingContent);
var imgLoadingContent = SpecialPowers.wrap(gImg1);
imgLoadingContent.removeObserver(gOuter);
imgLoadingContent = SpecialPowers.wrap(gImg2).QueryInterface(Ci.nsIImageLoadingContent);
imgLoadingContent = SpecialPowers.wrap(gImg2);
imgLoadingContent.removeObserver(gOuter);
SimpleTest.finish();
@ -79,7 +79,7 @@ function waitForLoadAndTest(image) {
context.drawImage(image, 0, 0);
// Attach the observer.
var imgLoadingContent = SpecialPowers.wrap(image).QueryInterface(Ci.nsIImageLoadingContent);
var imgLoadingContent = SpecialPowers.wrap(image);
imgLoadingContent.addObserver(gOuter);
// If the other image already loaded, add both images to the document, which

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

@ -1052,9 +1052,9 @@ JS_GetDataViewByteLength(JSObject* obj)
JS_FRIEND_API(JSObject*)
JS_NewDataView(JSContext* cx, HandleObject buffer, uint32_t byteOffset, int32_t byteLength)
{
RootedObject constructor(cx);
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(&DataViewObject::class_);
if (!GetBuiltinConstructor(cx, key, &constructor))
RootedObject constructor(cx, GlobalObject::getOrCreateConstructor(cx, key));
if (!constructor)
return nullptr;
FixedConstructArgs<3> cargs(cx);

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

@ -1569,8 +1569,9 @@ PromiseConstructor(JSContext* cx, unsigned argc, Value* vp)
newTarget = unwrappedNewTarget;
{
AutoCompartment ac(cx, newTarget);
RootedObject promiseCtor(cx);
if (!GetBuiltinConstructor(cx, JSProto_Promise, &promiseCtor))
Handle<GlobalObject*> global = cx->global();
RootedObject promiseCtor(cx, GlobalObject::getOrCreatePromiseConstructor(cx, global));
if (!promiseCtor)
return false;
// Promise subclasses don't get the special Xray treatment, so
@ -1578,7 +1579,8 @@ PromiseConstructor(JSContext* cx, unsigned argc, Value* vp)
// described above for instances of Promise itself.
if (newTarget == promiseCtor) {
needsWrapping = true;
if (!GetBuiltinPrototype(cx, JSProto_Promise, &proto))
proto = GlobalObject::getOrCreatePromisePrototype(cx, cx->global());
if (!proto)
return false;
}
}
@ -3169,8 +3171,9 @@ BlockOnPromise(JSContext* cx, HandleValue promiseVal, HandleObject blockedPromis
// |promise| is an unwrapped Promise, and |then| is the original
// |Promise.prototype.then|, inline it here.
// 25.4.5.3., step 3.
RootedObject PromiseCtor(cx);
if (!GetBuiltinConstructor(cx, JSProto_Promise, &PromiseCtor))
RootedObject PromiseCtor(cx,
GlobalObject::getOrCreatePromiseConstructor(cx, cx->global()));
if (!PromiseCtor)
return false;
RootedObject C(cx, SpeciesConstructor(cx, promiseObj, JSProto_Promise, IsPromiseSpecies));

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

@ -3931,7 +3931,8 @@ ReadableByteStreamControllerConvertPullIntoDescriptor(JSContext* cx,
// bytesFilled / elementSize).
RootedObject ctor(cx, pullIntoDescriptor->ctor());
if (!ctor) {
if (!GetBuiltinConstructor(cx, JSProto_Uint8Array, &ctor))
ctor = GlobalObject::getOrCreateConstructor(cx, JSProto_Uint8Array);
if (!ctor)
return nullptr;
}
RootedObject buffer(cx, pullIntoDescriptor->buffer());
@ -4430,12 +4431,14 @@ ReadableByteStreamControllerPullInto(JSContext* cx,
JSProtoKey protoKey = StandardProtoKeyOrNull(view);
MOZ_ASSERT(protoKey);
if (!GetBuiltinConstructor(cx, protoKey, &ctor))
ctor = GlobalObject::getOrCreateConstructor(cx, protoKey);
if (!ctor)
return nullptr;
elementSize = 1 << TypedArrayShift(view->as<TypedArrayObject>().type());
} else {
// Step 3: Let ctor be %DataView% (reordered).
if (!GetBuiltinConstructor(cx, JSProto_DataView, &ctor))
ctor = GlobalObject::getOrCreateConstructor(cx, JSProto_DataView);
if (!ctor)
return nullptr;
}

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

@ -5009,10 +5009,10 @@ bool
BaselineCompiler::emit_JSOP_BUILTINPROTO()
{
// The builtin prototype is a constant for a given global.
RootedObject builtin(cx);
JSProtoKey key = static_cast<JSProtoKey>(GET_UINT8(pc));
MOZ_ASSERT(key < JSProto_LIMIT);
if (!GetBuiltinPrototype(cx, key, &builtin))
JSObject* builtin = GlobalObject::getOrCreatePrototype(cx, key);
if (!builtin)
return false;
frame.push(ObjectValue(*builtin));
return true;

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

@ -1546,16 +1546,16 @@ GetPropIRGenerator::tryAttachPrimitive(ValOperandId valId, HandleId id)
return false;
}
primitiveType = JSVAL_TYPE_STRING;
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_String));
proto = MaybeNativeObject(cx_->global()->maybeGetPrototype(JSProto_String));
} else if (val_.isNumber()) {
primitiveType = JSVAL_TYPE_DOUBLE;
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_Number));
proto = MaybeNativeObject(cx_->global()->maybeGetPrototype(JSProto_Number));
} else if (val_.isBoolean()) {
primitiveType = JSVAL_TYPE_BOOLEAN;
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_Boolean));
proto = MaybeNativeObject(cx_->global()->maybeGetPrototype(JSProto_Boolean));
} else if (val_.isSymbol()) {
primitiveType = JSVAL_TYPE_SYMBOL;
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_Symbol));
proto = MaybeNativeObject(cx_->global()->maybeGetPrototype(JSProto_Symbol));
} else {
MOZ_ASSERT(val_.isNullOrUndefined() || val_.isMagic());
return false;

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

@ -7093,8 +7093,7 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, jsid id)
return nullptr;
}
JSObject* proto = GetBuiltinPrototypePure(&script()->global(), key);
if (proto)
if (JSObject* proto = script()->global().maybeGetPrototype(key))
return testSingletonProperty(proto, id);
return nullptr;

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

@ -1224,7 +1224,11 @@ JS_GetClassObject(JSContext* cx, JSProtoKey key, MutableHandleObject objp)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
return GetBuiltinConstructor(cx, key, objp);
JSObject* obj = GlobalObject::getOrCreateConstructor(cx, key);
if (!obj)
return false;
objp.set(obj);
return true;
}
JS_PUBLIC_API(bool)
@ -1232,7 +1236,11 @@ JS_GetClassPrototype(JSContext* cx, JSProtoKey key, MutableHandleObject objp)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
return GetBuiltinPrototype(cx, key, objp);
JSObject* proto = GlobalObject::getOrCreatePrototype(cx, key);
if (!proto)
return false;
objp.set(proto);
return true;
}
namespace JS {

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

@ -3793,8 +3793,11 @@ NewArray(JSContext* cx, uint32_t length,
allocKind = GetBackgroundAllocKind(allocKind);
RootedObject proto(cx, protoArg);
if (!proto && !GetBuiltinPrototype(cx, JSProto_Array, &proto))
return nullptr;
if (!proto) {
proto = GlobalObject::getOrCreateArrayPrototype(cx, cx->global());
if (!proto)
return nullptr;
}
Rooted<TaggedProto> taggedProto(cx, TaggedProto(proto));
bool isCachable = NewObjectWithTaggedProtoIsCachable(cx, taggedProto, newKind, &ArrayObject::class_);

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

@ -842,11 +842,11 @@ js::NewObjectWithClassProtoCommon(JSContext* cx, const Class* clasp, HandleObjec
if (protoKey == JSProto_Null)
protoKey = JSProto_Object;
RootedObject proto(cx);
if (!GetBuiltinPrototype(cx, protoKey, &proto))
JSObject* proto = GlobalObject::getOrCreatePrototype(cx, protoKey);
if (!proto)
return nullptr;
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, clasp, AsTaggedProto(proto)));
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, clasp, TaggedProto(proto)));
if (!group)
return nullptr;
@ -858,8 +858,7 @@ js::NewObjectWithClassProtoCommon(JSContext* cx, const Class* clasp, HandleObjec
NewObjectCache& cache = cx->caches().newObjectCache;
NewObjectCache::EntryIndex entry = -1;
cache.lookupGlobal(clasp, global, allocKind, &entry);
cache.fillGlobal(entry, clasp, global, allocKind,
&obj->as<NativeObject>());
cache.fillGlobal(entry, clasp, global, allocKind, &obj->as<NativeObject>());
}
return obj;
@ -1960,11 +1959,10 @@ js::InitClass(JSContext* cx, HandleObject obj, HandleObject protoProto_,
* js::InitClass depend on this nicety.
*/
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
if (key != JSProto_Null &&
!protoProto &&
!GetBuiltinPrototype(cx, JSProto_Object, &protoProto))
{
return nullptr;
if (key != JSProto_Null && !protoProto) {
protoProto = GlobalObject::getOrCreatePrototype(cx, JSProto_Object);
if (!protoProto)
return nullptr;
}
return DefineConstructorAndPrototype(cx, obj, key, atom, protoProto, clasp, constructor, nargs,
@ -2103,49 +2101,6 @@ JSObject::changeToSingleton(JSContext* cx, HandleObject obj)
return true;
}
static bool
MaybeResolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key)
{
if (global->isStandardClassResolved(key))
return true;
MOZ_ASSERT(!cx->helperThread());
return GlobalObject::resolveConstructor(cx, global, key);
}
bool
js::GetBuiltinConstructor(JSContext* cx, JSProtoKey key, MutableHandleObject objp)
{
MOZ_ASSERT(key != JSProto_Null);
Rooted<GlobalObject*> global(cx, cx->global());
if (!MaybeResolveConstructor(cx, global, key))
return false;
objp.set(&global->getConstructor(key).toObject());
return true;
}
bool
js::GetBuiltinPrototype(JSContext* cx, JSProtoKey key, MutableHandleObject protop)
{
MOZ_ASSERT(key != JSProto_Null);
Rooted<GlobalObject*> global(cx, cx->global());
if (!MaybeResolveConstructor(cx, global, key))
return false;
protop.set(&global->getPrototype(key).toObject());
return true;
}
bool
js::IsStandardPrototype(JSObject* obj, JSProtoKey key)
{
GlobalObject& global = obj->global();
Value v = global.getPrototype(key);
return v.isObject() && obj == &v.toObject();
}
/**
* Returns the original Object.prototype from the embedding-provided incumbent
* global.
@ -2187,6 +2142,13 @@ js::GetObjectFromIncumbentGlobal(JSContext* cx, MutableHandleObject obj)
return true;
}
static bool
IsStandardPrototype(JSObject* obj, JSProtoKey key)
{
Value v = obj->global().getPrototype(key);
return v.isObject() && obj == &v.toObject();
}
JSProtoKey
JS::IdentifyStandardInstance(JSObject* obj)
{
@ -3226,21 +3188,6 @@ js::IsDelegateOfObject(JSContext* cx, HandleObject protoObj, JSObject* obj, bool
}
}
JSObject*
js::GetBuiltinPrototypePure(GlobalObject* global, JSProtoKey protoKey)
{
MOZ_ASSERT(JSProto_Null <= protoKey);
MOZ_ASSERT(protoKey < JSProto_LIMIT);
if (protoKey != JSProto_Null) {
const Value& v = global->getPrototype(protoKey);
if (v.isObject())
return &v.toObject();
}
return nullptr;
}
JSObject*
js::PrimitiveToObject(JSContext* cx, const Value& v)
{

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

@ -1031,19 +1031,6 @@ GetThisValueOfWith(JSObject* env);
typedef JSObject* (*ClassInitializerOp)(JSContext* cx, JS::HandleObject obj);
/* Fast access to builtin constructors and prototypes. */
bool
GetBuiltinConstructor(JSContext* cx, JSProtoKey key, MutableHandleObject objp);
bool
GetBuiltinPrototype(JSContext* cx, JSProtoKey key, MutableHandleObject objp);
JSObject*
GetBuiltinPrototypePure(GlobalObject* global, JSProtoKey protoKey);
extern bool
IsStandardPrototype(JSObject* obj, JSProtoKey key);
} /* namespace js */
namespace js {

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

@ -119,18 +119,11 @@ GlobalObject::skipDeselectedConstructor(JSContext* cx, JSProtoKey key)
}
}
/* static */ bool
GlobalObject::ensureConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key)
{
if (global->isStandardClassResolved(key))
return true;
return resolveConstructor(cx, global, key);
}
/* static*/ bool
GlobalObject::resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key)
{
MOZ_ASSERT(!global->isStandardClassResolved(key));
MOZ_ASSERT(!cx->helperThread());
// Prohibit collection of allocation metadata. Metadata builders shouldn't
// need to observe lazily-constructed prototype objects coming into

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

@ -134,11 +134,42 @@ class GlobalObject : public NativeObject
return getSlot(APPLICATION_SLOTS + key);
}
static bool skipDeselectedConstructor(JSContext* cx, JSProtoKey key);
static bool ensureConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key);
static bool resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key);
static bool initBuiltinConstructor(JSContext* cx, Handle<GlobalObject*> global,
JSProtoKey key, HandleObject ctor, HandleObject proto);
private:
static bool resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key);
public:
static bool ensureConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key) {
if (global->isStandardClassResolved(key))
return true;
return resolveConstructor(cx, global, key);
}
static JSObject* getOrCreateConstructor(JSContext* cx, JSProtoKey key) {
MOZ_ASSERT(key != JSProto_Null);
Handle<GlobalObject*> global = cx->global();
if (!GlobalObject::ensureConstructor(cx, global, key))
return nullptr;
return &global->getConstructor(key).toObject();
}
static JSObject* getOrCreatePrototype(JSContext* cx, JSProtoKey key) {
MOZ_ASSERT(key != JSProto_Null);
Handle<GlobalObject*> global = cx->global();
if (!GlobalObject::ensureConstructor(cx, global, key))
return nullptr;
return &global->getPrototype(key).toObject();
}
JSObject* maybeGetPrototype(JSProtoKey protoKey) const {
MOZ_ASSERT(JSProto_Null < protoKey);
MOZ_ASSERT(protoKey < JSProto_LIMIT);
const Value& v = getPrototype(protoKey);
return v.isObject() ? &v.toObject() : nullptr;
}
void setConstructor(JSProtoKey key, const Value& v) {
MOZ_ASSERT(key <= JSProto_LIMIT);
setSlot(APPLICATION_SLOTS + key, v);

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

@ -1769,7 +1769,8 @@ GlobalHelperThreadState::mergeParseTaskCompartment(JSContext* cx, ParseTask* par
if (key != JSProto_Null) {
MOZ_ASSERT(key == JSProto_Object || key == JSProto_Array ||
key == JSProto_Function || key == JSProto_RegExp);
newProto = GetBuiltinPrototypePure(global, key);
newProto = global->maybeGetPrototype(key);
MOZ_ASSERT(newProto);
} else if (protoObj == parseTaskGenFunctionProto) {
newProto = global->getGeneratorFunctionPrototype();
} else if (protoObj == moduleProto) {

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

@ -4146,10 +4146,10 @@ END_CASE(JSOP_CHECKCLASSHERITAGE)
CASE(JSOP_BUILTINPROTO)
{
ReservedRooted<JSObject*> builtin(&rootObject0);
MOZ_ASSERT(GET_UINT8(REGS.pc) < JSProto_LIMIT);
JSProtoKey key = static_cast<JSProtoKey>(GET_UINT8(REGS.pc));
if (!GetBuiltinPrototype(cx, key, &builtin))
JSObject* builtin = GlobalObject::getOrCreatePrototype(cx, key);
if (!builtin)
goto error;
PUSH_OBJECT(*builtin);
}

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

@ -719,10 +719,13 @@ GetClassForProtoKey(JSProtoKey key)
/* static */ ObjectGroup*
ObjectGroup::defaultNewGroup(JSContext* cx, JSProtoKey key)
{
RootedObject proto(cx);
if (key != JSProto_Null && !GetBuiltinPrototype(cx, key, &proto))
return nullptr;
return defaultNewGroup(cx, GetClassForProtoKey(key), TaggedProto(proto.get()));
JSObject* proto = nullptr;
if (key != JSProto_Null) {
proto = GlobalObject::getOrCreatePrototype(cx, key);
if (!proto)
return nullptr;
}
return defaultNewGroup(cx, GetClassForProtoKey(key), TaggedProto(proto));
}
/////////////////////////////////////////////////////////////////////
@ -844,8 +847,8 @@ ObjectGroup::newArrayObject(JSContext* cx,
if (p) {
group = p->value();
} else {
RootedObject proto(cx);
if (!GetBuiltinPrototype(cx, JSProto_Array, &proto))
JSObject* proto = GlobalObject::getOrCreateArrayPrototype(cx, cx->global());
if (!proto)
return nullptr;
Rooted<TaggedProto> taggedProto(cx, TaggedProto(proto));
group = ObjectGroupCompartment::makeGroup(cx, &ArrayObject::class_, taggedProto);
@ -1167,8 +1170,8 @@ ObjectGroup::newPlainObject(JSContext* cx, IdValuePair* properties, size_t nprop
if (!CanShareObjectGroup(properties, nproperties))
return NewPlainObjectWithProperties(cx, properties, nproperties, newKind);
RootedObject proto(cx);
if (!GetBuiltinPrototype(cx, JSProto_Object, &proto))
JSObject* proto = GlobalObject::getOrCreatePrototype(cx, JSProto_Object);
if (!proto)
return nullptr;
Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
@ -1416,9 +1419,12 @@ ObjectGroup::allocationSiteGroup(JSContext* cx, JSScript* scriptArg, jsbytecode*
}
RootedScript script(cx, scriptArg);
RootedObject proto(cx, protoArg);
if (!proto && kind != JSProto_Null && !GetBuiltinPrototype(cx, kind, &proto))
return nullptr;
JSObject* proto = protoArg;
if (!proto && kind != JSProto_Null) {
proto = GlobalObject::getOrCreatePrototype(cx, kind);
if (!proto)
return nullptr;
}
Rooted<ObjectGroupCompartment::AllocationSiteKey> key(cx,
ObjectGroupCompartment::AllocationSiteKey(script, offset, kind, proto));
@ -1665,8 +1671,8 @@ ObjectGroupCompartment::getStringSplitStringGroup(JSContext* cx)
const Class* clasp = GetClassForProtoKey(JSProto_Array);
RootedObject proto(cx);
if (!GetBuiltinPrototype(cx, JSProto_Array, &proto))
JSObject* proto = GlobalObject::getOrCreateArrayPrototype(cx, cx->global());
if (!proto)
return nullptr;
Rooted<TaggedProto> tagged(cx, TaggedProto(proto));

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

@ -231,8 +231,8 @@ intrinsic_GetBuiltinConstructor(JSContext* cx, unsigned argc, Value* vp)
RootedId id(cx, AtomToId(atom));
JSProtoKey key = JS_IdToProtoKey(cx, id);
MOZ_ASSERT(key != JSProto_Null);
RootedObject ctor(cx);
if (!GetBuiltinConstructor(cx, key, &ctor))
JSObject* ctor = GlobalObject::getOrCreateConstructor(cx, key);
if (!ctor)
return false;
args.rval().setObject(*ctor);
return true;
@ -1992,8 +1992,8 @@ intrinsic_ConstructorForTypedArray(JSContext* cx, unsigned argc, Value* vp)
// compartment, and never call the constructor in the ArrayBuffer's
// compartment from script, we are not guaranteed to have initialized
// the constructor.
RootedObject ctor(cx);
if (!GetBuiltinConstructor(cx, protoKey, &ctor))
JSObject* ctor = GlobalObject::getOrCreateConstructor(cx, protoKey);
if (!ctor)
return false;
args.rval().setObject(*ctor);

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

@ -3500,7 +3500,7 @@ PreliminaryObjectArray::sweep()
JSObject* obj = *ptr;
GlobalObject* global = obj->compartment()->unsafeUnbarrieredMaybeGlobal();
if (global && !obj->isSingleton()) {
JSObject* objectProto = GetBuiltinPrototypePure(global, JSProto_Object);
JSObject* objectProto = global->maybeGetPrototype(JSProto_Object);
obj->setGroup(objectProto->groupRaw());
MOZ_ASSERT(obj->is<NativeObject>());
MOZ_ASSERT(obj->getClass() == objectProto->getClass());

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

@ -451,8 +451,12 @@ class TypedArrayObjectTemplate : public TypedArrayObject
// the time, though, that [[Prototype]] will not be interesting. If
// it isn't, we can do some more TI optimizations.
RootedObject checkProto(cx);
if (proto && !GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &checkProto))
return nullptr;
if (proto) {
checkProto =
GlobalObject::getOrCreatePrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()));
if (!checkProto)
return nullptr;
}
AutoSetNewObjectMetadata metadata(cx);
Rooted<TypedArrayObject*> obj(cx);
@ -876,7 +880,9 @@ class TypedArrayObjectTemplate : public TypedArrayObject
// this compartment.
RootedObject protoRoot(cx, proto);
if (!protoRoot) {
if (!GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &protoRoot))
protoRoot =
GlobalObject::getOrCreatePrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()));
if (!protoRoot)
return nullptr;
}

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

@ -362,8 +362,16 @@ abstract class OldBaseTest extends BaseRobocopTest {
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mSolo,
mDriver.getGeckoLeft(), mDriver.getGeckoTop());
meh.dragSync(mScreenMidWidth, mScreenMidHeight+100, mScreenMidWidth, mScreenMidHeight-100);
mAsserter.dumpLog("waitForPreferencesText scrolled down");
foundText = mSolo.waitForText(txt);
if (!foundText) {
meh.dragSync(mScreenMidWidth, mScreenMidHeight-150, mScreenMidWidth, mScreenMidHeight+150);
mAsserter.dumpLog("waitForPreferencesText scrolled up");
foundText = mSolo.waitForText(txt);
}
}
return foundText;
}

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

@ -35,8 +35,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s",
"--symbols-path=%(symbols_path)s",
"--quiet",
@ -55,8 +53,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s",
"--symbols-path=%(symbols_path)s",
"--quiet",
@ -74,8 +70,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s",
"--symbols-path=%(symbols_path)s",
"--quiet",
@ -95,8 +89,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s",
"--symbols-path=%(symbols_path)s",
"--quiet",
@ -114,8 +106,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s",
"--symbols-path=%(symbols_path)s",
"--quiet",
@ -133,8 +123,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s",
"--symbols-path=%(symbols_path)s",
"--quiet",
@ -153,8 +141,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s",
"--symbols-path=%(symbols_path)s",
"--quiet",
@ -173,8 +159,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--httpd-path", "%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"--extra-profile-file=fonts",
@ -185,24 +169,6 @@ config = {
],
"tests": ["tests/layout/reftests/reftest.list",],
},
"reftest-debug": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
"options": [
"--app=%(app)s",
"--ignore-window-size",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--httpd-path", "%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"--extra-profile-file=fonts",
"--extra-profile-file=hyphenation",
"tests/layout/reftests/reftest.list",
],
},
"crashtest": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
@ -212,8 +178,6 @@ config = {
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--httpd-path",
"%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
@ -221,23 +185,6 @@ config = {
],
"tests": ["tests/testing/crashtest/crashtests.list",],
},
"crashtest-debug": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
"options": [
"--app=%(app)s",
"--ignore-window-size",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--httpd-path",
"%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"tests/testing/crashtest/crashtests.list",
],
},
"jsreftest": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
@ -245,28 +192,14 @@ config = {
"--app=%(app)s",
"--ignore-window-size",
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
"--utility-path=%(utility_path)s",
"--httpd-path", "%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"--extra-profile-file=jsreftest/tests/user.js",
"--suite=jstestbrowser",
],
"tests": ["../jsreftest/tests/jstests.list",],
},
"jsreftest-debug": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
"options": [
"--app=%(app)s",
"--ignore-window-size",
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"../jsreftest/tests/jstests.list",
"--extra-profile-file=jsreftest/tests/user.js",
],
},
"xpcshell": {
"run_filename": "remotexpcshelltests.py",
"testsdir": "xpcshell",

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

@ -34,7 +34,5 @@ config = {
"emulator": {
"name": "test-1",
"device_id": "emulator-5554",
"http_port": "8854", # starting http port to use for the mochitest server
"ssl_port": "4454", # starting ssl port to use for the server
},
}

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

@ -31,7 +31,5 @@ config = {
"emulator": {
"name": "test-1",
"device_id": "emulator-5554",
"http_port": "8854", # starting http port to use for the mochitest server
"ssl_port": "4454", # starting ssl port to use for the server
},
}

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

@ -23,7 +23,6 @@ from mozprocess import ProcessHandler
from mozharness.base.log import FATAL
from mozharness.base.script import BaseScript, PreScriptAction, PostScriptAction
from mozharness.base.vcs.vcsbase import VCSMixin
from mozharness.mozilla.blob_upload import BlobUploadMixin, blobupload_config_options
from mozharness.mozilla.buildbot import TBPL_RETRY, EXIT_STATUS_DICT
from mozharness.mozilla.mozbase import MozbaseMixin
@ -31,7 +30,7 @@ from mozharness.mozilla.testing.testbase import TestingMixin, testing_config_opt
from mozharness.mozilla.testing.unittest import EmulatorMixin
class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin, BaseScript,
class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, BaseScript,
MozbaseMixin):
config_options = [[
["--test-suite"],
@ -39,13 +38,6 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
"dest": "test_suite",
"default": None
}
], [
["--adb-path"],
{"action": "store",
"dest": "adb_path",
"default": None,
"help": "Path to adb",
}
], [
["--total-chunk"],
{"action": "store",
@ -63,15 +55,6 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
]] + copy.deepcopy(testing_config_options) + \
copy.deepcopy(blobupload_config_options)
error_list = [
]
virtualenv_requirements = [
]
virtualenv_modules = [
]
app_name = None
def __init__(self, require_config_file=False):
@ -87,18 +70,10 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
'install',
'run-tests',
],
default_actions=['clobber',
'start-emulator',
'download-and-extract',
'create-virtualenv',
'verify-emulator',
'install',
'run-tests',
],
require_config_file=require_config_file,
config={
'virtualenv_modules': self.virtualenv_modules,
'virtualenv_requirements': self.virtualenv_requirements,
'virtualenv_modules': [],
'virtualenv_requirements': [],
'require_test_zip': True,
# IP address of the host as seen from the emulator
'remote_webserver': '10.0.2.2',
@ -451,8 +426,6 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
'remote_webserver': c['remote_webserver'],
'xre_path': self.xre_path,
'utility_path': self.xre_path,
'http_port': self.emulator['http_port'],
'ssl_port': self.emulator['ssl_port'],
'certs_path': os.path.join(dirs['abs_work_dir'], 'tests/certs'),
# TestingMixin._download_and_extract_symbols() will set
# self.symbols_path when downloading/extracting.
@ -791,11 +764,6 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
"""
self.start_time = datetime.datetime.now()
max_verify_time = datetime.timedelta(minutes=60)
aliases = {
'reftest-debug': 'reftest',
'jsreftest-debug': 'jsreftest',
'crashtest-debug': 'crashtest',
}
verify_args = []
suites = self._query_suites()
@ -838,13 +806,12 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
subprocess.list2cmdline(final_cmd)))
self.info("##### %s log begins" % self.test_suite)
# TinderBoxPrintRe does not know about the '-debug' categories
suite_category = aliases.get(self.test_suite, self.test_suite)
suite_category = self.test_suite
parser = self.get_test_output_parser(
suite_category,
config=self.config,
log_obj=self.log_obj,
error_list=self.error_list)
error_list=[])
self.run_command(final_cmd, cwd=cwd, env=env, output_parser=parser)
tbpl_status, log_level = parser.evaluate_parser(0)
parser.append_tinderboxprint_line(self.test_suite)

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

@ -0,0 +1,86 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VTuneProfiler.h"
#include "mozilla/Bootstrap.h"
#include <memory>
using namespace std;
VTuneProfiler* VTuneProfiler::mInstance = nullptr;
void
VTuneProfiler::Initialize()
{
// This is just a 'dirty trick' to find out if the ittnotify DLL was found.
// If it wasn't this function always returns 0, otherwise it returns incrementing
// numbers, if the library was found this wastes 2 events but that should be okay.
__itt_event testEvent = __itt_event_createA("Test event", strlen("Test event"));
testEvent = __itt_event_createA("Test event 2", strlen("Test event 2"));
if (testEvent) {
mInstance = new VTuneProfiler();
}
}
void
VTuneProfiler::Shutdown()
{
}
void
VTuneProfiler::TraceInternal(const char* aName, TracingKind aKind)
{
if (aKind == TRACING_EVENT) {
return;
}
string str(aName);
auto iter = mStrings.find(str);
__itt_event event;
if (iter != mStrings.end()) {
event = iter->second;
} else {
event = __itt_event_createA(aName, str.length());
mStrings.insert({ str, event });
}
if (aKind == TRACING_INTERVAL_START) {
__itt_event_start(event);
} else {
__itt_event_end(event);
}
}
void
VTuneProfiler::RegisterThreadInternal(const char* aName)
{
string str(aName);
if (!str.compare("GeckoMain")) {
// Process main thread.
switch (XRE_GetProcessType()) {
case GeckoProcessType::GeckoProcessType_Default:
__itt_thread_set_nameA("Main Process");
break;
case GeckoProcessType::GeckoProcessType_Content:
__itt_thread_set_nameA("Content Process");
break;
case GeckoProcessType::GeckoProcessType_GMPlugin:
__itt_thread_set_nameA("Plugin Process");
break;
case GeckoProcessType::GeckoProcessType_GPU:
__itt_thread_set_nameA("GPU Process");
break;
default:
__itt_thread_set_nameA("Unknown Process");
}
return;
}
__itt_thread_set_nameA(aName);
}

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

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef VTuneProfiler_h
#define VTuneProfiler_h
// The intent here is to add 0 overhead for regular users. In order to build
// the VTune profiler code at all --enable-vtune-instrumentation needs to be
// set as a build option. Even then, when none of the environment variables
// is specified that allow us to find the ittnotify DLL, these functions
// should be minimal overhead. When starting Firefox under VTune, these
// env vars will be automatically defined, otherwise INTEL_LIBITTNOTIFY32/64
// should be set to point at the ittnotify DLL.
#ifndef MOZ_VTUNE_INSTRUMENTATION
#define VTUNE_INIT()
#define VTUNE_SHUTDOWN()
#define VTUNE_TRACING(name, kind)
#define VTUNE_REGISTER_THREAD(name)
#else
#include <stddef.h>
#include <unordered_map>
#include <string>
#include "GeckoProfiler.h"
// This is the regular Intel header, these functions are actually defined for
// us inside js/src/vtune by an intel C file which actually dynamically resolves
// them to the correct DLL. Through libxul these will 'magically' resolve.
#include "vtune/ittnotify.h"
class VTuneProfiler
{
public:
static void Initialize();
static void Shutdown();
static void Trace(const char* aName, TracingKind aKind)
{
if (mInstance) {
mInstance->TraceInternal(aName, aKind);
}
}
static void RegisterThread(const char* aName)
{
if (mInstance)
{
mInstance->RegisterThreadInternal(aName);
}
}
private:
void TraceInternal(const char* aName, TracingKind aKind);
void RegisterThreadInternal(const char* aName);
// This is null when the ittnotify DLL could not be found.
static VTuneProfiler* mInstance;
std::unordered_map<std::string, __itt_event> mStrings;
};
#define VTUNE_INIT() VTuneProfiler::Initialize()
#define VTUNE_SHUTDOWN() VTuneProfiler::Shutdown()
#define VTUNE_TRACING(name, kind) VTuneProfiler::Trace(name, kind)
#define VTUNE_REGISTER_THREAD(name) VTuneProfiler::RegisterThread(name)
#endif
#endif /* VTuneProfiler_h */

Разница между файлами не показана из-за своего большого размера Загрузить разницу