Merge m-c to autoland. a=merge

This commit is contained in:
Ryan VanderMeulen 2017-10-18 21:02:15 -04:00
Родитель 211636b4b8 cb612851ed
Коммит 9c3824dc0c
199 изменённых файлов: 3408 добавлений и 1711 удалений

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

@ -55,6 +55,7 @@ tasks:
$if: 'tasks_for == "hg-push"'
then:
- "index.gecko.v2.${repository.project}.latest.firefox.decision"
- "index.gecko.v2.${repository.project}.revision.${push.revision}.firefox.decision"
- "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.decision"
- "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
- "tc-treeherder-stage.v2.${repository.project}.${push.revision}.${push.pushlog_id}"

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

@ -76,7 +76,11 @@ async function test() {
await waitForEvent(gBrowser.selectedBrowser, "load");
let spec = gBrowser.selectedBrowser.currentURI.spec;
let pageInfo = BrowserPageInfo(spec, "mediaTab");
// Pass a dummy imageElement, if there isn't an imageElement, pageInfo.js
// will do a preview, however this sometimes will cause intermittent failures,
// see bug 1403365.
let pageInfo = BrowserPageInfo(spec, "mediaTab", {});
info("waitForEvent pageInfo");
await waitForEvent(pageInfo, "load");

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

@ -9,10 +9,6 @@ pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%
pref("startup.homepage_welcome_url.additional", "");
// The time interval between checks for a new version (in seconds)
pref("app.update.interval", 28800); // 8 hours
// The time interval between the downloading of mar file chunks in the
// background (in seconds)
// 0 means "download everything at once"
pref("app.update.download.backgroundInterval", 0);
// Give the user x seconds to react before showing the big UI. default=192 hours
pref("app.update.promptWaitTime", 691200);
// URL user can browse to manually if for some reason all update installation

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

@ -7,10 +7,6 @@ pref("startup.homepage_welcome_url", "https://www.mozilla.org/projects/firefox/%
pref("startup.homepage_welcome_url.additional", "");
// The time interval between checks for a new version (in seconds)
pref("app.update.interval", 7200); // 2 hours
// The time interval between the downloading of mar file chunks in the
// background (in seconds)
// 0 means "download everything at once"
pref("app.update.download.backgroundInterval", 0);
// Give the user x seconds to react before showing the big UI. default=12 hours
pref("app.update.promptWaitTime", 43200);
// URL user can browse to manually if for some reason all update installation

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

@ -7,10 +7,6 @@ pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%
pref("startup.homepage_welcome_url.additional", "");
// Interval: Time between checks for a new version (in seconds)
pref("app.update.interval", 43200); // 12 hours
// The time interval between the downloading of mar file chunks in the
// background (in seconds)
// 0 means "download everything at once"
pref("app.update.download.backgroundInterval", 0);
// Give the user x seconds to react before showing the big UI. default=192 hours
pref("app.update.promptWaitTime", 691200);
// URL user can browse to manually if for some reason all update installation

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

@ -7,9 +7,6 @@ pref("startup.homepage_welcome_url", "");
pref("startup.homepage_welcome_url.additional", "");
// The time interval between checks for a new version (in seconds)
pref("app.update.interval", 86400); // 24 hours
// The time interval between the downloading of mar file chunks in the
// background (in seconds)
pref("app.update.download.backgroundInterval", 60);
// Give the user x seconds to react before showing the big UI. default=24 hours
pref("app.update.promptWaitTime", 86400);
// URL user can browse to manually if for some reason all update installation

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

@ -1026,11 +1026,10 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-it
.PanelUI-remotetabs-prefs-button {
-moz-appearance: none;
background-color: #0060df;
background-color: #0096dd;
/* !important for the color as an OSX specific rule when a lightweight theme
is used for buttons in the toolbox overrides. See bug 1238531 for details */
color: white !important;
font-size: 13px;
border-radius: 2px;
/* If you change the margin or padding below, the min-height of the synced tabs
panel (e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync,
@ -1042,12 +1041,9 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-it
min-width: 200px;
}
.PanelUI-remotetabs-prefs-button:hover {
background-color: #003eaa;
}
.PanelUI-remotetabs-prefs-button:hover,
.PanelUI-remotetabs-prefs-button:hover:active {
background-color: #002275;
background-color: #018acb;
}
.remotetabs-promo-link {

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

@ -16,6 +16,7 @@ support-files =
doc_inspector_highlighter-geometry_01.html
doc_inspector_highlighter-geometry_02.html
doc_inspector_highlighter_cssshapes.html
doc_inspector_highlighter_cssshapes_iframe.html
doc_inspector_highlighter_csstransform.html
doc_inspector_highlighter_dom.html
doc_inspector_highlighter_inline.html
@ -82,6 +83,7 @@ skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keybo
[browser_inspector_highlighter-cssshape_03.js]
[browser_inspector_highlighter-cssshape_04.js]
[browser_inspector_highlighter-cssshape_05.js]
[browser_inspector_highlighter-cssshape_iframe_01.js]
[browser_inspector_highlighter-csstransform_01.js]
[browser_inspector_highlighter-csstransform_02.js]
[browser_inspector_highlighter-embed.js]

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

@ -0,0 +1,46 @@
/* 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 that shapes in iframes are updated correctly on mouse events.
const TEST_URL = URL_ROOT + "doc_inspector_highlighter_cssshapes_iframe.html";
const HIGHLIGHTER_TYPE = "ShapesHighlighter";
add_task(function* () {
let inspector = yield openInspectorForURL(TEST_URL);
let helper = yield getHighlighterHelperFor(HIGHLIGHTER_TYPE)(inspector);
let {testActor} = inspector;
yield testPolygonIframeMovePoint(testActor, helper);
yield helper.finalize();
});
function* testPolygonIframeMovePoint(testActor, helper) {
info("Displaying polygon");
yield helper.show("#polygon", {mode: "cssClipPath"}, "#frame");
let { mouse, highlightedNode } = helper;
info("Moving polygon point visible in iframe");
yield mouse.down(10, 10);
yield mouse.move(20, 20);
yield mouse.up();
yield testActor.reflow();
let computedStyle = yield highlightedNode.getComputedStyle();
let definition = computedStyle["clip-path"].value;
ok(definition.includes("10px 10px"), "Point moved to 10px 10px");
info("Moving polygon point not visible in iframe");
yield mouse.down(110, 410);
yield mouse.move(120, 420);
yield mouse.up();
yield testActor.reflow();
computedStyle = yield highlightedNode.getComputedStyle();
definition = computedStyle["clip-path"].value;
ok(definition.includes("110px 51.25%"), "Point moved to 110px 51.25%");
}

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

@ -0,0 +1,11 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE html>
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 10px;
}
</style>
<iframe id="frame" src="doc_inspector_highlighter_cssshapes.html"></iframe>

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

@ -447,8 +447,12 @@ const getHighlighterHelperFor = (type) => Task.async(
return highlighter.actorID;
},
show: function* (selector = ":root", options) {
highlightedNode = yield getNodeFront(selector, inspector);
show: function* (selector = ":root", options, frameSelector = null) {
if (frameSelector) {
highlightedNode = yield getNodeFrontInFrame(selector, frameSelector, inspector);
} else {
highlightedNode = yield getNodeFront(selector, inspector);
}
return yield highlighter.show(highlightedNode, options);
},

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

@ -83,7 +83,8 @@ define(function (require, exports, module) {
// Render the value (summary) using Reps library.
return Rep(Object.assign({}, props, {
cropLimit: 50,
noGrip: true
noGrip: true,
omitLinkHref: false,
}));
},

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

@ -105,7 +105,7 @@ To run in the browser tab, the Network Monitor needs to get some dependencies fr
The Network Monitor UI is built using [React](http://searchfox.org/mozilla-central/source/devtools/docs/frontend/react.md) components (in `src/components/`).
* **MonitorPanel** in `monitor-panel.js` is the root element.
* **MonitorPanel** in `MonitorPanel.js` is the root element.
* Three major container components are
- **Toolbar** Panel related functions.
- **RequestList** Show each request information.

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

@ -28,7 +28,7 @@
const { bindActionCreators } = require("devtools/client/shared/vendor/redux");
const { Connector } = require("./src/connector/index");
const { configureStore } = require("./src/utils/create-store");
const App = createFactory(require("./src/components/app"));
const App = createFactory(require("./src/components/App"));
const { getDisplayedRequestById } = require("./src/selectors/index");
const { EVENTS } = require("./src/constants");

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

@ -12,8 +12,8 @@ const {
const { connect } = require("devtools/client/shared/vendor/react-redux");
// Components
const MonitorPanel = createFactory(require("./monitor-panel"));
const StatisticsPanel = createFactory(require("./statistics-panel"));
const MonitorPanel = createFactory(require("./MonitorPanel"));
const StatisticsPanel = createFactory(require("./StatisticsPanel"));
const { div } = DOM;

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

@ -13,7 +13,7 @@ const { L10N } = require("../utils/l10n");
const { sortObjectKeys } = require("../utils/sort-utils");
// Component
const PropertiesView = createFactory(require("./properties-view"));
const PropertiesView = createFactory(require("./PropertiesView"));
const { div } = DOM;

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

@ -24,8 +24,8 @@ const { sortObjectKeys } = require("../utils/sort-utils");
// Components
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
const MDNLink = createFactory(require("./mdn-link"));
const PropertiesView = createFactory(require("./properties-view"));
const MDNLink = createFactory(require("./MdnLink"));
const PropertiesView = createFactory(require("./PropertiesView"));
const { Rep } = REPS;
const { button, div, input, textarea, span } = DOM;

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

@ -19,9 +19,9 @@ const { getSelectedRequest } = require("../selectors/index");
// Components
const SplitBox = createFactory(require("devtools/client/shared/components/splitter/SplitBox"));
const NetworkDetailsPanel = createFactory(require("./network-details-panel"));
const RequestList = createFactory(require("./request-list"));
const Toolbar = createFactory(require("./toolbar"));
const NetworkDetailsPanel = createFactory(require("./NetworkDetailsPanel"));
const RequestList = createFactory(require("./RequestList"));
const Toolbar = createFactory(require("./Toolbar"));
const { div } = DOM;
const MediaQueryList = window.matchMedia("(min-width: 700px)");

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

@ -14,8 +14,8 @@ const Actions = require("../actions/index");
const { getSelectedRequest } = require("../selectors/index");
// Components
const CustomRequestPanel = createFactory(require("./custom-request-panel"));
const TabboxPanel = createFactory(require("./tabbox-panel"));
const CustomRequestPanel = createFactory(require("./CustomRequestPanel"));
const TabboxPanel = createFactory(require("./TabboxPanel"));
const { div } = DOM;

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

@ -14,7 +14,7 @@ const { getUrlQuery, parseQueryString, parseFormData } = require("../utils/reque
const { sortObjectKeys } = require("../utils/sort-utils");
// Components
const PropertiesView = createFactory(require("./properties-view"));
const PropertiesView = createFactory(require("./PropertiesView"));
const { div } = DOM;

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

@ -23,7 +23,7 @@ const SearchBox = createFactory(require("devtools/client/shared/components/Searc
const TreeViewClass = require("devtools/client/shared/components/tree/TreeView");
const TreeView = createFactory(TreeViewClass);
const TreeRow = createFactory(require("devtools/client/shared/components/tree/TreeRow"));
const SourceEditor = createFactory(require("./source-editor"));
const SourceEditor = createFactory(require("./SourceEditor"));
const { div, tr, td } = DOM;
const AUTO_EXPAND_MAX_LEVEL = 7;

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

@ -11,10 +11,10 @@ const {
} = require("devtools/client/shared/vendor/react");
// Components
const RequestListContent = createFactory(require("./request-list-content"));
const RequestListEmptyNotice = createFactory(require("./request-list-empty-notice"));
const RequestListHeader = createFactory(require("./request-list-header"));
const StatusBar = createFactory(require("./status-bar"));
const RequestListContent = createFactory(require("./RequestListContent"));
const RequestListEmptyNotice = createFactory(require("./RequestListEmptyNotice"));
const RequestListHeader = createFactory(require("./RequestListHeader"));
const StatusBar = createFactory(require("./StatusBar"));
const { div } = DOM;

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

@ -20,7 +20,7 @@ const {
} = require("../selectors/index");
// Components
const RequestListItem = createFactory(require("./request-list-item"));
const RequestListItem = createFactory(require("./RequestListItem"));
const RequestListContextMenu = require("../request-list-context-menu");
const { div } = DOM;

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

@ -17,7 +17,7 @@ const { L10N } = require("../utils/l10n");
const { getPerformanceAnalysisURL } = require("../utils/mdn-utils");
// Components
const MDNLink = createFactory(require("./mdn-link"));
const MDNLink = createFactory(require("./MdnLink"));
const { button, div, span } = DOM;

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

@ -15,26 +15,26 @@ const { propertiesEqual } = require("../utils/request-utils");
const { RESPONSE_HEADERS } = require("../constants");
// Components
const RequestListColumnCause = createFactory(require("./request-list-column-cause"));
const RequestListColumnContentSize = createFactory(require("./request-list-column-content-size"));
const RequestListColumnCookies = createFactory(require("./request-list-column-cookies"));
const RequestListColumnDomain = createFactory(require("./request-list-column-domain"));
const RequestListColumnDuration = createFactory(require("./request-list-column-duration"));
const RequestListColumnEndTime = createFactory(require("./request-list-column-end-time"));
const RequestListColumnFile = createFactory(require("./request-list-column-file"));
const RequestListColumnLatency = createFactory(require("./request-list-column-latency"));
const RequestListColumnMethod = createFactory(require("./request-list-column-method"));
const RequestListColumnProtocol = createFactory(require("./request-list-column-protocol"));
const RequestListColumnRemoteIP = createFactory(require("./request-list-column-remote-ip"));
const RequestListColumnResponseHeader = createFactory(require("./request-list-column-response-header"));
const RequestListColumnResponseTime = createFactory(require("./request-list-column-response-time"));
const RequestListColumnScheme = createFactory(require("./request-list-column-scheme"));
const RequestListColumnSetCookies = createFactory(require("./request-list-column-set-cookies"));
const RequestListColumnStartTime = createFactory(require("./request-list-column-start-time"));
const RequestListColumnStatus = createFactory(require("./request-list-column-status"));
const RequestListColumnTransferredSize = createFactory(require("./request-list-column-transferred-size"));
const RequestListColumnType = createFactory(require("./request-list-column-type"));
const RequestListColumnWaterfall = createFactory(require("./request-list-column-waterfall"));
const RequestListColumnCause = createFactory(require("./RequestListColumnCause"));
const RequestListColumnContentSize = createFactory(require("./RequestListColumnContentSize"));
const RequestListColumnCookies = createFactory(require("./RequestListColumnCookies"));
const RequestListColumnDomain = createFactory(require("./RequestListColumnDomain"));
const RequestListColumnDuration = createFactory(require("./RequestListColumnDuration"));
const RequestListColumnEndTime = createFactory(require("./RequestListColumnEndTime"));
const RequestListColumnFile = createFactory(require("./RequestListColumnFile"));
const RequestListColumnLatency = createFactory(require("./RequestListColumnLatency"));
const RequestListColumnMethod = createFactory(require("./RequestListColumnMethod"));
const RequestListColumnProtocol = createFactory(require("./RequestListColumnProtocol"));
const RequestListColumnRemoteIP = createFactory(require("./RequestListColumnRemoteIp"));
const RequestListColumnResponseHeader = createFactory(require("./RequestListColumnResponseHeader"));
const RequestListColumnResponseTime = createFactory(require("./RequestListColumnResponseTime"));
const RequestListColumnScheme = createFactory(require("./RequestListColumnScheme"));
const RequestListColumnSetCookies = createFactory(require("./RequestListColumnSetCookies"));
const RequestListColumnStartTime = createFactory(require("./RequestListColumnStartTime"));
const RequestListColumnStatus = createFactory(require("./RequestListColumnStatus"));
const RequestListColumnTransferredSize = createFactory(require("./RequestListColumnTransferredSize"));
const RequestListColumnType = createFactory(require("./RequestListColumnType"));
const RequestListColumnWaterfall = createFactory(require("./RequestListColumnWaterfall"));
const { div } = DOM;

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

@ -18,7 +18,7 @@ const {
} = require("../utils/request-utils");
// Components
const PropertiesView = createFactory(require("./properties-view"));
const PropertiesView = createFactory(require("./PropertiesView"));
const { div, img } = DOM;
const JSON_SCOPE_NAME = L10N.getStr("jsonScopeName");

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

@ -14,7 +14,7 @@ const { getUrlHost } = require("../utils/request-utils");
// Components
const TreeViewClass = require("devtools/client/shared/components/tree/TreeView");
const PropertiesView = createFactory(require("./properties-view"));
const PropertiesView = createFactory(require("./PropertiesView"));
const { div, input, span } = DOM;
const NOT_AVAILABLE = L10N.getStr("netmonitor.security.notAvailable");

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

@ -25,7 +25,7 @@ const { L10N } = require("../utils/l10n");
const { getPerformanceAnalysisURL } = require("../utils/mdn-utils");
// Components
const MDNLink = createFactory(require("./mdn-link"));
const MDNLink = createFactory(require("./MdnLink"));
const { button, div } = DOM;
const MediaQueryList = window.matchMedia("(min-width: 700px)");

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

@ -15,13 +15,13 @@ const { PANELS } = require("../constants");
// Components
const Tabbar = createFactory(require("devtools/client/shared/components/tabs/TabBar"));
const TabPanel = createFactory(require("devtools/client/shared/components/tabs/Tabs").TabPanel);
const CookiesPanel = createFactory(require("./cookies-panel"));
const HeadersPanel = createFactory(require("./headers-panel"));
const ParamsPanel = createFactory(require("./params-panel"));
const ResponsePanel = createFactory(require("./response-panel"));
const SecurityPanel = createFactory(require("./security-panel"));
const StackTracePanel = createFactory(require("./stack-trace-panel"));
const TimingsPanel = createFactory(require("./timings-panel"));
const CookiesPanel = createFactory(require("./CookiesPanel"));
const HeadersPanel = createFactory(require("./HeadersPanel"));
const ParamsPanel = createFactory(require("./ParamsPanel"));
const ResponsePanel = createFactory(require("./ResponsePanel"));
const SecurityPanel = createFactory(require("./SecurityPanel"));
const StackTracePanel = createFactory(require("./StackTracePanel"));
const TimingsPanel = createFactory(require("./TimingsPanel"));
const COOKIES_TITLE = L10N.getStr("netmonitor.tab.cookies");
const HEADERS_TITLE = L10N.getStr("netmonitor.tab.headers");

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

@ -9,7 +9,7 @@ const { L10N } = require("../utils/l10n");
const { getNetMonitorTimingsURL } = require("../utils/mdn-utils");
// Components
const MDNLink = require("./mdn-link");
const MDNLink = require("./MdnLink");
const { div, span } = DOM;
const types = ["blocked", "dns", "connect", "ssl", "send", "wait", "receive"];

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

@ -3,47 +3,47 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'app.js',
'cookies-panel.js',
'custom-request-panel.js',
'headers-panel.js',
'mdn-link.js',
'monitor-panel.js',
'network-details-panel.js',
'params-panel.js',
'properties-view.js',
'request-list-column-cause.js',
'request-list-column-content-size.js',
'request-list-column-cookies.js',
'request-list-column-domain.js',
'request-list-column-duration.js',
'request-list-column-end-time.js',
'request-list-column-file.js',
'request-list-column-latency.js',
'request-list-column-method.js',
'request-list-column-protocol.js',
'request-list-column-remote-ip.js',
'request-list-column-response-header.js',
'request-list-column-response-time.js',
'request-list-column-scheme.js',
'request-list-column-set-cookies.js',
'request-list-column-start-time.js',
'request-list-column-status.js',
'request-list-column-transferred-size.js',
'request-list-column-type.js',
'request-list-column-waterfall.js',
'request-list-content.js',
'request-list-empty-notice.js',
'request-list-header.js',
'request-list-item.js',
'request-list.js',
'response-panel.js',
'security-panel.js',
'source-editor.js',
'stack-trace-panel.js',
'statistics-panel.js',
'status-bar.js',
'tabbox-panel.js',
'timings-panel.js',
'toolbar.js',
'App.js',
'CookiesPanel.js',
'CustomRequestPanel.js',
'HeadersPanel.js',
'MdnLink.js',
'MonitorPanel.js',
'NetworkDetailsPanel.js',
'ParamsPanel.js',
'PropertiesView.js',
'RequestList.js',
'RequestListColumnCause.js',
'RequestListColumnContentSize.js',
'RequestListColumnCookies.js',
'RequestListColumnDomain.js',
'RequestListColumnDuration.js',
'RequestListColumnEndTime.js',
'RequestListColumnFile.js',
'RequestListColumnLatency.js',
'RequestListColumnMethod.js',
'RequestListColumnProtocol.js',
'RequestListColumnRemoteIp.js',
'RequestListColumnResponseHeader.js',
'RequestListColumnResponseTime.js',
'RequestListColumnScheme.js',
'RequestListColumnSetCookies.js',
'RequestListColumnStartTime.js',
'RequestListColumnStatus.js',
'RequestListColumnTransferredSize.js',
'RequestListColumnType.js',
'RequestListColumnWaterfall.js',
'RequestListContent.js',
'RequestListEmptyNotice.js',
'RequestListHeader.js',
'RequestListItem.js',
'ResponsePanel.js',
'SecurityPanel.js',
'SourceEditor.js',
'StackTracePanel.js',
'StatisticsPanel.js',
'StatusBar.js',
'TabboxPanel.js',
'TimingsPanel.js',
'Toolbar.js',
)

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

@ -15,7 +15,7 @@ const {
const Message = createFactory(require("devtools/client/webconsole/new-console-output/components/Message"));
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
const TabboxPanel = createFactory(require("devtools/client/netmonitor/src/components/tabbox-panel"));
const TabboxPanel = createFactory(require("devtools/client/netmonitor/src/components/TabboxPanel"));
NetworkEventMessage.displayName = "NetworkEventMessage";

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

@ -36,7 +36,7 @@ requireHacker.global_hook("default", path => {
return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/Services")`;
case "devtools/shared/client/object-client":
return `() => {}`;
case "devtools/client/netmonitor/src/components/tabbox-panel":
case "devtools/client/netmonitor/src/components/TabboxPanel":
return "{}";
}
return undefined;

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

@ -7,7 +7,7 @@
const { CanvasFrameAnonymousContentHelper,
createSVGNode, createNode, getComputedStyle } = require("./utils/markup");
const { setIgnoreLayoutChanges, getCurrentZoom,
getAdjustedQuads } = require("devtools/shared/layout/utils");
getAdjustedQuads, getFrameOffsets } = require("devtools/shared/layout/utils");
const { AutoRefreshHighlighter } = require("./auto-refresh");
const {
getDistance,
@ -205,7 +205,20 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
return;
}
const { target, type, pageX, pageY } = event;
let { target, type, pageX, pageY } = event;
// For events on highlighted nodes in an iframe, when the event takes place
// outside the iframe. Check if event target belongs to the iframe. If it doesn't,
// adjust pageX/pageY to be relative to the iframe rather than the parent.
if (target.ownerDocument !== this.currentNode.ownerDocument) {
let [xOffset, yOffset] = getFrameOffsets(target.ownerGlobal, this.currentNode);
// xOffset/yOffset are relative to the viewport, so first find the top/left
// edges of the viewport relative to the page.
let viewportLeft = pageX - event.clientX;
let viewportTop = pageY - event.clientY;
pageX -= viewportLeft + xOffset;
pageY -= viewportTop + yOffset;
}
switch (type) {
case "pagehide":

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

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body onload="document.removeChild(document.documentElement)">
<!-- The order of the two iframes matters! -->
<iframe src='data:text/html,<body onload="s = parent.document.getElementById(&apos;s&apos;).contentWindow;" onunload="s.location = s.location;">'></iframe>
<iframe id="s"></iframe>
</body>
</html>

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

@ -7,6 +7,7 @@ load 432114-1.html
load 432114-2.html
load 436900-1.html
asserts(0-1) load 436900-2.html # bug 566159
load 443655.html
load 500328-1.html
load 514779-1.xhtml
load 614499-1.html

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

@ -4126,7 +4126,7 @@ nsDocShell::GetChildOffset(int32_t* aChildOffset)
NS_IMETHODIMP
nsDocShell::GetHistoryID(nsID** aID)
{
*aID = static_cast<nsID*>(nsMemory::Clone(&mHistoryID, sizeof(nsID)));
*aID = mHistoryID.Clone();
return NS_OK;
}

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

@ -959,7 +959,7 @@ nsSHEntry::HasDynamicallyAddedChild(bool* aAdded)
NS_IMETHODIMP
nsSHEntry::GetDocshellID(nsID** aID)
{
*aID = static_cast<nsID*>(nsMemory::Clone(&mShared->mDocShellID, sizeof(nsID)));
*aID = mShared->mDocShellID.Clone();
return NS_OK;
}

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

@ -1052,6 +1052,8 @@ CustomElementReactionsStack::Enqueue(Element* aElement,
// If the custom element reactions stack is empty, then:
// Add element to the backup element queue.
MOZ_ASSERT(!aReaction->IsUpgradeReaction(),
"Upgrade reaction should not be scheduled to backup queue");
mBackupQueue.AppendElement(aElement);
elementData->mReactionQueue.AppendElement(aReaction);

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

@ -219,6 +219,16 @@ public:
virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const
{
}
#if DEBUG
bool IsUpgradeReaction()
{
return mIsUpgradeReaction;
}
protected:
bool mIsUpgradeReaction = false;
#endif
};
class CustomElementUpgradeReaction final : public CustomElementReaction
@ -227,6 +237,9 @@ public:
explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
: mDefinition(aDefinition)
{
#if DEBUG
mIsUpgradeReaction = true;
#endif
}
private:

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

@ -493,43 +493,42 @@ NeedsScriptTraverse(nsINode* aNode)
//----------------------------------------------------------------------
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAttrChildContentList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAttrChildContentList)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsChildContentList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsChildContentList)
// If nsAttrChildContentList is changed so that any additional fields are
// If nsChildContentList is changed so that any additional fields are
// traversed by the cycle collector, then CAN_SKIP must be updated to
// check that the additional fields are null.
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsAttrChildContentList)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsChildContentList)
// nsAttrChildContentList only ever has a single child, its wrapper, so if
// nsChildContentList only ever has a single child, its wrapper, so if
// the wrapper is known-live, the list can't be part of a garbage cycle.
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsAttrChildContentList)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsChildContentList)
return tmp->HasKnownLiveWrapper();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsAttrChildContentList)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsChildContentList)
return tmp->HasKnownLiveWrapperAndDoesNotNeedTracing(tmp);
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
// CanSkipThis returns false to avoid problems with incomplete unlinking.
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsAttrChildContentList)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsChildContentList)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_INTERFACE_TABLE_HEAD(nsAttrChildContentList)
NS_INTERFACE_TABLE_HEAD(nsChildContentList)
NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
NS_INTERFACE_TABLE(nsAttrChildContentList, nsINodeList, nsIDOMNodeList)
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsAttrChildContentList)
NS_INTERFACE_TABLE(nsChildContentList, nsINodeList, nsIDOMNodeList)
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsChildContentList)
NS_INTERFACE_MAP_END
JSObject*
nsAttrChildContentList::WrapObject(JSContext *cx,
JS::Handle<JSObject*> aGivenProto)
nsChildContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
{
return NodeListBinding::Wrap(cx, this, aGivenProto);
}
NS_IMETHODIMP
nsAttrChildContentList::GetLength(uint32_t* aLength)
nsChildContentList::GetLength(uint32_t* aLength)
{
*aLength = mNode ? mNode->GetChildCount() : 0;
@ -537,7 +536,7 @@ nsAttrChildContentList::GetLength(uint32_t* aLength)
}
NS_IMETHODIMP
nsAttrChildContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn)
nsChildContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn)
{
nsINode* node = Item(aIndex);
if (!node) {
@ -550,7 +549,7 @@ nsAttrChildContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn)
}
nsIContent*
nsAttrChildContentList::Item(uint32_t aIndex)
nsChildContentList::Item(uint32_t aIndex)
{
if (mNode) {
return mNode->GetChildAt(aIndex);
@ -560,7 +559,7 @@ nsAttrChildContentList::Item(uint32_t aIndex)
}
int32_t
nsAttrChildContentList::IndexOf(nsIContent* aContent)
nsChildContentList::IndexOf(nsIContent* aContent)
{
if (mNode) {
return mNode->IndexOf(aContent);
@ -569,77 +568,6 @@ nsAttrChildContentList::IndexOf(nsIContent* aContent)
return -1;
}
//----------------------------------------------------------------------
NS_IMETHODIMP
nsParentNodeChildContentList::GetLength(uint32_t* aLength)
{
if (!mIsCacheValid && !ValidateCache()) {
*aLength = 0;
return NS_OK;
}
MOZ_ASSERT(mIsCacheValid);
*aLength = mCachedChildArray.Length();
return NS_OK;
}
NS_IMETHODIMP
nsParentNodeChildContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn)
{
nsINode* node = Item(aIndex);
if (!node) {
*aReturn = nullptr;
return NS_OK;
}
return CallQueryInterface(node, aReturn);
}
nsIContent*
nsParentNodeChildContentList::Item(uint32_t aIndex)
{
if (!mIsCacheValid && !ValidateCache()) {
return nullptr;
}
MOZ_ASSERT(mIsCacheValid);
return mCachedChildArray.SafeElementAt(aIndex, nullptr);
}
int32_t
nsParentNodeChildContentList::IndexOf(nsIContent* aContent)
{
if (!mIsCacheValid && !ValidateCache()) {
return -1;
}
MOZ_ASSERT(mIsCacheValid);
return mCachedChildArray.IndexOf(aContent);
}
bool
nsParentNodeChildContentList::ValidateCache()
{
MOZ_ASSERT(!mIsCacheValid);
MOZ_ASSERT(mCachedChildArray.IsEmpty());
nsINode* parent = GetParentObject();
if (!parent) {
return false;
}
for (nsIContent* node = parent->GetFirstChild(); node;
node = node->GetNextSibling()) {
mCachedChildArray.AppendElement(node);
}
mIsCacheValid = true;
return true;
}
//----------------------------------------------------------------------
nsIHTMLCollection*

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

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
html {
color: orange;
}
</style>
<script>
function boom()
{
document.documentElement.offsetHeight;
document.getElementById("hostW").createShadowRoot().innerHTML = '<z></z>';
document.getElementsByTagName("style")[0].remove();
}
</script>
</head>
<body onload="boom();"><div style="display: contents;" id="hostW"></div></body>
</html>

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

@ -203,6 +203,7 @@ load 1158412.html
load 1181619.html
load 1230422.html
load 1251361.html
pref(dom.webcomponents.enabled,true) load 1281715.html
load 1304437.html
pref(dom.IntersectionObserver.enabled,true) load 1324209.html
load 1324500.html

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

@ -8,7 +8,7 @@
#define nsChildContentList_h__
#include "nsISupportsImpl.h"
#include "nsINodeList.h" // base class
#include "nsINodeList.h" // base class
#include "js/TypeDecls.h" // for Handle, Value, JSObject, JSContext
class nsIContent;
@ -20,20 +20,19 @@ class nsINode;
* and Item to its existing child list.
* @see nsIDOMNodeList
*/
class nsAttrChildContentList : public nsINodeList
class nsChildContentList final : public nsINodeList
{
public:
explicit nsAttrChildContentList(nsINode* aNode)
explicit nsChildContentList(nsINode* aNode)
: mNode(aNode)
{
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsAttrChildContentList)
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
// nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx,
JS::Handle<JSObject*> aGivenProto) override;
virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
// nsIDOMNodeList interface
NS_DECL_NSIDOMNODELIST
@ -42,7 +41,7 @@ public:
virtual int32_t IndexOf(nsIContent* aContent) override;
virtual nsIContent* Item(uint32_t aIndex) override;
virtual void DropReference()
void DropReference()
{
mNode = nullptr;
}
@ -52,56 +51,13 @@ public:
return mNode;
}
protected:
virtual ~nsAttrChildContentList() {}
private:
~nsChildContentList() {}
// The node whose children make up the list.
// This is a non-owning ref which is safe because it's set to nullptr by
// DropReference() by the node slots get destroyed.
nsINode* MOZ_NON_OWNING_REF mNode;
};
class nsParentNodeChildContentList final : public nsAttrChildContentList
{
public:
explicit nsParentNodeChildContentList(nsINode* aNode)
: nsAttrChildContentList(aNode)
, mIsCacheValid(false)
{
ValidateCache();
}
// nsIDOMNodeList interface
NS_DECL_NSIDOMNODELIST
// nsINodeList interface
virtual int32_t IndexOf(nsIContent* aContent) override;
virtual nsIContent* Item(uint32_t aIndex) override;
void DropReference() override
{
InvalidateCache();
nsAttrChildContentList::DropReference();
}
void InvalidateCache()
{
mIsCacheValid = false;
mCachedChildArray.Clear();
}
private:
~nsParentNodeChildContentList() {}
// Return true if validation succeeds, false otherwise
bool ValidateCache();
// Whether cached array of child nodes is valid
bool mIsCacheValid;
// Cached array of child nodes
AutoTArray<nsIContent*, 8> mCachedChildArray;
};
#endif /* nsChildContentList_h__ */

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

@ -544,20 +544,10 @@ nsDOMClassInfo::GetInterfaces(uint32_t *aCount, nsIID ***aArray)
}
*aArray = static_cast<nsIID **>(moz_xmalloc(count * sizeof(nsIID *)));
NS_ENSURE_TRUE(*aArray, NS_ERROR_OUT_OF_MEMORY);
uint32_t i;
for (i = 0; i < count; i++) {
nsIID *iid = static_cast<nsIID *>(nsMemory::Clone(mData->mInterfaces[i],
sizeof(nsIID)));
if (!iid) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, *aArray);
return NS_ERROR_OUT_OF_MEMORY;
}
*((*aArray) + i) = iid;
*((*aArray) + i) = mData->mInterfaces[i]->Clone();
}
return NS_OK;

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

@ -409,11 +409,7 @@ nsINode::ChildNodes()
{
nsSlots* slots = Slots();
if (!slots->mChildNodes) {
// Check |!IsElement()| first to catch the common case
// without virtual call |IsNodeOfType|
slots->mChildNodes = !IsElement() && IsNodeOfType(nsINode::eATTRIBUTE) ?
new nsAttrChildContentList(this) :
new nsParentNodeChildContentList(this);
slots->mChildNodes = new nsChildContentList(this);
}
return slots->mChildNodes;
@ -1556,8 +1552,8 @@ nsresult
nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
bool aNotify, nsAttrAndChildArray& aChildArray)
{
MOZ_ASSERT(!aKid->GetParentNode(), "Inserting node that already has parent");
MOZ_ASSERT(!IsNodeOfType(nsINode::eATTRIBUTE));
NS_PRECONDITION(!aKid->GetParentNode(),
"Inserting node that already has parent");
// The id-handling code, and in the future possibly other code, need to
// react to unexpected attribute changes.
@ -1601,14 +1597,6 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
mFirstChild = aKid;
}
// Invalidate cached array of child nodes
nsSlots* slots = GetExistingSlots();
if (slots && slots->mChildNodes) {
auto childNodes =
static_cast<nsParentNodeChildContentList*>(slots->mChildNodes.get());
childNodes->InvalidateCache();
}
nsIContent* parent =
IsNodeOfType(eDOCUMENT) ? nullptr : static_cast<nsIContent*>(this);
@ -1914,10 +1902,9 @@ nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify,
// nsIDocument::GetRootElement() calls until *after* it has removed aKid from
// aChildArray. Any calls before then could potentially restore a stale
// value for our cached root element, per note in nsDocument::RemoveChildAt().
MOZ_ASSERT(aKid && aKid->GetParentNode() == this &&
aKid == GetChildAt(aIndex) &&
IndexOf(aKid) == (int32_t)aIndex, "Bogus aKid");
MOZ_ASSERT(!IsNodeOfType(nsINode::eATTRIBUTE));
NS_PRECONDITION(aKid && aKid->GetParentNode() == this &&
aKid == GetChildAt(aIndex) &&
IndexOf(aKid) == (int32_t)aIndex, "Bogus aKid");
nsMutationGuard::DidMutate();
mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_CONTENT_MODEL, aNotify);
@ -1930,14 +1917,6 @@ nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify,
aChildArray.RemoveChildAt(aIndex);
// Invalidate cached array of child nodes
nsSlots* slots = GetExistingSlots();
if (slots && slots->mChildNodes) {
auto childNodes =
static_cast<nsParentNodeChildContentList*>(slots->mChildNodes.get());
childNodes->InvalidateCache();
}
if (aNotify) {
nsNodeUtils::ContentRemoved(this, aKid, previousSibling);
}

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

@ -36,7 +36,7 @@
#endif
class nsAttrAndChildArray;
class nsAttrChildContentList;
class nsChildContentList;
struct nsCSSSelectorList;
class nsDOMAttributeMap;
class nsIAnimationObserver;
@ -1114,7 +1114,7 @@ public:
* @see nsIDOMNodeList
* @see nsGenericHTMLElement::GetChildNodes
*/
RefPtr<nsAttrChildContentList> mChildNodes;
RefPtr<nsChildContentList> mChildNodes;
/**
* Weak reference to this node. This is cleared by the destructor of

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

@ -264,6 +264,37 @@ FileReader::DoAsyncWait()
return NS_OK;
}
namespace {
void
PopulateBufferForBinaryString(char16_t* aDest, const char* aSource,
uint32_t aCount)
{
const unsigned char* source = (const unsigned char*)aSource;
char16_t* end = aDest + aCount;
while (aDest != end) {
*aDest = *source;
++aDest;
++source;
}
}
nsresult
ReadFuncBinaryString(nsIInputStream* aInputStream,
void* aClosure,
const char* aFromRawSegment,
uint32_t aToOffset,
uint32_t aCount,
uint32_t* aWriteCount)
{
char16_t* dest = static_cast<char16_t*>(aClosure) + aToOffset;
PopulateBufferForBinaryString(dest, aFromRawSegment, aCount);
*aWriteCount = aCount;
return NS_OK;
}
} // anonymous
nsresult
FileReader::DoReadData(uint64_t aCount)
{
@ -291,34 +322,35 @@ FileReader::DoReadData(uint64_t aCount)
dest += oldLen;
while (aCount > 0) {
char tmpBuffer[4096];
uint32_t minCount =
XPCOM_MIN(aCount, static_cast<uint64_t>(sizeof(tmpBuffer)));
uint32_t read;
nsresult rv = mAsyncStream->Read(tmpBuffer, minCount, &read);
if (rv == NS_BASE_STREAM_CLOSED) {
rv = NS_OK;
}
if (NS_InputStreamIsBuffered(mAsyncStream)) {
nsresult rv = mAsyncStream->ReadSegments(ReadFuncBinaryString, dest,
aCount, &bytesRead);
NS_ENSURE_SUCCESS(rv, rv);
} else {
while (aCount > 0) {
char tmpBuffer[4096];
uint32_t minCount =
XPCOM_MIN(aCount, static_cast<uint64_t>(sizeof(tmpBuffer)));
uint32_t read;
if (read == 0) {
// The stream finished too early.
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = mAsyncStream->Read(tmpBuffer, minCount, &read);
if (rv == NS_BASE_STREAM_CLOSED) {
rv = NS_OK;
}
NS_ENSURE_SUCCESS(rv, rv);
if (read == 0) {
// The stream finished too early.
return NS_ERROR_OUT_OF_MEMORY;
}
PopulateBufferForBinaryString(dest, tmpBuffer, read);
dest += read;
aCount -= read;
bytesRead += read;
}
char16_t* end = dest + read;
const unsigned char* source = (const unsigned char*)tmpBuffer;
while (dest != end) {
*dest = *source;
++dest;
++source;
}
aCount -= read;
bytesRead += read;
}
MOZ_ASSERT(size.value() == oldLen + bytesRead);

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

@ -836,7 +836,8 @@ IndexedDatabaseManager::ClearBackgroundActor()
void
IndexedDatabaseManager::NoteLiveQuotaManager(QuotaManager* aQuotaManager)
{
MOZ_ASSERT(IsMainProcess());
// This can be called during Init, so we can't use IsMainProcess() yet.
MOZ_ASSERT(sIsMainProcess);
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aQuotaManager);

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

@ -0,0 +1,21 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
function boom()
{
div = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
div.appendChild(document.getElementById("v"));
document.body.appendChild(div);
}
</script>
</head>
<body onload="boom();">
<video id="v"><source></source></video>
</body>
</html>

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<script>
function boom()
{
audio1 = document.createElement("audio");
(audio1).appendChild(document.createElement("source"));
(audio1).appendChild(document.createElement("source"));
setTimeout(function() {
audio2 = document.createElement("audio");
audio2.appendChild(audio1);
}, 100);
}
</script>
<body onload="boom();"></body>

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

@ -8,6 +8,8 @@ HTTP load 481136-1.html # needs to be HTTP to recognize the ogg as an audio file
load 492286-1.xhtml
load 493915-1.html
load 495794-1.html
load 497734-1.xhtml
load 497734-2.html
load 576612-1.html
load 752784-1.html
skip-if(Android) load 789075-1.html # bug 1374405
@ -75,7 +77,7 @@ skip-if(Android) test-pref(media.navigator.permission.disabled,true) load 102845
load 1041466.html
load 1045650.html
load 1080986.html
load 1180881.html
skip-if(Android&&AndroidVersion=='21') load 1180881.html # bug 1409365
load 1197935.html
load 1122218.html
load 1127188.html

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

@ -193,16 +193,14 @@ WebAuthnManager::WebAuthnManager()
}
void
WebAuthnManager::MaybeClearTransaction()
WebAuthnManager::ClearTransaction()
{
mClientData.reset();
mInfo.reset();
mTransactionPromise = nullptr;
if (mCurrentParent) {
StopListeningForVisibilityEvents(mCurrentParent, this);
mCurrentParent = nullptr;
if (!NS_WARN_IF(mTransaction.isNothing())) {
StopListeningForVisibilityEvents(mTransaction.ref().mParent, this);
}
mTransaction.reset();
if (mChild) {
RefPtr<WebAuthnTransactionChild> c;
mChild.swap(c);
@ -210,10 +208,33 @@ WebAuthnManager::MaybeClearTransaction()
}
}
void
WebAuthnManager::RejectTransaction(const nsresult& aError)
{
if (!NS_WARN_IF(mTransaction.isNothing())) {
mTransaction.ref().mPromise->MaybeReject(aError);
}
ClearTransaction();
}
void
WebAuthnManager::CancelTransaction(const nsresult& aError)
{
if (mChild) {
mChild->SendRequestCancel();
}
RejectTransaction(aError);
}
WebAuthnManager::~WebAuthnManager()
{
MOZ_ASSERT(NS_IsMainThread());
MaybeClearTransaction();
if (mTransaction.isSome()) {
RejectTransaction(NS_ERROR_ABORT);
}
}
RefPtr<WebAuthnManager::BackgroundActorPromise>
@ -267,7 +288,9 @@ WebAuthnManager::MakeCredential(nsPIDOMWindowInner* aParent,
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aParent);
MaybeClearTransaction();
if (mTransaction.isSome()) {
CancelTransaction(NS_ERROR_ABORT);
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aParent);
@ -442,20 +465,23 @@ WebAuthnManager::MakeCredential(nsPIDOMWindowInner* aParent,
p->Then(GetMainThreadSerialEventTarget(), __func__,
[]() {
WebAuthnManager* mgr = WebAuthnManager::Get();
if (mgr && mgr->mChild) {
mgr->mChild->SendRequestRegister(mgr->mInfo.ref());
if (mgr && mgr->mChild && mgr->mTransaction.isSome()) {
mgr->mChild->SendRequestRegister(mgr->mTransaction.ref().mInfo);
}
},
[]() {
// This case can't actually happen, we'll have crashed if the child
// failed to create.
});
mTransactionPromise = promise;
mClientData = Some(clientDataJSON);
mCurrentParent = aParent;
mInfo = Some(info);
ListenForVisibilityEvents(aParent, this);
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(WebAuthnTransaction(aParent,
promise,
Move(info),
Move(clientDataJSON)));
return promise.forget();
}
@ -466,7 +492,9 @@ WebAuthnManager::GetAssertion(nsPIDOMWindowInner* aParent,
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aParent);
MaybeClearTransaction();
if (mTransaction.isSome()) {
CancelTransaction(NS_ERROR_ABORT);
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aParent);
@ -592,8 +620,8 @@ WebAuthnManager::GetAssertion(nsPIDOMWindowInner* aParent,
p->Then(GetMainThreadSerialEventTarget(), __func__,
[]() {
WebAuthnManager* mgr = WebAuthnManager::Get();
if (mgr && mgr->mChild) {
mgr->mChild->SendRequestSign(mgr->mInfo.ref());
if (mgr && mgr->mChild && mgr->mTransaction.isSome()) {
mgr->mChild->SendRequestSign(mgr->mTransaction.ref().mInfo);
}
},
[]() {
@ -601,13 +629,14 @@ WebAuthnManager::GetAssertion(nsPIDOMWindowInner* aParent,
// failed to create.
});
// Only store off the promise if we've succeeded in sending the IPC event.
mTransactionPromise = promise;
mClientData = Some(clientDataJSON);
mCurrentParent = aParent;
mInfo = Some(info);
ListenForVisibilityEvents(aParent, this);
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(WebAuthnTransaction(aParent,
promise,
Move(info),
Move(clientDataJSON)));
return promise.forget();
}
@ -618,7 +647,9 @@ WebAuthnManager::Store(nsPIDOMWindowInner* aParent,
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aParent);
MaybeClearTransaction();
if (mTransaction.isSome()) {
CancelTransaction(NS_ERROR_ABORT);
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aParent);
@ -636,18 +667,17 @@ void
WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mTransactionPromise);
MOZ_ASSERT(mInfo.isSome());
MOZ_ASSERT(mTransaction.isSome());
CryptoBuffer regData;
if (NS_WARN_IF(!regData.Assign(aRegBuffer.Elements(), aRegBuffer.Length()))) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
mozilla::dom::CryptoBuffer aaguidBuf;
if (NS_WARN_IF(!aaguidBuf.SetCapacity(16, mozilla::fallible))) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
// TODO: Adjust the AAGUID from all zeroes in Bug 1381575 (if needed)
@ -666,7 +696,7 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
nsresult rv = U2FDecomposeRegistrationResponse(regData, pubKeyBuf, keyHandleBuf,
attestationCertBuf, signatureBuf);
if (NS_WARN_IF(NS_FAILED(rv))) {
Cancel(rv);
RejectTransaction(rv);
return;
}
MOZ_ASSERT(keyHandleBuf.Length() <= 0xFFFF);
@ -674,19 +704,19 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
nsAutoString keyHandleBase64Url;
rv = keyHandleBuf.ToJwkBase64(keyHandleBase64Url);
if (NS_WARN_IF(NS_FAILED(rv))) {
Cancel(rv);
RejectTransaction(rv);
return;
}
CryptoBuffer clientDataBuf;
if (!clientDataBuf.Assign(mClientData.ref())) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
if (!clientDataBuf.Assign(mTransaction.ref().mClientData)) {
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
CryptoBuffer rpIdHashBuf;
if (!rpIdHashBuf.Assign(mInfo.ref().RpIdHash())) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
if (!rpIdHashBuf.Assign(mTransaction.ref().mInfo.RpIdHash())) {
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
@ -694,7 +724,7 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
CryptoBuffer pubKeyObj;
rv = CBOREncodePublicKeyObj(pubKeyBuf, pubKeyObj);
if (NS_FAILED(rv)) {
Cancel(rv);
RejectTransaction(rv);
return;
}
@ -702,7 +732,7 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
// See https://github.com/w3c/webauthn/issues/507
mozilla::dom::CryptoBuffer counterBuf;
if (NS_WARN_IF(!counterBuf.SetCapacity(4, mozilla::fallible))) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
counterBuf.AppendElement(0x00, mozilla::fallible);
@ -715,7 +745,7 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
CryptoBuffer attDataBuf;
rv = AssembleAttestationData(aaguidBuf, keyHandleBuf, pubKeyObj, attDataBuf);
if (NS_FAILED(rv)) {
Cancel(rv);
RejectTransaction(rv);
return;
}
@ -723,7 +753,7 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
rv = AssembleAuthenticatorData(rpIdHashBuf, FLAG_TUP, counterBuf, attDataBuf,
authDataBuf);
if (NS_FAILED(rv)) {
Cancel(rv);
RejectTransaction(rv);
return;
}
@ -733,7 +763,7 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
rv = CBOREncodeAttestationObj(authDataBuf, attestationCertBuf, signatureBuf,
attObj);
if (NS_FAILED(rv)) {
Cancel(rv);
RejectTransaction(rv);
return;
}
@ -741,18 +771,19 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
// values returned from the authenticator as well as the clientDataJSON
// computed earlier.
RefPtr<AuthenticatorAttestationResponse> attestation =
new AuthenticatorAttestationResponse(mCurrentParent);
new AuthenticatorAttestationResponse(mTransaction.ref().mParent);
attestation->SetClientDataJSON(clientDataBuf);
attestation->SetAttestationObject(attObj);
RefPtr<PublicKeyCredential> credential = new PublicKeyCredential(mCurrentParent);
RefPtr<PublicKeyCredential> credential =
new PublicKeyCredential(mTransaction.ref().mParent);
credential->SetId(keyHandleBase64Url);
credential->SetType(NS_LITERAL_STRING("public-key"));
credential->SetRawId(keyHandleBuf);
credential->SetResponse(attestation);
mTransactionPromise->MaybeResolve(credential);
MaybeClearTransaction();
mTransaction.ref().mPromise->MaybeResolve(credential);
ClearTransaction();
}
void
@ -760,25 +791,24 @@ WebAuthnManager::FinishGetAssertion(nsTArray<uint8_t>& aCredentialId,
nsTArray<uint8_t>& aSigBuffer)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mTransactionPromise);
MOZ_ASSERT(mInfo.isSome());
MOZ_ASSERT(mTransaction.isSome());
CryptoBuffer tokenSignatureData;
if (NS_WARN_IF(!tokenSignatureData.Assign(aSigBuffer.Elements(),
aSigBuffer.Length()))) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
CryptoBuffer clientDataBuf;
if (!clientDataBuf.Assign(mClientData.ref())) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
if (!clientDataBuf.Assign(mTransaction.ref().mClientData)) {
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
CryptoBuffer rpIdHashBuf;
if (!rpIdHashBuf.Assign(mInfo.ref().RpIdHash())) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
if (!rpIdHashBuf.Assign(mTransaction.ref().mInfo.RpIdHash())) {
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
@ -788,7 +818,7 @@ WebAuthnManager::FinishGetAssertion(nsTArray<uint8_t>& aCredentialId,
nsresult rv = U2FDecomposeSignResponse(tokenSignatureData, flags, counterBuf,
signatureBuf);
if (NS_WARN_IF(NS_FAILED(rv))) {
Cancel(rv);
RejectTransaction(rv);
return;
}
@ -798,20 +828,20 @@ WebAuthnManager::FinishGetAssertion(nsTArray<uint8_t>& aCredentialId,
/* deliberately empty */ attestationDataBuf,
authenticatorDataBuf);
if (NS_WARN_IF(NS_FAILED(rv))) {
Cancel(rv);
RejectTransaction(rv);
return;
}
CryptoBuffer credentialBuf;
if (!credentialBuf.Assign(aCredentialId)) {
Cancel(NS_ERROR_OUT_OF_MEMORY);
RejectTransaction(NS_ERROR_OUT_OF_MEMORY);
return;
}
nsAutoString credentialBase64Url;
rv = credentialBuf.ToJwkBase64(credentialBase64Url);
if (NS_WARN_IF(NS_FAILED(rv))) {
Cancel(rv);
RejectTransaction(rv);
return;
}
@ -821,20 +851,20 @@ WebAuthnManager::FinishGetAssertion(nsTArray<uint8_t>& aCredentialId,
// with the values returned from the authenticator as well as the
// clientDataJSON computed earlier.
RefPtr<AuthenticatorAssertionResponse> assertion =
new AuthenticatorAssertionResponse(mCurrentParent);
new AuthenticatorAssertionResponse(mTransaction.ref().mParent);
assertion->SetClientDataJSON(clientDataBuf);
assertion->SetAuthenticatorData(authenticatorDataBuf);
assertion->SetSignature(signatureBuf);
RefPtr<PublicKeyCredential> credential =
new PublicKeyCredential(mCurrentParent);
new PublicKeyCredential(mTransaction.ref().mParent);
credential->SetId(credentialBase64Url);
credential->SetType(NS_LITERAL_STRING("public-key"));
credential->SetRawId(credentialBuf);
credential->SetResponse(assertion);
mTransactionPromise->MaybeResolve(credential);
MaybeClearTransaction();
mTransaction.ref().mPromise->MaybeResolve(credential);
ClearTransaction();
}
void
@ -842,19 +872,7 @@ WebAuthnManager::RequestAborted(const nsresult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
Cancel(aError);
}
void
WebAuthnManager::Cancel(const nsresult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
if (mTransactionPromise) {
mTransactionPromise->MaybeReject(aError);
}
MaybeClearTransaction();
RejectTransaction(aError);
}
NS_IMETHODIMP
@ -862,7 +880,6 @@ WebAuthnManager::HandleEvent(nsIDOMEvent* aEvent)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aEvent);
MOZ_ASSERT(mChild);
nsAutoString type;
aEvent->GetType(type);
@ -878,9 +895,7 @@ WebAuthnManager::HandleEvent(nsIDOMEvent* aEvent)
MOZ_LOG(gWebAuthnManagerLog, LogLevel::Debug,
("Visibility change: WebAuthn window is hidden, cancelling job."));
mChild->SendRequestCancel();
Cancel(NS_ERROR_ABORT);
CancelTransaction(NS_ERROR_ABORT);
}
return NS_OK;

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

@ -60,7 +60,33 @@ class OwningArrayBufferViewOrArrayBuffer;
struct MakePublicKeyCredentialOptions;
class Promise;
class WebAuthnTransactionChild;
class WebAuthnTransactionInfo;
class WebAuthnTransaction
{
public:
WebAuthnTransaction(nsPIDOMWindowInner* aParent,
const RefPtr<Promise>& aPromise,
const WebAuthnTransactionInfo&& aInfo,
const nsAutoCString&& aClientData)
: mParent(aParent)
, mPromise(aPromise)
, mInfo(aInfo)
, mClientData(aClientData)
{ }
// Parent of the context we're running the transaction in.
nsCOMPtr<nsPIDOMWindowInner> mParent;
// JS Promise representing the transaction status.
RefPtr<Promise> mPromise;
// Holds the parameters of the current transaction, as we need them both
// before the transaction request is sent, and on successful return.
WebAuthnTransactionInfo mInfo;
// Client data used to assemble reply objects.
nsCString mClientData;
};
class WebAuthnManager final : public nsIIPCBackgroundChildCreateCallback,
public nsIDOMEventListener
@ -100,29 +126,23 @@ private:
WebAuthnManager();
virtual ~WebAuthnManager();
void Cancel(const nsresult& aError);
void MaybeClearTransaction();
// Clears all information we have about the current transaction.
void ClearTransaction();
// Rejects the current transaction and calls ClearTransaction().
void RejectTransaction(const nsresult& aError);
// Cancels the current transaction (by sending a Cancel message to the
// parent) and rejects it by calling RejectTransaction().
void CancelTransaction(const nsresult& aError);
typedef MozPromise<nsresult, nsresult, false> BackgroundActorPromise;
RefPtr<BackgroundActorPromise> GetOrCreateBackgroundActor();
// JS Promise representing transaction status.
RefPtr<Promise> mTransactionPromise;
// IPC Channel for the current transaction.
RefPtr<WebAuthnTransactionChild> mChild;
// Parent of the context we're currently running the transaction in.
nsCOMPtr<nsPIDOMWindowInner> mCurrentParent;
// Client data, stored on successful transaction creation, so that it can be
// used to assemble reply objects.
Maybe<nsCString> mClientData;
// Holds the parameters of the current transaction, as we need them both
// before the transaction request is sent, and on successful return.
Maybe<WebAuthnTransactionInfo> mInfo;
// The current transaction, if any.
Maybe<WebAuthnTransaction> mTransaction;
// Promise for dealing with PBackground Actor creation.
MozPromiseHolder<BackgroundActorPromise> mPBackgroundCreationPromise;

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

@ -26,10 +26,9 @@
// outparams using the &-operator. But it will have to do as there's no easy
// solution.
#include "mozilla/RefPtr.h"
#include "mozilla/ServoUtils.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/ThreadSafeWeakPtr.h"
#include "mozilla/DebugOnly.h"
@ -82,28 +81,6 @@ class UnscaledFont;
class ScaledFont;
}
template<>
struct WeakPtrTraits<gfx::UnscaledFont>
{
static void AssertSafeToAccessFromNonOwningThread()
{
// We want to allow UnscaledFont objects that were created on the main
// thread to be accessed from other threads if the Servo font metrics
// mutex is locked, and for objects created on Servo style worker threads
// to be accessed later back on the main thread.
AssertIsMainThreadOrServoFontMetricsLocked();
}
};
template<>
struct WeakPtrTraits<gfx::ScaledFont>
{
static void AssertSafeToAccessFromNonOwningThread()
{
AssertIsMainThreadOrServoFontMetricsLocked();
}
};
namespace gfx {
class ScaledFont;
@ -750,13 +727,11 @@ struct GlyphMetrics
Float mHeight;
};
class UnscaledFont
: public external::AtomicRefCounted<UnscaledFont>
, public SupportsWeakPtr<UnscaledFont>
class UnscaledFont : public SupportsThreadSafeWeakPtr<UnscaledFont>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFont)
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(UnscaledFont)
MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(UnscaledFont)
virtual ~UnscaledFont();
@ -796,13 +771,11 @@ private:
* at a particular size. It is passed into text drawing calls to describe
* the font used for the drawing call.
*/
class ScaledFont
: public external::AtomicRefCounted<ScaledFont>
, public SupportsWeakPtr<ScaledFont>
class ScaledFont : public SupportsThreadSafeWeakPtr<ScaledFont>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(ScaledFont)
MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(ScaledFont)
virtual ~ScaledFont();

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

@ -30,18 +30,18 @@ class StackingContextHelper;
class TextureForwarder;
template<class T>
class WeakPtrHashKey : public PLDHashEntryHdr
class ThreadSafeWeakPtrHashKey : public PLDHashEntryHdr
{
public:
typedef T* KeyType;
typedef RefPtr<T> KeyType;
typedef const T* KeyTypePointer;
explicit WeakPtrHashKey(KeyTypePointer aKey) : mKey(const_cast<KeyType>(aKey)) {}
explicit ThreadSafeWeakPtrHashKey(KeyTypePointer aKey) : mKey(do_AddRef(const_cast<T*>(aKey))) {}
KeyType GetKey() const { return mKey; }
bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
KeyType GetKey() const { return do_AddRef(mKey); }
bool KeyEquals(KeyTypePointer aKey) const { return mKey == aKey; }
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
static KeyTypePointer KeyToPointer(const KeyType& aKey) { return aKey.get(); }
static PLDHashNumber HashKey(KeyTypePointer aKey)
{
return NS_PTR_TO_UINT32(aKey) >> 2;
@ -49,11 +49,11 @@ public:
enum { ALLOW_MEMMOVE = true };
private:
WeakPtr<T> mKey;
ThreadSafeWeakPtr<T> mKey;
};
typedef WeakPtrHashKey<gfx::UnscaledFont> UnscaledFontHashKey;
typedef WeakPtrHashKey<gfx::ScaledFont> ScaledFontHashKey;
typedef ThreadSafeWeakPtrHashKey<gfx::UnscaledFont> UnscaledFontHashKey;
typedef ThreadSafeWeakPtrHashKey<gfx::ScaledFont> ScaledFontHashKey;
class WebRenderBridgeChild final : public PWebRenderBridgeChild
, public CompositableForwarder

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

@ -591,10 +591,9 @@ gfxFont *
gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle,
bool aNeedsBold)
{
WeakPtr<UnscaledFont>& unscaledFontPtr =
ThreadSafeWeakPtr<UnscaledFontDWrite>& unscaledFontPtr =
aNeedsBold ? mUnscaledFontBold : mUnscaledFont;
RefPtr<UnscaledFontDWrite> unscaledFont =
static_cast<UnscaledFontDWrite*>(unscaledFontPtr.get());
RefPtr<UnscaledFontDWrite> unscaledFont(unscaledFontPtr);
if (!unscaledFont) {
DWRITE_FONT_SIMULATIONS sims = DWRITE_FONT_SIMULATIONS_NONE;
if (aNeedsBold) {

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

@ -212,8 +212,8 @@ protected:
int8_t mIsCJK;
bool mForceGDIClassic;
mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFontBold;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontDWrite> mUnscaledFont;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontDWrite> mUnscaledFontBold;
};
// custom text renderer used to determine the fallback font for a given char

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

@ -249,8 +249,7 @@ FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold
return nullptr;
}
RefPtr<UnscaledFontFreeType> unscaledFont =
static_cast<UnscaledFontFreeType*>(mUnscaledFont.get());
RefPtr<UnscaledFontFreeType> unscaledFont(mUnscaledFont);
if (!unscaledFont) {
unscaledFont =
mFilename.IsEmpty() ?

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

@ -98,7 +98,7 @@ public:
nsCString mFilename;
uint8_t mFTFontIndex;
mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFreeType> mUnscaledFont;
};
class FT2FontFamily : public gfxFontFamily

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

@ -814,7 +814,7 @@ PreparePattern(FcPattern* aPattern, bool aIsPrinterFont)
void
gfxFontconfigFontEntry::UnscaledFontCache::MoveToFront(size_t aIndex) {
if (aIndex > 0) {
WeakPtr<UnscaledFont> front =
ThreadSafeWeakPtr<UnscaledFontFontconfig> front =
Move(mUnscaledFonts[aIndex]);
for (size_t i = aIndex; i > 0; i--) {
mUnscaledFonts[i] = Move(mUnscaledFonts[i-1]);
@ -826,13 +826,12 @@ gfxFontconfigFontEntry::UnscaledFontCache::MoveToFront(size_t aIndex) {
already_AddRefed<UnscaledFontFontconfig>
gfxFontconfigFontEntry::UnscaledFontCache::Lookup(const char* aFile, uint32_t aIndex) {
for (size_t i = 0; i < kNumEntries; i++) {
UnscaledFontFontconfig* entry =
static_cast<UnscaledFontFontconfig*>(mUnscaledFonts[i].get());
RefPtr<UnscaledFontFontconfig> entry(mUnscaledFonts[i]);
if (entry &&
!strcmp(entry->GetFile(), aFile) &&
entry->GetIndex() == aIndex) {
MoveToFront(i);
return do_AddRef(entry);
return entry.forget();
}
}
return nullptr;

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

@ -167,7 +167,7 @@ protected:
void MoveToFront(size_t aIndex);
static const size_t kNumEntries = 3;
mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFonts[kNumEntries];
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFontconfig> mUnscaledFonts[kNumEntries];
};
UnscaledFontCache mUnscaledFontCache;

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

@ -244,8 +244,7 @@ GDIFontEntry::CopyFontTable(uint32_t aTableTag, nsTArray<uint8_t>& aBuffer)
already_AddRefed<UnscaledFontGDI>
GDIFontEntry::LookupUnscaledFont(HFONT aFont)
{
RefPtr<UnscaledFontGDI> unscaledFont =
static_cast<UnscaledFontGDI*>(mUnscaledFont.get());
RefPtr<UnscaledFontGDI> unscaledFont(mUnscaledFont);
if (!unscaledFont) {
LOGFONT lf;
GetObject(aFont, sizeof(LOGFONT), &lf);

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

@ -204,7 +204,7 @@ protected:
LOGFONTW mLogFont;
mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontGDI> mUnscaledFont;
};
// a single font family, referencing one or more faces

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

@ -103,7 +103,7 @@ protected:
bool mCheckedForTracking;
nsTHashtable<nsUint32HashKey> mAvailableTables;
mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont;
// For AAT font being shaped by Core Text, a strong reference to the 'trak'
// table (if present).

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

@ -264,8 +264,7 @@ MacOSFontEntry::ReadCMAP(FontInfoData *aFontInfoData)
gfxFont*
MacOSFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold)
{
RefPtr<UnscaledFontMac> unscaledFont =
static_cast<UnscaledFontMac*>(mUnscaledFont.get());
RefPtr<UnscaledFontMac> unscaledFont(mUnscaledFont);
if (!unscaledFont) {
CGFontRef baseFont = GetFontRef();
if (!baseFont) {

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

@ -5313,6 +5313,37 @@ BytecodeEmitter::emitIteratorNext(ParseNode* pn, IteratorKind iterKind /* = Iter
return true;
}
bool
BytecodeEmitter::emitPushNotUndefinedOrNull()
{
MOZ_ASSERT(this->stackDepth > 0); // V
if (!emit1(JSOP_DUP)) // V V
return false;
if (!emit1(JSOP_UNDEFINED)) // V V UNDEFINED
return false;
if (!emit1(JSOP_STRICTNE)) // V ?NEQL
return false;
JumpList undefinedOrNullJump;
if (!emitJump(JSOP_AND, &undefinedOrNullJump)) // V ?NEQL
return false;
if (!emit1(JSOP_POP)) // V
return false;
if (!emit1(JSOP_DUP)) // V V
return false;
if (!emit1(JSOP_NULL)) // V V NULL
return false;
if (!emit1(JSOP_STRICTNE)) // V ?NEQL
return false;
if (!emitJumpTargetAndPatch(undefinedOrNullJump)) // V NOT-UNDEF-OR-NULL
return false;
return true;
}
bool
BytecodeEmitter::emitIteratorClose(IteratorKind iterKind /* = IteratorKind::Sync */,
CompletionKind completionKind /* = CompletionKind::Normal */,
@ -5338,15 +5369,12 @@ BytecodeEmitter::emitIteratorClose(IteratorKind iterKind /* = IteratorKind::Sync
// Step 4.
//
// Do nothing if "return" is null or undefined.
// Do nothing if "return" is undefined or null.
IfThenElseEmitter ifReturnMethodIsDefined(this);
if (!emit1(JSOP_DUP)) // ... ITER RET RET
if (!emitPushNotUndefinedOrNull()) // ... ITER RET NOT-UNDEF-OR-NULL
return false;
if (!emit1(JSOP_UNDEFINED)) // ... ITER RET RET UNDEFINED
return false;
if (!emit1(JSOP_NE)) // ... ITER RET ?NEQL
return false;
if (!ifReturnMethodIsDefined.emitIfElse())
if (!ifReturnMethodIsDefined.emitIfElse()) // ... ITER RET
return false;
if (completionKind == CompletionKind::Throw) {
@ -5447,10 +5475,12 @@ BytecodeEmitter::emitIteratorClose(IteratorKind iterKind /* = IteratorKind::Sync
}
}
if (!ifReturnMethodIsDefined.emitElse())
if (!ifReturnMethodIsDefined.emitElse()) // ... ITER RET
return false;
if (!emit1(JSOP_POP)) // ... ITER
return false;
if (!ifReturnMethodIsDefined.emitEnd())
return false;
@ -7024,11 +7054,9 @@ BytecodeEmitter::emitAsyncIterator()
return false;
IfThenElseEmitter ifAsyncIterIsUndefined(this);
if (!emit1(JSOP_DUP)) // OBJ ITERFN ITERFN
if (!emitPushNotUndefinedOrNull()) // OBJ ITERFN !UNDEF-OR-NULL
return false;
if (!emit1(JSOP_UNDEFINED)) // OBJ ITERFN ITERFN UNDEF
return false;
if (!emit1(JSOP_EQ)) // OBJ ITERFN EQ
if (!emit1(JSOP_NOT)) // OBJ ITERFN UNDEF-OR-NULL
return false;
if (!ifAsyncIterIsUndefined.emitIfElse()) // OBJ ITERFN
return false;
@ -8920,13 +8948,9 @@ BytecodeEmitter::emitYieldStar(ParseNode* iter)
// Step iii.
//
// Do nothing if "return" is undefined.
// Do nothing if "return" is undefined or null.
IfThenElseEmitter ifReturnMethodIsDefined(this);
if (!emit1(JSOP_DUP)) // ITER RESULT FTYPE FVALUE ITER RET RET
return false;
if (!emit1(JSOP_UNDEFINED)) // ITER RESULT FTYPE FVALUE ITER RET RET UNDEFINED
return false;
if (!emit1(JSOP_NE)) // ITER RESULT FTYPE FVALUE ITER RET ?NEQL
if (!emitPushNotUndefinedOrNull()) // ITER RESULT FTYPE FVALUE ITER RET NOT-UNDEF-OR-NULL
return false;
// Step iv.

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

@ -508,6 +508,9 @@ struct MOZ_STACK_CLASS BytecodeEmitter
// Helper to emit JSOP_CHECKISCALLABLE.
MOZ_MUST_USE bool emitCheckIsCallable(CheckIsCallableKind kind);
// Push whether the value atop of the stack is non-undefined and non-null.
MOZ_MUST_USE bool emitPushNotUndefinedOrNull();
// Emit a bytecode followed by an uint16 immediate operand stored in
// big-endian order.
MOZ_MUST_USE bool emitUint16Operand(JSOp op, uint32_t operand);

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

@ -150,6 +150,81 @@ check_one("super(...)",
},
" is not a function");
check_one("super.a",
function() {
class X extends Object {
test() {
super.a();
}
}
var x = new X();
x.test();
},
" is not a function");
check_one("super[a]",
function() {
var a = "a";
class X extends Object {
test() {
super[a]();
}
}
var x = new X();
x.test();
},
" is not a function");
check_one("super.a(...)",
function() {
class Y {
a() {
return 5;
}
}
class X extends Y {
test() {
super.a()();
}
}
var x = new X();
x.test();
},
" is not a function");
check_one("super[a](...)",
function() {
class Y {
a() {
return 5;
}
}
var a = "a";
class X extends Y {
test() {
super[a]()();
}
}
var x = new X();
x.test();
},
" is not a function");
check_one("super[1]",
function() {
class X extends Object {
foo() {
return super[1]();
}
}
new X().foo();
},
" is not a function");
check_one("eval(...)",
function() { eval("")(); },
" is not a function");

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

@ -0,0 +1,87 @@
class Y {
a() {
assertEq(this.__proto__, X.prototype);
return 1;
}
b() {
assertEq(this.__proto__, X.prototype);
return 2;
}
}
class X extends Y {
a() { throw "not invoked"; }
b() {
return super.a() + super.b();
}
c(i) {
var a, b;
if (i % 2) {
a = "a";
b = "b"
} else {
a = "b";
b = "a";
}
return super[a]() + super[b]();
}
}
function simple() {
var x = new X();
assertEq(x.b(), 3);
assertEq(x.c(), 3);
}
class A {
b() { return 1;}
}
class B extends A {
a() {
assertEq(super.b(), 1);
}
}
function nullHomeObjectSuperBase(i) {
var b = new B();
if (i == 500) {
Object.setPrototypeOf(B.prototype, null);
// Don't crash
}
b.a();
}
class SArray extends Array {
constructor() {
super("a", "b");
}
a() {
assertEq(super.length, 0);
assertEq(this.length, 2);
assertEq(this[0], "a");
assertEq(this[1], "b");
assertEq(super[0], undefined);
assertEq(super[1], undefined);
}
}
function array() {
var s = new SArray();
s.a();
}
for (var i = 0; i < 1e4; i++) {
simple();
array();
try {
nullHomeObjectSuperBase(i);
} catch (e) {
assertEq(i >= 500, true);
}
}

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

@ -1114,6 +1114,12 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC,
JitSpew(JitSpew_BaselineBailouts, " Popping top stack value into R0.");
builder.popValueInto(PCMappingSlotInfo::SlotInR0);
if (JSOp(*pc) == JSOP_GETELEM_SUPER) {
// Push a fake value so that the stack stays balanced.
if (!builder.writeValue(UndefinedValue(), "GETELEM_SUPER stack blance"))
return false;
}
// Need to adjust the frameSize for the frame to match the values popped
// into registers.
frameSize -= sizeof(Value);

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

@ -2088,6 +2088,11 @@ BaselineCacheIRCompiler::init(CacheKind kind)
allocator.initInputLocation(1, R1);
break;
case CacheKind::GetElemSuper:
MOZ_ASSERT(numInputs == 3);
allocator.initInputLocation(0, BaselineFrameSlot(0));
allocator.initInputLocation(1, R0);
allocator.initInputLocation(2, R1);
break;
case CacheKind::SetElem:
MOZ_ASSERT(numInputs == 3);
allocator.initInputLocation(0, R0);

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

@ -2307,21 +2307,21 @@ BaselineCompiler::emit_JSOP_GETELEM()
bool
BaselineCompiler::emit_JSOP_GETELEM_SUPER()
{
// Index -> R1, Receiver -> R2, Object -> R0
frame.popRegsAndSync(1);
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R2);
masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R1);
// Store obj in the scratch slot.
storeValue(frame.peek(-1), frame.addressOfScratchValue(), R2);
frame.pop();
// Keep receiver on stack.
frame.popn(2);
frame.push(R2);
frame.syncStack(0);
// Keep index and receiver in R0 and R1.
frame.popRegsAndSync(2);
// Keep obj on the stack.
frame.pushScratchValue();
ICGetElem_Fallback::Compiler stubCompiler(cx, /* hasReceiver = */ true);
if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
return false;
frame.pop();
frame.pop(); // This value is also popped in InitFromBailout.
frame.push(R0);
return true;
}

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