зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c. a=merge
This commit is contained in:
Коммит
cb612851ed
|
@ -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('s').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;
|
||||
|
|
37
gfx/2d/2D.h
37
gfx/2d/2D.h
|
@ -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;
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче