forked from mirrors/gecko-dev
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
a7cadef96e
146 changed files with 2884 additions and 780 deletions
|
|
@ -5,28 +5,60 @@
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionParent",
|
||||
"resource://gre/modules/ExtensionParent.jsm");
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
|
||||
var {
|
||||
promiseEvent,
|
||||
} = ExtensionUtils;
|
||||
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
function getBrowser(sidebar) {
|
||||
let browser = document.getElementById("webext-panels-browser");
|
||||
if (browser) {
|
||||
return Promise.resolve(browser);
|
||||
}
|
||||
|
||||
browser = document.createElementNS(XUL_NS, "browser");
|
||||
browser.setAttribute("id", "webext-panels-browser");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute("flex", "1");
|
||||
browser.setAttribute("disableglobalhistory", "true");
|
||||
browser.setAttribute("webextension-view-type", "sidebar");
|
||||
browser.setAttribute("context", "contentAreaContextMenu");
|
||||
browser.setAttribute("tooltip", "aHTMLTooltip");
|
||||
browser.setAttribute("onclick", "window.parent.contentAreaClick(event, true);");
|
||||
|
||||
let readyPromise;
|
||||
if (sidebar.remote) {
|
||||
browser.setAttribute("remote", "true");
|
||||
browser.setAttribute("remoteType",
|
||||
E10SUtils.getRemoteTypeForURI(sidebar.uri, true,
|
||||
E10SUtils.EXTENSION_REMOTE_TYPE));
|
||||
readyPromise = promiseEvent(browser, "XULFrameLoaderCreated");
|
||||
} else {
|
||||
readyPromise = Promise.resolve();
|
||||
}
|
||||
document.documentElement.appendChild(browser);
|
||||
|
||||
return readyPromise.then(() => {
|
||||
browser.messageManager.loadFrameScript("chrome://browser/content/content.js", false);
|
||||
ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
|
||||
return browser;
|
||||
});
|
||||
}
|
||||
|
||||
function loadWebPanel() {
|
||||
let sidebarURI = new URL(location);
|
||||
let uri = sidebarURI.searchParams.get("panel");
|
||||
let remote = sidebarURI.searchParams.get("remote");
|
||||
let browser = document.getElementById("webext-panels-browser");
|
||||
if (remote) {
|
||||
let remoteType = E10SUtils.getRemoteTypeForURI(uri, true,
|
||||
E10SUtils.EXTENSION_REMOTE_TYPE);
|
||||
browser.setAttribute("remote", "true");
|
||||
browser.setAttribute("remoteType", remoteType);
|
||||
} else {
|
||||
browser.removeAttribute("remote");
|
||||
browser.removeAttribute("remoteType");
|
||||
}
|
||||
browser.loadURI(uri);
|
||||
let sidebar = {
|
||||
uri: sidebarURI.searchParams.get("panel"),
|
||||
remote: sidebarURI.searchParams.get("remote"),
|
||||
};
|
||||
getBrowser(sidebar).then(browser => {
|
||||
browser.loadURI(sidebar.uri);
|
||||
});
|
||||
}
|
||||
|
||||
function load() {
|
||||
let browser = document.getElementById("webext-panels-browser");
|
||||
browser.messageManager.loadFrameScript("chrome://browser/content/content.js", true);
|
||||
ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
|
||||
|
||||
this.loadWebPanel();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,9 +65,4 @@
|
|||
</popupset>
|
||||
|
||||
<commandset id="editMenuCommands"/>
|
||||
<browser id="webext-panels-browser"
|
||||
type="content" flex="1"
|
||||
webextension-view-type="sidebar"
|
||||
context="contentAreaContextMenu" tooltip="aHTMLTooltip"
|
||||
onclick="window.parent.contentAreaClick(event, true);"/>
|
||||
</page>
|
||||
|
|
|
|||
|
|
@ -187,21 +187,24 @@ extensions.registerSchemaAPI("browsingData", "addon_parent", context => {
|
|||
|
||||
// since will be the start of what is returned by Sanitizer.getClearRange
|
||||
// divided by 1000 to convert to ms.
|
||||
let since = Sanitizer.getClearRange()[0] / 1000;
|
||||
// If Sanitizer.getClearRange returns undefined that means the range is
|
||||
// currently "Everything", so we should set since to 0.
|
||||
let clearRange = Sanitizer.getClearRange();
|
||||
let since = clearRange ? clearRange[0] / 1000 : 0;
|
||||
let options = {since};
|
||||
|
||||
let dataToRemove = {};
|
||||
let dataRemovalPermitted = {};
|
||||
|
||||
for (let item of PREF_LIST) {
|
||||
dataToRemove[item] = Preferences.get(`${PREF_DOMAIN}${item}`);
|
||||
// The property formData needs a different case than the
|
||||
// formdata preference.
|
||||
const name = item === "formdata" ? "formData" : item;
|
||||
dataToRemove[name] = Preferences.get(`${PREF_DOMAIN}${item}`);
|
||||
// Firefox doesn't have the same concept of dataRemovalPermitted
|
||||
// as Chrome, so it will always be true.
|
||||
dataRemovalPermitted[item] = true;
|
||||
dataRemovalPermitted[name] = true;
|
||||
}
|
||||
// formData has a different case than the pref formdata.
|
||||
dataToRemove.formData = Preferences.get(`${PREF_DOMAIN}formdata`);
|
||||
dataRemovalPermitted.formData = true;
|
||||
|
||||
return Promise.resolve({options, dataToRemove, dataRemovalPermitted});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -544,8 +544,9 @@ class Tab extends TabBase {
|
|||
|
||||
if (extension.tabManager.hasTabPermission(tabData)) {
|
||||
let entries = tabData.state ? tabData.state.entries : tabData.entries;
|
||||
result.url = entries[0].url;
|
||||
result.title = entries[0].title;
|
||||
let entry = entries[entries.length - 1];
|
||||
result.url = entry.url;
|
||||
result.title = entry.title;
|
||||
if (tabData.image) {
|
||||
result.favIconUrl = tabData.image;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,3 +95,36 @@ add_task(function* test_sessions_get_recently_closed() {
|
|||
|
||||
yield extension.unload();
|
||||
});
|
||||
|
||||
add_task(function* test_sessions_get_recently_closed_navigated() {
|
||||
function background() {
|
||||
browser.sessions.getRecentlyClosed({maxResults: 1}).then(recentlyClosed => {
|
||||
let tab = recentlyClosed[0].window.tabs[0];
|
||||
browser.test.assertEq("http://example.com/", tab.url,
|
||||
"Tab in closed window has the expected url.");
|
||||
browser.test.assertTrue(tab.title.includes("mochitest index"),
|
||||
"Tab in closed window has the expected title.");
|
||||
browser.test.notifyPass("getRecentlyClosed with navigation");
|
||||
});
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
permissions: ["sessions", "tabs"],
|
||||
},
|
||||
background,
|
||||
});
|
||||
|
||||
// Test with a window with navigation history.
|
||||
let win = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
for (let url of ["about:robots", "about:mozilla", "http://example.com/"]) {
|
||||
yield BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, url);
|
||||
yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
|
||||
}
|
||||
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
|
||||
yield extension.startup();
|
||||
yield extension.awaitFinish();
|
||||
yield extension.unload();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -126,6 +126,49 @@ add_task(function* sidebar_empty_panel() {
|
|||
yield extension.unload();
|
||||
});
|
||||
|
||||
add_task(function* sidebar_tab_query_bug_1340739() {
|
||||
let data = {
|
||||
manifest: {
|
||||
"permissions": [
|
||||
"tabs",
|
||||
],
|
||||
"sidebar_action": {
|
||||
"default_panel": "sidebar.html",
|
||||
},
|
||||
},
|
||||
useAddonManager: "temporary",
|
||||
files: {
|
||||
"sidebar.html": `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><meta charset="utf-8"/>
|
||||
<script src="sidebar.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
A Test Sidebar
|
||||
</body></html>
|
||||
`,
|
||||
"sidebar.js": function() {
|
||||
Promise.all([
|
||||
browser.tabs.query({}).then((tabs) => {
|
||||
browser.test.assertEq(1, tabs.length, "got tab without currentWindow");
|
||||
}),
|
||||
browser.tabs.query({currentWindow: true}).then((tabs) => {
|
||||
browser.test.assertEq(1, tabs.length, "got tab with currentWindow");
|
||||
}),
|
||||
]).then(() => {
|
||||
browser.test.sendMessage("sidebar");
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension(data);
|
||||
yield extension.startup();
|
||||
yield extension.awaitMessage("sidebar");
|
||||
yield extension.unload();
|
||||
});
|
||||
|
||||
add_task(function* cleanup() {
|
||||
// This is set on initial sidebar install.
|
||||
Services.prefs.clearUserPref("extensions.sidebar-button.shown");
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@
|
|||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
|
||||
"resource://gre/modules/Preferences.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Sanitizer",
|
||||
"resource:///modules/Sanitizer.jsm");
|
||||
|
||||
const PREF_DOMAIN = "privacy.cpd.";
|
||||
const SETTINGS_LIST = ["cache", "cookies", "history", "formData", "downloads"].sort();
|
||||
|
||||
add_task(function* testSettings() {
|
||||
add_task(function* testSettingsProperties() {
|
||||
function background() {
|
||||
browser.test.onMessage.addListener(msg => {
|
||||
browser.browsingData.settings().then(settings => {
|
||||
|
|
@ -25,21 +28,19 @@ add_task(function* testSettings() {
|
|||
|
||||
yield extension.startup();
|
||||
|
||||
let branch = Services.prefs.getBranch(PREF_DOMAIN);
|
||||
|
||||
extension.sendMessage("settings");
|
||||
let settings = yield extension.awaitMessage("settings");
|
||||
|
||||
let since = Sanitizer.getClearRange()[0] / 1000;
|
||||
|
||||
// Because it is based on the current timestamp, we cannot know the exact
|
||||
// value to expect for since, so allow a 10s variance.
|
||||
ok(Math.abs(settings.options.since - since) < 10000,
|
||||
"settings.options contains the expected since value.");
|
||||
// Verify that we get the keys back we expect.
|
||||
deepEqual(Object.keys(settings.dataToRemove).sort(), SETTINGS_LIST,
|
||||
"dataToRemove contains expected properties.");
|
||||
deepEqual(Object.keys(settings.dataRemovalPermitted).sort(), SETTINGS_LIST,
|
||||
"dataToRemove contains expected properties.");
|
||||
|
||||
let dataTypeSet = settings.dataToRemove;
|
||||
for (let key of Object.keys(dataTypeSet)) {
|
||||
equal(branch.getBoolPref(key.toLowerCase()), dataTypeSet[key], `${key} property of dataToRemove matches the expected pref.`);
|
||||
equal(Preferences.get(`${PREF_DOMAIN}${key.toLowerCase()}`), dataTypeSet[key],
|
||||
`${key} property of dataToRemove matches the expected pref.`);
|
||||
}
|
||||
|
||||
dataTypeSet = settings.dataRemovalPermitted;
|
||||
|
|
@ -48,29 +49,69 @@ add_task(function* testSettings() {
|
|||
}
|
||||
|
||||
// Explicitly set a pref to both true and false and then check.
|
||||
const SINGLE_PREF = "cache";
|
||||
const SINGLE_OPTION = "cache";
|
||||
const SINGLE_PREF = "privacy.cpd.cache";
|
||||
|
||||
do_register_cleanup(() => {
|
||||
branch.clearUserPref(SINGLE_PREF);
|
||||
Preferences.reset(SINGLE_PREF);
|
||||
});
|
||||
|
||||
branch.setBoolPref(SINGLE_PREF, true);
|
||||
Preferences.set(SINGLE_PREF, true);
|
||||
|
||||
extension.sendMessage("settings");
|
||||
settings = yield extension.awaitMessage("settings");
|
||||
equal(settings.dataToRemove[SINGLE_OPTION], true, "Preference that was set to true returns true.");
|
||||
|
||||
equal(settings.dataToRemove[SINGLE_PREF], true, "Preference that was set to true returns true.");
|
||||
|
||||
branch.setBoolPref(SINGLE_PREF, false);
|
||||
Preferences.set(SINGLE_PREF, false);
|
||||
|
||||
extension.sendMessage("settings");
|
||||
settings = yield extension.awaitMessage("settings");
|
||||
|
||||
equal(settings.dataToRemove[SINGLE_PREF], false, "Preference that was set to false returns false.");
|
||||
|
||||
do_register_cleanup(() => {
|
||||
branch.clearUserPref(SINGLE_PREF);
|
||||
});
|
||||
equal(settings.dataToRemove[SINGLE_OPTION], false, "Preference that was set to false returns false.");
|
||||
|
||||
yield extension.unload();
|
||||
});
|
||||
|
||||
add_task(function* testSettingsSince() {
|
||||
const TIMESPAN_PREF = "privacy.sanitize.timeSpan";
|
||||
const TEST_DATA = {
|
||||
TIMESPAN_5MIN: Date.now() - 5 * 60 * 1000,
|
||||
TIMESPAN_HOUR: Date.now() - 60 * 60 * 1000,
|
||||
TIMESPAN_2HOURS: Date.now() - 2 * 60 * 60 * 1000,
|
||||
TIMESPAN_EVERYTHING: 0,
|
||||
};
|
||||
|
||||
function background() {
|
||||
browser.test.onMessage.addListener(msg => {
|
||||
browser.browsingData.settings().then(settings => {
|
||||
browser.test.sendMessage("settings", settings);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
background,
|
||||
manifest: {
|
||||
permissions: ["browsingData"],
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
do_register_cleanup(() => {
|
||||
Preferences.reset(TIMESPAN_PREF);
|
||||
});
|
||||
|
||||
for (let timespan in TEST_DATA) {
|
||||
Preferences.set(TIMESPAN_PREF, Sanitizer[timespan]);
|
||||
|
||||
extension.sendMessage("settings");
|
||||
let settings = yield extension.awaitMessage("settings");
|
||||
|
||||
// Because it is based on the current timestamp, we cannot know the exact
|
||||
// value to expect for since, so allow a 10s variance.
|
||||
ok(Math.abs(settings.options.since - TEST_DATA[timespan]) < 10000,
|
||||
"settings.options contains the expected since value.");
|
||||
}
|
||||
|
||||
yield extension.unload();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ webextPerms.description.history=Access browsing history
|
|||
# %S will be replaced with the name of the application
|
||||
webextPerms.description.nativeMessaging=Exchange messages with programs other than %S
|
||||
webextPerms.description.notifications=Display notifications to you
|
||||
webextPerms.description.privacy=Read and modify privacy settings
|
||||
webextPerms.description.sessions=Access recently closed tabs
|
||||
webextPerms.description.tabs=Access browser tabs
|
||||
webextPerms.description.topSites=Access browsing history
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ included_inclnames_to_ignore = set([
|
|||
'unicode/udat.h', # ICU
|
||||
'unicode/udatpg.h', # ICU
|
||||
'unicode/uenum.h', # ICU
|
||||
'unicode/uloc.h', # ICU
|
||||
'unicode/unorm2.h', # ICU
|
||||
'unicode/unum.h', # ICU
|
||||
'unicode/unumsys.h', # ICU
|
||||
|
|
|
|||
|
|
@ -158,9 +158,9 @@ const RequestListContent = createClass({
|
|||
return false;
|
||||
}
|
||||
|
||||
if (requestItem.responseContent && target.closest(".requests-menu-icon-and-file")) {
|
||||
if (requestItem.responseContent && target.closest(".requests-list-icon-and-file")) {
|
||||
return setTooltipImageContent(tooltip, itemEl, requestItem);
|
||||
} else if (requestItem.cause && target.closest(".requests-menu-cause-stack")) {
|
||||
} else if (requestItem.cause && target.closest(".requests-list-cause-stack")) {
|
||||
return setTooltipStackTraceContent(tooltip, requestItem);
|
||||
}
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ const RequestListContent = createClass({
|
|||
return (
|
||||
div({
|
||||
ref: "contentEl",
|
||||
className: "requests-menu-contents",
|
||||
className: "requests-list-contents",
|
||||
tabIndex: 0,
|
||||
onKeyDown: this.onKeyDown,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -31,15 +31,13 @@ const RequestListEmptyNotice = createClass({
|
|||
render() {
|
||||
return div(
|
||||
{
|
||||
id: "requests-menu-empty-notice",
|
||||
className: "request-list-empty-notice",
|
||||
className: "requests-list-empty-notice",
|
||||
},
|
||||
div({ id: "notice-reload-message" },
|
||||
div({ className: "notice-reload-message" },
|
||||
span(null, L10N.getStr("netmonitor.reloadNotice1")),
|
||||
button(
|
||||
{
|
||||
id: "requests-menu-reload-notice-button",
|
||||
className: "devtools-button",
|
||||
className: "devtools-toolbarbutton requests-list-reload-notice-button",
|
||||
"data-standalone": true,
|
||||
onClick: this.props.onReloadClick,
|
||||
},
|
||||
|
|
@ -47,12 +45,11 @@ const RequestListEmptyNotice = createClass({
|
|||
),
|
||||
span(null, L10N.getStr("netmonitor.reloadNotice3"))
|
||||
),
|
||||
div({ id: "notice-perf-message" },
|
||||
div({ className: "notice-perf-message" },
|
||||
span(null, L10N.getStr("netmonitor.perfNotice1")),
|
||||
button({
|
||||
id: "requests-menu-perf-notice-button",
|
||||
title: L10N.getStr("netmonitor.perfNotice3"),
|
||||
className: "devtools-button",
|
||||
className: "devtools-button requests-list-perf-notice-button",
|
||||
"data-standalone": true,
|
||||
onClick: this.props.onPerfClick,
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ const RequestListHeader = createClass({
|
|||
const { sort, scale, waterfallWidth, onHeaderClick } = this.props;
|
||||
|
||||
return div(
|
||||
{ id: "requests-menu-toolbar", className: "devtools-toolbar" },
|
||||
div({ id: "toolbar-labels" },
|
||||
{ className: "devtools-toolbar requests-list-toolbar" },
|
||||
div({ className: "toolbar-labels" },
|
||||
HEADERS.map(header => {
|
||||
const name = header.name;
|
||||
const boxName = header.boxName || name;
|
||||
|
|
@ -96,8 +96,8 @@ const RequestListHeader = createClass({
|
|||
|
||||
return div(
|
||||
{
|
||||
id: `requests-menu-${boxName}-header-box`,
|
||||
className: `requests-menu-header requests-menu-${boxName}`,
|
||||
id: `requests-list-${boxName}-header-box`,
|
||||
className: `requests-list-header requests-list-${boxName}`,
|
||||
key: name,
|
||||
ref: "header",
|
||||
// Used to style the next column.
|
||||
|
|
@ -105,8 +105,8 @@ const RequestListHeader = createClass({
|
|||
},
|
||||
button(
|
||||
{
|
||||
id: `requests-menu-${name}-button`,
|
||||
className: `requests-menu-header-button requests-menu-${name}`,
|
||||
id: `requests-list-${name}-button`,
|
||||
className: `requests-list-header-button requests-list-${name}`,
|
||||
"data-sorted": sorted,
|
||||
title: sortedTitle,
|
||||
onClick: () => onHeaderClick(name),
|
||||
|
|
@ -163,7 +163,7 @@ function waterfallDivisionLabels(waterfallWidth, scale) {
|
|||
labels.push(div(
|
||||
{
|
||||
key: labels.length,
|
||||
className: "requests-menu-timings-division",
|
||||
className: "requests-list-timings-division",
|
||||
"data-division-scale": divisionScale,
|
||||
style: { width }
|
||||
},
|
||||
|
|
@ -175,11 +175,11 @@ function waterfallDivisionLabels(waterfallWidth, scale) {
|
|||
}
|
||||
|
||||
function WaterfallLabel(waterfallWidth, scale, label) {
|
||||
let className = "button-text requests-menu-waterfall-label-wrapper";
|
||||
let className = "button-text requests-list-waterfall-label-wrapper";
|
||||
|
||||
if (waterfallWidth != null && scale != null) {
|
||||
label = waterfallDivisionLabels(waterfallWidth, scale);
|
||||
className += " requests-menu-waterfall-visible";
|
||||
className += " requests-list-waterfall-visible";
|
||||
}
|
||||
|
||||
return div({ className }, label);
|
||||
|
|
|
|||
|
|
@ -175,9 +175,9 @@ const StatusColumn = createFactory(createClass({
|
|||
}
|
||||
|
||||
return (
|
||||
div({ className: "requests-menu-subitem requests-menu-status", title },
|
||||
div({ className: "requests-menu-status-icon", "data-code": code }),
|
||||
span({ className: "subitem-label requests-menu-status-code" }, status),
|
||||
div({ className: "requests-list-subitem requests-list-status", title },
|
||||
div({ className: "requests-list-status-icon", "data-code": code }),
|
||||
span({ className: "subitem-label requests-list-status-code" }, status)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -197,8 +197,8 @@ const MethodColumn = createFactory(createClass({
|
|||
render() {
|
||||
const { method } = this.props.item;
|
||||
return (
|
||||
div({ className: "requests-menu-subitem requests-menu-method-box" },
|
||||
span({ className: "subitem-label requests-menu-method" }, method)
|
||||
div({ className: "requests-list-subitem requests-list-method-box" },
|
||||
span({ className: "subitem-label requests-list-method" }, method)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -224,15 +224,15 @@ const FileColumn = createFactory(createClass({
|
|||
const { urlDetails, responseContentDataUri } = this.props.item;
|
||||
|
||||
return (
|
||||
div({ className: "requests-menu-subitem requests-menu-icon-and-file" },
|
||||
div({ className: "requests-list-subitem requests-list-icon-and-file" },
|
||||
img({
|
||||
className: "requests-menu-icon",
|
||||
className: "requests-list-icon",
|
||||
src: responseContentDataUri,
|
||||
hidden: !responseContentDataUri,
|
||||
"data-type": responseContentDataUri ? "thumbnail" : undefined,
|
||||
}),
|
||||
div({
|
||||
className: "subitem-label requests-menu-file",
|
||||
className: "subitem-label requests-list-file",
|
||||
title: urlDetails.unicodeUrl,
|
||||
},
|
||||
urlDetails.baseNameWithQuery,
|
||||
|
|
@ -277,13 +277,13 @@ const DomainColumn = createFactory(createClass({
|
|||
let title = urlDetails.host + (remoteAddress ? ` (${remoteAddress})` : "");
|
||||
|
||||
return (
|
||||
div({ className: "requests-menu-subitem requests-menu-security-and-domain" },
|
||||
div({ className: "requests-list-subitem requests-list-security-and-domain" },
|
||||
div({
|
||||
className: iconClassList.join(" "),
|
||||
title: iconTitle,
|
||||
onClick: onSecurityIconClick,
|
||||
}),
|
||||
span({ className: "subitem-label requests-menu-domain", title }, urlDetails.host),
|
||||
span({ className: "subitem-label requests-list-domain", title }, urlDetails.host),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -316,11 +316,11 @@ const CauseColumn = createFactory(createClass({
|
|||
|
||||
return (
|
||||
div({
|
||||
className: "requests-menu-subitem requests-menu-cause",
|
||||
className: "requests-list-subitem requests-list-cause",
|
||||
title: causeUri,
|
||||
},
|
||||
span({
|
||||
className: "requests-menu-cause-stack",
|
||||
className: "requests-list-cause-stack",
|
||||
hidden: !causeHasStack,
|
||||
}, "JS"),
|
||||
span({ className: "subitem-label" }, causeType),
|
||||
|
|
@ -356,7 +356,7 @@ const TypeColumn = createFactory(createClass({
|
|||
|
||||
return (
|
||||
div({
|
||||
className: "requests-menu-subitem requests-menu-type",
|
||||
className: "requests-list-subitem requests-list-type",
|
||||
title: mimeType,
|
||||
},
|
||||
span({ className: "subitem-label" }, abbrevType),
|
||||
|
|
@ -401,7 +401,7 @@ const TransferredSizeColumn = createFactory(createClass({
|
|||
|
||||
return (
|
||||
div({
|
||||
className: "requests-menu-subitem requests-menu-transferred",
|
||||
className: "requests-list-subitem requests-list-transferred",
|
||||
title: text,
|
||||
},
|
||||
span({ className }, text),
|
||||
|
|
@ -431,7 +431,7 @@ const ContentSizeColumn = createFactory(createClass({
|
|||
|
||||
return (
|
||||
div({
|
||||
className: "requests-menu-subitem subitem-label requests-menu-size",
|
||||
className: "requests-list-subitem subitem-label requests-list-size",
|
||||
title: text,
|
||||
},
|
||||
span({ className: "subitem-label" }, text),
|
||||
|
|
@ -464,9 +464,9 @@ const WaterfallColumn = createFactory(createClass({
|
|||
const { item, firstRequestStartedMillis } = this.props;
|
||||
|
||||
return (
|
||||
div({ className: "requests-menu-subitem requests-menu-waterfall" },
|
||||
div({ className: "requests-list-subitem requests-list-waterfall" },
|
||||
div({
|
||||
className: "requests-menu-timings",
|
||||
className: "requests-list-timings",
|
||||
style: {
|
||||
paddingInlineStart: `${item.startedMillis - firstRequestStartedMillis}px`,
|
||||
},
|
||||
|
|
@ -499,7 +499,7 @@ function timingBoxes(item) {
|
|||
if (width > 0) {
|
||||
boxes.push(div({
|
||||
key,
|
||||
className: "requests-menu-timings-box " + key,
|
||||
className: "requests-list-timings-box " + key,
|
||||
style: { width }
|
||||
}));
|
||||
}
|
||||
|
|
@ -510,8 +510,8 @@ function timingBoxes(item) {
|
|||
let text = L10N.getFormatStr("networkMenu.totalMS", totalTime);
|
||||
boxes.push(div({
|
||||
key: "total",
|
||||
className: "requests-menu-timings-total",
|
||||
title: text,
|
||||
className: "requests-list-timings-total",
|
||||
title: text
|
||||
}, text));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,12 +96,11 @@ const Toolbar = createClass({
|
|||
.replace("#4", getFormattedTime(millis));
|
||||
|
||||
let buttons = requestFilterTypes.map(([type, checked]) => {
|
||||
let classList = ["devtools-button"];
|
||||
let classList = ["devtools-button", `requests-list-filter-${type}-button`];
|
||||
checked && classList.push("checked");
|
||||
|
||||
return (
|
||||
button({
|
||||
id: `requests-menu-filter-${type}-button`,
|
||||
className: classList.join(" "),
|
||||
key: type,
|
||||
onClick: this.toggleRequestFilterType,
|
||||
|
|
@ -118,17 +117,15 @@ const Toolbar = createClass({
|
|||
span({ className: "devtools-toolbar devtools-toolbar-container" },
|
||||
span({ className: "devtools-toolbar-group" },
|
||||
button({
|
||||
id: "requests-menu-clear-button",
|
||||
className: "devtools-button devtools-clear-icon",
|
||||
className: "devtools-button devtools-clear-icon requests-list-clear-button",
|
||||
title: TOOLBAR_CLEAR,
|
||||
onClick: clearRequests,
|
||||
}),
|
||||
div({ id: "requests-menu-filter-buttons" }, buttons),
|
||||
div({ id: "requests-list-filter-buttons" }, buttons),
|
||||
),
|
||||
span({ className: "devtools-toolbar-group" },
|
||||
button({
|
||||
id: "requests-menu-network-summary-button",
|
||||
className: "devtools-button",
|
||||
className: "devtools-button requests-list-network-summary-button",
|
||||
title: count ? text : L10N.getStr("netmonitor.toolbar.perf"),
|
||||
onClick: openStatistics,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ RequestListContextMenu.prototype = {
|
|||
|
||||
let menu = new Menu();
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-copy-url",
|
||||
id: "request-list-context-copy-url",
|
||||
label: L10N.getStr("netmonitor.context.copyUrl"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyUrl.accesskey"),
|
||||
visible: !!selectedRequest,
|
||||
|
|
@ -58,7 +58,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-copy-url-params",
|
||||
id: "request-list-context-copy-url-params",
|
||||
label: L10N.getStr("netmonitor.context.copyUrlParams"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyUrlParams.accesskey"),
|
||||
visible: !!(selectedRequest && getUrlQuery(selectedRequest.url)),
|
||||
|
|
@ -66,7 +66,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-copy-post-data",
|
||||
id: "request-list-context-copy-post-data",
|
||||
label: L10N.getStr("netmonitor.context.copyPostData"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyPostData.accesskey"),
|
||||
visible: !!(selectedRequest && selectedRequest.requestPostData),
|
||||
|
|
@ -74,7 +74,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-copy-as-curl",
|
||||
id: "request-list-context-copy-as-curl",
|
||||
label: L10N.getStr("netmonitor.context.copyAsCurl"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyAsCurl.accesskey"),
|
||||
visible: !!selectedRequest,
|
||||
|
|
@ -87,7 +87,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-copy-request-headers",
|
||||
id: "request-list-context-copy-request-headers",
|
||||
label: L10N.getStr("netmonitor.context.copyRequestHeaders"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyRequestHeaders.accesskey"),
|
||||
visible: !!(selectedRequest && selectedRequest.requestHeaders),
|
||||
|
|
@ -95,7 +95,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "response-menu-context-copy-response-headers",
|
||||
id: "response-list-context-copy-response-headers",
|
||||
label: L10N.getStr("netmonitor.context.copyResponseHeaders"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyResponseHeaders.accesskey"),
|
||||
visible: !!(selectedRequest && selectedRequest.responseHeaders),
|
||||
|
|
@ -103,7 +103,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-copy-response",
|
||||
id: "request-list-context-copy-response",
|
||||
label: L10N.getStr("netmonitor.context.copyResponse"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyResponse.accesskey"),
|
||||
visible: !!(selectedRequest &&
|
||||
|
|
@ -114,7 +114,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-copy-image-as-data-uri",
|
||||
id: "request-list-context-copy-image-as-data-uri",
|
||||
label: L10N.getStr("netmonitor.context.copyImageAsDataUri"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyImageAsDataUri.accesskey"),
|
||||
visible: !!(selectedRequest &&
|
||||
|
|
@ -129,7 +129,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-copy-all-as-har",
|
||||
id: "request-list-context-copy-all-as-har",
|
||||
label: L10N.getStr("netmonitor.context.copyAllAsHar"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyAllAsHar.accesskey"),
|
||||
visible: this.sortedRequests.size > 0,
|
||||
|
|
@ -137,7 +137,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-save-all-as-har",
|
||||
id: "request-list-context-save-all-as-har",
|
||||
label: L10N.getStr("netmonitor.context.saveAllAsHar"),
|
||||
accesskey: L10N.getStr("netmonitor.context.saveAllAsHar.accesskey"),
|
||||
visible: this.sortedRequests.size > 0,
|
||||
|
|
@ -150,7 +150,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-resend",
|
||||
id: "request-list-context-resend",
|
||||
label: L10N.getStr("netmonitor.context.editAndResend"),
|
||||
accesskey: L10N.getStr("netmonitor.context.editAndResend.accesskey"),
|
||||
visible: !!(window.NetMonitorController.supportsCustomRequest &&
|
||||
|
|
@ -164,7 +164,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-newtab",
|
||||
id: "request-list-context-newtab",
|
||||
label: L10N.getStr("netmonitor.context.newTab"),
|
||||
accesskey: L10N.getStr("netmonitor.context.newTab.accesskey"),
|
||||
visible: !!selectedRequest,
|
||||
|
|
@ -172,7 +172,7 @@ RequestListContextMenu.prototype = {
|
|||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
id: "request-menu-context-perf",
|
||||
id: "request-list-context-perf",
|
||||
label: L10N.getStr("netmonitor.context.perfTools"),
|
||||
accesskey: L10N.getStr("netmonitor.context.perfTools.accesskey"),
|
||||
visible: !!window.NetMonitorController.supportsPerfStats,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ async function setTooltipImageContent(tooltip, itemEl, requestItem) {
|
|||
let options = { maxDim, naturalWidth, naturalHeight };
|
||||
setImageTooltip(tooltip, tooltip.doc, src, options);
|
||||
|
||||
return itemEl.querySelector(".requests-menu-icon");
|
||||
return itemEl.querySelector(".requests-list-icon");
|
||||
}
|
||||
|
||||
async function setTooltipStackTraceContent(tooltip, requestItem) {
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ const HeadersPanel = createClass({
|
|||
className: "tabpanel-summary-label headers-summary-label",
|
||||
}, SUMMARY_STATUS),
|
||||
div({
|
||||
className: "requests-menu-status-icon",
|
||||
className: "requests-list-status-icon",
|
||||
"data-code": code,
|
||||
}),
|
||||
input({
|
||||
|
|
|
|||
|
|
@ -40,20 +40,20 @@ function TimingsPanel({
|
|||
span({ className: "tabpanel-summary-label timings-label" },
|
||||
L10N.getStr(`netmonitor.timings.${type}`)
|
||||
),
|
||||
div({ className: "requests-menu-timings-container" },
|
||||
div({ className: "requests-list-timings-container" },
|
||||
span({
|
||||
className: "requests-menu-timings-offset",
|
||||
className: "requests-list-timings-offset",
|
||||
style: {
|
||||
width: `calc(${offsetScale} * (100% - ${TIMINGS_END_PADDING})`,
|
||||
},
|
||||
}),
|
||||
span({
|
||||
className: `requests-menu-timings-box ${type}`,
|
||||
className: `requests-list-timings-box ${type}`,
|
||||
style: {
|
||||
width: `calc(${timelineScale} * (100% - ${TIMINGS_END_PADDING}))`,
|
||||
},
|
||||
}),
|
||||
span({ className: "requests-menu-timings-total" },
|
||||
span({ className: "requests-list-timings-total" },
|
||||
L10N.getFormatStr("networkMenu.totalMS", timings[type])
|
||||
)
|
||||
),
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ add_task(function* () {
|
|||
});
|
||||
yield wait;
|
||||
|
||||
document.querySelector(".requests-menu-contents").focus();
|
||||
document.querySelector(".requests-list-contents").focus();
|
||||
|
||||
check(-1, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ add_task(function* () {
|
|||
// Wait until the first request makes the empty notice disappear
|
||||
yield waitForRequestListToAppear();
|
||||
|
||||
let requestsContainer = document.querySelector(".requests-menu-contents");
|
||||
let requestsContainer = document.querySelector(".requests-list-contents");
|
||||
ok(requestsContainer, "Container element exists as expected.");
|
||||
|
||||
// (1) Check that the scroll position is maintained at the bottom
|
||||
|
|
@ -57,7 +57,7 @@ add_task(function* () {
|
|||
|
||||
function waitForRequestListToAppear() {
|
||||
info("Waiting until the empty notice disappears and is replaced with the list");
|
||||
return waitUntil(() => !!document.querySelector(".requests-menu-contents"));
|
||||
return waitUntil(() => !!document.querySelector(".requests-list-contents"));
|
||||
}
|
||||
|
||||
function* waitForRequestsToOverflowContainer() {
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ add_task(function* () {
|
|||
|
||||
// Sort the requests by cause and check the order
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-cause-button"));
|
||||
document.querySelector("#requests-list-cause-button"));
|
||||
let expectedOrder = EXPECTED_REQUESTS.map(r => r.causeType).sort();
|
||||
expectedOrder.forEach((expectedCause, i) => {
|
||||
const cause = getSortedRequests(gStore.getState()).get(i).cause.type;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ add_task(function* () {
|
|||
let { EVENTS } = windowRequire("devtools/client/netmonitor/constants");
|
||||
let detailsPane = document.querySelector("#details-pane");
|
||||
let detailsPanelToggleButton = document.querySelector(".network-details-panel-toggle");
|
||||
let clearButton = document.querySelector("#requests-menu-clear-button");
|
||||
let clearButton = document.querySelector(".requests-list-clear-button");
|
||||
|
||||
gStore.dispatch(Actions.batchEnable(false));
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ add_task(function* () {
|
|||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-as-curl").click();
|
||||
.querySelector("#request-list-context-copy-as-curl").click();
|
||||
}, function validate(result) {
|
||||
if (typeof result !== "string") {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ add_task(function* () {
|
|||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-request-headers").click();
|
||||
.querySelector("#request-list-context-copy-request-headers").click();
|
||||
}, function validate(result) {
|
||||
// Sometimes, a "Cookie" header is left over from other tests. Remove it:
|
||||
result = String(result).replace(/Cookie: [^\n]+\n/, "");
|
||||
|
|
@ -69,7 +69,7 @@ add_task(function* () {
|
|||
// Context menu is appending in XUL document, we must select it from
|
||||
// _oolbox.doc
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#response-menu-context-copy-response-headers").click();
|
||||
.querySelector("#response-list-context-copy-response-headers").click();
|
||||
}, function validate(result) {
|
||||
// Fake the "Last-Modified" and "Date" headers because they will vary:
|
||||
result = String(result)
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ add_task(function* () {
|
|||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-image-as-data-uri").click();
|
||||
}, TEST_IMAGE_DATA_URI);
|
||||
.querySelector("#request-list-context-copy-image-as-data-uri").click();
|
||||
}, TEST_IMAGE_DATA_URI);
|
||||
|
||||
ok(true, "Clipboard contains the currently selected image as data uri.");
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ add_task(function* () {
|
|||
EventUtils.sendMouseEvent({ type: "contextmenu" },
|
||||
document.querySelectorAll(".request-list-item")[index]);
|
||||
let copyUrlParamsNode = monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-url-params");
|
||||
.querySelector("#request-list-context-copy-url-params");
|
||||
is(!!copyUrlParamsNode, !hidden,
|
||||
"The \"Copy URL Parameters\" context menu item should" + (hidden ? " " : " not ") +
|
||||
"be hidden.");
|
||||
|
|
@ -76,7 +76,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[index]);
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-url-params").click();
|
||||
.querySelector("#request-list-context-copy-url-params").click();
|
||||
}, queryString);
|
||||
ok(true, "The url query string copied from the selected item is correct.");
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ add_task(function* () {
|
|||
EventUtils.sendMouseEvent({ type: "contextmenu" },
|
||||
document.querySelectorAll(".request-list-item")[index]);
|
||||
let copyPostDataNode = monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-post-data");
|
||||
.querySelector("#request-list-context-copy-post-data");
|
||||
is(!!copyPostDataNode, !hidden,
|
||||
"The \"Copy POST Data\" context menu item should" + (hidden ? " " : " not ") +
|
||||
"be hidden.");
|
||||
|
|
@ -100,7 +100,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[index]);
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-post-data").click();
|
||||
.querySelector("#request-list-context-copy-post-data").click();
|
||||
}, postData);
|
||||
ok(true, "The post data string copied from the selected item is correct.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ add_task(function* () {
|
|||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-response").click();
|
||||
.querySelector("#request-list-context-copy-response").click();
|
||||
}, EXPECTED_RESULT);
|
||||
|
||||
yield teardown(monitor);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ add_task(function* () {
|
|||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-image-as-data-uri").click();
|
||||
.querySelector("#request-list-context-copy-image-as-data-uri").click();
|
||||
}, function check(text) {
|
||||
return text.startsWith("data:") && !/undefined/.test(text);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ add_task(function* () {
|
|||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-copy-url").click();
|
||||
.querySelector("#request-list-context-copy-url").click();
|
||||
}, requestItem.url);
|
||||
|
||||
yield teardown(monitor);
|
||||
|
|
|
|||
|
|
@ -166,93 +166,94 @@ add_task(function* () {
|
|||
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-html-button"));
|
||||
document.querySelector(".requests-list-filter-html-button"));
|
||||
testFilterButtons(monitor, "html");
|
||||
testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
// Reset filters
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-css-button"));
|
||||
document.querySelector(".requests-list-filter-css-button"));
|
||||
testFilterButtons(monitor, "css");
|
||||
testContents([0, 1, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-js-button"));
|
||||
document.querySelector(".requests-list-filter-js-button"));
|
||||
testFilterButtons(monitor, "js");
|
||||
testContents([0, 0, 1, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-xhr-button"));
|
||||
document.querySelector(".requests-list-filter-xhr-button"));
|
||||
testFilterButtons(monitor, "xhr");
|
||||
testContents([1, 1, 1, 1, 1, 1, 1, 1, 0]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-fonts-button"));
|
||||
document.querySelector(".requests-list-filter-fonts-button"));
|
||||
testFilterButtons(monitor, "fonts");
|
||||
testContents([0, 0, 0, 1, 0, 0, 0, 0, 0]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-images-button"));
|
||||
document.querySelector(".requests-list-filter-images-button"));
|
||||
testFilterButtons(monitor, "images");
|
||||
testContents([0, 0, 0, 0, 1, 0, 0, 0, 0]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-media-button"));
|
||||
document.querySelector(".requests-list-filter-media-button"));
|
||||
testFilterButtons(monitor, "media");
|
||||
testContents([0, 0, 0, 0, 0, 1, 1, 0, 0]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-flash-button"));
|
||||
document.querySelector(".requests-list-filter-flash-button"));
|
||||
testFilterButtons(monitor, "flash");
|
||||
testContents([0, 0, 0, 0, 0, 0, 0, 1, 0]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-ws-button"));
|
||||
document.querySelector(".requests-list-filter-ws-button"));
|
||||
testFilterButtons(monitor, "ws");
|
||||
testContents([0, 0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
|
||||
testFilterButtons(monitor, "all");
|
||||
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
|
||||
// Text in filter box that matches nothing should hide all.
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
setFreetextFilter("foobar");
|
||||
testContents([0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
// Text in filter box that matches should filter out everything else.
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
setFreetextFilter("sample");
|
||||
testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
// Text in filter box that matches should filter out everything else.
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
setFreetextFilter("SAMPLE");
|
||||
testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
// Test negative filtering (only show unmatched items)
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
setFreetextFilter("-sample");
|
||||
testContents([0, 0, 0, 1, 1, 1, 1, 1, 1]);
|
||||
|
||||
|
|
@ -261,9 +262,9 @@ add_task(function* () {
|
|||
// Enable filtering for html and css; should show request of both type.
|
||||
setFreetextFilter("");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-html-button"));
|
||||
document.querySelector(".requests-list-filter-html-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-css-button"));
|
||||
document.querySelector(".requests-list-filter-css-button"));
|
||||
testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
|
|
@ -273,35 +274,35 @@ add_task(function* () {
|
|||
testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-flash-button"));
|
||||
document.querySelector(".requests-list-filter-flash-button"));
|
||||
setFreetextFilter("");
|
||||
testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0]);
|
||||
testContents([1, 1, 0, 0, 0, 0, 0, 1, 0]);
|
||||
|
||||
// Disable some filters. Only one left active.
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-css-button"));
|
||||
document.querySelector(".requests-list-filter-css-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-flash-button"));
|
||||
document.querySelector(".requests-list-filter-flash-button"));
|
||||
testFilterButtons(monitor, "html");
|
||||
testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
// Disable last active filter. Should toggle to all.
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-html-button"));
|
||||
document.querySelector(".requests-list-filter-html-button"));
|
||||
testFilterButtons(monitor, "all");
|
||||
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
|
||||
// Enable few filters and click on all. Only "all" should be checked.
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-html-button"));
|
||||
document.querySelector(".requests-list-filter-html-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-css-button"));
|
||||
document.querySelector(".requests-list-filter-css-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-ws-button"));
|
||||
document.querySelector(".requests-list-filter-ws-button"));
|
||||
testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 1]);
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
testFilterButtons(monitor, "all");
|
||||
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ add_task(function* () {
|
|||
|
||||
info("Testing html filtering.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-html-button"));
|
||||
document.querySelector(".requests-list-filter-html-button"));
|
||||
testFilterButtons(monitor, "html");
|
||||
testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ add_task(function* () {
|
|||
|
||||
info("Resetting filters.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-all-button"));
|
||||
document.querySelector(".requests-list-filter-all-button"));
|
||||
testFilterButtons(monitor, "all");
|
||||
testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
|
|
|
|||
|
|
@ -64,13 +64,13 @@ add_task(function* () {
|
|||
|
||||
info("Sorting by size, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-size-button"));
|
||||
document.querySelector("#requests-list-size-button"));
|
||||
testFilterButtons(monitor, "all");
|
||||
testContents([6, 4, 5, 0, 1, 2, 3], 7, 6);
|
||||
|
||||
info("Testing html filtering.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-html-button"));
|
||||
document.querySelector(".requests-list-filter-html-button"));
|
||||
testFilterButtons(monitor, "html");
|
||||
testContents([6, 4, 5, 0, 1, 2, 3], 1, 6);
|
||||
|
||||
|
|
@ -98,9 +98,9 @@ add_task(function* () {
|
|||
|
||||
function resetSorting() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-waterfall-button"));
|
||||
document.querySelector("#requests-list-waterfall-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-size-button"));
|
||||
document.querySelector("#requests-list-size-button"));
|
||||
}
|
||||
|
||||
function getSelectedIndex(state) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ add_task(function* () {
|
|||
|
||||
let buttons = ["html", "css", "js", "xhr", "fonts", "images", "media", "flash"];
|
||||
for (let button of buttons) {
|
||||
let buttonEl = document.querySelector(`#requests-menu-filter-${button}-button`);
|
||||
let buttonEl = document.querySelector(`.requests-list-filter-${button}-button`);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, buttonEl);
|
||||
testStatus();
|
||||
}
|
||||
|
|
@ -49,8 +49,8 @@ add_task(function* () {
|
|||
yield teardown(monitor);
|
||||
|
||||
function testStatus() {
|
||||
let value = document.querySelector("#requests-menu-network-summary-button").textContent;
|
||||
info("Current summary: " + value);
|
||||
let value = document.querySelector(".requests-list-network-summary-button").textContent;
|
||||
info("Current summary: " + value);
|
||||
|
||||
let state = gStore.getState();
|
||||
let totalRequestsCount = state.requests.requests.size;
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ add_task(function* () {
|
|||
}
|
||||
|
||||
function checkImageThumbnail() {
|
||||
is(document.querySelectorAll(".requests-menu-icon[data-type=thumbnail]").length, 1,
|
||||
is(document.querySelectorAll(".requests-list-icon[data-type=thumbnail]").length, 1,
|
||||
"There should be only one image request with a thumbnail displayed.");
|
||||
is(document.querySelector(".requests-menu-icon[data-type=thumbnail]").src, TEST_IMAGE_DATA_URI,
|
||||
"The image requests-menu-icon thumbnail is displayed correctly.");
|
||||
is(document.querySelector(".requests-menu-icon[data-type=thumbnail]").hidden, false,
|
||||
"The image requests-menu-icon thumbnail should not be hidden.");
|
||||
is(document.querySelector(".requests-list-icon[data-type=thumbnail]").src, TEST_IMAGE_DATA_URI,
|
||||
"The image requests-list-icon thumbnail is displayed correctly.");
|
||||
is(document.querySelector(".requests-list-icon[data-type=thumbnail]").hidden, false,
|
||||
"The image requests-list-icon thumbnail should not be hidden.");
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ add_task(function* test() {
|
|||
document.querySelectorAll(".request-list-item")[1]);
|
||||
|
||||
info("Checking if the image thumbnail is hidden when mouse leaves the menu widget");
|
||||
let requestsListContents = document.querySelector(".requests-menu-contents");
|
||||
let requestsListContents = document.querySelector(".requests-list-contents");
|
||||
EventUtils.synthesizeMouse(requestsListContents, 0, 0, { type: "mouseout" }, monitor.panelWin);
|
||||
yield waitUntil(() => !toolboxDoc.querySelector(".tooltip-container.tooltip-visible"));
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ add_task(function* test() {
|
|||
* with the expected content.
|
||||
*/
|
||||
function* showTooltipAndVerify(toolboxDoc, target) {
|
||||
let anchor = target.querySelector(".requests-menu-file");
|
||||
let anchor = target.querySelector(".requests-list-file");
|
||||
yield showTooltipOn(toolboxDoc, anchor);
|
||||
|
||||
info("Tooltip was successfully opened for the image request.");
|
||||
|
|
@ -95,7 +95,7 @@ add_task(function* test() {
|
|||
*/
|
||||
function* hideTooltipAndVerify(toolboxDoc, target) {
|
||||
// Hovering over the "method" column hides the tooltip.
|
||||
let anchor = target.querySelector(".requests-menu-method");
|
||||
let anchor = target.querySelector(".requests-list-method");
|
||||
let win = anchor.ownerDocument.defaultView;
|
||||
EventUtils.synthesizeMouseAtCenter(anchor, { type: "mousemove" }, win);
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ add_task(function* () {
|
|||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
.querySelector("#request-menu-context-newtab").click();
|
||||
.querySelector("#request-list-context-newtab").click();
|
||||
yield onTabOpen;
|
||||
|
||||
ok(true, "A new tab has been opened");
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ add_task(function* () {
|
|||
|
||||
let wait = waitForNetworkEvents(monitor, 1);
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-reload-notice-button"));
|
||||
document.querySelector(".requests-list-reload-notice-button"));
|
||||
yield wait;
|
||||
|
||||
is(document.querySelectorAll(".request-list-item").length, 1,
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ add_task(function* () {
|
|||
info("Starting test... ");
|
||||
|
||||
let { document, windowRequire } = monitor.panelWin;
|
||||
let { EVENTS } = windowRequire("devtools/client/netmonitor/constants");
|
||||
let button = document.querySelector("#requests-menu-reload-notice-button");
|
||||
let button = document.querySelector(".requests-list-reload-notice-button");
|
||||
button.click();
|
||||
|
||||
let markers = [];
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ add_task(function* () {
|
|||
|
||||
info("Sorting the items by filename.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-file-button"));
|
||||
document.querySelector("#requests-list-file-button"));
|
||||
|
||||
info("Testing that security icon can be clicked after the items were sorted.");
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ add_task(function* () {
|
|||
yield performRequests();
|
||||
|
||||
for (let subitemNode of Array.from(document.querySelectorAll(
|
||||
"requests-menu-subitem.requests-menu-security-and-domain"))) {
|
||||
let domain = subitemNode.querySelector(".requests-menu-domain").textContent;
|
||||
"requests-list-subitem.requests-list-security-and-domain"))) {
|
||||
let domain = subitemNode.querySelector(".requests-list-domain").textContent;
|
||||
|
||||
info("Found a request to " + domain);
|
||||
ok(domain in EXPECTED_SECURITY_STATES, "Domain " + domain + " was expected.");
|
||||
|
|
|
|||
|
|
@ -245,27 +245,27 @@ add_task(function* () {
|
|||
is(tabEl.getAttribute("selected"), "true",
|
||||
"The timings tab in the network details pane should be selected.");
|
||||
|
||||
ok(tabpanel.querySelector("#timings-summary-blocked .requests-menu-timings-total")
|
||||
ok(tabpanel.querySelector("#timings-summary-blocked .requests-list-timings-total")
|
||||
.getAttribute("value").match(/[0-9]+/),
|
||||
"The blocked timing info does not appear to be correct.");
|
||||
|
||||
ok(tabpanel.querySelector("#timings-summary-dns .requests-menu-timings-total")
|
||||
ok(tabpanel.querySelector("#timings-summary-dns .requests-list-timings-total")
|
||||
.getAttribute("value").match(/[0-9]+/),
|
||||
"The dns timing info does not appear to be correct.");
|
||||
|
||||
ok(tabpanel.querySelector("#timings-summary-connect .requests-menu-timings-total")
|
||||
ok(tabpanel.querySelector("#timings-summary-connect .requests-list-timings-total")
|
||||
.getAttribute("value").match(/[0-9]+/),
|
||||
"The connect timing info does not appear to be correct.");
|
||||
|
||||
ok(tabpanel.querySelector("#timings-summary-send .requests-menu-timings-total")
|
||||
ok(tabpanel.querySelector("#timings-summary-send .requests-list-timings-total")
|
||||
.getAttribute("value").match(/[0-9]+/),
|
||||
"The send timing info does not appear to be correct.");
|
||||
|
||||
ok(tabpanel.querySelector("#timings-summary-wait .requests-menu-timings-total")
|
||||
ok(tabpanel.querySelector("#timings-summary-wait .requests-list-timings-total")
|
||||
.getAttribute("value").match(/[0-9]+/),
|
||||
"The wait timing info does not appear to be correct.");
|
||||
|
||||
ok(tabpanel.querySelector("#timings-summary-receive .requests-menu-timings-total")
|
||||
ok(tabpanel.querySelector("#timings-summary-receive .requests-list-timings-total")
|
||||
.getAttribute("value").match(/[0-9]+/),
|
||||
"The receive timing info does not appear to be correct.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ add_task(function* () {
|
|||
is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"),
|
||||
true,
|
||||
"The pane toggle button should be disabled when the frontend is opened.");
|
||||
ok(document.querySelector("#requests-menu-empty-notice"),
|
||||
ok(document.querySelector(".requests-list-empty-notice"),
|
||||
"An empty notice should be displayed when the frontend is opened.");
|
||||
is(gStore.getState().requests.requests.size, 0,
|
||||
"The requests menu should be empty when the frontend is opened.");
|
||||
|
|
@ -41,7 +41,7 @@ add_task(function* () {
|
|||
is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"),
|
||||
false,
|
||||
"The pane toggle button should be enabled after the first request.");
|
||||
ok(!document.querySelector("#requests-menu-empty-notice"),
|
||||
ok(!document.querySelector(".requests-list-empty-notice"),
|
||||
"The empty notice should be hidden after the first request.");
|
||||
is(gStore.getState().requests.requests.size, 1,
|
||||
"The requests menu should not be empty after the first request.");
|
||||
|
|
@ -53,7 +53,7 @@ add_task(function* () {
|
|||
is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"),
|
||||
false,
|
||||
"The pane toggle button should be still be enabled after a reload.");
|
||||
ok(!document.querySelector("#requests-menu-empty-notice"),
|
||||
ok(!document.querySelector(".requests-list-empty-notice"),
|
||||
"The empty notice should be still hidden after a reload.");
|
||||
is(gStore.getState().requests.requests.size, 1,
|
||||
"The requests menu should not be empty after a reload.");
|
||||
|
|
@ -65,7 +65,7 @@ add_task(function* () {
|
|||
is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"),
|
||||
true,
|
||||
"The pane toggle button should be disabled when after clear.");
|
||||
ok(document.querySelector("#requests-menu-empty-notice"),
|
||||
ok(document.querySelector(".requests-list-empty-notice"),
|
||||
"An empty notice should be displayed again after clear.");
|
||||
is(gStore.getState().requests.requests.size, 0,
|
||||
"The requests menu should be empty after clear.");
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ add_task(function* () {
|
|||
|
||||
info("Testing status sort, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-status-button"));
|
||||
document.querySelector("#requests-list-status-button"));
|
||||
testHeaders("status", "ascending");
|
||||
testContents([0, 1, 2, 3, 4], 0);
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ add_task(function* () {
|
|||
|
||||
info("Testing status sort, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-status-button"));
|
||||
document.querySelector("#requests-list-status-button"));
|
||||
testHeaders("status", "descending");
|
||||
testContents([9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 9);
|
||||
|
||||
|
|
@ -96,13 +96,13 @@ add_task(function* () {
|
|||
|
||||
info("Testing status sort yet again, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-status-button"));
|
||||
document.querySelector("#requests-list-status-button"));
|
||||
testHeaders("status", "ascending");
|
||||
testContents([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 0);
|
||||
|
||||
info("Testing status sort yet again, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-status-button"));
|
||||
document.querySelector("#requests-list-status-button"));
|
||||
testHeaders("status", "descending");
|
||||
testContents([14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 14);
|
||||
|
||||
|
|
@ -110,8 +110,8 @@ add_task(function* () {
|
|||
|
||||
function testHeaders(sortType, direction) {
|
||||
let doc = monitor.panelWin.document;
|
||||
let target = doc.querySelector("#requests-menu-" + sortType + "-button");
|
||||
let headers = doc.querySelectorAll(".requests-menu-header-button");
|
||||
let target = doc.querySelector("#requests-list-" + sortType + "-button");
|
||||
let headers = doc.querySelectorAll(".requests-list-header-button");
|
||||
|
||||
for (let header of headers) {
|
||||
if (header != target) {
|
||||
|
|
|
|||
|
|
@ -66,127 +66,127 @@ add_task(function* () {
|
|||
|
||||
info("Testing status sort, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-status-button"));
|
||||
document.querySelector("#requests-list-status-button"));
|
||||
testHeaders("status", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing status sort, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-status-button"));
|
||||
document.querySelector("#requests-list-status-button"));
|
||||
testHeaders("status", "descending");
|
||||
testContents([4, 3, 2, 1, 0]);
|
||||
|
||||
info("Testing status sort, ascending. Checking sort loops correctly.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-status-button"));
|
||||
document.querySelector("#requests-list-status-button"));
|
||||
testHeaders("status", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing method sort, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-method-button"));
|
||||
document.querySelector("#requests-list-method-button"));
|
||||
testHeaders("method", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing method sort, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-method-button"));
|
||||
document.querySelector("#requests-list-method-button"));
|
||||
testHeaders("method", "descending");
|
||||
testContents([4, 3, 2, 1, 0]);
|
||||
|
||||
info("Testing method sort, ascending. Checking sort loops correctly.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-method-button"));
|
||||
document.querySelector("#requests-list-method-button"));
|
||||
testHeaders("method", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing file sort, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-file-button"));
|
||||
document.querySelector("#requests-list-file-button"));
|
||||
testHeaders("file", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing file sort, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-file-button"));
|
||||
document.querySelector("#requests-list-file-button"));
|
||||
testHeaders("file", "descending");
|
||||
testContents([4, 3, 2, 1, 0]);
|
||||
|
||||
info("Testing file sort, ascending. Checking sort loops correctly.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-file-button"));
|
||||
document.querySelector("#requests-list-file-button"));
|
||||
testHeaders("file", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing type sort, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-type-button"));
|
||||
document.querySelector("#requests-list-type-button"));
|
||||
testHeaders("type", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing type sort, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-type-button"));
|
||||
document.querySelector("#requests-list-type-button"));
|
||||
testHeaders("type", "descending");
|
||||
testContents([4, 3, 2, 1, 0]);
|
||||
|
||||
info("Testing type sort, ascending. Checking sort loops correctly.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-type-button"));
|
||||
document.querySelector("#requests-list-type-button"));
|
||||
testHeaders("type", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing transferred sort, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-transferred-button"));
|
||||
document.querySelector("#requests-list-transferred-button"));
|
||||
testHeaders("transferred", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing transferred sort, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-transferred-button"));
|
||||
document.querySelector("#requests-list-transferred-button"));
|
||||
testHeaders("transferred", "descending");
|
||||
testContents([4, 3, 2, 1, 0]);
|
||||
|
||||
info("Testing transferred sort, ascending. Checking sort loops correctly.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-transferred-button"));
|
||||
document.querySelector("#requests-list-transferred-button"));
|
||||
testHeaders("transferred", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing size sort, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-size-button"));
|
||||
document.querySelector("#requests-list-size-button"));
|
||||
testHeaders("size", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing size sort, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-size-button"));
|
||||
document.querySelector("#requests-list-size-button"));
|
||||
testHeaders("size", "descending");
|
||||
testContents([4, 3, 2, 1, 0]);
|
||||
|
||||
info("Testing size sort, ascending. Checking sort loops correctly.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-size-button"));
|
||||
document.querySelector("#requests-list-size-button"));
|
||||
testHeaders("size", "ascending");
|
||||
testContents([0, 1, 2, 3, 4]);
|
||||
|
||||
info("Testing waterfall sort, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-waterfall-button"));
|
||||
document.querySelector("#requests-list-waterfall-button"));
|
||||
testHeaders("waterfall", "ascending");
|
||||
testContents([0, 2, 4, 3, 1]);
|
||||
|
||||
info("Testing waterfall sort, descending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-waterfall-button"));
|
||||
document.querySelector("#requests-list-waterfall-button"));
|
||||
testHeaders("waterfall", "descending");
|
||||
testContents([4, 2, 0, 1, 3]);
|
||||
|
||||
info("Testing waterfall sort, ascending. Checking sort loops correctly.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-waterfall-button"));
|
||||
document.querySelector("#requests-list-waterfall-button"));
|
||||
testHeaders("waterfall", "ascending");
|
||||
testContents([0, 2, 4, 3, 1]);
|
||||
|
||||
|
|
@ -201,8 +201,8 @@ add_task(function* () {
|
|||
|
||||
function testHeaders(sortType, direction) {
|
||||
let doc = monitor.panelWin.document;
|
||||
let target = doc.querySelector("#requests-menu-" + sortType + "-button");
|
||||
let headers = doc.querySelectorAll(".requests-menu-header-button");
|
||||
let target = doc.querySelector("#requests-list-" + sortType + "-button");
|
||||
let headers = doc.querySelectorAll(".requests-list-header-button");
|
||||
|
||||
for (let header of headers) {
|
||||
if (header != target) {
|
||||
|
|
|
|||
|
|
@ -17,15 +17,15 @@ add_task(function* () {
|
|||
let Actions = windowRequire("devtools/client/netmonitor/actions/index");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-html-button"));
|
||||
document.querySelector(".requests-list-filter-html-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-css-button"));
|
||||
document.querySelector(".requests-list-filter-css-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-js-button"));
|
||||
document.querySelector(".requests-list-filter-js-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-ws-button"));
|
||||
document.querySelector(".requests-list-filter-ws-button"));
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#requests-menu-filter-other-button"));
|
||||
document.querySelector(".requests-list-filter-other-button"));
|
||||
testFilterButtonsCustom(monitor, [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1]);
|
||||
info("The correct filtering predicates are used before entering perf. analysis mode.");
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ add_task(function* () {
|
|||
|
||||
is(summaryValues[0].value, uri, "The url summary value is incorrect.");
|
||||
is(summaryValues[1].value, method, "The method summary value is incorrect.");
|
||||
is(panel.querySelector(".requests-menu-status-icon").dataset.code, status,
|
||||
is(panel.querySelector(".requests-list-status-icon").dataset.code, status,
|
||||
"The status summary code is incorrect.");
|
||||
is(summaryValues[3].value, status + " " + statusText,
|
||||
"The status summary value is incorrect.");
|
||||
|
|
|
|||
|
|
@ -19,14 +19,14 @@ add_task(function* () {
|
|||
// Disable transferred size column support for this test.
|
||||
// Without this, the waterfall only has enough room for one division, which
|
||||
// would remove most of the value of this test.
|
||||
// $("#requests-menu-transferred-header-box").hidden = true;
|
||||
// $("#requests-menu-item-template .requests-menu-transferred").hidden = true;
|
||||
// $("#requests-list-transferred-header-box").hidden = true;
|
||||
// $("#requests-list-item-template .requests-list-transferred").hidden = true;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
ok($("#requests-menu-waterfall-label"),
|
||||
ok($("#requests-list-waterfall-label"),
|
||||
"An timeline label should be displayed when the frontend is opened.");
|
||||
ok($all(".requests-menu-timings-division").length == 0,
|
||||
ok($all(".requests-list-timings-division").length == 0,
|
||||
"No tick labels should be displayed when the frontend is opened.");
|
||||
|
||||
ok(!RequestsMenu._canvas, "No canvas should be created when the frontend is opened.");
|
||||
|
|
@ -41,12 +41,12 @@ add_task(function* () {
|
|||
NetMonitorController.NetworkEventsHandler.clearMarkers();
|
||||
RequestsMenu._flushWaterfallViews(true);
|
||||
|
||||
ok(!$("#requests-menu-waterfall-label"),
|
||||
ok(!$("#requests-list-waterfall-label"),
|
||||
"The timeline label should be hidden after the first request.");
|
||||
ok($all(".requests-menu-timings-division").length >= 3,
|
||||
ok($all(".requests-list-timings-division").length >= 3,
|
||||
"There should be at least 3 tick labels in the network requests header.");
|
||||
|
||||
let timingDivisionEls = $all(".requests-menu-timings-division");
|
||||
let timingDivisionEls = $all(".requests-list-timings-division");
|
||||
is(timingDivisionEls[0].textContent, L10N.getFormatStr("networkMenu.millisecond", 0),
|
||||
"The first tick label has correct value");
|
||||
is(timingDivisionEls[1].textContent, L10N.getFormatStr("networkMenu.millisecond", 80),
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ add_task(function* () {
|
|||
yield wait;
|
||||
|
||||
let milDivs = document.querySelectorAll(
|
||||
".requests-menu-timings-division[data-division-scale=millisecond]");
|
||||
".requests-list-timings-division[data-division-scale=millisecond]");
|
||||
let secDivs = document.querySelectorAll(
|
||||
".requests-menu-timings-division[data-division-scale=second]");
|
||||
".requests-list-timings-division[data-division-scale=second]");
|
||||
let minDivs = document.querySelectorAll(
|
||||
".requests-menu-timings-division[data-division-scale=minute]");
|
||||
".requests-list-timings-division[data-division-scale=minute]");
|
||||
|
||||
info("Number of millisecond divisions: " + milDivs.length);
|
||||
info("Number of second divisions: " + secDivs.length);
|
||||
|
|
|
|||
|
|
@ -94,8 +94,8 @@ function asExpected(wrapper, expectTypes, description) {
|
|||
let className = expectTypes[type] ?
|
||||
"devtools-button checked" : "devtools-button";
|
||||
it(`'${type}' button is ${checked} ${description}`, () => {
|
||||
expect(wrapper.find(`#requests-menu-filter-${type}-button`).html())
|
||||
.toBe(`<button id="requests-menu-filter-${type}-button" class="` + className +
|
||||
expect(wrapper.find(`.requests-list-filter-${type}-button`).html())
|
||||
.toBe(`<button class="` + className +
|
||||
`" data-key="${type}">netmonitor.toolbar.filter.${type}</button>`);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,32 +275,32 @@ function verifyRequestItemTarget(document, requestList, requestItem, aMethod,
|
|||
is(requestItem.url, aUrl, "The attached url is correct.");
|
||||
}
|
||||
|
||||
is(target.querySelector(".requests-menu-method").textContent,
|
||||
is(target.querySelector(".requests-list-method").textContent,
|
||||
aMethod, "The displayed method is correct.");
|
||||
|
||||
if (fuzzyUrl) {
|
||||
ok(target.querySelector(".requests-menu-file").textContent.startsWith(
|
||||
ok(target.querySelector(".requests-list-file").textContent.startsWith(
|
||||
name + (query ? "?" + query : "")), "The displayed file is correct.");
|
||||
ok(target.querySelector(".requests-menu-file").getAttribute("title").startsWith(unicodeUrl),
|
||||
ok(target.querySelector(".requests-list-file").getAttribute("title").startsWith(unicodeUrl),
|
||||
"The tooltip file is correct.");
|
||||
} else {
|
||||
is(target.querySelector(".requests-menu-file").textContent,
|
||||
is(target.querySelector(".requests-list-file").textContent,
|
||||
name + (query ? "?" + query : ""), "The displayed file is correct.");
|
||||
is(target.querySelector(".requests-menu-file").getAttribute("title"),
|
||||
is(target.querySelector(".requests-list-file").getAttribute("title"),
|
||||
unicodeUrl, "The tooltip file is correct.");
|
||||
}
|
||||
|
||||
is(target.querySelector(".requests-menu-domain").textContent,
|
||||
is(target.querySelector(".requests-list-domain").textContent,
|
||||
hostPort, "The displayed domain is correct.");
|
||||
|
||||
let domainTooltip = hostPort + (remoteAddress ? " (" + remoteAddress + ")" : "");
|
||||
is(target.querySelector(".requests-menu-domain").getAttribute("title"),
|
||||
is(target.querySelector(".requests-list-domain").getAttribute("title"),
|
||||
domainTooltip, "The tooltip domain is correct.");
|
||||
|
||||
if (status !== undefined) {
|
||||
let value = target.querySelector(".requests-menu-status-icon").getAttribute("data-code");
|
||||
let codeValue = target.querySelector(".requests-menu-status-code").textContent;
|
||||
let tooltip = target.querySelector(".requests-menu-status").getAttribute("title");
|
||||
let value = target.querySelector(".requests-list-status-icon").getAttribute("data-code");
|
||||
let codeValue = target.querySelector(".requests-list-status-code").textContent;
|
||||
let tooltip = target.querySelector(".requests-list-status").getAttribute("title");
|
||||
info("Displayed status: " + value);
|
||||
info("Displayed code: " + codeValue);
|
||||
info("Tooltip status: " + tooltip);
|
||||
|
|
@ -309,40 +309,40 @@ function verifyRequestItemTarget(document, requestList, requestItem, aMethod,
|
|||
is(tooltip, status + " " + statusText, "The tooltip status is correct.");
|
||||
}
|
||||
if (cause !== undefined) {
|
||||
let value = target.querySelector(".requests-menu-cause > .subitem-label").textContent;
|
||||
let tooltip = target.querySelector(".requests-menu-cause").getAttribute("title");
|
||||
let value = target.querySelector(".requests-list-cause > .subitem-label").textContent;
|
||||
let tooltip = target.querySelector(".requests-list-cause").getAttribute("title");
|
||||
info("Displayed cause: " + value);
|
||||
info("Tooltip cause: " + tooltip);
|
||||
is(value, cause.type, "The displayed cause is correct.");
|
||||
is(tooltip, cause.loadingDocumentUri, "The tooltip cause is correct.")
|
||||
}
|
||||
if (type !== undefined) {
|
||||
let value = target.querySelector(".requests-menu-type").textContent;
|
||||
let tooltip = target.querySelector(".requests-menu-type").getAttribute("title");
|
||||
let value = target.querySelector(".requests-list-type").textContent;
|
||||
let tooltip = target.querySelector(".requests-list-type").getAttribute("title");
|
||||
info("Displayed type: " + value);
|
||||
info("Tooltip type: " + tooltip);
|
||||
is(value, type, "The displayed type is correct.");
|
||||
is(tooltip, fullMimeType, "The tooltip type is correct.");
|
||||
}
|
||||
if (transferred !== undefined) {
|
||||
let value = target.querySelector(".requests-menu-transferred").textContent;
|
||||
let tooltip = target.querySelector(".requests-menu-transferred").getAttribute("title");
|
||||
let value = target.querySelector(".requests-list-transferred").textContent;
|
||||
let tooltip = target.querySelector(".requests-list-transferred").getAttribute("title");
|
||||
info("Displayed transferred size: " + value);
|
||||
info("Tooltip transferred size: " + tooltip);
|
||||
is(value, transferred, "The displayed transferred size is correct.");
|
||||
is(tooltip, transferred, "The tooltip transferred size is correct.");
|
||||
}
|
||||
if (size !== undefined) {
|
||||
let value = target.querySelector(".requests-menu-size").textContent;
|
||||
let tooltip = target.querySelector(".requests-menu-size").getAttribute("title");
|
||||
let value = target.querySelector(".requests-list-size").textContent;
|
||||
let tooltip = target.querySelector(".requests-list-size").getAttribute("title");
|
||||
info("Displayed size: " + value);
|
||||
info("Tooltip size: " + tooltip);
|
||||
is(value, size, "The displayed size is correct.");
|
||||
is(tooltip, size, "The tooltip size is correct.");
|
||||
}
|
||||
if (time !== undefined) {
|
||||
let value = target.querySelector(".requests-menu-timings-total").textContent;
|
||||
let tooltip = target.querySelector(".requests-menu-timings-total").getAttribute("title");
|
||||
let value = target.querySelector(".requests-list-timings-total").textContent;
|
||||
let tooltip = target.querySelector(".requests-list-timings-total").getAttribute("title");
|
||||
info("Displayed time: " + value);
|
||||
info("Tooltip time: " + tooltip);
|
||||
ok(~~(value.match(/[0-9]+/)) >= 0, "The displayed time is correct.");
|
||||
|
|
@ -385,9 +385,9 @@ function waitFor(subject, eventName) {
|
|||
*/
|
||||
function testFilterButtons(monitor, filterType) {
|
||||
let doc = monitor.panelWin.document;
|
||||
let target = doc.querySelector("#requests-menu-filter-" + filterType + "-button");
|
||||
let target = doc.querySelector(".requests-list-filter-" + filterType + "-button");
|
||||
ok(target, `Filter button '${filterType}' was found`);
|
||||
let buttons = [...doc.querySelectorAll("#requests-menu-filter-buttons button")];
|
||||
let buttons = [...doc.querySelectorAll("#requests-list-filter-buttons button")];
|
||||
ok(buttons.length > 0, "More than zero filter buttons were found");
|
||||
|
||||
// Only target should be checked.
|
||||
|
|
@ -405,7 +405,7 @@ function testFilterButtons(monitor, filterType) {
|
|||
*/
|
||||
function testFilterButtonsCustom(aMonitor, aIsChecked) {
|
||||
let doc = aMonitor.panelWin.document;
|
||||
let buttons = doc.querySelectorAll("#requests-menu-filter-buttons button");
|
||||
let buttons = doc.querySelectorAll("#requests-list-filter-buttons button");
|
||||
for (let i = 0; i < aIsChecked.length; i++) {
|
||||
let button = buttons[i];
|
||||
if (aIsChecked[i]) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#toolbar-labels {
|
||||
.toolbar-labels {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex: auto;
|
||||
|
|
@ -96,22 +96,22 @@
|
|||
font-size: 120%;
|
||||
}
|
||||
|
||||
#notice-perf-message {
|
||||
.notice-perf-message {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
#requests-menu-perf-notice-button {
|
||||
.requests-list-perf-notice-button {
|
||||
min-width: 30px;
|
||||
min-height: 26px;
|
||||
margin: 0 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#requests-menu-perf-notice-button::before {
|
||||
.requests-list-perf-notice-button::before {
|
||||
background-image: url(images/profiler-stopwatch.svg);
|
||||
}
|
||||
|
||||
#requests-menu-reload-notice-button {
|
||||
.requests-list-reload-notice-button {
|
||||
font-size: inherit;
|
||||
min-height: 26px;
|
||||
margin: 0 5px;
|
||||
|
|
@ -119,21 +119,21 @@
|
|||
|
||||
/* Network requests table */
|
||||
|
||||
#requests-menu-toolbar {
|
||||
.requests-list-toolbar {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#requests-menu-filter-buttons {
|
||||
.requests-list-filter-buttons {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.theme-firebug #requests-menu-toolbar {
|
||||
.theme-firebug .requests-list-toolbar {
|
||||
height: 19px !important;
|
||||
}
|
||||
|
||||
.requests-menu-contents {
|
||||
.requests-list-contents {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-x: hidden;
|
||||
|
|
@ -142,7 +142,7 @@
|
|||
--timings-rev-scale: 1;
|
||||
}
|
||||
|
||||
.requests-menu-subitem {
|
||||
.requests-list-subitem {
|
||||
display: flex;
|
||||
flex: none;
|
||||
box-sizing: border-box;
|
||||
|
|
@ -157,12 +157,12 @@
|
|||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.requests-menu-header {
|
||||
.requests-list-header {
|
||||
display: flex;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.requests-menu-header-button {
|
||||
.requests-list-header-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: auto;
|
||||
|
|
@ -187,27 +187,27 @@
|
|||
font-weight: inherit !important;
|
||||
}
|
||||
|
||||
.requests-menu-header-button::-moz-focus-inner {
|
||||
.requests-list-header-button::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.requests-menu-header:first-child .requests-menu-header-button {
|
||||
.requests-list-header:first-child .requests-list-header-button {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.requests-menu-header-button:hover {
|
||||
.requests-list-header-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.requests-menu-header-button > .button-text {
|
||||
.requests-list-header-button > .button-text {
|
||||
flex: auto;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.requests-menu-header-button > .button-icon {
|
||||
.requests-list-header-button > .button-icon {
|
||||
flex: none;
|
||||
height: 4px;
|
||||
margin-inline-start: 3px;
|
||||
|
|
@ -215,32 +215,32 @@
|
|||
width: 7px;
|
||||
}
|
||||
|
||||
.requests-menu-header-button[data-sorted=ascending] > .button-icon {
|
||||
.requests-list-header-button[data-sorted=ascending] > .button-icon {
|
||||
background-image: var(--sort-ascending-image);
|
||||
}
|
||||
|
||||
.requests-menu-header-button[data-sorted=descending] > .button-icon {
|
||||
.requests-list-header-button[data-sorted=descending] > .button-icon {
|
||||
background-image: var(--sort-descending-image);
|
||||
}
|
||||
|
||||
.requests-menu-waterfall-label-wrapper {
|
||||
.requests-list-waterfall-label-wrapper {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.requests-menu-header-button[data-sorted],
|
||||
.requests-menu-header-button[data-sorted]:hover {
|
||||
.requests-list-header-button[data-sorted],
|
||||
.requests-list-header-button[data-sorted]:hover {
|
||||
background-color: var(--theme-selection-background);
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
.requests-menu-header-button[data-sorted],
|
||||
.requests-menu-header[data-active] + .requests-menu-header .requests-menu-header-button {
|
||||
.requests-list-header-button[data-sorted],
|
||||
.requests-list-header[data-active] + .requests-list-header .requests-list-header-button {
|
||||
border-image: linear-gradient(var(--theme-splitter-color), var(--theme-splitter-color)) 1 1;
|
||||
}
|
||||
|
||||
/* Firebug theme support for Network panel header */
|
||||
|
||||
.theme-firebug .requests-menu-header {
|
||||
.theme-firebug .requests-list-header {
|
||||
padding: 0 !important;
|
||||
font-weight: bold;
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.05),
|
||||
|
|
@ -248,24 +248,24 @@
|
|||
#C8D2DC;
|
||||
}
|
||||
|
||||
.theme-firebug .requests-menu-header-button {
|
||||
.theme-firebug .requests-list-header-button {
|
||||
min-height: 17px;
|
||||
}
|
||||
|
||||
.theme-firebug .requests-menu-header-button > .button-icon {
|
||||
.theme-firebug .requests-list-header-button > .button-icon {
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.theme-firebug .requests-menu-header-button[data-sorted] {
|
||||
.theme-firebug .requests-list-header-button[data-sorted] {
|
||||
background-color: #AAC3DC;
|
||||
}
|
||||
|
||||
:root[platform="linux"].theme-firebug .requests-menu-header-button[data-sorted] {
|
||||
:root[platform="linux"].theme-firebug .requests-list-header-button[data-sorted] {
|
||||
background-color: #FAC8AF !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.theme-firebug .requests-menu-header:hover:active {
|
||||
.theme-firebug .requests-list-header:hover:active {
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0.1),
|
||||
transparent);
|
||||
}
|
||||
|
|
@ -273,35 +273,35 @@
|
|||
|
||||
/* Network requests table: specific column dimensions */
|
||||
|
||||
.requests-menu-status {
|
||||
.requests-list-status {
|
||||
max-width: 6em;
|
||||
text-align: center;
|
||||
width: 10vw;
|
||||
}
|
||||
|
||||
.requests-menu-method,
|
||||
.requests-menu-method-box {
|
||||
.requests-list-method,
|
||||
.requests-list-method-box {
|
||||
max-width: 7em;
|
||||
text-align: center;
|
||||
width: 10vw;
|
||||
}
|
||||
|
||||
.requests-menu-icon-and-file {
|
||||
.requests-list-icon-and-file {
|
||||
width: 22vw;
|
||||
}
|
||||
|
||||
.requests-menu-icon {
|
||||
.requests-list-icon {
|
||||
background: transparent;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-inline-end: 4px;
|
||||
}
|
||||
|
||||
.requests-menu-icon {
|
||||
.requests-list-icon {
|
||||
outline: 1px solid var(--table-splitter-color);
|
||||
}
|
||||
|
||||
.requests-menu-security-and-domain {
|
||||
.requests-list-security-and-domain {
|
||||
width: 14vw;
|
||||
}
|
||||
|
||||
|
|
@ -336,25 +336,25 @@
|
|||
background-image: url(chrome://devtools/skin/images/globe.svg);
|
||||
}
|
||||
|
||||
.requests-menu-type,
|
||||
.requests-menu-size {
|
||||
.requests-list-type,
|
||||
.requests-list-size {
|
||||
max-width: 6em;
|
||||
width: 8vw;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.requests-menu-transferred {
|
||||
.requests-list-transferred {
|
||||
max-width: 8em;
|
||||
width: 8vw;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.requests-menu-cause {
|
||||
.requests-list-cause {
|
||||
max-width: 8em;
|
||||
width: 8vw;
|
||||
}
|
||||
|
||||
.requests-menu-cause-stack {
|
||||
.requests-list-cause-stack {
|
||||
background-color: var(--theme-body-color-alt);
|
||||
color: var(--theme-body-background);
|
||||
font-size: 8px;
|
||||
|
|
@ -367,19 +367,19 @@
|
|||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.request-list-item.selected .requests-menu-transferred.theme-comment {
|
||||
.request-list-item.selected .requests-list-transferred.theme-comment {
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
/* Network requests table: status codes */
|
||||
|
||||
.requests-menu-status-code {
|
||||
.requests-list-status-code {
|
||||
margin-inline-start: 3px !important;
|
||||
width: 3em;
|
||||
margin-inline-end: -3em !important;
|
||||
}
|
||||
|
||||
.requests-menu-status-icon {
|
||||
.requests-list-status-icon {
|
||||
background: #fff;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
|
|
@ -390,29 +390,29 @@
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.request-list-item.selected .requests-menu-status-icon {
|
||||
.request-list-item.selected .requests-list-status-icon {
|
||||
filter: brightness(1.3);
|
||||
}
|
||||
|
||||
.requests-menu-status-icon:not([data-code]) {
|
||||
.requests-list-status-icon:not([data-code]) {
|
||||
background-color: var(--theme-content-color2);
|
||||
}
|
||||
|
||||
.requests-menu-status-icon[data-code="cached"] {
|
||||
.requests-list-status-icon[data-code="cached"] {
|
||||
border: 2px solid var(--theme-content-color2);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.requests-menu-status-icon[data-code^="1"] {
|
||||
.requests-list-status-icon[data-code^="1"] {
|
||||
background-color: var(--theme-highlight-blue);
|
||||
}
|
||||
|
||||
.requests-menu-status-icon[data-code^="2"] {
|
||||
.requests-list-status-icon[data-code^="2"] {
|
||||
background-color: var(--theme-highlight-green);
|
||||
}
|
||||
|
||||
/* 3xx are triangles */
|
||||
.requests-menu-status-icon[data-code^="3"] {
|
||||
.requests-list-status-icon[data-code^="3"] {
|
||||
background-color: transparent;
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
|
@ -423,12 +423,12 @@
|
|||
}
|
||||
|
||||
/* 4xx and 5xx are squares - error codes */
|
||||
.requests-menu-status-icon[data-code^="4"] {
|
||||
.requests-list-status-icon[data-code^="4"] {
|
||||
background-color: var(--theme-highlight-red);
|
||||
border-radius: 0; /* squares */
|
||||
}
|
||||
|
||||
.requests-menu-status-icon[data-code^="5"] {
|
||||
.requests-list-status-icon[data-code^="5"] {
|
||||
background-color: var(--theme-highlight-pink);
|
||||
border-radius: 0;
|
||||
transform: rotate(45deg);
|
||||
|
|
@ -436,16 +436,16 @@
|
|||
|
||||
/* Network requests table: waterfall header */
|
||||
|
||||
.requests-menu-waterfall {
|
||||
.requests-list-waterfall {
|
||||
flex: auto;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
.requests-menu-waterfall-label-wrapper:not(.requests-menu-waterfall-visible) {
|
||||
.requests-list-waterfall-label-wrapper:not(.requests-list-waterfall-visible) {
|
||||
padding-inline-start: 16px;
|
||||
}
|
||||
|
||||
.requests-menu-timings-division {
|
||||
.requests-list-timings-division {
|
||||
padding-top: 2px;
|
||||
padding-inline-start: 4px;
|
||||
font-size: 75%;
|
||||
|
|
@ -457,34 +457,34 @@
|
|||
flex: initial;
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:not(:first-child) {
|
||||
.requests-list-timings-division:not(:first-child) {
|
||||
border-inline-start: 1px dashed;
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:-moz-locale-dir(ltr) {
|
||||
.requests-list-timings-division:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:-moz-locale-dir(rtl) {
|
||||
.requests-list-timings-division:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.theme-dark .requests-menu-timings-division {
|
||||
.theme-dark .requests-list-timings-division {
|
||||
border-inline-start-color: #5a6169 !important;
|
||||
}
|
||||
|
||||
.theme-light .requests-menu-timings-division {
|
||||
.theme-light .requests-list-timings-division {
|
||||
border-inline-start-color: #585959 !important;
|
||||
}
|
||||
|
||||
.requests-menu-timings-division[data-division-scale=second],
|
||||
.requests-menu-timings-division[data-division-scale=minute] {
|
||||
.requests-list-timings-division[data-division-scale=second],
|
||||
.requests-list-timings-division[data-division-scale=minute] {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Network requests table: waterfall items */
|
||||
|
||||
.requests-menu-subitem.requests-menu-waterfall {
|
||||
.requests-list-subitem.requests-list-waterfall {
|
||||
padding-inline-start: 0;
|
||||
padding-inline-end: 4px;
|
||||
/* Background created on a <canvas> in js. */
|
||||
|
|
@ -494,34 +494,34 @@
|
|||
background-position: left center;
|
||||
}
|
||||
|
||||
.requests-menu-subitem.requests-menu-waterfall:-moz-locale-dir(rtl) {
|
||||
.requests-list-subitem.requests-list-waterfall:-moz-locale-dir(rtl) {
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings {
|
||||
.requests-list-timings {
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
transform: scaleX(var(--timings-scale));
|
||||
}
|
||||
|
||||
.requests-menu-timings:-moz-locale-dir(ltr) {
|
||||
.requests-list-timings:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings:-moz-locale-dir(rtl) {
|
||||
.requests-list-timings:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total:-moz-locale-dir(ltr) {
|
||||
.requests-list-timings-total:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total:-moz-locale-dir(rtl) {
|
||||
.requests-list-timings-total:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total {
|
||||
.requests-list-timings-total {
|
||||
display: inline-block;
|
||||
padding-inline-start: 4px;
|
||||
font-size: 85%;
|
||||
|
|
@ -531,37 +531,37 @@
|
|||
transform: scaleX(var(--timings-rev-scale));
|
||||
}
|
||||
|
||||
.requests-menu-timings-box {
|
||||
.requests-list-timings-box {
|
||||
display: inline-block;
|
||||
height: 9px;
|
||||
}
|
||||
|
||||
.theme-firebug .requests-menu-timings-box {
|
||||
.theme-firebug .requests-list-timings-box {
|
||||
background-image: linear-gradient(rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.blocked {
|
||||
.requests-list-timings-box.blocked {
|
||||
background-color: var(--timing-blocked-color);
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.dns {
|
||||
.requests-list-timings-box.dns {
|
||||
background-color: var(--timing-dns-color);
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.connect {
|
||||
.requests-list-timings-box.connect {
|
||||
background-color: var(--timing-connect-color);
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.send {
|
||||
.requests-list-timings-box.send {
|
||||
background-color: var(--timing-send-color);
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.wait {
|
||||
.requests-list-timings-box.wait {
|
||||
background-color: var(--timing-wait-color);
|
||||
}
|
||||
|
||||
.requests-menu-timings-box.receive {
|
||||
.requests-list-timings-box.receive {
|
||||
background-color: var(--timing-receive-color);
|
||||
}
|
||||
|
||||
|
|
@ -595,27 +595,27 @@
|
|||
background: #EFEFEF;
|
||||
}
|
||||
|
||||
.theme-firebug .requests-menu-subitem {
|
||||
.theme-firebug .requests-list-subitem {
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
/* HTTP Status Column */
|
||||
.theme-firebug .requests-menu-subitem.requests-menu-status {
|
||||
.theme-firebug .requests-list-subitem.requests-list-status {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Method Column */
|
||||
|
||||
.theme-firebug .requests-menu-subitem.requests-menu-method-box {
|
||||
.theme-firebug .requests-list-subitem.requests-list-method-box {
|
||||
color: rgb(128, 128, 128);
|
||||
}
|
||||
|
||||
.request-list-item.selected .requests-menu-method {
|
||||
.request-list-item.selected .requests-list-method {
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
/* Size Column */
|
||||
.theme-firebug .requests-menu-subitem.requests-menu-size {
|
||||
.theme-firebug .requests-list-subitem.requests-list-size {
|
||||
justify-content: end;
|
||||
padding-inline-end: 4px;
|
||||
}
|
||||
|
|
@ -706,23 +706,23 @@
|
|||
width: 10em;
|
||||
}
|
||||
|
||||
.requests-menu-timings-container {
|
||||
.requests-list-timings-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-offset {
|
||||
.requests-list-timings-offset {
|
||||
transition: width 0.2s ease-out;
|
||||
}
|
||||
|
||||
.requests-menu-timings-box {
|
||||
.requests-list-timings-box {
|
||||
border: none;
|
||||
min-width: 1px;
|
||||
transition: width 0.2s ease-out;
|
||||
}
|
||||
|
||||
.theme-firebug .requests-menu-timings-total {
|
||||
.theme-firebug .requests-list-timings-total {
|
||||
color: var(--theme-body-color);
|
||||
}
|
||||
|
||||
|
|
@ -805,7 +805,7 @@
|
|||
|
||||
/* Performance analysis buttons */
|
||||
|
||||
#requests-menu-network-summary-button {
|
||||
.requests-list-network-summary-button {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
|
|
@ -818,7 +818,7 @@
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
#requests-menu-network-summary-button > .summary-info-icon {
|
||||
.requests-list-network-summary-button > .summary-info-icon {
|
||||
background-image: url(images/profiler-stopwatch.svg);
|
||||
filter: var(--icon-filter);
|
||||
width: 16px;
|
||||
|
|
@ -826,13 +826,13 @@
|
|||
opacity: 0.8;
|
||||
}
|
||||
|
||||
#requests-menu-network-summary-button > .summary-info-text {
|
||||
.requests-list-network-summary-button > .summary-info-text {
|
||||
opacity: 0.8;
|
||||
margin-inline-start: 0.5em;
|
||||
}
|
||||
|
||||
#requests-menu-network-summary-button:hover > .summary-info-icon,
|
||||
#requests-menu-network-summary-button:hover > .summary-info-text {
|
||||
.requests-list-network-summary-button:hover > .summary-info-icon,
|
||||
.requests-list-network-summary-button:hover > .summary-info-text {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
|
@ -1010,51 +1010,51 @@
|
|||
@media (max-width: 700px) {
|
||||
#toolbar-spacer,
|
||||
.network-details-panel-toggle,
|
||||
#requests-menu-network-summary-button > .summary-info-text {
|
||||
.requests-list-network-summary-button > .summary-info-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#requests-menu-toolbar {
|
||||
.requests-list-toolbar {
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.requests-menu-header-button {
|
||||
.requests-list-header-button {
|
||||
min-height: 22px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.requests-menu-status {
|
||||
.requests-list-status {
|
||||
max-width: none;
|
||||
width: 10vw;
|
||||
}
|
||||
|
||||
.requests-menu-status-code {
|
||||
.requests-list-status-code {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.requests-menu-method,
|
||||
.requests-menu-method-box {
|
||||
.requests-list-method,
|
||||
.requests-list-method-box {
|
||||
max-width: none;
|
||||
width: 12vw;
|
||||
}
|
||||
|
||||
.requests-menu-icon-and-file {
|
||||
.requests-list-icon-and-file {
|
||||
width: 22vw;
|
||||
}
|
||||
|
||||
.requests-menu-security-and-domain {
|
||||
.requests-list-security-and-domain {
|
||||
width: 16vw;
|
||||
}
|
||||
|
||||
.requests-menu-cause,
|
||||
.requests-menu-type,
|
||||
.requests-menu-transferred,
|
||||
.requests-menu-size {
|
||||
.requests-list-cause,
|
||||
.requests-list-type,
|
||||
.requests-list-transferred,
|
||||
.requests-list-size {
|
||||
max-width: none;
|
||||
width: 10vw;
|
||||
}
|
||||
|
||||
.requests-menu-waterfall {
|
||||
.requests-list-waterfall {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
@ -1071,11 +1071,11 @@
|
|||
}
|
||||
|
||||
/* Platform overrides (copied in from the old platform specific files) */
|
||||
:root[platform="win"] .requests-menu-header-button > .button-box {
|
||||
:root[platform="win"] .requests-list-header-button > .button-box {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root[platform="win"] .requests-menu-timings-division {
|
||||
:root[platform="win"] .requests-list-timings-division {
|
||||
padding-top: 1px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
|
@ -1090,7 +1090,7 @@
|
|||
|
||||
/* Responsive sidebar */
|
||||
@media (max-width: 700px) {
|
||||
:root[platform="linux"] .requests-menu-header-button {
|
||||
:root[platform="linux"] .requests-list-header-button {
|
||||
font-size: 85%;
|
||||
}
|
||||
}
|
||||
|
|
@ -1233,7 +1233,7 @@
|
|||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
.headers-summary .requests-menu-status-icon {
|
||||
.headers-summary .requests-list-status-icon {
|
||||
min-width: 10px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -388,20 +388,23 @@ nsIContent::GetBaseURI(bool aTryUseXHRDocBaseURI) const
|
|||
elem = elem->GetParent();
|
||||
} while(elem);
|
||||
|
||||
// Now resolve against all xml:base attrs
|
||||
for (uint32_t i = baseAttrs.Length() - 1; i != uint32_t(-1); --i) {
|
||||
nsCOMPtr<nsIURI> newBase;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(newBase), baseAttrs[i],
|
||||
doc->GetDocumentCharacterSet().get(), base);
|
||||
// Do a security check, almost the same as nsDocument::SetBaseURL()
|
||||
// Only need to do this on the final uri
|
||||
if (NS_SUCCEEDED(rv) && i == 0) {
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(NodePrincipal(), newBase,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
base.swap(newBase);
|
||||
if (!baseAttrs.IsEmpty()) {
|
||||
doc->WarnOnceAbout(nsIDocument::eXMLBaseAttribute);
|
||||
// Now resolve against all xml:base attrs
|
||||
for (uint32_t i = baseAttrs.Length() - 1; i != uint32_t(-1); --i) {
|
||||
nsCOMPtr<nsIURI> newBase;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(newBase), baseAttrs[i],
|
||||
doc->GetDocumentCharacterSet().get(), base);
|
||||
// Do a security check, almost the same as nsDocument::SetBaseURL()
|
||||
// Only need to do this on the final uri
|
||||
if (NS_SUCCEEDED(rv) && i == 0) {
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(NodePrincipal(), newBase,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
base.swap(newBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,3 +51,4 @@ DEPRECATED_OPERATION(LenientSetter)
|
|||
DEPRECATED_OPERATION(FileLastModifiedDate)
|
||||
DEPRECATED_OPERATION(ImageBitmapRenderingContext_TransferImageBitmap)
|
||||
DEPRECATED_OPERATION(URLCreateObjectURL_MediaStream)
|
||||
DEPRECATED_OPERATION(XMLBaseAttribute)
|
||||
|
|
|
|||
|
|
@ -1473,9 +1473,9 @@ nsIDocument::~nsIDocument()
|
|||
}
|
||||
|
||||
bool
|
||||
nsDocument::IsAboutPage()
|
||||
nsDocument::IsAboutPage() const
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
|
||||
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
principal->GetURI(getter_AddRefs(uri));
|
||||
bool isAboutScheme = true;
|
||||
|
|
@ -10148,7 +10148,13 @@ nsIDocument::WarnOnceAbout(DeprecatedOperations aOperation,
|
|||
return;
|
||||
}
|
||||
mDeprecationWarnedAbout[aOperation] = true;
|
||||
const_cast<nsIDocument*>(this)->SetDocumentAndPageUseCounter(OperationToUseCounter(aOperation));
|
||||
// Don't count deprecated operations for about pages since those pages
|
||||
// are almost in our control, and we always need to remove uses there
|
||||
// before we remove the operation itself anyway.
|
||||
if (!static_cast<const nsDocument*>(this)->IsAboutPage()) {
|
||||
const_cast<nsIDocument*>(this)->
|
||||
SetDocumentAndPageUseCounter(OperationToUseCounter(aOperation));
|
||||
}
|
||||
uint32_t flags = asError ? nsIScriptError::errorFlag
|
||||
: nsIScriptError::warningFlag;
|
||||
nsContentUtils::ReportToConsole(flags,
|
||||
|
|
|
|||
|
|
@ -1527,7 +1527,7 @@ private:
|
|||
void ClearAllBoxObjects();
|
||||
|
||||
// Returns true if the scheme for the url for this document is "about"
|
||||
bool IsAboutPage();
|
||||
bool IsAboutPage() const;
|
||||
|
||||
// These are not implemented and not supported.
|
||||
nsDocument(const nsDocument& aOther);
|
||||
|
|
|
|||
|
|
@ -323,3 +323,5 @@ GeolocationInsecureRequestIsForbidden=A Geolocation request can only be fulfille
|
|||
LargeAllocationNonWin32=This page would be loaded in a new process due to a Large-Allocation header, however Large-Allocation process creation is disabled on non-Win32 platforms.
|
||||
# LOCALIZATION NOTE: Do not translate URL.createObjectURL(MediaStream).
|
||||
URLCreateObjectURL_MediaStream=URL.createObjectURL(MediaStream) is deprecated and will be removed soon.
|
||||
# LOCALIZATION NOTE: Do not translate xml:base.
|
||||
XMLBaseAttributeWarning=Use of xml:base attribute is deprecated and will be removed soon. Please remove any use of it.
|
||||
|
|
|
|||
|
|
@ -310,6 +310,66 @@ LocalAllocPolicy::Cancel()
|
|||
mTokenRequest.DisconnectIfExists();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class tracks shutdown promises to ensure all decoders are shut down
|
||||
* completely before MFR continues the rest of the shutdown procedure.
|
||||
*/
|
||||
class MediaFormatReader::ShutdownPromisePool
|
||||
{
|
||||
public:
|
||||
ShutdownPromisePool()
|
||||
: mOnShutdownComplete(new ShutdownPromise::Private(__func__))
|
||||
{
|
||||
}
|
||||
|
||||
// Return a promise which will be resolved when all the tracking promises
|
||||
// are resolved. Note no more promises should be added for tracking once
|
||||
// this function is called.
|
||||
RefPtr<ShutdownPromise> Shutdown();
|
||||
|
||||
// Track a shutdown promise.
|
||||
void Track(RefPtr<ShutdownPromise> aPromise);
|
||||
|
||||
// Shut down a decoder and track its shutdown promise.
|
||||
void ShutdownDecoder(already_AddRefed<MediaDataDecoder> aDecoder)
|
||||
{
|
||||
Track(RefPtr<MediaDataDecoder>(aDecoder)->Shutdown());
|
||||
}
|
||||
|
||||
private:
|
||||
bool mShutdown = false;
|
||||
const RefPtr<ShutdownPromise::Private> mOnShutdownComplete;
|
||||
nsTHashtable<nsRefPtrHashKey<ShutdownPromise>> mPromises;
|
||||
};
|
||||
|
||||
RefPtr<ShutdownPromise>
|
||||
MediaFormatReader::ShutdownPromisePool::Shutdown()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mShutdown);
|
||||
mShutdown = true;
|
||||
if (mPromises.Count() == 0) {
|
||||
mOnShutdownComplete->Resolve(true, __func__);
|
||||
}
|
||||
return mOnShutdownComplete;
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::ShutdownPromisePool::Track(RefPtr<ShutdownPromise> aPromise)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mShutdown);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mPromises.Contains(aPromise));
|
||||
mPromises.PutEntry(aPromise);
|
||||
aPromise->Then(
|
||||
AbstractThread::GetCurrent(), __func__,
|
||||
[aPromise, this]() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPromises.Contains(aPromise));
|
||||
mPromises.RemoveEntry(aPromise);
|
||||
if (mShutdown && mPromises.Count() == 0) {
|
||||
mOnShutdownComplete->Resolve(true, __func__);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class MediaFormatReader::DecoderFactory
|
||||
{
|
||||
using InitPromise = MediaDataDecoder::InitPromise;
|
||||
|
|
@ -323,8 +383,10 @@ public:
|
|||
, mOwner(WrapNotNull(aOwner)) { }
|
||||
|
||||
void CreateDecoder(TrackType aTrack);
|
||||
// Shutdown any decoder pending initialization.
|
||||
RefPtr<ShutdownPromise> ShutdownDecoder(TrackType aTrack)
|
||||
|
||||
// Shutdown any decoder pending initialization and reset mAudio/mVideo to its
|
||||
// pristine state so CreateDecoder() is ready to be called again immediately.
|
||||
void ShutdownDecoder(TrackType aTrack)
|
||||
{
|
||||
MOZ_ASSERT(aTrack == TrackInfo::kAudioTrack
|
||||
|| aTrack == TrackInfo::kVideoTrack);
|
||||
|
|
@ -332,18 +394,11 @@ public:
|
|||
data.mPolicy->Cancel();
|
||||
data.mTokenRequest.DisconnectIfExists();
|
||||
data.mInitRequest.DisconnectIfExists();
|
||||
if (!data.mDecoder) {
|
||||
return ShutdownPromise::CreateAndResolve(true, __func__);
|
||||
if (data.mDecoder) {
|
||||
mOwner->mShutdownPromisePool->ShutdownDecoder(data.mDecoder.forget());
|
||||
}
|
||||
if (data.mShutdownRequest.Exists()) {
|
||||
// A shutdown is already in progress due to a prior initialization error,
|
||||
// return the existing promise.
|
||||
data.mShutdownRequest.Disconnect();
|
||||
RefPtr<ShutdownPromise> p = data.mShutdownPromise.forget();
|
||||
return p;
|
||||
}
|
||||
RefPtr<MediaDataDecoder> decoder = data.mDecoder.forget();
|
||||
return decoder->Shutdown();
|
||||
data.mStage = Stage::None;
|
||||
MOZ_ASSERT(!data.mToken);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -371,8 +426,6 @@ private:
|
|||
RefPtr<MediaDataDecoder> mDecoder;
|
||||
MozPromiseRequestHolder<TokenPromise> mTokenRequest;
|
||||
MozPromiseRequestHolder<InitPromise> mInitRequest;
|
||||
MozPromiseRequestHolder<ShutdownPromise> mShutdownRequest;
|
||||
RefPtr<ShutdownPromise> mShutdownPromise;
|
||||
} mAudio, mVideo;
|
||||
|
||||
void RunStage(Data& aData);
|
||||
|
|
@ -583,18 +636,8 @@ MediaFormatReader::DecoderFactory::DoInitDecoder(Data& aData)
|
|||
MOZ_RELEASE_ASSERT(!ownerData.mDecoder,
|
||||
"Can't have a decoder already set");
|
||||
aData.mStage = Stage::None;
|
||||
aData.mShutdownPromise = aData.mDecoder->Shutdown();
|
||||
aData.mShutdownPromise
|
||||
->Then(
|
||||
mOwner->OwnerThread(), __func__,
|
||||
[this, &aData, aError]() {
|
||||
aData.mShutdownRequest.Complete();
|
||||
aData.mShutdownPromise = nullptr;
|
||||
aData.mDecoder = nullptr;
|
||||
mOwner->NotifyError(aData.mTrack, aError);
|
||||
},
|
||||
[]() { MOZ_RELEASE_ASSERT(false, "Can't ever get here"); })
|
||||
->Track(aData.mShutdownRequest);
|
||||
mOwner->mShutdownPromisePool->ShutdownDecoder(aData.mDecoder.forget());
|
||||
mOwner->NotifyError(aData.mTrack, aError);
|
||||
})
|
||||
->Track(aData.mInitRequest);
|
||||
}
|
||||
|
|
@ -978,6 +1021,7 @@ MediaFormatReader::MediaFormatReader(AbstractMediaDecoder* aDecoder,
|
|||
, mSeekScheduled(false)
|
||||
, mVideoFrameContainer(aVideoFrameContainer)
|
||||
, mDecoderFactory(new DecoderFactory(this))
|
||||
, mShutdownPromisePool(new ShutdownPromisePool())
|
||||
{
|
||||
MOZ_ASSERT(aDemuxer);
|
||||
MOZ_COUNT_CTOR(MediaFormatReader);
|
||||
|
|
@ -1015,14 +1059,12 @@ MediaFormatReader::Shutdown()
|
|||
mVideo.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
|
||||
}
|
||||
|
||||
nsTArray<RefPtr<ShutdownPromise>> promises;
|
||||
|
||||
if (HasAudio()) {
|
||||
mAudio.ResetDemuxer();
|
||||
mAudio.mTrackDemuxer->BreakCycles();
|
||||
mAudio.mTrackDemuxer = nullptr;
|
||||
mAudio.ResetState();
|
||||
promises.AppendElement(ShutdownDecoderWithPromise(TrackInfo::kAudioTrack));
|
||||
mShutdownPromisePool->Track(ShutdownDecoderWithPromise(TrackInfo::kAudioTrack));
|
||||
}
|
||||
|
||||
if (HasVideo()) {
|
||||
|
|
@ -1030,24 +1072,20 @@ MediaFormatReader::Shutdown()
|
|||
mVideo.mTrackDemuxer->BreakCycles();
|
||||
mVideo.mTrackDemuxer = nullptr;
|
||||
mVideo.ResetState();
|
||||
promises.AppendElement(ShutdownDecoderWithPromise(TrackInfo::kVideoTrack));
|
||||
mShutdownPromisePool->Track(ShutdownDecoderWithPromise(TrackInfo::kVideoTrack));
|
||||
}
|
||||
|
||||
promises.AppendElement(mDemuxer->Shutdown());
|
||||
mShutdownPromisePool->Track(mDemuxer->Shutdown());
|
||||
mDemuxer = nullptr;
|
||||
|
||||
mCompositorUpdatedListener.DisconnectIfExists();
|
||||
mOnTrackWaitingForKeyListener.Disconnect();
|
||||
|
||||
RefPtr<ShutdownPromise> p = mShutdownPromise.Ensure(__func__);
|
||||
ShutdownPromise::All(OwnerThread(), promises)
|
||||
mShutdown = true;
|
||||
return mShutdownPromisePool->Shutdown()
|
||||
->Then(OwnerThread(), __func__, this,
|
||||
&MediaFormatReader::TearDownDecoders,
|
||||
&MediaFormatReader::TearDownDecoders);
|
||||
|
||||
mShutdown = true;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
RefPtr<ShutdownPromise>
|
||||
|
|
@ -1075,7 +1113,8 @@ MediaFormatReader::ShutdownDecoderWithPromise(TrackType aTrack)
|
|||
// in the Decoder Factory.
|
||||
// This will be a no-op until we're processing the final decoder shutdown
|
||||
// prior to the MediaFormatReader being shutdown.
|
||||
return mDecoderFactory->ShutdownDecoder(aTrack);
|
||||
mDecoderFactory->ShutdownDecoder(aTrack);
|
||||
return ShutdownPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
// Finally, let's just shut down the currently active decoder.
|
||||
|
|
@ -1099,7 +1138,7 @@ MediaFormatReader::ShutdownDecoder(TrackType aTrack)
|
|||
Unused << ShutdownDecoderWithPromise(aTrack);
|
||||
}
|
||||
|
||||
void
|
||||
RefPtr<ShutdownPromise>
|
||||
MediaFormatReader::TearDownDecoders()
|
||||
{
|
||||
if (mAudio.mTaskQueue) {
|
||||
|
|
@ -1117,12 +1156,7 @@ MediaFormatReader::TearDownDecoders()
|
|||
mPlatform = nullptr;
|
||||
mVideoFrameContainer = nullptr;
|
||||
|
||||
if (mShutdownPromise.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MediaDecoderReader::Shutdown();
|
||||
mShutdownPromise.Resolve(true, __func__);
|
||||
return MediaDecoderReader::Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -575,6 +575,9 @@ private:
|
|||
class DecoderFactory;
|
||||
UniquePtr<DecoderFactory> mDecoderFactory;
|
||||
|
||||
class ShutdownPromisePool;
|
||||
UniquePtr<ShutdownPromisePool> mShutdownPromisePool;
|
||||
|
||||
MediaEventListener mCompositorUpdatedListener;
|
||||
MediaEventListener mOnTrackWaitingForKeyListener;
|
||||
|
||||
|
|
@ -592,8 +595,7 @@ private:
|
|||
|
||||
void ShutdownDecoder(TrackType aTrack);
|
||||
RefPtr<ShutdownPromise> ShutdownDecoderWithPromise(TrackType aTrack);
|
||||
void TearDownDecoders();
|
||||
MozPromiseHolder<ShutdownPromise> mShutdownPromise;
|
||||
RefPtr<ShutdownPromise> TearDownDecoders();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
|
|
@ -272,21 +272,16 @@ GetSupportedKeySystems()
|
|||
clearkey.mSessionTypes.AppendElement(MediaKeySessionType::Persistent_license);
|
||||
}
|
||||
#if defined(XP_WIN)
|
||||
// Clearkey CDM uses WMF decoders on Windows.
|
||||
if (WMFDecoderModule::HasAAC()) {
|
||||
clearkey.mMP4.SetCanDecryptAndDecode(EME_CODEC_AAC);
|
||||
} else {
|
||||
clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC);
|
||||
}
|
||||
// Clearkey CDM uses WMF's H.264 decoder on Windows.
|
||||
if (WMFDecoderModule::HasH264()) {
|
||||
clearkey.mMP4.SetCanDecryptAndDecode(EME_CODEC_H264);
|
||||
} else {
|
||||
clearkey.mMP4.SetCanDecrypt(EME_CODEC_H264);
|
||||
}
|
||||
#else
|
||||
clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC);
|
||||
clearkey.mMP4.SetCanDecrypt(EME_CODEC_H264);
|
||||
#endif
|
||||
clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC);
|
||||
if (Preferences::GetBool("media.eme.vp9-in-mp4.enabled", false)) {
|
||||
clearkey.mMP4.SetCanDecrypt(EME_CODEC_VP9);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include "WidevineUtils.h"
|
||||
#include "WidevineFileIO.h"
|
||||
#include "GMPPlatform.h"
|
||||
#include <mozilla/SizePrintfMacros.h>
|
||||
#include <stdarg.h>
|
||||
#include "TimeUnits.h"
|
||||
|
||||
|
|
@ -161,43 +160,6 @@ WidevineDecryptor::SetServerCertificate(uint32_t aPromiseId,
|
|||
CDM()->SetServerCertificate(aPromiseId, aServerCert, aServerCertSize);
|
||||
}
|
||||
|
||||
class WidevineDecryptedBlock : public cdm::DecryptedBlock {
|
||||
public:
|
||||
|
||||
WidevineDecryptedBlock()
|
||||
: mBuffer(nullptr)
|
||||
, mTimestamp(0)
|
||||
{
|
||||
}
|
||||
|
||||
~WidevineDecryptedBlock() override {
|
||||
if (mBuffer) {
|
||||
mBuffer->Destroy();
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SetDecryptedBuffer(cdm::Buffer* aBuffer) override {
|
||||
mBuffer = aBuffer;
|
||||
}
|
||||
|
||||
cdm::Buffer* DecryptedBuffer() override {
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
void SetTimestamp(int64_t aTimestamp) override {
|
||||
mTimestamp = aTimestamp;
|
||||
}
|
||||
|
||||
int64_t Timestamp() const override {
|
||||
return mTimestamp;
|
||||
}
|
||||
|
||||
private:
|
||||
cdm::Buffer* mBuffer;
|
||||
int64_t mTimestamp;
|
||||
};
|
||||
|
||||
cdm::Time
|
||||
WidevineDecryptor::ThrottleDecrypt(cdm::Time aWallTime, cdm::Time aSampleDuration)
|
||||
{
|
||||
|
|
@ -327,28 +289,6 @@ WidevineDecryptor::DecryptingComplete()
|
|||
Release();
|
||||
}
|
||||
|
||||
class WidevineBuffer : public cdm::Buffer {
|
||||
public:
|
||||
explicit WidevineBuffer(size_t aSize) {
|
||||
CDM_LOG("WidevineBuffer(size=%" PRIuSIZE ") created", aSize);
|
||||
mBuffer.SetLength(aSize);
|
||||
}
|
||||
~WidevineBuffer() override {
|
||||
CDM_LOG("WidevineBuffer(size=%" PRIu32 ") destroyed", Size());
|
||||
}
|
||||
void Destroy() override { delete this; }
|
||||
uint32_t Capacity() const override { return mBuffer.Length(); };
|
||||
uint8_t* Data() override { return mBuffer.Elements(); }
|
||||
void SetSize(uint32_t aSize) override { mBuffer.SetLength(aSize); }
|
||||
uint32_t Size() const override { return mBuffer.Length(); }
|
||||
|
||||
private:
|
||||
WidevineBuffer(const WidevineBuffer&);
|
||||
void operator=(const WidevineBuffer&);
|
||||
|
||||
nsTArray<uint8_t> mBuffer;
|
||||
};
|
||||
|
||||
Buffer*
|
||||
WidevineDecryptor::Allocate(uint32_t aCapacity)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@
|
|||
|
||||
#include "WidevineUtils.h"
|
||||
#include "WidevineDecryptor.h"
|
||||
#include <mozilla/SizePrintfMacros.h>
|
||||
|
||||
#include "gmp-api/gmp-errors.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
@ -76,4 +78,90 @@ CDMWrapper::~CDMWrapper()
|
|||
mCDM = nullptr;
|
||||
}
|
||||
|
||||
WidevineBuffer::WidevineBuffer(size_t aSize)
|
||||
{
|
||||
CDM_LOG("WidevineBuffer(size=%" PRIuSIZE ") created", aSize);
|
||||
mBuffer.SetLength(aSize);
|
||||
}
|
||||
|
||||
WidevineBuffer::~WidevineBuffer()
|
||||
{
|
||||
CDM_LOG("WidevineBuffer(size=%" PRIu32 ") destroyed", Size());
|
||||
}
|
||||
|
||||
void
|
||||
WidevineBuffer::Destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WidevineBuffer::Capacity() const
|
||||
{
|
||||
return mBuffer.Length();
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
WidevineBuffer::Data()
|
||||
{
|
||||
return mBuffer.Elements();
|
||||
}
|
||||
|
||||
void
|
||||
WidevineBuffer::SetSize(uint32_t aSize)
|
||||
{
|
||||
mBuffer.SetLength(aSize);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WidevineBuffer::Size() const
|
||||
{
|
||||
return mBuffer.Length();
|
||||
}
|
||||
|
||||
nsTArray<uint8_t>
|
||||
WidevineBuffer::ExtractBuffer() {
|
||||
nsTArray<uint8_t> out;
|
||||
out.SwapElements(mBuffer);
|
||||
return out;
|
||||
}
|
||||
|
||||
WidevineDecryptedBlock::WidevineDecryptedBlock()
|
||||
: mBuffer(nullptr)
|
||||
, mTimestamp(0)
|
||||
{
|
||||
}
|
||||
|
||||
WidevineDecryptedBlock::~WidevineDecryptedBlock()
|
||||
{
|
||||
if (mBuffer) {
|
||||
mBuffer->Destroy();
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WidevineDecryptedBlock::SetDecryptedBuffer(cdm::Buffer* aBuffer)
|
||||
{
|
||||
mBuffer = aBuffer;
|
||||
}
|
||||
|
||||
cdm::Buffer*
|
||||
WidevineDecryptedBlock::DecryptedBuffer()
|
||||
{
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
void
|
||||
WidevineDecryptedBlock::SetTimestamp(int64_t aTimestamp)
|
||||
{
|
||||
mTimestamp = aTimestamp;
|
||||
}
|
||||
|
||||
int64_t
|
||||
WidevineDecryptedBlock::Timestamp() const
|
||||
{
|
||||
return mTimestamp;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
|
|
@ -61,6 +61,43 @@ void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto,
|
|||
cdm::InputBuffer &aInputBuffer,
|
||||
nsTArray<cdm::SubsampleEntry> &aSubsamples);
|
||||
|
||||
class WidevineBuffer : public cdm::Buffer
|
||||
{
|
||||
public:
|
||||
explicit WidevineBuffer(size_t aSize);
|
||||
~WidevineBuffer() override;
|
||||
void Destroy() override;
|
||||
uint32_t Capacity() const override;
|
||||
uint8_t* Data() override;
|
||||
void SetSize(uint32_t aSize) override;
|
||||
uint32_t Size() const override;
|
||||
|
||||
// Moves contents of buffer out into temporary.
|
||||
// Note: This empties the buffer.
|
||||
nsTArray<uint8_t> ExtractBuffer();
|
||||
|
||||
private:
|
||||
nsTArray<uint8_t> mBuffer;
|
||||
WidevineBuffer(const WidevineBuffer&);
|
||||
void operator=(const WidevineBuffer&);
|
||||
};
|
||||
|
||||
class WidevineDecryptedBlock : public cdm::DecryptedBlock
|
||||
{
|
||||
public:
|
||||
|
||||
WidevineDecryptedBlock();
|
||||
~WidevineDecryptedBlock() override;
|
||||
void SetDecryptedBuffer(cdm::Buffer* aBuffer) override;
|
||||
cdm::Buffer* DecryptedBuffer() override;
|
||||
void SetTimestamp(int64_t aTimestamp) override;
|
||||
int64_t Timestamp() const override;
|
||||
|
||||
private:
|
||||
cdm::Buffer* mBuffer;
|
||||
int64_t mTimestamp;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WidevineUtils_h_
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ SOURCES += [
|
|||
'WidevineVideoFrame.cpp',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'WidevineDecryptor.h',
|
||||
'WidevineUtils.h'
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
|
|
|||
|
|
@ -297,6 +297,10 @@ NormalizedConstraints::NormalizedConstraints(
|
|||
: NormalizedConstraintSet(*aOthers[0])
|
||||
, mBadConstraint(nullptr)
|
||||
{
|
||||
for (auto& entry : aOthers[0]->mAdvanced) {
|
||||
mAdvanced.push_back(entry);
|
||||
}
|
||||
|
||||
// Create a list of member pointers.
|
||||
nsTArray<MemberPtrType> list;
|
||||
NormalizedConstraints dummy(dom::MediaTrackConstraints(), &list);
|
||||
|
|
|
|||
|
|
@ -836,10 +836,20 @@ VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand)
|
|||
: VRControllerHost(VRDeviceType::Oculus)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost);
|
||||
mControllerInfo.mControllerName.AssignLiteral("Oculus Touch (");
|
||||
mControllerInfo.mControllerName.AppendPrintf("%s%s",
|
||||
GamepadHandValues::strings[uint32_t(aHand)].value,
|
||||
")");
|
||||
|
||||
char* touchID = "";
|
||||
switch (aHand) {
|
||||
case dom::GamepadHand::Left:
|
||||
touchID = "Oculus Touch (Left)";
|
||||
break;
|
||||
case dom::GamepadHand::Right:
|
||||
touchID = "Oculus Touch (Right)";
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
mControllerInfo.mControllerName = touchID;
|
||||
mControllerInfo.mMappingType = GamepadMappingType::_empty;
|
||||
mControllerInfo.mHand = aHand;
|
||||
mControllerInfo.mNumButtons = kNumOculusButton;
|
||||
|
|
@ -988,10 +998,13 @@ VRSystemManagerOculus::HandleInput()
|
|||
|
||||
// Start to process pose
|
||||
ovrTrackingState state = ovr_GetTrackingState(mSession, 0.0, false);
|
||||
ovrPoseStatef& pose(state.HandPoses[i]);
|
||||
// HandPoses is ordered by ovrControllerType_LTouch and ovrControllerType_RTouch,
|
||||
// therefore, we can't get its state by the index of mOculusController.
|
||||
const uint32_t handIdx = static_cast<uint32_t>(controller->GetHand()) - 1;
|
||||
ovrPoseStatef& pose(state.HandPoses[handIdx]);
|
||||
GamepadPoseState poseState;
|
||||
|
||||
if (state.HandStatusFlags[i] & ovrStatus_OrientationTracked) {
|
||||
if (state.HandStatusFlags[handIdx] & ovrStatus_OrientationTracked) {
|
||||
poseState.flags |= GamepadCapabilityFlags::Cap_Orientation;
|
||||
poseState.orientation[0] = pose.ThePose.Orientation.x;
|
||||
poseState.orientation[1] = pose.ThePose.Orientation.y;
|
||||
|
|
@ -1006,7 +1019,7 @@ VRSystemManagerOculus::HandleInput()
|
|||
poseState.angularAcceleration[1] = pose.AngularAcceleration.y;
|
||||
poseState.angularAcceleration[2] = pose.AngularAcceleration.z;
|
||||
}
|
||||
if (state.HandStatusFlags[i] & ovrStatus_PositionTracked) {
|
||||
if (state.HandStatusFlags[handIdx] & ovrStatus_PositionTracked) {
|
||||
poseState.flags |= GamepadCapabilityFlags::Cap_Position;
|
||||
poseState.position[0] = pose.ThePose.Position.x;
|
||||
poseState.position[1] = pose.ThePose.Position.y;
|
||||
|
|
@ -1039,10 +1052,10 @@ VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
|
|||
|
||||
for (uint32_t i = 0; i < kNumOculusButton; ++i) {
|
||||
switch (hand) {
|
||||
case mozilla::dom::GamepadHand::Left:
|
||||
case dom::GamepadHand::Left:
|
||||
buttonMask = kOculusTouchLButton[i];
|
||||
break;
|
||||
case mozilla::dom::GamepadHand::Right:
|
||||
case dom::GamepadHand::Right:
|
||||
buttonMask = kOculusTouchRButton[i];
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1080,6 +1093,7 @@ VRSystemManagerOculus::HandlePoseTracking(uint32_t aControllerIdx,
|
|||
const GamepadPoseState& aPose,
|
||||
VRControllerHost* aController)
|
||||
{
|
||||
MOZ_ASSERT(aController);
|
||||
if (aPose != aController->GetPose()) {
|
||||
aController->SetPose(aPose);
|
||||
NewPoseState(aControllerIdx, aPose);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "unicode/udat.h"
|
||||
#include "unicode/udatpg.h"
|
||||
#include "unicode/uenum.h"
|
||||
#include "unicode/uloc.h"
|
||||
#include "unicode/unum.h"
|
||||
#include "unicode/unumsys.h"
|
||||
#include "unicode/upluralrules.h"
|
||||
|
|
@ -167,6 +168,12 @@ uloc_countAvailable()
|
|||
MOZ_CRASH("uloc_countAvailable: Intl API disabled");
|
||||
}
|
||||
|
||||
UBool
|
||||
uloc_isRightToLeft(const char* locale)
|
||||
{
|
||||
MOZ_CRASH("uloc_isRightToLeft: Intl API disabled");
|
||||
}
|
||||
|
||||
struct UFormattable;
|
||||
|
||||
void
|
||||
|
|
@ -4031,6 +4038,34 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::intl_GetLocaleInfo(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
|
||||
JSAutoByteString locale(cx, args[0].toString());
|
||||
if (!locale)
|
||||
return false;
|
||||
|
||||
RootedObject info(cx, NewBuiltinClassInstance<PlainObject>(cx));
|
||||
if (!info)
|
||||
return false;
|
||||
|
||||
if (!DefineProperty(cx, info, cx->names().locale, args[0]))
|
||||
return false;
|
||||
|
||||
bool rtl = uloc_isRightToLeft(icuLocale(locale.ptr()));
|
||||
|
||||
RootedValue dir(cx, StringValue(rtl ? cx->names().rtl : cx->names().ltr));
|
||||
|
||||
if (!DefineProperty(cx, info, cx->names().direction, dir))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*info);
|
||||
return true;
|
||||
}
|
||||
|
||||
const Class js::IntlClass = {
|
||||
js_Object_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Intl)
|
||||
|
|
|
|||
|
|
@ -509,6 +509,20 @@ intl_GetPluralCategories(JSContext* cx, unsigned argc, Value* vp);
|
|||
extern MOZ_MUST_USE bool
|
||||
intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
/**
|
||||
* Returns a plain object with locale information for a single valid locale
|
||||
* (callers must perform this validation). The object will have these
|
||||
* properties:
|
||||
*
|
||||
* direction
|
||||
* a string with a value "ltr" for left-to-right locale, and "rtl" for
|
||||
* right-to-left locale.
|
||||
* locale
|
||||
* a BCP47 compilant locale string for the resolved locale.
|
||||
*/
|
||||
extern MOZ_MUST_USE bool
|
||||
intl_GetLocaleInfo(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
/**
|
||||
* Returns an Array with CLDR-based fields display names.
|
||||
* The function takes three arguments:
|
||||
|
|
|
|||
|
|
@ -3337,3 +3337,22 @@ function Intl_getDisplayNames(locales, options) {
|
|||
return result;
|
||||
}
|
||||
|
||||
function Intl_getLocaleInfo(locales) {
|
||||
const requestedLocales = CanonicalizeLocaleList(locales);
|
||||
|
||||
// In the future, we may want to expose uloc_getAvailable and use it here.
|
||||
const DateTimeFormat = dateTimeFormatInternalProperties;
|
||||
const localeData = DateTimeFormat.localeData;
|
||||
|
||||
const localeOpt = new Record();
|
||||
localeOpt.localeMatcher = "best fit";
|
||||
|
||||
const r = ResolveLocale(callFunction(DateTimeFormat.availableLocales, DateTimeFormat),
|
||||
requestedLocales,
|
||||
localeOpt,
|
||||
DateTimeFormat.relevantExtensionKeys,
|
||||
localeData);
|
||||
|
||||
return intl_GetLocaleInfo(r.locale);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -939,6 +939,7 @@ AddIntlExtras(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
static const JSFunctionSpec funcs[] = {
|
||||
JS_SELF_HOSTED_FN("getCalendarInfo", "Intl_getCalendarInfo", 1, 0),
|
||||
JS_SELF_HOSTED_FN("getLocaleInfo", "Intl_getLocaleInfo", 1, 0),
|
||||
JS_SELF_HOSTED_FN("getDisplayNames", "Intl_getDisplayNames", 2, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
|
|
|||
38
js/src/tests/Intl/getLocaleInfo.js
Normal file
38
js/src/tests/Intl/getLocaleInfo.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras"))
|
||||
/* 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/. */
|
||||
|
||||
// Tests the getCalendarInfo function with a diverse set of arguments.
|
||||
|
||||
function checkLocaleInfo(info, expected)
|
||||
{
|
||||
assertEq(Object.getPrototypeOf(info), Object.prototype);
|
||||
|
||||
assertEq(info.direction, expected.direction);
|
||||
assertEq(info.locale, expected.locale);
|
||||
}
|
||||
|
||||
addIntlExtras(Intl);
|
||||
|
||||
let gLI = Intl.getLocaleInfo;
|
||||
|
||||
assertEq(gLI.length, 1);
|
||||
|
||||
checkLocaleInfo(gLI('en-US'), {
|
||||
direction: "ltr",
|
||||
locale: "en-US"
|
||||
});
|
||||
|
||||
checkLocaleInfo(gLI('fr'), {
|
||||
direction: "ltr",
|
||||
locale: "fr"
|
||||
});
|
||||
|
||||
checkLocaleInfo(gLI('ar'), {
|
||||
direction: "rtl",
|
||||
locale: "ar"
|
||||
});
|
||||
|
||||
if (typeof reportCompare === 'function')
|
||||
reportCompare(0, 0);
|
||||
|
|
@ -91,6 +91,7 @@
|
|||
macro(defineSetter, defineSetter, "__defineSetter__") \
|
||||
macro(delete, delete_, "delete") \
|
||||
macro(deleteProperty, deleteProperty, "deleteProperty") \
|
||||
macro(direction, direction, "direction") \
|
||||
macro(displayURL, displayURL, "displayURL") \
|
||||
macro(do, do_, "do") \
|
||||
macro(done, done, "done") \
|
||||
|
|
@ -210,6 +211,7 @@
|
|||
macro(locale, locale, "locale") \
|
||||
macro(lookupGetter, lookupGetter, "__lookupGetter__") \
|
||||
macro(lookupSetter, lookupSetter, "__lookupSetter__") \
|
||||
macro(ltr, ltr, "ltr") \
|
||||
macro(MapConstructorInit, MapConstructorInit, "MapConstructorInit") \
|
||||
macro(MapIterator, MapIterator, "Map Iterator") \
|
||||
macro(maximumFractionDigits, maximumFractionDigits, "maximumFractionDigits") \
|
||||
|
|
@ -298,6 +300,7 @@
|
|||
macro(resumeGenerator, resumeGenerator, "resumeGenerator") \
|
||||
macro(return, return_, "return") \
|
||||
macro(revoke, revoke, "revoke") \
|
||||
macro(rtl, rtl, "rtl") \
|
||||
macro(script, script, "script") \
|
||||
macro(scripts, scripts, "scripts") \
|
||||
macro(second, second, "second") \
|
||||
|
|
|
|||
|
|
@ -2615,6 +2615,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
|||
JS_FN("intl_FormatDateTime", intl_FormatDateTime, 2,0),
|
||||
JS_FN("intl_FormatNumber", intl_FormatNumber, 2,0),
|
||||
JS_FN("intl_GetCalendarInfo", intl_GetCalendarInfo, 1,0),
|
||||
JS_FN("intl_GetLocaleInfo", intl_GetLocaleInfo, 1,0),
|
||||
JS_FN("intl_ComputeDisplayNames", intl_ComputeDisplayNames, 3,0),
|
||||
JS_FN("intl_IsValidTimeZoneName", intl_IsValidTimeZoneName, 1,0),
|
||||
JS_FN("intl_NumberFormat", intl_NumberFormat, 2,0),
|
||||
|
|
|
|||
15
layout/style/crashtests/1340344.html
Normal file
15
layout/style/crashtests/1340344.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload = function(){
|
||||
var anim =
|
||||
document.documentElement.animate([{ "color": "hsla(6e147grad,16%,183.379675555%,0.0210463770007)" }]);
|
||||
anim.ready.then(() => {
|
||||
document.documentElement.classList.remove("reftest-wait");
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
|
|
@ -169,3 +169,4 @@ load 1321357-1.html
|
|||
load 1328535-1.html
|
||||
load 1331272.html
|
||||
HTTP load 1333001-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1340344.html
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ EXPORTS.mozilla.css += [
|
|||
UNIFIED_SOURCES += [
|
||||
'AnimationCollection.cpp',
|
||||
'AnimationCommon.cpp',
|
||||
'BindingStyleRule.cpp',
|
||||
'CounterStyleManager.cpp',
|
||||
'CSS.cpp',
|
||||
'CSSLexer.cpp',
|
||||
|
|
@ -208,6 +209,7 @@ UNIFIED_SOURCES += [
|
|||
'ServoCSSRuleList.cpp',
|
||||
'ServoDeclarationBlock.cpp',
|
||||
'ServoElementSnapshot.cpp',
|
||||
'ServoSpecifiedValues.cpp',
|
||||
'ServoStyleRule.cpp',
|
||||
'ServoStyleSet.cpp',
|
||||
'ServoStyleSheet.cpp',
|
||||
|
|
@ -217,21 +219,13 @@ UNIFIED_SOURCES += [
|
|||
'SVGAttrAnimationRuleProcessor.cpp',
|
||||
]
|
||||
|
||||
# - BindingStyleRule.cpp doesn't _really_ needs to be built separately,
|
||||
# except insofar as it shifts unified build boundaries, causing
|
||||
# Unified_cpp_layout_style4.cpp to include nsStyleCoord.cpp, which
|
||||
# includes, via nsStyleCoord.h, <type_traits>, which ends up including
|
||||
# <xutility>, which fails in much the way described in
|
||||
# <https://bugzilla.mozilla.org/show_bug.cgi?id=1331102>.
|
||||
# - nsCSSRuleProcessor.cpp needs to be built separately because it uses
|
||||
# plarena.h.
|
||||
# - nsLayoutStylesheetCache.cpp needs to be built separately because it uses
|
||||
# nsExceptionHandler.h, which includes windows.h.
|
||||
SOURCES += [
|
||||
'BindingStyleRule.cpp',
|
||||
'nsCSSRuleProcessor.cpp',
|
||||
'nsLayoutStylesheetCache.cpp',
|
||||
'ServoSpecifiedValues.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
|
|
|||
|
|
@ -6936,7 +6936,12 @@ CSSParserImpl::ParseHue(float& aAngle)
|
|||
// The '0' value is handled by <number> parsing, so use VARIANT_ANGLE flag
|
||||
// instead of VARIANT_ANGLE_OR_ZERO.
|
||||
if (ParseSingleTokenVariant(angleValue, VARIANT_ANGLE, nullptr)) {
|
||||
// Convert double value of GetAngleValueInDegrees() to float.
|
||||
aAngle = angleValue.GetAngleValueInDegrees();
|
||||
// And then clamp it as finite values in float.
|
||||
aAngle = mozilla::clamped(aAngle,
|
||||
-std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,14 @@
|
|||
|
||||
/* representation of length values in computed style data */
|
||||
|
||||
#include "nsStyleCoord.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
// nsStyleCoord.h must not be the first header in a unified source file,
|
||||
// otherwise it may not build with MSVC due to a bug in our STL wrapper.
|
||||
// See bug 1331102.
|
||||
#include "nsStyleCoord.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
nsStyleCoord::nsStyleCoord(nsStyleUnit aUnit)
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ MP4VideoInfo::Update(const MetaData* aMetaData, const char* aMimeType)
|
|||
#ifdef MOZ_RUST_MP4PARSE
|
||||
static void
|
||||
UpdateTrackProtectedInfo(mozilla::TrackInfo& aConfig,
|
||||
const mp4parser_sinf_info& aSinf)
|
||||
const mp4parse_sinf_info& aSinf)
|
||||
{
|
||||
if (aSinf.is_encrypted != 0) {
|
||||
aConfig.mCrypto.mValid = true;
|
||||
|
|
|
|||
|
|
@ -48,20 +48,30 @@ typedef struct mp4parse_track_info {
|
|||
int64_t media_time;
|
||||
} mp4parse_track_info;
|
||||
|
||||
typedef struct mp4parse_indice {
|
||||
uint64_t start_offset;
|
||||
uint64_t end_offset;
|
||||
uint64_t start_composition;
|
||||
uint64_t end_composition;
|
||||
uint64_t start_decode;
|
||||
bool sync;
|
||||
} mp4parse_indice;
|
||||
|
||||
typedef struct mp4parse_byte_data {
|
||||
uint32_t length;
|
||||
uint8_t const* data;
|
||||
mp4parse_indice const* indices;
|
||||
} mp4parse_byte_data;
|
||||
|
||||
typedef struct mp4parse_pssh_info {
|
||||
mp4parse_byte_data data;
|
||||
} mp4parse_pssh_info;
|
||||
|
||||
typedef struct mp4parser_sinf_info {
|
||||
typedef struct mp4parse_sinf_info {
|
||||
uint32_t is_encrypted;
|
||||
uint8_t iv_size;
|
||||
mp4parse_byte_data kid;
|
||||
} mp4parser_sinf_info;
|
||||
} mp4parse_sinf_info;
|
||||
|
||||
typedef struct mp4parse_track_audio_info {
|
||||
uint16_t channels;
|
||||
|
|
@ -69,7 +79,7 @@ typedef struct mp4parse_track_audio_info {
|
|||
uint32_t sample_rate;
|
||||
uint16_t profile;
|
||||
mp4parse_byte_data codec_specific_config;
|
||||
mp4parser_sinf_info protected_data;
|
||||
mp4parse_sinf_info protected_data;
|
||||
} mp4parse_track_audio_info;
|
||||
|
||||
typedef struct mp4parse_track_video_info {
|
||||
|
|
@ -78,7 +88,7 @@ typedef struct mp4parse_track_video_info {
|
|||
uint16_t image_width;
|
||||
uint16_t image_height;
|
||||
mp4parse_byte_data extra_data;
|
||||
mp4parser_sinf_info protected_data;
|
||||
mp4parse_sinf_info protected_data;
|
||||
} mp4parse_track_video_info;
|
||||
|
||||
typedef struct mp4parse_fragment_info {
|
||||
|
|
@ -116,6 +126,8 @@ mp4parse_error mp4parse_get_track_audio_info(mp4parse_parser* parser, uint32_t t
|
|||
/// Fill the supplied `mp4parse_track_video_info` with metadata for `track`.
|
||||
mp4parse_error mp4parse_get_track_video_info(mp4parse_parser* parser, uint32_t track_index, mp4parse_track_video_info* info);
|
||||
|
||||
mp4parse_error mp4parse_get_indice_table(mp4parse_parser* parser, uint32_t track_id, mp4parse_byte_data* indices);
|
||||
|
||||
/// Fill the supplied `mp4parse_fragment_info` with metadata from fragmented file.
|
||||
mp4parse_error mp4parse_get_fragment_info(mp4parse_parser* parser, mp4parse_fragment_info* info);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,11 +27,14 @@ diff --git a/media/libstagefright/binding/mp4parse_capi/Cargo.toml b/media/libst
|
|||
index aeeebc65..5c0836a 100644
|
||||
--- a/media/libstagefright/binding/mp4parse_capi/Cargo.toml
|
||||
+++ b/media/libstagefright/binding/mp4parse_capi/Cargo.toml
|
||||
@@ -18,18 +18,12 @@ exclude = [
|
||||
@@ -18,21 +18,12 @@ exclude = [
|
||||
"*.mp4",
|
||||
]
|
||||
|
||||
-build = "build.rs"
|
||||
-
|
||||
-[badges]
|
||||
-travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" }
|
||||
+build = false
|
||||
|
||||
[dependencies]
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ authors = [
|
|||
description = "Parser for ISO base media file format (mp4)"
|
||||
documentation = "https://mp4parse-docs.surge.sh/mp4parse/"
|
||||
license = "MPL-2.0"
|
||||
categories = ["multimedia::video"]
|
||||
|
||||
repository = "https://github.com/mozilla/mp4parse-rust"
|
||||
|
||||
|
|
@ -18,6 +19,9 @@ exclude = [
|
|||
"*.mp4",
|
||||
]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" }
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.0.0"
|
||||
bitreader = { version = "0.2.0" }
|
||||
|
|
|
|||
|
|
@ -134,4 +134,6 @@ box_database!(
|
|||
TrackEncryptionBox 0x74656e63, // "tenc"
|
||||
ProtectionSchemeInformationBox 0x73696e66, // "sinf"
|
||||
OriginalFormatBox 0x66726d61, // "frma"
|
||||
MP3AudioSampleEntry 0x2e6d7033, // ".mp3" - from F4V.
|
||||
CompositionOffsetBox 0x63747473, // "ctts"
|
||||
);
|
||||
|
|
|
|||
|
|
@ -151,46 +151,64 @@ struct MediaHeaderBox {
|
|||
|
||||
// Chunk offset box 'stco' or 'co64'
|
||||
#[derive(Debug)]
|
||||
struct ChunkOffsetBox {
|
||||
offsets: Vec<u64>,
|
||||
pub struct ChunkOffsetBox {
|
||||
pub offsets: Vec<u64>,
|
||||
}
|
||||
|
||||
// Sync sample box 'stss'
|
||||
#[derive(Debug)]
|
||||
struct SyncSampleBox {
|
||||
samples: Vec<u32>,
|
||||
pub struct SyncSampleBox {
|
||||
pub samples: Vec<u32>,
|
||||
}
|
||||
|
||||
// Sample to chunk box 'stsc'
|
||||
#[derive(Debug)]
|
||||
struct SampleToChunkBox {
|
||||
samples: Vec<SampleToChunk>,
|
||||
pub struct SampleToChunkBox {
|
||||
pub samples: Vec<SampleToChunk>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SampleToChunk {
|
||||
first_chunk: u32,
|
||||
samples_per_chunk: u32,
|
||||
sample_description_index: u32,
|
||||
pub struct SampleToChunk {
|
||||
pub first_chunk: u32,
|
||||
pub samples_per_chunk: u32,
|
||||
pub sample_description_index: u32,
|
||||
}
|
||||
|
||||
// Sample size box 'stsz'
|
||||
#[derive(Debug)]
|
||||
struct SampleSizeBox {
|
||||
sample_size: u32,
|
||||
sample_sizes: Vec<u32>,
|
||||
pub struct SampleSizeBox {
|
||||
pub sample_size: u32,
|
||||
pub sample_sizes: Vec<u32>,
|
||||
}
|
||||
|
||||
// Time to sample box 'stts'
|
||||
#[derive(Debug)]
|
||||
struct TimeToSampleBox {
|
||||
samples: Vec<Sample>,
|
||||
pub struct TimeToSampleBox {
|
||||
pub samples: Vec<Sample>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct Sample {
|
||||
pub sample_count: u32,
|
||||
pub sample_delta: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum TimeOffsetVersion {
|
||||
Version0(u32),
|
||||
Version1(i32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TimeOffset {
|
||||
pub sample_count: u32,
|
||||
pub time_offset: TimeOffsetVersion,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Sample {
|
||||
sample_count: u32,
|
||||
sample_delta: u32,
|
||||
pub struct CompositionOffsetBox {
|
||||
pub samples: Vec<TimeOffset>,
|
||||
}
|
||||
|
||||
// Handler reference box 'hdlr'
|
||||
|
|
@ -228,6 +246,7 @@ pub enum AudioCodecSpecific {
|
|||
ES_Descriptor(ES_Descriptor),
|
||||
FLACSpecificBox(FLACSpecificBox),
|
||||
OpusSpecificBox(OpusSpecificBox),
|
||||
MP3,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -396,6 +415,7 @@ pub struct TrackScaledTime(pub u64, pub usize);
|
|||
/// A fragmented file contains no sample data in stts, stsc, and stco.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct EmptySampleTableBoxes {
|
||||
// TODO: Track has stts, stsc and stco, this structure can be discarded.
|
||||
pub empty_stts : bool,
|
||||
pub empty_stsc : bool,
|
||||
pub empty_stco : bool,
|
||||
|
|
@ -421,6 +441,12 @@ pub struct Track {
|
|||
pub empty_sample_boxes: EmptySampleTableBoxes,
|
||||
pub data: Option<SampleEntry>,
|
||||
pub tkhd: Option<TrackHeaderBox>, // TODO(kinetik): find a nicer way to export this.
|
||||
pub stts: Option<TimeToSampleBox>,
|
||||
pub stsc: Option<SampleToChunkBox>,
|
||||
pub stsz: Option<SampleSizeBox>,
|
||||
pub stco: Option<ChunkOffsetBox>, // It is for stco or co64.
|
||||
pub stss: Option<SyncSampleBox>,
|
||||
pub ctts: Option<CompositionOffsetBox>,
|
||||
}
|
||||
|
||||
impl Track {
|
||||
|
|
@ -840,30 +866,41 @@ fn read_stbl<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
|
|||
}
|
||||
BoxType::TimeToSampleBox => {
|
||||
let stts = read_stts(&mut b)?;
|
||||
track.empty_sample_boxes.empty_stts = stts.samples.is_empty();
|
||||
log!("{:?}", stts);
|
||||
track.empty_sample_boxes.empty_stts = stts.samples.is_empty();
|
||||
track.stts = Some(stts);
|
||||
}
|
||||
BoxType::SampleToChunkBox => {
|
||||
let stsc = read_stsc(&mut b)?;
|
||||
track.empty_sample_boxes.empty_stsc = stsc.samples.is_empty();
|
||||
log!("{:?}", stsc);
|
||||
track.empty_sample_boxes.empty_stsc = stsc.samples.is_empty();
|
||||
track.stsc = Some(stsc);
|
||||
}
|
||||
BoxType::SampleSizeBox => {
|
||||
let stsz = read_stsz(&mut b)?;
|
||||
log!("{:?}", stsz);
|
||||
track.stsz = Some(stsz);
|
||||
}
|
||||
BoxType::ChunkOffsetBox => {
|
||||
let stco = read_stco(&mut b)?;
|
||||
track.empty_sample_boxes.empty_stco = stco.offsets.is_empty();
|
||||
log!("{:?}", stco);
|
||||
track.stco = Some(stco);
|
||||
}
|
||||
BoxType::ChunkLargeOffsetBox => {
|
||||
let co64 = read_co64(&mut b)?;
|
||||
log!("{:?}", co64);
|
||||
track.stco = Some(co64);
|
||||
}
|
||||
BoxType::SyncSampleBox => {
|
||||
let stss = read_stss(&mut b)?;
|
||||
log!("{:?}", stss);
|
||||
track.stss = Some(stss);
|
||||
}
|
||||
BoxType::CompositionOffsetBox => {
|
||||
let ctts = read_ctts(&mut b)?;
|
||||
log!("{:?}", ctts);
|
||||
track.ctts = Some(ctts);
|
||||
}
|
||||
_ => skip_box_content(&mut b)?,
|
||||
};
|
||||
|
|
@ -1115,6 +1152,45 @@ fn read_stsc<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleToChunkBox> {
|
|||
})
|
||||
}
|
||||
|
||||
fn read_ctts<T: Read>(src: &mut BMFFBox<T>) -> Result<CompositionOffsetBox> {
|
||||
let (version, _) = read_fullbox_extra(src)?;
|
||||
|
||||
let counts = be_u32(src)?;
|
||||
|
||||
if src.bytes_left() < (counts as usize * 8) {
|
||||
return Err(Error::InvalidData("insufficient data in 'ctts' box"));
|
||||
}
|
||||
|
||||
let mut offsets = Vec::new();
|
||||
for _ in 0..counts {
|
||||
let (sample_count, time_offset) = match version {
|
||||
0 => {
|
||||
let count = be_u32(src)?;
|
||||
let offset = TimeOffsetVersion::Version0(be_u32(src)?);
|
||||
(count, offset)
|
||||
},
|
||||
1 => {
|
||||
let count = be_u32(src)?;
|
||||
let offset = TimeOffsetVersion::Version1(be_i32(src)?);
|
||||
(count, offset)
|
||||
},
|
||||
_ => {
|
||||
return Err(Error::InvalidData("unsupported version in 'ctts' box"));
|
||||
}
|
||||
};
|
||||
offsets.push(TimeOffset {
|
||||
sample_count: sample_count,
|
||||
time_offset: time_offset,
|
||||
});
|
||||
}
|
||||
|
||||
skip_box_remain(src)?;
|
||||
|
||||
Ok(CompositionOffsetBox {
|
||||
samples: offsets,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a stsz box.
|
||||
fn read_stsz<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleSizeBox> {
|
||||
let (_, _) = read_fullbox_extra(src)?;
|
||||
|
|
@ -1433,7 +1509,6 @@ fn read_dfla<T: Read>(src: &mut BMFFBox<T>) -> Result<FLACSpecificBox> {
|
|||
if blocks.is_empty() {
|
||||
return Err(Error::InvalidData("FLACSpecificBox missing metadata"));
|
||||
} else if blocks[0].block_type != 0 {
|
||||
println!("flac metadata block:\n {:?}", blocks[0]);
|
||||
return Err(Error::InvalidData(
|
||||
"FLACSpecificBox must have STREAMINFO metadata first"));
|
||||
} else if blocks[0].data.len() != 34 {
|
||||
|
|
@ -1602,7 +1677,8 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>, track: &mut Track) ->
|
|||
}
|
||||
BoxType::VPCodecConfigurationBox => { // vpcC
|
||||
if (name != BoxType::VP8SampleEntry &&
|
||||
name != BoxType::VP9SampleEntry) ||
|
||||
name != BoxType::VP9SampleEntry &&
|
||||
name != BoxType::ProtectedVisualSampleEntry) ||
|
||||
codec_specific.is_some() {
|
||||
return Err(Error::InvalidData("malformed video sample entry"));
|
||||
}
|
||||
|
|
@ -1687,6 +1763,9 @@ fn read_audio_sample_entry<T: Read>(src: &mut BMFFBox<T>, track: &mut Track) ->
|
|||
|
||||
// Skip chan/etc. for now.
|
||||
let mut codec_specific = None;
|
||||
if name == BoxType::MP3AudioSampleEntry {
|
||||
codec_specific = Some(AudioCodecSpecific::MP3);
|
||||
}
|
||||
let mut protection_info = Vec::new();
|
||||
let mut iter = src.box_iter();
|
||||
while let Some(mut b) = iter.next_box()? {
|
||||
|
|
@ -1889,16 +1968,18 @@ fn read_buf<T: ReadBytesExt>(src: &mut T, size: usize) -> Result<Vec<u8>> {
|
|||
// - zero or more byte strings, with a single null terminating the string.
|
||||
// - zero byte strings with no null terminator (i.e. zero space in the box for the string)
|
||||
// - length-prefixed strings with no null terminator (e.g. bear_rotate_0.mp4)
|
||||
// - multiple byte strings where more than one byte is a null.
|
||||
fn read_null_terminated_string<T: ReadBytesExt>(src: &mut T, mut size: usize) -> Result<String> {
|
||||
let mut buf = Vec::new();
|
||||
while size > 0 {
|
||||
let c = src.read_u8()?;
|
||||
size -= 1;
|
||||
if c == 0 {
|
||||
break;
|
||||
}
|
||||
buf.push(c);
|
||||
size -= 1;
|
||||
}
|
||||
skip(src, size)?;
|
||||
String::from_utf8(buf).map_err(From::from)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -884,3 +884,19 @@ fn read_esds() {
|
|||
assert_eq!(es.audio_channel_count, Some(6));
|
||||
assert_eq!(es.codec_esds, aac_esds);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_null_terminated_string() {
|
||||
let tests = vec![
|
||||
vec![0u8], // Short null-terminated string.
|
||||
vec![65u8, 0u8], // Normal null-terminated string.
|
||||
vec![], // Empty string (no data).
|
||||
vec![4u8, 65u8, 66u8, 67u8, 68u8], // Length-prefixed string, not null-terminated.
|
||||
vec![0u8, 0u8], // Doubly null-terminated string.
|
||||
];
|
||||
for v in tests.iter() {
|
||||
let mut c = Cursor::new(v);
|
||||
super::read_null_terminated_string(&mut c, v.len()).expect("string read failed");
|
||||
assert_eq!(c.position(), v.len() as u64);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@ fn public_api() {
|
|||
assert!(opus.version > 0);
|
||||
"Opus"
|
||||
}
|
||||
mp4::AudioCodecSpecific::MP3 => {
|
||||
"MP3"
|
||||
}
|
||||
}, "ES");
|
||||
assert!(a.samplesize > 0);
|
||||
assert!(a.samplerate > 0);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ use mp4parse::TrackTimeScale;
|
|||
use mp4parse::TrackScaledTime;
|
||||
use mp4parse::serialize_opus_header;
|
||||
use mp4parse::CodecType;
|
||||
use mp4parse::Track;
|
||||
|
||||
// rusty-cheddar's C enum generation doesn't namespace enum members by
|
||||
// prefixing them, so we're forced to do it in our member names until
|
||||
|
|
@ -113,17 +114,31 @@ pub struct mp4parse_track_info {
|
|||
// TODO(kinetik): include crypto guff
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Default, Debug, PartialEq)]
|
||||
pub struct mp4parse_indice {
|
||||
pub start_offset: u64,
|
||||
pub end_offset: u64,
|
||||
pub start_composition: u64,
|
||||
pub end_composition: u64,
|
||||
pub start_decode: u64,
|
||||
pub sync: bool,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct mp4parse_byte_data {
|
||||
pub length: u32,
|
||||
// cheddar can't handle generic type, so it needs to be multiple data types here.
|
||||
pub data: *const u8,
|
||||
pub indices: *const mp4parse_indice,
|
||||
}
|
||||
|
||||
impl Default for mp4parse_byte_data {
|
||||
fn default() -> Self {
|
||||
mp4parse_byte_data {
|
||||
length: 0,
|
||||
data: std::ptr::null_mut(),
|
||||
data: std::ptr::null(),
|
||||
indices: std::ptr::null(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -133,6 +148,10 @@ impl mp4parse_byte_data {
|
|||
self.length = data.len() as u32;
|
||||
self.data = data.as_ptr();
|
||||
}
|
||||
fn set_indices(&mut self, data: &Vec<mp4parse_indice>) {
|
||||
self.length = data.len() as u32;
|
||||
self.indices = data.as_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -143,7 +162,7 @@ pub struct mp4parse_pssh_info {
|
|||
|
||||
#[repr(C)]
|
||||
#[derive(Default)]
|
||||
pub struct mp4parser_sinf_info {
|
||||
pub struct mp4parse_sinf_info {
|
||||
pub is_encrypted: u32,
|
||||
pub iv_size: u8,
|
||||
pub kid: mp4parse_byte_data,
|
||||
|
|
@ -157,7 +176,7 @@ pub struct mp4parse_track_audio_info {
|
|||
pub sample_rate: u32,
|
||||
pub profile: u16,
|
||||
pub codec_specific_config: mp4parse_byte_data,
|
||||
pub protected_data: mp4parser_sinf_info,
|
||||
pub protected_data: mp4parse_sinf_info,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -168,7 +187,7 @@ pub struct mp4parse_track_video_info {
|
|||
pub image_width: u16,
|
||||
pub image_height: u16,
|
||||
pub extra_data: mp4parse_byte_data,
|
||||
pub protected_data: mp4parser_sinf_info,
|
||||
pub protected_data: mp4parse_sinf_info,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -187,6 +206,7 @@ struct Wrap {
|
|||
poisoned: bool,
|
||||
opus_header: HashMap<u32, Vec<u8>>,
|
||||
pssh_data: Vec<u8>,
|
||||
sample_table: HashMap<u32, Vec<mp4parse_indice>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -221,6 +241,10 @@ impl mp4parse_parser {
|
|||
fn pssh_data_mut(&mut self) -> &mut Vec<u8> {
|
||||
&mut self.0.pssh_data
|
||||
}
|
||||
|
||||
fn sample_table_mut(&mut self) -> &mut HashMap<u32, Vec<mp4parse_indice>> {
|
||||
&mut self.0.sample_table
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -266,6 +290,7 @@ pub unsafe extern fn mp4parse_new(io: *const mp4parse_io) -> *mut mp4parse_parse
|
|||
poisoned: false,
|
||||
opus_header: HashMap::new(),
|
||||
pssh_data: Vec::new(),
|
||||
sample_table: HashMap::new(),
|
||||
}));
|
||||
|
||||
Box::into_raw(parser)
|
||||
|
|
@ -401,6 +426,8 @@ pub unsafe extern fn mp4parse_get_track_info(parser: *mut mp4parse_parser, track
|
|||
mp4parse_codec::MP4PARSE_CODEC_MP3,
|
||||
AudioCodecSpecific::ES_Descriptor(_) =>
|
||||
mp4parse_codec::MP4PARSE_CODEC_UNKNOWN,
|
||||
AudioCodecSpecific::MP3 =>
|
||||
mp4parse_codec::MP4PARSE_CODEC_MP3,
|
||||
},
|
||||
Some(SampleEntry::Video(ref video)) => match video.codec_specific {
|
||||
VideoCodecSpecific::VPxConfig(_) =>
|
||||
|
|
@ -536,6 +563,7 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut mp4parse_parser,
|
|||
}
|
||||
}
|
||||
}
|
||||
AudioCodecSpecific::MP3 => (),
|
||||
}
|
||||
|
||||
match audio.protection_info.iter().find(|sinf| sinf.tenc.is_some()) {
|
||||
|
|
@ -615,6 +643,367 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut mp4parse_parser,
|
|||
MP4PARSE_OK
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn mp4parse_get_indice_table(parser: *mut mp4parse_parser, track_id: u32, indices: *mut mp4parse_byte_data) -> mp4parse_error {
|
||||
if parser.is_null() || (*parser).poisoned() {
|
||||
return MP4PARSE_ERROR_BADARG;
|
||||
}
|
||||
|
||||
// Initialize fields to default values to ensure all fields are always valid.
|
||||
*indices = Default::default();
|
||||
|
||||
let context = (*parser).context();
|
||||
let tracks = &context.tracks;
|
||||
let track = match tracks.iter().find(|track| track.track_id == Some(track_id)) {
|
||||
Some(t) => t,
|
||||
_ => return MP4PARSE_ERROR_INVALID,
|
||||
};
|
||||
|
||||
let index_table = (*parser).sample_table_mut();
|
||||
match index_table.get(&track_id) {
|
||||
Some(v) => {
|
||||
(*indices).set_indices(v);
|
||||
return MP4PARSE_OK;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
// Find the track start offset time from 'elst'.
|
||||
// 'media_time' maps start time onward, 'empty_duration' adds time offset
|
||||
// before first frame is displayed.
|
||||
let offset_time =
|
||||
match (&track.empty_duration, &track.media_time, &context.timescale) {
|
||||
(&Some(empty_duration), &Some(media_time), &Some(scale)) => {
|
||||
(empty_duration.0 - media_time.0) as i64 * scale.0 as i64
|
||||
},
|
||||
(&Some(empty_duration), _, &Some(scale)) => {
|
||||
empty_duration.0 as i64 * scale.0 as i64
|
||||
},
|
||||
(_, &Some(media_time), &Some(scale)) => {
|
||||
(0 - media_time.0) as i64 * scale.0 as i64
|
||||
},
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
match create_sample_table(track, offset_time) {
|
||||
Some(v) => {
|
||||
(*indices).set_indices(&v);
|
||||
index_table.insert(track_id, v);
|
||||
return MP4PARSE_OK;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
MP4PARSE_ERROR_INVALID
|
||||
}
|
||||
|
||||
// Convert a 'ctts' compact table to full table by iterator,
|
||||
// (sample_with_the_same_offset_count, offset) => (offset), (offset), (offset) ...
|
||||
//
|
||||
// For example:
|
||||
// (2, 10), (4, 9) into (10, 10, 9, 9, 9, 9) by calling next_offset_time().
|
||||
struct TimeOffsetIterator<'a> {
|
||||
cur_sample_range: std::ops::Range<u32>,
|
||||
cur_offset: i64,
|
||||
ctts_iter: Option<std::slice::Iter<'a, mp4parse::TimeOffset>>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for TimeOffsetIterator<'a> {
|
||||
type Item = i64;
|
||||
|
||||
fn next(&mut self) -> Option<i64> {
|
||||
let has_sample = self.cur_sample_range.next()
|
||||
.or_else(|| {
|
||||
// At end of current TimeOffset, find the next TimeOffset.
|
||||
let iter = match self.ctts_iter {
|
||||
Some(ref mut v) => v,
|
||||
_ => return None,
|
||||
};
|
||||
let offset_version;
|
||||
self.cur_sample_range = match iter.next() {
|
||||
Some(v) => {
|
||||
offset_version = v.time_offset;
|
||||
(0 .. v.sample_count)
|
||||
},
|
||||
_ => {
|
||||
offset_version = mp4parse::TimeOffsetVersion::Version0(0);
|
||||
(0 .. 0)
|
||||
},
|
||||
};
|
||||
|
||||
self.cur_offset = match offset_version {
|
||||
mp4parse::TimeOffsetVersion::Version0(i) => i as i64,
|
||||
mp4parse::TimeOffsetVersion::Version1(i) => i as i64,
|
||||
};
|
||||
|
||||
self.cur_sample_range.next()
|
||||
});
|
||||
|
||||
has_sample.and(Some(self.cur_offset))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TimeOffsetIterator<'a> {
|
||||
fn next_offset_time(&mut self) -> i64 {
|
||||
match self.next() {
|
||||
Some(v) => v as i64,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert 'stts' compact table to full table by iterator,
|
||||
// (sample_count_with_the_same_time, time) => (time, time, time) ... repeats
|
||||
// sample_count_with_the_same_time.
|
||||
//
|
||||
// For example:
|
||||
// (2, 3000), (1, 2999) to (3000, 3000, 2999).
|
||||
struct TimeToSampleIteraor<'a> {
|
||||
cur_sample_count: std::ops::Range<u32>,
|
||||
cur_sample_delta: u32,
|
||||
stts_iter: std::slice::Iter<'a, mp4parse::Sample>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for TimeToSampleIteraor<'a> {
|
||||
type Item = u32;
|
||||
|
||||
fn next(&mut self) -> Option<u32> {
|
||||
let has_sample = self.cur_sample_count.next()
|
||||
.or_else(|| {
|
||||
self.cur_sample_count = match self.stts_iter.next() {
|
||||
Some(v) => {
|
||||
self.cur_sample_delta = v.sample_delta;
|
||||
(0 .. v.sample_count)
|
||||
},
|
||||
_ => (0 .. 0),
|
||||
};
|
||||
|
||||
self.cur_sample_count.next()
|
||||
});
|
||||
|
||||
has_sample.and(Some(self.cur_sample_delta))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TimeToSampleIteraor<'a> {
|
||||
fn next_delta(&mut self) -> u32 {
|
||||
match self.next() {
|
||||
Some(v) => v,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert 'stco' compact table to full table by iterator.
|
||||
// (start_chunk_num, sample_number) => (start_chunk_num, sample_number),
|
||||
// (start_chunk_num + 1, sample_number),
|
||||
// (start_chunk_num + 2, sample_number),
|
||||
// ...
|
||||
// (next start_chunk_num, next sample_number),
|
||||
// ...
|
||||
//
|
||||
// For example:
|
||||
// (1, 5), (5, 10), (9, 2) => (1, 5), (2, 5), (3, 5), (4, 5), (5, 10), (6, 10),
|
||||
// (7, 10), (8, 10), (9, 2)
|
||||
struct SampleToChunkIterator<'a> {
|
||||
chunks: std::ops::Range<u32>,
|
||||
sample_count: u32,
|
||||
stsc_peek_iter: std::iter::Peekable<std::slice::Iter<'a, mp4parse::SampleToChunk>>,
|
||||
remain_chunk_count: u32, // total chunk number from 'stco'.
|
||||
}
|
||||
|
||||
impl<'a> Iterator for SampleToChunkIterator<'a> {
|
||||
type Item = (u32, u32);
|
||||
|
||||
fn next(&mut self) -> Option<(u32, u32)> {
|
||||
let has_chunk = self.chunks.next()
|
||||
.or_else(|| {
|
||||
self.chunks = match (self.stsc_peek_iter.next(), self.stsc_peek_iter.peek()) {
|
||||
(Some(next), Some(peek)) => {
|
||||
self.sample_count = next.samples_per_chunk;
|
||||
((next.first_chunk - 1) .. (peek.first_chunk - 1))
|
||||
},
|
||||
(Some(next), None) => {
|
||||
self.sample_count = next.samples_per_chunk;
|
||||
// Total chunk number in 'stsc' could be different to 'stco',
|
||||
// there could be more chunks at the last 'stsc' record.
|
||||
((next.first_chunk - 1) .. next.first_chunk + self.remain_chunk_count -1)
|
||||
},
|
||||
_ => (0 .. 0),
|
||||
};
|
||||
self.remain_chunk_count -= self.chunks.len() as u32;
|
||||
self.chunks.next()
|
||||
});
|
||||
|
||||
has_chunk.map_or(None, |id| { Some((id, self.sample_count)) })
|
||||
}
|
||||
}
|
||||
|
||||
// A helper struct to convert track time to us.
|
||||
struct PresentationTime {
|
||||
time: i64,
|
||||
scale: TrackTimeScale
|
||||
}
|
||||
|
||||
impl PresentationTime {
|
||||
fn new(time: i64, scale: TrackTimeScale) -> PresentationTime {
|
||||
PresentationTime {
|
||||
time: time,
|
||||
scale: scale,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_us(&self) -> i64 {
|
||||
let track_time = TrackScaledTime(self.time as u64, self.scale.1);
|
||||
match track_time_to_us(track_time, self.scale) {
|
||||
Some(v) => v as i64,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_sample_table(track: &Track, track_offset_time: i64) -> Option<Vec<mp4parse_indice>> {
|
||||
let timescale = match track.timescale {
|
||||
Some(t) => t,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let (stsc, stco, stsz, stts) =
|
||||
match (&track.stsc, &track.stco, &track.stsz, &track.stts) {
|
||||
(&Some(ref a), &Some(ref b), &Some(ref c), &Some(ref d)) => (a, b, c, d),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
// According to spec, no sync table means every sample is sync sample.
|
||||
let has_sync_table = match track.stss {
|
||||
Some(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let mut sample_table = Vec::new();
|
||||
let mut sample_size_iter = stsz.sample_sizes.iter();
|
||||
|
||||
// Get 'stsc' iterator for (chunk_id, chunk_sample_count) and calculate the sample
|
||||
// offset address.
|
||||
let stsc_iter = SampleToChunkIterator {
|
||||
chunks: (0 .. 0),
|
||||
sample_count: 0,
|
||||
stsc_peek_iter: stsc.samples.as_slice().iter().peekable(),
|
||||
remain_chunk_count: stco.offsets.len() as u32,
|
||||
};
|
||||
|
||||
for i in stsc_iter {
|
||||
let chunk_id = i.0 as usize;
|
||||
let sample_counts = i.1;
|
||||
let mut cur_position: u64 = stco.offsets[chunk_id];
|
||||
for _ in 0 .. sample_counts {
|
||||
let start_offset = cur_position;
|
||||
let end_offset = match (stsz.sample_size, sample_size_iter.next()) {
|
||||
(_, Some(t)) => start_offset + *t as u64,
|
||||
(t, _) if t > 0 => start_offset + t as u64,
|
||||
_ => 0,
|
||||
};
|
||||
if end_offset == 0 {
|
||||
return None;
|
||||
}
|
||||
cur_position = end_offset;
|
||||
|
||||
sample_table.push(
|
||||
mp4parse_indice {
|
||||
start_offset: start_offset,
|
||||
end_offset: end_offset,
|
||||
start_composition: 0,
|
||||
end_composition: 0,
|
||||
start_decode: 0,
|
||||
sync: !has_sync_table,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the sync sample in sample_table according to 'stss'.
|
||||
match &track.stss {
|
||||
&Some(ref v) => {
|
||||
for iter in &v.samples {
|
||||
sample_table[(iter - 1) as usize].sync = true;
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let ctts_iter = match &track.ctts {
|
||||
&Some(ref v) => Some(v.samples.as_slice().iter()),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let mut ctts_offset_iter = TimeOffsetIterator {
|
||||
cur_sample_range: (0 .. 0),
|
||||
cur_offset: 0,
|
||||
ctts_iter: ctts_iter,
|
||||
};
|
||||
|
||||
let mut stts_iter = TimeToSampleIteraor {
|
||||
cur_sample_count: (0 .. 0),
|
||||
cur_sample_delta: 0,
|
||||
stts_iter: stts.samples.as_slice().iter(),
|
||||
};
|
||||
|
||||
// sum_delta is the sum of stts_iter delta.
|
||||
// According to sepc:
|
||||
// decode time => DT(n) = DT(n-1) + STTS(n)
|
||||
// composition time => CT(n) = DT(n) + CTTS(n)
|
||||
// Note:
|
||||
// composition time needs to add the track offset time from 'elst' table.
|
||||
let mut sum_delta = PresentationTime::new(0, timescale);
|
||||
for sample in sample_table.as_mut_slice() {
|
||||
let decode_time = sum_delta.to_us();
|
||||
sum_delta.time += stts_iter.next_delta() as i64;
|
||||
|
||||
// ctts_offset is the current sample offset time.
|
||||
let ctts_offset = PresentationTime::new(ctts_offset_iter.next_offset_time(), timescale);
|
||||
|
||||
let start_composition = (decode_time + ctts_offset.to_us() + track_offset_time) as u64;
|
||||
let end_composition = (sum_delta.to_us() + ctts_offset.to_us() + track_offset_time) as u64;
|
||||
|
||||
sample.start_decode = decode_time as u64;
|
||||
sample.start_composition = start_composition;
|
||||
sample.end_composition = end_composition;
|
||||
}
|
||||
|
||||
// Correct composition end time due to 'ctts' causes composition time re-ordering.
|
||||
//
|
||||
// Composition end time is not in specification. However, gecko needs it, so we need to
|
||||
// calculate to correct the composition end time.
|
||||
if track.ctts.is_some() {
|
||||
// Create an index table refers to sample_table and sorted by start_composisiton time.
|
||||
let mut sort_table = Vec::new();
|
||||
sort_table.reserve(sample_table.len());
|
||||
for i in 0 .. sample_table.len() {
|
||||
sort_table.push(i);
|
||||
}
|
||||
|
||||
sort_table.sort_by_key(|i| {
|
||||
match sample_table.get(*i) {
|
||||
Some(v) => {
|
||||
v.start_composition
|
||||
},
|
||||
_ => 0,
|
||||
}
|
||||
});
|
||||
|
||||
let iter = sort_table.iter();
|
||||
for i in 0 .. (iter.len() - 1) {
|
||||
let current_index = sort_table[i] as usize;
|
||||
let peek_index = sort_table[i + 1] as usize;
|
||||
let next_start_composition_time = sample_table[peek_index].start_composition;
|
||||
let ref mut sample = sample_table[current_index];
|
||||
sample.end_composition = next_start_composition_time;
|
||||
}
|
||||
}
|
||||
|
||||
Some(sample_table)
|
||||
}
|
||||
|
||||
/// Fill the supplied `mp4parse_fragment_info` with metadata from fragmented file.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn mp4parse_get_fragment_info(parser: *mut mp4parse_parser, info: *mut mp4parse_fragment_info) -> mp4parse_error {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# Script to update mp4parse-rust sources to latest upstream
|
||||
|
||||
# Default version.
|
||||
VER=v0.6.0
|
||||
VER=6dfc85b277f8a072083b71f23cc05981b22a10bc
|
||||
|
||||
# Accept version or commit from the command line.
|
||||
if test -n "$1"; then
|
||||
|
|
|
|||
|
|
@ -823,26 +823,24 @@ WebrtcVideoConduit::GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
|
|||
unsigned int* packetsSent,
|
||||
uint64_t* bytesSent)
|
||||
{
|
||||
{
|
||||
CSFLogVerbose(logTag, "%s for VideoConduit:%p", __FUNCTION__, this);
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
if (!mSendStream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const webrtc::VideoSendStream::Stats& stats = mSendStream->GetStats();
|
||||
*packetsSent = 0;
|
||||
for (auto entry: stats.substreams){
|
||||
*packetsSent += entry.second.rtp_stats.transmitted.packets;
|
||||
// NG -- per https://www.w3.org/TR/webrtc-stats/ this is only payload bytes
|
||||
*bytesSent += entry.second.rtp_stats.MediaPayloadBytes();
|
||||
}
|
||||
// Note: timestamp is not correct per the spec... should be time the rtcp
|
||||
// was received (remote) or sent (local)
|
||||
*timestamp = webrtc::Clock::GetRealTimeClock()->TimeInMilliseconds();
|
||||
return true;
|
||||
CSFLogVerbose(logTag, "%s for VideoConduit:%p", __FUNCTION__, this);
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
if (!mSendStream) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
const webrtc::VideoSendStream::Stats& stats = mSendStream->GetStats();
|
||||
*packetsSent = 0;
|
||||
for (auto entry: stats.substreams){
|
||||
*packetsSent += entry.second.rtp_stats.transmitted.packets;
|
||||
// NG -- per https://www.w3.org/TR/webrtc-stats/ this is only payload bytes
|
||||
*bytesSent += entry.second.rtp_stats.MediaPayloadBytes();
|
||||
}
|
||||
|
||||
// Note: timestamp is not correct per the spec... should be time the rtcp
|
||||
// was received (remote) or sent (local)
|
||||
*timestamp = webrtc::Clock::GetRealTimeClock()->TimeInMilliseconds();
|
||||
return true;
|
||||
}
|
||||
|
||||
MediaConduitErrorCode
|
||||
|
|
|
|||
|
|
@ -628,8 +628,10 @@ pref("media.mediasource.enabled", true);
|
|||
|
||||
pref("media.mediadrm-widevinecdm.visible", true);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// Enable EME (Encrypted Media Extensions)
|
||||
pref("media.eme.enabled", true);
|
||||
#endif
|
||||
|
||||
// optimize images memory usage
|
||||
pref("image.downscale-during-decode.enabled", true);
|
||||
|
|
|
|||
|
|
@ -1218,7 +1218,7 @@ var BrowserApp = {
|
|||
|
||||
if (fullscreenState) {
|
||||
this.fullscreenTransitionTab = newTab;
|
||||
doc.exitFullscreen();
|
||||
this.selectedBrowser.contentDocument.exitFullscreen();
|
||||
}
|
||||
|
||||
if (typeof aParams.tabIndex == "number") {
|
||||
|
|
|
|||
|
|
@ -3248,6 +3248,12 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
|||
// share the request context - see bug 1236650
|
||||
httpChannel->SetRequestContextID(mRequestContextID);
|
||||
|
||||
// Preserve the loading order
|
||||
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(newChannel);
|
||||
if (p) {
|
||||
p->SetPriority(mPriority);
|
||||
}
|
||||
|
||||
if (httpInternal) {
|
||||
// Convey third party cookie, conservative, and spdy flags.
|
||||
httpInternal->SetThirdPartyFlags(mThirdPartyFlags);
|
||||
|
|
|
|||
91
netwerk/test/unit/test_channel_priority.js
Normal file
91
netwerk/test/unit/test_channel_priority.js
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */
|
||||
/* globals Cu, Ci, Assert, run_next_test, add_test, do_register_cleanup */
|
||||
/* globals runningInParent, do_send_remote_message */
|
||||
/* globals ChannelListener */
|
||||
|
||||
'use strict';
|
||||
|
||||
/* globals NetUtil*/
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
/* globals HttpServer */
|
||||
Cu.import('resource://testing-common/httpd.js');
|
||||
|
||||
let httpserver;
|
||||
let port;
|
||||
|
||||
function startHttpServer() {
|
||||
httpserver = new HttpServer();
|
||||
|
||||
httpserver.registerPathHandler('/resource', (metadata, response) => {
|
||||
response.setStatusLine(metadata.httpVersion, 200, 'OK');
|
||||
response.setHeader('Content-Type', 'text/plain', false);
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
response.bodyOutputStream.write("data", 4);
|
||||
});
|
||||
|
||||
httpserver.registerPathHandler('/redirect', (metadata, response) => {
|
||||
response.setStatusLine(metadata.httpVersion, 302, 'Redirect');
|
||||
response.setHeader('Location', '/resource', false);
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
});
|
||||
|
||||
httpserver.start(-1);
|
||||
port = httpserver.identity.primaryPort;
|
||||
}
|
||||
|
||||
function stopHttpServer() {
|
||||
httpserver.stop(()=>{});
|
||||
}
|
||||
|
||||
function makeRequest(uri) {
|
||||
let requestChannel = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true});
|
||||
requestChannel.QueryInterface(Ci.nsISupportsPriority);
|
||||
requestChannel.priority = Ci.nsISupportsPriority.PRIORITY_HIGHEST;
|
||||
requestChannel.asyncOpen2(new ChannelListener(checkResponse, requestChannel));
|
||||
}
|
||||
|
||||
function checkResponse(request, buffer, requestChannel) {
|
||||
requestChannel.QueryInterface(Ci.nsISupportsPriority);
|
||||
Assert.equal(requestChannel.priority, Ci.nsISupportsPriority.PRIORITY_HIGHEST);
|
||||
|
||||
// the response channel can be different (if it was redirected)
|
||||
let responseChannel = request.QueryInterface(Ci.nsISupportsPriority);
|
||||
Assert.equal(responseChannel.priority, Ci.nsISupportsPriority.PRIORITY_HIGHEST);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_regular_request() {
|
||||
makeRequest(`http://localhost:${port}/resource`);
|
||||
});
|
||||
|
||||
add_test(function test_redirect() {
|
||||
makeRequest(`http://localhost:${port}/redirect`);
|
||||
});
|
||||
|
||||
function run_test() { // jshint ignore:line
|
||||
if (!runningInParent) {
|
||||
// add a task to report test finished to parent process at the end of test queue,
|
||||
// since do_register_cleanup is not available in child xpcshell test script.
|
||||
add_test(function () {
|
||||
do_send_remote_message('finished');
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
// waiting for parent process to assign server port via configPort()
|
||||
return;
|
||||
}
|
||||
|
||||
startHttpServer();
|
||||
do_register_cleanup(stopHttpServer);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
// This is used by unit_ipc/test_channel_priority_wrap.js for e10s XPCShell test
|
||||
function configPort(serverPort) { // jshint ignore:line
|
||||
port = serverPort;
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -381,3 +381,4 @@ skip-if = os == "android"
|
|||
[test_rusturl.js]
|
||||
[test_trackingProtection_annotateChannels.js]
|
||||
[test_race_cache_network.js]
|
||||
[test_channel_priority.js]
|
||||
|
|
|
|||
50
netwerk/test/unit_ipc/test_channel_priority_wrap.js
Normal file
50
netwerk/test/unit_ipc/test_channel_priority_wrap.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */
|
||||
/* globals Cu, do_register_cleanup, do_test_finished */
|
||||
/* globals run_test_in_child, sendCommand, do_await_remote_message */
|
||||
|
||||
'use strict';
|
||||
|
||||
/* globals HttpServer */
|
||||
Cu.import('resource://testing-common/httpd.js');
|
||||
|
||||
let httpserver;
|
||||
let port;
|
||||
|
||||
function startHttpServer() {
|
||||
httpserver = new HttpServer();
|
||||
|
||||
httpserver.registerPathHandler('/resource', (metadata, response) => {
|
||||
response.setStatusLine(metadata.httpVersion, 200, 'OK');
|
||||
response.setHeader('Content-Type', 'text/plain', false);
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
response.bodyOutputStream.write("data", 4);
|
||||
});
|
||||
|
||||
httpserver.registerPathHandler('/redirect', (metadata, response) => {
|
||||
response.setStatusLine(metadata.httpVersion, 302, 'Redirect');
|
||||
response.setHeader('Location', '/resource', false);
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
});
|
||||
|
||||
httpserver.start(-1);
|
||||
port = httpserver.identity.primaryPort;
|
||||
}
|
||||
|
||||
function stopHttpServer() {
|
||||
httpserver.stop(()=>{});
|
||||
}
|
||||
|
||||
function run_test() { // jshint ignore:line
|
||||
do_register_cleanup(stopHttpServer);
|
||||
|
||||
run_test_in_child('../unit/test_channel_priority.js', () => {
|
||||
startHttpServer();
|
||||
sendCommand(`configPort(${port});`);
|
||||
do_await_remote_message('finished').then(() => {
|
||||
do_test_finished();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -55,6 +55,7 @@ support-files =
|
|||
!/netwerk/test/unit/data/signed_win.exe
|
||||
!/netwerk/test/unit/test_alt-data_simple.js
|
||||
!/netwerk/test/unit/test_alt-data_stream.js
|
||||
!/netwerk/test/unit/test_channel_priority.js
|
||||
|
||||
[test_bug528292_wrap.js]
|
||||
[test_bug248970_cookie_wrap.js]
|
||||
|
|
@ -99,3 +100,4 @@ skip-if = true
|
|||
[test_channel_id.js]
|
||||
[test_trackingProtection_annotateChannels_wrap1.js]
|
||||
[test_trackingProtection_annotateChannels_wrap2.js]
|
||||
[test_channel_priority_wrap.js]
|
||||
|
|
|
|||
|
|
@ -777,16 +777,22 @@ class MachCommandConditions(object):
|
|||
"""Must have a mercurial source checkout."""
|
||||
if hasattr(cls, 'substs'):
|
||||
top_srcdir = cls.substs.get('top_srcdir')
|
||||
return top_srcdir and os.path.isdir(os.path.join(top_srcdir, '.hg'))
|
||||
return False
|
||||
elif hasattr(cls, 'topsrcdir'):
|
||||
top_srcdir = cls.topsrcdir
|
||||
else:
|
||||
return False
|
||||
return top_srcdir and os.path.isdir(os.path.join(top_srcdir, '.hg'))
|
||||
|
||||
@staticmethod
|
||||
def is_git(cls):
|
||||
"""Must have a git source checkout."""
|
||||
if hasattr(cls, 'substs'):
|
||||
top_srcdir = cls.substs.get('top_srcdir')
|
||||
return top_srcdir and os.path.isdir(os.path.join(top_srcdir, '.git'))
|
||||
return False
|
||||
elif hasattr(cls, 'topsrcdir'):
|
||||
top_srcdir = cls.topsrcdir
|
||||
else:
|
||||
return False
|
||||
return top_srcdir and os.path.exists(os.path.join(top_srcdir, '.git'))
|
||||
|
||||
|
||||
class PathArgument(object):
|
||||
|
|
|
|||
|
|
@ -695,9 +695,9 @@ class Clobber(MachCommandBase):
|
|||
raise
|
||||
|
||||
if 'python' in what:
|
||||
if os.path.isdir(mozpath.join(self.topsrcdir, '.hg')):
|
||||
if conditions.is_hg(self):
|
||||
cmd = ['hg', 'purge', '--all', '-I', 'glob:**.py[co]']
|
||||
elif os.path.isdir(mozpath.join(self.topsrcdir, '.git')):
|
||||
elif conditions.is_git(self):
|
||||
cmd = ['git', 'clean', '-f', '-x', '*.py[co]']
|
||||
else:
|
||||
cmd = ['find', '.', '-type', 'f', '-name', '*.py[co]', '-delete']
|
||||
|
|
|
|||
|
|
@ -173,6 +173,11 @@ const statements = {
|
|||
"scanAllRecords": `SELECT * FROM collection_data;`,
|
||||
|
||||
"clearCollectionMetadata": `DELETE FROM collection_metadata;`,
|
||||
|
||||
"calculateStorage": `
|
||||
SELECT collection_name, SUM(LENGTH(record)) as size, COUNT(record) as num_records
|
||||
FROM collection_data
|
||||
GROUP BY collection_name;`,
|
||||
};
|
||||
|
||||
const createStatements = [
|
||||
|
|
@ -380,6 +385,17 @@ class FirefoxAdapter extends Kinto.adapters.BaseAdapter {
|
|||
});
|
||||
}
|
||||
|
||||
calculateStorage() {
|
||||
return this._executeStatement(statements.calculateStorage, {})
|
||||
.then(result => {
|
||||
return Array.from(result, row => ({
|
||||
collectionName: row.getResultByName("collection_name"),
|
||||
size: row.getResultByName("size"),
|
||||
numRecords: row.getResultByName("num_records"),
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the sync status of every record and collection we have
|
||||
* access to.
|
||||
|
|
|
|||
94
servo/Cargo.lock
generated
94
servo/Cargo.lock
generated
|
|
@ -154,7 +154,7 @@ dependencies = [
|
|||
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clang-sys 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.20.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -281,7 +281,7 @@ dependencies = [
|
|||
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_config 0.0.1",
|
||||
"webrender_traits 0.16.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
|
@ -345,14 +345,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.20.4"
|
||||
version = "2.20.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -442,7 +442,7 @@ dependencies = [
|
|||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"profile_traits 0.0.1",
|
||||
"script_traits 0.0.1",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -462,7 +462,7 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -521,7 +521,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -608,7 +608,7 @@ dependencies = [
|
|||
"msg 0.0.1",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -633,7 +633,7 @@ dependencies = [
|
|||
name = "domobject_derive"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -1075,7 +1075,7 @@ name = "heapsize_derive"
|
|||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -1119,7 +1119,7 @@ dependencies = [
|
|||
"mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tendril 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -1275,7 +1275,7 @@ dependencies = [
|
|||
name = "jstraceable_derive"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -1329,7 +1329,7 @@ dependencies = [
|
|||
"selectors 0.18.0",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_config 0.0.1",
|
||||
"servo_geometry 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
|
|
@ -1373,7 +1373,7 @@ dependencies = [
|
|||
"script_traits 0.0.1",
|
||||
"selectors 0.18.0",
|
||||
"serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_config 0.0.1",
|
||||
"servo_geometry 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
|
|
@ -1801,7 +1801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "offscreen_gl_context"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -2020,7 +2020,7 @@ dependencies = [
|
|||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_config 0.0.1",
|
||||
"task_info 0.0.1",
|
||||
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -2072,7 +2072,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2128,7 +2128,7 @@ dependencies = [
|
|||
"aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -2221,7 +2221,7 @@ dependencies = [
|
|||
"msg 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -2238,7 +2238,7 @@ dependencies = [
|
|||
"script_traits 0.0.1",
|
||||
"selectors 0.18.0",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_atoms 0.0.1",
|
||||
"servo_config 0.0.1",
|
||||
"servo_geometry 0.0.1",
|
||||
|
|
@ -2317,7 +2317,7 @@ dependencies = [
|
|||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"profile_traits 0.0.1",
|
||||
"rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -2354,7 +2354,7 @@ name = "serde_codegen"
|
|||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -2374,7 +2374,7 @@ name = "serde_codegen_internals"
|
|||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2382,14 +2382,14 @@ name = "serde_derive"
|
|||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "0.9.6"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -2798,16 +2798,25 @@ name = "syn"
|
|||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.11.4"
|
||||
version = "0.11.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synom 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synom"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -2816,7 +2825,7 @@ name = "synstructure"
|
|||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -2872,7 +2881,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2912,7 +2921,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "term_size"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -2931,7 +2940,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -3169,7 +3178,7 @@ dependencies = [
|
|||
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -3189,7 +3198,7 @@ dependencies = [
|
|||
"gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -3345,7 +3354,7 @@ dependencies = [
|
|||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||
"checksum cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8bdd78cca65a739cb5475dbf6b6bbb49373e327f4a6f2b499c0f98632df38c10"
|
||||
"checksum clang-sys 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f98f0715ff67f27ca6a2f8f0ffc2a56f8edbc7acd57489c29eadc3a15c4eafe"
|
||||
"checksum clap 2.20.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a60af5cb867dd4ee2378398acde80c73b466b58a963f598061ce7e394800998d"
|
||||
"checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
|
||||
"checksum cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a3a6805df695087e7c1bcd9a82e03ad6fb864c8e67ac41b1348229ce5b7f0407"
|
||||
"checksum cocoa 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d55b620aff4da7d4b9d85f2974cc62a097146623b75e3f36734fe68d8cef493e"
|
||||
"checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d"
|
||||
|
|
@ -3453,7 +3462,7 @@ dependencies = [
|
|||
"checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
|
||||
"checksum objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "877f30f37acef6749b1841cceab289707f211aecfc756553cd63976190e6cc2e"
|
||||
"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
|
||||
"checksum offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b33309fc17d50be59b466fe26a337023f297e8c9e9032ca0ccfdcdf3c0c627d0"
|
||||
"checksum offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac875ea951d7d695a1cc8c370777d6a0e2b7355ca49506034683df09b24b1bc"
|
||||
"checksum ogg 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "426d8dc59cdd206be1925461087350385c0a02f291d87625829c6d08e72b457b"
|
||||
"checksum ogg_metadata 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e755cc735fa6faa709cb23048433d9201d6caa85fa96215386ccdd5e9b40ad01"
|
||||
"checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842"
|
||||
|
|
@ -3477,7 +3486,7 @@ dependencies = [
|
|||
"checksum png 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3cb773e9a557edb568ce9935cf783e3cdcabe06a9449d41b3e5506d88e582c82"
|
||||
"checksum quasi 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dcbf815446dc6a0afbc72d88f9a8aa71b608d10b168e09437c80c0fd6fd410c9"
|
||||
"checksum quasi_codegen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b06172e92ab0099427609854ffb1512c377be5fc4beaf572ae5d5a01b8359596"
|
||||
"checksum quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b44fd83db28b83c1c58187159934906e5e955c812e211df413b76b03c909a5"
|
||||
"checksum quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "08de3f12e670f83f61e450443cbae34496a35b665691fd8e99b24ec662f75865"
|
||||
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
|
||||
"checksum rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50c575b58c2b109e2fbc181820cbe177474f35610ff9e357dc75f6bac854ffbf"
|
||||
"checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
|
||||
|
|
@ -3497,7 +3506,7 @@ dependencies = [
|
|||
"checksum serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "afad7924a009f859f380e4a2e3a509a845c2ac66435fcead74a4d983b21ae806"
|
||||
"checksum serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3172bf2940b975c0e4f6ab42a511c0a4407d4f46ccef87a9d3615db5c26fa96"
|
||||
"checksum serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6af30425c5161deb200aac4803c62b903eb3be7e889c5823d0e16c4ce0ce989c"
|
||||
"checksum serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e095e4e94e7382b76f48e93bd845ffddda62df8dfd4c163b1bfa93d40e22e13a"
|
||||
"checksum serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb96d30e4e6f9fc52e08f51176d078b6f79b981dc3ed4134f7b850be9f446a8"
|
||||
"checksum servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f013da79c3fb2a9653534b064cd2ca62e10f8b6d19ed8fdc885cb2873412789"
|
||||
"checksum servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21069a884c33fe6ee596975e1f3849ed88c4ec857fbaf11d33672d8ebe051217"
|
||||
"checksum servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93f799b649b4a2bf362398910eca35240704c7e765e780349b2bb1070d892262"
|
||||
|
|
@ -3520,7 +3529,8 @@ dependencies = [
|
|||
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)" = "58fd09df59565db3399efbba34ba8a2fec1307511ebd245d0061ff9d42691673"
|
||||
"checksum syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f94368aae82bb29656c98443a7026ca931a659e8d19dcdc41d6e273054e820"
|
||||
"checksum syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e28da8d02d75d1e58b89258e0741128f0b0d8a8309fb5c627be0fbd37a76c67"
|
||||
"checksum synom 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8fece1853fb872b0acdc3ff88f37c474018e125ef81cd4cb8c0ca515746b62ed"
|
||||
"checksum synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a811f8e51453cada27c033be6b5fdac6e4e63981983702eb85b4c897a25ecc6c"
|
||||
"checksum syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb3f52553a966675982404dc34028291b347e0c9a9c0b0b34f2da6be8a0443f8"
|
||||
"checksum syntex_errors 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dee2f6e49c075f71332bb775219d5982bee6732d26227fa1ae1b53cdb12f5cc5"
|
||||
|
|
@ -3530,9 +3540,9 @@ dependencies = [
|
|||
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
||||
"checksum tendril 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cebf864c2d90394a1b66d6fe45963f9a177f2af81a0edea5060f77627f9c4587"
|
||||
"checksum term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d168af3930b369cfe245132550579d47dfd873d69470755a19c2c6568dbbd989"
|
||||
"checksum term_size 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "71662702fe5cd2cf95edd4ad655eea42f24a87a0e44059cbaa4e55260b7bc331"
|
||||
"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
|
||||
"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
|
||||
"checksum thread_local 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7793b722f0f77ce716e7f1acf416359ca32ff24d04ffbac4269f44a4a83be05d"
|
||||
"checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
|
||||
"checksum thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf947d192a9be60ef5131cc7a4648886ba89d712f16700ebbf80c8a69d05d48f"
|
||||
"checksum threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59f6d3eff89920113dac9db44dde461d71d01e88a5b57b258a0466c32b5d7fe1"
|
||||
"checksum time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "211b63c112206356ef1ff9b19355f43740fc3f85960c598a93d3a3d3ba7beade"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use script_traits::{TouchpadPressurePhase, TouchEventType, TouchId, WindowSizeDa
|
|||
use script_traits::CompositorEvent::{self, MouseMoveEvent, MouseButtonEvent, TouchEvent, TouchpadPressureEvent};
|
||||
use servo_config::opts;
|
||||
use servo_config::prefs::PREFS;
|
||||
use servo_geometry::ScreenPx;
|
||||
use servo_geometry::DeviceIndependentPixel;
|
||||
use servo_url::ServoUrl;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
|
|
@ -155,10 +155,10 @@ pub struct IOCompositor<Window: WindowMethods> {
|
|||
|
||||
/// "Desktop-style" zoom that resizes the viewport to fit the window.
|
||||
/// See `ViewportPx` docs in util/geom.rs for details.
|
||||
page_zoom: ScaleFactor<f32, ViewportPx, ScreenPx>,
|
||||
page_zoom: ScaleFactor<f32, ViewportPx, DeviceIndependentPixel>,
|
||||
|
||||
/// The device pixel ratio for this window.
|
||||
scale_factor: ScaleFactor<f32, ScreenPx, DevicePixel>,
|
||||
scale_factor: ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>,
|
||||
|
||||
channel_to_self: Box<CompositorProxy + Send>,
|
||||
|
||||
|
|
@ -378,7 +378,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
fn new(window: Rc<Window>, state: InitialCompositorState)
|
||||
-> IOCompositor<Window> {
|
||||
let window_size = window.framebuffer_size();
|
||||
let scale_factor = window.scale_factor();
|
||||
let scale_factor = window.hidpi_factor();
|
||||
let composite_target = match opts::get().output_file {
|
||||
Some(_) => CompositeTarget::PngFile,
|
||||
None => CompositeTarget::Window
|
||||
|
|
@ -756,7 +756,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
}
|
||||
|
||||
fn send_window_size(&self, size_type: WindowSizeType) {
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let dppx = self.page_zoom * self.hidpi_factor();
|
||||
let initial_viewport = self.window_size.to_f32() / dppx;
|
||||
let visible_viewport = initial_viewport / self.viewport_zoom;
|
||||
let msg = ConstellationMsg::WindowSize(WindowSizeData {
|
||||
|
|
@ -889,7 +889,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
debug!("compositor resizing to {:?}", new_size.to_untyped());
|
||||
|
||||
// A size change could also mean a resolution change.
|
||||
let new_scale_factor = self.window.scale_factor();
|
||||
let new_scale_factor = self.window.hidpi_factor();
|
||||
if self.scale_factor != new_scale_factor {
|
||||
self.scale_factor = new_scale_factor;
|
||||
self.update_zoom_transform();
|
||||
|
|
@ -948,7 +948,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
};
|
||||
|
||||
if let Some(pipeline) = self.pipeline(root_pipeline_id) {
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let dppx = self.page_zoom * self.hidpi_factor();
|
||||
let translated_point = (point / dppx).to_untyped();
|
||||
let event_to_send = match mouse_window_event {
|
||||
MouseWindowEvent::Click(button, _) => {
|
||||
|
|
@ -986,7 +986,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
return;
|
||||
}
|
||||
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let dppx = self.page_zoom * self.hidpi_factor();
|
||||
let event_to_send = MouseMoveEvent(Some((cursor / dppx).to_untyped()));
|
||||
let msg = ConstellationControlMsg::SendEvent(root_pipeline_id, event_to_send);
|
||||
if let Some(pipeline) = self.pipeline(root_pipeline_id) {
|
||||
|
|
@ -1012,7 +1012,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
|
||||
fn on_touch_down(&mut self, identifier: TouchId, point: TypedPoint2D<f32, DevicePixel>) {
|
||||
self.touch_handler.on_touch_down(identifier, point);
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let dppx = self.page_zoom * self.hidpi_factor();
|
||||
let translated_point = (point / dppx).to_untyped();
|
||||
self.send_event_to_root_pipeline(TouchEvent(TouchEventType::Down,
|
||||
identifier,
|
||||
|
|
@ -1042,7 +1042,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
});
|
||||
}
|
||||
TouchAction::DispatchEvent => {
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let dppx = self.page_zoom * self.hidpi_factor();
|
||||
let translated_point = (point / dppx).to_untyped();
|
||||
self.send_event_to_root_pipeline(TouchEvent(TouchEventType::Move,
|
||||
identifier,
|
||||
|
|
@ -1053,7 +1053,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
}
|
||||
|
||||
fn on_touch_up(&mut self, identifier: TouchId, point: TypedPoint2D<f32, DevicePixel>) {
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let dppx = self.page_zoom * self.hidpi_factor();
|
||||
let translated_point = (point / dppx).to_untyped();
|
||||
self.send_event_to_root_pipeline(TouchEvent(TouchEventType::Up,
|
||||
identifier,
|
||||
|
|
@ -1066,7 +1066,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
fn on_touch_cancel(&mut self, identifier: TouchId, point: TypedPoint2D<f32, DevicePixel>) {
|
||||
// Send the event to script.
|
||||
self.touch_handler.on_touch_cancel(identifier, point);
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let dppx = self.page_zoom * self.hidpi_factor();
|
||||
let translated_point = (point / dppx).to_untyped();
|
||||
self.send_event_to_root_pipeline(TouchEvent(TouchEventType::Cancel,
|
||||
identifier,
|
||||
|
|
@ -1078,7 +1078,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
pressure: f32,
|
||||
phase: TouchpadPressurePhase) {
|
||||
if let Some(true) = PREFS.get("dom.forcetouch.enabled").as_boolean() {
|
||||
let dppx = self.page_zoom * self.device_pixels_per_screen_px();
|
||||
let dppx = self.page_zoom * self.hidpi_factor();
|
||||
let translated_point = (point / dppx).to_untyped();
|
||||
self.send_event_to_root_pipeline(TouchpadPressureEvent(translated_point,
|
||||
pressure,
|
||||
|
|
@ -1291,7 +1291,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
}
|
||||
}
|
||||
|
||||
fn device_pixels_per_screen_px(&self) -> ScaleFactor<f32, ScreenPx, DevicePixel> {
|
||||
fn hidpi_factor(&self) -> ScaleFactor<f32, DeviceIndependentPixel, DevicePixel> {
|
||||
match opts::get().device_pixels_per_px {
|
||||
Some(device_pixels_per_px) => ScaleFactor::new(device_pixels_per_px),
|
||||
None => match opts::get().output_file {
|
||||
|
|
@ -1302,7 +1302,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
}
|
||||
|
||||
fn device_pixels_per_page_px(&self) -> ScaleFactor<f32, PagePx, DevicePixel> {
|
||||
self.viewport_zoom * self.page_zoom * self.device_pixels_per_screen_px()
|
||||
self.viewport_zoom * self.page_zoom * self.hidpi_factor()
|
||||
}
|
||||
|
||||
fn update_zoom_transform(&mut self) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue