Update On Fri Sep 29 20:52:55 CEST 2023

This commit is contained in:
github-action[bot] 2023-09-29 20:52:56 +02:00
parent 2544639060
commit ec3e5dd440
1886 changed files with 29015 additions and 15439 deletions

View file

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Merge day clobber 2023-09-25
Modified build files in third_party/libwebrtc - Bug 1832465 - remove libXtst usage from libwebrtc

51
Cargo.lock generated
View file

@ -408,21 +408,28 @@ dependencies = [
name = "bindgen"
version = "0.63.999"
dependencies = [
"bindgen 0.66.1",
"bindgen 0.66.999",
]
[[package]]
name = "bindgen"
version = "0.64.999"
dependencies = [
"bindgen 0.66.1",
"bindgen 0.66.999",
]
[[package]]
name = "bindgen"
version = "0.66.1"
version = "0.66.999"
dependencies = [
"bindgen 0.68.1",
]
[[package]]
name = "bindgen"
version = "0.68.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7"
checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
dependencies = [
"bitflags 2.4.0",
"cexpr",
@ -567,7 +574,7 @@ dependencies = [
name = "builtins-static"
version = "0.1.0"
dependencies = [
"bindgen 0.66.1",
"bindgen 0.68.1",
"mozilla-central-workspace-hack",
"nom",
"pkcs11-bindings",
@ -870,11 +877,11 @@ dependencies = [
[[package]]
name = "coreaudio-sys"
version = "0.2.12"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f034b2258e6c4ade2f73bf87b21047567fb913ee9550837c2316d139b0262b24"
checksum = "d8478e5bdad14dce236b9898ea002eabfa87cbe14f0aa538dbe3b6a4bec4332d"
dependencies = [
"bindgen 0.64.999",
"bindgen 0.68.1",
]
[[package]]
@ -1417,7 +1424,7 @@ dependencies = [
name = "dom"
version = "0.1.0"
dependencies = [
"bitflags 1.999.999",
"bitflags 2.4.0",
]
[[package]]
@ -2008,7 +2015,7 @@ name = "gecko-profiler"
version = "0.1.0"
dependencies = [
"bincode",
"bindgen 0.66.1",
"bindgen 0.68.1",
"lazy_static",
"mozbuild",
"profiler-macros",
@ -2548,7 +2555,7 @@ name = "http3server"
version = "0.1.1"
dependencies = [
"base64 0.21.3",
"bindgen 0.66.1",
"bindgen 0.68.1",
"cfg-if 1.0.0",
"http",
"hyper",
@ -3618,7 +3625,7 @@ name = "mozilla-central-workspace-hack"
version = "0.1.0"
dependencies = [
"arrayvec",
"bindgen 0.66.1",
"bindgen 0.68.1",
"bytes",
"chrono",
"env_logger",
@ -3923,7 +3930,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c17aec6d4e1822c023689899f09311592a36cbf6de8f85dfaf5f01976790d8d"
dependencies = [
"bindgen 0.66.1",
"bindgen 0.66.999",
"mozbuild",
"once_cell",
"pkcs11-bindings",
@ -3941,7 +3948,7 @@ source = "git+https://github.com/mozilla/application-services?rev=1a59041d0c7d36
name = "nsstring"
version = "0.1.0"
dependencies = [
"bitflags 1.999.999",
"bitflags 2.4.0",
"encoding_rs",
]
@ -4275,7 +4282,7 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0fabbdbe64b22820753da90995b3a73d02907eaeeac6f2414962a566aaa18ea"
dependencies = [
"bindgen 0.66.1",
"bindgen 0.66.999",
]
[[package]]
@ -4537,12 +4544,12 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.11.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
@ -4820,7 +4827,7 @@ dependencies = [
name = "selectors"
version = "0.22.0"
dependencies = [
"bitflags 1.999.999",
"bitflags 2.4.0",
"cssparser",
"derive_more 0.99.999",
"fxhash",
@ -5186,8 +5193,8 @@ dependencies = [
"app_units",
"arrayvec",
"atomic_refcell",
"bindgen 0.66.1",
"bitflags 1.999.999",
"bindgen 0.68.1",
"bitflags 2.4.0",
"byteorder",
"cssparser",
"derive_more 0.99.999",
@ -5254,7 +5261,7 @@ name = "style_traits"
version = "0.0.1"
dependencies = [
"app_units",
"bitflags 1.999.999",
"bitflags 2.4.0",
"cssparser",
"euclid",
"lazy_static",

View file

@ -132,8 +132,9 @@ base64 = { path = "build/rust/base64" }
# Patch wasi 0.10 to 0.11
wasi = { path = "build/rust/wasi" }
# Patch bindgen 0.63 and 0.64 to 0.66
# Patch bindgen 0.63, 0.64 and 0.66 to 0.68
bindgen_0_63 = { package = "bindgen", path = "build/rust/bindgen-0.63" }
bindgen_0_64 = { package = "bindgen", path = "build/rust/bindgen-0.64" }
bindgen = { path = "build/rust/bindgen" }
# Patch nix 0.24 to 0.26
@ -164,9 +165,6 @@ web-sys = { path = "build/rust/dummy-web/web-sys" }
# Overrides to allow easier use of common internal crates.
moz_asserts = { path = "mozglue/static/rust/moz_asserts" }
# Patch rayon core to import https://github.com/rayon-rs/rayon/pull/1063
rayon-core = { path = "third_party/rust/rayon-core" }
# Patch `rure` to disable building the cdylib and staticlib targets
# Cargo has no way to disable building targets your dependencies provide which
# you don't depend on, and linking the cdylib breaks during instrumentation

View file

@ -11,10 +11,7 @@
# Bug 1557153: www.mozilla.org gets a special workaround in UITourChild.sys.mjs
# Bug 1837407: support.mozilla.org gets a special workaround for similar reasons.
origin uitour 1 https://www.mozilla.org
origin uitour 1 https://monitor.firefox.com
origin uitour 1 https://screenshots.firefox.com
origin uitour 1 https://support.mozilla.org
origin uitour 1 https://truecolors.firefox.com
origin uitour 1 about:home
origin uitour 1 about:newtab
@ -24,8 +21,5 @@ origin install 1 https://addons.mozilla.org
# Remote troubleshooting
origin remote-troubleshooting 1 https://support.mozilla.org
# addon install
origin install 1 https://fpn.firefox.com
# autoplay video/audio
origin autoplay-media 1 about:welcome

View file

@ -4,6 +4,19 @@ const TEST_ROOT =
"http://mochi.test:8888/browser/browser/base/content/test/favicons/";
const TEST_URL = TEST_ROOT + "file_favicon_change_not_in_document.html";
// Runs the given task in the document of the browser.
function runInDoc(browser, task) {
return ContentTask.spawn(browser, `(${task.toString()})();`, scriptStr => {
let script = content.document.createElement("script");
script.textContent = scriptStr;
content.document.body.appendChild(script);
// Link events are dispatched asynchronously so allow the event loop to run
// to ensure that any events are actually dispatched before returning.
return new Promise(resolve => content.setTimeout(resolve, 0));
});
}
/*
* This test tests a link element won't fire DOMLinkChanged/DOMLinkAdded unless
* it is added to the DOM. See more details in bug 1083895.
@ -53,3 +66,83 @@ add_task(async function () {
gBrowser.removeTab(extraTab);
});
/*
* This verifies that creating and manipulating link elements inside document
* fragments doesn't trigger the link events.
*/
add_task(async function () {
let extraTab = (gBrowser.selectedTab = BrowserTestUtils.addTab(
gBrowser,
TEST_ROOT
));
let browser = extraTab.linkedBrowser;
let domLinkAddedFired = 0;
let domLinkChangedFired = 0;
const linkAddedHandler = event => domLinkAddedFired++;
const linkChangedhandler = event => domLinkChangedFired++;
BrowserTestUtils.addContentEventListener(
browser,
"DOMLinkAdded",
linkAddedHandler
);
BrowserTestUtils.addContentEventListener(
browser,
"DOMLinkChanged",
linkChangedhandler
);
BrowserTestUtils.startLoadingURIString(browser, TEST_ROOT + "blank.html");
await BrowserTestUtils.browserLoaded(browser);
is(domLinkAddedFired, 0, "Should have been no link add events");
is(domLinkChangedFired, 0, "Should have been no link change events");
await runInDoc(browser, () => {
let fragment = document
.createRange()
.createContextualFragment(
'<link type="image/ico" href="file_generic_favicon.ico" rel="icon">'
);
fragment.firstElementChild.setAttribute("type", "image/png");
});
is(domLinkAddedFired, 0, "Should have been no link add events");
is(domLinkChangedFired, 0, "Should have been no link change events");
await runInDoc(browser, () => {
let fragment = document.createDocumentFragment();
let link = document.createElement("link");
link.setAttribute("href", "file_generic_favicon.ico");
link.setAttribute("rel", "icon");
link.setAttribute("type", "image/ico");
fragment.appendChild(link);
link.setAttribute("type", "image/png");
});
is(domLinkAddedFired, 0, "Should have been no link add events");
is(domLinkChangedFired, 0, "Should have been no link change events");
let expectedFavicon = TEST_ROOT + "file_generic_favicon.ico";
let faviconPromise = waitForFavicon(browser, expectedFavicon);
// Moving an element from the fragment into the DOM should trigger the add
// events and start favicon loading.
await runInDoc(browser, () => {
let fragment = document
.createRange()
.createContextualFragment(
'<link type="image/ico" href="file_generic_favicon.ico" rel="icon">'
);
document.head.appendChild(fragment);
});
is(domLinkAddedFired, 1, "Should have been one link add events");
is(domLinkChangedFired, 0, "Should have been no link change events");
await faviconPromise;
gBrowser.removeTab(extraTab);
});

View file

@ -4199,15 +4199,11 @@ BrowserGlue.prototype = {
// originInfo in the format [origin, type]
[
["https://www.mozilla.org", "uitour"],
["https://monitor.firefox.com", "uitour"],
["https://screenshots.firefox.com", "uitour"],
["https://support.mozilla.org", "uitour"],
["https://truecolors.firefox.com", "uitour"],
["about:home", "uitour"],
["about:newtab", "uitour"],
["https://addons.mozilla.org", "install"],
["https://support.mozilla.org", "remote-troubleshooting"],
["https://fpn.firefox.com", "install"],
["about:welcome", "autoplay-media"],
].forEach(originInfo => {
// Reset permission on the condition that it is set to

View file

@ -255,7 +255,15 @@ class SyncedTabsInView extends ViewPage {
where = "tab";
}
currentWindow.openTrustedLinkIn(event.originalTarget.url, where);
Services.telemetry.recordEvent("firefoxview_next", "synced_tabs", "tabs");
Services.telemetry.recordEvent(
"firefoxview_next",
"synced_tabs",
"tabs",
null,
{
page: this.recentBrowsing ? "recentbrowsing" : "syncedtabs",
}
);
}
}

View file

@ -324,7 +324,15 @@ add_task(async function test_tabs() {
100
);
TelemetryTestUtils.assertEvents(
[["firefoxview_next", "synced_tabs", "tabs"]],
[
[
"firefoxview_next",
"synced_tabs",
"tabs",
null,
{ page: "syncedtabs" },
],
],
{ category: "firefoxview_next" },
{ clear: true, process: "parent" }
);

View file

@ -353,7 +353,7 @@ const OPTIN_DEFAULT = {
content: {
position: "split",
title: { string_id: "shopping-onboarding-headline" },
subtitle: { string_id: "shopping-onboarding-dynamic-subtitle" },
subtitle: { string_id: "shopping-onboarding-dynamic-subtitle-1" },
above_button_content: [
{
type: "text",

View file

@ -67,6 +67,7 @@
.screenshots-button {
display: inline-flex;
align-items: center;
cursor: pointer;
text-align: center;
user-select: none;

View file

@ -1397,7 +1397,7 @@ class ContentHandler {
if (lazy.serpEventTelemetryCategorization && telemetryState) {
let provider = item?.info.provider;
if (provider) {
SearchSERPCategorization.categorizeDomainsFromProvider(
SearchSERPCategorization.maybeCategorizeAndReportDomainsFromProvider(
info.nonAdDomains,
info.adDomains,
provider
@ -1416,7 +1416,9 @@ class ContentHandler {
*/
class DomainCategorizer {
/**
* Categorizes domains extracted from SERPs.
* Categorizes and reports domains extracted from SERPs. Note that we don't
* process domains if the domain-to-categories map is empty (if the client
* couldn't download Remote Settings attachments, for example).
*
* @param {Set} nonAdDomains
* The non-ad domains extracted from the page.
@ -1425,15 +1427,28 @@ class DomainCategorizer {
* @param {string} provider
* The provider associated with the page.
*/
categorizeDomainsFromProvider(nonAdDomains, adDomains, provider) {
maybeCategorizeAndReportDomainsFromProvider(
nonAdDomains,
adDomains,
provider
) {
for (let domains of [nonAdDomains, adDomains]) {
// We don't want to generate and report telemetry if a client was unable
// to download the domain-to-categories mapping from Remote Settings.
if (SearchSERPDomainToCategoriesMap.empty) {
continue;
}
domains = this.processDomains(domains, provider);
let resultsToReport = this.applyCategorizationLogic(domains);
this.dummyLogger(domains, resultsToReport);
this.dummyLogger(
domains,
resultsToReport,
SearchSERPDomainToCategoriesMap.version
);
}
}
// TODO: check with DS to get the final aggregation logic.
// TODO: check with DS to get the final aggregation logic. (Bug 1854196)
/**
* Applies the logic for reducing extracted domains to a single category for
* the SERP.
@ -1505,8 +1520,9 @@ class DomainCategorizer {
}
// TODO: replace this method once we know where to send the categorized
// domains and overall SERP category.
dummyLogger(domains, resultsToReport) {
// domains and overall SERP category. (Bug 1854692)
dummyLogger(domains, resultsToReport, version) {
lazy.logConsole.debug("Version of the attachments:", version);
lazy.logConsole.debug("Domains extracted from SERP:", [...domains]);
lazy.logConsole.debug(
"Categorization results to report to Glean:",
@ -1795,13 +1811,6 @@ class DomainToCategoriesMap {
return;
}
if (!records.length) {
lazy.logConsole.error(
"No valid attachments available for domain-to-categories map."
);
return;
}
let fileContents = [];
for (let record of records) {
let result;

View file

@ -2,7 +2,9 @@
tags = "search-telemetry"
support-files = ["head.js"]
["browser_search_glean_serp_telemetry_enabled_by_nimbus_variable.js"]
["browser_search_glean_serp_event_telemetry_categorization_enabled_by_nimbus_variable.js"]
["browser_search_glean_serp_event_telemetry_enabled_by_nimbus_variable.js"]
support-files = ["searchTelemetryAd.html"]
["browser_search_telemetry_abandonment.js"]

View file

@ -0,0 +1,133 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Test to verify we can toggle the Glean SERP event telemetry for SERP
// categorization feature via a Nimbus variable.
const lazy = {};
const TELEMETRY_PREF =
"browser.search.serpEventTelemetryCategorization.enabled";
ChromeUtils.defineESModuleGetters(lazy, {
ExperimentAPI: "resource://nimbus/ExperimentAPI.sys.mjs",
ExperimentFakes: "resource://testing-common/NimbusTestUtils.sys.mjs",
SearchSERPCategorization: "resource:///modules/SearchSERPTelemetry.sys.mjs",
SearchSERPDomainToCategoriesMap:
"resource:///modules/SearchSERPTelemetry.sys.mjs",
});
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"serpEventsCategorizationEnabled",
TELEMETRY_PREF,
false
);
function testCategorizationLogic() {
const TEST_DOMAIN_TO_CATEGORIES_MAP = {
"byVQ4ej7T7s2xf/cPqgMyw==": [2, 90],
"1TEnSjgNCuobI6olZinMiQ==": [2, 95],
"/Bnju09b9iBPjg7K+5ENIw==": [2, 78, 4, 10],
"Ja6RJq5LQftdl7NQrX1avQ==": [2, 56, 4, 24],
"Jy26Qt99JrUderAcURtQ5A==": [2, 89],
"sZnJyyzY9QcN810Q6jfbvw==": [2, 43],
"QhmteGKeYk0okuB/bXzwRw==": [2, 65],
"CKQZZ1IJjzjjE4LUV8vUSg==": [2, 67],
"FK7mL5E1JaE6VzOiGMmlZg==": [2, 89],
"mzcR/nhDcrs0ed4kTf+ZFg==": [2, 99],
};
lazy.SearchSERPDomainToCategoriesMap.overrideMapForTests(
TEST_DOMAIN_TO_CATEGORIES_MAP
);
let domains = new Set([
"test1.com",
"test2.com",
"test3.com",
"test4.com",
"test5.com",
"test6.com",
"test7.com",
"test8.com",
"test9.com",
"test10.com",
]);
let resultsToReport =
lazy.SearchSERPCategorization.applyCategorizationLogic(domains);
Assert.deepEqual(
resultsToReport,
{ category: "2", num_domains: 10, num_inconclusive: 0, num_unknown: 0 },
"Should report the correct values for categorizing the SERP."
);
}
add_setup(async function () {
// Enable local telemetry recording for the duration of the tests.
let oldCanRecord = Services.telemetry.canRecordExtended;
Services.telemetry.canRecordExtended = true;
await SpecialPowers.pushPrefEnv({
set: [["browser.search.log", true]],
});
registerCleanupFunction(async () => {
Services.telemetry.canRecordExtended = oldCanRecord;
await SpecialPowers.popPrefEnv();
resetTelemetry();
});
});
add_task(async function test_enable_experiment_when_pref_is_not_enabled() {
let prefBranch = Services.prefs.getDefaultBranch("");
let originalPrefValue = prefBranch.getBoolPref(TELEMETRY_PREF);
// Ensure the build being tested has the preference value as false.
// Changing the preference in the test must be done on the default branch
// because in the telemetry code, we're referencing the preference directly
// instead of through NimbusFeatures. Enrolling in an experiment will change
// the default branch, and not overwrite the user branch.
prefBranch.setBoolPref(TELEMETRY_PREF, false);
Assert.equal(
lazy.serpEventsCategorizationEnabled,
false,
"serpEventsCategorizationEnabled should be false when not enrolled in experiment."
);
await lazy.ExperimentAPI.ready();
let doExperimentCleanup = await lazy.ExperimentFakes.enrollWithFeatureConfig(
{
featureId: NimbusFeatures.search.featureId,
value: {
serpEventTelemetryCategorizationEnabled: true,
},
},
{ isRollout: true }
);
Assert.equal(
lazy.serpEventsCategorizationEnabled,
true,
"serpEventsCategorizationEnabled should be true when enrolled in experiment."
);
// To ensure Nimbus set
// "browser.search.serpEventCategorizationTelemetry.enabled" to
// true, we test that we're able to categorize a set of domains.
testCategorizationLogic();
await doExperimentCleanup();
Assert.equal(
lazy.serpEventsCategorizationEnabled,
false,
"serpEventsCategorizationEnabled should be false after experiment."
);
// Clean up.
prefBranch.setBoolPref(TELEMETRY_PREF, originalPrefValue);
});

View file

@ -1,8 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Test to verify we can toggle the Glean SERP telemetry feature via a Nimbus
// variable.
// Test to verify we can toggle the Glean SERP event telemetry feature via a
// Nimbus variable.
const lazy = {};

View file

@ -9,6 +9,8 @@
ChromeUtils.defineESModuleGetters(this, {
SearchSERPCategorization: "resource:///modules/SearchSERPTelemetry.sys.mjs",
SearchSERPDomainToCategoriesMap:
"resource:///modules/SearchSERPTelemetry.sys.mjs",
SearchUtils: "resource://gre/modules/SearchUtils.sys.mjs",
sinon: "resource://testing-common/Sinon.sys.mjs",
});
@ -58,6 +60,15 @@ const TEST_PROVIDER_INFO = [
},
];
const TEST_DOMAIN_TO_CATEGORIES_MAP = {
// foobar.org
"DqNorjpE3CBY9OZh0wf1uA==": [2, 90],
// abc.org
"kpuib0kvhtSp1moICEmGWg==": [2, 95],
// def.org
"+5WbbjV3Nmxp0mBZODcJWg==": [2, 78, 4, 10],
};
let stub;
add_setup(async function () {
SearchSERPTelemetry.overrideSearchTelemetryForTests(TEST_PROVIDER_INFO);
@ -84,6 +95,10 @@ add_setup(async function () {
add_task(async function test_categorization_reporting() {
resetTelemetry();
SearchSERPDomainToCategoriesMap.overrideMapForTests(
TEST_DOMAIN_TO_CATEGORIES_MAP
);
let url = getSERPUrl("searchTelemetryDomainCategorizationReporting.html");
info("Load a sample SERP with organic results.");
let promise = waitForPageWithCategorizedDomains();
@ -91,7 +106,7 @@ add_task(async function test_categorization_reporting() {
await promise;
// TODO: This needs to be refactored to actually test the reporting of the
// categorization.
// categorization. (Bug 1854692)
Assert.deepEqual(
Array.from(stub.getCall(0).args[0]),
["foobar.org"],
@ -106,3 +121,22 @@ add_task(async function test_categorization_reporting() {
BrowserTestUtils.removeTab(tab);
});
add_task(async function test_no_reporting_if_no_records() {
// Simulate a failure to download attachments from Remote Settings.
SearchSERPDomainToCategoriesMap.overrideMapForTests(null);
let url = getSERPUrl("searchTelemetryDomainCategorizationReporting.html");
info("Load a sample SERP with organic results.");
let promise = waitForPageWithCategorizedDomains();
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
await promise;
Assert.equal(
stub.getCall(2),
null,
"dummyLogger should not have been called if attachments weren't downloaded."
);
BrowserTestUtils.removeTab(tab);
});

View file

@ -91,6 +91,9 @@ export class ShoppingContainer extends MozLitElement {
// If we're not opted in or there's no shopping URL in the main browser,
// the actor will pass `null`, which means this will clear out any existing
// content in the sidebar.
if (!this.productUrl && productUrl && data) {
this.firstAnalysis = true;
}
this.data = data;
this.showOnboarding = showOnboarding;
this.productUrl = productUrl;
@ -109,6 +112,7 @@ export class ShoppingContainer extends MozLitElement {
case "NewAnalysisRequested":
case "ReanalysisRequested":
this.isAnalysisInProgress = true;
this.firstAnalysis = false;
this.analysisEvent = {
type: event.type,
productUrl: this.productUrl,
@ -200,14 +204,16 @@ export class ShoppingContainer extends MozLitElement {
}
if (this.data.needs_analysis) {
if (!this.data.product_id) {
// Product is not yet registered to our db and thus we cannot show any data.
let notEnoughReviews = !this.data.grade || !this.data.adjusted_rating;
if (!this.data.product_id || (this.firstAnalysis && notEnoughReviews)) {
// Product is either new to us or (bug 1848695) it's the initial page load of a product
// with not enough reviews.
return html`<unanalyzed-product-card
productUrl=${ifDefined(this.productUrl)}
></unanalyzed-product-card>`;
}
if (!this.data.grade || !this.data.adjusted_rating) {
if (notEnoughReviews) {
// We already saw and tried to analyze this product before, but there are not enough reviews
// to make a detailed analysis.
return html`<shopping-message-bar

View file

@ -5,3 +5,10 @@
### This file is not in a locales directory to prevent it from
### being translated as the feature is still in heavy development
### and strings are likely to change often.
# Dynamic subtitle. Sites are limited to Amazon, Walmart or Best Buy.
# Variables:
# $currentSite (str) - The current shopping page name
# $secondSite (str) - A second shopping page name
# $thirdSite (str) - A third shopping page name
shopping-onboarding-dynamic-subtitle-1 = See how reliable product reviews are on <b>{ $currentSite }</b> before you buy. Review checker, an experimental feature from { -brand-product-name }, is built right into the browser. It works on <b>{ $secondSite }</b> and <b>{ $thirdSite }</b>, too.

View file

@ -3,12 +3,9 @@
"use strict";
/**
* Tests that the correct shopping-message-bar component appears if there are not enough
* reviews to provided an analysis.
* The footer should be visible.
*/
add_task(async function test_not_enough_reviews() {
// Tests that the unanalyzed card is the card that is shown on the initial page load.
add_task(async function test_show_unanalyzed_on_initial_load() {
await BrowserTestUtils.withNewTab(
{
url: "about:shoppingsidebar",
@ -19,15 +16,9 @@ add_task(async function test_not_enough_reviews() {
browser,
MOCK_NOT_ENOUGH_REVIEWS_PRODUCT_RESPONSE
);
ok(
shoppingContainer.shoppingMessageBarEl,
"Got shopping-message-bar element"
);
is(
shoppingContainer.shoppingMessageBarType,
"not-enough-reviews",
"shopping-message-bar type should be correct"
shoppingContainer.unanalyzedProductEl,
"Got unanalyzed card on first try"
);
verifyAnalysisDetailsHidden(shoppingContainer);
@ -35,3 +26,55 @@ add_task(async function test_not_enough_reviews() {
}
);
});
add_task(async function test_show_not_enough_reviews_after_analysis() {
await BrowserTestUtils.withNewTab(
{
url: "about:shoppingsidebar",
gBrowser,
},
async browser => {
await SpecialPowers.spawn(
browser,
[MOCK_NOT_ENOUGH_REVIEWS_PRODUCT_RESPONSE],
async mockData => {
let shoppingContainer =
content.document.querySelector(
"shopping-container"
).wrappedJSObject;
shoppingContainer.data = Cu.cloneInto(mockData, content);
// Tell shopping container this is not the initial analysis.
shoppingContainer.firstAnalysis = false;
let messageBarVisiblePromise = ContentTaskUtils.waitForCondition(
() => {
return (
!!shoppingContainer.shoppingMessageBarEl &&
ContentTaskUtils.is_visible(
shoppingContainer.shoppingMessageBarEl
)
);
},
"Waiting for shopping-message-bar to be visible"
);
await messageBarVisiblePromise;
await shoppingContainer.updateComplete;
ok(
shoppingContainer.shoppingMessageBarEl,
"Got shopping-message-bar element"
);
is(
shoppingContainer.shoppingMessageBarEl?.getAttribute("type"),
"not-enough-reviews",
"shopping-message-bar type should be correct"
);
}
);
}
);
});

View file

@ -61,6 +61,11 @@ class WithCommonStyles extends MozLitElement {
context: { type: Object },
};
connectedCallback() {
super.connectedCallback();
this.classList.add("anonymous-content-host");
}
storyContent() {
if (this.story) {
return this.story();

View file

@ -35,15 +35,11 @@ add_task(async function test_resettingDefaults() {
// Origin infos for default permissions in the format [origin, type].
let originInfos = [
["https://www.mozilla.org", "uitour"],
["https://monitor.firefox.com", "uitour"],
["https://screenshots.firefox.com", "uitour"],
["https://support.mozilla.org", "uitour"],
["https://truecolors.firefox.com", "uitour"],
["about:home", "uitour"],
["about:newtab", "uitour"],
["https://addons.mozilla.org", "install"],
["https://support.mozilla.org", "remote-troubleshooting"],
["https://fpn.firefox.com", "install"],
["about:welcome", "autoplay-media"],
];

View file

@ -105,11 +105,17 @@ class _QuickSuggest {
* The currently active backend.
*/
get backend() {
return this.getFeature(
lazy.UrlbarPrefs.get("quickSuggestRustEnabled")
? "SuggestBackendRust"
: "SuggestBackendJs"
);
return lazy.UrlbarPrefs.get("quickSuggestRustEnabled")
? this.rustBackend
: this.jsBackend;
}
/**
* @returns {SuggestBackendRust}
* The Rust backend. Not used when the JS backend is enabled.
*/
get rustBackend() {
return this.#features.SuggestBackendRust;
}
/**

View file

@ -307,12 +307,15 @@ class ProviderQuickSuggest extends UrlbarProvider {
* @param {string} options.source
* The suggestion source, one of: "remote-settings", "merino", "rust"
* @param {string} options.provider
* This value depends on the value of `source`:
* - remote-settings: The name of the `BaseFeature` instance
* (`feature.name`) that manages the suggestion type.
* - merino: The name of the Merino provider that serves the suggestion
* type.
* - rust: The name of the suggestion type as defined in `suggest.udl`.
* This value depends on `source`. The possible values per source are:
*
* remote-settings:
* The name of the `BaseFeature` instance (`feature.name`) that manages
* the suggestion type
* merino:
* The name of the Merino provider that serves the suggestion type
* rust:
* The name of the suggestion type as defined in `suggest.udl`
* @returns {BaseFeature}
* The feature instance or null if no feature was found.
*/
@ -370,13 +373,10 @@ class ProviderQuickSuggest extends UrlbarProvider {
}
}
// `source` will be one of: "remote-settings", "merino"
// `source` will be one of: "remote-settings", "merino", "rust"
result.payload.source = suggestion.source;
// If the suggestion source is remote settings, `provider` will be the name
// of the `BaseFeature` instance (`feature.name`) that manages the
// suggestion type. If the source is Merino, it will be the name of the
// Merino provider that served the suggestion.
// `provider` depends on `source`. See `#getFeature()` for possible values.
result.payload.provider = suggestion.provider;
result.payload.telemetryType = this.#getSuggestionTelemetryType(suggestion);

View file

@ -115,6 +115,8 @@ urlbar:
`rs_adm_sponsored`,
`rs_amo`,
`rs_pocket`,
`rust_adm_nonsponsored`,
`rust_adm_sponsored`,
`search_engine`,
`search_history`,
`search_suggest`,
@ -241,6 +243,8 @@ urlbar:
`rs_adm_sponsored`,
`rs_amo`,
`rs_pocket`,
`rust_adm_nonsponsored`,
`rust_adm_sponsored`,
`search_engine`,
`search_history`,
`search_shortcut_button`,
@ -354,6 +358,8 @@ urlbar:
`rs_adm_sponsored`,
`rs_amo`,
`rs_pocket`,
`rust_adm_nonsponsored`,
`rust_adm_sponsored`,
`search_engine`,
`search_history`,
`search_suggest`,
@ -494,6 +500,8 @@ urlbar:
`rs_adm_sponsored`,
`rs_amo`,
`rs_pocket`,
`rust_adm_nonsponsored`,
`rust_adm_sponsored`,
`search_engine`,
`search_history`,
`search_suggest`,

View file

@ -53,11 +53,13 @@ export class BaseFeature {
/**
* @returns {Array}
* If the subclass's `shouldEnable` implementation depends on preferences
* instead of Nimbus variables, the subclass should override this getter and
* return their names in this array so that `enable()` can be called when
* they change. Names should be in the same format that `UrlbarPrefs.get()`
* expects.
* If the subclass's `shouldEnable` implementation depends on any prefs that
* are not fallbacks for Nimbus variables, the subclass should override this
* getter and return their names in this array so that `update()` can be
* called when they change. Names should be relative to `browser.urlbar.`.
* It doesn't hurt to include prefs that are fallbacks for Nimbus variables,
* it's just not necessary because `QuickSuggest` will update all features
* whenever a `urlbar` Nimbus variable or its fallback pref changes.
*/
get enablingPreferences() {
return null;

View file

@ -7,6 +7,7 @@ import { BaseFeature } from "resource:///modules/urlbar/private/BaseFeature.sys.
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
PromiseUtils: "resource://gre/modules/PromiseUtils.sys.mjs",
SuggestIngestionConstraints: "resource://gre/modules/RustSuggest.sys.mjs",
SuggestStore: "resource://gre/modules/RustSuggest.sys.mjs",
Suggestion: "resource://gre/modules/RustSuggest.sys.mjs",
@ -61,16 +62,43 @@ export class SuggestBackendRust extends BaseFeature {
}
async enable(enabled) {
// Create a new deferred. If one already exists, then this method is being
// re-entered. In that case, chain the old deferred's promise to the new one
// by resolving it when the new one is resolved. See `enablePromise`.
let oldDeferred = this.#enabledDeferred;
this.#enabledDeferred = lazy.PromiseUtils.defer();
this.#enabledDeferred.promise.then(() => oldDeferred?.resolve());
if (!enabled) {
this.#store = null;
this.#enabledDeferred.resolve();
} else {
let store = await this.#initStore(this.#storePath);
if (this.isEnabled) {
this.#store = store;
this.#enabledDeferred.resolve();
this.#enabledDeferred = null;
}
}
}
/**
* @returns {Promise|null}
* If the feature is currently being enabled or disabled (see `enable()`),
* this will be a promise that is resolved when the enable/disable is fully
* complete. On enable, the feature initializes the backing `SuggestStore`
* and performs ingestion, and the promise will be resolved once that's
* done. If enable/disable is not currently happening, this will be null.
*
* Since `enable()` is async, it can be re-entered. When that happens, any
* promises returned by this getter will not be resolved until the final
* call completes. (Currently only enable is actually async; disable is
* sync. Consumers should not rely on that behavior.)
*/
get enablePromise() {
return this.#enabledDeferred?.promise;
}
async query(searchString) {
this.logger.info("Handling query: " + JSON.stringify(searchString));
@ -151,6 +179,8 @@ export class SuggestBackendRust extends BaseFeature {
// The `SuggestStore` instance.
#store;
#enabledDeferred = null;
}
/**

View file

@ -607,7 +607,7 @@ add_task(async function selected_result_experimental_addon() {
await extension.unload();
});
add_task(async function selected_result_adm_sponsored() {
add_task(async function selected_result_rs_adm_sponsored() {
const cleanupQuickSuggest = await ensureQuickSuggestInit();
await doTest(async browser => {
@ -626,10 +626,10 @@ add_task(async function selected_result_adm_sponsored() {
]);
});
cleanupQuickSuggest();
await cleanupQuickSuggest();
});
add_task(async function selected_result_adm_nonsponsored() {
add_task(async function selected_result_rs_adm_nonsponsored() {
const cleanupQuickSuggest = await ensureQuickSuggestInit();
await doTest(async browser => {
@ -648,7 +648,7 @@ add_task(async function selected_result_adm_nonsponsored() {
]);
});
cleanupQuickSuggest();
await cleanupQuickSuggest();
});
add_task(async function selected_result_input_field() {
@ -699,7 +699,7 @@ add_task(async function selected_result_weather() {
]);
});
cleanupQuickSuggest();
await cleanupQuickSuggest();
await SpecialPowers.popPrefEnv();
});
@ -734,7 +734,7 @@ add_task(async function selected_result_navigational() {
]);
});
cleanupQuickSuggest();
await cleanupQuickSuggest();
});
add_task(async function selected_result_dynamic_wikipedia() {
@ -769,7 +769,7 @@ add_task(async function selected_result_dynamic_wikipedia() {
]);
});
cleanupQuickSuggest();
await cleanupQuickSuggest();
});
add_task(async function selected_result_search_shortcut_button() {
@ -986,6 +986,54 @@ add_task(async function selected_result_addons() {
]);
});
cleanupQuickSuggest();
await cleanupQuickSuggest();
await SpecialPowers.popPrefEnv();
});
add_task(async function selected_result_rust_adm_sponsored() {
const cleanupQuickSuggest = await ensureQuickSuggestInit({
rustEnabled: true,
});
await doTest(async browser => {
await openPopup("sponsored");
await selectRowByURL("https://example.com/sponsored");
await doEnter();
assertEngagementTelemetry([
{
selected_result: "rust_adm_sponsored",
selected_result_subtype: "",
selected_position: 2,
provider: "UrlbarProviderQuickSuggest",
results: "search_engine,rust_adm_sponsored",
},
]);
});
await cleanupQuickSuggest();
});
add_task(async function selected_result_rust_adm_nonsponsored() {
const cleanupQuickSuggest = await ensureQuickSuggestInit({
rustEnabled: true,
});
await doTest(async browser => {
await openPopup("nonsponsored");
await selectRowByURL("https://example.com/nonsponsored");
await doEnter();
assertEngagementTelemetry([
{
selected_result: "rust_adm_nonsponsored",
selected_result_subtype: "",
selected_position: 2,
provider: "UrlbarProviderQuickSuggest",
results: "search_engine,rust_adm_nonsponsored",
},
]);
});
await cleanupQuickSuggest();
});

View file

@ -6,6 +6,9 @@
// Test for the following data of engagement telemetry.
// - engagement_type
// This test has many subtests and can time out in verify mode.
requestLongerTimeout(5);
add_setup(async function () {
await setup();
});
@ -118,7 +121,7 @@ add_task(async function engagement_type_dismiss() {
await SpecialPowers.popPrefEnv();
}
cleanupQuickSuggest();
await cleanupQuickSuggest();
});
add_task(async function engagement_type_help() {
@ -147,5 +150,5 @@ add_task(async function engagement_type_help() {
await SpecialPowers.popPrefEnv();
}
cleanupQuickSuggest();
await cleanupQuickSuggest();
});

View file

@ -26,7 +26,7 @@ async function doExposureTest({
});
await SpecialPowers.popPrefEnv();
cleanupQuickSuggest();
await cleanupQuickSuggest();
}
async function defaultSelect(query) {

View file

@ -111,7 +111,7 @@ async function doTopPickTest({ trigger, assert }) {
});
await SpecialPowers.popPrefEnv();
cleanupQuickSuggest();
await cleanupQuickSuggest();
}
async function doTopSiteTest({ trigger, assert }) {
@ -223,7 +223,7 @@ async function doSuggestTest({ trigger, assert }) {
});
await SpecialPowers.popPrefEnv();
cleanupQuickSuggest();
await cleanupQuickSuggest();
}
async function doAboutPageTest({ trigger, assert }) {

View file

@ -90,13 +90,9 @@ function _assertGleanTelemetry(telemetryName, expectedExtraList) {
}
}
async function ensureQuickSuggestInit({
merinoSuggestions = undefined,
config = undefined,
} = {}) {
async function ensureQuickSuggestInit({ ...args } = {}) {
return lazy.QuickSuggestTestUtils.ensureQuickSuggestInit({
config,
merinoSuggestions,
...args,
remoteSettingsResults: [
{
type: "data",

View file

@ -382,15 +382,23 @@ class _QuickSuggestTestUtils {
* Merino without using this function by using `MerinoTestUtils` directly.
* @param {object} options.config
* The quick suggest configuration object.
* @param {object} options.rustEnabled
* Whether the Rust backend should be enabled. If false, the JS backend will
* be used. (There's no way to tell this function not to change the backend.
* If you need that, please modify this function to support it!)
* @returns {Function}
* A cleanup function. You only need to call this function if you're in a
* browser chrome test and you did not also call `init`. You can ignore it
* otherwise.
* An async cleanup function. This function is automatically registered as
* a cleanup function, so you only need to call it if your test needs to
* clean up quick suggest before it ends, for example if you have a small
* number of tasks that need quick suggest and it's not enabled throughout
* your test. The cleanup function is idempotent so there's no harm in
* calling it more than once. Be sure to `await` it.
*/
async ensureQuickSuggestInit({
remoteSettingsResults,
merinoSuggestions = null,
config = DEFAULT_CONFIG,
rustEnabled = false,
} = {}) {
this.#mockRemoteSettings = new MockRemoteSettings({
config,
@ -403,8 +411,23 @@ class _QuickSuggestTestUtils {
this.info?.("ensureQuickSuggestInit calling QuickSuggest.init()");
lazy.QuickSuggest.init();
// Sync with current data.
await this.#mockRemoteSettings.sync();
// Set the Rust pref and wait for the backend to become enabled/disabled.
// This must happen after setting up `MockRustSuggest`. Otherwise the real
// Rust component will be used and the Rust remote settings client will try
// to access the real remote settings server on ingestion.
this.info?.(
"ensureQuickSuggestInit setting rustEnabled and awaiting enablePromise"
);
lazy.UrlbarPrefs.set("quicksuggest.rustEnabled", rustEnabled);
await lazy.QuickSuggest.rustBackend.enablePromise;
this.info?.("ensureQuickSuggestInit done awaiting enablePromise");
if (!rustEnabled) {
// Sync with current data.
this.info?.("ensureQuickSuggestInit syncing MockRemoteSettings");
await this.#mockRemoteSettings.sync();
this.info?.("ensureQuickSuggestInit done syncing MockRemoteSettings");
}
// Set up Merino.
if (merinoSuggestions) {
@ -415,20 +438,51 @@ class _QuickSuggestTestUtils {
this.info?.("ensureQuickSuggestInit done setting up Merino server");
}
let cleanupCalled = false;
let cleanup = async () => {
this.info?.("ensureQuickSuggestInit starting cleanup");
this.#mockRemoteSettings.cleanup();
this.#mockRustSuggest.cleanup();
if (merinoSuggestions) {
lazy.UrlbarPrefs.clear("quicksuggest.dataCollection.enabled");
if (!cleanupCalled) {
cleanupCalled = true;
await this.#uninitQuickSuggest(!!merinoSuggestions);
}
this.info?.("ensureQuickSuggestInit finished cleanup");
};
this.registerCleanupFunction?.(cleanup);
return cleanup;
}
async #uninitQuickSuggest(clearDataCollectionEnabled) {
this.info?.("uninitQuickSuggest started");
// We need to reset the Rust enabled status. If the status changes, it will
// either trigger the Rust backend to enable itself and ingest from remote
// settings (if Rust was disabled) or trigger the JS backend to enable
// itself and re-sync all features (if Rust was enabled). Wait for each to
// finish *before* cleaning up MockRustSuggest and MockRemoteSettings. This
// will ensure that all activity has stopped before this function returns.
let rustEnabled = lazy.UrlbarPrefs.get("quicksuggest.rustEnabled");
lazy.UrlbarPrefs.clear("quicksuggest.rustEnabled");
this.info?.(
"uninitQuickSuggest setting rustEnabled and awaiting enablePromise"
);
await lazy.QuickSuggest.rustBackend.enablePromise;
this.info?.("uninitQuickSuggest done awaiting enablePromise");
if (rustEnabled && !lazy.UrlbarPrefs.get("quicksuggest.rustEnabled")) {
this.info?.("uninitQuickSuggest syncing MockRemoteSettings");
await this.#mockRemoteSettings.sync();
this.info?.("uninitQuickSuggest done syncing MockRemoteSettings");
}
this.#mockRemoteSettings.cleanup();
this.#mockRustSuggest.cleanup();
if (clearDataCollectionEnabled) {
lazy.UrlbarPrefs.clear("quicksuggest.dataCollection.enabled");
}
this.info?.("uninitQuickSuggest done");
}
/**
* Clears the current remote settings data and adds a new set of data.
* This can be used to add remote settings data after

View file

@ -321,7 +321,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "7ed03afa074cbb58a850c1864e96545ff8279fd0"
"revision": "edd314149ac0592de32769eb1233cccad7419cd6"
},
"cy": {
"pin": false,
@ -339,7 +339,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "f83c0cfb045efcc999ac5a296b25244c0a8f92ec"
"revision": "b78125482cc73fa984ac75eef36c6df18cda2f45"
},
"da": {
"pin": false,
@ -375,7 +375,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "d38a5a358798688665e465f8b43025934756d560"
"revision": "d7e14ce594e51ccb109cec65a9601251778dbb0d"
},
"dsb": {
"pin": false,
@ -969,7 +969,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "b8d152c431c0573bef5957a151d117445e423e17"
"revision": "01b557f9c9a4463f5bcf477871d58fbe57ada3ea"
},
"ja": {
"pin": false,
@ -1011,7 +1011,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "c18408d748ecc6e1418f20a3e7f5cfce4a7ad236"
"revision": "23a4ed422a2345ac0d80207269d99bd0cb9a18bc"
},
"kab": {
"pin": false,
@ -1299,7 +1299,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "6765bf6d7fe8dcc63bd84d01bb8bb95b7f4ad82b"
"revision": "dd12c884dd05498900c0106d1475424f4c6adce6"
},
"ne-NP": {
"pin": false,
@ -1353,7 +1353,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "cb663dfd8eff6a37e7792696eec1fcab238aec38"
"revision": "94d575c8194fc13193a2a2db10d4abcec8647f38"
},
"oc": {
"pin": false,
@ -1587,7 +1587,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "b27c3460e031af989eb49930279bb52e5e91fb74"
"revision": "652b4171d24d0415672f99258ada72f1224b9fa1"
},
"sk": {
"pin": false,
@ -1929,7 +1929,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "6f97487158703da81939322753d8f46b7d1cc20d"
"revision": "630181bf0415015cb2d576ab35fe0f8a0e3827f1"
},
"wo": {
"pin": false,
@ -1983,7 +1983,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "a408bb3b2bd87ee68da783ad086eabd0807af786"
"revision": "6ce46a6cd8e0841714b7b568c01b08b40f55ee69"
},
"zh-TW": {
"pin": false,

View file

@ -393,16 +393,9 @@
.urlbarView-dynamic-weather-bottom {
font-size: var(--urlbarView-small-font-size);
margin-top: 0.40em;
opacity: 0.6;
}
.urlbarView-row[dynamicType=weather][selected] > .urlbarView-row-inner > .urlbarView-dynamic-weather-summary {
> .urlbarView-dynamic-weather-top > .urlbarView-url {
color: inherit;
}
> .urlbarView-dynamic-weather-bottom {
opacity: 1;
.urlbarView-row[dynamicType=weather]:not([selected]) > .urlbarView-row-inner > .urlbarView-dynamic-weather-summary > & {
opacity: 0.6;
}
}

View file

@ -260,7 +260,7 @@
visibility: hidden;
}
.urlbarView-row[type=tabtosearch] > .urlbarView-row-inner > .urlbarView-no-wrap > & {
.urlbarView-row[type=tabtosearch]:not([selected]) > .urlbarView-row-inner > .urlbarView-no-wrap > & {
/* We use the URL color for this icon to inherit its accessibility
properties, like adapting to high contrast modes. We also want to ensure
contrast from the result highlight. */
@ -550,14 +550,19 @@
/* Title separator */
.urlbarView-title-separator::before {
content: "\2014";
margin: 0 .4em;
opacity: 0.6;
}
.urlbarView-title-separator {
&::before {
content: "\2014";
margin: 0 .4em;
opacity: 0.6;
}
.urlbarView-title:empty + .urlbarView-tags:empty + .urlbarView-title-separator {
display: none;
.urlbarView-title:empty + .urlbarView-tags:empty + &,
/* This targets both rich and non-rich results, so not using the child selector here. */
.urlbarView-row:is([type=search], [restyled-search]):not([selected], [show-action-text], :hover) &,
.urlbarView-row:not([has-action], [has-url], [restyled-search]) & {
display: none;
}
}
/* Action labels */
@ -607,25 +612,6 @@
}
}
.urlbarView-row[selected] > .urlbarView-row-inner > .urlbarView-url,
.urlbarView-row[rich-suggestion][selected] > .urlbarView-row-inner > .urlbarView-row-body > .urlbarView-row-body-top > .urlbarView-url,
.urlbarView-row[type=tabtosearch][selected] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-favicon {
color: inherit;
}
.urlbarView-row:is([type=remotetab], [sponsored]):not([selected], :hover) > .urlbarView-row-inner > .urlbarView-url,
.urlbarView-row:is([show-action-text], [restyled-search]) > .urlbarView-row-inner > .urlbarView-url,
.urlbarView-row:is([type=search], [restyled-search]):not([selected], [show-action-text], :hover) > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-title-separator,
.urlbarView-row:is([type=search], [restyled-search]):not([selected], [show-action-text], :hover) > .urlbarView-row-inner > .urlbarView-row-body > .urlbarView-row-body-top > .urlbarView-row-body-top-no-wrap > .urlbarView-title-separator,
.urlbarView-row:not([has-action], [has-url], [restyled-search]) > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-title-separator,
.urlbarView-row:not([has-action], [has-url], [restyled-search]) > .urlbarView-row-inner > .urlbarView-row-body > .urlbarView-row-body-top > .urlbarView-row-body-top-no-wrap > .urlbarView-title-separator,
.urlbarView:not([action-override]) .urlbarView-row[type=switchtab] > .urlbarView-row-inner > .urlbarView-url {
/* Use visibility:collapse instead of display:none since the latter can
confuse the overflow state of title and url elements when their content
changes while they're hidden. */
visibility: collapse;
}
/* Switch-to-tab action text is styled as a chiclet. */
.urlbarView-row:is([type=switchtab], [type=remotetab]) {
> .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-action {
@ -666,11 +652,24 @@
.urlbarView-url {
flex-grow: 1;
flex-shrink: 1;
color: var(--link-color);
font-size: var(--urlbarView-small-font-size);
/* Increase line-height to avoid cutting overhanging glyphs due to masking on
the element */
line-height: 1.4;
/* This targets both rich and non-rich results, so not using the child selector here. */
.urlbarView-row:not([selected]) & {
color: var(--link-color);
}
.urlbarView-row:is([type=remotetab], [sponsored]):not([selected], :hover) > .urlbarView-row-inner > &,
.urlbarView-row:is([show-action-text], [restyled-search]) > .urlbarView-row-inner > &,
.urlbarView:not([action-override]) .urlbarView-row[type=switchtab] > .urlbarView-row-inner > & {
/* Use visibility:collapse instead of display:none since the latter can
confuse the overflow state of these elements when their content
changes while they're hidden (bug 1549787). */
visibility: collapse;
}
}
/* Tags */

View file

@ -0,0 +1,18 @@
[package]
name = "bindgen"
version = "0.64.999"
edition = "2018"
license = "BSD-3-Clause"
[lib]
path = "lib.rs"
[dependencies.bindgen]
version = "0.66.0"
default-features = false
[features]
logging = ["bindgen/logging"]
runtime = ["bindgen/runtime"]
static = ["bindgen/static"]
which-rustfmt = ["bindgen/which-rustfmt"]

View file

@ -0,0 +1,26 @@
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pub use bindgen::*;

View file

@ -1,6 +1,6 @@
[package]
name = "bindgen"
version = "0.64.999"
version = "0.66.999"
edition = "2018"
license = "BSD-3-Clause"
@ -8,7 +8,7 @@ license = "BSD-3-Clause"
path = "lib.rs"
[dependencies.bindgen]
version = "0.66.0"
version = "0.68.0"
default-features = false
[features]

View file

@ -19,11 +19,4 @@ else
mk_add_options "export PATH=$MOZ_FETCHES_DIR/binutils/bin:$PATH"
fi
case "$PERFHERDER_EXTRA_OPTIONS" in
base-toolchains*)
# Clang versions < 8.0 don't support wasm.
export WASM_SANDBOXED_LIBRARIES=
;;
esac
. "$topsrcdir/build/unix/mozconfig.stdcxx"

View file

@ -49,7 +49,7 @@ uuid = { version = "1", features = ["serde", "v4"], optional = true }
scopeguard = { version = "1", optional = true }
[build-dependencies]
bindgen = { version = "0.66", default-features = false, features = ["runtime"], optional = true }
bindgen = { version = "0.68", default-features = false, features = ["runtime"], optional = true }
libc = "0.2"
memchr = { version = "2", optional = true }
nom = { version = "7", optional = true }

View file

@ -466,7 +466,7 @@ define make_default_rule
$(1):
endef
$(foreach dep, $(filter %.h,$(RUST_LIBRARY_DEPS)),$(eval $(call make_default_rule,$(dep))))
$(foreach dep, $(RUST_LIBRARY_DEPS),$(eval $(call make_default_rule,$(dep))))
SUGGEST_INSTALL_ON_FAILURE = (ret=$$?; if [ $$ret = 101 ]; then echo If $1 is not installed, install it using: cargo install $1; fi; exit $$ret)
@ -548,7 +548,7 @@ define RUST_PROGRAM_DEPENDENCIES
$(1)_deps := $(wordlist 2, 10000000, $(if $(wildcard $(1).d),$(shell cat $(1).d)))
$(1): $(CARGO_FILE) $(call resfile,module) $(if $$($(1)_deps),$$($(1)_deps),force-cargo-program-build)
$(if $$($(1)_deps),+$(MAKE) force-cargo-program-build,:)
$(foreach dep,$(filter %.h,$$($(1)_deps)),$(eval $(call make_default_rule,$(dep))))
$(foreach dep,$$($(1)_deps),$(eval $(call make_default_rule,$(dep))))
endef
$(foreach RUST_PROGRAM,$(RUST_PROGRAMS), $(eval $(call RUST_PROGRAM_DEPENDENCIES,$(RUST_PROGRAM))))

View file

@ -493,7 +493,7 @@ $(LIBRARY): $(OBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
$(WASM_ARCHIVE): $(CWASMOBJS) $(CPPWASMOBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
$(REPORT_BUILD_VERBOSE)
$(RM) $(WASM_ARCHIVE)
$(WASM_CXX) -o $@ -Wl,--export-all -Wl,--stack-first -Wl,-z,stack-size=$(if $(MOZ_OPTIMIZE),262144,1048576) -Wl,--no-entry -Wl,--import-memory -Wl,--import-table $(CWASMOBJS) $(CPPWASMOBJS) -lwasi-emulated-process-clocks
$(WASM_CXX) -o $@ -Wl,--export-all -Wl,--stack-first -Wl,-z,stack-size=$(if $(MOZ_OPTIMIZE),262144,1048576) -Wl,--no-entry -Wl,--import-memory -Wl,--import-table $(CWASMOBJS) $(CPPWASMOBJS) $(addprefix -l,$(WASM_LIBS))
ifeq ($(OS_ARCH),WINNT)
# Import libraries are created by the rules creating shared libraries.

View file

@ -1,16 +1,16 @@
/* 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 { div, input } from "react-dom-factories";
import { div, input, label } from "react-dom-factories";
import PropTypes from "prop-types";
export default function ExceptionOption({
className,
isChecked = false,
label,
label: inputLabel,
onChange,
}) {
return div(
return label(
{
className,
onClick: onChange,
@ -24,7 +24,7 @@ export default function ExceptionOption({
{
className: "breakpoint-exceptions-label",
},
label
inputLabel
)
);
}

View file

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ExceptionOption renders with values 1`] = `
<div
<label
className="testClassName"
onClick={[Function]}
>
@ -15,5 +15,5 @@ exports[`ExceptionOption renders with values 1`] = `
>
testLabel
</div>
</div>
</label>
`;

View file

@ -11,6 +11,13 @@
white-space: nowrap;
background-color: var(--theme-sidebar-background);
--breakpoint-expression-right-clear-space: 36px;
--paused-background-color: hsl(54, 100%, 92%);
--paused-color: var(--theme-body-color);
.theme-dark & {
--paused-background-color: hsl(42, 37%, 19%);
--paused-color: hsl(43, 94%, 81%);
}
}
.secondary-panes .controlled > div {

View file

@ -3,7 +3,7 @@
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
import React, { Component } from "react";
import { div } from "react-dom-factories";
import { div, span } from "react-dom-factories";
import PropTypes from "prop-types";
import { connect } from "../../utils/connect";
@ -39,6 +39,7 @@ export class Thread extends Component {
{
className: classnames("thread", {
selected: thread.actor == currentThread,
paused: isPaused,
}),
key: thread.actor,
onClick: this.onSelectThread,
@ -58,13 +59,12 @@ export class Thread extends Component {
label
),
isPaused
? div(
? span(
{
className: "pause-badge",
role: "status",
},
React.createElement(AccessibleImage, {
className: "pause",
})
L10N.getStr("pausedThread")
)
: null
);

View file

@ -20,19 +20,29 @@
cursor: pointer;
display: flex;
align-items: center;
}
gap: 4px;
.threads-list > .thread:hover {
background-color: var(--search-overlays-semitransparent);
}
&:hover {
background-color: var(--search-overlays-semitransparent);
}
.threads-list > .thread.selected {
background-color: var(--tab-line-selected-color);
&.selected {
background: var(--theme-selection-background);
color: var(--theme-selection-color);
& .img {
background-color: currentColor;
}
}
&.paused:not(.selected) {
background-color: var(--paused-background-color);
color: var(--paused-color);
}
}
.threads-list .icon {
flex: none;
margin-inline-end: 4px;
}
.threads-list .img {
@ -50,14 +60,5 @@
.threads-list .pause-badge {
flex: none;
margin-inline-start: 4px;
}
.threads-list > .thread.selected {
background: var(--theme-selection-background);
color: var(--theme-selection-color);
}
.threads-list > .thread.selected .img {
background-color: currentColor;
font-weight: bold;
}

View file

@ -7,8 +7,8 @@
flex-direction: column;
justify-content: center;
border-bottom: 1px solid var(--theme-splitter-color);
background-color: hsl(54, 100%, 92%);
color: var(--theme-body-color);
background-color: var(--paused-background-color);
color: var(--paused-color);
font-size: 12px;
cursor: default;
min-height: 44px;
@ -36,11 +36,6 @@
padding-right: 4px;
}
.theme-dark .secondary-panes .why-paused {
background-color: hsl(42, 37%, 19%);
color: hsl(43, 94%, 81%);
}
.why-paused .message {
font-style: italic;
font-weight: 100;

View file

@ -32,7 +32,7 @@ exports[`XHR Breakpoints should render with 0 expressions passed from props 1`]
label="Pause on any URL"
onChange={[Function]}
>
<div
<label
className="breakpoints-exceptions"
onClick={[Function]}
>
@ -46,7 +46,7 @@ exports[`XHR Breakpoints should render with 0 expressions passed from props 1`]
>
Pause on any URL
</div>
</div>
</label>
</ExceptionOption>
</div>
<form
@ -228,7 +228,7 @@ exports[`XHR Breakpoints should render with 8 expressions passed from props 1`]
label="Pause on any URL"
onChange={[Function]}
>
<div
<label
className="breakpoints-exceptions"
onClick={[Function]}
>
@ -242,7 +242,7 @@ exports[`XHR Breakpoints should render with 8 expressions passed from props 1`]
>
Pause on any URL
</div>
</div>
</label>
</ExceptionOption>
</div>
<ul

View file

@ -13,6 +13,9 @@ const TEST_ORG_IFRAME_URI = `${URL_ROOT_ORG_SSL}examples/doc_dbg-fission-frame-s
const DATA_URI = "data:text/html,<title>foo</title>";
add_task(async function () {
// Make sure that the thread section is expanded
await pushPref("devtools.debugger.threads-visible", true);
// Load a test page with a remote frame and wait for both sources to be visible.
// simple1.js is imported by the main page. simple2.js comes from the frame.
const dbg = await initDebuggerWithAbsoluteURL(

View file

@ -18,6 +18,17 @@ add_task(async function () {
selectors: { getSelectedSource },
} = dbg;
// Check threads
await waitForElement(dbg, "threadsPaneItems");
let threadsEl = findAllElements(dbg, "threadsPaneItems");
is(threadsEl.length, 2, "There are two threads in the thread panel");
ok(
Array.from(threadsEl).every(
el => !isThreadElementPaused(el) && !getThreadElementPausedBadge(el)
),
"No threads are paused"
);
// Add breakpoint within the iframe, which is hit early on load
await selectSource(dbg, "simple2.js");
await addBreakpoint(dbg, "simple2.js", 7);
@ -35,6 +46,38 @@ add_task(async function () {
await waitForPaused(dbg);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 7);
await waitForElement(dbg, "threadsPaneItems");
threadsEl = findAllElements(dbg, "threadsPaneItems");
is(threadsEl.length, 2, "There are two threads in the thread panel");
const [mainThreadEl, remoteThreadEl] = threadsEl;
is(
mainThreadEl.textContent,
"Main Thread",
"first thread displayed is the main thread"
);
ok(
!isThreadElementPaused(mainThreadEl),
"Main Thread does not have the paused styling"
);
ok(
!getThreadElementPausedBadge(mainThreadEl),
"Main Thread does not have a paused badge"
);
ok(
remoteThreadEl.textContent.startsWith(URL_ROOT_ORG_SSL),
"second thread displayed is the remote thread"
);
ok(
isThreadElementPaused(remoteThreadEl),
"paused thread has the paused styling"
);
is(
getThreadElementPausedBadge(remoteThreadEl).textContent,
"paused",
"paused badge is displayed in the remote thread item"
);
await stepIn(dbg);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 7);
@ -48,3 +91,11 @@ add_task(async function () {
await dbg.toolbox.closeToolbox();
});
function isThreadElementPaused(el) {
return el.classList.contains("paused");
}
function getThreadElementPausedBadge(el) {
return el.querySelector(".pause-badge");
}

View file

@ -1783,7 +1783,7 @@ const selectors = {
projectSearchRefreshButton: ".project-text-search button.refresh-btn",
threadsPaneItems: ".threads-pane .thread",
threadsPaneItem: i => `.threads-pane .thread:nth-child(${i})`,
threadsPaneItemPause: i => `${selectors.threadsPaneItem(i)} .pause-badge`,
threadsPaneItemPause: i => `${selectors.threadsPaneItem(i)}.paused`,
CodeMirrorLines: ".CodeMirror-lines",
inlinePreviewLabels: ".inline-preview .inline-preview-label",
inlinePreviewValues: ".inline-preview .inline-preview-value",

View file

@ -181,6 +181,9 @@ threadsHeader=Threads
# program as opposed to worker threads.
mainThread=Main Thread
# LOCALIZATION NOTE (pausedThread): The text to describe the status of paused threads
pausedThread=paused
# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list
# when there are no sources.
noSourcesText=This page has no sources.

View file

@ -152,6 +152,14 @@ blockedrequest.label=Blocked by DevTools
# Tooltip shown for disabled console messages
webconsole.disableIcon.title=This message is no longer active, message details are not available
# LOCALIZATION NOTE (command.title)
# Tooltip shown for console input evaluated code displayed in the console output
command.title=Evaluated code
# LOCALIZATION NOTE (result.title)
# Tooltip shown for evaluation result displayed in the console output
result.title=Evaluation result
# LOCALIZATION NOTE (webconsole.find.key)
# Key shortcut used to focus the search box on upper right of the console
webconsole.find.key=CmdOrCtrl+F

View file

@ -1,13 +1,13 @@
# wasmparser version
Current version is: 5.7.0
Current version is: 5.8.0
# Upgrade process
1. Pull latest release from npm and extract WasmDis.js and WasmParser.js, e.g.
```
curl https://registry.npmjs.org/wasmparser/-/wasmparser-5.7.0.tgz | tar -zx --strip-components 3 package/dist/cjs/{WasmDis,WasmParser}.js
curl https://registry.npmjs.org/wasmparser/-/wasmparser-5.8.0.tgz | tar -zx --strip-components 3 package/dist/cjs/{WasmDis,WasmParser}.js
```
2. Remove reference to source maps (last line)

View file

@ -119,6 +119,8 @@ function memoryAddressToString(address, code) {
case 65090 /* OperatorCode.i64_atomic_rmw_xchg */:
case 65097 /* OperatorCode.i64_atomic_rmw_cmpxchg */:
case 1036381 /* OperatorCode.v128_load64_zero */:
case 1036375 /* OperatorCode.v128_load64_lane */:
case 1036379 /* OperatorCode.v128_store64_lane */:
defaultAlignFlags = 3;
break;
case 40 /* OperatorCode.i32_load */:
@ -149,6 +151,8 @@ function memoryAddressToString(address, code) {
case 65096 /* OperatorCode.i32_atomic_rmw_cmpxchg */:
case 65102 /* OperatorCode.i64_atomic_rmw32_cmpxchg_u */:
case 1036380 /* OperatorCode.v128_load32_zero */:
case 1036374 /* OperatorCode.v128_load32_lane */:
case 1036378 /* OperatorCode.v128_store32_lane */:
defaultAlignFlags = 2;
break;
case 46 /* OperatorCode.i32_load16_s */:
@ -175,6 +179,8 @@ function memoryAddressToString(address, code) {
case 65094 /* OperatorCode.i64_atomic_rmw16_xchg_u */:
case 65099 /* OperatorCode.i32_atomic_rmw16_cmpxchg_u */:
case 65101 /* OperatorCode.i64_atomic_rmw16_cmpxchg_u */:
case 1036373 /* OperatorCode.v128_load16_lane */:
case 1036377 /* OperatorCode.v128_store16_lane */:
defaultAlignFlags = 1;
break;
case 44 /* OperatorCode.i32_load8_s */:
@ -201,6 +207,8 @@ function memoryAddressToString(address, code) {
case 65093 /* OperatorCode.i64_atomic_rmw8_xchg_u */:
case 65098 /* OperatorCode.i32_atomic_rmw8_cmpxchg_u */:
case 65100 /* OperatorCode.i64_atomic_rmw8_cmpxchg_u */:
case 1036372 /* OperatorCode.v128_load8_lane */:
case 1036376 /* OperatorCode.v128_store8_lane */:
defaultAlignFlags = 0;
break;
}
@ -466,17 +474,17 @@ var WasmDisassembler = /** @class */ (function () {
return "any";
case -19 /* TypeKind.eqref */:
return "eq";
case -22 /* TypeKind.i31ref */:
case -20 /* TypeKind.i31ref */:
return "i31";
case -25 /* TypeKind.structref */:
case -21 /* TypeKind.structref */:
return "struct";
case -26 /* TypeKind.arrayref */:
case -22 /* TypeKind.arrayref */:
return "array";
case -24 /* TypeKind.nullfuncref */:
case -13 /* TypeKind.nullfuncref */:
return "nofunc";
case -23 /* TypeKind.nullexternref */:
case -14 /* TypeKind.nullexternref */:
return "noextern";
case -27 /* TypeKind.nullref */:
case -15 /* TypeKind.nullref */:
return "none";
}
};
@ -492,9 +500,9 @@ var WasmDisassembler = /** @class */ (function () {
return "f64";
case -5 /* TypeKind.v128 */:
return "v128";
case -6 /* TypeKind.i8 */:
case -8 /* TypeKind.i8 */:
return "i8";
case -7 /* TypeKind.i16 */:
case -9 /* TypeKind.i16 */:
return "i16";
case -16 /* TypeKind.funcref */:
return "funcref";
@ -504,21 +512,21 @@ var WasmDisassembler = /** @class */ (function () {
return "anyref";
case -19 /* TypeKind.eqref */:
return "eqref";
case -22 /* TypeKind.i31ref */:
case -20 /* TypeKind.i31ref */:
return "i31ref";
case -25 /* TypeKind.structref */:
case -21 /* TypeKind.structref */:
return "structref";
case -26 /* TypeKind.arrayref */:
case -22 /* TypeKind.arrayref */:
return "arrayref";
case -24 /* TypeKind.nullfuncref */:
case -13 /* TypeKind.nullfuncref */:
return "nullfuncref";
case -23 /* TypeKind.nullexternref */:
case -14 /* TypeKind.nullexternref */:
return "nullexternref";
case -27 /* TypeKind.nullref */:
case -15 /* TypeKind.nullref */:
return "nullref";
case -21 /* TypeKind.ref */:
case -28 /* TypeKind.ref */:
return "(ref ".concat(this.typeIndexToString(type.ref_index), ")");
case -20 /* TypeKind.ref_null */:
case -29 /* TypeKind.ref_null */:
return "(ref null ".concat(this.typeIndexToString(type.ref_index), ")");
default:
throw new Error("Unexpected type ".concat(JSON.stringify(type)));
@ -670,22 +678,13 @@ var WasmDisassembler = /** @class */ (function () {
break;
case 12 /* OperatorCode.br */:
case 13 /* OperatorCode.br_if */:
case 212 /* OperatorCode.br_on_null */:
case 213 /* OperatorCode.br_on_null */:
case 214 /* OperatorCode.br_on_non_null */:
this.appendBuffer(" ");
this.appendBuffer(this.useLabel(operator.brDepth));
break;
case 64322 /* OperatorCode.br_on_cast_ */:
case 64323 /* OperatorCode.br_on_cast_fail_ */:
case 64326 /* OperatorCode.br_on_cast__ */:
case 64327 /* OperatorCode.br_on_cast_fail__ */:
this.appendBuffer(" ");
this.appendBuffer(this.typeIndexToString(operator.refType));
this.appendBuffer(" ");
this.appendBuffer(this.useLabel(operator.brDepth));
break;
case 64334 /* OperatorCode.br_on_cast */:
case 64335 /* OperatorCode.br_on_cast_fail */:
case 64280 /* OperatorCode.br_on_cast */:
case 64281 /* OperatorCode.br_on_cast_fail */:
this.appendBuffer(" flags=" + operator.literal);
this.appendBuffer(" ");
this.appendBuffer(this.typeIndexToString(operator.srcType));
@ -889,6 +888,21 @@ var WasmDisassembler = /** @class */ (function () {
case 1036322 /* OperatorCode.f64x2_replace_lane */:
this.appendBuffer(" ".concat(operator.lineIndex));
break;
case 1036372 /* OperatorCode.v128_load8_lane */:
case 1036373 /* OperatorCode.v128_load16_lane */:
case 1036374 /* OperatorCode.v128_load32_lane */:
case 1036375 /* OperatorCode.v128_load64_lane */:
case 1036376 /* OperatorCode.v128_store8_lane */:
case 1036377 /* OperatorCode.v128_store16_lane */:
case 1036378 /* OperatorCode.v128_store32_lane */:
case 1036379 /* OperatorCode.v128_store64_lane */:
var memoryAddress = memoryAddressToString(operator.memoryAddress, operator.code);
if (memoryAddress !== null) {
this.appendBuffer(" ");
this.appendBuffer(memoryAddress);
}
this.appendBuffer(" ".concat(operator.lineIndex));
break;
case 64520 /* OperatorCode.memory_init */:
case 64521 /* OperatorCode.data_drop */:
this.appendBuffer(" ".concat(operator.segmentIndex));
@ -923,46 +937,43 @@ var WasmDisassembler = /** @class */ (function () {
this.appendBuffer(" ".concat(elementName_1));
break;
}
case 64259 /* OperatorCode.struct_get */:
case 64260 /* OperatorCode.struct_get_s */:
case 64261 /* OperatorCode.struct_get_u */:
case 64262 /* OperatorCode.struct_set */: {
case 64258 /* OperatorCode.struct_get */:
case 64259 /* OperatorCode.struct_get_s */:
case 64260 /* OperatorCode.struct_get_u */:
case 64261 /* OperatorCode.struct_set */: {
var refType = this.typeIndexToString(operator.refType);
var fieldName = this._nameResolver.getFieldName(operator.refType, operator.fieldIndex, true);
this.appendBuffer(" ".concat(refType, " ").concat(fieldName));
break;
}
case 64304 /* OperatorCode.rtt_canon */:
case 64305 /* OperatorCode.rtt_sub */:
case 64306 /* OperatorCode.rtt_fresh_sub */:
case 64321 /* OperatorCode.ref_cast */:
case 64329 /* OperatorCode.ref_cast_null */:
case 64320 /* OperatorCode.ref_test */:
case 64328 /* OperatorCode.ref_test_null */:
case 64264 /* OperatorCode.struct_new_default */:
case 64258 /* OperatorCode.struct_new_default_with_rtt */:
case 64263 /* OperatorCode.struct_new */:
case 64257 /* OperatorCode.struct_new_with_rtt */:
case 64284 /* OperatorCode.array_new_default */:
case 64274 /* OperatorCode.array_new_default_with_rtt */:
case 64283 /* OperatorCode.array_new */:
case 64273 /* OperatorCode.array_new_with_rtt */:
case 64275 /* OperatorCode.array_get */:
case 64276 /* OperatorCode.array_get_s */:
case 64277 /* OperatorCode.array_get_u */:
case 64278 /* OperatorCode.array_set */:
case 64279 /* OperatorCode.array_len_ */: {
case 64278 /* OperatorCode.ref_cast */:
case 64279 /* OperatorCode.ref_cast_null */:
case 64276 /* OperatorCode.ref_test */:
case 64277 /* OperatorCode.ref_test_null */:
case 64257 /* OperatorCode.struct_new_default */:
case 64256 /* OperatorCode.struct_new */:
case 64263 /* OperatorCode.array_new_default */:
case 64262 /* OperatorCode.array_new */:
case 64267 /* OperatorCode.array_get */:
case 64268 /* OperatorCode.array_get_s */:
case 64269 /* OperatorCode.array_get_u */:
case 64270 /* OperatorCode.array_set */: {
var refType = this.typeIndexToString(operator.refType);
this.appendBuffer(" ".concat(refType));
break;
}
case 64280 /* OperatorCode.array_copy */: {
case 64272 /* OperatorCode.array_fill */: {
var dstType = this.typeIndexToString(operator.refType);
this.appendBuffer(" ".concat(dstType));
break;
}
case 64273 /* OperatorCode.array_copy */: {
var dstType = this.typeIndexToString(operator.refType);
var srcType = this.typeIndexToString(operator.srcType);
this.appendBuffer(" ".concat(dstType, " ").concat(srcType));
break;
}
case 64282 /* OperatorCode.array_new_fixed */: {
case 64264 /* OperatorCode.array_new_fixed */: {
var refType = this.typeIndexToString(operator.refType);
var length_1 = operator.len;
this.appendBuffer(" ".concat(refType, " ").concat(length_1));

View file

@ -271,9 +271,9 @@ var OperatorCode;
OperatorCode[OperatorCode["ref_null"] = 208] = "ref_null";
OperatorCode[OperatorCode["ref_is_null"] = 209] = "ref_is_null";
OperatorCode[OperatorCode["ref_func"] = 210] = "ref_func";
OperatorCode[OperatorCode["ref_as_non_null"] = 211] = "ref_as_non_null";
OperatorCode[OperatorCode["br_on_null"] = 212] = "br_on_null";
OperatorCode[OperatorCode["ref_eq"] = 213] = "ref_eq";
OperatorCode[OperatorCode["ref_eq"] = 211] = "ref_eq";
OperatorCode[OperatorCode["ref_as_non_null"] = 212] = "ref_as_non_null";
OperatorCode[OperatorCode["br_on_null"] = 213] = "br_on_null";
OperatorCode[OperatorCode["br_on_non_null"] = 214] = "br_on_non_null";
OperatorCode[OperatorCode["memory_atomic_notify"] = 65024] = "memory_atomic_notify";
OperatorCode[OperatorCode["memory_atomic_wait32"] = 65025] = "memory_atomic_wait32";
@ -599,72 +599,38 @@ var OperatorCode;
OperatorCode[OperatorCode["i16x8_relaxed_q15mulr_s"] = 1036561] = "i16x8_relaxed_q15mulr_s";
OperatorCode[OperatorCode["i16x8_dot_i8x16_i7x16_s"] = 1036562] = "i16x8_dot_i8x16_i7x16_s";
OperatorCode[OperatorCode["i32x4_dot_i8x16_i7x16_add_s"] = 1036563] = "i32x4_dot_i8x16_i7x16_add_s";
// GC proposal (milestone 6).
OperatorCode[OperatorCode["struct_new_with_rtt"] = 64257] = "struct_new_with_rtt";
OperatorCode[OperatorCode["struct_new_default_with_rtt"] = 64258] = "struct_new_default_with_rtt";
OperatorCode[OperatorCode["struct_get"] = 64259] = "struct_get";
OperatorCode[OperatorCode["struct_get_s"] = 64260] = "struct_get_s";
OperatorCode[OperatorCode["struct_get_u"] = 64261] = "struct_get_u";
OperatorCode[OperatorCode["struct_set"] = 64262] = "struct_set";
OperatorCode[OperatorCode["struct_new"] = 64263] = "struct_new";
OperatorCode[OperatorCode["struct_new_default"] = 64264] = "struct_new_default";
OperatorCode[OperatorCode["array_fill"] = 64271] = "array_fill";
OperatorCode[OperatorCode["array_new_with_rtt"] = 64273] = "array_new_with_rtt";
OperatorCode[OperatorCode["array_new_default_with_rtt"] = 64274] = "array_new_default_with_rtt";
OperatorCode[OperatorCode["array_get"] = 64275] = "array_get";
OperatorCode[OperatorCode["array_get_s"] = 64276] = "array_get_s";
OperatorCode[OperatorCode["array_get_u"] = 64277] = "array_get_u";
OperatorCode[OperatorCode["array_set"] = 64278] = "array_set";
OperatorCode[OperatorCode["array_len_"] = 64279] = "array_len_";
OperatorCode[OperatorCode["array_len"] = 64281] = "array_len";
OperatorCode[OperatorCode["array_copy"] = 64280] = "array_copy";
OperatorCode[OperatorCode["array_new_fixed"] = 64282] = "array_new_fixed";
OperatorCode[OperatorCode["array_new"] = 64283] = "array_new";
OperatorCode[OperatorCode["array_new_default"] = 64284] = "array_new_default";
OperatorCode[OperatorCode["array_new_data"] = 64285] = "array_new_data";
OperatorCode[OperatorCode["array_init_from_data"] = 64286] = "array_init_from_data";
OperatorCode[OperatorCode["array_new_elem"] = 64287] = "array_new_elem";
OperatorCode[OperatorCode["i31_new"] = 64288] = "i31_new";
OperatorCode[OperatorCode["i31_get_s"] = 64289] = "i31_get_s";
OperatorCode[OperatorCode["i31_get_u"] = 64290] = "i31_get_u";
OperatorCode[OperatorCode["rtt_canon"] = 64304] = "rtt_canon";
OperatorCode[OperatorCode["rtt_sub"] = 64305] = "rtt_sub";
OperatorCode[OperatorCode["rtt_fresh_sub"] = 64306] = "rtt_fresh_sub";
OperatorCode[OperatorCode["ref_test"] = 64320] = "ref_test";
OperatorCode[OperatorCode["ref_cast"] = 64321] = "ref_cast";
OperatorCode[OperatorCode["br_on_cast_"] = 64322] = "br_on_cast_";
OperatorCode[OperatorCode["br_on_cast_fail_"] = 64323] = "br_on_cast_fail_";
OperatorCode[OperatorCode["ref_test_"] = 64324] = "ref_test_";
OperatorCode[OperatorCode["ref_cast_"] = 64325] = "ref_cast_";
OperatorCode[OperatorCode["br_on_cast__"] = 64326] = "br_on_cast__";
OperatorCode[OperatorCode["br_on_cast_fail__"] = 64327] = "br_on_cast_fail__";
OperatorCode[OperatorCode["ref_test_null"] = 64328] = "ref_test_null";
OperatorCode[OperatorCode["ref_cast_null"] = 64329] = "ref_cast_null";
OperatorCode[OperatorCode["br_on_cast_null_"] = 64330] = "br_on_cast_null_";
OperatorCode[OperatorCode["br_on_cast_fail_null_"] = 64331] = "br_on_cast_fail_null_";
OperatorCode[OperatorCode["ref_cast_nop"] = 64332] = "ref_cast_nop";
OperatorCode[OperatorCode["br_on_cast"] = 64334] = "br_on_cast";
OperatorCode[OperatorCode["br_on_cast_fail"] = 64335] = "br_on_cast_fail";
OperatorCode[OperatorCode["ref_is_func_"] = 64336] = "ref_is_func_";
OperatorCode[OperatorCode["ref_is_data_"] = 64337] = "ref_is_data_";
OperatorCode[OperatorCode["ref_is_i31_"] = 64338] = "ref_is_i31_";
OperatorCode[OperatorCode["ref_is_array_"] = 64339] = "ref_is_array_";
OperatorCode[OperatorCode["array_init_data"] = 64340] = "array_init_data";
OperatorCode[OperatorCode["array_init_elem"] = 64341] = "array_init_elem";
OperatorCode[OperatorCode["ref_as_func_"] = 64344] = "ref_as_func_";
OperatorCode[OperatorCode["ref_as_data_"] = 64345] = "ref_as_data_";
OperatorCode[OperatorCode["ref_as_i31_"] = 64346] = "ref_as_i31_";
OperatorCode[OperatorCode["ref_as_array_"] = 64347] = "ref_as_array_";
OperatorCode[OperatorCode["br_on_func_"] = 64352] = "br_on_func_";
OperatorCode[OperatorCode["br_on_data_"] = 64353] = "br_on_data_";
OperatorCode[OperatorCode["br_on_i31_"] = 64354] = "br_on_i31_";
OperatorCode[OperatorCode["br_on_non_func_"] = 64355] = "br_on_non_func_";
OperatorCode[OperatorCode["br_on_non_data_"] = 64356] = "br_on_non_data_";
OperatorCode[OperatorCode["br_on_non_i31_"] = 64357] = "br_on_non_i31_";
OperatorCode[OperatorCode["br_on_array_"] = 64358] = "br_on_array_";
OperatorCode[OperatorCode["br_on_non_array_"] = 64359] = "br_on_non_array_";
OperatorCode[OperatorCode["extern_internalize"] = 64368] = "extern_internalize";
OperatorCode[OperatorCode["extern_externalize"] = 64369] = "extern_externalize";
// GC proposal.
OperatorCode[OperatorCode["struct_new"] = 64256] = "struct_new";
OperatorCode[OperatorCode["struct_new_default"] = 64257] = "struct_new_default";
OperatorCode[OperatorCode["struct_get"] = 64258] = "struct_get";
OperatorCode[OperatorCode["struct_get_s"] = 64259] = "struct_get_s";
OperatorCode[OperatorCode["struct_get_u"] = 64260] = "struct_get_u";
OperatorCode[OperatorCode["struct_set"] = 64261] = "struct_set";
OperatorCode[OperatorCode["array_new"] = 64262] = "array_new";
OperatorCode[OperatorCode["array_new_default"] = 64263] = "array_new_default";
OperatorCode[OperatorCode["array_new_fixed"] = 64264] = "array_new_fixed";
OperatorCode[OperatorCode["array_new_data"] = 64265] = "array_new_data";
OperatorCode[OperatorCode["array_new_elem"] = 64266] = "array_new_elem";
OperatorCode[OperatorCode["array_get"] = 64267] = "array_get";
OperatorCode[OperatorCode["array_get_s"] = 64268] = "array_get_s";
OperatorCode[OperatorCode["array_get_u"] = 64269] = "array_get_u";
OperatorCode[OperatorCode["array_set"] = 64270] = "array_set";
OperatorCode[OperatorCode["array_len"] = 64271] = "array_len";
OperatorCode[OperatorCode["array_fill"] = 64272] = "array_fill";
OperatorCode[OperatorCode["array_copy"] = 64273] = "array_copy";
OperatorCode[OperatorCode["array_init_data"] = 64274] = "array_init_data";
OperatorCode[OperatorCode["array_init_elem"] = 64275] = "array_init_elem";
OperatorCode[OperatorCode["ref_test"] = 64276] = "ref_test";
OperatorCode[OperatorCode["ref_test_null"] = 64277] = "ref_test_null";
OperatorCode[OperatorCode["ref_cast"] = 64278] = "ref_cast";
OperatorCode[OperatorCode["ref_cast_null"] = 64279] = "ref_cast_null";
OperatorCode[OperatorCode["br_on_cast"] = 64280] = "br_on_cast";
OperatorCode[OperatorCode["br_on_cast_fail"] = 64281] = "br_on_cast_fail";
OperatorCode[OperatorCode["extern_internalize"] = 64282] = "extern_internalize";
OperatorCode[OperatorCode["extern_externalize"] = 64283] = "extern_externalize";
OperatorCode[OperatorCode["ref_i31"] = 64284] = "ref_i31";
OperatorCode[OperatorCode["i31_get_s"] = 64285] = "i31_get_s";
OperatorCode[OperatorCode["i31_get_u"] = 64286] = "i31_get_u";
})(OperatorCode = exports.OperatorCode || (exports.OperatorCode = {}));
exports.OperatorCodeNames = [
"unreachable",
@ -878,9 +844,9 @@ exports.OperatorCodeNames = [
"ref.null",
"ref.is_null",
"ref.func",
"ref.eq",
"ref.as_non_null",
"br_on_null",
"ref.eq",
"br_on_non_null",
undefined,
undefined,
@ -1309,71 +1275,41 @@ exports.OperatorCodeNames = [
].forEach(function (s, i) {
exports.OperatorCodeNames[0xfe00 | i] = s;
});
exports.OperatorCodeNames[0xfb01] = "struct.new_with_rtt";
exports.OperatorCodeNames[0xfb02] = "struct.new_default_with_rtt";
exports.OperatorCodeNames[0xfb03] = "struct.get";
exports.OperatorCodeNames[0xfb04] = "struct.get_s";
exports.OperatorCodeNames[0xfb05] = "struct.get_u";
exports.OperatorCodeNames[0xfb06] = "struct.set";
exports.OperatorCodeNames[0xfb07] = "struct.new";
exports.OperatorCodeNames[0xfb08] = "struct.new_default";
exports.OperatorCodeNames[0xfb0f] = "array.fill";
exports.OperatorCodeNames[0xfb11] = "array.new_with_rtt";
exports.OperatorCodeNames[0xfb12] = "array.new_default_with_rtt";
exports.OperatorCodeNames[0xfb13] = "array.get";
exports.OperatorCodeNames[0xfb14] = "array.get_s";
exports.OperatorCodeNames[0xfb15] = "array.get_u";
exports.OperatorCodeNames[0xfb16] = "array.set";
exports.OperatorCodeNames[0xfb17] = "array.len"; // TODO remove
exports.OperatorCodeNames[0xfb18] = "array.copy";
exports.OperatorCodeNames[0xfb19] = "array.len";
exports.OperatorCodeNames[0xfb1a] = "array.new_fixed";
exports.OperatorCodeNames[0xfb1b] = "array.new";
exports.OperatorCodeNames[0xfb1c] = "array.new_default";
exports.OperatorCodeNames[0xfb1d] = "array.new_data";
exports.OperatorCodeNames[0xfb1e] = "array.init_from_data";
exports.OperatorCodeNames[0xfb1f] = "array.new_elem";
exports.OperatorCodeNames[0xfb20] = "i31.new";
exports.OperatorCodeNames[0xfb21] = "i31.get_s";
exports.OperatorCodeNames[0xfb22] = "i31.get_u";
exports.OperatorCodeNames[0xfb30] = "rtt.canon";
exports.OperatorCodeNames[0xfb31] = "rtt.sub";
exports.OperatorCodeNames[0xfb32] = "rtt.fresh_sub";
exports.OperatorCodeNames[0xfb40] = "ref.test";
exports.OperatorCodeNames[0xfb41] = "ref.cast";
exports.OperatorCodeNames[0xfb42] = "br_on_cast";
exports.OperatorCodeNames[0xfb43] = "br_on_cast_fail";
exports.OperatorCodeNames[0xfb44] = "ref.test_static";
exports.OperatorCodeNames[0xfb45] = "ref.cast_static";
exports.OperatorCodeNames[0xfb46] = "br_on_cast_static";
exports.OperatorCodeNames[0xfb47] = "br_on_cast_static_fail";
exports.OperatorCodeNames[0xfb48] = "ref.test_null";
exports.OperatorCodeNames[0xfb49] = "ref.cast_null";
exports.OperatorCodeNames[0xfb4a] = "br_on_cast_null";
exports.OperatorCodeNames[0xfb4b] = "br_on_cast_fail_null";
exports.OperatorCodeNames[0xfb4c] = "ref.cast_nop";
exports.OperatorCodeNames[0xfb4e] = "br_on_cast";
exports.OperatorCodeNames[0xfb4f] = "br_on_cast_fail";
exports.OperatorCodeNames[0xfb50] = "ref.is_func";
exports.OperatorCodeNames[0xfb51] = "ref.is_data";
exports.OperatorCodeNames[0xfb52] = "ref.is_i31";
exports.OperatorCodeNames[0xfb53] = "ref.is_array";
exports.OperatorCodeNames[0xfb54] = "array.init_data";
exports.OperatorCodeNames[0xfb55] = "array.init_elem";
exports.OperatorCodeNames[0xfb58] = "ref.as_func";
exports.OperatorCodeNames[0xfb59] = "ref.as_data";
exports.OperatorCodeNames[0xfb5a] = "ref.as_i31";
exports.OperatorCodeNames[0xfb5b] = "ref.as_array";
exports.OperatorCodeNames[0xfb60] = "br_on_func";
exports.OperatorCodeNames[0xfb61] = "br_on_data";
exports.OperatorCodeNames[0xfb62] = "br_on_i31";
exports.OperatorCodeNames[0xfb63] = "br_on_non_func";
exports.OperatorCodeNames[0xfb64] = "br_on_non_data";
exports.OperatorCodeNames[0xfb65] = "br_on_non_i31";
exports.OperatorCodeNames[0xfb66] = "br_on_array";
exports.OperatorCodeNames[0xfb67] = "br_on_non_array";
exports.OperatorCodeNames[0xfb70] = "extern.internalize";
exports.OperatorCodeNames[0xfb71] = "extern.externalize";
[
"struct.new",
"struct.new_default",
"struct.get",
"struct.get_s",
"struct.get_u",
"struct.set",
"array.new",
"array.new_default",
"array.new_fixed",
"array.new_data",
"array.new_elem",
"array.get",
"array.get_s",
"array.get_u",
"array.set",
"array.len",
"array.fill",
"array.copy",
"array.init_data",
"array.init_elem",
"ref.test",
"ref.test null",
"ref.cast",
"ref.cast null",
"br_on_cast",
"br_on_cast_fail",
"extern.internalize",
"extern.externalize",
"ref.i31",
"i31.get_s",
"i31.get_u",
].forEach(function (s, i) {
exports.OperatorCodeNames[0xfb00 | i] = s;
});
var ExternalKind;
(function (ExternalKind) {
ExternalKind[ExternalKind["Function"] = 0] = "Function";
@ -1390,26 +1326,26 @@ var TypeKind;
TypeKind[TypeKind["f32"] = -3] = "f32";
TypeKind[TypeKind["f64"] = -4] = "f64";
TypeKind[TypeKind["v128"] = -5] = "v128";
TypeKind[TypeKind["i8"] = -6] = "i8";
TypeKind[TypeKind["i16"] = -7] = "i16";
TypeKind[TypeKind["i8"] = -8] = "i8";
TypeKind[TypeKind["i16"] = -9] = "i16";
TypeKind[TypeKind["nullfuncref"] = -13] = "nullfuncref";
TypeKind[TypeKind["nullref"] = -15] = "nullref";
TypeKind[TypeKind["nullexternref"] = -14] = "nullexternref";
TypeKind[TypeKind["funcref"] = -16] = "funcref";
TypeKind[TypeKind["externref"] = -17] = "externref";
TypeKind[TypeKind["anyref"] = -18] = "anyref";
TypeKind[TypeKind["eqref"] = -19] = "eqref";
TypeKind[TypeKind["ref_null"] = -20] = "ref_null";
TypeKind[TypeKind["ref"] = -21] = "ref";
TypeKind[TypeKind["i31ref"] = -22] = "i31ref";
TypeKind[TypeKind["nullexternref"] = -23] = "nullexternref";
TypeKind[TypeKind["nullfuncref"] = -24] = "nullfuncref";
TypeKind[TypeKind["structref"] = -25] = "structref";
TypeKind[TypeKind["arrayref"] = -26] = "arrayref";
TypeKind[TypeKind["nullref"] = -27] = "nullref";
TypeKind[TypeKind["i31ref"] = -20] = "i31ref";
TypeKind[TypeKind["structref"] = -21] = "structref";
TypeKind[TypeKind["arrayref"] = -22] = "arrayref";
TypeKind[TypeKind["ref"] = -28] = "ref";
TypeKind[TypeKind["ref_null"] = -29] = "ref_null";
TypeKind[TypeKind["func"] = -32] = "func";
TypeKind[TypeKind["struct"] = -33] = "struct";
TypeKind[TypeKind["array"] = -34] = "array";
TypeKind[TypeKind["subtype"] = -48] = "subtype";
TypeKind[TypeKind["rec_group"] = -49] = "rec_group";
TypeKind[TypeKind["subtype_final"] = -50] = "subtype_final";
TypeKind[TypeKind["subtype_final"] = -49] = "subtype_final";
TypeKind[TypeKind["rec_group"] = -50] = "rec_group";
TypeKind[TypeKind["empty_block_type"] = -64] = "empty_block_type";
})(TypeKind = exports.TypeKind || (exports.TypeKind = {}));
var FieldDef = /** @class */ (function () {
@ -1458,7 +1394,7 @@ var RefType = /** @class */ (function (_super) {
__extends(RefType, _super);
function RefType(kind, ref_index) {
var _this = this;
if (kind != -21 /* TypeKind.ref */ && kind !== -20 /* TypeKind.ref_null */) {
if (kind != -28 /* TypeKind.ref */ && kind !== -29 /* TypeKind.ref_null */) {
throw new Error("Unexpected type kind: ".concat(kind, "}"));
}
_this = _super.call(this, kind) || this;
@ -1467,7 +1403,7 @@ var RefType = /** @class */ (function (_super) {
}
Object.defineProperty(RefType.prototype, "isNullable", {
get: function () {
return this.kind == -20 /* TypeKind.ref_null */;
return this.kind == -29 /* TypeKind.ref_null */;
},
enumerable: false,
configurable: true
@ -1865,8 +1801,8 @@ var BinaryReader = /** @class */ (function () {
return new Type(kind);
}
switch (kind) {
case -20 /* TypeKind.ref_null */:
case -21 /* TypeKind.ref */:
case -29 /* TypeKind.ref_null */:
case -28 /* TypeKind.ref */:
var index = this.readHeapType();
return new RefType(kind, index);
case -1 /* TypeKind.i32 */:
@ -1874,24 +1810,24 @@ var BinaryReader = /** @class */ (function () {
case -3 /* TypeKind.f32 */:
case -4 /* TypeKind.f64 */:
case -5 /* TypeKind.v128 */:
case -6 /* TypeKind.i8 */:
case -7 /* TypeKind.i16 */:
case -8 /* TypeKind.i8 */:
case -9 /* TypeKind.i16 */:
case -16 /* TypeKind.funcref */:
case -17 /* TypeKind.externref */:
case -18 /* TypeKind.anyref */:
case -19 /* TypeKind.eqref */:
case -22 /* TypeKind.i31ref */:
case -23 /* TypeKind.nullexternref */:
case -24 /* TypeKind.nullfuncref */:
case -25 /* TypeKind.structref */:
case -26 /* TypeKind.arrayref */:
case -27 /* TypeKind.nullref */:
case -20 /* TypeKind.i31ref */:
case -14 /* TypeKind.nullexternref */:
case -13 /* TypeKind.nullfuncref */:
case -21 /* TypeKind.structref */:
case -22 /* TypeKind.arrayref */:
case -15 /* TypeKind.nullref */:
case -32 /* TypeKind.func */:
case -33 /* TypeKind.struct */:
case -34 /* TypeKind.array */:
case -48 /* TypeKind.subtype */:
case -49 /* TypeKind.rec_group */:
case -50 /* TypeKind.subtype_final */:
case -50 /* TypeKind.rec_group */:
case -49 /* TypeKind.subtype_final */:
case -64 /* TypeKind.empty_block_type */:
return new Type(kind);
default:
@ -2035,7 +1971,7 @@ var BinaryReader = /** @class */ (function () {
case -48 /* TypeKind.subtype */:
this.result = this.readSubtype(false);
break;
case -50 /* TypeKind.subtype_final */:
case -49 /* TypeKind.subtype_final */:
this.result = this.readSubtype(true);
break;
case -33 /* TypeKind.struct */:
@ -2049,8 +1985,8 @@ var BinaryReader = /** @class */ (function () {
case -3 /* TypeKind.f32 */:
case -4 /* TypeKind.f64 */:
case -5 /* TypeKind.v128 */:
case -6 /* TypeKind.i8 */:
case -7 /* TypeKind.i16 */:
case -8 /* TypeKind.i8 */:
case -9 /* TypeKind.i16 */:
case -16 /* TypeKind.funcref */:
case -17 /* TypeKind.externref */:
case -18 /* TypeKind.anyref */:
@ -2069,7 +2005,7 @@ var BinaryReader = /** @class */ (function () {
return this.read();
}
var form = this.readVarInt7();
if (form == -49 /* TypeKind.rec_group */) {
if (form == -50 /* TypeKind.rec_group */) {
this.state = 47 /* BinaryReaderState.BEGIN_REC_GROUP */;
this.result = null;
this._recGroupTypesLeft = this.readVarUint32();
@ -2558,79 +2494,60 @@ var BinaryReader = /** @class */ (function () {
var code, brDepth, refType, srcType, fieldIndex, segmentIndex, len, literal;
code = this._data[this._pos++] | 0xfb00;
switch (code) {
case 64334 /* OperatorCode.br_on_cast */:
case 64335 /* OperatorCode.br_on_cast_fail */:
case 64280 /* OperatorCode.br_on_cast */:
case 64281 /* OperatorCode.br_on_cast_fail */:
literal = this.readUint8();
brDepth = this.readVarUint32();
srcType = this.readHeapType();
refType = this.readHeapType();
break;
case 64322 /* OperatorCode.br_on_cast_ */:
case 64323 /* OperatorCode.br_on_cast_fail_ */:
brDepth = this.readVarUint32();
refType = this.readHeapType();
break;
case 64326 /* OperatorCode.br_on_cast__ */:
case 64327 /* OperatorCode.br_on_cast_fail__ */:
brDepth = this.readVarUint32();
case 64267 /* OperatorCode.array_get */:
case 64268 /* OperatorCode.array_get_s */:
case 64269 /* OperatorCode.array_get_u */:
case 64270 /* OperatorCode.array_set */:
case 64262 /* OperatorCode.array_new */:
case 64263 /* OperatorCode.array_new_default */:
case 64256 /* OperatorCode.struct_new */:
case 64257 /* OperatorCode.struct_new_default */:
refType = this.readVarUint32();
break;
case 64275 /* OperatorCode.array_get */:
case 64276 /* OperatorCode.array_get_s */:
case 64277 /* OperatorCode.array_get_u */:
case 64279 /* OperatorCode.array_len_ */:
case 64278 /* OperatorCode.array_set */:
case 64283 /* OperatorCode.array_new */:
case 64273 /* OperatorCode.array_new_with_rtt */:
case 64284 /* OperatorCode.array_new_default */:
case 64274 /* OperatorCode.array_new_default_with_rtt */:
case 64263 /* OperatorCode.struct_new */:
case 64257 /* OperatorCode.struct_new_with_rtt */:
case 64264 /* OperatorCode.struct_new_default */:
case 64258 /* OperatorCode.struct_new_default_with_rtt */:
case 64304 /* OperatorCode.rtt_canon */:
case 64305 /* OperatorCode.rtt_sub */:
case 64306 /* OperatorCode.rtt_fresh_sub */:
refType = this.readVarUint32();
break;
case 64282 /* OperatorCode.array_new_fixed */:
case 64264 /* OperatorCode.array_new_fixed */:
refType = this.readVarUint32();
len = this.readVarUint32();
break;
case 64280 /* OperatorCode.array_copy */:
case 64272 /* OperatorCode.array_fill */:
refType = this.readVarUint32();
break;
case 64273 /* OperatorCode.array_copy */:
refType = this.readVarUint32();
srcType = this.readVarUint32();
break;
case 64259 /* OperatorCode.struct_get */:
case 64260 /* OperatorCode.struct_get_s */:
case 64261 /* OperatorCode.struct_get_u */:
case 64262 /* OperatorCode.struct_set */:
case 64258 /* OperatorCode.struct_get */:
case 64259 /* OperatorCode.struct_get_s */:
case 64260 /* OperatorCode.struct_get_u */:
case 64261 /* OperatorCode.struct_set */:
refType = this.readVarUint32();
fieldIndex = this.readVarUint32();
break;
case 64285 /* OperatorCode.array_new_data */:
case 64287 /* OperatorCode.array_new_elem */:
case 64340 /* OperatorCode.array_init_data */:
case 64341 /* OperatorCode.array_init_elem */:
case 64265 /* OperatorCode.array_new_data */:
case 64266 /* OperatorCode.array_new_elem */:
case 64274 /* OperatorCode.array_init_data */:
case 64275 /* OperatorCode.array_init_elem */:
refType = this.readVarUint32();
segmentIndex = this.readVarUint32();
break;
case 64320 /* OperatorCode.ref_test */:
case 64328 /* OperatorCode.ref_test_null */:
case 64321 /* OperatorCode.ref_cast */:
case 64329 /* OperatorCode.ref_cast_null */:
case 64276 /* OperatorCode.ref_test */:
case 64277 /* OperatorCode.ref_test_null */:
case 64278 /* OperatorCode.ref_cast */:
case 64279 /* OperatorCode.ref_cast_null */:
refType = this.readHeapType();
break;
case 64324 /* OperatorCode.ref_test_ */:
case 64325 /* OperatorCode.ref_cast_ */:
refType = this.readVarUint32();
break;
case 64281 /* OperatorCode.array_len */:
case 64369 /* OperatorCode.extern_externalize */:
case 64368 /* OperatorCode.extern_internalize */:
case 64288 /* OperatorCode.i31_new */:
case 64289 /* OperatorCode.i31_get_s */:
case 64290 /* OperatorCode.i31_get_u */:
case 64271 /* OperatorCode.array_len */:
case 64283 /* OperatorCode.extern_externalize */:
case 64282 /* OperatorCode.extern_internalize */:
case 64284 /* OperatorCode.ref_i31 */:
case 64285 /* OperatorCode.i31_get_s */:
case 64286 /* OperatorCode.i31_get_u */:
break;
default:
this.error = new Error("Unknown operator: 0x".concat(code.toString(16).padStart(4, "0")));
@ -2790,6 +2707,17 @@ var BinaryReader = /** @class */ (function () {
case 1036322 /* OperatorCode.f64x2_replace_lane */:
lineIndex = this.readUint8();
break;
case 1036372 /* OperatorCode.v128_load8_lane */:
case 1036373 /* OperatorCode.v128_load16_lane */:
case 1036374 /* OperatorCode.v128_load32_lane */:
case 1036375 /* OperatorCode.v128_load64_lane */:
case 1036376 /* OperatorCode.v128_store8_lane */:
case 1036377 /* OperatorCode.v128_store16_lane */:
case 1036378 /* OperatorCode.v128_store32_lane */:
case 1036379 /* OperatorCode.v128_store64_lane */:
memoryAddress = this.readMemoryImmediate();
lineIndex = this.readUint8();
break;
case 1036302 /* OperatorCode.i8x16_swizzle */:
case 1036303 /* OperatorCode.i8x16_splat */:
case 1036304 /* OperatorCode.i16x8_splat */:
@ -2956,8 +2884,8 @@ var BinaryReader = /** @class */ (function () {
case 1036507 /* OperatorCode.i64x2_ge_s */:
case 1036508 /* OperatorCode.i64x2_extmul_low_i32x4_s */:
case 1036509 /* OperatorCode.i64x2_extmul_high_i32x4_s */:
case 1036508 /* OperatorCode.i64x2_extmul_low_i32x4_s */:
case 1036509 /* OperatorCode.i64x2_extmul_high_i32x4_s */:
case 1036510 /* OperatorCode.i64x2_extmul_low_i32x4_u */:
case 1036511 /* OperatorCode.i64x2_extmul_high_i32x4_u */:
case 1036512 /* OperatorCode.f32x4_abs */:
case 1036512 /* OperatorCode.f32x4_abs */:
case 1036513 /* OperatorCode.f32x4_neg */:
@ -3214,7 +3142,7 @@ var BinaryReader = /** @class */ (function () {
break;
case 12 /* OperatorCode.br */:
case 13 /* OperatorCode.br_if */:
case 212 /* OperatorCode.br_on_null */:
case 213 /* OperatorCode.br_on_null */:
case 214 /* OperatorCode.br_on_non_null */:
brDepth = this.readVarUint32();
break;
@ -3485,8 +3413,8 @@ var BinaryReader = /** @class */ (function () {
case 195 /* OperatorCode.i64_extend16_s */:
case 196 /* OperatorCode.i64_extend32_s */:
case 209 /* OperatorCode.ref_is_null */:
case 211 /* OperatorCode.ref_as_non_null */:
case 213 /* OperatorCode.ref_eq */:
case 212 /* OperatorCode.ref_as_non_null */:
case 211 /* OperatorCode.ref_eq */:
break;
default:
this.error = new Error("Unknown operator: ".concat(code));

View file

@ -242,6 +242,11 @@ button::selection {
:-moz-focusring {
outline: var(--theme-focus-outline);
outline-offset: -1px;
/* offset the outline for checkbox and radio buttons so it doesn't conflict with existing border */
:is(input[type="radio"], input[type="checkbox"], checkbox)& {
outline-offset: 2px;
}
}
textbox[focused="true"] {
@ -255,14 +260,6 @@ textbox :-moz-focusring {
outline: none;
}
/* Form fields should already have box-shadow hightlight */
select:-moz-focusring,
input[type="radio"]:-moz-focusring,
input[type="checkbox"]:-moz-focusring,
checkbox:-moz-focusring {
outline: none;
}
/* Tab and button of toolbox does not need to display outline */
.devtools-button:-moz-focusring,

View file

@ -9,6 +9,9 @@ const dom = require("resource://devtools/client/shared/vendor/react-dom-factorie
const {
l10n,
} = require("resource://devtools/client/webconsole/utils/messages.js");
const {
MESSAGE_TYPE,
} = require("resource://devtools/client/webconsole/constants.js");
const l10nLevels = {
error: "level.error",
@ -40,15 +43,17 @@ function getIconElement(level, type, title) {
classnames.push("logtrace");
} else if (type === "blockedReason") {
title = l10n.getStr("blockedrequest.label");
} else if (type === MESSAGE_TYPE.COMMAND) {
title = l10n.getStr("command.title");
} else if (type === MESSAGE_TYPE.RESULT) {
title = l10n.getStr("result.title");
}
{
return dom.span({
className: classnames.join(" "),
title,
"aria-live": "off",
});
}
return dom.span({
className: classnames.join(" "),
title,
"aria-live": "off",
});
}
MessageIcon.displayName = "MessageIcon";

View file

@ -4,6 +4,7 @@
const {
MESSAGE_LEVEL,
MESSAGE_TYPE,
} = require("resource://devtools/client/webconsole/constants.js");
const expect = require("expect");
@ -33,6 +34,28 @@ describe("MessageIcon component:", () => {
expect(rendered.hasClass("logpoint")).toBe(true);
});
it("renders evaluation expression items", () => {
const rendered = render(
MessageIcon({
level: MESSAGE_LEVEL.LOG,
type: MESSAGE_TYPE.COMMAND,
})
);
expect(rendered.hasClass("icon")).toBe(true);
expect(rendered.attr("title")).toBe("Evaluated code");
});
it("renders evaluation expression result items", () => {
const rendered = render(
MessageIcon({
level: MESSAGE_LEVEL.LOG,
type: MESSAGE_TYPE.RESULT,
})
);
expect(rendered.hasClass("icon")).toBe(true);
expect(rendered.attr("title")).toBe("Evaluation result");
});
it("renders icon with custom title", () => {
const expectedTitle = "Rendered with custom title";
const rendered = render(

View file

@ -422,6 +422,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
"stop-opacity",
"stroke-miterlimit",
"stroke-opacity",
"zoom",
"-moz-window-opacity",
]),
],

View file

@ -48,6 +48,7 @@
#include "nsIConstraintValidation.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/Try.h"
#include "mozilla/dom/DragEvent.h"
#include "mozilla/dom/Event.h" // for Event
#include "mozilla/dom/File.h" // for input type=file

View file

@ -65,9 +65,9 @@ using namespace mozilla::dom;
// Default this to time out unused content viewers after 30 minutes
#define CONTENT_VIEWER_TIMEOUT_SECONDS_DEFAULT (30 * 60)
static const char* kObservedPrefs[] = {PREF_SHISTORY_SIZE,
PREF_SHISTORY_MAX_TOTAL_VIEWERS,
PREF_FISSION_BFCACHEINPARENT, nullptr};
static constexpr const char* kObservedPrefs[] = {
PREF_SHISTORY_SIZE, PREF_SHISTORY_MAX_TOTAL_VIEWERS,
PREF_FISSION_BFCACHEINPARENT, nullptr};
static int32_t gHistoryMaxSize = 50;

View file

@ -2429,7 +2429,6 @@ NS_INTERFACE_TABLE_HEAD(Document)
NS_INTERFACE_TABLE_ENTRY(Document, nsIScriptObjectPrincipal)
NS_INTERFACE_TABLE_ENTRY(Document, EventTarget)
NS_INTERFACE_TABLE_ENTRY(Document, nsISupportsWeakReference)
NS_INTERFACE_TABLE_ENTRY(Document, nsIRadioGroupContainer)
NS_INTERFACE_TABLE_END
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(Document)
NS_INTERFACE_MAP_END
@ -2504,6 +2503,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
DocumentOrShadowRoot::Traverse(tmp, cb);
if (tmp->mRadioGroupContainer) {
RadioGroupContainer::Traverse(tmp->mRadioGroupContainer.get(), cb);
}
for (auto& sheets : tmp->mAdditionalSheets) {
tmp->TraverseStyleSheets(sheets, "mAdditionalSheets[<origin>][i]", cb);
}
@ -2703,6 +2706,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
DocumentOrShadowRoot::Unlink(tmp);
tmp->mRadioGroupContainer = nullptr;
// Document has a pretty complex destructor, so we're going to
// assume that *most* cycles you actually want to break somewhere
// else, and not unlink an awful lot here.
@ -14144,8 +14149,8 @@ void Document::MaybeWarnAboutZoom() {
if (mHasWarnedAboutZoom) {
return;
}
const bool usedZoom = Servo_IsUnknownPropertyRecordedInUseCounter(
mStyleUseCounters.get(), CountedUnknownProperty::Zoom);
const bool usedZoom = Servo_IsPropertyIdRecordedInUseCounter(
mStyleUseCounters.get(), eCSSProperty_zoom);
if (!usedZoom) {
return;
}
@ -15819,6 +15824,12 @@ void Document::DocAddSizeOfExcludingThis(nsWindowSizes& aWindowSizes) const {
aWindowSizes.mState.mMallocSizeOf);
}
if (mRadioGroupContainer) {
aWindowSizes.mDOMSizes.mDOMOtherSize +=
mRadioGroupContainer->SizeOfIncludingThis(
aWindowSizes.mState.mMallocSizeOf);
}
aWindowSizes.mDOMSizes.mDOMOtherSize +=
mStyledLinks.ShallowSizeOfExcludingThis(
aWindowSizes.mState.mMallocSizeOf);
@ -18761,4 +18772,11 @@ HighlightRegistry& Document::HighlightRegistry() {
return *mHighlightRegistry;
}
RadioGroupContainer& Document::OwnedRadioGroupContainer() {
if (!mRadioGroupContainer) {
mRadioGroupContainer = MakeUnique<RadioGroupContainer>();
}
return *mRadioGroupContainer;
}
} // namespace mozilla::dom

View file

@ -52,6 +52,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/EventTarget.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/RadioGroupContainer.h"
#include "mozilla/dom/TreeOrderedArray.h"
#include "mozilla/dom/ViewportMetaData.h"
#include "mozilla/glean/GleanMetrics.h"
@ -79,7 +80,6 @@
#include "nsIParser.h"
#include "nsIPrincipal.h"
#include "nsIProgressEventSink.h"
#include "nsIRadioGroupContainer.h"
#include "nsIReferrerInfo.h"
#include "nsIRequestObserver.h"
#include "nsIScriptObjectPrincipal.h"
@ -532,7 +532,6 @@ enum class SheetPreloadStatus : uint8_t {
class Document : public nsINode,
public DocumentOrShadowRoot,
public nsSupportsWeakReference,
public nsIRadioGroupContainer,
public nsIScriptObjectPrincipal,
public DispatcherTrait,
public SupportsWeakPtr {
@ -584,49 +583,6 @@ class Document : public nsINode,
} \
} while (0)
// nsIRadioGroupContainer
NS_IMETHOD WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor) final {
return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor);
}
void SetCurrentRadioButton(const nsAString& aName,
HTMLInputElement* aRadio) final {
DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio);
}
HTMLInputElement* GetCurrentRadioButton(const nsAString& aName) final {
return DocumentOrShadowRoot::GetCurrentRadioButton(aName);
}
NS_IMETHOD
GetNextRadioButton(const nsAString& aName, const bool aPrevious,
HTMLInputElement* aFocusedRadio,
HTMLInputElement** aRadioOut) final {
return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious,
aFocusedRadio, aRadioOut);
}
void AddToRadioGroup(const nsAString& aName, HTMLInputElement* aRadio) final {
DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio, nullptr);
}
void RemoveFromRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) final {
DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio);
}
uint32_t GetRequiredRadioCount(const nsAString& aName) const final {
return DocumentOrShadowRoot::GetRequiredRadioCount(aName);
}
void RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) final {
DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded);
}
bool GetValueMissingState(const nsAString& aName) const final {
return DocumentOrShadowRoot::GetValueMissingState(aName);
}
void SetValueMissingState(const nsAString& aName, bool aValue) final {
return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
}
nsIPrincipal* EffectiveCookiePrincipal() const;
nsIPrincipal* EffectiveStoragePrincipal() const;
@ -5360,6 +5316,8 @@ class Document : public nsINode,
// Registry of custom highlight definitions associated with this document.
RefPtr<class HighlightRegistry> mHighlightRegistry;
UniquePtr<RadioGroupContainer> mRadioGroupContainer;
public:
// Needs to be public because the bindings code pokes at it.
JS::ExpandoAndGeneration mExpandoAndGeneration;
@ -5375,6 +5333,8 @@ class Document : public nsINode,
}
void LoadEventFired();
RadioGroupContainer& OwnedRadioGroupContainer();
};
NS_DEFINE_STATIC_IID_ACCESSOR(Document, NS_IDOCUMENT_IID)

View file

@ -18,7 +18,6 @@
#include "nsTHashtable.h"
#include "nsContentUtils.h"
#include "nsFocusManager.h"
#include "nsIRadioVisitor.h"
#include "nsIFormControl.h"
#include "nsLayoutUtils.h"
#include "nsNameSpaceManager.h"
@ -668,8 +667,6 @@ void DocumentOrShadowRoot::Traverse(DocumentOrShadowRoot* tmp,
for (auto iter = tmp->mIdentifierMap.Iter(); !iter.Done(); iter.Next()) {
iter.Get()->Traverse(&cb);
}
RadioGroupManager::Traverse(tmp, cb);
}
void DocumentOrShadowRoot::UnlinkStyleSheets(
@ -691,7 +688,6 @@ void DocumentOrShadowRoot::Unlink(DocumentOrShadowRoot* tmp) {
});
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAdoptedStyleSheets);
tmp->mIdentifierMap.Clear();
RadioGroupManager::Unlink(tmp);
}
} // namespace mozilla::dom

View file

@ -15,13 +15,11 @@
#include "nsContentListDeclarations.h"
#include "nsTArray.h"
#include "nsTHashSet.h"
#include "RadioGroupManager.h"
class nsContentList;
class nsCycleCollectionTraversalCallback;
class nsINode;
class nsINodeList;
class nsIRadioVisitor;
class nsWindowSizes;
namespace mozilla {
@ -48,7 +46,7 @@ class Sequence;
* TODO(emilio, bug 1418159): In the future this should hold most of the
* relevant style state, this should allow us to fix bug 548397.
*/
class DocumentOrShadowRoot : public RadioGroupManager {
class DocumentOrShadowRoot {
enum class Kind {
Document,
ShadowRoot,

View file

@ -62,6 +62,7 @@
#include "mozilla/StaticPrefs_full_screen_api.h"
#include "mozilla/TextControlElement.h"
#include "mozilla/TextEvents.h"
#include "mozilla/Try.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/AnimatableBinding.h"

View file

@ -21,6 +21,7 @@
#include "mozilla/dom/WorkerScope.h"
#include "mozilla/dom/EventSourceEventService.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Try.h"
#include "mozilla/UniquePtrExtensions.h"
#include "nsComponentManagerUtils.h"
#include "nsIThreadRetargetableStreamListener.h"

View file

@ -29,6 +29,7 @@
#include "mozilla/TouchEvents.h"
#include "mozilla/URLExtraData.h"
#include "mozilla/dom/Attr.h"
#include "mozilla/dom/RadioGroupContainer.h"
#include "nsDOMAttributeMap.h"
#include "nsAtom.h"
#include "mozilla/dom/NodeInfo.h"
@ -659,6 +660,7 @@ void FragmentOrElement::nsExtendedDOMSlots::UnlinkExtendedSlots(
aContent.ClearMayHaveAnimations();
}
mExplicitlySetAttrElements.Clear();
mRadioGroupContainer = nullptr;
}
void FragmentOrElement::nsExtendedDOMSlots::TraverseExtendedSlots(
@ -683,6 +685,9 @@ void FragmentOrElement::nsExtendedDOMSlots::TraverseExtendedSlots(
if (mAnimations) {
mAnimations->Traverse(aCb);
}
if (mRadioGroupContainer) {
RadioGroupContainer::Traverse(mRadioGroupContainer.get(), aCb);
}
}
size_t FragmentOrElement::nsExtendedDOMSlots::SizeOfExcludingThis(
@ -717,6 +722,10 @@ size_t FragmentOrElement::nsExtendedDOMSlots::SizeOfExcludingThis(
n += mCustomElementData->SizeOfIncludingThis(aMallocSizeOf);
}
if (mRadioGroupContainer) {
n += mRadioGroupContainer->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}

View file

@ -17,6 +17,7 @@
#include "mozilla/EnumSet.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/dom/RadioGroupContainer.h"
#include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
#include "nsIContent.h" // base class
#include "nsAtomHashKeys.h"
@ -114,6 +115,14 @@ class FragmentOrElement : public nsIContent {
return Children()->Length();
}
RadioGroupContainer& OwnedRadioGroupContainer() {
auto* slots = ExtendedDOMSlots();
if (!slots->mRadioGroupContainer) {
slots->mRadioGroupContainer = MakeUnique<RadioGroupContainer>();
}
return *slots->mRadioGroupContainer;
}
public:
/**
* If there are listeners for DOMNodeInserted event, fires the event on all
@ -208,6 +217,12 @@ class FragmentOrElement : public nsIContent {
*/
UniquePtr<PopoverData> mPopoverData;
/**
* RadioGroupContainer for radio buttons grouped under this disconnected
* element.
*/
UniquePtr<RadioGroupContainer> mRadioGroupContainer;
/**
* Last remembered size (in CSS pixels) for the element.
* @see {@link https://drafts.csswg.org/css-sizing-4/#last-remembered}

View file

@ -4,9 +4,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RadioGroupManager.h"
#include "nsIRadioVisitor.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "mozilla/dom/RadioGroupContainer.h"
#include "mozilla/Assertions.h"
#include "nsIRadioVisitor.h"
#include "nsRadioVisitor.h"
namespace mozilla::dom {
@ -26,10 +28,24 @@ struct nsRadioGroupStruct {
bool mGroupSuffersFromValueMissing;
};
RadioGroupManager::RadioGroupManager() = default;
RadioGroupContainer::RadioGroupContainer() = default;
void RadioGroupManager::Traverse(RadioGroupManager* tmp,
nsCycleCollectionTraversalCallback& cb) {
RadioGroupContainer::~RadioGroupContainer() {
for (const auto& group : mRadioGroups) {
for (const auto& button : group.GetData()->mRadioButtons) {
// When the radio group container is being cycle-collected, any remaining
// connected buttons will also be in the process of being cycle-collected.
// Here, we unset the button's reference to the container so that when it
// is collected it does not attempt to remove itself from a potentially
// already deleted radio group.
button->DisconnectRadioGroupContainer();
}
}
}
/* static */
void RadioGroupContainer::Traverse(RadioGroupContainer* tmp,
nsCycleCollectionTraversalCallback& cb) {
for (const auto& entry : tmp->mRadioGroups) {
nsRadioGroupStruct* radioGroup = entry.GetWeak();
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(
@ -45,12 +61,13 @@ void RadioGroupManager::Traverse(RadioGroupManager* tmp,
}
}
void RadioGroupManager::Unlink(RadioGroupManager* tmp) {
tmp->mRadioGroups.Clear();
size_t RadioGroupContainer::SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const {
return mRadioGroups.SizeOfIncludingThis(aMallocSizeOf);
}
nsresult RadioGroupManager::WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor) {
nsresult RadioGroupContainer::WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor) {
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
for (size_t i = 0; i < radioGroup->mRadioButtons.Length(); i++) {
@ -62,21 +79,20 @@ nsresult RadioGroupManager::WalkRadioGroup(const nsAString& aName,
return NS_OK;
}
void RadioGroupManager::SetCurrentRadioButton(const nsAString& aName,
HTMLInputElement* aRadio) {
void RadioGroupContainer::SetCurrentRadioButton(const nsAString& aName,
HTMLInputElement* aRadio) {
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
radioGroup->mSelectedRadioButton = aRadio;
}
HTMLInputElement* RadioGroupManager::GetCurrentRadioButton(
HTMLInputElement* RadioGroupContainer::GetCurrentRadioButton(
const nsAString& aName) {
return GetOrCreateRadioGroup(aName)->mSelectedRadioButton;
}
nsresult RadioGroupManager::GetNextRadioButton(const nsAString& aName,
const bool aPrevious,
HTMLInputElement* aFocusedRadio,
HTMLInputElement** aRadioOut) {
nsresult RadioGroupContainer::GetNextRadioButton(
const nsAString& aName, const bool aPrevious,
HTMLInputElement* aFocusedRadio, HTMLInputElement** aRadioOut) {
*aRadioOut = nullptr;
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
@ -114,9 +130,9 @@ nsresult RadioGroupManager::GetNextRadioButton(const nsAString& aName,
return NS_OK;
}
void RadioGroupManager::AddToRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio,
nsIContent* aAncestor) {
void RadioGroupContainer::AddToRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio,
nsIContent* aAncestor) {
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
nsContentUtils::AddElementToListByTreeOrder(radioGroup->mRadioButtons, aRadio,
aAncestor);
@ -126,9 +142,13 @@ void RadioGroupManager::AddToRadioGroup(const nsAString& aName,
}
}
void RadioGroupManager::RemoveFromRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) {
void RadioGroupContainer::RemoveFromRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) {
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
MOZ_ASSERT(
radioGroup->mRadioButtons.Contains(aRadio),
"Attempting to remove radio button from group it is not a part of!");
radioGroup->mRadioButtons.RemoveElement(aRadio);
if (aRadio->IsRequired()) {
@ -138,14 +158,14 @@ void RadioGroupManager::RemoveFromRadioGroup(const nsAString& aName,
}
}
uint32_t RadioGroupManager::GetRequiredRadioCount(
uint32_t RadioGroupContainer::GetRequiredRadioCount(
const nsAString& aName) const {
nsRadioGroupStruct* radioGroup = GetRadioGroup(aName);
return radioGroup ? radioGroup->mRequiredRadioCount : 0;
}
void RadioGroupManager::RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) {
void RadioGroupContainer::RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) {
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
if (aRequiredAdded) {
@ -157,25 +177,25 @@ void RadioGroupManager::RadioRequiredWillChange(const nsAString& aName,
}
}
bool RadioGroupManager::GetValueMissingState(const nsAString& aName) const {
bool RadioGroupContainer::GetValueMissingState(const nsAString& aName) const {
nsRadioGroupStruct* radioGroup = GetRadioGroup(aName);
return radioGroup && radioGroup->mGroupSuffersFromValueMissing;
}
void RadioGroupManager::SetValueMissingState(const nsAString& aName,
bool aValue) {
void RadioGroupContainer::SetValueMissingState(const nsAString& aName,
bool aValue) {
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
radioGroup->mGroupSuffersFromValueMissing = aValue;
}
nsRadioGroupStruct* RadioGroupManager::GetRadioGroup(
nsRadioGroupStruct* RadioGroupContainer::GetRadioGroup(
const nsAString& aName) const {
nsRadioGroupStruct* radioGroup = nullptr;
mRadioGroups.Get(aName, &radioGroup);
return radioGroup;
}
nsRadioGroupStruct* RadioGroupManager::GetOrCreateRadioGroup(
nsRadioGroupStruct* RadioGroupContainer::GetOrCreateRadioGroup(
const nsAString& aName) {
return mRadioGroups.GetOrInsertNew(aName);
}

View file

@ -7,32 +7,25 @@
#ifndef mozilla_dom_nsRadioGroupStruct_h
#define mozilla_dom_nsRadioGroupStruct_h
#include "nsCOMArray.h"
#include "nsIFormControl.h"
#include "nsIRadioGroupContainer.h"
#include "nsClassHashtable.h"
class nsIContent;
namespace mozilla {
namespace html {
class nsIRadioVisitor;
}
namespace dom {
namespace mozilla::dom {
class HTMLInputElement;
struct nsRadioGroupStruct;
class RadioGroupManager {
class RadioGroupContainer final {
public:
RadioGroupManager();
RadioGroupContainer();
~RadioGroupContainer();
static void Traverse(RadioGroupManager* tmp,
static void Traverse(RadioGroupContainer* tmp,
nsCycleCollectionTraversalCallback& cb);
static void Unlink(RadioGroupManager* tmp);
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
// nsIRadioGroupContainer
NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor);
void SetCurrentRadioButton(const nsAString& aName, HTMLInputElement* aRadio);
HTMLInputElement* GetCurrentRadioButton(const nsAString& aName);
@ -55,7 +48,6 @@ class RadioGroupManager {
nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
};
} // namespace dom
} // namespace mozilla
} // namespace mozilla::dom
#endif // mozilla_dom_nsRadioGroupStruct_h

View file

@ -35,6 +35,7 @@
#include "mozilla/StackWalk.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Try.h"
#include "nsCOMPtr.h"
#include "nsDebug.h"

View file

@ -44,7 +44,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(DocumentFragment)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ShadowRoot)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
NS_INTERFACE_MAP_ENTRY(nsIRadioGroupContainer)
NS_INTERFACE_MAP_END_INHERITING(DocumentFragment)
NS_IMPL_ADDREF_INHERITED(ShadowRoot, DocumentFragment)

View file

@ -16,7 +16,6 @@
#include "mozilla/ServoBindings.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIRadioGroupContainer.h"
#include "nsStubMutationObserver.h"
#include "nsTHashtable.h"
@ -40,9 +39,7 @@ class CSSImportRule;
class Element;
class HTMLInputElement;
class ShadowRoot final : public DocumentFragment,
public DocumentOrShadowRoot,
public nsIRadioGroupContainer {
class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {
friend class DocumentOrShadowRoot;
public:
@ -234,58 +231,16 @@ class ShadowRoot final : public DocumentFragment,
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
// nsIRadioGroupContainer
NS_IMETHOD WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor) override {
return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor);
}
void SetCurrentRadioButton(const nsAString& aName,
HTMLInputElement* aRadio) override {
DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio);
}
HTMLInputElement* GetCurrentRadioButton(const nsAString& aName) override {
return DocumentOrShadowRoot::GetCurrentRadioButton(aName);
}
NS_IMETHOD
GetNextRadioButton(const nsAString& aName, const bool aPrevious,
HTMLInputElement* aFocusedRadio,
HTMLInputElement** aRadioOut) override {
return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious,
aFocusedRadio, aRadioOut);
}
void AddToRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) override {
DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio, this);
}
void RemoveFromRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) override {
DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio);
}
uint32_t GetRequiredRadioCount(const nsAString& aName) const override {
return DocumentOrShadowRoot::GetRequiredRadioCount(aName);
}
void RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) override {
DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded);
}
bool GetValueMissingState(const nsAString& aName) const override {
return DocumentOrShadowRoot::GetValueMissingState(aName);
}
void SetValueMissingState(const nsAString& aName, bool aValue) override {
return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
}
protected:
// FIXME(emilio): This will need to become more fine-grained.
void ApplicableRulesChanged();
virtual ~ShadowRoot();
const ShadowRootMode mMode;
Element::DelegatesFocus mDelegatesFocus;
const SlotAssignmentMode mSlotAssignment;
// Make sure that the first field is pointer-aligned so it doesn't get packed
// in the base class' padding, since otherwise rust-bindgen can't generate
// correct bindings for it, see
// https://github.com/rust-lang/rust-bindgen/issues/380
// The computed data from the style sheets.
UniquePtr<StyleAuthorStyles> mServoStyles;
@ -301,6 +256,12 @@ class ShadowRoot final : public DocumentFragment,
// tree.
nsTArray<const Element*> mParts;
const ShadowRootMode mMode;
Element::DelegatesFocus mDelegatesFocus;
const SlotAssignmentMode mSlotAssignment;
// Whether this is the <details> internal shadow tree.
bool mIsDetailsShadowTree : 1;

View file

@ -148,34 +148,74 @@ custom PercentageStrokeWidthInSVGText whether percentage stroke-width is used in
// Missing-property use counters. We claim these are "method" use
// counters, because we don't need a separate description string for
// them and we only need one use counter, not a getter/setter pair.
method HTMLDocument.caretRangeFromPoint
method HTMLDocument.exitPictureInPicture
method HTMLDocument.featurePolicy
method HTMLDocument.onbeforecopy
method HTMLDocument.onbeforecut
method HTMLDocument.onbeforepaste
method HTMLDocument.oncancel
method HTMLDocument.onfreeze
method HTMLDocument.onmousewheel
method HTMLDocument.onresume
method HTMLDocument.onsearch
method HTMLDocument.onwebkitfullscreenchange
method HTMLDocument.onwebkitfullscreenerror
method HTMLDocument.pictureInPictureElement
method HTMLDocument.pictureInPictureEnabled
method HTMLDocument.registerElement
method HTMLDocument.wasDiscarded
method HTMLDocument.webkitCancelFullScreen
method HTMLDocument.webkitCurrentFullScreenElement
method HTMLDocument.webkitExitFullscreen
method HTMLDocument.webkitFullscreenElement
method HTMLDocument.webkitFullscreenEnabled
method HTMLDocument.webkitHidden
method HTMLDocument.webkitIsFullScreen
method HTMLDocument.webkitVisibilityState
method HTMLDocument.xmlEncoding
method HTMLDocument.xmlStandalone
method HTMLDocument.xmlVersion
method Clipboard.read
method Clipboard.readText
method Clipboard.write
method DataTransferItem.webkitGetAsEntry
method Document.caretRangeFromPoint
method Document.exitPictureInPicture
method Document.featurePolicy
method Document.onbeforecopy
method Document.onbeforecut
method Document.onbeforepaste
method Document.oncancel
method Document.onfreeze
method Document.onmousewheel
method Document.onresume
method Document.onsearch
method Document.onwebkitfullscreenchange
method Document.onwebkitfullscreenerror
method Document.pictureInPictureElement
method Document.pictureInPictureEnabled
method Document.registerElement
method Document.wasDiscarded
method Document.webkitCancelFullScreen
method Document.webkitCurrentFullScreenElement
method Document.webkitExitFullscreen
method Document.webkitFullscreenElement
method Document.webkitFullscreenEnabled
method Document.webkitHidden
method Document.webkitIsFullScreen
method Document.webkitVisibilityState
method Document.xmlEncoding
method Document.xmlStandalone
method Document.xmlVersion
method Element.computedStyleMap
method Element.onmousewheel
method Element.scrollIntoViewIfNeeded
method HTMLButtonElement.popoverTargetAction
method HTMLButtonElement.popoverTargetElement
method HTMLElement.attributeStyleMap
method HTMLElement.hidePopover
method HTMLElement.popover
method HTMLElement.showPopover
method HTMLElement.togglePopover
method HTMLIFrameElement.loading
method HTMLInputElement.capture
method HTMLInputElement.incremental
method HTMLInputElement.onsearch
method HTMLInputElement.popoverTargetAction
method HTMLInputElement.popoverTargetElement
method HTMLInputElement.webkitdirectory
method HTMLInputElement.webkitEntries
method HTMLMediaElement.disableRemotePlayback
method HTMLMediaElement.remote
method HTMLVideoElement.cancelVideoFrameCallback
method HTMLVideoElement.disablePictureInPicture
method HTMLVideoElement.onenterpictureinpicture
method HTMLVideoElement.onleavepictureinpicture
method HTMLVideoElement.playsInline
method HTMLVideoElement.requestPictureInPicture
method HTMLVideoElement.requestVideoFrameCallback
method ImageData.colorSpace
method Location.ancestorOrigins
method Navigator.canShare
method Navigator.clearAppBadge
method Navigator.setAppBadge
method Navigator.share
method Navigator.userActivation
method Navigator.wakeLock
method ShadowRoot.pictureInPictureElement
method Window.AbsoluteOrientationSensor
method Window.Accelerometer
method Window.BackgroundFetchManager
@ -254,9 +294,11 @@ method Window.offscreenBuffering
method Window.onbeforeinstallprompt
method Window.oncancel
method Window.onmousewheel
method Window.onorientationchange
method Window.onsearch
method Window.onselectionchange
method Window.openDatabase
method Window.orientation
method Window.OrientationSensor
method Window.OverconstrainedError
method Window.PasswordCredential
@ -337,6 +379,7 @@ method Window.webkitSpeechRecognition
method Window.webkitSpeechRecognitionError
method Window.webkitSpeechRecognitionEvent
method Window.webkitStorageInfo
method WorkerNavigator.permissions
// Gecko-specific command usage of `Document.execCommand`
custom DocumentExecCommandContentReadOnly calls execCommand with contentReadOnly

View file

@ -255,7 +255,7 @@ EXPORTS.mozilla.dom += [
"Pose.h",
"PostMessageEvent.h",
"ProcessMessageManager.h",
"RadioGroupManager.h",
"RadioGroupContainer.h",
"ResizeObserver.h",
"ResizeObserverController.h",
"ResponsiveImageSelector.h",
@ -438,7 +438,7 @@ UNIFIED_SOURCES += [
"Pose.cpp",
"PostMessageEvent.cpp",
"ProcessMessageManager.cpp",
"RadioGroupManager.cpp",
"RadioGroupContainer.cpp",
"RangeUtils.cpp",
"RemoteOuterWindowProxy.cpp",
"ResizeObserver.cpp",

View file

@ -70,6 +70,7 @@
#include "mozilla/Services.h"
#include "mozilla/Unused.h"
#include "mozilla/StaticPrefs_full_screen_api.h"
#include "mozilla/Try.h"
#include "mozilla/widget/IMEData.h"
#include <algorithm>

View file

@ -26,10 +26,11 @@
using namespace mozilla;
using namespace mozilla::dom;
static const char* kPrefSVGDisabled = "svg.disabled";
static const char* kPrefMathMLDisabled = "mathml.disabled";
static const char* kObservedNSPrefs[] = {kPrefMathMLDisabled, kPrefSVGDisabled,
nullptr};
static constexpr const char* kPrefSVGDisabled = "svg.disabled";
static constexpr const char* kPrefMathMLDisabled = "mathml.disabled";
static constexpr const char* kObservedNSPrefs[] = {kPrefMathMLDisabled,
kPrefSVGDisabled, nullptr};
StaticRefPtr<nsNameSpaceManager> nsNameSpaceManager::sInstance;
/* static */

View file

@ -15,6 +15,7 @@
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Try.h"
#include "mozilla/ResultExtensions.h"
#include "nsNetCID.h"
#include "nsPrintfCString.h"

View file

@ -11,4 +11,4 @@ license = "MPL-2.0"
path = "lib.rs"
[dependencies]
bitflags = "1.0"
bitflags = "2"

View file

@ -9,6 +9,7 @@ use bitflags::bitflags;
bitflags! {
/// Event-based element states.
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ElementState: u64 {
/// The mouse is down on this element.
/// <https://html.spec.whatwg.org/multipage/#selector-active>
@ -147,6 +148,7 @@ bitflags! {
bitflags! {
/// Event-based document states.
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct DocumentState: u64 {
/// Window activation status
const WINDOW_INACTIVE = 1 << 0;

View file

@ -12,6 +12,7 @@
#include "ClientSourceChild.h"
#include "ClientState.h"
#include "ClientValidation.h"
#include "mozilla/Try.h"
#include "mozilla/dom/BlobURLProtocolHandler.h"
#include "mozilla/dom/ClientIPCTypes.h"
#include "mozilla/dom/DOMMozPromiseRequestHolder.h"

View file

@ -145,21 +145,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLFormElement,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPastNameLookupTable)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTargetContext)
RadioGroupManager::Traverse(tmp, cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLFormElement,
nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRelList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTargetContext)
RadioGroupManager::Unlink(tmp);
tmp->Clear();
tmp->mExpandoAndGeneration.OwnerUnlinked();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLFormElement,
nsGenericHTMLElement,
nsIRadioGroupContainer)
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(HTMLFormElement,
nsGenericHTMLElement)
// EventTarget
void HTMLFormElement::AsyncEventRunning(AsyncEventDispatcher* aEvent) {
@ -1251,7 +1248,7 @@ nsresult HTMLFormElement::AddElement(nsGenericHTMLFormElement* aChild,
// being count twice.
if (type == FormControlType::InputRadio) {
RefPtr<HTMLInputElement> radio = static_cast<HTMLInputElement*>(aChild);
radio->AddedToRadioGroup();
radio->AddToRadioGroup();
}
return NS_OK;
@ -1287,7 +1284,7 @@ nsresult HTMLFormElement::RemoveElement(nsGenericHTMLFormElement* aChild,
MOZ_ASSERT(fc);
if (fc->ControlType() == FormControlType::InputRadio) {
RefPtr<HTMLInputElement> radio = static_cast<HTMLInputElement*>(aChild);
radio->WillRemoveFromRadioGroup();
radio->RemoveFromRadioGroup();
}
// Determine whether to remove the child from the elements list
@ -1860,59 +1857,6 @@ int32_t HTMLFormElement::IndexOfContent(nsIContent* aContent) {
return mControls->IndexOfContent(aContent, &index) == NS_OK ? index : 0;
}
void HTMLFormElement::SetCurrentRadioButton(const nsAString& aName,
HTMLInputElement* aRadio) {
RadioGroupManager::SetCurrentRadioButton(aName, aRadio);
}
HTMLInputElement* HTMLFormElement::GetCurrentRadioButton(
const nsAString& aName) {
return RadioGroupManager::GetCurrentRadioButton(aName);
}
NS_IMETHODIMP
HTMLFormElement::GetNextRadioButton(const nsAString& aName,
const bool aPrevious,
HTMLInputElement* aFocusedRadio,
HTMLInputElement** aRadioOut) {
return RadioGroupManager::GetNextRadioButton(aName, aPrevious, aFocusedRadio,
aRadioOut);
}
NS_IMETHODIMP
HTMLFormElement::WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor) {
return RadioGroupManager::WalkRadioGroup(aName, aVisitor);
}
void HTMLFormElement::AddToRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) {
RadioGroupManager::AddToRadioGroup(aName, aRadio, this);
}
void HTMLFormElement::RemoveFromRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) {
RadioGroupManager::RemoveFromRadioGroup(aName, aRadio);
}
uint32_t HTMLFormElement::GetRequiredRadioCount(const nsAString& aName) const {
return RadioGroupManager::GetRequiredRadioCount(aName);
}
void HTMLFormElement::RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) {
RadioGroupManager::RadioRequiredWillChange(aName, aRequiredAdded);
}
bool HTMLFormElement::GetValueMissingState(const nsAString& aName) const {
return RadioGroupManager::GetValueMissingState(aName);
}
void HTMLFormElement::SetValueMissingState(const nsAString& aName,
bool aValue) {
RadioGroupManager::SetValueMissingState(aName, aValue);
}
void HTMLFormElement::Clear() {
for (int32_t i = mImageElements.Length() - 1; i >= 0; i--) {
mImageElements[i]->ClearForm(false);

View file

@ -13,11 +13,10 @@
#include "mozilla/dom/AnchorAreaFormRelValues.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/PopupBlocker.h"
#include "mozilla/dom/RadioGroupManager.h"
#include "mozilla/dom/RadioGroupContainer.h"
#include "nsCOMPtr.h"
#include "nsIFormControl.h"
#include "nsGenericHTMLElement.h"
#include "nsIRadioGroupContainer.h"
#include "nsIWeakReferenceUtils.h"
#include "nsThreadUtils.h"
#include "nsInterfaceHashtable.h"
@ -39,9 +38,7 @@ class HTMLImageElement;
class FormData;
class HTMLFormElement final : public nsGenericHTMLElement,
public nsIRadioGroupContainer,
public AnchorAreaFormRelValues,
RadioGroupManager {
public AnchorAreaFormRelValues {
friend class HTMLFormControlsCollection;
public:
@ -61,25 +58,6 @@ class HTMLFormElement final : public nsGenericHTMLElement,
return aElement == mDefaultSubmitElement;
}
// nsIRadioGroupContainer
void SetCurrentRadioButton(const nsAString& aName,
HTMLInputElement* aRadio) override;
HTMLInputElement* GetCurrentRadioButton(const nsAString& aName) override;
NS_IMETHOD GetNextRadioButton(const nsAString& aName, const bool aPrevious,
HTMLInputElement* aFocusedRadio,
HTMLInputElement** aRadioOut) override;
NS_IMETHOD WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor) override;
void AddToRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) override;
void RemoveFromRadioGroup(const nsAString& aName,
HTMLInputElement* aRadio) override;
uint32_t GetRequiredRadioCount(const nsAString& aName) const override;
void RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) override;
bool GetValueMissingState(const nsAString& aName) const override;
void SetValueMissingState(const nsAString& aName, bool aValue) override;
// EventTarget
void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;

View file

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "HTMLFrameSetElement.h"
#include "mozilla/Try.h"
#include "mozilla/dom/HTMLFrameSetElementBinding.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/EventHandlerBinding.h"

View file

@ -30,14 +30,13 @@
#include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/TextUtils.h"
#include "mozilla/Try.h"
#include "nsAttrValueInlines.h"
#include "nsCRTGlue.h"
#include "nsIFilePicker.h"
#include "nsNetUtil.h"
#include "nsQueryObject.h"
#include "nsIRadioVisitor.h"
#include "HTMLDataListElement.h"
#include "HTMLFormSubmissionConstants.h"
#include "mozilla/Telemetry.h"
@ -85,7 +84,9 @@
#include <algorithm>
// input type=radio
#include "nsIRadioGroupContainer.h"
#include "mozilla/dom/RadioGroupContainer.h"
#include "nsIRadioVisitor.h"
#include "nsRadioVisitor.h"
// input type=file
#include "mozilla/dom/FileSystemEntry.h"
@ -106,7 +107,6 @@
#include "nsContentCreatorFunctions.h"
#include "nsContentUtils.h"
#include "mozilla/dom/DirectionalityUtils.h"
#include "nsRadioVisitor.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/Preferences.h"
@ -1014,7 +1014,8 @@ HTMLInputElement::HTMLInputElement(already_AddRefed<dom::NodeInfo>&& aNodeInfo,
mPickerRunning(false),
mIsPreviewEnabled(false),
mHasBeenTypePassword(false),
mHasPatternAttribute(false) {
mHasPatternAttribute(false),
mRadioGroupContainer(nullptr) {
// If size is above 512, mozjemalloc allocates 1kB, see
// memory/build/mozjemalloc.cpp
static_assert(sizeof(HTMLInputElement) <= 512,
@ -1186,9 +1187,9 @@ void HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsAtom* aName,
if (mType == FormControlType::InputRadio) {
if ((aName == nsGkAtoms::name || (aName == nsGkAtoms::type && !mForm)) &&
(mForm || mDoneCreating)) {
WillRemoveFromRadioGroup();
RemoveFromRadioGroup();
} else if (aName == nsGkAtoms::required) {
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
auto* container = GetCurrentRadioGroupContainer();
if (container && ((aValue && !HasAttr(aNameSpaceID, aName)) ||
(!aValue && HasAttr(aNameSpaceID, aName)))) {
@ -1284,7 +1285,7 @@ void HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
// If we are not done creating the radio, we also should not do it.
if ((aName == nsGkAtoms::name || (aName == nsGkAtoms::type && !mForm)) &&
mType == FormControlType::InputRadio && (mForm || mDoneCreating)) {
AddedToRadioGroup();
AddToRadioGroup();
UpdateValueMissingValidityStateForRadio(false);
needValidityUpdate = true;
}
@ -1416,7 +1417,7 @@ void HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
void HTMLInputElement::BeforeSetForm(bool aBindToTree) {
// No need to remove from radio group if we are just binding to tree.
if (mType == FormControlType::InputRadio && !aBindToTree) {
WillRemoveFromRadioGroup();
RemoveFromRadioGroup();
}
}
@ -1424,8 +1425,9 @@ void HTMLInputElement::AfterClearForm(bool aUnbindOrDelete) {
MOZ_ASSERT(!mForm);
// Do not add back to radio group if we are releasing or unbinding from tree.
if (mType == FormControlType::InputRadio && !aUnbindOrDelete) {
AddedToRadioGroup();
if (mType == FormControlType::InputRadio && !aUnbindOrDelete &&
!GetCurrentRadioGroupContainer()) {
AddToRadioGroup();
UpdateValueMissingValidityStateForRadio(false);
}
}
@ -2861,8 +2863,7 @@ void HTMLInputElement::DoSetChecked(bool aChecked, bool aNotify,
return;
}
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (container) {
if (auto* container = GetCurrentRadioGroupContainer()) {
nsAutoString name;
GetAttr(nsGkAtoms::name, name);
container->SetCurrentRadioButton(name, nullptr);
@ -2885,8 +2886,7 @@ void HTMLInputElement::RadioSetChecked(bool aNotify) {
}
// Let the group know that we are now the One True Radio Button
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (container) {
if (auto* container = GetCurrentRadioGroupContainer()) {
nsAutoString name;
GetAttr(nsGkAtoms::name, name);
container->SetCurrentRadioButton(name, this);
@ -2897,38 +2897,39 @@ void HTMLInputElement::RadioSetChecked(bool aNotify) {
SetCheckedInternal(true, aNotify);
}
nsIRadioGroupContainer* HTMLInputElement::GetRadioGroupContainer() const {
RadioGroupContainer* HTMLInputElement::GetCurrentRadioGroupContainer() const {
NS_ASSERTION(
mType == FormControlType::InputRadio,
"GetRadioGroupContainer should only be called when type='radio'");
return mRadioGroupContainer;
}
RadioGroupContainer* HTMLInputElement::FindTreeRadioGroupContainer() const {
nsAutoString name;
GetAttr(nsGkAtoms::name, name);
if (name.IsEmpty()) {
return nullptr;
}
if (mForm) {
return mForm;
return &mForm->OwnedRadioGroupContainer();
}
if (IsInNativeAnonymousSubtree()) {
return nullptr;
}
DocumentOrShadowRoot* docOrShadow = GetUncomposedDocOrConnectedShadowRoot();
if (!docOrShadow) {
return nullptr;
if (Document* doc = GetUncomposedDoc()) {
return &doc->OwnedRadioGroupContainer();
}
return &static_cast<FragmentOrElement*>(SubtreeRoot())
->OwnedRadioGroupContainer();
}
nsCOMPtr<nsIRadioGroupContainer> container =
do_QueryInterface(&(docOrShadow->AsNode()));
return container;
void HTMLInputElement::DisconnectRadioGroupContainer() {
mRadioGroupContainer = nullptr;
}
HTMLInputElement* HTMLInputElement::GetSelectedRadioButton() const {
nsIRadioGroupContainer* container = GetRadioGroupContainer();
auto* container = GetCurrentRadioGroupContainer();
if (!container) {
return nullptr;
}
@ -4140,7 +4141,7 @@ nsresult HTMLInputElement::MaybeHandleRadioButtonNavigation(
}
// Arrow key pressed, focus+select prev/next radio button
RefPtr<HTMLInputElement> selectedRadioButton;
if (nsIRadioGroupContainer* container = GetRadioGroupContainer()) {
if (auto* container = GetCurrentRadioGroupContainer()) {
nsAutoString name;
GetAttr(nsGkAtoms::name, name);
container->GetNextRadioButton(name, move == RadioButtonMove::Back, this,
@ -4270,6 +4271,12 @@ void HTMLInputElement::MaybeLoadImage() {
}
nsresult HTMLInputElement::BindToTree(BindContext& aContext, nsINode& aParent) {
// If we are currently bound to a disconnected subtree root, remove
// ourselves from it first.
if (!mForm && mType == FormControlType::InputRadio) {
RemoveFromRadioGroup();
}
nsresult rv =
nsGenericHTMLFormControlElementWithState::BindToTree(aContext, aParent);
NS_ENSURE_SUCCESS(rv, rv);
@ -4292,9 +4299,8 @@ nsresult HTMLInputElement::BindToTree(BindContext& aContext, nsINode& aParent) {
// Add radio to document if we don't have a form already (if we do it's
// already been added into that group)
if (!mForm && mType == FormControlType::InputRadio &&
GetUncomposedDocOrConnectedShadowRoot()) {
AddedToRadioGroup();
if (!mForm && mType == FormControlType::InputRadio) {
AddToRadioGroup();
}
// Set direction based on value if dir=auto
@ -4346,7 +4352,7 @@ void HTMLInputElement::UnbindFromTree(bool aNullParent) {
// of the case where we're removing from the document and we don't
// have a form
if (!mForm && mType == FormControlType::InputRadio) {
WillRemoveFromRadioGroup();
RemoveFromRadioGroup();
}
if (CreatesDateTimeWidget() && IsInComposedDoc()) {
@ -4356,6 +4362,12 @@ void HTMLInputElement::UnbindFromTree(bool aNullParent) {
nsImageLoadingContent::UnbindFromTree(aNullParent);
nsGenericHTMLFormControlElementWithState::UnbindFromTree(aNullParent);
// If we are contained within a disconnected subtree, attempt to add
// ourselves to the subtree root's radio group.
if (!mForm && mType == FormControlType::InputRadio) {
AddToRadioGroup();
}
// GetCurrentDoc is returning nullptr so we can update the value
// missing validity state to reflect we are no longer into a doc.
UpdateValueMissingValidityState();
@ -6220,16 +6232,27 @@ bool HTMLInputElement::RestoreState(PresState* aState) {
* Radio group stuff
*/
void HTMLInputElement::AddedToRadioGroup() {
// If the element is neither in a form nor a document, there is no group so we
// should just stop here.
if (!mForm && (!GetUncomposedDocOrConnectedShadowRoot() ||
IsInNativeAnonymousSubtree())) {
void HTMLInputElement::AddToRadioGroup() {
MOZ_ASSERT(!mRadioGroupContainer,
"Radio button must be removed from previous radio group container "
"before being added to another!");
// If the element has no radio group container we can stop here.
auto* container = FindTreeRadioGroupContainer();
if (!container) {
return;
}
// Make sure not to notify if we're still being created
bool notify = mDoneCreating;
nsAutoString name;
GetAttr(nsGkAtoms::name, name);
// If we are part of a radio group, the element must have a name.
MOZ_ASSERT(!name.IsEmpty());
//
// Add the radio to the radio group container.
//
container->AddToRadioGroup(name, this, mForm);
mRadioGroupContainer = container;
//
// If the input element is checked, and we add it to the group, it will
@ -6242,8 +6265,9 @@ void HTMLInputElement::AddedToRadioGroup() {
// radio button, but as adding a checked radio button into the group
// should not be that common an occurrence, I think we can live with
// that.
// Make sure not to notify if we're still being created.
//
RadioSetChecked(notify);
RadioSetChecked(mDoneCreating);
}
//
@ -6258,24 +6282,14 @@ void HTMLInputElement::AddedToRadioGroup() {
SetCheckedChangedInternal(checkedChanged);
//
// Add the radio to the radio group container.
//
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
if (container) {
nsAutoString name;
GetAttr(nsGkAtoms::name, name);
container->AddToRadioGroup(name, this);
// We initialize the validity of the element to the validity of the group
// because we assume UpdateValueMissingState() will be called after.
SetValidityState(VALIDITY_STATE_VALUE_MISSING,
container->GetValueMissingState(name));
}
// We initialize the validity of the element to the validity of the group
// because we assume UpdateValueMissingState() will be called after.
SetValidityState(VALIDITY_STATE_VALUE_MISSING,
container->GetValueMissingState(name));
}
void HTMLInputElement::WillRemoveFromRadioGroup() {
nsIRadioGroupContainer* container = GetRadioGroupContainer();
void HTMLInputElement::RemoveFromRadioGroup() {
auto* container = GetCurrentRadioGroupContainer();
if (!container) {
return;
}
@ -6296,6 +6310,7 @@ void HTMLInputElement::WillRemoveFromRadioGroup() {
// the group validity is updated (with this element being ignored).
UpdateValueMissingValidityStateForRadio(true);
container->RemoveFromRadioGroup(name, this);
mRadioGroupContainer = nullptr;
}
bool HTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
@ -6352,7 +6367,7 @@ bool HTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
// Current radio button is not selected.
// But make it tabbable if nothing in group is selected.
nsIRadioGroupContainer* container = GetRadioGroupContainer();
auto* container = GetCurrentRadioGroupContainer();
if (!container) {
*aIsFocusable = defaultFocusable;
return false;
@ -6369,8 +6384,7 @@ bool HTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
}
nsresult HTMLInputElement::VisitGroup(nsIRadioVisitor* aVisitor) {
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (container) {
if (auto* container = GetCurrentRadioGroupContainer()) {
nsAutoString name;
GetAttr(nsGkAtoms::name, name);
return container->WalkRadioGroup(name, aVisitor);
@ -6661,21 +6675,15 @@ void HTMLInputElement::UpdateValueMissingValidityStateForRadio(
bool selected = selection || (!aIgnoreSelf && mChecked);
bool required = !aIgnoreSelf && IsRequired();
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
auto* container = GetCurrentRadioGroupContainer();
if (!container) {
SetValidityState(VALIDITY_STATE_VALUE_MISSING, false);
return;
}
nsAutoString name;
GetAttr(nsGkAtoms::name, name);
if (!container) {
// As per the spec, a radio button not within a radio button group cannot
// suffer from being missing; however, we currently are failing to get a
// radio group in the case of a single, named radio button that has no
// form owner, forcing us to check for validity in that case here.
SetValidityState(VALIDITY_STATE_VALUE_MISSING,
required && !selected && !name.IsEmpty());
return;
}
// If the current radio is required and not ignored, we can assume the entire
// group is required.
if (!required) {

View file

@ -28,6 +28,7 @@
#include "mozilla/dom/ConstraintValidation.h"
#include "mozilla/dom/FileInputType.h"
#include "mozilla/dom/HiddenInputType.h"
#include "mozilla/dom/RadioGroupContainer.h"
#include "nsGenericHTMLElement.h"
#include "nsImageLoadingContent.h"
#include "nsCOMPtr.h"
@ -35,7 +36,6 @@
#include "nsIContentPrefService2.h"
#include "nsContentUtils.h"
class nsIRadioGroupContainer;
class nsIRadioVisitor;
namespace mozilla {
@ -277,8 +277,9 @@ class HTMLInputElement final : public TextControlElement,
void SetCheckedChangedInternal(bool aCheckedChanged);
bool GetCheckedChanged() const { return mCheckedChanged; }
void AddedToRadioGroup();
void WillRemoveFromRadioGroup();
void AddToRadioGroup();
void RemoveFromRadioGroup();
void DisconnectRadioGroupContainer();
/**
* Helper function returning the currently selected button in the radio group.
@ -1144,12 +1145,15 @@ class HTMLInputElement final : public TextControlElement,
}
/**
* Returns the radio group container if the element has one, null otherwise.
* The radio group container will be the form owner if there is one.
* The current document otherwise.
* @return the radio group container if the element has one, null otherwise.
* Returns the radio group container within the DOM tree that the element
* is currently a member of, if one exists.
*/
nsIRadioGroupContainer* GetRadioGroupContainer() const;
RadioGroupContainer* GetCurrentRadioGroupContainer() const;
/**
* Returns the radio group container within the DOM tree that the element
* should be added into, if one exists.
*/
RadioGroupContainer* FindTreeRadioGroupContainer() const;
/**
* Parse a color string of the form #XXXXXX where X should be hexa characters
@ -1633,6 +1637,12 @@ class HTMLInputElement final : public TextControlElement,
*/
static bool IsDateTimeTypeSupported(FormControlType);
/**
* The radio group container containing the group the element is a part of.
* This allows the element to only access a container it has been added to.
*/
RadioGroupContainer* mRadioGroupContainer;
struct nsFilePickerFilter {
nsFilePickerFilter() : mFilterMask(0) {}

View file

@ -92,23 +92,24 @@ nsresult HTMLLinkElement::BindToTree(BindContext& aContext, nsINode& aParent) {
LinkStyle::BindToTree();
if (IsInUncomposedDoc() &&
AttrValueIs(kNameSpaceID_None, nsGkAtoms::rel, nsGkAtoms::localization,
eIgnoreCase)) {
aContext.OwnerDoc().LocalizationLinkAdded(this);
}
if (IsInUncomposedDoc()) {
if (AttrValueIs(kNameSpaceID_None, nsGkAtoms::rel, nsGkAtoms::localization,
eIgnoreCase)) {
aContext.OwnerDoc().LocalizationLinkAdded(this);
}
LinkAdded();
LinkAdded();
}
return rv;
}
void HTMLLinkElement::LinkAdded() {
CreateAndDispatchEvent(OwnerDoc(), u"DOMLinkAdded"_ns);
CreateAndDispatchEvent(u"DOMLinkAdded"_ns);
}
void HTMLLinkElement::LinkRemoved() {
CreateAndDispatchEvent(OwnerDoc(), u"DOMLinkRemoved"_ns);
CreateAndDispatchEvent(u"DOMLinkRemoved"_ns);
}
void HTMLLinkElement::UnbindFromTree(bool aNullParent) {
@ -123,13 +124,16 @@ void HTMLLinkElement::UnbindFromTree(bool aNullParent) {
// We want to update the localization but only if the link is removed from a
// DOM change, and not because the document is going away.
bool ignore;
if (oldDoc && oldDoc->GetScriptHandlingObject(ignore) &&
AttrValueIs(kNameSpaceID_None, nsGkAtoms::rel, nsGkAtoms::localization,
eIgnoreCase)) {
oldDoc->LocalizationLinkRemoved(this);
if (oldDoc) {
if (oldDoc->GetScriptHandlingObject(ignore) &&
AttrValueIs(kNameSpaceID_None, nsGkAtoms::rel, nsGkAtoms::localization,
eIgnoreCase)) {
oldDoc->LocalizationLinkRemoved(this);
}
CreateAndDispatchEvent(u"DOMLinkRemoved"_ns);
}
CreateAndDispatchEvent(oldDoc, u"DOMLinkRemoved"_ns);
nsGenericHTMLElement::UnbindFromTree(aNullParent);
Unused << UpdateStyleSheetInternal(oldDoc, oldShadowRoot);
@ -165,9 +169,8 @@ bool HTMLLinkElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
aMaybeScriptedPrincipal, aResult);
}
void HTMLLinkElement::CreateAndDispatchEvent(Document* aDoc,
const nsAString& aEventName) {
if (!aDoc) return;
void HTMLLinkElement::CreateAndDispatchEvent(const nsAString& aEventName) {
MOZ_ASSERT(IsInUncomposedDoc());
// In the unlikely case that both rev is specified *and* rel=stylesheet,
// this code will cause the event to fire, on the principle that maybe the
@ -212,7 +215,7 @@ void HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::href) {
mCachedURI = nullptr;
if (IsInUncomposedDoc()) {
CreateAndDispatchEvent(OwnerDoc(), u"DOMLinkChanged"_ns);
CreateAndDispatchEvent(u"DOMLinkChanged"_ns);
}
mTriggeringPrincipal = nsContentUtils::GetAttrTriggeringPrincipal(
this, aValue ? aValue->GetStringValue() : EmptyString(),

View file

@ -61,7 +61,7 @@ class HTMLLinkElement final : public nsGenericHTMLElement,
nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult) override;
void CreateAndDispatchEvent(Document* aDoc, const nsAString& aEventName);
void CreateAndDispatchEvent(const nsAString& aEventName);
// WebIDL
bool Disabled() const;

View file

@ -30,7 +30,6 @@ EXPORTS += [
"nsIConstraintValidation.h",
"nsIFormControl.h",
"nsIHTMLCollection.h",
"nsIRadioGroupContainer.h",
"nsIRadioVisitor.h",
]

View file

@ -1256,13 +1256,13 @@ static inline void MapLangAttributeInto(MappedDeclarationsBuilder& aBuilder) {
const nsAtom* lang = langValue->GetAtomValue();
if (nsStyleUtil::MatchesLanguagePrefix(lang, u"zh")) {
aBuilder.SetKeywordValue(eCSSProperty_text_emphasis_position,
StyleTextEmphasisPosition::UNDER.bits);
StyleTextEmphasisPosition::UNDER._0);
} else if (nsStyleUtil::MatchesLanguagePrefix(lang, u"ja") ||
nsStyleUtil::MatchesLanguagePrefix(lang, u"mn")) {
// This branch is currently no part of the spec.
// See bug 1040668 comment 69 and comment 75.
aBuilder.SetKeywordValue(eCSSProperty_text_emphasis_position,
StyleTextEmphasisPosition::OVER.bits);
StyleTextEmphasisPosition::OVER._0);
}
}
}

View file

@ -1,101 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsIRadioGroupContainer_h___
#define nsIRadioGroupContainer_h___
#include "nsISupports.h"
class nsIRadioVisitor;
class nsIFormControl;
namespace mozilla::dom {
class HTMLInputElement;
} // namespace mozilla::dom
#define NS_IRADIOGROUPCONTAINER_IID \
{ \
0x800320a0, 0x733f, 0x11e4, { \
0x82, 0xf8, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 \
} \
}
/**
* A container that has multiple radio groups in it, defined by name.
*/
class nsIRadioGroupContainer : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRADIOGROUPCONTAINER_IID)
/**
* Walk through the radio group, visiting each note with avisitor->Visit()
* @param aName the group name
* @param aVisitor the visitor to visit with
*/
NS_IMETHOD WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor) = 0;
/**
* Set the current radio button in a group
* @param aName the group name
* @param aRadio the currently selected radio button
*/
virtual void SetCurrentRadioButton(
const nsAString& aName, mozilla::dom::HTMLInputElement* aRadio) = 0;
/**
* Get the current radio button in a group
* @param aName the group name
* @return the currently selected radio button
*/
virtual mozilla::dom::HTMLInputElement* GetCurrentRadioButton(
const nsAString& aName) = 0;
/**
* Get the next/prev radio button in a group
* @param aName the group name
* @param aPrevious, true gets previous radio button, false gets next
* @param aFocusedRadio the currently focused radio button
* @param aRadio the currently selected radio button [OUT]
*/
NS_IMETHOD GetNextRadioButton(const nsAString& aName, const bool aPrevious,
mozilla::dom::HTMLInputElement* aFocusedRadio,
mozilla::dom::HTMLInputElement** aRadio) = 0;
/**
* Add radio button to radio group
*
* Note that forms do not do anything for this method since they already
* store radio groups on their own.
*
* @param aName radio group's name
* @param aRadio radio button's pointer
*/
virtual void AddToRadioGroup(const nsAString& aName,
mozilla::dom::HTMLInputElement* aRadio) = 0;
/**
* Remove radio button from radio group
*
* Note that forms do not do anything for this method since they already
* store radio groups on their own.
*
* @param aName radio group's name
* @param aRadio radio button's pointer
*/
virtual void RemoveFromRadioGroup(const nsAString& aName,
mozilla::dom::HTMLInputElement* aRadio) = 0;
virtual uint32_t GetRequiredRadioCount(const nsAString& aName) const = 0;
virtual void RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) = 0;
virtual bool GetValueMissingState(const nsAString& aName) const = 0;
virtual void SetValueMissingState(const nsAString& aName, bool aValue) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIRadioGroupContainer,
NS_IRADIOGROUPCONTAINER_IID)
#endif /* nsIRadioGroupContainer_h__ */

View file

@ -8,6 +8,7 @@
#include "mozilla/AutoMemMap.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/Try.h"
#include "mozilla/ipc/FileDescriptor.h"
namespace mozilla::ipc {

View file

@ -19,6 +19,7 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/IOBuffers.h"
#include "mozilla/ScriptPreloader.h"
#include "mozilla/Try.h"
using namespace mozilla::loader;

View file

@ -10,6 +10,7 @@
#include "ScriptPreloader-inl.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/Try.h"
#include "mozilla/ipc/FileDescriptor.h"
using namespace mozilla::loader;

View file

@ -11,6 +11,7 @@
#include "VideoUtils.h"
#include "BufferReader.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/Try.h"
namespace mozilla {

View file

@ -44,6 +44,7 @@
#include "mozilla/ipc/ProcessUtils.h"
#include "nsDebugImpl.h"
#include "nsIObserverService.h"
#include "nsIXULRuntime.h"
#include "nsThreadManager.h"

View file

@ -271,7 +271,8 @@ bool RemoteDecoderManagerChild::Supports(
// process. As HEVC support is still a experimental feature, we don't want
// to report support for it arbitrarily.
if (MP4Decoder::IsHEVC(aParams.mConfig.mMimeType)) {
return aLocation == RemoteDecodeIn::UtilityProcess_MFMediaEngineCDM;
return aLocation == RemoteDecodeIn::UtilityProcess_MFMediaEngineCDM ||
aLocation == RemoteDecodeIn::GpuProcess;
}
return trackSupport.contains(TrackSupport::Video);
}

View file

@ -23,6 +23,7 @@
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/VideoBridgeChild.h"
#include "mozilla/layers/VideoBridgeParent.h"
#include "nsIObserverService.h"
#ifdef MOZ_WMF_MEDIA_ENGINE
# include "MFMediaEngineParent.h"

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