Update On Tue Jul 23 20:50:04 CEST 2024

This commit is contained in:
github-action[bot] 2024-07-23 20:50:05 +02:00
parent ef5a0ff909
commit f3b66784ec
694 changed files with 28780 additions and 30308 deletions

39
Cargo.lock generated
View file

@ -4052,8 +4052,8 @@ dependencies = [
[[package]]
name = "neqo-bin"
version = "0.7.9"
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
version = "0.8.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
dependencies = [
"clap",
"clap-verbosity-flag",
@ -4063,8 +4063,8 @@ dependencies = [
"neqo-common",
"neqo-crypto",
"neqo-http3",
"neqo-qpack",
"neqo-transport",
"neqo-udp",
"qlog",
"quinn-udp",
"regex",
@ -4074,8 +4074,8 @@ dependencies = [
[[package]]
name = "neqo-common"
version = "0.7.9"
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
version = "0.8.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
dependencies = [
"enum-map",
"env_logger",
@ -4087,8 +4087,8 @@ dependencies = [
[[package]]
name = "neqo-crypto"
version = "0.7.9"
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
version = "0.8.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
dependencies = [
"bindgen 0.69.4",
"log",
@ -4102,8 +4102,8 @@ dependencies = [
[[package]]
name = "neqo-http3"
version = "0.7.9"
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
version = "0.8.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
dependencies = [
"enumset",
"log",
@ -4113,18 +4113,16 @@ dependencies = [
"neqo-transport",
"qlog",
"sfv",
"smallvec",
"url",
]
[[package]]
name = "neqo-qpack"
version = "0.7.9"
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
version = "0.8.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
dependencies = [
"log",
"neqo-common",
"neqo-crypto",
"neqo-transport",
"qlog",
"static_assertions",
@ -4132,8 +4130,8 @@ dependencies = [
[[package]]
name = "neqo-transport"
version = "0.7.9"
source = "git+https://github.com/mozilla/neqo?tag=v0.7.9#121fe683ae4b39a5b694f671abfd397cbd9b4322"
version = "0.8.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
dependencies = [
"enum-map",
"indexmap 2.2.6",
@ -4142,6 +4140,17 @@ dependencies = [
"neqo-crypto",
"qlog",
"smallvec",
"static_assertions",
]
[[package]]
name = "neqo-udp"
version = "0.8.1"
source = "git+https://github.com/mozilla/neqo?tag=v0.8.1#f0bffce01be53309a9cc93dc344141f57918cb3b"
dependencies = [
"log",
"neqo-common",
"quinn-udp",
]
[[package]]

View file

@ -642,6 +642,11 @@ export class ContentSearchParent extends JSWindowActorParent {
// the meantime, then we need to update the browser. event.detail will be
// the docshell's new parent <xul:browser> element.
let browser = this.browsingContext.top.embedderElement;
if (!browser) {
// The associated browser has gone away, so there's nothing more we can
// do here.
return;
}
let eventItem = {
type: "Message",
name: msg.name,

View file

@ -2043,7 +2043,7 @@ pref("identity.fxaccounts.commands.missed.fetch_interval", 86400);
// Controls whether this client can send and receive "close tab"
// commands from other FxA clients
pref("identity.fxaccounts.commands.remoteTabManagement.enabled", false);
pref("identity.fxaccounts.commands.remoteTabManagement.enabled", true);
// Controls whether or not the client association ping has values set on it
// when the sync-ui-state:update notification fires.

View file

@ -181,7 +181,9 @@ var gBrowserInit = {
},
onLoad() {
gBrowser.addEventListener("DOMUpdateBlockedPopups", gPopupBlockerObserver);
gBrowser.addEventListener("DOMUpdateBlockedPopups", e =>
PopupBlockerObserver.handleEvent(e)
);
gBrowser.addEventListener(
"TranslationsParent:LanguageState",
FullPageTranslationsPanel

View file

@ -62,6 +62,7 @@ ChromeUtils.defineESModuleGetters(this, {
PlacesUIUtils: "resource:///modules/PlacesUIUtils.sys.mjs",
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
Pocket: "chrome://pocket/content/Pocket.sys.mjs",
PopupBlockerObserver: "resource:///modules/PopupBlockerObserver.sys.mjs",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
ProcessHangMonitor: "resource:///modules/ProcessHangMonitor.sys.mjs",
PromptUtils: "resource://gre/modules/PromptUtils.sys.mjs",
@ -1130,257 +1131,6 @@ const gStoragePressureObserver = {
},
};
var gPopupBlockerObserver = {
async handleEvent(aEvent) {
if (aEvent.originalTarget != gBrowser.selectedBrowser) {
return;
}
gPermissionPanel.refreshPermissionIcons();
let popupCount =
gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount();
if (!popupCount) {
// Hide the notification box (if it's visible).
let notificationBox = gBrowser.getNotificationBox();
let notification =
notificationBox.getNotificationWithValue("popup-blocked");
if (notification) {
notificationBox.removeNotification(notification, false);
}
return;
}
// Only show the notification again if we've not already shown it. Since
// notifications are per-browser, we don't need to worry about re-adding
// it.
if (gBrowser.selectedBrowser.popupBlocker.shouldShowNotification) {
if (Services.prefs.getBoolPref("privacy.popups.showBrowserMessage")) {
const label = {
"l10n-id":
popupCount < this.maxReportedPopups
? "popup-warning-message"
: "popup-warning-exceeded-message",
"l10n-args": { popupCount },
};
let notificationBox = gBrowser.getNotificationBox();
let notification =
notificationBox.getNotificationWithValue("popup-blocked") ||
(await this.notificationPromise);
if (notification) {
notification.label = label;
} else {
const image = "chrome://browser/skin/notification-icons/popup.svg";
const priority = notificationBox.PRIORITY_INFO_MEDIUM;
try {
this.notificationPromise = notificationBox.appendNotification(
"popup-blocked",
{ label, image, priority },
[
{
"l10n-id": "popup-warning-button",
popup: "blockedPopupOptions",
callback: null,
},
]
);
await this.notificationPromise;
} catch (err) {
console.warn(err);
} finally {
this.notificationPromise = null;
}
}
}
// Record the fact that we've reported this blocked popup, so we don't
// show it again.
gBrowser.selectedBrowser.popupBlocker.didShowNotification();
}
},
toggleAllowPopupsForSite(aEvent) {
var pm = Services.perms;
var shouldBlock = aEvent.target.getAttribute("block") == "true";
var perm = shouldBlock ? pm.DENY_ACTION : pm.ALLOW_ACTION;
pm.addFromPrincipal(gBrowser.contentPrincipal, "popup", perm);
if (!shouldBlock) {
gBrowser.selectedBrowser.popupBlocker.unblockAllPopups();
}
gBrowser.getNotificationBox().removeCurrentNotification();
},
fillPopupList(aEvent) {
// XXXben - rather than using |currentURI| here, which breaks down on multi-framed sites
// we should really walk the blockedPopups and create a list of "allow for <host>"
// menuitems for the common subset of hosts present in the report, this will
// make us frame-safe.
//
// XXXjst - Note that when this is fixed to work with multi-framed sites,
// also back out the fix for bug 343772 where
// nsGlobalWindow::CheckOpenAllow() was changed to also
// check if the top window's location is allow-listed.
let browser = gBrowser.selectedBrowser;
var uriOrPrincipal = browser.contentPrincipal.isContentPrincipal
? browser.contentPrincipal
: browser.currentURI;
var blockedPopupAllowSite = document.getElementById(
"blockedPopupAllowSite"
);
try {
blockedPopupAllowSite.removeAttribute("hidden");
let uriHost = uriOrPrincipal.asciiHost
? uriOrPrincipal.host
: uriOrPrincipal.spec;
var pm = Services.perms;
if (
pm.testPermissionFromPrincipal(browser.contentPrincipal, "popup") ==
pm.ALLOW_ACTION
) {
// Offer an item to block popups for this site, if an allow-list entry exists
// already for it.
document.l10n.setAttributes(
blockedPopupAllowSite,
"popups-infobar-block",
{ uriHost }
);
blockedPopupAllowSite.setAttribute("block", "true");
} else {
// Offer an item to allow popups for this site
document.l10n.setAttributes(
blockedPopupAllowSite,
"popups-infobar-allow",
{ uriHost }
);
blockedPopupAllowSite.removeAttribute("block");
}
} catch (e) {
blockedPopupAllowSite.hidden = true;
}
let blockedPopupDontShowMessage = document.getElementById(
"blockedPopupDontShowMessage"
);
let showMessage = Services.prefs.getBoolPref(
"privacy.popups.showBrowserMessage"
);
blockedPopupDontShowMessage.setAttribute("checked", !showMessage);
let blockedPopupsSeparator = document.getElementById(
"blockedPopupsSeparator"
);
blockedPopupsSeparator.hidden = true;
browser.popupBlocker.getBlockedPopups().then(blockedPopups => {
let foundUsablePopupURI = false;
if (blockedPopups) {
for (let i = 0; i < blockedPopups.length; i++) {
let blockedPopup = blockedPopups[i];
// popupWindowURI will be null if the file picker popup is blocked.
// xxxdz this should make the option say "Show file picker" and do it (Bug 590306)
if (!blockedPopup.popupWindowURISpec) {
continue;
}
var popupURIspec = blockedPopup.popupWindowURISpec;
// Sometimes the popup URI that we get back from the blockedPopup
// isn't useful (for instance, netscape.com's popup URI ends up
// being "http://www.netscape.com", which isn't really the URI of
// the popup they're trying to show). This isn't going to be
// useful to the user, so we won't create a menu item for it.
if (
popupURIspec == "" ||
popupURIspec == "about:blank" ||
popupURIspec == "<self>" ||
popupURIspec == uriOrPrincipal.spec
) {
continue;
}
// Because of the short-circuit above, we may end up in a situation
// in which we don't have any usable popup addresses to show in
// the menu, and therefore we shouldn't show the separator. However,
// since we got past the short-circuit, we must've found at least
// one usable popup URI and thus we'll turn on the separator later.
foundUsablePopupURI = true;
var menuitem = document.createXULElement("menuitem");
document.l10n.setAttributes(menuitem, "popup-show-popup-menuitem", {
popupURI: popupURIspec,
});
menuitem.setAttribute(
"oncommand",
"gPopupBlockerObserver.showBlockedPopup(event);"
);
menuitem.setAttribute("popupReportIndex", i);
menuitem.setAttribute(
"popupInnerWindowId",
blockedPopup.innerWindowId
);
menuitem.browsingContext = blockedPopup.browsingContext;
menuitem.popupReportBrowser = browser;
aEvent.target.appendChild(menuitem);
}
}
// Show the separator if we added any
// showable popup addresses to the menu.
if (foundUsablePopupURI) {
blockedPopupsSeparator.removeAttribute("hidden");
}
}, null);
},
onPopupHiding(aEvent) {
let item = aEvent.target.lastElementChild;
while (item && item.id != "blockedPopupsSeparator") {
let next = item.previousElementSibling;
item.remove();
item = next;
}
},
showBlockedPopup(aEvent) {
let target = aEvent.target;
let browsingContext = target.browsingContext;
let innerWindowId = target.getAttribute("popupInnerWindowId");
let popupReportIndex = target.getAttribute("popupReportIndex");
let browser = target.popupReportBrowser;
browser.popupBlocker.unblockPopup(
browsingContext,
innerWindowId,
popupReportIndex
);
},
editPopupSettings() {
openPreferences("privacy-permissions-block-popups");
},
dontShowMessage() {
var showMessage = Services.prefs.getBoolPref(
"privacy.popups.showBrowserMessage"
);
Services.prefs.setBoolPref(
"privacy.popups.showBrowserMessage",
!showMessage
);
gBrowser.getNotificationBox().removeCurrentNotification();
},
};
XPCOMUtils.defineLazyPreferenceGetter(
gPopupBlockerObserver,
"maxReportedPopups",
"privacy.popups.maxReported"
);
var gKeywordURIFixup = {
check(browser, { fixedURI, keywordProviderName, preferredURI }) {
// We get called irrespective of whether we did a keyword search, or

View file

@ -25,7 +25,7 @@
"gClickAndHoldListenersOnElement",
"gSessionHistoryObserver",
"gStoragePressureObserver",
"gPopupBlockerObserver",
"PopupBlockerObserver",
"gKeywordURIFixup",
"_createNullPrincipalFromTabUserContextId",
"HandleAppCommandEvent",

View file

@ -11,6 +11,11 @@ document.addEventListener(
let mainPopupSet = document.getElementById("mainPopupSet");
// eslint-disable-next-line complexity
mainPopupSet.addEventListener("command", event => {
if (event.target.hasAttribute("popupReportIndex")) {
PopupBlockerObserver.showBlockedPopup(event);
return;
}
switch (event.target.id) {
// == tabContextMenu ==
case "context_openANewTab":
@ -185,13 +190,13 @@ document.addEventListener(
// == blockedPopupOptions ==
case "blockedPopupAllowSite":
gPopupBlockerObserver.toggleAllowPopupsForSite(event);
PopupBlockerObserver.toggleAllowPopupsForSite(event);
break;
case "blockedPopupEdit":
gPopupBlockerObserver.editPopupSettings();
PopupBlockerObserver.editPopupSettings(event);
break;
case "blockedPopupDontShowMessage":
gPopupBlockerObserver.dontShowMessage();
PopupBlockerObserver.dontShowMessage(event);
break;
// == pictureInPictureToggleContextMenu ==
@ -320,7 +325,7 @@ document.addEventListener(
ToolbarContextMenu.updateExtension(event.target, event);
break;
case "blockedPopupOptions":
gPopupBlockerObserver.fillPopupList(event);
PopupBlockerObserver.fillPopupList(event);
break;
case "pageActionContextMenu":
BrowserPageActions.onContextMenuShowing(event, event.target);
@ -362,7 +367,7 @@ document.addEventListener(
mainPopupSet.addEventListener("popuphiding", event => {
switch (event.target.id) {
case "blockedPopupOptions":
gPopupBlockerObserver.onPopupHiding(event);
PopupBlockerObserver.onPopupHiding(event);
break;
case "tabbrowser-tab-tooltip":
event.target.removeAttribute("position");

View file

@ -1232,6 +1232,22 @@ export class BackupService extends EventTarget {
await IOUtils.remove(compressedStagingPath);
});
// Record the size of the complete single-file archive
let archiveSizeKilobytes = await BackupResource.getFileSize(
archiveTmpPath
);
let archiveSizeBytesNearestMebibyte = MeasurementUtils.fuzzByteSize(
archiveSizeKilobytes * BYTES_IN_KILOBYTE,
1 * BYTES_IN_MEBIBYTE
);
lazy.logConsole.debug(
"backup archive size in bytes: " + archiveSizeBytesNearestMebibyte
);
Glean.browserBackup.compressedArchiveSize.accumulate(
archiveSizeBytesNearestMebibyte / BYTES_IN_MEBIBYTE
);
let archivePath = await this.finalizeSingleFileArchive(
archiveTmpPath,
archiveDestFolderPath,

View file

@ -47,6 +47,23 @@ browser.backup:
expires: never
telemetry_mirror: BROWSER_BACKUP_TOTAL_BACKUP_SIZE
compressed_archive_size:
type: memory_distribution
memory_unit: megabyte
description: >
The total compressed size of a single-file profile data backup archive.
To reduce fingerprintability, we round to the nearest 1 mebibyte.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1907625
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1907625
data_sensitivity:
- technical
notification_emails:
- mconley@mozilla.com
expires: never
telemetry_mirror: BROWSER_BACKUP_COMPRESSED_ARCHIVE_SIZE
total_backup_time:
type: timing_distribution
time_unit: millisecond

View file

@ -92,6 +92,10 @@ async function testCreateBackupHelper(sandbox, taskFn) {
let totalBackupSizeHistogram = TelemetryTestUtils.getAndClearHistogram(
"BROWSER_BACKUP_TOTAL_BACKUP_SIZE"
);
// Handle for the metric for total byte size of single-file archive
let compressedArchiveSizeHistogram = TelemetryTestUtils.getAndClearHistogram(
"BROWSER_BACKUP_COMPRESSED_ARCHIVE_SIZE"
);
// Handle for the metric for total time taking by profile backup
let backupTimerHistogram = TelemetryTestUtils.getAndClearHistogram(
"BROWSER_BACKUP_TOTAL_BACKUP_TIME_MS"
@ -196,11 +200,12 @@ async function testCreateBackupHelper(sandbox, taskFn) {
"Snapshots directory should have had all staging folders cleaned up"
);
// 1 mebibyte minimum recorded value if staging folder is under 1 mebibyte
// 1 mebibyte minimum recorded value if total data size is under 1 mebibyte
// This assumes that these BackupService tests do not create sizable fake files
const SMALLEST_BACKUP_SIZE_BYTES = 1048576;
const SMALLEST_BACKUP_SIZE_MEBIBYTES = 1;
// Validate total (uncompressed profile data) size
let totalBackupSize = Glean.browserBackup.totalBackupSize.testGetValue();
Assert.equal(
totalBackupSize.count,
@ -218,6 +223,25 @@ async function testCreateBackupHelper(sandbox, taskFn) {
1
);
// Validate final archive (compressed/encrypted profile data + HTML) size
let compressedArchiveSize =
Glean.browserBackup.compressedArchiveSize.testGetValue();
Assert.equal(
compressedArchiveSize.count,
1,
"Should have collected a single measurement for the backup compressed archive size"
);
Assert.equal(
compressedArchiveSize.sum,
SMALLEST_BACKUP_SIZE_BYTES,
"Should have collected the right value for the backup compressed archive size"
);
TelemetryTestUtils.assertHistogram(
compressedArchiveSizeHistogram,
SMALLEST_BACKUP_SIZE_MEBIBYTES,
1
);
// Check that resources were called from highest to lowest backup priority.
sinon.assert.callOrder(
FakeBackupResource3.prototype.backup,

View file

@ -313,10 +313,7 @@ $letter-fallback-color: $white;
.icon {
margin-inline-end: 2px;
fill: var(--newtab-contextual-text-primary-color);
// Contrast fix for users who have wallpapers set
@include wallpaper-contrast-fix;
fill: currentColor;
}
span {

View file

@ -859,13 +859,7 @@ main section {
}
.top-site-outer .title .icon {
margin-inline-end: 2px;
fill: var(--newtab-contextual-text-primary-color);
}
.lightWallpaper .top-site-outer .title .icon {
color-scheme: light;
}
.darkWallpaper .top-site-outer .title .icon {
color-scheme: dark;
fill: currentColor;
}
.top-site-outer .title span {
display: block;

View file

@ -863,13 +863,7 @@ main section {
}
.top-site-outer .title .icon {
margin-inline-end: 2px;
fill: var(--newtab-contextual-text-primary-color);
}
.lightWallpaper .top-site-outer .title .icon {
color-scheme: light;
}
.darkWallpaper .top-site-outer .title .icon {
color-scheme: dark;
fill: currentColor;
}
.top-site-outer .title span {
display: block;

View file

@ -859,13 +859,7 @@ main section {
}
.top-site-outer .title .icon {
margin-inline-end: 2px;
fill: var(--newtab-contextual-text-primary-color);
}
.lightWallpaper .top-site-outer .title .icon {
color-scheme: light;
}
.darkWallpaper .top-site-outer .title .icon {
color-scheme: dark;
fill: currentColor;
}
.top-site-outer .title span {
display: block;

View file

@ -76,11 +76,31 @@ add_task(async function testResetAll() {
// Modify the state of some of the features.
doc.getElementById("test-featureC").click();
doc.getElementById("test-featureD").click();
// Check the prefs changed
ok(!Services.prefs.getBoolPref("test.featureA"), "modified state A");
ok(Services.prefs.getBoolPref("test.featureB"), "modified state B");
ok(Services.prefs.getBoolPref(KNOWN_PREF_1), "modified state C");
ok(!Services.prefs.getBoolPref(KNOWN_PREF_2), "modified state D");
// Check that telemetry appeared:
const { TelemetryTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/TelemetryTestUtils.sys.mjs"
);
let snapshot = TelemetryTestUtils.getProcessScalars("parent", true, true);
TelemetryTestUtils.assertKeyedScalar(
snapshot,
"browser.ui.interaction.preferences_paneExperimental",
"test-featureC",
1
);
TelemetryTestUtils.assertKeyedScalar(
snapshot,
"browser.ui.interaction.preferences_paneExperimental",
"test-featureD",
1
);
// State after reset.
let prefChangedPromise = new Promise(resolve => {
Services.prefs.addObserver(KNOWN_PREF_2, function observer() {

View file

@ -115,13 +115,18 @@ function* convertLayoutToUI(fields, l10nStrings) {
/**
* Retrieves the current form data from the current form element on the page.
* NOTE: We are intentionally not using FormData here because on iOS we have states where
* selects are disabled and FormData ignores disabled elements. We want getCurrentFormData
* to always refelect the exact state of the form.
*
* @returns {object} An object containing key-value pairs of form data.
*/
export const getCurrentFormData = () => {
const formElement = document.querySelector("form");
const formData = new FormData(formElement);
return Object.fromEntries(formData.entries());
const formData = {};
for (const element of document.querySelector("form").elements) {
formData[element.name] = element.value ?? "";
}
return formData;
};
/**

View file

@ -199,7 +199,7 @@ add_task(async function check_autofill_in_hidden_formfields() {
);
is(
autofillState,
"",
testIndex == 1 ? "autofill" : "",
"input autofill state after change " +
"input " +
testIndex +

View file

@ -1244,6 +1244,23 @@ const AVAILABLE_UA_OVERRIDES = [
},
},
},
{
/*
* Bug 1813177 - UA override for rbi.org.in
*
* The site endlessly redirects for a Firefox mobile UA string.
*/
id: "bug1813177",
platform: "android",
domain: "m.rbi.org.in",
bug: "1813177",
config: {
matches: ["*://m.rbi.org.in/*"],
uaTransformer: () => {
return UAHelpers.getDeviceAppropriateChromeUA();
},
},
},
];
module.exports = AVAILABLE_UA_OVERRIDES;

View file

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Web Compatibility Interventions",
"description": "Urgent post-release fixes for web compatibility.",
"version": "129.7.0",
"version": "129.8.0",
"browser_specific_settings": {
"gecko": {
"id": "webcompat@mozilla.org",

View file

@ -16,7 +16,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"af": {
"pin": false,
@ -35,7 +35,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"an": {
"pin": false,
@ -54,7 +54,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ar": {
"pin": false,
@ -73,7 +73,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ast": {
"pin": false,
@ -92,7 +92,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"az": {
"pin": false,
@ -111,7 +111,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"be": {
"pin": false,
@ -130,7 +130,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"bg": {
"pin": false,
@ -149,7 +149,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"bn": {
"pin": false,
@ -168,7 +168,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"bo": {
"pin": false,
@ -187,7 +187,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"br": {
"pin": false,
@ -206,7 +206,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"brx": {
"pin": false,
@ -225,7 +225,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"bs": {
"pin": false,
@ -244,7 +244,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ca": {
"pin": false,
@ -263,7 +263,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ca-valencia": {
"pin": false,
@ -282,7 +282,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"cak": {
"pin": false,
@ -301,7 +301,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ckb": {
"pin": false,
@ -320,7 +320,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"cs": {
"pin": false,
@ -339,7 +339,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"cy": {
"pin": false,
@ -358,7 +358,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"da": {
"pin": false,
@ -377,7 +377,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"de": {
"pin": false,
@ -396,7 +396,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"dsb": {
"pin": false,
@ -415,7 +415,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"el": {
"pin": false,
@ -434,7 +434,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"en-CA": {
"pin": false,
@ -453,7 +453,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"en-GB": {
"pin": false,
@ -472,7 +472,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"eo": {
"pin": false,
@ -491,7 +491,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"es-AR": {
"pin": false,
@ -510,7 +510,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"es-CL": {
"pin": false,
@ -529,7 +529,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"es-ES": {
"pin": false,
@ -548,7 +548,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"es-MX": {
"pin": false,
@ -567,7 +567,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"et": {
"pin": false,
@ -586,7 +586,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"eu": {
"pin": false,
@ -605,7 +605,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"fa": {
"pin": false,
@ -624,7 +624,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ff": {
"pin": false,
@ -643,7 +643,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"fi": {
"pin": false,
@ -662,7 +662,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"fr": {
"pin": false,
@ -681,7 +681,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"fur": {
"pin": false,
@ -700,7 +700,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"fy-NL": {
"pin": false,
@ -719,7 +719,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ga-IE": {
"pin": false,
@ -738,7 +738,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"gd": {
"pin": false,
@ -757,7 +757,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"gl": {
"pin": false,
@ -776,7 +776,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"gn": {
"pin": false,
@ -795,7 +795,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"gu-IN": {
"pin": false,
@ -814,7 +814,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"he": {
"pin": false,
@ -833,7 +833,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"hi-IN": {
"pin": false,
@ -852,7 +852,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"hr": {
"pin": false,
@ -871,7 +871,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"hsb": {
"pin": false,
@ -890,7 +890,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"hu": {
"pin": false,
@ -909,7 +909,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"hy-AM": {
"pin": false,
@ -928,7 +928,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"hye": {
"pin": false,
@ -947,7 +947,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ia": {
"pin": false,
@ -966,7 +966,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"id": {
"pin": false,
@ -985,7 +985,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"is": {
"pin": false,
@ -1004,7 +1004,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"it": {
"pin": false,
@ -1023,7 +1023,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ja": {
"pin": false,
@ -1040,7 +1040,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ja-JP-mac": {
"pin": false,
@ -1048,7 +1048,7 @@
"macosx64",
"macosx64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ka": {
"pin": false,
@ -1067,7 +1067,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"kab": {
"pin": false,
@ -1086,7 +1086,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"kk": {
"pin": false,
@ -1105,7 +1105,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"km": {
"pin": false,
@ -1124,7 +1124,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"kn": {
"pin": false,
@ -1143,7 +1143,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ko": {
"pin": false,
@ -1162,7 +1162,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"lij": {
"pin": false,
@ -1181,7 +1181,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"lo": {
"pin": false,
@ -1200,7 +1200,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"lt": {
"pin": false,
@ -1219,7 +1219,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ltg": {
"pin": false,
@ -1238,7 +1238,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"lv": {
"pin": false,
@ -1257,7 +1257,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"meh": {
"pin": false,
@ -1276,7 +1276,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"mk": {
"pin": false,
@ -1295,7 +1295,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"mr": {
"pin": false,
@ -1314,7 +1314,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ms": {
"pin": false,
@ -1333,7 +1333,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"my": {
"pin": false,
@ -1352,7 +1352,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"nb-NO": {
"pin": false,
@ -1371,7 +1371,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ne-NP": {
"pin": false,
@ -1390,7 +1390,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"nl": {
"pin": false,
@ -1409,7 +1409,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"nn-NO": {
"pin": false,
@ -1428,7 +1428,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"oc": {
"pin": false,
@ -1447,7 +1447,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"pa-IN": {
"pin": false,
@ -1466,7 +1466,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"pl": {
"pin": false,
@ -1485,7 +1485,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"pt-BR": {
"pin": false,
@ -1504,7 +1504,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"pt-PT": {
"pin": false,
@ -1523,7 +1523,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"rm": {
"pin": false,
@ -1542,7 +1542,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ro": {
"pin": false,
@ -1561,7 +1561,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ru": {
"pin": false,
@ -1580,7 +1580,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"sat": {
"pin": false,
@ -1599,7 +1599,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"sc": {
"pin": false,
@ -1618,7 +1618,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"scn": {
"pin": false,
@ -1637,7 +1637,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"sco": {
"pin": false,
@ -1656,7 +1656,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"si": {
"pin": false,
@ -1675,7 +1675,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"sk": {
"pin": false,
@ -1694,7 +1694,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"skr": {
"pin": false,
@ -1713,7 +1713,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"sl": {
"pin": false,
@ -1732,7 +1732,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"son": {
"pin": false,
@ -1751,7 +1751,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"sq": {
"pin": false,
@ -1770,7 +1770,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"sr": {
"pin": false,
@ -1789,7 +1789,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"sv-SE": {
"pin": false,
@ -1808,7 +1808,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"szl": {
"pin": false,
@ -1827,7 +1827,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ta": {
"pin": false,
@ -1846,7 +1846,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"te": {
"pin": false,
@ -1865,7 +1865,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"tg": {
"pin": false,
@ -1884,7 +1884,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"th": {
"pin": false,
@ -1903,7 +1903,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"tl": {
"pin": false,
@ -1922,7 +1922,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"tr": {
"pin": false,
@ -1941,7 +1941,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"trs": {
"pin": false,
@ -1960,7 +1960,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"uk": {
"pin": false,
@ -1979,7 +1979,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"ur": {
"pin": false,
@ -1998,7 +1998,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"uz": {
"pin": false,
@ -2017,7 +2017,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"vi": {
"pin": false,
@ -2036,7 +2036,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"wo": {
"pin": false,
@ -2055,7 +2055,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"xh": {
"pin": false,
@ -2074,7 +2074,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"zh-CN": {
"pin": false,
@ -2093,7 +2093,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
},
"zh-TW": {
"pin": false,
@ -2112,6 +2112,6 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5d07323c047c56813b10038b39f92828c78d5e8e"
"revision": "b43286e5d630a3009f9a96c86ec327b55d2b1ade"
}
}

View file

@ -74,6 +74,7 @@ const UI_TARGET_ELEMENTS = [
"image",
"radio",
"richlistitem",
"moz-checkbox",
];
// The containers of interactive elements that we care about and their pretty

View file

@ -0,0 +1,268 @@
/* 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/. */
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
export var PopupBlockerObserver = {
handleEvent(aEvent) {
if (aEvent.type === "DOMUpdateBlockedPopups") {
this.onDOMUpdateBlockedPopups(aEvent);
}
},
async onDOMUpdateBlockedPopups(aEvent) {
let window = aEvent.originalTarget.ownerGlobal;
let { gBrowser, gPermissionPanel } = window;
if (aEvent.originalTarget != gBrowser.selectedBrowser) {
return;
}
gPermissionPanel.refreshPermissionIcons();
let popupCount =
gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount();
if (!popupCount) {
// Hide the notification box (if it's visible).
let notificationBox = gBrowser.getNotificationBox();
let notification =
notificationBox.getNotificationWithValue("popup-blocked");
if (notification) {
notificationBox.removeNotification(notification, false);
}
return;
}
// Only show the notification again if we've not already shown it. Since
// notifications are per-browser, we don't need to worry about re-adding
// it.
if (gBrowser.selectedBrowser.popupBlocker.shouldShowNotification) {
if (Services.prefs.getBoolPref("privacy.popups.showBrowserMessage")) {
const label = {
"l10n-id":
popupCount < this.maxReportedPopups
? "popup-warning-message"
: "popup-warning-exceeded-message",
"l10n-args": { popupCount },
};
let notificationBox = gBrowser.getNotificationBox();
let notification =
notificationBox.getNotificationWithValue("popup-blocked") ||
(await this.notificationPromise);
if (notification) {
notification.label = label;
} else {
const image = "chrome://browser/skin/notification-icons/popup.svg";
const priority = notificationBox.PRIORITY_INFO_MEDIUM;
try {
this.notificationPromise = notificationBox.appendNotification(
"popup-blocked",
{ label, image, priority },
[
{
"l10n-id": "popup-warning-button",
popup: "blockedPopupOptions",
callback: null,
},
]
);
await this.notificationPromise;
} catch (err) {
console.warn(err);
} finally {
this.notificationPromise = null;
}
}
}
// Record the fact that we've reported this blocked popup, so we don't
// show it again.
gBrowser.selectedBrowser.popupBlocker.didShowNotification();
}
},
toggleAllowPopupsForSite(aEvent) {
let window = aEvent.originalTarget.ownerGlobal;
let { gBrowser } = window;
var pm = Services.perms;
var shouldBlock = aEvent.target.getAttribute("block") == "true";
var perm = shouldBlock ? pm.DENY_ACTION : pm.ALLOW_ACTION;
pm.addFromPrincipal(gBrowser.contentPrincipal, "popup", perm);
if (!shouldBlock) {
gBrowser.selectedBrowser.popupBlocker.unblockAllPopups();
}
gBrowser.getNotificationBox().removeCurrentNotification();
},
fillPopupList(aEvent) {
let window = aEvent.originalTarget.ownerGlobal;
let { gBrowser, document } = window;
// XXXben - rather than using |currentURI| here, which breaks down on multi-framed sites
// we should really walk the blockedPopups and create a list of "allow for <host>"
// menuitems for the common subset of hosts present in the report, this will
// make us frame-safe.
//
// XXXjst - Note that when this is fixed to work with multi-framed sites,
// also back out the fix for bug 343772 where
// nsGlobalWindow::CheckOpenAllow() was changed to also
// check if the top window's location is allow-listed.
let browser = gBrowser.selectedBrowser;
var uriOrPrincipal = browser.contentPrincipal.isContentPrincipal
? browser.contentPrincipal
: browser.currentURI;
var blockedPopupAllowSite = document.getElementById(
"blockedPopupAllowSite"
);
try {
blockedPopupAllowSite.removeAttribute("hidden");
let uriHost = uriOrPrincipal.asciiHost
? uriOrPrincipal.host
: uriOrPrincipal.spec;
var pm = Services.perms;
if (
pm.testPermissionFromPrincipal(browser.contentPrincipal, "popup") ==
pm.ALLOW_ACTION
) {
// Offer an item to block popups for this site, if an allow-list entry exists
// already for it.
document.l10n.setAttributes(
blockedPopupAllowSite,
"popups-infobar-block",
{ uriHost }
);
blockedPopupAllowSite.setAttribute("block", "true");
} else {
// Offer an item to allow popups for this site
document.l10n.setAttributes(
blockedPopupAllowSite,
"popups-infobar-allow",
{ uriHost }
);
blockedPopupAllowSite.removeAttribute("block");
}
} catch (e) {
blockedPopupAllowSite.hidden = true;
}
let blockedPopupDontShowMessage = document.getElementById(
"blockedPopupDontShowMessage"
);
let showMessage = Services.prefs.getBoolPref(
"privacy.popups.showBrowserMessage"
);
blockedPopupDontShowMessage.setAttribute("checked", !showMessage);
let blockedPopupsSeparator = document.getElementById(
"blockedPopupsSeparator"
);
blockedPopupsSeparator.hidden = true;
browser.popupBlocker.getBlockedPopups().then(blockedPopups => {
let foundUsablePopupURI = false;
if (blockedPopups) {
for (let i = 0; i < blockedPopups.length; i++) {
let blockedPopup = blockedPopups[i];
// popupWindowURI will be null if the file picker popup is blocked.
// xxxdz this should make the option say "Show file picker" and do it (Bug 590306)
if (!blockedPopup.popupWindowURISpec) {
continue;
}
var popupURIspec = blockedPopup.popupWindowURISpec;
// Sometimes the popup URI that we get back from the blockedPopup
// isn't useful (for instance, netscape.com's popup URI ends up
// being "http://www.netscape.com", which isn't really the URI of
// the popup they're trying to show). This isn't going to be
// useful to the user, so we won't create a menu item for it.
if (
popupURIspec == "" ||
popupURIspec == "about:blank" ||
popupURIspec == "<self>" ||
popupURIspec == uriOrPrincipal.spec
) {
continue;
}
// Because of the short-circuit above, we may end up in a situation
// in which we don't have any usable popup addresses to show in
// the menu, and therefore we shouldn't show the separator. However,
// since we got past the short-circuit, we must've found at least
// one usable popup URI and thus we'll turn on the separator later.
foundUsablePopupURI = true;
var menuitem = document.createXULElement("menuitem");
document.l10n.setAttributes(menuitem, "popup-show-popup-menuitem", {
popupURI: popupURIspec,
});
menuitem.setAttribute("popupReportIndex", i);
menuitem.setAttribute(
"popupInnerWindowId",
blockedPopup.innerWindowId
);
menuitem.browsingContext = blockedPopup.browsingContext;
menuitem.popupReportBrowser = browser;
aEvent.target.appendChild(menuitem);
}
}
// Show the separator if we added any
// showable popup addresses to the menu.
if (foundUsablePopupURI) {
blockedPopupsSeparator.removeAttribute("hidden");
}
}, null);
},
onPopupHiding(aEvent) {
let item = aEvent.target.lastElementChild;
while (item && item.id != "blockedPopupsSeparator") {
let next = item.previousElementSibling;
item.remove();
item = next;
}
},
showBlockedPopup(aEvent) {
let target = aEvent.target;
let browsingContext = target.browsingContext;
let innerWindowId = target.getAttribute("popupInnerWindowId");
let popupReportIndex = target.getAttribute("popupReportIndex");
let browser = target.popupReportBrowser;
browser.popupBlocker.unblockPopup(
browsingContext,
innerWindowId,
popupReportIndex
);
},
editPopupSettings(aEvent) {
let window = aEvent.originalTarget.ownerGlobal;
let { openPreferences } = window;
openPreferences("privacy-permissions-block-popups");
},
dontShowMessage(aEvent) {
let window = aEvent.originalTarget.ownerGlobal;
let { gBrowser } = window;
var showMessage = Services.prefs.getBoolPref(
"privacy.popups.showBrowserMessage"
);
Services.prefs.setBoolPref(
"privacy.popups.showBrowserMessage",
!showMessage
);
gBrowser.getNotificationBox().removeCurrentNotification();
},
};
XPCOMUtils.defineLazyPreferenceGetter(
PopupBlockerObserver,
"maxReportedPopups",
"privacy.popups.maxReported"
);

View file

@ -129,6 +129,7 @@ EXTRA_JS_MODULES += [
"PageActions.sys.mjs",
"PartnerLinkAttribution.sys.mjs",
"PermissionUI.sys.mjs",
"PopupBlockerObserver.sys.mjs",
"ProcessHangMonitor.sys.mjs",
"Sanitizer.sys.mjs",
"SelectionChangedMenulist.sys.mjs",

View file

@ -25,7 +25,7 @@ buildscript {
dependencies {
classpath 'org.mozilla.apilint:apilint:0.5.3'
classpath 'com.android.tools.build:gradle:8.0.2' // Bug 1881001 for using AC version
classpath ComponentsDependencies.tools_androidgradle
classpath 'org.apache.commons:commons-exec:1.3'
classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.25.0'
classpath 'org.tomlj:tomlj:1.1.0'

View file

@ -39279,6 +39279,9 @@ Please specify the "importAttributesKeyword" generator option, whose value can b
}
if (libExports$2.isThisExpression(node)) {
if (expression.startsWith("[")) {
return `this${expression}`;
}
return `this.${expression}`;
}

View file

@ -375,10 +375,6 @@ class DebuggerPanel {
destroy() {
this.panelWin.Debugger.destroy();
this.emit("destroyed");
this.panelWin.L10N = null;
this.panelWin.sourceMapURLService = null;
this.panelWin = null;
this.commands = null;
}
}

View file

@ -188,6 +188,9 @@ function getMemberSnippet(node, expression = "", optional = false) {
}
if (t.isThisExpression(node)) {
if (expression.startsWith("[")) {
return `this${expression}`;
}
return `this.${expression}`;
}

View file

@ -75,6 +75,35 @@ add_task(async function () {
{ line: 84, column: 16, expression: "boom", result: `0` },
]);
await testPreviews(dbg, "thisProperties", [
{ line: 96, column: 13, expression: "myProperty", result: "Object" },
{ line: 96, column: 23, expression: "x", result: "this-myProperty-x" },
{
line: 98,
column: 13,
expression: "propertyName",
result: "myProperty",
},
{
line: 98,
column: 26,
expression: "y",
result: "this-myProperty-y",
},
{
line: 99,
column: 14,
expression: "propertyName",
result: "myProperty",
},
{
line: 99,
column: 28,
expression: "z",
result: "this-myProperty-z",
},
]);
await testHoveringInvalidTargetTokens(dbg);
info(

View file

@ -83,4 +83,21 @@ function multipleTokens() {
foo.bar.baz;
foo || blip.boom;
debugger;
}
function thisProperties() {
new(class {
constructor() {
this.myProperty = {
x: "this-myProperty-x",
y: "this-myProperty-y",
z: "this-myProperty-z",
};
this.myProperty.x;
const propertyName = "myProperty";
this[propertyName].y;
this?.[propertyName].z;
debugger;
}
});
}

View file

@ -55,22 +55,24 @@ loader.lazyRequireGetter(
* "reparented" when the node (or one of its parents) is moved under
* a different node
*/
function Selection() {
EventEmitter.decorate(this);
class Selection extends EventEmitter {
constructor() {
super();
this.setNodeFront = this.setNodeFront.bind(this);
}
#nodeFront;
// The WalkerFront is dynamic and is always set to the selected NodeFront's WalkerFront.
this._walker = null;
#walker = null;
// A single node front can be represented twice on the client when the node is a slotted
// element. It will be displayed once as a direct child of the host element, and once as
// a child of a slot in the "shadow DOM". The latter is called the slotted version.
this._isSlotted = false;
#isSlotted = false;
this._onMutations = this._onMutations.bind(this);
this.setNodeFront = this.setNodeFront.bind(this);
}
Selection.prototype = {
_onMutations(mutations) {
#onMutations = mutations => {
let attributeChange = false;
let pseudoChange = false;
let detached = false;
@ -111,44 +113,44 @@ Selection.prototype = {
if (detached) {
this.emit("detached-front", detachedNodeParent);
}
},
};
destroy() {
this.setWalker();
this._nodeFront = null;
},
this.#nodeFront = null;
}
/**
* @param {WalkerFront|null} walker
*/
setWalker(walker = null) {
if (this._walker) {
this._removeWalkerFrontEventListeners(this._walker);
if (this.#walker) {
this.#removeWalkerFrontEventListeners(this.#walker);
}
this._walker = walker;
if (this._walker) {
this._setWalkerFrontEventListeners(this._walker);
this.#walker = walker;
if (this.#walker) {
this.#setWalkerFrontEventListeners(this.#walker);
}
},
}
/**
* Set event listeners on the passed walker front
*
* @param {WalkerFront} walker
*/
_setWalkerFrontEventListeners(walker) {
walker.on("mutations", this._onMutations);
},
#setWalkerFrontEventListeners(walker) {
walker.on("mutations", this.#onMutations);
}
/**
* Remove event listeners we previously set on walker front
*
* @param {WalkerFront} walker
*/
_removeWalkerFrontEventListeners(walker) {
walker.off("mutations", this._onMutations);
},
#removeWalkerFrontEventListeners(walker) {
walker.off("mutations", this.#onMutations);
}
/**
* Called when a target front is destroyed.
@ -161,14 +163,14 @@ Selection.prototype = {
// event so consumers can act accordingly (e.g. in the inspector, another node will be
// selected)
if (
this._walker &&
this.#walker &&
!targetFront.isTopLevel &&
this._walker.targetFront == targetFront
this.#walker.targetFront == targetFront
) {
this._removeWalkerFrontEventListeners(this._walker);
this.#removeWalkerFrontEventListeners(this.#walker);
this.emit("detached-front");
}
},
}
/**
* Update the currently selected node-front.
@ -190,7 +192,7 @@ Selection.prototype = {
nodeFront = parentNode;
}
if (this._nodeFront == null && nodeFront == null) {
if (this.#nodeFront == null && nodeFront == null) {
// Avoid to notify multiple "unselected" events with a null/undefined nodeFront
// (e.g. once when the webpage start to navigate away from the current webpage,
// and then again while the new page is being loaded).
@ -199,8 +201,8 @@ Selection.prototype = {
this.emit("node-front-will-unset");
this._isSlotted = isSlotted;
this._nodeFront = nodeFront;
this.#isSlotted = isSlotted;
this.#nodeFront = nodeFront;
if (nodeFront) {
this.setWalker(nodeFront.walkerFront);
@ -209,51 +211,51 @@ Selection.prototype = {
}
this.emit("new-node-front", nodeFront, this.reason);
},
}
get nodeFront() {
return this._nodeFront;
},
return this.#nodeFront;
}
isRoot() {
return (
this.isNode() && this.isConnected() && this._nodeFront.isDocumentElement
this.isNode() && this.isConnected() && this.#nodeFront.isDocumentElement
);
},
}
isNode() {
return !!this._nodeFront;
},
return !!this.#nodeFront;
}
isConnected() {
let node = this._nodeFront;
let node = this.#nodeFront;
if (!node || node.isDestroyed()) {
return false;
}
while (node) {
if (node === this._walker.rootNode) {
if (node === this.#walker.rootNode) {
return true;
}
node = node.parentOrHost();
}
return false;
},
}
isHTMLNode() {
const xhtmlNs = "http://www.w3.org/1999/xhtml";
return this.isNode() && this.nodeFront.namespaceURI == xhtmlNs;
},
}
isSVGNode() {
const svgNs = "http://www.w3.org/2000/svg";
return this.isNode() && this.nodeFront.namespaceURI == svgNs;
},
}
isMathMLNode() {
const mathmlNs = "http://www.w3.org/1998/Math/MathML";
return this.isNode() && this.nodeFront.namespaceURI == mathmlNs;
},
}
// Node type
@ -261,65 +263,65 @@ Selection.prototype = {
return (
this.isNode() && this.nodeFront.nodeType == nodeConstants.ELEMENT_NODE
);
},
}
isPseudoElementNode() {
return this.isNode() && this.nodeFront.isPseudoElement;
},
}
isAnonymousNode() {
return this.isNode() && this.nodeFront.isAnonymous;
},
}
isAttributeNode() {
return (
this.isNode() && this.nodeFront.nodeType == nodeConstants.ATTRIBUTE_NODE
);
},
}
isTextNode() {
return this.isNode() && this.nodeFront.nodeType == nodeConstants.TEXT_NODE;
},
}
isCDATANode() {
return (
this.isNode() &&
this.nodeFront.nodeType == nodeConstants.CDATA_SECTION_NODE
);
},
}
isEntityRefNode() {
return (
this.isNode() &&
this.nodeFront.nodeType == nodeConstants.ENTITY_REFERENCE_NODE
);
},
}
isEntityNode() {
return (
this.isNode() && this.nodeFront.nodeType == nodeConstants.ENTITY_NODE
);
},
}
isProcessingInstructionNode() {
return (
this.isNode() &&
this.nodeFront.nodeType == nodeConstants.PROCESSING_INSTRUCTION_NODE
);
},
}
isCommentNode() {
return (
this.isNode() &&
this.nodeFront.nodeType == nodeConstants.PROCESSING_INSTRUCTION_NODE
);
},
}
isDocumentNode() {
return (
this.isNode() && this.nodeFront.nodeType == nodeConstants.DOCUMENT_NODE
);
},
}
/**
* @returns true if the selection is the <body> HTML element.
@ -330,7 +332,7 @@ Selection.prototype = {
this.isConnected() &&
this.nodeFront.nodeName === "BODY"
);
},
}
/**
* @returns true if the selection is the <head> HTML element.
@ -341,35 +343,35 @@ Selection.prototype = {
this.isConnected() &&
this.nodeFront.nodeName === "HEAD"
);
},
}
isDocumentTypeNode() {
return (
this.isNode() &&
this.nodeFront.nodeType == nodeConstants.DOCUMENT_TYPE_NODE
);
},
}
isDocumentFragmentNode() {
return (
this.isNode() &&
this.nodeFront.nodeType == nodeConstants.DOCUMENT_FRAGMENT_NODE
);
},
}
isNotationNode() {
return (
this.isNode() && this.nodeFront.nodeType == nodeConstants.NOTATION_NODE
);
},
}
isSlotted() {
return this._isSlotted;
},
return this.#isSlotted;
}
isShadowRootNode() {
return this.isNode() && this.nodeFront.isShadowRoot;
},
};
}
}
module.exports = Selection;

View file

@ -138,6 +138,11 @@ add_task(async function () {
() => eventTooltipBadge.getAttribute("aria-pressed") === "false"
);
ok(true, "The event tooltip badge is not pressed anymore");
is(
inspector.markup.doc.activeElement,
eventTooltipBadge,
"The event tooltip badge is now focused"
);
// wait for a bit to check the split console wasn't opened
await wait(500);

View file

@ -133,6 +133,7 @@ function TextPropertyEditor(ruleEditor, property) {
this.telemetry = this.toolbox.telemetry;
this._isDragging = false;
this._capturingPointerId = null;
this._hasDragged = false;
this._draggingController = null;
this._draggingValueCache = null;
@ -153,9 +154,9 @@ function TextPropertyEditor(ruleEditor, property) {
this._onValidate = this.ruleView.debounce(this._previewValue, 10, this);
this._onValueDone = this._onValueDone.bind(this);
this._draggingOnMouseDown = this._draggingOnMouseDown.bind(this);
this._draggingOnPointerDown = this._draggingOnPointerDown.bind(this);
this._draggingOnMouseMove = throttle(this._draggingOnMouseMove, 30, this);
this._draggingOnMouseUp = this._draggingOnMouseUp.bind(this);
this._draggingOnPointerUp = this._draggingOnPointerUp.bind(this);
this._draggingOnKeydown = this._draggingOnKeydown.bind(this);
this._create();
@ -394,8 +395,8 @@ TextPropertyEditor.prototype = {
}
});
this.valueSpan.addEventListener("mouseup", () => {
// if we have dragged, we will handle the pending click in _draggingOnMouseUp instead
this.valueSpan.addEventListener("pointerup", () => {
// if we have dragged, we will handle the pending click in _draggingOnPointerUp instead
if (this._hasDragged) {
return;
}
@ -1469,9 +1470,16 @@ TextPropertyEditor.prototype = {
return !!dimensionMatchObj;
},
_draggingOnMouseDown(event) {
_draggingOnPointerDown(event) {
// We want to handle a drag during a mouse button is pressed. So, we can
// ignore pointer events which are caused by other devices.
if (event.pointerType != "mouse") {
return;
}
this._isDragging = true;
this.valueSpan.setPointerCapture(event.pointerId);
this._capturingPointerId = event.pointerId;
this._draggingController = new AbortController();
const { signal } = this._draggingController;
@ -1487,10 +1495,12 @@ TextPropertyEditor.prototype = {
unit,
};
// "pointermove" is fired when the button state is changed too. Therefore,
// we should listen to "mousemove" to handle the pointer position changes.
this.valueSpan.addEventListener("mousemove", this._draggingOnMouseMove, {
signal,
});
this.valueSpan.addEventListener("mouseup", this._draggingOnMouseUp, {
this.valueSpan.addEventListener("pointerup", this._draggingOnPointerUp, {
signal,
});
this.valueSpan.addEventListener("keydown", this._draggingOnKeydown, {
@ -1545,7 +1555,7 @@ TextPropertyEditor.prototype = {
this._hasDragged = true;
},
_draggingOnMouseUp(event) {
_draggingOnPointerUp() {
if (!this._isDragging) {
return;
}
@ -1553,18 +1563,18 @@ TextPropertyEditor.prototype = {
this.committed.value = this.prop.value;
this.prop.setEnabled(true);
}
this._onStopDragging(event);
this._onStopDragging();
},
_draggingOnKeydown(event) {
if (event.key == "Escape") {
this.prop.setValue(this.committed.value, this.committed.priority);
this._onStopDragging(event);
this._onStopDragging();
event.preventDefault();
}
},
_onStopDragging(event) {
_onStopDragging() {
// childHasDragged is used to stop the propagation of a click event when we
// release the mouse in the ruleview.
// The click event is not emitted when we have a pending click on the text property.
@ -1574,7 +1584,15 @@ TextPropertyEditor.prototype = {
this._isDragging = false;
this._hasDragged = false;
this._draggingValueCache = null;
this.valueSpan.releasePointerCapture(event.pointerId);
if (this._capturingPointerId !== null) {
this._capturingPointerId = null;
try {
this.valueSpan.releasePointerCapture(this._capturingPointerId);
} catch (e) {
// Ignore exception even if the pointerId has already been invalidated
// before the capture has already been released implicitly.
}
}
this.valueSpan.classList.remove(IS_DRAGGING_CLASSNAME);
this._draggingController.abort();
},
@ -1588,7 +1606,11 @@ TextPropertyEditor.prototype = {
return;
}
this.valueSpan.classList.add(DRAGGABLE_VALUE_CLASSNAME);
this.valueSpan.addEventListener("mousedown", this._draggingOnMouseDown);
this.valueSpan.addEventListener(
"pointerdown",
this._draggingOnPointerDown,
{ passive: true }
);
},
_removeDraggingCapacity() {
@ -1597,7 +1619,11 @@ TextPropertyEditor.prototype = {
}
this._draggingController = null;
this.valueSpan.classList.remove(DRAGGABLE_VALUE_CLASSNAME);
this.valueSpan.removeEventListener("mousedown", this._draggingOnMouseDown);
this.valueSpan.removeEventListener(
"pointerdown",
this._draggingOnPointerDown,
{ passive: true }
);
},
/**

View file

@ -38,6 +38,12 @@ class Draggable extends Component {
this.mouseY = 0;
}
startDragging(ev) {
// We want to handle a drag during a mouse button is pressed. So, we can
// ignore pointer events which are caused by other devices.
if (ev.pointerType != "mouse") {
return;
}
const xDiff = Math.abs(this.mouseX - ev.clientX);
const yDiff = Math.abs(this.mouseY - ev.clientY);
@ -52,10 +58,16 @@ class Draggable extends Component {
return;
}
this.isDragging = true;
ev.preventDefault();
// "pointermove" is fired when the button state is changed too. Therefore,
// we should listen to "mousemove" to handle the pointer position changes.
this.draggableEl.current.addEventListener("mousemove", this.onMove);
this.draggableEl.current.setPointerCapture(ev.pointerId);
this.draggableEl.current.addEventListener(
"mousedown",
event => event.preventDefault(),
{ once: true }
);
this.props.onStart && this.props.onStart();
}
@ -77,15 +89,17 @@ class Draggable extends Component {
this.props.onMove(ev.clientX, ev.clientY);
}
stopDragging(ev) {
stopDragging() {
if (!this.isDragging) {
return;
}
this.isDragging = false;
ev.preventDefault();
this.draggableEl.current.removeEventListener("mousemove", this.onMove);
this.draggableEl.current.releasePointerCapture(ev.pointerId);
this.draggableEl.current.addEventListener(
"mouseup",
event => event.preventDefault(),
{ once: true }
);
this.props.onStop && this.props.onStop();
}
@ -96,8 +110,8 @@ class Draggable extends Component {
style: this.props.style,
title: this.props.title,
className: this.props.className,
onMouseDown: this.startDragging,
onMouseUp: this.stopDragging,
onPointerDown: this.startDragging,
onPointerUp: this.stopDragging,
onDoubleClick: this.onDoubleClick,
});
}

View file

@ -43,9 +43,14 @@ class LinearEasingFunctionWidget extends EventEmitter {
this.parent = parent;
this.#initMarkup();
this.#svgEl.addEventListener("mousedown", this.#onMouseDown.bind(this), {
signal: this.#abortController.signal,
});
this.#svgEl.addEventListener(
"pointerdown",
this.#onPointerDown.bind(this),
{
signal: this.#abortController.signal,
passive: true,
}
);
this.#svgEl.addEventListener("dblclick", this.#onDoubleClick.bind(this), {
signal: this.#abortController.signal,
});
@ -179,12 +184,15 @@ class LinearEasingFunctionWidget extends EventEmitter {
}
/**
* Handle mousedown event on the svg
* Handle pointerdown event on the svg
*
* @param {MouseEvent} event
* @param {PointerEvent} event
*/
#onMouseDown(event) {
#onPointerDown(event) {
if (
// We want to handle a drag during a mouse button is pressed. So, we can
// ignore pointer events which are caused by other devices.
event.pointerType != "mouse" ||
!event.target.classList.contains(
LinearEasingFunctionWidget.CONTROL_POINTS_CLASSNAME
)
@ -196,14 +204,20 @@ class LinearEasingFunctionWidget extends EventEmitter {
this.#draggedEl.setPointerCapture(event.pointerId);
this.#dragAbortController = new AbortController();
// Note that "pointermove" is also fired when the button state is changed.
// Therefore, we should listen to "mousemove".
this.#draggedEl.addEventListener(
"mousemove",
this.#onMouseMove.bind(this),
{ signal: this.#dragAbortController.signal }
);
this.#draggedEl.addEventListener("mouseup", this.#onMouseUp.bind(this), {
signal: this.#dragAbortController.signal,
});
this.#draggedEl.addEventListener(
"pointerup",
this.#onPointerUp.bind(this),
{
signal: this.#dragAbortController.signal,
}
);
}
/**
@ -255,13 +269,10 @@ class LinearEasingFunctionWidget extends EventEmitter {
}, 20);
/**
* Handle mouseup event on a control point. Only active when there's a control point
* Handle pointerup event on a control point. Only active when there's a control point
* being dragged.
*
* @param {MouseEvent} event
*/
#onMouseUp(event) {
this.#draggedEl.releasePointerCapture(event.pointerId);
#onPointerUp() {
this.#draggedEl = null;
this.#dragAbortController.abort();
this.#dragAbortController = null;

View file

@ -491,7 +491,7 @@ HTMLTooltip.prototype = {
this.container.classList.add("tooltip-visible");
// Keep a pointer on the focused element to refocus it when hiding the tooltip.
this._focusedElement = this.doc.activeElement;
this._focusedElement = anchor.ownerDocument.activeElement;
if (this.doc.defaultView) {
if (!this._pendingEventListenerPromise) {
@ -801,7 +801,8 @@ HTMLTooltip.prototype = {
this.emit("hidden");
const tooltipHasFocus = this.container.contains(this.doc.activeElement);
const tooltipHasFocus =
this.doc.hasFocus() && this.container.contains(this.doc.activeElement);
if (tooltipHasFocus && this._focusedElement) {
this._focusedElement.focus();
this._focusedElement = null;

View file

@ -72,15 +72,19 @@
background-color: var(--badge-interactive-background-color);
color: var(--badge-interactive-color);
cursor: pointer;
&:focus {
outline: var(--theme-focus-outline);
outline-offset: var(--theme-outline-offset);
box-shadow: var(--theme-outline-box-shadow);
}
}
.inspector-badge:not(.active).interactive:focus,
.inspector-badge:not(.active).interactive:hover {
.inspector-badge:not(.active).interactive:is(:focus, :hover) {
background-color: var(--badge-hover-background-color);
}
.inspector-badge.active,
.inspector-badge.interactive.active {
.inspector-badge:is(.active,.interactive.active) {
background-color: var(--badge-active-background-color);
border-color: var(--badge-active-border-color);
color: var(--theme-selection-color);

View file

@ -94,8 +94,7 @@ add_task(async function () {
const node = await waitFor(() => findConsoleAPIMessage(hud, "oi-test"));
const oi = node.querySelector(".tree");
expandObjectInspectorNode(oi);
await waitFor(() => getObjectInspectorNodes(oi).length > 1);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
await testStringGetter(oi);
await testNumberGetter(oi);
@ -379,8 +378,7 @@ async function testObjectGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
checkChildren(node, [`foo: "bar"`, `<prototype>`]);
}
@ -411,8 +409,7 @@ async function testArrayGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
const children = getObjectInspectorChildrenNodes(node);
const firstBucket = children[0];
@ -423,8 +420,7 @@ async function testArrayGetter(oi) {
true,
"The bucket can be expanded"
);
expandObjectInspectorNode(firstBucket);
await waitFor(() => !!getObjectInspectorChildrenNodes(firstBucket).length);
await expandObjectInspectorNode(firstBucket);
checkChildren(
firstBucket,
Array.from({ length: 100 }, (_, i) => `${i}: ${i}`)
@ -456,18 +452,15 @@ async function testMapGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
checkChildren(node, [`size`, `<entries>`, `<prototype>`]);
const entriesNode = findObjectInspectorNode(oi, "<entries>");
expandObjectInspectorNode(entriesNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(entriesNode).length);
await expandObjectInspectorNode(entriesNode);
checkChildren(entriesNode, [`foo → Object { bar: "baz" }`]);
const entryNode = getObjectInspectorChildrenNodes(entriesNode)[0];
expandObjectInspectorNode(entryNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(entryNode).length);
await expandObjectInspectorNode(entryNode);
checkChildren(entryNode, [`<key>: "foo"`, `<value>: Object { bar: "baz" }`]);
}
@ -496,18 +489,15 @@ async function testProxyGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
checkChildren(node, [`<target>`, `<handler>`]);
const targetNode = findObjectInspectorNode(oi, "<target>");
expandObjectInspectorNode(targetNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(targetNode).length);
await expandObjectInspectorNode(targetNode);
checkChildren(targetNode, [`a: 1`, `<prototype>`]);
const handlerNode = findObjectInspectorNode(oi, "<handler>");
expandObjectInspectorNode(handlerNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(handlerNode).length);
await expandObjectInspectorNode(handlerNode);
checkChildren(handlerNode, [`get:`, `<prototype>`]);
}
@ -536,8 +526,7 @@ async function testThrowingGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
checkChildren(node, [
`columnNumber`,
`fileName`,
@ -571,7 +560,7 @@ async function testLongStringGetter(oi, longString) {
"The node can be expanded"
);
expandObjectInspectorNode(getLongStringNode());
await expandObjectInspectorNode(getLongStringNode());
await waitFor(() =>
getLongStringNode().textContent.includes(
`myLongStringGetter: "${longString}"`

View file

@ -136,18 +136,7 @@ function testInputRelatedElementsAreNotVisibile(hud) {
}
async function testObjectInspectorPropertiesAreSet(objInspector) {
const onMutation = waitForNodeMutation(objInspector, {
childList: true,
});
const arrow = objInspector.querySelector(".theme-twisty");
arrow.click();
await onMutation;
ok(
arrow.classList.contains("open"),
"The arrow of the root node of the tree is expanded after clicking on it"
);
await expandObjectInspectorNode(objInspector.querySelector(".tree-node"));
const nameNode = objInspector.querySelector(
".node:not(.lessen) .object-label"

View file

@ -19,9 +19,7 @@ add_task(async function () {
const node = await waitFor(() => findConsoleAPIMessage(hud, "oi-test"));
info("Expand the MouseEvent object");
const oi = node.querySelector(".tree");
expandObjectInspectorNode(oi);
await waitFor(() => getObjectInspectorNodes(oi).length > 1);
await expandObjectInspectorNode(node.querySelector(".tree .tree-node"));
info("Wait for a bit so any warning message could be displayed");
await wait(1000);

View file

@ -53,16 +53,7 @@ add_task(async function () {
ok(true, "The object was rendered in an ObjectInspector");
info("Expanding the object");
const onOiExpanded = waitFor(() => {
return oi.querySelectorAll(".node").length === 3;
});
oi.querySelector(".theme-twisty").click();
await onOiExpanded;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"Object expanded"
);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
// The object inspector now looks like:
// {...}

View file

@ -47,7 +47,7 @@ add_task(async function () {
const [oi1, oi2, oi3] = objectInspectors;
info("Expanding the first object inspector");
await expandObjectInspector(oi1);
await expandObjectInspectorNode(oi1.querySelector(".tree-node"));
// The first object inspector now looks like:
// ▼ {…}
@ -61,7 +61,7 @@ add_task(async function () {
ok(oi1.textContent.includes('hello: "world!"'), "Expected content");
info("Expanding the second object inspector");
await expandObjectInspector(oi2);
await expandObjectInspectorNode(oi2.querySelector(".tree-node"));
// The second object inspector now looks like:
// ▼ func()
@ -123,12 +123,3 @@ add_task(async function () {
ok(true, "Inspector selected and new node got selected");
is(inspectorSelectedNodeFront.id, "testEl", "The expected node was selected");
});
function expandObjectInspector(oi) {
const onMutation = waitForNodeMutation(oi, {
childList: true,
});
oi.querySelector(".theme-twisty").click();
return onMutation;
}

View file

@ -30,33 +30,9 @@ add_task(async function () {
const [arrayOi, objectOi] = objectInspectors;
let arrayOiArrowButton = arrayOi.querySelector(".theme-twisty");
is(
arrayOiArrowButton.getAttribute("title"),
"Expand",
"Toggle button has expected title when node is collapsed"
);
await expandObjectInspectorNode(arrayOi.querySelector(".tree-node"));
info("Expanding the array object inspector");
let onArrayOiMutation = waitForNodeMutation(arrayOi, {
childList: true,
});
arrayOiArrowButton.click();
await onArrayOiMutation;
arrayOiArrowButton = arrayOi.querySelector(".theme-twisty");
ok(
arrayOi.querySelector(".theme-twisty").classList.contains("open"),
"Toggle button of the root node of the tree is expanded after clicking on it"
);
is(
arrayOiArrowButton.getAttribute("title"),
"Collapse",
"Toggle button has expected title when node is expanded"
);
let arrayOiNodes = arrayOi.querySelectorAll(".node");
let arrayOiNodes = arrayOi.querySelectorAll(".tree-node");
// The object inspector now looks like:
// ▼ […]
@ -73,19 +49,7 @@ add_task(async function () {
info("Expanding a leaf of the array object inspector");
let arrayOiNestedObject = arrayOiNodes[3];
onArrayOiMutation = waitForNodeMutation(arrayOi, {
childList: true,
});
arrayOiNestedObject.querySelector(".theme-twisty").click();
await onArrayOiMutation;
ok(
arrayOiNestedObject
.querySelector(".theme-twisty")
.classList.contains("open"),
"The arrow of the root node of the tree is expanded after clicking on it"
);
await expandObjectInspectorNode(arrayOiNestedObject);
arrayOiNodes = arrayOi.querySelectorAll(".node");
@ -106,10 +70,11 @@ add_task(async function () {
);
info("Collapsing the root");
onArrayOiMutation = waitForNodeMutation(arrayOi, {
const onArrayOiMutation = waitForNodeMutation(arrayOi, {
childList: true,
});
arrayOi.querySelector(".theme-twisty").click();
await onArrayOiMutation;
is(
arrayOi.querySelector(".theme-twisty").classList.contains("open"),
@ -121,15 +86,7 @@ add_task(async function () {
is(arrayOiNodes.length, 1, "Only the root node is visible");
info("Expanding the root again");
onArrayOiMutation = waitForNodeMutation(arrayOi, {
childList: true,
});
arrayOi.querySelector(".theme-twisty").click();
ok(
arrayOi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the root node of the tree is expanded again after clicking on it"
);
await expandObjectInspectorNode(arrayOi.querySelector(".tree-node"));
arrayOiNodes = arrayOi.querySelectorAll(".node");
arrayOiNestedObject = arrayOiNodes[3];
@ -146,17 +103,7 @@ add_task(async function () {
"There is the expected number of nodes in the tree"
);
const onObjectOiMutation = waitForNodeMutation(objectOi, {
childList: true,
});
objectOi.querySelector(".theme-twisty").click();
await onObjectOiMutation;
ok(
objectOi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the root node of the tree is expanded after clicking on it"
);
await expandObjectInspectorNode(objectOi.querySelector(".tree-node"));
const objectOiNodes = objectOi.querySelectorAll(".node");
// The object inspector now looks like:

View file

@ -36,8 +36,7 @@ add_task(async function () {
"Elements with getter/setter should be shown correctly"
);
expandObjectInspectorNode(oi);
await waitFor(() => getObjectInspectorNodes(oi).length > 1);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
await testGetter(oi, "0");
await testSetterOnly(oi, "1");

View file

@ -148,48 +148,29 @@ add_task(async function () {
async function testSmallMap(oi) {
info("Expanding the Map");
let onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onMapOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(entriesNode);
entriesNode.querySelector(".theme-twisty").click();
await onMapOiMutation;
oiNodes = oi.querySelectorAll(".node");
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 6 nodes, the 4 original ones, and the 2 entries.
is(oiNodes.length, 6, "There is the expected number of nodes in the tree");
info("Expand first entry");
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oiNodes[3].querySelector(".theme-twisty").click();
await onMapOiMutation;
await expandObjectInspectorNode(oiNodes[3]);
oiNodes = oi.querySelectorAll(".node");
oiNodes = oi.querySelectorAll(".tree-node");
/*
* Map (2)
* | size: 2
@ -203,13 +184,9 @@ async function testSmallMap(oi) {
is(oiNodes.length, 8, "There is the expected number of nodes in the tree");
info("Expand <key> for first entry");
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oiNodes[4].querySelector(".theme-twisty").click();
await onMapOiMutation;
await expandObjectInspectorNode(oiNodes[4]);
oiNodes = oi.querySelectorAll(".node");
oiNodes = oi.querySelectorAll(".tree-node");
/*
* Map (2)
* | size: 2
@ -225,84 +202,50 @@ async function testSmallMap(oi) {
is(oiNodes.length, 10, "There is the expected number of nodes in the tree");
info("Expand <value> for first entry");
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oiNodes[7].querySelector(".theme-twisty").click();
await onMapOiMutation;
await expandObjectInspectorNode(oiNodes[7]);
oiNodes = oi.querySelectorAll(".node");
oiNodes = oi.querySelectorAll(".tree-node");
Assert.greater(oiNodes.length, 10, "The document node was expanded");
}
async function testMap(oi) {
info("Expanding the Map");
let onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onMapOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(entriesNode);
entriesNode.querySelector(".theme-twisty").click();
await onMapOiMutation;
oiNodes = oi.querySelectorAll(".node");
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 24 nodes, the 4 original ones, and the 20 entries.
is(oiNodes.length, 24, "There is the expected number of nodes in the tree");
}
async function testLargeMap(oi) {
info("Expanding the large map");
let onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onMapOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onMapOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 8 nodes, the 4 original ones, and the 4 buckets.
@ -315,46 +258,27 @@ async function testLargeMap(oi) {
async function testSmallSet(oi) {
info("Expanding the Set");
let onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onMapOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(entriesNode);
entriesNode.querySelector(".theme-twisty").click();
await onMapOiMutation;
oiNodes = oi.querySelectorAll(".node");
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 6 nodes, the 4 original ones, and the 2 entries.
is(oiNodes.length, 6, "There is the expected number of nodes in the tree");
info("Expand first entry");
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oiNodes[3].querySelector(".theme-twisty").click();
await onMapOiMutation;
await expandObjectInspectorNode(oiNodes[3]);
oiNodes = oi.querySelectorAll(".node");
/*
@ -372,35 +296,20 @@ async function testSmallSet(oi) {
async function testSet(oi) {
info("Expanding the Set");
let onSetOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onSetOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the Set");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
onSetOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onSetOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 24 nodes, the 4 original ones, and the 20 entries.
@ -409,35 +318,20 @@ async function testSet(oi) {
async function testLargeSet(oi) {
info("Expanding the large Set");
let onSetOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onSetOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the Set");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
onSetOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onSetOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 7 nodes, the 4 original ones, and the 3 buckets.
@ -455,36 +349,21 @@ async function testUrlSearchParams(oi) {
);
info("Expanding the URLSearchParams");
let onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the URLSearchParams");
onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 14 nodes, the 4 original ones, and the 11 entries.
@ -530,36 +409,21 @@ async function testHeaders(oi) {
);
info("Expanding the Headers");
let onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 3 nodes: the root, entries and the proto.
is(oiNodes.length, 3, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[1];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the Headers");
onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 6 nodes, the 3 original ones, and the 3 entries.
@ -582,36 +446,21 @@ async function testFormData(oi) {
);
info("Expanding the FormData");
let onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 3 nodes: the root, entries and the proto.
is(oiNodes.length, 3, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[1];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the FormData");
onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 6 nodes, the 3 original ones, and the 3 entries.
@ -643,36 +492,21 @@ async function testMidiInputs(oi, midiInputs) {
);
info("Expanding the MIDIInputMap");
let onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the MIDIInputMap");
onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 5 nodes, the 4 original ones, and the entry.
@ -693,36 +527,21 @@ async function testMidiOutputs(oi, midiOutputs) {
);
info("Expanding the MIDIOutputMap");
let onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the MIDIOutputMap");
onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 7 nodes, the 4 original ones, and the 3 entries.
@ -753,80 +572,61 @@ async function testHighlightsRegistry(oi) {
);
info("Expanding the HighlightRegistry");
let onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the HighlightRegistry");
onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(entriesNode);
entriesNode.querySelector(".theme-twisty").click();
await onOiMutation;
oiNodes = oi.querySelectorAll(".node");
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 7 nodes, the 4 original ones, and the 3 entries.
is(oiNodes.length, 7, "There is the expected number of nodes in the tree");
is(
oiNodes[3].textContent,
oiNodes[3].querySelector(".node").textContent,
`0: search → Highlight { priority: 0, type: "highlight", size: 0 }`,
"First entry is displayed as expected"
);
is(
oiNodes[4].textContent,
oiNodes[4].querySelector(".node").textContent,
`1: glow → Highlight { priority: 0, type: "highlight", size: 0 }`,
`Second entry is displayed as expected`
);
is(
oiNodes[5].textContent,
oiNodes[5].querySelector(".node").textContent,
`2: anchor → Highlight { priority: 0, type: "highlight", size: 0 }`,
`Third entry entry is displayed as expected`
);
info("Expand last entry");
onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oiNodes[5].querySelector(".theme-twisty").click();
await onOiMutation;
await expandObjectInspectorNode(oiNodes[5]);
oiNodes = oi.querySelectorAll(".node");
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 9 nodes, the 7 original ones, <key> and <value>
is(oiNodes.length, 9, "There is the expected number of nodes in the tree");
is(oiNodes[6].textContent, `<key>: "anchor"`, `Got expected key node`);
is(
oiNodes[7].textContent,
oiNodes[6].querySelector(".node").textContent,
`<key>: "anchor"`,
`Got expected key node`
);
is(
oiNodes[7].querySelector(".node").textContent,
`<value>: Highlight { priority: 0, type: "highlight", size: 0 }`,
`Got expected value node`
);
info("Expand Highlight object");
onOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oiNodes[7].querySelector(".theme-twisty").click();
await onOiMutation;
await expandObjectInspectorNode(oiNodes[7]);
oiNodes = oi.querySelectorAll(".node");
// There are now 13 nodes, the 9 previous ones, and all the properties of the Highlight object
@ -847,35 +647,21 @@ async function testHighlightsRegistry(oi) {
async function testCustomStateSet(oi) {
info("Expanding the CustomStateSet");
let onCustomStateSetOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onCustomStateSetOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let oiNodes = oi.querySelectorAll(".node");
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
onCustomStateSetOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onCustomStateSetOiMutation;
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 6 nodes, the 4 original ones, and the 2 entries.

View file

@ -87,8 +87,7 @@ add_task(async function () {
const node = await waitFor(() => findConsoleAPIMessage(hud, "oi-test"));
const oi = node.querySelector(".tree");
expandObjectInspectorNode(oi);
await waitFor(() => getObjectInspectorNodes(oi).length > 1);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
await testStringGetter(oi);
await testNumberGetter(oi);
@ -373,8 +372,7 @@ async function testObjectGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
checkChildren(node, [`foo: "bar"`, `<prototype>`]);
}
@ -405,8 +403,7 @@ async function testArrayGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
const children = getObjectInspectorChildrenNodes(node);
const firstBucket = children[0];
@ -417,8 +414,7 @@ async function testArrayGetter(oi) {
true,
"The bucket can be expanded"
);
expandObjectInspectorNode(firstBucket);
await waitFor(() => !!getObjectInspectorChildrenNodes(firstBucket).length);
await expandObjectInspectorNode(firstBucket);
checkChildren(
firstBucket,
Array.from({ length: 100 }, (_, i) => `${i}: ${i}`)
@ -450,18 +446,15 @@ async function testMapGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
checkChildren(node, [`size`, `<entries>`, `<prototype>`]);
const entriesNode = findObjectInspectorNode(oi, "<entries>");
expandObjectInspectorNode(entriesNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(entriesNode).length);
await expandObjectInspectorNode(entriesNode);
checkChildren(entriesNode, [`foo → Object { bar: "baz" }`]);
const entryNode = getObjectInspectorChildrenNodes(entriesNode)[0];
expandObjectInspectorNode(entryNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(entryNode).length);
await expandObjectInspectorNode(entryNode);
checkChildren(entryNode, [`<key>: "foo"`, `<value>: Object { bar: "baz" }`]);
}
@ -490,18 +483,15 @@ async function testProxyGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
await expandObjectInspectorNode(node);
checkChildren(node, [`<target>`, `<handler>`]);
const targetNode = findObjectInspectorNode(oi, "<target>");
expandObjectInspectorNode(targetNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(targetNode).length);
await expandObjectInspectorNode(targetNode);
checkChildren(targetNode, [`a: 1`, `<prototype>`]);
const handlerNode = findObjectInspectorNode(oi, "<handler>");
expandObjectInspectorNode(handlerNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(handlerNode).length);
await expandObjectInspectorNode(handlerNode);
checkChildren(handlerNode, [`get:`, `<prototype>`]);
}
@ -530,7 +520,7 @@ async function testThrowingGetter(oi) {
);
is(isObjectInspectorNodeExpandable(node), true, "The node can be expanded");
expandObjectInspectorNode(node);
await expandObjectInspectorNode(node);
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
checkChildren(node, [
`columnNumber`,
@ -565,7 +555,7 @@ async function testLongStringGetter(oi, longString) {
"The node can be expanded"
);
expandObjectInspectorNode(getLongStringNode());
await expandObjectInspectorNode(getLongStringNode());
await waitFor(() =>
getLongStringNode().textContent.includes(
`myLongStringGetter: "${longString}"`

View file

@ -68,7 +68,7 @@ add_task(async function () {
});
async function testObject(oi, { myValue, value }) {
expandObjectInspectorNode(oi.querySelector(".tree-node"));
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
const prototypeNode = await waitFor(() =>
findObjectInspectorNode(oi, "<prototype>")
);
@ -95,9 +95,7 @@ async function testObject(oi, { myValue, value }) {
}
async function getValueNode(prototypeNode) {
expandObjectInspectorNode(prototypeNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(prototypeNode).length);
await expandObjectInspectorNode(prototypeNode);
const children = getObjectInspectorChildrenNodes(prototypeNode);
const valueNode = children.find(

View file

@ -49,7 +49,7 @@ add_task(async function () {
async function testObject(oi, values) {
let node = oi.querySelector(".tree-node");
for (const value of values) {
await expand(node);
await expandObjectInspectorNode(node);
if (value != null) {
const getter = findObjectInspectorNodeChild(node, "getter");
await invokeGetter(getter);
@ -62,11 +62,6 @@ async function testObject(oi, values) {
}
}
function expand(node) {
expandObjectInspectorNode(node);
return waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
}
function invokeGetter(node) {
getObjectInspectorInvokeGetterButton(node).click();
return waitFor(() => !getObjectInspectorInvokeGetterButton(node));

View file

@ -43,35 +43,20 @@ async function logMessages(hud) {
async function checkValues(oi, storageType) {
info(`Expanding the ${storageType} object`);
let onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
oi.querySelector(".theme-twisty").click();
await onMapOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
let nodes = oi.querySelectorAll(".node");
let nodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(nodes.length, 5, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = nodes[3];
is(
entriesNode.textContent,
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
entriesNode.querySelector(".theme-twisty").click();
await onMapOiMutation;
await expandObjectInspectorNode(entriesNode);
nodes = oi.querySelectorAll(".node");
// There are now 7 nodes, the 5 original ones, and the 2 entries.

View file

@ -26,13 +26,11 @@ add_task(async function testExpandNestedPromise() {
const oi = node.querySelector(".tree");
const [promiseNode] = getObjectInspectorNodes(oi);
expandObjectInspectorNode(promiseNode);
await waitFor(() => getObjectInspectorNodes(oi).length > 1);
await expandObjectInspectorNode(promiseNode);
checkChildren(promiseNode, [`0`, `<state>`, `<value>`, `<prototype>`]);
const valueNode = findObjectInspectorNode(oi, "<value>");
expandObjectInspectorNode(valueNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(valueNode).length);
await expandObjectInspectorNode(valueNode);
checkChildren(valueNode, [`1`, `<state>`, `<value>`]);
});
@ -58,18 +56,15 @@ add_task(async function testExpandCyclicPromise() {
const oi = node.querySelector(".tree");
const [promiseNode] = getObjectInspectorNodes(oi);
expandObjectInspectorNode(promiseNode);
await waitFor(() => getObjectInspectorNodes(oi).length > 1);
await expandObjectInspectorNode(promiseNode);
checkChildren(promiseNode, [`foo`, `<state>`, `<value>`]);
const valueNode = findObjectInspectorNode(oi, "<value>");
expandObjectInspectorNode(valueNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(valueNode).length);
await expandObjectInspectorNode(valueNode);
checkChildren(valueNode, [`bar`, `<state>`, `<reason>`]);
const reasonNode = findObjectInspectorNode(oi, "<reason>");
expandObjectInspectorNode(reasonNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(reasonNode).length);
await expandObjectInspectorNode(reasonNode);
checkChildren(reasonNode, [`foo`, `<state>`, `<value>`]);
});

View file

@ -23,18 +23,15 @@ add_task(async function () {
const oi = node.querySelector(".tree");
const [proxyNode] = getObjectInspectorNodes(oi);
expandObjectInspectorNode(proxyNode);
await waitFor(() => getObjectInspectorNodes(oi).length > 1);
await expandObjectInspectorNode(proxyNode);
checkChildren(proxyNode, [`<target>`, `<handler>`]);
const targetNode = findObjectInspectorNode(oi, "<target>");
expandObjectInspectorNode(targetNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(targetNode).length);
await expandObjectInspectorNode(targetNode);
checkChildren(targetNode, [`<target>`, `<handler>`]);
const handlerNode = findObjectInspectorNode(oi, "<handler>");
expandObjectInspectorNode(handlerNode);
await waitFor(() => !!getObjectInspectorChildrenNodes(handlerNode).length);
await expandObjectInspectorNode(handlerNode);
checkChildren(handlerNode, [`<target>`, `<handler>`]);
});

View file

@ -62,17 +62,7 @@ add_task(async function () {
const [oi] = objectInspectors;
info("Expanding the Object");
const onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oi.querySelector(".theme-twisty").click();
await onMapOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
const oiNodes = getObjectInspectorNodes(oi);
// The object inspector should look like this:
@ -130,7 +120,7 @@ add_task(async function () {
);
info("Expand public property disguised as private property");
expandObjectInspectorNode(publicDisguisedAsPrivateNodeEl);
await expandObjectInspectorNode(publicDisguisedAsPrivateNodeEl);
const publicPropChildren = await waitFor(() => {
const children = getObjectInspectorChildrenNodes(
publicDisguisedAsPrivateNodeEl
@ -162,7 +152,7 @@ add_task(async function () {
);
info("Expand private property");
expandObjectInspectorNode(privatePropertyNodeEl);
await expandObjectInspectorNode(privatePropertyNodeEl);
const privatePropChildren = await waitFor(() => {
const children = getObjectInspectorChildrenNodes(privatePropertyNodeEl);
if (children.length === 0) {
@ -231,7 +221,7 @@ add_task(async function () {
);
info("Expand private property prototype");
expandObjectInspectorNode(privatePropertyPrototypeEl);
await expandObjectInspectorNode(privatePropertyPrototypeEl);
const privatePropertyPrototypeChildren = await waitFor(() => {
const children = getObjectInspectorChildrenNodes(
privatePropertyPrototypeEl

View file

@ -20,13 +20,7 @@ add_task(async function () {
const node = await waitFor(() => findConsoleAPIMessage(hud, "oi-test"));
const objectInspector = node.querySelector(".tree");
let onOiMutation = waitForNodeMutation(objectInspector, {
childList: true,
});
info("Expanding the object inspector");
objectInspector.querySelector(".theme-twisty").click();
await onOiMutation;
await expandObjectInspectorNode(objectInspector.querySelector(".tree-node"));
const nodes = objectInspector.querySelectorAll(".node");
const lastNode = nodes[nodes.length - 1];
@ -38,7 +32,7 @@ add_task(async function () {
ok(hasVerticalOverflow(outputContainer), "There is a vertical overflow");
const scrollTop = outputContainer.scrollTop;
onOiMutation = waitForNodeMutation(objectInspector, {
const onOiMutation = waitForNodeMutation(objectInspector, {
childList: true,
});

View file

@ -35,17 +35,7 @@ add_task(async function () {
const [oi] = objectInspectors;
info("Expanding the Object");
const onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oi.querySelector(".theme-twisty").click();
await onMapOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
const oiNodes = oi.querySelectorAll(".node");
// The object inspector should look like this:

View file

@ -45,16 +45,7 @@ add_task(async function () {
info("Expanding the array object inspector");
const [oi] = objectInspectors;
const onOiExpanded = waitFor(() => {
return oi.querySelectorAll(".node").length === 3;
});
oi.querySelector(".theme-twisty").click();
await onOiExpanded;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"Object inspector expanded"
);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
// The object inspector now looks like:
// Object { testProp2: "testValue2" }

View file

@ -38,17 +38,7 @@ add_task(async function () {
async function expandOiAndCheckPrimitiveValue(oi, expectedPrimitiveValue) {
info("Expanding the Object");
const onMapOiMutation = waitForNodeMutation(oi, {
childList: true,
});
oi.querySelector(".theme-twisty").click();
await onMapOiMutation;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"The arrow of the node has the expected class after clicking on it"
);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
const primitiveValueNode = [...getObjectInspectorNodes(oi)].find(nodes =>
nodes.textContent.includes("<primitive value>")

View file

@ -101,16 +101,7 @@ add_task(async function () {
ok(true, "The object was rendered in an ObjectInspector");
info("Expanding the object");
const onOiExpanded = waitFor(() => {
return oi.querySelectorAll(".node").length === 3;
});
oi.querySelector(".theme-twisty").click();
await onOiExpanded;
ok(
oi.querySelector(".theme-twisty").classList.contains("open"),
"Object expanded"
);
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
// The object inspector now looks like:
// Object { fav: "eggplant" }

View file

@ -1269,13 +1269,55 @@ async function selectNodeWithPicker(toolbox, selector) {
*
* @param {HTMLElement} node: Object inspector node (.tree-node)
*/
function expandObjectInspectorNode(node) {
async function expandObjectInspectorNode(node) {
if (!node.classList.contains("tree-node")) {
ok(false, "Node should be a .tree-node");
return;
}
const arrow = getObjectInspectorNodeArrow(node);
if (!arrow) {
ok(false, "Node can't be expanded");
return;
}
if (arrow.classList.contains("open")) {
ok(false, "Node already expanded");
return;
}
const isLongString = node.querySelector(".node > .objectBox-string");
let onMutation;
let textContentBeforeExpand;
if (!isLongString) {
const objectInspector = node.closest(".object-inspector");
onMutation = waitForNodeMutation(objectInspector, {
childList: true,
});
} else {
textContentBeforeExpand = node.textContent;
}
arrow.click();
// Long strings are not going to be expanded into children element.
// Instead the tree node will update itself to show the long string.
// So that we can't wait for the childList mutation.
if (isLongString) {
// Reps will expand on click...
await waitFor(() => arrow.classList.contains("open"));
// ...but it will fetch the long string content asynchronously after having expanded the TreeNode.
// So also wait for the string to be updated and be longer.
await waitFor(
() => node.textContent.length > textContentBeforeExpand.length
);
} else {
await onMutation;
// Waiting for the object inspector mutation isn't enough,
// also wait for the children element, with higher aria-level to be added to the DOM.
await waitFor(() => !!getObjectInspectorChildrenNodes(node).length);
}
ok(
arrow.classList.contains("open"),
"The arrow of the root node of the tree is expanded after clicking on it"
);
}
/**
@ -1316,7 +1358,7 @@ function getObjectInspectorNodes(oi) {
* deeper than the passed node)
*/
function getObjectInspectorChildrenNodes(node) {
const getLevel = n => parseInt(n.getAttribute("aria-level"), 10);
const getLevel = n => parseInt(n.getAttribute("aria-level") || "0", 10);
const level = getLevel(node);
const childLevel = level + 1;
const children = [];

View file

@ -73,3 +73,72 @@ Last, but not least, this feature can be used on try via:
```bash
./mach mochitest try fuzzy devtools/test/folder/ --env DEBUG_STEP=true
```
Once you found a problematic line, or want to know more about what happens on a particular line of your mochitest,
you can then use the DEBUG_TRACE_LINE env variable.
It expect a line number of the mochitest file running and it will trace all JavaScript code ran from that line of code.
```bash
DEBUG_TRACE_LINE=42 ./mach mochitest browser_devtools_test.js
```
This will log something like this:
```
0:17.14 GECKO(94170) [STEP] chrome://mochitests/content/browser/devtools/client/webconsole/test/browser/head.js
0:17.14 GECKO(94170) [STEP] ───────────────────────────────────────────────────────────────────────────────────
0:17.14 GECKO(94170) [STEP] 73:36 | async function openNewTabAndConsole↦ (url, clearJstermHistory = true, hostId) {
0:17.15 GECKO(94170) [STEP] 74:19 | const toolbox = ↦ await openNewTabAndToolbox(url, "webconsole", hostId);
0:17.15 GECKO(94170) [STEP]
0:17.15 GECKO(94170) [STEP] chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js
0:17.15 GECKO(94170) [STEP] ──────────────────────────────────────────────────────────────────────────────
0:17.15 GECKO(94170) [STEP] 1273:36 | async function openNewTabAndToolbox↦ (url, toolId, hostType) {
0:17.15 GECKO(94170) [STEP] 1274:15 | const tab = ↦ await addTab(url);
0:17.15 GECKO(94170) [STEP] 531:22 | async function addTab↦ (url, options = {}) {
0:17.15 GECKO(94170) [STEP] 532:3 | ↦ info("Adding a new tab with URL: " + url);
```
where you can see the execution flow between function to functions being called, but also the progress within a function call.
Similarly to DEBUG_STEP, '↦' symbols highlights the precise execution location.
If this helper isn't enough. You can also spawn the tracer from any place manually from any privileged codebase, by using the following snippet:
```js
const { JSTracer } = ChromeUtils.importESModule(
"resource://devtools/server/tracer/tracer.sys.mjs",
{ global: "contextual" }
);
// You have to at least pass an empty object to startTracing,
// otherwise, all the attributes at optional.
JSTracer.startTracing({
// If you want to log a custom string before each trace
prefix: "[my log]",
// Only if you want to restrict to a specific global,
// otherwise it will trace the current global automatically.
global: window,
// If you are about to call code from another global(s),
// this will trace code from all active globals in the current thread.
// (use only if needed)
traceAllGlobals: true,
// Only if you want to step within function execution (this adds lots of additional traces!)
traceSteps: true,
// If you want to restrict traces to one JS file
filterFrameSourceUrl: "foo.js",
// If you want to avoid logging nested trace above a given threshold
maxDepth: 10,
// If you want the tracer to automatically stop after having logged a given amount of traces
maxRecords: 10,
// If you want to log all DOM events fired on the traced global(s)
traceDOMEvents: true,
// If you want to log all DOM Mutations happening in the traced global(s)
traceDOMMutations: ["add", "attributes", "delete"],
});
[...run some JS code...]
JSTracer.stopTracing();
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View file

@ -46,6 +46,19 @@ Logging output
(`:trace --logMethod console`)
* Debugger Sidebar
The JS Tracer will log all JS function calls into the Debugger panel, in the Tracer sidebar.
This involves a user interface dedicated to navigate through all the traces.
You can easily see all the DOM Events triggering JavaScript code, and browser all the stacks displayed
as a tree.
This UI is an under-development prototype and may change significantly or even be dropped in the future.
|image5|
(`:trace --logMethod debugger-sidebar`)
* Profiler record
The JS Tracer will log all JS function calls in the background. When you stop tracing,
@ -86,6 +99,9 @@ Logging output
.. |image4| image:: profiler-trace.png
:class: border
:alt: The JS Traces displayed in the Firefox Profiler UI
.. |image5| image:: debugger-sidebar.png
:class: border
:alt: The JS Traces displayed in the Debugger sidebar
Delayed start
-------------

View file

@ -287,6 +287,7 @@ class NodeActor extends Actor {
characterDataOldValue: true,
childList: true,
subtree: true,
// Track addition/removal of pseudo-elements too
chromeOnlyNodes: true,
});
this.mutationObserver = observer;

View file

@ -347,14 +347,16 @@ class WalkerActor extends Actor {
return "[WalkerActor " + this.actorID + "]";
}
getDocumentWalker(node, skipTo) {
// Allow native anon content (like <video> controls) if preffed on
const filter = this.showAllAnonymousContent
getDocumentWalkerFilter() {
// Allow native anonymous content (like <video> controls) if preffed on
return this.showAllAnonymousContent
? allAnonymousContentTreeWalkerFilter
: standardTreeWalkerFilter;
}
getDocumentWalker(node, skipTo) {
return new DocumentWalker(node, this.rootWin, {
filter,
filter: this.getDocumentWalkerFilter(),
skipTo,
showAnonymousContent: true,
});
@ -899,7 +901,7 @@ class WalkerActor extends Actor {
}
/**
* Returns the raw children of the DOM node, with anon content filtered as needed
* Returns the raw children of the DOM node, with anonymous content filtered as needed
* @param Node rawNode.
* @param boolean includeAssigned
* Whether <slot> assigned children should be returned. See
@ -2199,6 +2201,19 @@ class WalkerActor extends Actor {
* See https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationRecord
*/
onMutations(mutations) {
// Don't send a mutation event if the mutation target would be ignored by the walker
// filter function.
const documentWalkerFilter = this.getDocumentWalkerFilter();
if (
mutations.every(
mutation =>
documentWalkerFilter(mutation.target) ===
nodeFilterConstants.FILTER_SKIP
)
) {
return;
}
// Notify any observers that want *all* mutations (even on nodes that aren't
// referenced). This is not sent over the protocol so can only be used by
// scripts running in the server process.
@ -2325,6 +2340,13 @@ class WalkerActor extends Actor {
*/
onAnonymousrootcreated(event) {
const root = event.target;
// Don't trigger a mutation if the document walker would filter out the element.
const documentWalkerFilter = this.getDocumentWalkerFilter();
if (documentWalkerFilter(root) === nodeFilterConstants.FILTER_SKIP) {
return;
}
const parent = this.rawParentNode(root);
if (!parent) {
// These events are async. The node might have been removed already, in

View file

@ -293,6 +293,12 @@ already_AddRefed<AbortSignal> AbortSignal::Any(
} else {
// Step 4.2. Otherwise, make resultSignal dependent on its source signals
for (const auto& sourceSignal : signal->mSourceSignals) {
if (!sourceSignal) {
// Bug 1908466, sourceSignal might have been garbage collected.
// As signal is not aborted, sourceSignal also wasn't.
// Thus do not depend on it, as it cannot be aborted anymore.
continue;
}
MOZ_ASSERT(!sourceSignal->Aborted() && !sourceSignal->Dependent());
resultSignal->MakeDependentOn(sourceSignal);
}

View file

@ -27,7 +27,8 @@
test(function(t) {
const div = addDiv(t,
{ style: "width: 10px; height: 100px; " +
"animation: animWidth 100s scroll(), animTop 200s;" });
"animation: animWidth 100s, animTop 200s; " +
"animation-timeline: scroll(), auto;"});
// Sanity check to make sure the scroll animation is there.
addDiv(t, { class: "fill-vh" });
@ -50,7 +51,8 @@ test(function(t) {
test(function(t) {
const div = addDiv(t,
{ style: "width: 10px; height: 100px; " +
"animation: animWidth 100s scroll(), animTop 100s;" });
"animation: animWidth 100s, animTop 100s; " +
"animation-timeline: scroll(), auto;"});
// Sanity check to make sure the scroll animation is there.
addDiv(t, { class: "fill-vh" });

View file

@ -3515,6 +3515,27 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
// previous element in the document. So the tabindex on elements
// should be ignored.
ignoreTabIndex = true;
// If selection starts from a focusable and tabbable element, we want
// to make it focused rather than next/previous one.
if (startContent->IsElement() && startContent->GetPrimaryFrame() &&
startContent->GetPrimaryFrame()->IsFocusable().IsTabbable()) {
startContent =
forward ? (startContent->GetPreviousSibling()
? startContent->GetPreviousSibling()
// We don't need to get previous leaf node
// because it may be too far from
// startContent. We just want the previous
// node immediately before startContent.
: startContent->GetParent())
// We want the next node immdiately after startContent.
// Therefore, we don't want its first child.
: startContent->GetNextNonChildNode();
// If we reached the root element, we should treat it as there is no
// selection as same as above.
if (startContent == rootElement) {
startContent = nullptr;
}
}
}
}

View file

@ -40,6 +40,7 @@ struct Focusable {
// > 0 can be tabbed to in the order specified by this value
int32_t mTabIndex = -1;
explicit operator bool() const { return mFocusable; }
[[nodiscard]] bool IsTabbable() const { return mFocusable && mTabIndex >= 0; }
};
// IID for the nsIContent interface

View file

@ -1886,6 +1886,10 @@ void nsJSContext::EnsureStatics() {
"javascript.options.mem.gc_incremental",
(void*)JSGC_INCREMENTAL_GC_ENABLED);
Preferences::RegisterCallbackAndCall(SetMemoryPrefChangedCallbackBool,
"javascript.options.mem.gc_generational",
(void*)JSGC_NURSERY_ENABLED);
Preferences::RegisterCallbackAndCall(SetMemoryPrefChangedCallbackBool,
"javascript.options.mem.gc_compacting",
(void*)JSGC_COMPACTING_ENABLED);

View file

@ -468,7 +468,8 @@ void ClientWebGLContext::EndComposition() {
layers::TextureType ClientWebGLContext::GetTexTypeForSwapChain() const {
const RefPtr<layers::ImageBridgeChild> imageBridge =
layers::ImageBridgeChild::GetSingleton();
return layers::TexTypeForWebgl(imageBridge);
return layers::TexTypeForWebgl(imageBridge,
mNotLost->outOfProcess != nullptr);
}
void ClientWebGLContext::Present(WebGLFramebufferJS* const xrFb,
@ -587,8 +588,9 @@ Maybe<layers::SurfaceDescriptor> ClientWebGLContext::GetFrontBuffer(
}
Maybe<layers::SurfaceDescriptor> ClientWebGLContext::PresentFrontBuffer(
WebGLFramebufferJS* const fb, const layers::TextureType type, bool webvr) {
Present(fb, type, webvr);
WebGLFramebufferJS* const fb, bool webvr) {
const auto texType = GetTexTypeForSwapChain();
Present(fb, texType, webvr);
return GetFrontBuffer(fb, webvr);
}

View file

@ -1088,8 +1088,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(
WebGLFramebufferJS*, const bool webvr = false) override;
Maybe<layers::SurfaceDescriptor> PresentFrontBuffer(
WebGLFramebufferJS*, layers::TextureType,
const bool webvr = false) override;
WebGLFramebufferJS*, const bool webvr = false) override;
RefPtr<gfx::SourceSurface> GetFrontBufferSnapshot(
bool requireAlphaPremult = true) override;
already_AddRefed<layers::FwdTransactionTracker> UseCompositableForwarder(

View file

@ -34,13 +34,12 @@ namespace mozilla::dom {
OffscreenCanvasCloneData::OffscreenCanvasCloneData(
OffscreenCanvasDisplayHelper* aDisplay, uint32_t aWidth, uint32_t aHeight,
layers::LayersBackend aCompositorBackend, layers::TextureType aTextureType,
bool aNeutered, bool aIsWriteOnly, nsIPrincipal* aExpandedReader)
layers::LayersBackend aCompositorBackend, bool aNeutered, bool aIsWriteOnly,
nsIPrincipal* aExpandedReader)
: mDisplay(aDisplay),
mWidth(aWidth),
mHeight(aHeight),
mCompositorBackendType(aCompositorBackend),
mTextureType(aTextureType),
mNeutered(aNeutered),
mIsWriteOnly(aIsWriteOnly),
mExpandedReader(aExpandedReader) {}
@ -56,13 +55,12 @@ OffscreenCanvas::OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth,
OffscreenCanvas::OffscreenCanvas(
nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight,
layers::LayersBackend aCompositorBackend, layers::TextureType aTextureType,
layers::LayersBackend aCompositorBackend,
already_AddRefed<OffscreenCanvasDisplayHelper> aDisplay)
: DOMEventTargetHelper(aGlobal),
mWidth(aWidth),
mHeight(aHeight),
mCompositorBackendType(aCompositorBackend),
mTextureType(aTextureType),
mDisplay(aDisplay) {}
OffscreenCanvas::~OffscreenCanvas() {
@ -321,7 +319,7 @@ void OffscreenCanvas::DequeueCommitToCompositor() {
MOZ_ASSERT(mPendingCommit);
mPendingCommit = nullptr;
Maybe<OffscreenCanvasDisplayData> update = std::move(mPendingUpdate);
mDisplay->CommitFrameToCompositor(mCurrentContext, mTextureType, update);
mDisplay->CommitFrameToCompositor(mCurrentContext, update);
}
void OffscreenCanvas::CommitFrameToCompositor() {
@ -338,7 +336,7 @@ void OffscreenCanvas::CommitFrameToCompositor() {
}
Maybe<OffscreenCanvasDisplayData> update = std::move(mPendingUpdate);
mDisplay->CommitFrameToCompositor(mCurrentContext, mTextureType, update);
mDisplay->CommitFrameToCompositor(mCurrentContext, update);
}
UniquePtr<OffscreenCanvasCloneData> OffscreenCanvas::ToCloneData(
@ -374,8 +372,8 @@ UniquePtr<OffscreenCanvasCloneData> OffscreenCanvas::ToCloneData(
}
auto cloneData = MakeUnique<OffscreenCanvasCloneData>(
mDisplay, mWidth, mHeight, mCompositorBackendType, mTextureType,
mNeutered, mIsWriteOnly, mExpandedReader);
mDisplay, mWidth, mHeight, mCompositorBackendType, mNeutered,
mIsWriteOnly, mExpandedReader);
SetNeutered();
return cloneData;
}
@ -598,7 +596,7 @@ already_AddRefed<OffscreenCanvas> OffscreenCanvas::CreateFromCloneData(
MOZ_ASSERT(aData);
RefPtr<OffscreenCanvas> wc = new OffscreenCanvas(
aGlobal, aData->mWidth, aData->mHeight, aData->mCompositorBackendType,
aData->mTextureType, aData->mDisplay.forget());
aData->mDisplay.forget());
if (aData->mNeutered) {
wc->SetNeutered();
}

View file

@ -48,15 +48,14 @@ struct OffscreenCanvasCloneData final {
OffscreenCanvasCloneData(OffscreenCanvasDisplayHelper* aDisplay,
uint32_t aWidth, uint32_t aHeight,
layers::LayersBackend aCompositorBackend,
layers::TextureType aTextureType, bool aNeutered,
bool aIsWriteOnly, nsIPrincipal* aExpandedReader);
bool aNeutered, bool aIsWriteOnly,
nsIPrincipal* aExpandedReader);
~OffscreenCanvasCloneData();
RefPtr<OffscreenCanvasDisplayHelper> mDisplay;
uint32_t mWidth;
uint32_t mHeight;
layers::LayersBackend mCompositorBackendType;
layers::TextureType mTextureType;
bool mNeutered;
bool mIsWriteOnly;
RefPtr<nsIPrincipal> mExpandedReader;
@ -76,7 +75,6 @@ class OffscreenCanvas final : public DOMEventTargetHelper,
OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight,
layers::LayersBackend aCompositorBackend,
layers::TextureType aTextureType,
already_AddRefed<OffscreenCanvasDisplayHelper> aDisplay);
void Destroy();
@ -195,7 +193,6 @@ class OffscreenCanvas final : public DOMEventTargetHelper,
layers::LayersBackend mCompositorBackendType =
layers::LayersBackend::LAYERS_NONE;
layers::TextureType mTextureType = layers::TextureType::Unknown;
RefPtr<OffscreenCanvasDisplayHelper> mDisplay;
RefPtr<CancelableRunnable> mPendingCommit;

View file

@ -171,7 +171,6 @@ void OffscreenCanvasDisplayHelper::FlushForDisplay() {
bool OffscreenCanvasDisplayHelper::CommitFrameToCompositor(
nsICanvasRenderingContextInternal* aContext,
layers::TextureType aTextureType,
const Maybe<OffscreenCanvasDisplayData>& aData) {
auto endTransaction = MakeScopeExit([&]() {
if (auto* cm = gfx::CanvasManagerChild::Get()) {
@ -242,7 +241,7 @@ bool OffscreenCanvasDisplayHelper::CommitFrameToCompositor(
aContext->OnBeforePaintTransaction();
}
desc = aContext->PresentFrontBuffer(nullptr, aTextureType);
desc = aContext->PresentFrontBuffer(nullptr);
if (desc) {
hasRemoteTextureDesc =
desc->type() ==

View file

@ -51,7 +51,6 @@ class OffscreenCanvasDisplayHelper final {
void FlushForDisplay();
bool CommitFrameToCompositor(nsICanvasRenderingContextInternal* aContext,
layers::TextureType aTextureType,
const Maybe<OffscreenCanvasDisplayData>& aData);
void DestroyCanvas();

View file

@ -1377,6 +1377,7 @@ bool WebGLContext::PushRemoteTexture(
case layers::SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
case layers::SurfaceDescriptor::TSurfaceTextureDescriptor:
case layers::SurfaceDescriptor::TSurfaceDescriptorAndroidHardwareBuffer:
case layers::SurfaceDescriptor::TEGLImageDescriptor:
case layers::SurfaceDescriptor::TSurfaceDescriptorDMABuf:
keepAlive = surf;
break;

View file

@ -210,8 +210,7 @@ class nsICanvasRenderingContextInternal : public nsISupports,
}
virtual mozilla::Maybe<mozilla::layers::SurfaceDescriptor> PresentFrontBuffer(
mozilla::WebGLFramebufferJS* fb, mozilla::layers::TextureType,
const bool webvr = false) {
mozilla::WebGLFramebufferJS* fb, const bool webvr = false) {
return GetFrontBuffer(fb, webvr);
}

View file

@ -17,63 +17,63 @@ defaults pref(webgl.colorspaces.prototype,true)
### Generated, do not edit. ###
# -
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200)
### Generated, do not edit. ###
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000)
### Generated, do not edit. ###
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502)
### Generated, do not edit. ###
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000)
### Generated, do not edit. ###
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000)
### Generated, do not edit. ###
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200)
### Generated, do not edit. ###
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000)
skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000)
skip-if(cocoaWidget||winWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000)
### Generated, do not edit. ###
skip-if(cocoaWidget) fails-if(!Android) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200)
skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200)
skip-if(cocoaWidget||winWidget) fails-if(!Android) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200)
skip-if(cocoaWidget||winWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200)
### Generated, do not edit. ###
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502)
skip-if(!cocoaWidget) fuzzy(0-1,0-10000) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502)
skip-if(!cocoaWidget&&!winWidget) fuzzy(0-1,0-10000) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000)
### Generated, do not edit. ###
skip-if(cocoaWidget) fuzzy(0-1,0-10000) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000)
skip-if(cocoaWidget) fuzzy(0-1,0-10000) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000)
skip-if(cocoaWidget) fails-if(!Android) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000)
skip-if(cocoaWidget||winWidget) fuzzy(0-1,0-10000) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000)
skip-if(cocoaWidget||winWidget) fuzzy(0-1,0-10000) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000)
skip-if(cocoaWidget||winWidget) fails-if(!Android) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000)
### Generated, do not edit. ###
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000)
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502)
skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502)
skip-if(cocoaWidget||winWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502)
### Generated, do not edit. ###
skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000)
skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000)
skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000)
skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000)
### Generated, do not edit. ###

View file

@ -275,13 +275,13 @@ def reftests_from_config(test_config: Config) -> Iterable[ColorReftest]:
["skip-if(cocoaWidget||winWidget) "], expected_color_srgb
)
elif test_config["e_context"] == "webgl":
# Mac
# Win, Mac
yield from reftests_from_expected_color(
["skip-if(!cocoaWidget)"], correct_color
["skip-if(!cocoaWidget&&!winWidget)"], correct_color
)
# Win, Lin, Android
# Lin, Android
yield from reftests_from_expected_color(
["skip-if(cocoaWidget) "], expected_color_srgb
["skip-if(cocoaWidget||winWidget) "], expected_color_srgb
)
else:
assert False, test_config["e_context"]

View file

@ -1039,22 +1039,19 @@ OffscreenCanvas* HTMLCanvasElement::TransferControlToOffscreen(
}
LayersBackend backend = LayersBackend::LAYERS_NONE;
TextureType textureType = TextureType::Unknown;
nsIWidget* docWidget = nsContentUtils::WidgetForDocument(OwnerDoc());
if (docWidget) {
WindowRenderer* renderer = docWidget->GetWindowRenderer();
if (renderer) {
backend = renderer->GetCompositorBackendType();
textureType = TexTypeForWebgl(renderer->AsKnowsCompositor());
}
}
CSSIntSize sz = GetWidthHeight();
mOffscreenDisplay =
MakeRefPtr<OffscreenCanvasDisplayHelper>(this, sz.width, sz.height);
mOffscreenCanvas =
new OffscreenCanvas(win->AsGlobal(), sz.width, sz.height, backend,
textureType, do_AddRef(mOffscreenDisplay));
mOffscreenCanvas = new OffscreenCanvas(win->AsGlobal(), sz.width, sz.height,
backend, do_AddRef(mOffscreenDisplay));
if (mWriteOnly) {
mOffscreenCanvas->SetWriteOnly(mExpandedReader);
}

View file

@ -7057,7 +7057,8 @@ void HTMLInputElement::OnValueChanged(ValueChangeKind aKind,
if (aKind != ValueChangeKind::Internal) {
mLastValueChangeWasInteractive = aKind == ValueChangeKind::UserInteraction;
if (State().HasState(ElementState::AUTOFILL)) {
if (mLastValueChangeWasInteractive &&
State().HasState(ElementState::AUTOFILL)) {
RemoveStates(ElementState::AUTOFILL | ElementState::AUTOFILL_PREVIEW);
}
}

View file

@ -217,7 +217,14 @@ void ExternalEngineStateMachine::InitEngine() {
if (mEngine) {
MOZ_ASSERT(mInfo);
auto* state = mState.AsInitEngine();
state->mInitPromise = mEngine->Init(*mInfo, !mMinimizePreroll);
ExternalPlaybackEngine::InitFlagSet flags;
if (mMinimizePreroll) {
flags += ExternalPlaybackEngine::InitFlag::ShouldPreload;
}
if (mReader->IsEncryptedCustomIdent()) {
flags += ExternalPlaybackEngine::InitFlag::EncryptedCustomIdent;
}
state->mInitPromise = mEngine->Init(*mInfo, flags);
state->mInitPromise
->Then(OwnerThread(), __func__, this,
&ExternalEngineStateMachine::OnEngineInitSuccess,
@ -296,7 +303,7 @@ void ExternalEngineStateMachine::OnMetadataRead(MetadataHolder&& aMetadata) {
#ifdef MOZ_WMF_MEDIA_ENGINE
// Only support encrypted playback. Not a real "error", because it would
// fallback to another state machine.
if (!mInfo->IsEncrypted() &&
if ((!mInfo->IsEncrypted() && !mReader->IsEncryptedCustomIdent()) &&
StaticPrefs::media_wmf_media_engine_enabled() == 2) {
LOG("External engine only supports encrypted playback by the pref");
DecodeError(
@ -1271,6 +1278,7 @@ RefPtr<SetCDMPromise> ExternalEngineStateMachine::SetCDMProxy(
if (!mEngine || !mEngine->IsInited()) {
LOG("SetCDMProxy is called before init");
mReader->SetEncryptedCustomIdent();
mPendingTasks.AppendElement(NS_NewRunnableFunction(
"ExternalEngineStateMachine::SetCDMProxy",
[self = RefPtr{this}, proxy = RefPtr{aProxy}, this] {

View file

@ -340,9 +340,16 @@ class ExternalPlaybackEngine {
virtual ~ExternalPlaybackEngine() = default;
enum class InitFlag {
None,
ShouldPreload,
EncryptedCustomIdent,
};
using InitFlagSet = EnumSet<InitFlag, uint8_t>;
// Init the engine and specify the preload request.
virtual RefPtr<GenericNonExclusivePromise> Init(const MediaInfo& aInfo,
bool aShouldPreload) = 0;
virtual RefPtr<GenericNonExclusivePromise> Init(
const MediaInfo& aInfo, const InitFlagSet& aFlags) = 0;
virtual void Shutdown() = 0;
virtual uint64_t Id() const = 0;
virtual bool IsInited() const = 0;

View file

@ -718,9 +718,9 @@ void MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
LOG("Seek, target=%f", aTime);
MOZ_ASSERT(aTime >= 0.0, "Cannot seek to a negative value.");
LOG("Seek");
auto time = TimeUnit::FromSeconds(aTime);
mLogicalPosition = aTime;

View file

@ -2996,6 +2996,9 @@ void MediaDecoderStateMachine::DecodeMetadataState::OnMetadataRead(
} else if (Info().mUnadjustedMetadataEndTime.isSome()) {
const TimeUnit unadjusted = Info().mUnadjustedMetadataEndTime.ref();
const TimeUnit adjustment = Info().mStartTime;
SLOG("No metadata duration, calculate one. unadjusted=%" PRId64
", adjustment=%" PRId64,
unadjusted.ToMicroseconds(), adjustment.ToMicroseconds());
mMaster->mInfo->mMetadataDuration.emplace(unadjusted - adjustment);
mMaster->mDuration = Info().mMetadataDuration;
}
@ -3015,6 +3018,8 @@ void MediaDecoderStateMachine::DecodeMetadataState::OnMetadataRead(
}
MOZ_ASSERT(mMaster->mDuration.Ref().isSome());
SLOG("OnMetadataRead, duration=%" PRId64,
mMaster->mDuration.Ref()->ToMicroseconds());
mMaster->mMetadataLoadedEvent.Notify(std::move(aMetadata.mInfo),
std::move(aMetadata.mTags),
@ -3480,7 +3485,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
INIT_MIRROR(mOutputTracks, nsTArray<RefPtr<ProcessedMediaTrack>>()),
INIT_MIRROR(mOutputPrincipal, PRINCIPAL_HANDLE_NONE),
INIT_CANONICAL(mCanonicalOutputPrincipal, PRINCIPAL_HANDLE_NONE),
mShuttingDown(false) {
mShuttingDown(false),
mInitialized(false) {
MOZ_COUNT_CTOR(MediaDecoderStateMachine);
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
@ -3518,6 +3524,7 @@ void MediaDecoderStateMachine::InitializationTask(MediaDecoder* aDecoder) {
&MediaDecoderStateMachine::OutputPrincipalChanged);
mMediaSink = CreateMediaSink();
mInitialized = true;
MOZ_ASSERT(!mStateObj);
auto* s = new DecodeMetadataState(this);
@ -3923,14 +3930,15 @@ void MediaDecoderStateMachine::BufferedRangeUpdated() {
// Use estimated duration from buffer ranges when mDuration is unknown or
// the estimated duration is larger.
if (mDuration.Ref().isNothing() || mDuration.Ref()->IsInfinite() ||
end > mDuration.Ref().ref()) {
PROFILER_MARKER_TEXT(
"MDSM::BufferedRangeUpdated", MEDIA_PLAYBACK, {},
nsPrintfCString(
"duration:%" PRId64 "->%" PRId64,
mDuration.Ref().isNothing() ? 0 : mDuration.Ref()->ToMicroseconds(),
end.ToMicroseconds()));
if ((mDuration.Ref().isNothing() || mDuration.Ref()->IsInfinite() ||
end > mDuration.Ref().ref()) &&
end.IsPositiveOrZero()) {
nsPrintfCString msg{
"duration:%" PRId64 "->%" PRId64,
mDuration.Ref().isNothing() ? 0 : mDuration.Ref()->ToMicroseconds(),
end.ToMicroseconds()};
PROFILER_MARKER_TEXT("MDSM::BufferedRangeUpdated", MEDIA_PLAYBACK, {}, msg);
LOG("%s", msg.get());
mDuration = Some(end);
DDLOG(DDLogCategory::Property, "duration_us",
mDuration.Ref()->ToMicroseconds());
@ -4883,6 +4891,14 @@ bool MediaDecoderStateMachine::IsCDMProxySupported(CDMProxy* aProxy) {
#endif
}
RefPtr<SetCDMPromise> MediaDecoderStateMachine::SetCDMProxy(CDMProxy* aProxy) {
// Playback hasn't started yet.
if (!mInitialized) {
mReader->SetEncryptedCustomIdent();
}
return MediaDecoderStateMachineBase::SetCDMProxy(aProxy);
}
} // namespace mozilla
// avoid redefined macro in unified build

View file

@ -159,6 +159,8 @@ class MediaDecoderStateMachine
bool IsCDMProxySupported(CDMProxy* aProxy) override;
RefPtr<SetCDMPromise> SetCDMProxy(CDMProxy* aProxy) override;
private:
class StateObject;
class DecodeMetadataState;
@ -565,6 +567,8 @@ class MediaDecoderStateMachine
Atomic<bool> mShuttingDown;
Atomic<bool> mInitialized;
public:
AbstractCanonical<PrincipalHandle>* CanonicalOutputPrincipal() {
return &mCanonicalOutputPrincipal;

View file

@ -382,7 +382,10 @@ void MediaFormatReader::DecoderFactory::DoCreateDecoder(Data& aData) {
{*ownerData.GetCurrentInfo()->GetAsAudioInfo(), mOwner->mCrashHelper,
CreateDecoderParams::UseNullDecoder(ownerData.mIsNullDecode),
TrackInfo::kAudioTrack, std::move(onWaitingForKeyEvent),
mOwner->mMediaEngineId, mOwner->mTrackingId});
mOwner->mMediaEngineId, mOwner->mTrackingId,
mOwner->mEncryptedCustomIdent
? CreateDecoderParams::EncryptedCustomIdent::True
: CreateDecoderParams::EncryptedCustomIdent::False});
break;
}
@ -402,7 +405,10 @@ void MediaFormatReader::DecoderFactory::DoCreateDecoder(Data& aData) {
OptionSet(ownerData.mHardwareDecodingDisabled
? Option::HardwareDecoderNotAllowed
: Option::Default),
mOwner->mMediaEngineId, mOwner->mTrackingId});
mOwner->mMediaEngineId, mOwner->mTrackingId,
mOwner->mEncryptedCustomIdent
? CreateDecoderParams::EncryptedCustomIdent::True
: CreateDecoderParams::EncryptedCustomIdent::False});
break;
}
@ -895,7 +901,8 @@ MediaFormatReader::MediaFormatReader(MediaFormatReaderInit& aInit,
mTrackingId(std::move(aInit.mTrackingId)),
mReadMetadataStartTime(Nothing()),
mReadMetaDataTime(TimeDuration::Zero()),
mTotalWaitingForVideoDataTime(TimeDuration::Zero()) {
mTotalWaitingForVideoDataTime(TimeDuration::Zero()),
mEncryptedCustomIdent(false) {
MOZ_ASSERT(aDemuxer);
MOZ_COUNT_CTOR(MediaFormatReader);
DDLINKCHILD("audio decoder data", "MediaFormatReader::DecoderDataWithPromise",
@ -1289,8 +1296,11 @@ void MediaFormatReader::OnDemuxerInitDone(const MediaResult& aResult) {
// If the duration is 0 on both audio and video, it mMetadataDuration is to be
// Nothing(). Duration will use buffered ranges.
LOG("videoDuration=%" PRId64 ", audioDuration=%" PRId64,
videoDuration.ToMicroseconds(), audioDuration.ToMicroseconds());
if (videoDuration.IsPositive() || audioDuration.IsPositive()) {
auto duration = std::max(videoDuration, audioDuration);
LOG("Determine mMetadataDuration=%" PRId64, duration.ToMicroseconds());
mInfo.mMetadataDuration = Some(duration);
}
@ -1345,6 +1355,7 @@ void MediaFormatReader::MaybeResolveMetadataPromise() {
if (!startTime.IsInfinite()) {
mInfo.mStartTime = startTime; // mInfo.mStartTime is initialized to 0.
LOG("Set start time=%s", mInfo.mStartTime.ToString().get());
}
MetadataHolder metadata;
@ -3275,6 +3286,8 @@ void MediaFormatReader::UpdateBuffered() {
// IntervalSet already starts at 0 or is empty, nothing to shift.
mBuffered = intervals;
} else {
LOG("Subtract start time for buffered range, startTime=%" PRId64,
mInfo.mStartTime.ToMicroseconds());
mBuffered = intervals.Shift(TimeUnit::Zero() - mInfo.mStartTime);
}
}
@ -3488,6 +3501,11 @@ void MediaFormatReader::OnFirstDemuxFailed(TrackInfo::TrackType aType,
MaybeResolveMetadataPromise();
}
void MediaFormatReader::SetEncryptedCustomIdent() {
LOG("Set mEncryptedCustomIdent");
mEncryptedCustomIdent = true;
}
} // namespace mozilla
#undef NS_DispatchToMainThread

View file

@ -139,6 +139,12 @@ class MediaFormatReader final
// Windows when the media engine playback is enabled.
void UpdateMediaEngineId(uint64_t aMediaEngineId);
// This function will be called if the media key is set before playback
// starts, indicating the playback should be encrypted.
void SetEncryptedCustomIdent();
bool IsEncryptedCustomIdent() const { return mEncryptedCustomIdent; }
protected:
// Recomputes mBuffered.
void UpdateBuffered();
@ -900,6 +906,12 @@ class MediaFormatReader final
// The total amount of time we have been waiting for the video data due to
// lacking of data.
TimeDuration mTotalWaitingForVideoDataTime;
// https://github.com/w3c/encrypted-media/issues/251#issuecomment-819783073
// Treat playback as encrypted if the media key is set before playback starts,
// this allows websites to start with non-encrypted stream and switch to
// encrypted stream later.
Atomic<bool> mEncryptedCustomIdent;
};
} // namespace mozilla

View file

@ -209,4 +209,12 @@ RefPtr<SetCDMPromise> ReaderProxy::SetCDMProxy(CDMProxy* aProxy) {
&MediaFormatReader::SetCDMProxy, aProxy);
}
void ReaderProxy::SetEncryptedCustomIdent() {
mReader->SetEncryptedCustomIdent();
}
bool ReaderProxy::IsEncryptedCustomIdent() const {
return mReader->IsEncryptedCustomIdent();
}
} // namespace mozilla

View file

@ -89,6 +89,10 @@ class ReaderProxy {
void UpdateMediaEngineId(uint64_t aMediaEngineId);
void SetEncryptedCustomIdent();
bool IsEncryptedCustomIdent() const;
private:
~ReaderProxy();
RefPtr<MetadataPromise> OnMetadataRead(MetadataHolder&& aMetadata);

View file

@ -47,7 +47,7 @@ MFMediaEngineChild::MFMediaEngineChild(MFMediaEngineWrapper* aOwner,
}
RefPtr<GenericNonExclusivePromise> MFMediaEngineChild::Init(
const MediaInfo& aInfo, bool aShouldPreload) {
const MediaInfo& aInfo, const ExternalPlaybackEngine::InitFlagSet& aFlags) {
if (!mManagerThread) {
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_FAILURE,
__func__);
@ -62,7 +62,7 @@ RefPtr<GenericNonExclusivePromise> MFMediaEngineChild::Init(
RemoteDecodeIn::UtilityProcess_MFMediaEngineCDM)
->Then(
mManagerThread, __func__,
[self, this, aShouldPreload, info = aInfo](bool) {
[self, this, flag = aFlags, info = aInfo](bool) {
RefPtr<RemoteDecoderManagerChild> manager =
RemoteDecoderManagerChild::GetSingleton(
RemoteDecodeIn::UtilityProcess_MFMediaEngineCDM);
@ -79,7 +79,11 @@ RefPtr<GenericNonExclusivePromise> MFMediaEngineChild::Init(
info.HasAudio() ? Some(info.mAudio) : Nothing(),
info.HasVideo() ? Some(info.mVideo) : Nothing());
MediaEngineInfoIPDL initInfo(mediaInfo, aShouldPreload);
MediaEngineInfoIPDL initInfo(
mediaInfo,
flag.contains(ExternalPlaybackEngine::InitFlag::ShouldPreload),
flag.contains(
ExternalPlaybackEngine::InitFlag::EncryptedCustomIdent));
SendInitMediaEngine(initInfo)
->Then(
mManagerThread, __func__,
@ -263,9 +267,9 @@ MFMediaEngineWrapper::MFMediaEngineWrapper(ExternalEngineStateMachine* aOwner,
mCurrentTimeInSecond(0.0) {}
RefPtr<GenericNonExclusivePromise> MFMediaEngineWrapper::Init(
const MediaInfo& aInfo, bool aShouldPreload) {
const MediaInfo& aInfo, const InitFlagSet& aFlags) {
WLOG("Init");
return mEngine->Init(aInfo, aShouldPreload);
return mEngine->Init(aInfo, aFlags);
}
MFMediaEngineWrapper::~MFMediaEngineWrapper() { mEngine->OwnerDestroyed(); }

View file

@ -32,8 +32,9 @@ class MFMediaEngineChild final : public PMFMediaEngineChild {
void OwnerDestroyed();
void IPDLActorDestroyed();
RefPtr<GenericNonExclusivePromise> Init(const MediaInfo& aInfo,
bool aShouldPreload);
RefPtr<GenericNonExclusivePromise> Init(
const MediaInfo& aInfo,
const ExternalPlaybackEngine::InitFlagSet& aFlags);
void Shutdown();
// Methods for PMFMediaEngineChild
@ -101,7 +102,7 @@ class MFMediaEngineWrapper final : public ExternalPlaybackEngine {
// Methods for ExternalPlaybackEngine
RefPtr<GenericNonExclusivePromise> Init(const MediaInfo& aInfo,
bool aShouldPreload) override;
const InitFlagSet& aFlags) override;
void Play() override;
void Pause() override;
void Seek(const media::TimeUnit& aTargetTime) override;

View file

@ -338,12 +338,14 @@ mozilla::ipc::IPCResult MFMediaEngineParent::RecvInitMediaEngine(
// TODO : really need this?
Unused << mMediaEngine->SetPreload(MF_MEDIA_ENGINE_PRELOAD_AUTOMATIC);
}
RETURN_PARAM_IF_FAILED(SetMediaInfo(aInfo.mediaInfo()), IPC_OK());
RETURN_PARAM_IF_FAILED(
SetMediaInfo(aInfo.mediaInfo(), aInfo.encryptedCustomIdent()), IPC_OK());
aResolver(mMediaEngineId);
return IPC_OK();
}
HRESULT MFMediaEngineParent::SetMediaInfo(const MediaInfoIPDL& aInfo) {
HRESULT MFMediaEngineParent::SetMediaInfo(const MediaInfoIPDL& aInfo,
bool aIsEncrytpedCustomInit) {
AssertOnManagerThread();
MOZ_ASSERT(mIsCreatedMediaEngine, "Hasn't created media engine?");
MOZ_ASSERT(!mMediaSource);
@ -357,23 +359,23 @@ HRESULT MFMediaEngineParent::SetMediaInfo(const MediaInfoIPDL& aInfo) {
});
// Create media source and set it to the media engine.
NS_ENSURE_TRUE(
SUCCEEDED(MakeAndInitialize<MFMediaSource>(
&mMediaSource, aInfo.audioInfo(), aInfo.videoInfo(), mManagerThread)),
IPC_OK());
NS_ENSURE_TRUE(SUCCEEDED(MakeAndInitialize<MFMediaSource>(
&mMediaSource, aInfo.audioInfo(), aInfo.videoInfo(),
mManagerThread, aIsEncrytpedCustomInit)),
IPC_OK());
const bool isEncryted = mMediaSource->IsEncrypted();
ENGINE_MARKER("MFMediaEngineParent,CreatedMediaSource");
nsPrintfCString message(
"Created the media source, audio=%s, video=%s, encrypted-audio=%s, "
"encrypted-video=%s, isEncrypted=%d",
"encrypted-video=%s, aIsEncrytpedCustomInit=%d, isEncrypted=%d",
aInfo.audioInfo() ? aInfo.audioInfo()->mMimeType.BeginReading() : "none",
aInfo.videoInfo() ? aInfo.videoInfo()->mMimeType.BeginReading() : "none",
aInfo.audioInfo() && aInfo.audioInfo()->mCrypto.IsEncrypted() ? "yes"
: "no",
aInfo.videoInfo() && aInfo.videoInfo()->mCrypto.IsEncrypted() ? "yes"
: "no",
isEncryted);
aIsEncrytpedCustomInit, isEncryted);
LOG("%s", message.get());
if (aInfo.videoInfo()) {

View file

@ -68,7 +68,7 @@ class MFMediaEngineParent final : public PMFMediaEngineParent {
~MFMediaEngineParent();
void CreateMediaEngine();
HRESULT SetMediaInfo(const MediaInfoIPDL& aInfo);
HRESULT SetMediaInfo(const MediaInfoIPDL& aInfo, bool aIsEncrytpedCustomInit);
void InitializeDXGIDeviceManager();

View file

@ -19,6 +19,7 @@ struct MediaEngineInfoIPDL
{
MediaInfoIPDL mediaInfo;
bool preload;
bool encryptedCustomIdent;
};
struct MediaInfoIPDL

View file

@ -334,7 +334,10 @@ RefPtr<PlatformDecoderModule::CreateDecoderPromise> PDMFactory::CreateDecoder(
MOZ_ASSERT(mNullPDM);
return CreateDecoderWithPDM(mNullPDM, aParams);
}
bool isEncrypted = mEMEPDM && aParams.mConfig.mCrypto.IsEncrypted();
bool isEncrypted =
mEMEPDM && (aParams.mConfig.mCrypto.IsEncrypted() ||
aParams.mEncryptedCustomIdent ==
CreateDecoderParams::EncryptedCustomIdent::True);
if (isEncrypted) {
return CreateDecoderWithPDM(mEMEPDM, aParams);

View file

@ -120,6 +120,10 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
using UseNullDecoder = media::UseNullDecoder;
using NoWrapper = media::NoWrapper;
using VideoFrameRate = media::VideoFrameRate;
enum class EncryptedCustomIdent : bool {
False,
True,
};
explicit CreateDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) {}
CreateDecoderParams(const CreateDecoderParams& aParams) = default;
@ -185,6 +189,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
// Used on Windows when the MF media engine playback is enabled.
Maybe<uint64_t> mMediaEngineId;
Maybe<TrackingId> mTrackingId;
EncryptedCustomIdent mEncryptedCustomIdent;
private:
void Set(layers::ImageContainer* aImageContainer) {
@ -217,6 +222,9 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
mMediaEngineId = aMediaEngineId;
}
void Set(const Maybe<TrackingId>& aTrackingId) { mTrackingId = aTrackingId; }
void Set(const EncryptedCustomIdent aEncryptedCustomIdent) {
mEncryptedCustomIdent = aEncryptedCustomIdent;
}
void Set(const CreateDecoderParams& aParams) {
// Set all but mTrackInfo;
mImageContainer = aParams.mImageContainer;

View file

@ -392,7 +392,9 @@ static already_AddRefed<MediaDataDecoderProxy> CreateDecoderWrapper(
RefPtr<EMEDecoderModule::CreateDecoderPromise>
EMEDecoderModule::AsyncCreateDecoder(const CreateDecoderParams& aParams) {
MOZ_ASSERT(aParams.mConfig.mCrypto.IsEncrypted());
MOZ_ASSERT(aParams.mConfig.mCrypto.IsEncrypted() ||
aParams.mEncryptedCustomIdent ==
CreateDecoderParams::EncryptedCustomIdent::True);
MOZ_ASSERT(mPDM);
if (aParams.mConfig.IsVideo()) {

View file

@ -23,11 +23,12 @@ using Microsoft::WRL::MakeAndInitialize;
/* static */
MFMediaEngineAudioStream* MFMediaEngineAudioStream::Create(
uint64_t aStreamId, const TrackInfo& aInfo, MFMediaSource* aParentSource) {
uint64_t aStreamId, const TrackInfo& aInfo, bool aIsEncrytpedCustomInit,
MFMediaSource* aParentSource) {
MOZ_ASSERT(aInfo.IsAudio());
MFMediaEngineAudioStream* stream;
if (FAILED(MakeAndInitialize<MFMediaEngineAudioStream>(
&stream, aStreamId, aInfo, aParentSource))) {
&stream, aStreamId, aInfo, aIsEncrytpedCustomInit, aParentSource))) {
return nullptr;
}
return stream;
@ -129,7 +130,7 @@ nsCString MFMediaEngineAudioStream::GetCodecName() const {
}
bool MFMediaEngineAudioStream::IsEncrypted() const {
return mAudioInfo.mCrypto.IsEncrypted();
return mAudioInfo.mCrypto.IsEncrypted() || mIsEncrytpedCustomInit;
}
#undef LOG

View file

@ -17,6 +17,7 @@ class MFMediaEngineAudioStream final : public MFMediaEngineStream {
static MFMediaEngineAudioStream* Create(uint64_t aStreamId,
const TrackInfo& aInfo,
bool aIsEncrytpedCustomInit,
MFMediaSource* aParentSource);
nsCString GetDescriptionName() const override {

View file

@ -122,11 +122,13 @@ MFMediaEngineStream::~MFMediaEngineStream() {
}
HRESULT MFMediaEngineStream::RuntimeClassInitialize(
uint64_t aStreamId, const TrackInfo& aInfo, MFMediaSource* aParentSource) {
uint64_t aStreamId, const TrackInfo& aInfo, bool aIsEncrytpedCustomInit,
MFMediaSource* aParentSource) {
mParentSource = aParentSource;
mTaskQueue = aParentSource->GetTaskQueue();
MOZ_ASSERT(mTaskQueue);
mStreamId = aStreamId;
mIsEncrytpedCustomInit = aIsEncrytpedCustomInit;
auto errorExit = MakeScopeExit([&] {
SLOG("Failed to initialize media stream (id=%" PRIu64 ")", aStreamId);

View file

@ -42,6 +42,7 @@ class MFMediaEngineStream
virtual nsCString GetCodecName() const = 0;
HRESULT RuntimeClassInitialize(uint64_t aStreamId, const TrackInfo& aInfo,
bool aIsEncrytpedCustomInit,
MFMediaSource* aParentSource);
// Called by MFMediaSource.
@ -188,6 +189,9 @@ class MFMediaEngineStream
// True if the stream has received the last data, but it could be reset if the
// stream starts delivering more data. Used on the task queue only.
bool mReceivedEOS;
// https://github.com/w3c/encrypted-media/issues/251#issuecomment-819783073
bool mIsEncrytpedCustomInit;
};
/**

Some files were not shown because too many files have changed in this diff Show more