Update On Fri Sep 6 20:50:23 CEST 2024

This commit is contained in:
github-action[bot] 2024-09-06 20:50:24 +02:00
parent 5822b45acc
commit b3a8d77781
2384 changed files with 7853 additions and 3542 deletions

View file

@ -834,6 +834,9 @@ pref("browser.shopping.experience2023.sidebarClosedCount", 0);
// When conditions are met, shows a prompt on the shopping sidebar asking users if they want to disable auto-open behavior
pref("browser.shopping.experience2023.showKeepSidebarClosedMessage", true);
// Integrates the Review Checker shopping feature into the global sidebar
pref("browser.shopping.experience2023.integratedSidebar", false);
// Spin the cursor while the page is loading
pref("browser.spin_cursor_while_busy", false);
@ -947,9 +950,6 @@ pref("browser.tabs.tabMinWidth", 76);
// of the text at small font sizes.
pref("browser.tabs.secondaryTextUnsupportedLocales", "ar,bn,bo,ckb,fa,gu,he,hi,ja,km,kn,ko,lo,mr,my,ne,pa,si,ta,te,th,ur,zh");
//Control the visibility of Tab Manager Menu.
pref("browser.tabs.tabmanager.enabled", true);
// When tabs opened by links in other tabs via a combination of
// browser.link.open_newwindow being set to 3 and target="_blank" etc are
// closed:
@ -1230,15 +1230,9 @@ pref("network.manage-offline-status", true);
// We want to make sure mail URLs are handled externally...
pref("network.protocol-handler.external.mailto", true); // for mail
#ifdef XP_WIN
pref("network.protocol-handler.external.ms-windows-store", true);
#endif
// ...without warning dialogs
pref("network.protocol-handler.warn-external.mailto", false);
#ifdef XP_WIN
pref("network.protocol-handler.warn-external.ms-windows-store", false);
#endif
// By default, all protocol handlers are exposed. This means that
// the browser will respond to openURL commands for all URL types.
@ -1740,6 +1734,10 @@ pref("browser.partnerlink.campaign.topsites", "amzn_2020_a1");
// Activates preloading of the new tab url.
pref("browser.newtab.preload", true);
// Mozilla Ad Routing Service (MARS) unified ads service
pref("browser.newtabpage.activity-stream.unifiedAds.enabled", false);
pref("browser.newtabpage.activity-stream.unifiedAds.endpoint", "https://ads.mozilla.org/");
// Weather widget for newtab
pref("browser.newtabpage.activity-stream.showWeather", true);
pref("browser.newtabpage.activity-stream.weather.query", "");

View file

@ -87,6 +87,165 @@ const ERROR_L10N_IDS = new Map([
],
]);
customElements.define(
"addon-webext-permissions-notification",
class MozAddonPermissionsNotification extends customElements.get(
"popupnotification"
) {
show() {
super.show();
if (!this.notification) {
return;
}
if (!this.notification.options?.customElementOptions) {
throw new Error(
"Mandatory customElementOptions property missing from notification options"
);
}
this.textEl = this.querySelector("#addon-webext-perm-text");
this.introEl = this.querySelector("#addon-webext-perm-intro");
this.permsSingleEl = this.querySelector(
"#addon-webext-perm-single-entry"
);
this.permsListEl = this.querySelector("#addon-webext-perm-list");
this.render();
}
get hasNoPermissions() {
const { strings, showIncognitoCheckbox } =
this.notification.options.customElementOptions;
return !(showIncognitoCheckbox || strings.msgs.length);
}
get hasMultiplePermissionsEntries() {
const { strings, showIncognitoCheckbox } =
this.notification.options.customElementOptions;
return (
strings.msgs.length > 1 ||
(strings.msgs.length === 1 && showIncognitoCheckbox)
);
}
render() {
const { strings, showIncognitoCheckbox } =
this.notification.options.customElementOptions;
const { textEl, introEl, permsSingleEl, permsListEl } = this;
const HTML_NS = "http://www.w3.org/1999/xhtml";
const doc = this.ownerDocument;
this.#clearChildElements();
if (strings.text) {
textEl.textContent = strings.text;
// By default, multiline strings don't get formatted properly. These
// are presently only used in site permission add-ons, so we treat it
// as a special case to avoid unintended effects on other things.
if (strings.text.includes("\n\n")) {
textEl.classList.add("addon-webext-perm-text-multiline");
}
textEl.hidden = false;
}
if (strings.listIntro) {
introEl.textContent = strings.listIntro;
introEl.hidden = false;
}
// Return earlier if there are no permissions to list.
if (this.hasNoPermissions) {
return;
}
// If there are multiple permissions entries to be shown,
// add to the list element one entry for each granted permission
// (and one for the private browsing checkbox, if it should
// be shown) and return earlier.
if (this.hasMultiplePermissionsEntries) {
for (let msg of strings.msgs) {
let item = doc.createElementNS(HTML_NS, "li");
item.classList.add("webext-perm-granted");
item.textContent = msg;
permsListEl.appendChild(item);
}
if (showIncognitoCheckbox) {
let item = doc.createElementNS(HTML_NS, "li");
item.classList.add(
"webext-perm-optional",
"webext-perm-privatebrowsing"
);
item.appendChild(this.#createPrivateBrowsingCheckbox());
permsListEl.appendChild(item);
}
permsListEl.hidden = false;
return;
}
// Render a single permission entry, which will be either:
// - an entry for the private browsing checkbox
// - or single granted permission entry.
if (showIncognitoCheckbox) {
permsSingleEl.appendChild(this.#createPrivateBrowsingCheckbox());
permsSingleEl.hidden = false;
permsSingleEl.classList.add(
"webext-perm-optional",
"webext-perm-privatebrowsing"
);
return;
}
permsSingleEl.textContent = strings.msgs[0];
permsSingleEl.hidden = false;
}
#clearChildElements() {
const { textEl, introEl, permsSingleEl, permsListEl } = this;
// Clear all changes to the child elements that may have been changed
// by a previous call of the render method.
textEl.textContent = "";
textEl.hidden = true;
textEl.classList.remove("addon-webext-perm-text-multiline");
introEl.textContent = "";
introEl.hidden = true;
permsSingleEl.textContent = "";
permsSingleEl.hidden = true;
permsSingleEl.classList.remove(
"webext-perm-optional",
"webext-perm-privatebrowsing"
);
permsListEl.textContent = "";
permsListEl.hidden = true;
}
#createPrivateBrowsingCheckbox() {
const { onPrivateBrowsingAllowedChanged, grantPrivateBrowsingAllowed } =
this.notification.options.customElementOptions;
const doc = this.ownerDocument;
let checkboxEl = doc.createXULElement("checkbox");
checkboxEl.checked = grantPrivateBrowsingAllowed;
checkboxEl.addEventListener("CheckboxStateChange", () => {
onPrivateBrowsingAllowedChanged?.(checkboxEl.checked);
});
doc.l10n.setAttributes(
checkboxEl,
"popup-notification-addon-privatebrowsing-checkbox"
);
return checkboxEl;
}
}
);
customElements.define(
"addon-progress-notification",
class MozAddonProgressNotification extends customElements.get(

View file

@ -5,7 +5,7 @@
<hbox flex="1" id="browser">
<box context="sidebar-context-menu" id="sidebar-main" hidden="true">
<html:sidebar-main flex="1">
<html:div id="vertical-tabs" slot="tabstrip" customizable="true"></html:div>
<box id="vertical-tabs" slot="tabstrip" customizable="true" contextmenu="toolbar-context-menu"></box>
</html:sidebar-main>
</box>
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">

View file

@ -111,20 +111,14 @@
<popupnotificationcontent id="addon-install-confirmation-content" orient="vertical"/>
</popupnotification>
<popupnotification id="addon-webext-permissions-notification" hidden="true">
<popupnotification id="addon-webext-permissions-notification"
is="addon-webext-permissions-notification"
hidden="true">
<popupnotificationcontent class="addon-webext-perm-notification-content" orient="vertical">
<description id="addon-webext-perm-text" class="addon-webext-perm-text"/>
<label id="addon-webext-perm-intro" class="addon-webext-perm-text"/>
<label id="addon-webext-perm-single-entry" class="addon-webext-perm-single-entry"/>
<html:ul id="addon-webext-perm-list" class="addon-webext-perm-list"/>
<hbox>
<html:a
is="moz-support-link"
id="addon-webext-perm-info"
class="popup-notification-learnmore-link"
support-page="extension-permissions"
/>
</hbox>
</popupnotificationcontent>
</popupnotification>

View file

@ -244,11 +244,11 @@ skip-if = ["os == 'linux' && !debug"] # Bug 1556066
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_bug1261299.js"]
skip-if = ["os != 'mac'"] # Because of tests for supporting Service Menu of macOS, bug 1261299
run-if = ["os == 'mac'"] # Because of tests for supporting Service Menu of macOS, bug 1261299
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_bug1297539.js"]
skip-if = ["os != 'mac'"] # Because of tests for supporting pasting from Service Menu of macOS, bug 1297539
run-if = ["os == 'mac'"] # Because of tests for supporting pasting from Service Menu of macOS, bug 1297539
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_bug1299667.js"]
@ -273,10 +273,8 @@ skip-if = ["true"] # Clicks in content don't go through contentAreaClick.
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_datachoices_notification.js"]
skip-if = [
"!datareporting",
"verify && !debug && os == 'win'",
]
run-if = ["datareporting"]
skip-if = ["verify && !debug && os == 'win'"]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_documentnavigation.js"]
@ -397,10 +395,8 @@ support-files = [
["browser_remoteTroubleshoot.js"]
https_first_disabled = true
skip-if = [
"!updater",
"os == 'linux' && asan", # Bug 1711507
]
run-if = ["updater"]
skip-if = ["os == 'linux' && asan"] # Bug 1711507
reason = "depends on UpdateUtils .Locale"
support-files = ["test_remoteTroubleshoot.html"]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
@ -409,7 +405,7 @@ support-files = ["test_remoteTroubleshoot.html"]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_restore_isAppTab.js"]
skip-if = ["!crashreporter"] # test requires crashreporter due to 1536221
run-if = ["crashreporter"] # test requires crashreporter due to 1536221
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_save_link-perwindowpb.js"]

View file

@ -14,7 +14,10 @@ https_first_disabled = true
run-if = ["os == 'mac'"] # Mac only feature
["browser_history_recently_closed_tabs.js"]
skip-if = ["os == 'mac'"] # No menubar on macOS.
run-if = [
"os == 'linux'",
"os == 'win'",
] # No menubar on macOS.
support-files = ["file_shareurl.html"]

View file

@ -40,8 +40,8 @@ support-files = ["!/browser/components/downloads/test/browser/head.js"]
["browser_preferences_usage.js"]
https_first_disabled = true
run-if = ["debug"]
skip-if = [
"!debug",
"apple_catalina", # platform migration
"socketprocess_networking",
]
@ -52,7 +52,7 @@ skip-if = [
support-files = ["file_empty.html"]
["browser_startup_content_subframe.js"]
skip-if = ["!fission"]
run-if = ["fission"]
support-files = [
"file_empty.html",
"StartupContentSubframe.sys.mjs",
@ -65,7 +65,10 @@ run-if = [
]
["browser_startup_hiddenwindow.js"]
skip-if = ["os == 'mac'"]
run-if = [
"os == 'linux'",
"os == 'win'",
]
["browser_tabclose.js"]
skip-if = [

View file

@ -5,4 +5,4 @@ prefs = [
]
["../browser_startup_images.js"]
skip-if = ["!debug"]
run-if = ["debug"]

View file

@ -5,4 +5,4 @@ prefs = [
]
["../browser_startup_images.js"]
skip-if = ["!debug"]
run-if = ["debug"]

View file

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = ["!crashreporter"]
run-if = ["crashreporter"]
support-files = [
"head.js",
"file_contains_emptyiframe.html",

View file

@ -39,10 +39,8 @@ skip-if = ["a11y_checks"] # Bug 1858037 to investigate intermittent a11y_checks
["browser_permissions_pointerevent.js"]
["browser_permissions_unsigned.js"]
skip-if = [
"require_signing",
"a11y_checks", # Bugs 1858041 and 1854461 to investigate intermittent a11y_checks results (fails on Autoland, passes on Try)
]
run-if = ["!require_signing"]
skip-if = ["a11y_checks"] # Bugs 1858041 and 1854461 to investigate intermittent a11y_checks results (fails on Autoland, passes on Try)
["browser_update_checkForUpdates.js"]

View file

@ -49,14 +49,12 @@ add_task(async function test_tab_switch_dismiss() {
content.wrappedJSObject.installMozAM(url);
});
await promisePopupNotificationShown("addon-webext-permissions");
const panel = await promisePopupNotificationShown("addon-webext-permissions");
assertPermissionsListCount({ grantedPermissionsCount: 5 });
let permsLearnMore = document.getElementById("addon-webext-perm-info");
ok(
BrowserTestUtils.isVisible(permsLearnMore),
"Learn more link is shown on Permission popup"
let permsLearnMore = panel.querySelector(
".popup-notification-learnmore-link"
);
is(
permsLearnMore.href,
@ -64,6 +62,10 @@ add_task(async function test_tab_switch_dismiss() {
"extension-permissions",
"Learn more link has desired URL"
);
ok(
BrowserTestUtils.isVisible(permsLearnMore),
"Learn more link is shown on Permission popup"
);
// Switching tabs dismisses the notification and cancels the install.
let switchTo = await BrowserTestUtils.openNewForegroundTab(gBrowser);

View file

@ -230,9 +230,9 @@ function checkNotification(
expectIncognitoCheckboxHidden
) {
let icon = panel.getAttribute("icon");
let learnMoreLink = panel.querySelector(".popup-notification-learnmore-link");
let ul = document.getElementById("addon-webext-perm-list");
let singleDataEl = document.getElementById("addon-webext-perm-single-entry");
let learnMoreLink = document.getElementById("addon-webext-perm-info");
if (checkIcon instanceof RegExp) {
ok(

View file

@ -110,7 +110,8 @@ export var ToolbarContextMenu = {
parent.classList.contains("customization-target") ||
parent.getAttribute("overflowfortoolbar") || // Needs to work in the overflow list as well.
parent.localName == "toolbarpaletteitem" ||
parent.localName == "toolbar"
parent.localName == "toolbar" ||
parent.id == "vertical-tabs"
) {
break;
}
@ -126,36 +127,50 @@ export var ToolbarContextMenu = {
}
}
MozXULElement.insertFTLIfNeeded("browser/toolbarContextMenu.ftl");
let firstMenuItem = aInsertPoint || popup.firstElementChild;
let toolbarNodes = gNavToolbox.querySelectorAll("toolbar");
for (let toolbar of toolbarNodes) {
if (!toolbar.hasAttribute("toolbarname")) {
continue;
}
let showTabStripItems = toolbarItem?.id == "tabbrowser-tabs";
let isVerticalTabStripMenu =
showTabStripItems && toolbarItem.parentElement.id == "vertical-tabs";
if (toolbar.id == "PersonalToolbar") {
let menu = BookmarkingUI.buildBookmarksToolbarSubmenu(toolbar);
popup.insertBefore(menu, firstMenuItem);
} else {
let menuItem = document.createXULElement("menuitem");
menuItem.setAttribute("id", "toggle_" + toolbar.id);
menuItem.setAttribute("toolbarId", toolbar.id);
menuItem.setAttribute("type", "checkbox");
menuItem.setAttribute("label", toolbar.getAttribute("toolbarname"));
let hidingAttribute =
toolbar.getAttribute("type") == "menubar" ? "autohide" : "collapsed";
menuItem.setAttribute(
"checked",
toolbar.getAttribute(hidingAttribute) != "true"
);
menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
if (popup.id != "toolbar-context-menu") {
menuItem.setAttribute("key", toolbar.getAttribute("key"));
if (aInsertPoint) {
aInsertPoint.hidden = isVerticalTabStripMenu;
}
document.getElementById("toolbar-context-customize").hidden =
isVerticalTabStripMenu;
if (!isVerticalTabStripMenu) {
MozXULElement.insertFTLIfNeeded("browser/toolbarContextMenu.ftl");
let firstMenuItem = aInsertPoint || popup.firstElementChild;
let toolbarNodes = gNavToolbox.querySelectorAll("toolbar");
for (let toolbar of toolbarNodes) {
if (!toolbar.hasAttribute("toolbarname")) {
continue;
}
popup.insertBefore(menuItem, firstMenuItem);
menuItem.addEventListener("command", onViewToolbarCommand);
if (toolbar.id == "PersonalToolbar") {
let menu = BookmarkingUI.buildBookmarksToolbarSubmenu(toolbar);
popup.insertBefore(menu, firstMenuItem);
} else {
let menuItem = document.createXULElement("menuitem");
menuItem.setAttribute("id", "toggle_" + toolbar.id);
menuItem.setAttribute("toolbarId", toolbar.id);
menuItem.setAttribute("type", "checkbox");
menuItem.setAttribute("label", toolbar.getAttribute("toolbarname"));
let hidingAttribute =
toolbar.getAttribute("type") == "menubar"
? "autohide"
: "collapsed";
menuItem.setAttribute(
"checked",
toolbar.getAttribute(hidingAttribute) != "true"
);
menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
if (popup.id != "toolbar-context-menu") {
menuItem.setAttribute("key", toolbar.getAttribute("key"));
}
popup.insertBefore(menuItem, firstMenuItem);
menuItem.addEventListener("command", onViewToolbarCommand);
}
}
}
@ -171,7 +186,6 @@ export var ToolbarContextMenu = {
return;
}
let showTabStripItems = toolbarItem?.id == "tabbrowser-tabs";
for (let node of popup.querySelectorAll(
'menuitem[contexttype="toolbaritem"]'
)) {

View file

@ -316,6 +316,17 @@ export class ExtensionControlledPopup {
anchorButton = action || doc.getElementById("PanelUI-menu-button");
}
let anchor = anchorButton.icon;
if (this.learnMoreLink) {
const learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") +
this.learnMoreLink;
popupnotification.setAttribute("learnmoreurl", learnMoreURL);
} else {
// In practice this isn't really needed because each of the
// controlled popups use its own popupnotification instance
// and they always have an learnMoreURL.
popupnotification.removeAttribute("learnmoreurl");
}
popupnotification.show();
panel.openPopup(anchor);
}
@ -349,11 +360,6 @@ export class ExtensionControlledPopup {
lazy.BrowserUIUtils.getLocalizedFragment(doc, message, addonDetails)
);
}
let link = doc.createElement("a", { is: "moz-support-link" });
link.setAttribute("class", "learnMore");
link.setAttribute("support-page", this.learnMoreLink);
description.appendChild(link);
}
async _ensureWindowReady(win) {

View file

@ -162,14 +162,23 @@ add_task(async function testExtensionControlledPopup() {
let description = doc.getElementById("extension-controlled-description");
is(
description.textContent,
"An extension, Ext Controlled, changed the page you see when you open a new tab.Learn more",
"An extension, Ext Controlled, changed the page you see when you open a new tab.",
"The extension name is in the description"
);
let link = description.querySelector("a.learnMore");
const learnMoreEl = panel.querySelector(
"#extension-controlled-notification .popup-notification-learnmore-link"
);
ok(
BrowserTestUtils.isVisible(learnMoreEl),
"Expect the popupnotification learnmore link to be visible"
);
is(
link.href,
"http://127.0.0.1:8888/support-dummy/extension-controlled",
"The link has the href set from learnMoreLink"
learnMoreEl.getAttribute("href"),
Services.urlFormatter.formatURLPref("app.support.baseURL") +
"extension-controlled",
"learnmore link should have the expected url set"
);
// Force close the popup, as if a user clicked away from it.

View file

@ -66,11 +66,12 @@ add_task(async function test_multiple_extensions_overriding_home_page() {
function background() {
browser.test.onMessage.addListener(async msg => {
switch (msg) {
case "checkHomepage":
case "checkHomepage": {
let homepage = await browser.browserSettings.homepageOverride.get({});
browser.test.sendMessage("homepage", homepage);
break;
case "trySet":
}
case "trySet": {
let setResult = await browser.browserSettings.homepageOverride.set({
value: "foo",
});
@ -80,7 +81,8 @@ add_task(async function test_multiple_extensions_overriding_home_page() {
);
browser.test.sendMessage("homepageSet");
break;
case "tryClear":
}
case "tryClear": {
let clearResult =
await browser.browserSettings.homepageOverride.clear({});
browser.test.assertFalse(
@ -89,6 +91,7 @@ add_task(async function test_multiple_extensions_overriding_home_page() {
);
browser.test.sendMessage("homepageCleared");
break;
}
}
});
}
@ -489,13 +492,28 @@ add_task(async function test_doorhanger_new_window() {
is(
description.textContent,
"An extension, Ext2, changed what you see when you open your homepage and new windows.Learn more",
"An extension, Ext2, changed what you see when you open your homepage and new windows.",
"The extension name is in the popup"
);
let popupnotification = doc.getElementById("extension-homepage-notification");
let learnMoreEl = popupnotification.querySelector(
".popup-notification-learnmore-link"
);
ok(
BrowserTestUtils.isVisible(learnMoreEl),
"Expect the popupnotification learnmore link to be visible"
);
is(
learnMoreEl.getAttribute("href"),
Services.urlFormatter.formatURLPref("app.support.baseURL") +
"extension-home",
"learnmore link should have the expected url set"
);
// Click Manage.
let popupHidden = promisePopupHidden(panel);
let popupnotification = doc.getElementById("extension-homepage-notification");
popupnotification.secondaryButton.click();
await popupHidden;
@ -518,7 +536,7 @@ add_task(async function test_doorhanger_new_window() {
is(
description.textContent,
"An extension, Ext1, changed what you see when you open your homepage and new windows.Learn more",
"An extension, Ext1, changed what you see when you open your homepage and new windows.",
"The extension name is in the popup"
);
@ -591,7 +609,7 @@ add_task(async function test_overriding_home_page_incognito_not_allowed() {
let popupnotification = description.closest("popupnotification");
is(
description.textContent,
"An extension, extension, changed what you see when you open your homepage and new windows.Learn more",
"An extension, extension, changed what you see when you open your homepage and new windows.",
"The extension name is in the popup"
);
is(

View file

@ -73,10 +73,34 @@ add_task(function test_doorhanger_keep() {
"The doorhanger is anchored to the all tabs button"
);
// Click the Keep Tabs Hidden button.
let popupnotification = document.getElementById(
let description = panel.querySelector(
"#extension-tab-hide-notification-description"
);
is(
description.textContent,
"An extension, Generated extension, is hiding some of your tabs. You can still access all of your tabs from .",
"The extension name is in the description"
);
const popupnotification = document.getElementById(
"extension-tab-hide-notification"
);
const learnMoreEl = popupnotification.querySelector(
".popup-notification-learnmore-link"
);
ok(
learnMoreEl,
"Expect the popupnotification learnmore link to be visible"
);
is(
learnMoreEl.getAttribute("href"),
Services.urlFormatter.formatURLPref("app.support.baseURL") +
"extension-hiding-tabs",
"learnmore link should have the expected url set"
);
// Click the Keep Tabs Hidden button.
let popupHidden = promisePopupHidden(panel);
popupnotification.button.click();
await popupHidden;
@ -227,17 +251,6 @@ add_task(async function test_tabs_showhide() {
SessionStore.setBrowserState(JSON.stringify(sessData));
await restored;
if (!Services.prefs.getBoolPref("browser.tabs.tabmanager.enabled")) {
for (let win of BrowserWindowIterator()) {
let allTabsButton = win.document.getElementById("alltabs-button");
is(
getComputedStyle(allTabsButton).display,
"none",
"The all tabs button is hidden"
);
}
}
// Attempt to hide all the tabs, however the active tab in each window cannot
// be hidden, so the result will be 3 hidden tabs.
extension.sendMessage("hideall");

View file

@ -258,10 +258,25 @@ add_task(async function test_new_tab_keep_settings() {
is(
panel.querySelector("#extension-new-tab-notification-description")
.textContent,
"An extension, New Tab Add-on, changed the page you see when you open a new tab.Learn more",
"An extension, New Tab Add-on, changed the page you see when you open a new tab.",
"The description includes the add-on name"
);
const learnMoreEl = panel.querySelector(
"#extension-new-tab-notification .popup-notification-learnmore-link"
);
ok(
BrowserTestUtils.isVisible(learnMoreEl),
"Expect the popupnotification learnmore link to be visible"
);
is(
learnMoreEl.getAttribute("href"),
Services.urlFormatter.formatURLPref("app.support.baseURL") +
"extension-home",
"learnmore link should have the expected url set"
);
// Click the Keep Changes button.
let confirmationSaved = TestUtils.waitForCondition(() => {
return ExtensionSettingsStore.getSetting(

View file

@ -210,6 +210,20 @@ export const PREFS_CONFIG = new Map([
value: true,
},
],
[
"unifiedAds.enabled",
{
title: "Use Mozilla Ad Routing Service (MARS) unified ads API",
value: false,
},
],
[
"unifiedAds.endpoint",
{
title: "Mozilla Ad Routing Service (MARS) unified ads API endpoint URL",
value: "https://ads.mozilla.org/",
},
],
[
"system.showWeather",
{

View file

@ -115,21 +115,13 @@ var TabStateCacheInternal = {
}
let history = data.history;
let toIdx = history.entries.length;
if ("toIdx" in change) {
toIdx = Math.min(toIdx, change.toIdx + 1);
}
for (let key of Object.keys(change)) {
if (key == "entries") {
if (change.fromIdx != kLastIndex) {
let start = change.fromIdx + 1;
history.entries.splice.apply(
history.entries,
[start, toIdx - start].concat(change.entries)
);
history.entries.splice(start, Infinity, ...change.entries);
}
} else if (key != "fromIdx" && key != "toIdx") {
} else if (key != "fromIdx") {
history[key] = change[key];
}
}

View file

@ -38,6 +38,7 @@ export class SidebarHistory extends SidebarPage {
this._menuSortBySite = doc.getElementById("sidebar-history-sort-by-site");
this._menu.addEventListener("command", this);
this.addContextMenuListeners();
this.addSidebarFocusedListeners();
this.controller.updateCache();
}
@ -45,6 +46,7 @@ export class SidebarHistory extends SidebarPage {
super.disconnectedCallback();
this._menu.removeEventListener("command", this);
this.removeContextMenuListeners();
this.removeSidebarFocusedListeners();
}
handleContextMenuEvent(e) {
@ -74,6 +76,10 @@ export class SidebarHistory extends SidebarPage {
}
}
handleSidebarFocusedEvent() {
this.searchTextbox?.focus();
}
onPrimaryAction(e) {
navigateToLink(e);
}
@ -260,7 +266,6 @@ export class SidebarHistory extends SidebarPage {
data-l10n-attrs="placeholder"
@fxview-search-textbox-query=${this.onSearchQuery}
.size=${15}
autofocus
></fxview-search-textbox>
<moz-button
class="menu-button"

View file

@ -93,7 +93,10 @@ export default class SidebarMain extends MozLitElement {
event.explicitOriginalTarget.flattenedTreeParentNode;
if (
this.contextMenuTarget.getAttribute("extensionId") ||
this.contextMenuTarget.className.includes("tab")
this.contextMenuTarget.className.includes("tab") ||
document
.getElementById("vertical-tabs")
.contains(this.contextMenuTarget.flattenedTreeParentNode)
) {
this.updateExtensionContextMenuItems();
return;

View file

@ -56,6 +56,14 @@ export class SidebarPage extends MozLitElement {
this._contextMenu.removeEventListener("command", this);
}
addSidebarFocusedListeners() {
this.topWindow.addEventListener("SidebarFocused", this);
}
removeSidebarFocusedListeners() {
this.topWindow.removeEventListener("SidebarFocused", this);
}
handleEvent(e) {
switch (e.type) {
case "contextmenu":
@ -64,6 +72,9 @@ export class SidebarPage extends MozLitElement {
case "command":
this.handleCommandEvent?.(e);
break;
case "SidebarFocused":
this.handleSidebarFocusedEvent?.(e);
break;
}
}

View file

@ -24,6 +24,7 @@ class SyncedTabsInSidebar extends SidebarPage {
static queries = {
cards: { all: "moz-card" },
searchTextbox: "fxview-search-textbox",
};
constructor() {
@ -36,12 +37,14 @@ class SyncedTabsInSidebar extends SidebarPage {
this.controller.addSyncObservers();
this.controller.updateStates();
this.addContextMenuListeners();
this.addSidebarFocusedListeners();
}
disconnectedCallback() {
super.disconnectedCallback();
this.controller.removeSyncObservers();
this.removeContextMenuListeners();
this.removeSidebarFocusedListeners();
}
handleContextMenuEvent(e) {
@ -65,6 +68,10 @@ class SyncedTabsInSidebar extends SidebarPage {
}
}
handleSidebarFocusedEvent() {
this.searchTextbox?.focus();
}
/**
* The template shown when the list of synced devices is currently
* unavailable.
@ -208,7 +215,6 @@ class SyncedTabsInSidebar extends SidebarPage {
>
</sidebar-panel-header>
<fxview-search-textbox
autofocus
data-l10n-id="firefoxview-search-text-box-syncedtabs"
data-l10n-attrs="placeholder"
@fxview-search-textbox-query=${this.onSearchQuery}

View file

@ -31,11 +31,18 @@ add_task(async function test_adopt_from_window() {
});
// Check category of new window sidebar is that of opener window sidebar
let newSidebarBox = document.getElementById("sidebar-box");
await BrowserTestUtils.waitForCondition(
() => BrowserTestUtils.isVisible(newSidebarBox),
"New sidebar box is visible"
let newSidebarBox;
await BrowserTestUtils.waitForCondition(() => {
newSidebarBox = newWin.document.getElementById("sidebar-box");
return newSidebarBox && BrowserTestUtils.isVisible(newSidebarBox);
}, "New sidebar box is visible");
Assert.notEqual(
newSidebarBox,
sidebarBox,
"sidebar box from the new window should be a different object"
);
await BrowserTestUtils.waitForCondition(
() => !!newSidebarBox.getAttribute("sidebarcommand"),
"Category has been set"
@ -60,3 +67,61 @@ add_task(async function test_adopt_from_window() {
await BrowserTestUtils.closeWindow(newWin);
await BrowserTestUtils.closeWindow(win);
});
add_task(async function test_focus_history_from_adopted() {
const win = await BrowserTestUtils.openNewBrowserWindow();
const { document } = win;
const sidebar = document.querySelector("sidebar-main");
ok(sidebar, "Sidebar is shown.");
await sidebar.updateComplete;
await toggleSidebarPanel(win, "viewHistorySidebar");
const { SidebarController } = win;
const { contentDocument } = SidebarController.browser;
const historySidebar = contentDocument.querySelector("sidebar-history");
await BrowserTestUtils.waitForCondition(
() => !historySidebar.controller.isHistoryPending
);
await historySidebar.updateComplete;
Assert.equal(
historySidebar.shadowRoot.activeElement,
historySidebar.searchTextbox,
"Search box should be focused"
);
// Open a new window from the window containing the open sidebar
const newWin = lazy.BrowserWindowTracker.openWindow({
openerWindow: win,
});
let NewSidebarController;
await BrowserTestUtils.waitForCondition(
() => (NewSidebarController = newWin.SidebarController),
"newWin SidebarController is present"
);
let newWinHistorySidebar;
let newContentDocument;
await BrowserTestUtils.waitForCondition(() => {
newContentDocument = NewSidebarController.browser.contentDocument;
newWinHistorySidebar = newContentDocument?.querySelector("sidebar-history");
return (
newWinHistorySidebar?.controller &&
!newWinHistorySidebar.controller.isHistoryPending
);
}, "Make sure sidebar-history is present and history isn't pending");
await newWinHistorySidebar.updateComplete;
ok(newWinHistorySidebar.searchTextbox, "Search box should be present");
Assert.notEqual(
newWinHistorySidebar.shadowRoot.activeElement,
newWinHistorySidebar.searchTextbox,
"Search box should not be focused"
);
await BrowserTestUtils.closeWindow(newWin);
await BrowserTestUtils.closeWindow(win);
});

View file

@ -88,6 +88,18 @@ add_task(async function test_history_cards_created() {
}
});
add_task(async function test_history_searchbox_focus() {
const { component } = await showHistorySidebar();
const { searchTextbox } = component;
ok(component.shadowRoot.activeElement, "check activeElement is present");
Assert.equal(
component.shadowRoot.activeElement,
searchTextbox,
"Check search box is focused"
);
});
add_task(async function test_history_search() {
const { component, contentWindow } = await showHistorySidebar();
const { searchTextbox } = component;

View file

@ -119,3 +119,17 @@ add_task(async function test_tabs() {
SidebarController.hide();
sandbox.restore();
});
add_task(async function test_syncedtabs_searchbox_focus() {
await SidebarController.show("viewTabsSidebar");
const { contentDocument } = SidebarController.browser;
const component = contentDocument.querySelector("sidebar-syncedtabs");
const { searchTextbox } = component;
ok(component.shadowRoot.activeElement, "check activeElement is present");
Assert.equal(
component.shadowRoot.activeElement,
searchTextbox,
"Check search box is focused"
);
});

View file

@ -103,6 +103,40 @@ add_task(async function test_toggle_vertical_tabs() {
is(win.gBrowser.tabs.length, 4, "Tabstrip now has four tabs");
const toolbarContextMenu = document.getElementById("toolbar-context-menu");
EventUtils.synthesizeMouseAtPoint(
containerRect.left + containerRect.width / 2,
tabRect.bottom + 100,
{
type: "contextmenu",
button: 2,
},
win
);
await openAndWaitForContextMenu(
toolbarContextMenu,
win.gBrowser.selectedTab,
() => {
ok(
document.getElementById("toolbar-context-customize").hidden,
"Customize menu item should be hidden"
);
ok(
!document.getElementById("toggle_PersonalToolbar"),
"Bookmarks menu item should not be present"
);
ok(
!document.getElementById("toolbar-context-reloadSelectedTab").hidden,
"Reload tab item should be visible"
);
ok(
!document.getElementById("toolbar-context-undoCloseTab").hidden,
"Undo close tab item should be visible"
);
}
);
// flip the pref to move the tabstrip horizontally
await SpecialPowers.pushPrefEnv({ set: [["sidebar.verticalTabs", false]] });

View file

@ -59,14 +59,10 @@ var gTabsPanel = {
insertBefore: document.getElementById("allTabsMenu-tabsSeparator"),
filterFn: tab => tab.hidden && tab.soundPlaying,
});
let showPinnedTabs = Services.prefs.getBoolPref(
"browser.tabs.tabmanager.enabled"
);
this.allTabsPanel = new TabsPanel({
view: this.allTabsView,
containerNode: this.allTabsViewTabs,
filterFn: tab =>
!tab.hidden && (!tab.pinned || (showPinnedTabs && tab.pinned)),
filterFn: tab => !tab.hidden,
dropIndicator: this.dropIndicator,
});

View file

@ -327,8 +327,6 @@ skip-if = ["true"] # Bug 1616418 Bug 1549985
["browser_tab_manager_keyboard_access.js"]
skip-if = ["true"] # Bug 1900477
["browser_tab_manager_visibility.js"]
["browser_tab_move_to_new_window_reload.js"]
["browser_tab_play.js"]

View file

@ -4,12 +4,6 @@
"use strict";
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["browser.tabs.tabmanager.enabled", true]],
});
});
async function openAllTabsPanel(win) {
const button = win.document.getElementById("alltabs-button");
const allTabsView = win.document.getElementById("allTabsMenu-allTabsView");

View file

@ -9,12 +9,6 @@ const URL3 = "data:text/plain,tab3";
const URL4 = "data:text/plain,tab4";
const URL5 = "data:text/plain,tab5";
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["browser.tabs.tabmanager.enabled", true]],
});
});
/**
* Tests that middle-clicking on a tab in the Tab Manager will close it.
*/

View file

@ -46,8 +46,6 @@ function getOrderOfTabs(tabs) {
}
async function testWithNewWindow(func) {
Services.prefs.setBoolPref("browser.tabs.tabmanager.enabled", true);
const newWindow = await BrowserTestUtils.openNewBrowserWindow();
await Promise.all([
@ -75,8 +73,6 @@ async function testWithNewWindow(func) {
await func(newWindow);
await BrowserTestUtils.closeWindow(newWindow);
Services.prefs.clearUserPref("browser.tabs.tabmanager.enabled");
}
add_task(async function test_reorder() {

View file

@ -25,9 +25,6 @@ async function waitForAllTabsMenu(window = window) {
* by other tests.
*/
add_task(async function test_open_tabmanager_keyboard() {
await SpecialPowers.pushPrefEnv({
set: [["browser.tabs.tabmanager.enabled", true]],
});
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
let elem = newWindow.document.getElementById("alltabs-button");

View file

@ -1,54 +0,0 @@
/**
* Test the Tab Manager visibility respects browser.tabs.tabmanager.enabled preference
* */
"use strict";
// The hostname for the test URIs.
const TEST_HOSTNAME = "https://example.com";
const DUMMY_PAGE_PATH =
"/browser/components/tabbrowser/test/browser/tabs/dummy_page.html";
add_task(async function tab_manager_visibility_preference_on() {
Services.prefs.setBoolPref("browser.tabs.tabmanager.enabled", true);
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
await BrowserTestUtils.withNewTab(
{
gBrowser: newWindow.gBrowser,
url: TEST_HOSTNAME + DUMMY_PAGE_PATH,
},
async function () {
await Assert.ok(
BrowserTestUtils.isVisible(
newWindow.document.getElementById("alltabs-button")
),
"tab manage menu is visible when browser.tabs.tabmanager.enabled preference is set to true"
);
}
);
Services.prefs.clearUserPref("browser.tabs.tabmanager.enabled");
BrowserTestUtils.closeWindow(newWindow);
});
add_task(async function tab_manager_visibility_preference_off() {
Services.prefs.setBoolPref("browser.tabs.tabmanager.enabled", false);
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
await BrowserTestUtils.withNewTab(
{
gBrowser: newWindow.gBrowser,
url: TEST_HOSTNAME + DUMMY_PAGE_PATH,
},
async function () {
await Assert.ok(
BrowserTestUtils.isHidden(
newWindow.document.getElementById("alltabs-button")
),
"tab manage menu is hidden when browser.tabs.tabmanager.enabled preference is set to true"
);
}
);
Services.prefs.clearUserPref("browser.tabs.tabmanager.enabled");
BrowserTestUtils.closeWindow(newWindow);
});

View file

@ -17,6 +17,7 @@ add_heuristic_tests(
{ fieldName: "cc-number" },
{ fieldName: "cc-exp-month" },
{ fieldName: "cc-exp-year" },
{ fieldName: "cc-csc" },
],
},
{
@ -47,6 +48,7 @@ add_heuristic_tests(
{ fieldName: "cc-number", reason: "autocomplete" },
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
{ fieldName: "cc-exp-year", reason: "update-heuristic" },
{ fieldName: "cc-csc", reason: "regex-heuristic" },
],
},
],

View file

@ -14,6 +14,7 @@ add_heuristic_tests(
fields: [
{ fieldName: "cc-number", reason: "fathom" },
{ fieldName: "cc-exp", reason: "update-heuristic" },
{ fieldName: "cc-csc", reason: "regex-heuristic" },
{ fieldName: "cc-name", reason: "regex-heuristic" },
],
},

View file

@ -70,7 +70,7 @@ add_heuristic_tests([
{
fields: [
{ fieldName: "cc-number", reason: "autocomplete" },
//{ fieldName: "cc-csc", reason: "autocomplete" },
{ fieldName: "cc-csc", reason: "autocomplete" },
],
},
{

View file

@ -77,7 +77,7 @@ add_heuristic_tests(
{ fieldName: "cc-number", reason: "fathom" }, // ac-off
{ fieldName: "cc-exp-month" },
{ fieldName: "cc-exp-year" },
// { fieldName: "cc-csc"}, // ac-off
{ fieldName: "cc-csc"}, // ac-off
{ fieldName: "cc-name", reason: "fathom" }, // ac-off
],
},

View file

@ -14,6 +14,7 @@ add_heuristic_tests(
fields: [
{ fieldName: "cc-number" },
{ fieldName: "cc-name" },
{ fieldName: "cc-csc", reason: "regex-heuristic" },
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
{ fieldName: "cc-exp-year", reason: "regex-heuristic" },
],

View file

@ -14,6 +14,7 @@ add_heuristic_tests(
fields: [
{ fieldName: "cc-number" },
{ fieldName: "cc-exp" },
{ fieldName: "cc-csc" },
{ fieldName: "cc-given-name" },
{ fieldName: "cc-family-name" },
],

View file

@ -13,10 +13,10 @@ add_heuristic_tests(
},
fields: [
{ fieldName: "cc-number" },
//{ fieldName: "cc-cvc" },
{ fieldName: "cc-csc", reason: "regex-heuristic" },
{ fieldName: "cc-exp-month" },
{ fieldName: "cc-exp-year" },
{ fieldName: "cc-type", reason: "regex-heuristic" },
{ fieldName: "cc-type", reason: "regex-heuristic" },
],
},
{

View file

@ -15,6 +15,7 @@ add_heuristic_tests(
{ fieldName: "cc-number", reason: "fathom" },
{ fieldName: "cc-exp-month" },
{ fieldName: "cc-exp-year" },
{ fieldName: "cc-csc" },
],
},
],

View file

@ -45,6 +45,7 @@ add_heuristic_tests(
fields: [
{ fieldName: "cc-exp-month", reason: "regex-heuristic" }, // invisible
{ fieldName: "cc-exp-year", reason: "regex-heuristic" }, // invisible
{ fieldName: "cc-csc", reason: "regex-heuristic" },
],
},
],

View file

@ -19,6 +19,7 @@ add_heuristic_tests(
{ fieldName: "cc-number", part: 4 },
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
{ fieldName: "cc-exp-year", reason: "regex-heuristic" },
{ fieldName: "cc-csc", reason: "regex-heuristic" },
],
},
],

View file

@ -27,12 +27,12 @@ add_heuristic_tests(
// field is currently recognized as a 'csc' field. We need to implement a heuristic
// to accurately determine the field type when a field aligns with multiple field types
// instead of depending on the order of we perform the matching
//{
//invalid: true,
//fields: [
//{ fieldName: "email", reason: "regex-heuristic"},
//],
//},
{
invalid: true,
fields: [
{ fieldName: "cc-csc", reason: "regex-heuristic"},
],
},
],
},
],

View file

@ -36,6 +36,7 @@ add_heuristic_tests(
fields: [
{ fieldName: "cc-name" },
{ fieldName: "cc-number" }, // ac-off
{ fieldName: "cc-csc", reason: "regex-heuristic"},
],
},
{
@ -47,7 +48,7 @@ add_heuristic_tests(
{ fieldName: "cc-number" }, // ac-off
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
{ fieldName: "cc-exp-year", reason: "regex-heuristic" },
// { fieldName: "cc-csc"},
{ fieldName: "cc-csc", reason: "regex-heuristic"},
],
},
{

View file

@ -42,6 +42,7 @@ add_heuristic_tests(
{ fieldName: "cc-exp-month" },
{ fieldName: "cc-exp-year" },
{ fieldName: "cc-number" },
{ fieldName: "cc-csc" },
],
},
{

View file

@ -19,7 +19,7 @@ add_heuristic_tests(
},
{
fields: [
// { fieldName: "cc-csc"},
{ fieldName: "cc-csc", reason: "regex-heuristic"},
{ fieldName: "cc-type", reason: "regex-heuristic" },
{ fieldName: "cc-number", reason: "fathom" },
{ fieldName: "cc-exp", reason: "update-heuristic" },
@ -28,6 +28,7 @@ add_heuristic_tests(
{
invalid: true,
fields: [
{ fieldName: "cc-csc", reason: "regex-heuristic" },
{ fieldName: "cc-number", reason: "regex-heuristic" }, // txtQvcGiftCardNumber
],
},
@ -58,15 +59,16 @@ add_heuristic_tests(
reason: "fathom",
},
fields: [
{ fieldName: "cc-csc", reason: "regex-heuristic"},
{ fieldName: "cc-type", reason: "regex-heuristic" }, // ac-off
{ fieldName: "cc-number" }, // ac-off
{ fieldName: "cc-exp", reason: "update-heuristic" },
// { fieldName: "cc-csc"},
],
},
{
invalid: true,
fields: [
{ fieldName: "cc-csc", reason: "regex-heuristic" },
{ fieldName: "cc-number", reason: "regex-heuristic" }, // txtQvcGiftCardNumbe, ac-off
],
},

View file

@ -212,6 +212,8 @@ this.addonsSearchDetection = class extends ExtensionAPI {
fire.sync({ addonId, firstUrl, lastUrl });
};
const remoteTab = context.xulBrowser.frameLoader.remoteTab;
const listener = ({ requestId, url, originUrl }) => {
// We exclude requests not originating from the location bar,
// bookmarks and other "system-ish" requests.
@ -227,20 +229,47 @@ this.addonsSearchDetection = class extends ExtensionAPI {
const wrapper = ChannelWrapper.getRegisteredChannel(
requestId,
context.extension.policy,
context.xulBrowser.frameLoader.remoteTab
remoteTab
);
wrapper.addEventListener("stop", stopListener);
}
};
const ensureRegisterChannel = data => {
// onRedirected depends on ChannelWrapper.getRegisteredChannel,
// which in turn depends on registerTraceableChannel to have been
// called. When a blocking webRequest listener is present, the
// parent/ext-webRequest.js implementation already calls that.
//
// A downside to a blocking webRequest listener is that it delays
// the network request until a roundtrip to the listener in the
// extension process has happened. Since we don't need to handle
// the onBeforeRequest event, avoid the overhead by handling the
// event and registration here, in the parent process.
data.registerTraceableChannel(extension.policy, remoteTab);
};
const parsedFilter = {
types: ["main_frame"],
urls: ExtensionUtils.parseMatchPatterns(filter.urls),
};
WebRequest.onBeforeRequest.addListener(
ensureRegisterChannel,
parsedFilter,
// blocking is needed to unlock data.registerTraceableChannel.
["blocking"],
{
addonId: extension.id,
policy: extension.policy,
blockingAllowed: true,
}
);
WebRequest.onBeforeRedirect.addListener(
listener,
// filter
{
types: ["main_frame"],
urls: ExtensionUtils.parseMatchPatterns(filter.urls),
},
parsedFilter,
// info
[],
// listener details
@ -252,6 +281,7 @@ this.addonsSearchDetection = class extends ExtensionAPI {
);
return () => {
WebRequest.onBeforeRequest.removeListener(ensureRegisterChannel);
WebRequest.onBeforeRedirect.removeListener(listener);
};
},

View file

@ -47,12 +47,6 @@ class AddonsSearchDetection {
this.onRedirectedListener
);
}
// If there is already a listener, remove it so that we can re-add one
// after. This is because we're using the same listener with different URL
// patterns (when the list of search engines changes).
if (browser.webRequest.onBeforeRequest.hasListener(this.noOpListener)) {
browser.webRequest.onBeforeRequest.removeListener(this.noOpListener);
}
// Retrieve the list of URL patterns to monitor with our listener.
//
@ -65,23 +59,12 @@ class AddonsSearchDetection {
return;
}
browser.webRequest.onBeforeRequest.addListener(
this.noOpListener,
{ types: ["main_frame"], urls: patterns },
["blocking"]
);
browser.addonsSearchDetection.onRedirected.addListener(
this.onRedirectedListener,
{ urls: patterns }
);
}
// This listener is required to force the registration of traceable channels.
noOpListener() {
// Do nothing.
}
async onRedirectedListener({ addonId, firstUrl, lastUrl }) {
// When we do not have an add-on ID (in the request property bag), we
// likely detected a search server-side redirect.

View file

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

View file

@ -43,8 +43,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
const DEFAULT_EXTENSION_ICON =
"chrome://mozapps/skin/extensions/extensionGeneric.svg";
const HTML_NS = "http://www.w3.org/1999/xhtml";
function getTabBrowser(browser) {
while (browser.ownerGlobal.docShell.itemType !== Ci.nsIDocShell.typeChrome) {
browser = browser.ownerGlobal.docShell.chromeEventHandler;
@ -397,8 +395,6 @@ export var ExtensionsUI = {
);
}
let checkbox;
const incognitoPermissionName = "internal:privateBrowsingAllowed";
let grantPrivateBrowsingAllowed = false;
if (showIncognitoCheckbox) {
@ -416,79 +412,7 @@ export var ExtensionsUI = {
let promise = new Promise(resolve => {
function eventCallback(topic) {
let doc = this.browser.ownerDocument;
if (topic == "showing") {
let textEl = doc.getElementById("addon-webext-perm-text");
textEl.textContent = strings.text;
textEl.hidden = !strings.text;
// By default, multiline strings don't get formatted properly. These
// are presently only used in site permission add-ons, so we treat it
// as a special case to avoid unintended effects on other things.
let isMultiline = strings.text.includes("\n\n");
textEl.classList.toggle(
"addon-webext-perm-text-multiline",
isMultiline
);
let listIntroEl = doc.getElementById("addon-webext-perm-intro");
listIntroEl.textContent = strings.listIntro;
listIntroEl.hidden = !strings.msgs.length || !strings.listIntro;
// Show the link to the sumo page if there are permissions listed
// or the private browsing checkbox is visible.
let listInfoEl = doc.getElementById("addon-webext-perm-info");
listInfoEl.hidden = !strings.msgs.length && !showIncognitoCheckbox;
let list = doc.getElementById("addon-webext-perm-list");
while (list.firstChild) {
list.firstChild.remove();
}
let singleEntryEl = doc.getElementById(
"addon-webext-perm-single-entry"
);
singleEntryEl.textContent = "";
singleEntryEl.hidden = true;
list.hidden = true;
const createPrivateBrowsingCheckbox = () => {
let checkboxEl = doc.createXULElement("checkbox");
checkboxEl.checked = grantPrivateBrowsingAllowed;
doc.l10n.setAttributes(
checkboxEl,
"popup-notification-addon-privatebrowsing-checkbox"
);
return checkboxEl;
};
if (strings.msgs.length === 0 && showIncognitoCheckbox) {
checkbox = createPrivateBrowsingCheckbox();
singleEntryEl.appendChild(checkbox);
singleEntryEl.hidden = false;
singleEntryEl.classList.add("webext-perm-optional");
singleEntryEl.classList.add("webext-perm-privatebrowsing");
} else if (strings.msgs.length === 1 && !showIncognitoCheckbox) {
singleEntryEl.textContent = strings.msgs[0];
singleEntryEl.hidden = false;
} else if (strings.msgs.length) {
for (let msg of strings.msgs) {
let item = doc.createElementNS(HTML_NS, "li");
item.classList.add("webext-perm-granted");
item.textContent = msg;
list.appendChild(item);
}
if (showIncognitoCheckbox) {
let item = doc.createElementNS(HTML_NS, "li");
item.classList.add("webext-perm-optional");
item.classList.add("webext-perm-privatebrowsing");
checkbox = createPrivateBrowsingCheckbox();
item.appendChild(checkbox);
list.appendChild(item);
}
list.hidden = false;
}
} else if (topic == "swapping") {
if (topic == "swapping") {
return true;
}
if (topic == "removed") {
@ -499,16 +423,38 @@ export var ExtensionsUI = {
return false;
}
// Show the SUMO link already part of the popupnotification by
// setting learnMoreURL option if there are permissions to be
// granted to the addon being installed (or if the private
// browsing checkbox is shown).
const learnMoreURL =
strings.msgs.length || showIncognitoCheckbox
? Services.urlFormatter.formatURLPref("app.support.baseURL") +
"extension-permissions"
: undefined;
let options = {
hideClose: true,
popupIconURL: icon || DEFAULT_EXTENSION_ICON,
popupIconClass: icon ? "" : "addon-warning-icon",
learnMoreURL,
persistent: true,
eventCallback,
removeOnDismissal: true,
popupOptions: {
position: "bottomright topright",
},
// Pass additional options used internally by the
// addon-webext-permissions-notification custom element
// (defined and registered by browser-addons.js).
customElementOptions: {
strings,
showIncognitoCheckbox,
grantPrivateBrowsingAllowed,
onPrivateBrowsingAllowedChanged(value) {
grantPrivateBrowsingAllowed = value;
},
},
};
// The prompt/notification machinery has a special affordance wherein
// certain subsets of the header string can be designated "names", and
@ -529,9 +475,6 @@ export var ExtensionsUI = {
label: strings.acceptText,
accessKey: strings.acceptKey,
callback: () => {
grantPrivateBrowsingAllowed = showIncognitoCheckbox
? checkbox.checked
: undefined;
resolve(true);
},
};

View file

@ -125,12 +125,15 @@
/* Content area */
.sidebar-splitter {
appearance: none;
width: 6px;
background-color: -moz-dialog;
border: 1px ThreeDShadow;
border-style: none solid;
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.revamp") {
.sidebar-splitter {
appearance: none;
width: 6px;
background-color: -moz-dialog;
border: 1px ThreeDShadow;
border-style: none solid;
}
}
/* Tabstrip */

View file

@ -16,7 +16,7 @@
html|*.addon-webext-perm-list {
margin-block-end: 0;
padding-inline-start: 10px;
padding-inline-start: 0;
> html|li {
list-style: none;

View file

@ -195,6 +195,23 @@ body {
margin: 0;
}
/* Chrome/content separation */
#navigator-toolbox {
/* This reserves space for the tabbox shadow */
border-bottom: var(--hairline-border-width) solid var(--toolbar-bgcolor);
}
#tabbrowser-tabbox {
position: relative;
box-shadow: 0 0 0 var(--hairline-border-width) var(--chrome-content-separator-color);
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
box-shadow: 0 0 0 var(--hairline-border-width) var(--chrome-content-separator-color), 0 2px 6px 0 light-dark(rgb(0, 0, 0, 0.2), rgb(0, 0, 0, 0.8));
}
}
/* Toolbox and Toolbars */
#navigator-toolbox {
@ -318,23 +335,6 @@ body {
}
}
/* Chrome/content separation */
#navigator-toolbox {
/* This reserves space for the tabbox shadow */
border-bottom: var(--hairline-border-width) solid var(--toolbar-bgcolor);
}
#tabbrowser-tabbox {
position: relative;
box-shadow: 0 0 0 var(--hairline-border-width) var(--chrome-content-separator-color);
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
box-shadow: 0 0 0 var(--hairline-border-width) var(--chrome-content-separator-color), 0 2px 6px 0 light-dark(rgb(0, 0, 0, 0.2), rgb(0, 0, 0, 0.8));
}
}
/* Hide the TabsToolbar titlebar controls if the menubar is permanently shown.
* (That is, if the menu bar doesn't autohide, and we're not in a fullscreen or
* popup window.) */

View file

@ -78,7 +78,10 @@
}
.sidebar-splitter {
@media not (-moz-platform: linux) {
--splitter-width: 4px;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") or (not (-moz-platform: linux)) {
/* We don't let the splitter overlap the sidebar on Linux since the sidebar's
scrollbar is too narrow on Linux. */
appearance: none;
@ -86,22 +89,23 @@
border-inline-end-width: 1px;
border-color: var(--sidebar-border-color);
min-width: 1px;
width: 4px;
width: var(--splitter-width);
background-image: none !important;
background-color: transparent;
margin-inline-start: -4px;
margin-inline-start: calc(-1 * var(--splitter-width));
position: relative;
#sidebar-box[positionend] + & {
border-inline-width: 1px 0;
margin-inline: 0 -4px;
margin-inline: 0 calc(-1 * var(--splitter-width));
}
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
--splitter-width: 6px;
transition: background-color 0.5s ease-in-out;
border-color: transparent;
border-style: none;
&:hover {
background-color: var(--focus-outline-color);

View file

@ -832,8 +832,6 @@ sidebar-main[expanded] > #vertical-tabs > #tabbrowser-tabs[orient="vertical"] .t
&[visible] {
display: flex;
/* make the scrollbars hug the side of the container */
margin-inline-end: -2px;
}
}
@ -1000,19 +998,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
#alltabs-button {
list-style-image: url(chrome://global/skin/icons/arrow-down.svg);
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "browser.tabs.tabmanager.enabled") {
#tabbrowser-tabs:not([overflow], [hashiddentabs]) ~ & {
display: none;
}
#tabbrowser-tabs:not([overflow])[using-closing-tabs-spacer] ~ & {
/* temporary space to keep a tab's close button under the cursor */
display: flex;
visibility: hidden;
}
}
#tabbrowser-tabs[hiddensoundplaying] ~ & > .toolbarbutton-badge-stack > .toolbarbutton-badge {
background: transparent url(chrome://browser/skin/tabbrowser/tab-audio-playing-small.svg);
box-shadow: none;

View file

@ -317,5 +317,4 @@ def googlevr_sdk(value, target):
set_define("MOZ_ANDROID_GOOGLE_VR", googlevr_sdk.enabled)
set_config("MOZ_ANDROID_GOOGLE_VR", googlevr_sdk.enabled)
set_config("MOZ_ANDROID_GOOGLE_VR_INCLUDE", googlevr_sdk.include)
set_config("MOZ_ANDROID_GOOGLE_VR_LIBS", googlevr_sdk.libs)

View file

@ -44,7 +44,6 @@ option(
set_config("ENABLE_MOZSEARCH_PLUGIN", True, when="--enable-mozsearch-plugin")
set_define("MOZ_MOZSEARCH_PLUGIN", True, when="--enable-mozsearch-plugin")
@depends(

View file

@ -76,42 +76,3 @@ set_define(
check_msg="for memfd_create in sys/mman.h",
),
)
# TODO: Move these checks to file specific to --enable-project=js.
have_perf_event_h = check_header("linux/perf_event.h", when=building_linux)
option(
"--with-linux-headers",
help="location where the Linux kernel headers can be found",
nargs=1,
)
passed_linux_header_flags = depends_if("--with-linux-headers")(
lambda v: ["-I%s" % v[0]]
)
@depends(
try_compile(
includes=["asm/unistd.h"],
body="return sizeof(__NR_perf_event_open);",
flags=passed_linux_header_flags,
check_msg="for perf_event_open system call",
),
when=have_perf_event_h,
)
def have_perf_event_open(have_perf_event_open):
if have_perf_event_open:
return True
set_config("HAVE_LINUX_PERF_EVENT_H", have_perf_event_open)
@depends(passed_linux_header_flags, have_perf_event_open)
def linux_headers_includes(passed_linux_header_flags, have_perf_event_open):
if have_perf_event_open and passed_linux_header_flags:
return passed_linux_header_flags[0]
set_config("LINUX_HEADERS_INCLUDES", linux_headers_includes)

View file

@ -176,7 +176,6 @@ def virtualenv_python3():
set_config("PYTHON3", virtualenv_python3.path)
set_config("PYTHON3_VERSION", virtualenv_python3.str_version)
# Inject mozconfig options
@ -379,28 +378,6 @@ def exposed_vcs_checkout_type(vcs_checkout_type, hg, git, automation):
set_config("VCS_CHECKOUT_TYPE", exposed_vcs_checkout_type)
# Obtain a Repository interface for the current VCS repository.
@depends(build_environment, exposed_vcs_checkout_type, hg, git)
@imports(_from="mozversioncontrol", _import="get_repository_object")
def vcs_repository(build_env, vcs_checkout_type, hg, git):
if vcs_checkout_type == "hg":
return get_repository_object(build_env.topsrcdir, hg=hg)
elif vcs_checkout_type == "git":
return get_repository_object(build_env.topsrcdir, git=git)
elif vcs_checkout_type:
raise FatalCheckError("unhandled VCS type: %s" % vcs_checkout_type)
@depends_if(vcs_repository)
@checking("for sparse checkout")
def vcs_sparse_checkout(repo):
return repo.sparse_checkout_present()
set_config("VCS_SPARSE_CHECKOUT", vcs_sparse_checkout)
# The application/project to build
# ==============================================================
option(
@ -1193,9 +1170,7 @@ set_config("EARLY_BETA_OR_EARLIER", milestone.is_early_beta_or_earlier)
set_define("EARLY_BETA_OR_EARLIER", milestone.is_early_beta_or_earlier)
set_define("MOZILLA_VERSION", depends(milestone)(lambda m: '"%s"' % m.version))
set_config("MOZILLA_VERSION", milestone.version)
set_define("MOZILLA_VERSION_U", milestone.version)
set_define("MOZILLA_UAVERSION", depends(milestone)(lambda m: '"%s"' % m.uaversion))
set_config("MOZILLA_SYMBOLVERSION", milestone.symbolversion)
set_config("MOZ_APP_VERSION", milestone.app_version)
set_config("MOZ_APP_VERSION_DISPLAY", milestone.app_version_display)

View file

@ -131,7 +131,7 @@ with only_when(building_with_gnu_compatible_cc):
is_libatomic_optional = check_std_atomic_requirements()
is_libatomic_required = check_std_atomic_requirements(
flag="-latomic", when=~is_libatomic_optional
flag=["-latomic"], when=~is_libatomic_optional
)
@depends(is_libatomic_optional, is_libatomic_required)

View file

@ -51,7 +51,6 @@ def js_without_nspr(build_nspr, system_nspr, js_standalone):
return not build_nspr and not system_nspr
set_config("JS_WITHOUT_NSPR", True, when=js_without_nspr)
set_define("JS_WITHOUT_NSPR", True, when=js_without_nspr)

View file

@ -406,9 +406,6 @@ def hazard_analysis(value):
return True
set_config("MOZ_HAZARD", hazard_analysis)
# Cross-compilation related things.
# ==============================================================
option(
@ -428,20 +425,6 @@ def toolchain_prefix(value, host, target, cross_compiling):
return ("%s-" % target.toolchain, "%s-" % target.alias)
@depends(toolchain_prefix, target)
def first_toolchain_prefix(toolchain_prefix, target):
# Pass TOOLCHAIN_PREFIX down to the build system if it was given from the
# command line/environment (in which case there's only one value in the tuple),
# or when cross-compiling for Android or OSX.
if toolchain_prefix and (
target.os in ("Android", "OSX") or len(toolchain_prefix) == 1
):
return toolchain_prefix[0]
set_config("TOOLCHAIN_PREFIX", first_toolchain_prefix)
# Compilers
# ==============================================================
include("compilers-util.configure")
@ -1069,14 +1052,6 @@ def compiler_wrapper(wrapper, ccache):
return tuple(wrapper)
@depends_if(compiler_wrapper)
def using_compiler_wrapper(compiler_wrapper):
return True
set_config("MOZ_USING_COMPILER_WRAPPER", using_compiler_wrapper)
@dependable
def wasm():
return split_triplet("wasm32-wasi", allow_wasi=True)
@ -2062,7 +2037,6 @@ def select_linker_tmpl(host_or_target):
select_linker = select_linker_tmpl(target)
set_config("LINKER_KIND", select_linker.KIND)
@template
@ -2758,10 +2732,6 @@ def ub_signed_overflow_san_flags(
linker_flags.ldflags.extend(["-fsanitize=signed-integer-overflow", "-rdynamic"])
set_define("MOZ_SIGNED_OVERFLOW_SANITIZE", True, when=ub_signed_overflow_san)
set_config("MOZ_SIGNED_OVERFLOW_SANITIZE", True, when=ub_signed_overflow_san)
option(
"--enable-unsigned-overflow-sanitizer",
help="Enable UndefinedBehavior Sanitizer (Unsigned Integer Overflow Parts)",
@ -2801,9 +2771,6 @@ def ub_unsigned_overflow_san_flags(
)
set_define("MOZ_UNSIGNED_OVERFLOW_SANITIZE", True, when=ub_unsigned_overflow_san)
set_config("MOZ_UNSIGNED_OVERFLOW_SANITIZE", True, when=ub_unsigned_overflow_san)
#
any_ubsan = ubsan | ub_signed_overflow_san | ub_unsigned_overflow_san

View file

@ -3,7 +3,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import codecs
import errno
import io
import itertools
import logging
@ -154,12 +153,7 @@ def main(argv):
js_config = config.copy()
pwd = os.getcwd()
try:
try:
os.makedirs("js/src")
except OSError as e:
if e.errno != errno.EEXIST:
raise
os.makedirs("js/src", exist_ok=True)
os.chdir("js/src")
js_config["OLD_CONFIGURE_SUBSTS"] = old_js_configure_substs
js_config["OLD_CONFIGURE_DEFINES"] = old_js_configure_defines

View file

@ -140,6 +140,9 @@ support-files = [
"test-network-exceptions.html",
"test-network-request.html",
"test-network.html",
"test-json-mime.html",
"test-json-mime.json",
"test-json-mime.json^headers^",
"test-non-javascript-mime.html",
"test-non-javascript-mime.js",
"test-non-javascript-mime.js^headers^",
@ -564,6 +567,8 @@ fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and
["browser_webconsole_non_javascript_mime_warning.js"]
["browser_webconsole_json_mime_warning.js"]
["browser_webconsole_non_javascript_mime_worker_error.js"]
["browser_webconsole_non_standard_doctype_errors.js"]

View file

@ -0,0 +1,20 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that <script> loads with JSON MIME types produce a warning.
// See Bug 1916351.
"use strict";
const TEST_URI =
"https://example.com/browser/devtools/client/webconsole/" +
"test/browser/" +
"test-json-mime.html";
const MIME_WARNING_MSG =
"The script from “https://example.com/browser/devtools/client/webconsole/test/browser/test-json-mime.json” was loaded even though its MIME type (“application/json”) is not a valid JavaScript MIME type.";
add_task(async function () {
const hud = await openNewTabAndConsole(TEST_URI);
await waitFor(() => findWarningMessage(hud, MIME_WARNING_MSG), "", 100);
ok(true, "JSON MIME type warning displayed");
});

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Web Console test for script with JSON MIME type</title>
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<script src="test-json-mime.json"></script>
</head>
<body>
<p>Web Console test for script with JSON MIME type.</p>
</body>
</html>

View file

@ -0,0 +1 @@
{ "test": 123 }

View file

@ -0,0 +1 @@
Content-Type: application/json

View file

@ -9270,43 +9270,39 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
// XXXbz mTiming should know what channel it's for, so we don't
// need this hackery.
bool toBeReset = false;
bool isJavaScript = SchemeIsJavascript(aLoadState->URI());
const bool isJavaScript = SchemeIsJavascript(aLoadState->URI());
const bool isDownload = !aLoadState->FileName().IsVoid();
const bool toBeReset = !isJavaScript && MaybeInitTiming();
if (!isJavaScript) {
toBeReset = MaybeInitTiming();
}
bool isNotDownload = aLoadState->FileName().IsVoid();
if (mTiming && isNotDownload) {
// FIXME(emilio): Should this be done by javascript: uris? What about external
// protocols?
if (mTiming && !isDownload) {
mTiming->NotifyBeforeUnload();
}
// Check if the page doesn't want to be unloaded. The javascript:
// protocol handler deals with this for javascript: URLs.
if (!isJavaScript && isNotDownload &&
if (!isJavaScript && !isDownload &&
!aLoadState->NotifiedBeforeUnloadListeners() && mDocumentViewer) {
bool okToUnload;
// Check if request is exempted from HTTPSOnlyMode and if https-first is
// enabled, if so it means:
// * https-first failed to upgrade request to https
// * we already asked for permission to unload and the user accepted
// otherwise we wouldn't be here.
bool isPrivateWin = GetOriginAttributes().IsPrivateBrowsing();
bool isHistoryOrReload = false;
uint32_t loadType = aLoadState->LoadType();
const bool isPrivateWin = GetOriginAttributes().IsPrivateBrowsing();
const uint32_t loadType = aLoadState->LoadType();
// Check if request is a reload.
if (loadType == LOAD_RELOAD_NORMAL ||
const bool isHistoryOrReload =
loadType == LOAD_RELOAD_NORMAL ||
loadType == LOAD_RELOAD_BYPASS_CACHE ||
loadType == LOAD_RELOAD_BYPASS_PROXY ||
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE ||
loadType == LOAD_HISTORY) {
isHistoryOrReload = true;
}
loadType == LOAD_HISTORY;
// If it isn't a reload, the request already failed to be upgraded and
// https-first is enabled then don't ask the user again for permission to
// unload and just unload.
bool okToUnload;
if (!isHistoryOrReload && aLoadState->IsExemptFromHTTPSFirstMode() &&
nsHTTPSOnlyUtils::IsHttpsFirstModeEnabled(isPrivateWin)) {
rv = mDocumentViewer->PermitUnload(
@ -9324,7 +9320,7 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
}
}
if (mTiming && isNotDownload) {
if (mTiming && !isDownload) {
mTiming->NotifyUnloadAccepted(mCurrentURI);
}
@ -9358,7 +9354,7 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
// new request parameter.
// Also pass nullptr for the document, since it doesn't affect the return
// value for our purposes here.
bool savePresentation =
const bool savePresentation =
CanSavePresentation(aLoadState->LoadType(), nullptr, nullptr,
/* aReportBFCacheComboTelemetry */ true);
@ -9379,12 +9375,12 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
}
}
// Don't stop current network activity for javascript: URL's since
// they might not result in any data, and thus nothing should be
// stopped in those cases. In the case where they do result in
// data, the javascript: URL channel takes care of stopping
// current network activity.
if (!isJavaScript && isNotDownload) {
// Don't stop current network activity for javascript: URL's since they might
// not result in any data, and thus nothing should be stopped in those cases.
// In the case where they do result in data, the javascript: URL channel takes
// care of stopping current network activity. Similarly, downloads don't
// unload this document...
if (!isJavaScript && !isDownload) {
// Stop any current network activity.
// Also stop content if this is a zombie doc. otherwise
// the onload will be delayed by other loads initiated in the
@ -9392,7 +9388,6 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
// didn't fully load before the next load was initiated.
// If not a zombie, don't stop content until data
// starts arriving from the new URI...
if ((mDocumentViewer && mDocumentViewer->GetPreviousViewer()) ||
LOAD_TYPE_HAS_FLAGS(aLoadState->LoadType(), LOAD_FLAGS_STOP_CONTENT)) {
rv = Stop(nsIWebNavigation::STOP_ALL);

View file

@ -45,6 +45,9 @@ class AbortFollower : public nsISupports {
};
/*
* TODO(krosylight): The only consumer of this is Fetch. It would be nice to
* merge this back to AbortSignal as it's quite a duplication right now.
*
* AbortSignalImpl is a minimal implementation without an associated global
* and without event dispatching, those are added in AbortSignal.
* See Bug 1478101
@ -60,7 +63,7 @@ class AbortSignalImpl : public nsISupports, public SupportsWeakPtr {
// Helper for other DOM code
JS::Value RawReason() const;
virtual void SignalAbort(JS::Handle<JS::Value> aReason);
void SignalAbort(JS::Handle<JS::Value> aReason);
protected:
// Subclasses of this class must call these Traverse and Unlink functions
@ -72,6 +75,10 @@ class AbortSignalImpl : public nsISupports, public SupportsWeakPtr {
virtual ~AbortSignalImpl() { UnlinkFollowers(); }
virtual void SignalAbortWithDependents();
virtual void RunAbortSteps();
void SetAborted(JS::Handle<JS::Value> aReason);
JS::Heap<JS::Value> mReason;
@ -83,7 +90,10 @@ class AbortSignalImpl : public nsISupports, public SupportsWeakPtr {
void UnlinkFollowers();
// Raw pointers. |AbortFollower::Follow| adds to this array, and
// TODO(krosylight): We should rename all names around the term "Follow". See
// bug 1873648.
//
// |AbortFollower::Follow| adds to this array, and
// |AbortFollower::Unfollow| (also called by the destructor) will remove
// from this array. Finally, calling |SignalAbort()| will (after running all
// abort algorithms) empty this and make all contained followers |Unfollow()|.

View file

@ -41,17 +41,35 @@ void AbortSignalImpl::GetReason(JSContext* aCx,
JS::Value AbortSignalImpl::RawReason() const { return mReason.get(); }
// https://dom.spec.whatwg.org/#abortsignal-signal-abort steps 1-4
// https://dom.spec.whatwg.org/#abortsignal-signal-abort
void AbortSignalImpl::SignalAbort(JS::Handle<JS::Value> aReason) {
// Step 1.
// Step 1: If signal is aborted, then return.
if (mAborted) {
return;
}
// Step 2.
// Step 2: Set signals abort reason to reason if it is given; otherwise to a
// new "AbortError" DOMException.
//
// (But given AbortSignalImpl is supposed to run without JS context, the
// DOMException creation is deferred to the getter.)
SetAborted(aReason);
// Step 3.
// Step 3 - 6
SignalAbortWithDependents();
}
void AbortSignalImpl::SignalAbortWithDependents() {
// AbortSignalImpl cannot have dependents, so just run abort steps for itself.
RunAbortSteps();
}
// https://dom.spec.whatwg.org/#run-the-abort-steps
// This skips event firing as AbortSignalImpl is not supposed to be exposed to
// JS. It's done instead in AbortSignal::RunAbortSteps.
void AbortSignalImpl::RunAbortSteps() {
// Step 1: For each algorithm of signals abort algorithms: run algorithm.
//
// When there are multiple followers, the follower removal algorithm
// https://dom.spec.whatwg.org/#abortsignal-remove could be invoked in an
// earlier algorithm to remove a later algorithm, so |mFollowers| must be a
@ -61,7 +79,7 @@ void AbortSignalImpl::SignalAbort(JS::Handle<JS::Value> aReason) {
follower->RunAbortAlgorithm();
}
// Step 4.
// Step 2: Empty signals abort algorithms.
UnlinkFollowers();
}
@ -277,14 +295,26 @@ already_AddRefed<AbortSignal> AbortSignal::Any(
RefPtr<AbortSignal> resultSignal =
new AbortSignal(aGlobal, false, JS::UndefinedHandleValue);
// Step 2. For each signal of signals: if signal is aborted, then set
// resultSignal's abort reason to signal's abort reason and return
// resultSignal.
for (const auto& signal : aSignals) {
if (signal->Aborted()) {
JS::Rooted<JS::Value> reason(RootingCx(), signal->RawReason());
resultSignal->SetAborted(reason);
return resultSignal.forget();
if (!aSignals.IsEmpty()) {
// (Prepare for step 2 which uses the reason of this. Cannot use
// RawReason because that can cause constructing new DOMException for each
// dependent signal instead of sharing the single one.)
AutoJSAPI jsapi;
if (!jsapi.Init(aGlobal)) {
return nullptr;
}
JSContext* cx = jsapi.cx();
// Step 2. For each signal of signals: if signal is aborted, then set
// resultSignal's abort reason to signal's abort reason and return
// resultSignal.
for (const auto& signal : aSignals) {
if (signal->Aborted()) {
JS::Rooted<JS::Value> reason(cx);
signal->GetReason(cx, &reason);
resultSignal->SetAborted(reason);
return resultSignal.forget();
}
}
}
@ -339,17 +369,56 @@ void AbortSignal::ThrowIfAborted(JSContext* aCx, ErrorResult& aRv) {
}
}
// https://dom.spec.whatwg.org/#abortsignal-signal-abort
void AbortSignal::SignalAbort(JS::Handle<JS::Value> aReason) {
// Step 1, in case "signal abort" algorithm is called directly
if (Aborted()) {
return;
// Step 3 - 6 of https://dom.spec.whatwg.org/#abortsignal-signal-abort
void AbortSignal::SignalAbortWithDependents() {
// Step 3: Let dependentSignalsToAbort be a new list.
nsTArray<RefPtr<AbortSignal>> dependentSignalsToAbort;
// mDependentSignals can go away after this function.
nsTArray<RefPtr<AbortSignal>> dependentSignals = std::move(mDependentSignals);
if (!dependentSignals.IsEmpty()) {
// (Prepare for step 4.1.1 which uses the reason of this. Cannot use
// RawReason because that can cause constructing new DOMException for each
// dependent signal instead of sharing the single one.)
AutoJSAPI jsapi;
if (!jsapi.Init(GetParentObject())) {
return;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> reason(cx);
GetReason(cx, &reason);
// Step 4. For each dependentSignal of signals dependent signals:
for (const auto& dependentSignal : dependentSignals) {
MOZ_ASSERT(dependentSignal->mSourceSignals.Contains(this));
// Step 4.1: If dependentSignal is not aborted, then:
if (!dependentSignal->Aborted()) {
// Step 4.1.1: Set dependentSignals abort reason to signals abort
// reason.
dependentSignal->SetAborted(reason);
// Step 4.1.2: Append dependentSignal to dependentSignalsToAbort.
dependentSignalsToAbort.AppendElement(dependentSignal);
}
}
}
// Steps 1-4.
AbortSignalImpl::SignalAbort(aReason);
// Step 5: Run the abort steps for signal.
RunAbortSteps();
// Step 5. Fire an event named abort at this signal
// Step 6: For each dependentSignal of dependentSignalsToAbort, run the abort
// steps for dependentSignal.
for (const auto& dependentSignal : dependentSignalsToAbort) {
dependentSignal->RunAbortSteps();
}
}
// https://dom.spec.whatwg.org/#run-the-abort-steps
void AbortSignal::RunAbortSteps() {
// Step 1 - 2:
AbortSignalImpl::RunAbortSteps();
// Step 3. Fire an event named abort at this signal.
EventInit init;
init.mBubbles = false;
init.mCancelable = false;
@ -358,14 +427,6 @@ void AbortSignal::SignalAbort(JS::Handle<JS::Value> aReason) {
event->SetTrusted(true);
DispatchEvent(*event);
// Step 6. Abort dependentSignals of this signal
for (const auto& dependant : mDependentSignals) {
MOZ_ASSERT(dependant->mSourceSignals.Contains(this));
dependant->SignalAbort(aReason);
}
// clear dependent signals so that they might be garbage collected
mDependentSignals.Clear();
}
bool AbortSignal::Dependent() const { return mDependent; }

View file

@ -55,9 +55,6 @@ class AbortSignal : public DOMEventTargetHelper, public AbortSignalImpl {
void ThrowIfAborted(JSContext* aCx, ErrorResult& aRv);
// AbortSignalImpl
void SignalAbort(JS::Handle<JS::Value> aReason) override;
virtual bool IsTaskSignal() const { return false; }
bool Dependent() const;
@ -67,6 +64,10 @@ class AbortSignal : public DOMEventTargetHelper, public AbortSignalImpl {
void MakeDependentOn(AbortSignal* aSignal);
void SignalAbortWithDependents() override;
void RunAbortSteps() override;
nsTArray<WeakPtr<AbortSignal>> mSourceSignals;
nsTArray<RefPtr<AbortSignal>> mDependentSignals;

View file

@ -1493,7 +1493,7 @@ inline Maybe<Enum> StringToEnum(const StringT& aString) {
}
template <typename Enum>
inline const nsCString& GetEnumString(Enum stringId) {
inline constexpr const nsLiteralCString& GetEnumString(Enum stringId) {
MOZ_RELEASE_ASSERT(
static_cast<size_t>(stringId) <
mozilla::ArrayLength(binding_detail::EnumStrings<Enum>::Values));

View file

@ -12458,22 +12458,22 @@ class CGEnum(CGThing):
declare=fill(
"""
template <> struct EnumStrings<${name}> {
static const nsLiteralCString Values[${count}];
};
""",
name=self.enum.identifier.name,
count=self.nEnumStrings(),
),
define=fill(
"""
const nsLiteralCString EnumStrings<${name}>::Values[${count}] = {
$*{entries}
static constexpr nsLiteralCString Values[${count}] {
$*{entries}
};
};
""",
name=self.enum.identifier.name,
count=self.nEnumStrings(),
entries="".join('"%s"_ns,\n' % val for val in self.enum.values()),
),
define=fill(
"""
constexpr nsLiteralCString EnumStrings<${name}>::Values[${count}];
""",
name=self.enum.identifier.name,
count=self.nEnumStrings(),
),
),
)
toJSValue = CGEnumToJSValue(enum)

View file

@ -2598,24 +2598,91 @@ bool SharedContextWebgl::PruneTextureMemory(size_t aMargin, bool aPruneUnused) {
return mNumTextureHandles < oldItems;
}
void DrawTargetWebgl::FillRect(const Rect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions) {
if (SupportsPattern(aPattern)) {
RectDouble xformRect = TransformDouble(aRect);
if (aPattern.GetType() == PatternType::COLOR) {
if (Maybe<Rect> clipped = RectClippedToViewport(xformRect)) {
// If the pattern is transform-invariant and the rect clips to the
// viewport, just clip drawing to the viewport to avoid transform
// issues.
DrawRect(*clipped, aPattern, aOptions, Nothing(), nullptr, false);
return;
// Attempt to convert a linear gradient to a 1D ramp texture.
Maybe<SurfacePattern> DrawTargetWebgl::LinearGradientToSurface(
const RectDouble& aBounds, const Pattern& aPattern) {
MOZ_ASSERT(aPattern.GetType() == PatternType::LINEAR_GRADIENT);
const auto& gradient = static_cast<const LinearGradientPattern&>(aPattern);
// The gradient points must be transformed by the gradient's matrix.
Point gradBegin = gradient.mMatrix.TransformPoint(gradient.mBegin);
Point gradEnd = gradient.mMatrix.TransformPoint(gradient.mEnd);
// Get the gradient points in user-space.
Point begin = mTransform.TransformPoint(gradBegin);
Point end = mTransform.TransformPoint(gradEnd);
// Find the normalized direction of the gradient and its length.
Point dir = end - begin;
float len = dir.Length();
dir = dir / len;
// Restrict the rendered bounds to fall within the canvas.
Rect visBounds = NarrowToFloat(aBounds.SafeIntersect(RectDouble(GetRect())));
// Calculate the distances along the gradient direction of the bounds.
float dist0 = (visBounds.TopLeft() - begin).DotProduct(dir);
float distX = visBounds.width * dir.x;
float distY = visBounds.height * dir.y;
float minDist = floorf(
std::max(dist0 + std::min(distX, 0.0f) + std::min(distY, 0.0f), 0.0f));
float maxDist = ceilf(
std::min(dist0 + std::max(distX, 0.0f) + std::max(distY, 0.0f), len));
// Calculate the approximate size of the ramp texture, and see if it would be
// sufficiently smaller than just rendering the primitive.
float subLen = maxDist - minDist;
if (subLen > 0 && subLen < 0.5f * visBounds.Area()) {
// Create a 1D texture to contain the gradient ramp. Reserve two extra
// texels at the beginning and end of the ramp to account for clamping.
RefPtr<DrawTargetSkia> dt = new DrawTargetSkia;
if (dt->Init(IntSize(int32_t(subLen + 2), 1), SurfaceFormat::B8G8R8A8)) {
// Fill the section of the gradient ramp that is actually used.
dt->FillRect(Rect(dt->GetRect()),
LinearGradientPattern(Point(1 - minDist, 0.0f),
Point(len + 1 - minDist, 0.0f),
gradient.mStops));
if (RefPtr<SourceSurface> snapshot = dt->Snapshot()) {
// Calculate a matrix that will map the gradient ramp texture onto the
// actual direction of the gradient.
Point gradDir = (gradEnd - gradBegin) / len;
Point tangent = Point(-gradDir.y, gradDir.x) / gradDir.Length();
SurfacePattern surfacePattern(
snapshot, ExtendMode::CLAMP,
Matrix(gradDir.x, gradDir.y, tangent.x, tangent.y, gradBegin.x,
gradBegin.y)
.PreTranslate(minDist - 1, 0));
if (SupportsPattern(surfacePattern)) {
return Some(surfacePattern);
}
}
}
if (RectInsidePrecisionLimits(xformRect)) {
DrawRect(aRect, aPattern, aOptions);
}
return Nothing();
}
void DrawTargetWebgl::FillRect(const Rect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions) {
RectDouble xformRect = TransformDouble(aRect);
if (aPattern.GetType() == PatternType::COLOR) {
if (Maybe<Rect> clipped = RectClippedToViewport(xformRect)) {
// If the pattern is transform-invariant and the rect clips to the
// viewport, just clip drawing to the viewport to avoid transform
// issues.
DrawRect(*clipped, aPattern, aOptions, Nothing(), nullptr, false);
return;
}
}
if (RectInsidePrecisionLimits(xformRect)) {
if (SupportsPattern(aPattern)) {
DrawRect(aRect, aPattern, aOptions);
return;
}
if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) {
if (Maybe<SurfacePattern> surface =
LinearGradientToSurface(xformRect, aPattern)) {
if (DrawRect(aRect, *surface, aOptions, Nothing(), nullptr, true, true,
true)) {
return;
}
}
}
}
if (!mWebglValid) {
MarkSkiaChanged(aOptions);
mSkia->FillRect(aRect, aPattern, aOptions);
@ -2772,7 +2839,7 @@ void DrawTargetWebgl::Fill(const Path* aPath, const Pattern& aPattern,
const SkPath& skiaPath = static_cast<const PathSkia*>(aPath)->GetPath();
SkRect skiaRect = SkRect::MakeEmpty();
// Draw the path as a simple rectangle with a supported pattern when possible.
if (skiaPath.isRect(&skiaRect) && SupportsPattern(aPattern)) {
if (skiaPath.isRect(&skiaRect)) {
RectDouble rect = SkRectToRectDouble(skiaRect);
RectDouble xformRect = TransformDouble(rect);
if (aPattern.GetType() == PatternType::COLOR) {
@ -2784,9 +2851,21 @@ void DrawTargetWebgl::Fill(const Path* aPath, const Pattern& aPattern,
return;
}
}
if (RectInsidePrecisionLimits(xformRect)) {
DrawRect(NarrowToFloat(rect), aPattern, aOptions);
return;
if (SupportsPattern(aPattern)) {
DrawRect(NarrowToFloat(rect), aPattern, aOptions);
return;
}
if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) {
if (Maybe<SurfacePattern> surface =
LinearGradientToSurface(xformRect, aPattern)) {
if (DrawRect(NarrowToFloat(rect), *surface, aOptions, Nothing(),
nullptr, true, true, true)) {
return;
}
}
}
}
}

View file

@ -619,6 +619,8 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
bool aTransformed = true, bool aClipped = true,
bool aAccelOnly = false, bool aForceUpdate = false,
const StrokeOptions* aStrokeOptions = nullptr);
Maybe<SurfacePattern> LinearGradientToSurface(const RectDouble& aBounds,
const Pattern& aPattern);
ColorPattern GetClearPattern() const;

View file

@ -13,9 +13,6 @@
#include "nsStringFwd.h"
namespace mozilla::dom {
const char* kFetchPriorityAttributeValueHigh = "high";
const char* kFetchPriorityAttributeValueLow = "low";
const char* kFetchPriorityAttributeValueAuto = "auto";
FetchPriority ToFetchPriority(RequestPriority aRequestPriority) {
switch (aRequestPriority) {

View file

@ -37,9 +37,9 @@ void LogPriorityMapping(LazyLogModule& aLazyLogModule,
FetchPriority aFetchPriority,
int32_t aSupportsPriority);
extern const char* kFetchPriorityAttributeValueHigh;
extern const char* kFetchPriorityAttributeValueLow;
extern const char* kFetchPriorityAttributeValueAuto;
constexpr const char kFetchPriorityAttributeValueHigh[] = "high";
constexpr const char kFetchPriorityAttributeValueLow[] = "low";
constexpr const char kFetchPriorityAttributeValueAuto[] = "auto";
} // namespace dom
} // namespace mozilla

View file

@ -229,10 +229,10 @@ nsresult HTMLDNSPrefetch::Prefetch(
const OriginAttributes& aPartitionedPrincipalOriginAttributes,
nsIDNSService::DNSFlags flags) {
if (IsNeckoChild()) {
// We need to check IsEmpty() because net_IsValidHostName()
// We need to check IsEmpty() because net_IsValidDNSHost()
// considers empty strings to be valid hostnames
if (!hostname.IsEmpty() &&
net_IsValidHostName(NS_ConvertUTF16toUTF8(hostname))) {
net_IsValidDNSHost(NS_ConvertUTF16toUTF8(hostname))) {
// during shutdown gNeckoChild might be null
if (gNeckoChild) {
gNeckoChild->SendHTMLDNSPrefetch(
@ -312,10 +312,10 @@ nsresult HTMLDNSPrefetch::CancelPrefetch(
nsIDNSService::DNSFlags flags, nsresult aReason) {
// Forward this request to Necko Parent if we're a child process
if (IsNeckoChild()) {
// We need to check IsEmpty() because net_IsValidHostName()
// We need to check IsEmpty() because net_IsValidDNSHost()
// considers empty strings to be valid hostnames
if (!hostname.IsEmpty() &&
net_IsValidHostName(NS_ConvertUTF16toUTF8(hostname))) {
net_IsValidDNSHost(NS_ConvertUTF16toUTF8(hostname))) {
// during shutdown gNeckoChild might be null
if (gNeckoChild && gNeckoChild->CanSend()) {
gNeckoChild->SendCancelHTMLDNSPrefetch(

View file

@ -104,7 +104,7 @@ static const uint8_t NS_INPUTMODE_NUMERIC = 6;
static const uint8_t NS_INPUTMODE_DECIMAL = 7;
static const uint8_t NS_INPUTMODE_SEARCH = 8;
static const nsAttrValue::EnumTable kInputmodeTable[] = {
static constexpr nsAttrValue::EnumTable kInputmodeTable[] = {
{"none", NS_INPUTMODE_NONE},
{"text", NS_INPUTMODE_TEXT},
{"tel", NS_INPUTMODE_TEL},
@ -123,7 +123,7 @@ static const uint8_t NS_ENTERKEYHINT_PREVIOUS = 5;
static const uint8_t NS_ENTERKEYHINT_SEARCH = 6;
static const uint8_t NS_ENTERKEYHINT_SEND = 7;
static const nsAttrValue::EnumTable kEnterKeyHintTable[] = {
static constexpr nsAttrValue::EnumTable kEnterKeyHintTable[] = {
{"enter", NS_ENTERKEYHINT_ENTER},
{"done", NS_ENTERKEYHINT_DONE},
{"go", NS_ENTERKEYHINT_GO},
@ -138,7 +138,7 @@ static const uint8_t NS_AUTOCAPITALIZE_SENTENCES = 2;
static const uint8_t NS_AUTOCAPITALIZE_WORDS = 3;
static const uint8_t NS_AUTOCAPITALIZE_CHARACTERS = 4;
static const nsAttrValue::EnumTable kAutocapitalizeTable[] = {
static constexpr nsAttrValue::EnumTable kAutocapitalizeTable[] = {
{"none", NS_AUTOCAPITALIZE_NONE},
{"sentences", NS_AUTOCAPITALIZE_SENTENCES},
{"words", NS_AUTOCAPITALIZE_WORDS},
@ -168,7 +168,7 @@ nsresult nsGenericHTMLElement::CopyInnerTo(Element* aDst) {
return NS_OK;
}
static const nsAttrValue::EnumTable kDirTable[] = {
static constexpr nsAttrValue::EnumTable kDirTable[] = {
{"ltr", Directionality::Ltr},
{"rtl", Directionality::Rtl},
{"auto", Directionality::Auto},
@ -179,11 +179,11 @@ namespace {
// See <https://html.spec.whatwg.org/#the-popover-attribute>.
enum class PopoverAttributeKeyword : uint8_t { Auto, EmptyString, Manual };
static const char* kPopoverAttributeValueAuto = "auto";
static const char* kPopoverAttributeValueEmptyString = "";
static const char* kPopoverAttributeValueManual = "manual";
static constexpr const char kPopoverAttributeValueAuto[] = "auto";
static constexpr const char kPopoverAttributeValueEmptyString[] = "";
static constexpr const char kPopoverAttributeValueManual[] = "manual";
static const nsAttrValue::EnumTable kPopoverTable[] = {
static constexpr nsAttrValue::EnumTable kPopoverTable[] = {
{kPopoverAttributeValueAuto, PopoverAttributeKeyword::Auto},
{kPopoverAttributeValueEmptyString, PopoverAttributeKeyword::EmptyString},
{kPopoverAttributeValueManual, PopoverAttributeKeyword::Manual},
@ -210,7 +210,7 @@ FetchPriority nsGenericHTMLElement::ToFetchPriority(const nsAString& aValue) {
namespace {
// <https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fetch-priority-attributes>.
static const nsAttrValue::EnumTable kFetchPriorityEnumTable[] = {
static constexpr nsAttrValue::EnumTable kFetchPriorityEnumTable[] = {
{kFetchPriorityAttributeValueHigh, FetchPriority::High},
{kFetchPriorityAttributeValueLow, FetchPriority::Low},
{kFetchPriorityAttributeValueAuto, FetchPriority::Auto},
@ -1109,7 +1109,7 @@ nsMapRuleToAttributesFunc nsGenericHTMLElement::GetAttributeMappingFunction()
return &MapCommonAttributesInto;
}
static const nsAttrValue::EnumTable kDivAlignTable[] = {
static constexpr nsAttrValue::EnumTable kDivAlignTable[] = {
{"left", StyleTextAlign::MozLeft},
{"right", StyleTextAlign::MozRight},
{"center", StyleTextAlign::MozCenter},
@ -1117,7 +1117,7 @@ static const nsAttrValue::EnumTable kDivAlignTable[] = {
{"justify", StyleTextAlign::Justify},
{nullptr, 0}};
static const nsAttrValue::EnumTable kFrameborderTable[] = {
static constexpr nsAttrValue::EnumTable kFrameborderTable[] = {
{"yes", FrameBorderProperty::Yes},
{"no", FrameBorderProperty::No},
{"1", FrameBorderProperty::One},
@ -1125,7 +1125,7 @@ static const nsAttrValue::EnumTable kFrameborderTable[] = {
{nullptr, 0}};
// TODO(emilio): Nobody uses the parsed attribute here.
static const nsAttrValue::EnumTable kScrollingTable[] = {
static constexpr nsAttrValue::EnumTable kScrollingTable[] = {
{"yes", ScrollingAttribute::Yes},
{"no", ScrollingAttribute::No},
{"on", ScrollingAttribute::On},
@ -1135,7 +1135,7 @@ static const nsAttrValue::EnumTable kScrollingTable[] = {
{"auto", ScrollingAttribute::Auto},
{nullptr, 0}};
static const nsAttrValue::EnumTable kTableVAlignTable[] = {
static constexpr nsAttrValue::EnumTable kTableVAlignTable[] = {
{"top", StyleVerticalAlignKeyword::Top},
{"middle", StyleVerticalAlignKeyword::Middle},
{"bottom", StyleVerticalAlignKeyword::Bottom},
@ -1144,7 +1144,7 @@ static const nsAttrValue::EnumTable kTableVAlignTable[] = {
bool nsGenericHTMLElement::ParseAlignValue(const nsAString& aString,
nsAttrValue& aResult) {
static const nsAttrValue::EnumTable kAlignTable[] = {
static constexpr nsAttrValue::EnumTable kAlignTable[] = {
{"left", StyleTextAlign::Left},
{"right", StyleTextAlign::Right},
@ -1194,7 +1194,7 @@ bool nsGenericHTMLElement::ParseAlignValue(const nsAString& aString,
//----------------------------------------
static const nsAttrValue::EnumTable kTableHAlignTable[] = {
static constexpr nsAttrValue::EnumTable kTableHAlignTable[] = {
{"left", StyleTextAlign::Left},
{"right", StyleTextAlign::Right},
{"center", StyleTextAlign::Center},
@ -1209,7 +1209,7 @@ bool nsGenericHTMLElement::ParseTableHAlignValue(const nsAString& aString,
//----------------------------------------
// This table is used for td, th, tr, col, thead, tbody and tfoot.
static const nsAttrValue::EnumTable kTableCellHAlignTable[] = {
static constexpr nsAttrValue::EnumTable kTableCellHAlignTable[] = {
{"left", StyleTextAlign::MozLeft},
{"right", StyleTextAlign::MozRight},
{"center", StyleTextAlign::MozCenter},
@ -1251,9 +1251,7 @@ bool nsGenericHTMLElement::ParseImageAttribute(nsAtom* aAttribute,
bool nsGenericHTMLElement::ParseReferrerAttribute(const nsAString& aString,
nsAttrValue& aResult) {
using mozilla::dom::ReferrerInfo;
// This is a bit sketchy, we assume GetEnumString(…).get() points to a static
// buffer, relying on the fact that GetEnumString(…) returns a literal string.
static const nsAttrValue::EnumTable kReferrerPolicyTable[] = {
static constexpr nsAttrValue::EnumTable kReferrerPolicyTable[] = {
{GetEnumString(ReferrerPolicy::No_referrer).get(),
static_cast<int16_t>(ReferrerPolicy::No_referrer)},
{GetEnumString(ReferrerPolicy::Origin).get(),
@ -2770,7 +2768,7 @@ void nsGenericHTMLFormControlElement::SetFormAutofillState(
//----------------------------------------------------------------------
static const nsAttrValue::EnumTable kPopoverTargetActionTable[] = {
static constexpr nsAttrValue::EnumTable kPopoverTargetActionTable[] = {
{"toggle", PopoverTargetAction::Toggle},
{"show", PopoverTargetAction::Show},
{"hide", PopoverTargetAction::Hide},

View file

@ -53,7 +53,7 @@ bool PrivateAttribution::GetSourceHostIfNonPrivate(nsACString& aSourceHost,
[[nodiscard]] static bool ValidateHost(const nsACString& aHost,
ErrorResult& aRv) {
if (!net_IsValidHostName(aHost)) {
if (!net_IsValidDNSHost(aHost)) {
aRv.ThrowSyntaxError(aHost + " is not a valid host name"_ns);
return false;
}

View file

@ -6,6 +6,7 @@
#include "SVGPolyElement.h"
#include "DOMSVGPointList.h"
#include "mozilla/dom/SVGAnimatedLength.h"
#include "mozilla/gfx/2D.h"
#include "SVGContentUtils.h"
@ -48,13 +49,15 @@ void SVGPolyElement::GetMarkPoints(nsTArray<SVGMark>* aMarks) {
if (!points.Length()) return;
float px = points[0].mX, py = points[0].mY, prevAngle = 0.0;
float zoom = UserSpaceMetrics::GetZoom(this);
float px = points[0].mX * zoom, py = points[0].mY * zoom, prevAngle = 0.0;
aMarks->AppendElement(SVGMark(px, py, 0, SVGMark::eStart));
for (uint32_t i = 1; i < points.Length(); ++i) {
float x = points[i].mX;
float y = points[i].mY;
float x = points[i].mX * zoom;
float y = points[i].mY * zoom;
float angle = std::atan2(y - py, x - px);
// Vertex marker.
@ -93,18 +96,20 @@ bool SVGPolyElement::GetGeometryBounds(Rect* aBounds,
return false;
}
float zoom = UserSpaceMetrics::GetZoom(this);
if (aToBoundsSpace.IsRectilinear()) {
// We can avoid transforming each point and just transform the result.
// Important for large point lists.
Rect bounds(points[0], Size());
Rect bounds(points[0] * zoom, Size());
for (uint32_t i = 1; i < points.Length(); ++i) {
bounds.ExpandToEnclose(points[i]);
bounds.ExpandToEnclose(points[i] * zoom);
}
*aBounds = aToBoundsSpace.TransformBounds(bounds);
} else {
*aBounds = Rect(aToBoundsSpace.TransformPoint(points[0]), Size());
*aBounds = Rect(aToBoundsSpace.TransformPoint(points[0] * zoom), Size());
for (uint32_t i = 1; i < points.Length(); ++i) {
aBounds->ExpandToEnclose(aToBoundsSpace.TransformPoint(points[i]));
aBounds->ExpandToEnclose(aToBoundsSpace.TransformPoint(points[i] * zoom));
}
}
return true;

View file

@ -6,6 +6,7 @@
#include "mozilla/dom/SVGPolygonElement.h"
#include "mozilla/dom/SVGPolygonElementBinding.h"
#include "mozilla/dom/SVGAnimatedLength.h"
#include "mozilla/gfx/2D.h"
#include "SVGContentUtils.h"
@ -64,9 +65,11 @@ already_AddRefed<Path> SVGPolygonElement::BuildPath(PathBuilder* aBuilder) {
return nullptr;
}
aBuilder->MoveTo(points[0]);
float zoom = UserSpaceMetrics::GetZoom(this);
aBuilder->MoveTo(points[0] * zoom);
for (uint32_t i = 1; i < points.Length(); ++i) {
aBuilder->LineTo(points[i]);
aBuilder->LineTo(points[i] * zoom);
}
aBuilder->Close();

View file

@ -6,6 +6,7 @@
#include "mozilla/dom/SVGPolylineElement.h"
#include "mozilla/dom/SVGPolylineElementBinding.h"
#include "mozilla/dom/SVGAnimatedLength.h"
#include "mozilla/gfx/2D.h"
using namespace mozilla::gfx;
@ -41,9 +42,11 @@ already_AddRefed<Path> SVGPolylineElement::BuildPath(PathBuilder* aBuilder) {
return nullptr;
}
aBuilder->MoveTo(points[0]);
float zoom = UserSpaceMetrics::GetZoom(this);
aBuilder->MoveTo(points[0] * zoom);
for (uint32_t i = 1; i < points.Length(); ++i) {
aBuilder->LineTo(points[i]);
aBuilder->LineTo(points[i] * zoom);
}
return aBuilder->Finish();

Binary file not shown.

View file

@ -1,10 +1,6 @@
# 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/.
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

7
gradlew vendored
View file

@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum

2
gradlew.bat vendored
View file

@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################

View file

@ -37,7 +37,7 @@ namespace gc {
class Arena;
struct Cell;
class TenuredChunk;
class ArenaChunk;
class StoreBuffer;
class TenuredCell;
@ -84,7 +84,7 @@ const size_t ArenaBitmapWords = HowMany(ArenaBitmapBits, JS_BITS_PER_WORD);
enum class ChunkKind : uint8_t {
Invalid = 0,
TenuredHeap,
TenuredArenas,
NurseryToSpace,
NurseryFromSpace
};
@ -97,13 +97,13 @@ class ChunkBase {
// Initialize a tenured heap chunk.
explicit ChunkBase(JSRuntime* rt) {
MOZ_ASSERT((uintptr_t(this) & ChunkMask) == 0);
initBaseForTenuredChunk(rt);
initBaseForArenaChunk(rt);
}
void initBaseForTenuredChunk(JSRuntime* rt) {
void initBaseForArenaChunk(JSRuntime* rt) {
runtime = rt;
storeBuffer = nullptr;
kind = ChunkKind::TenuredHeap;
kind = ChunkKind::TenuredArenas;
nurseryChunkIndex = UINT8_MAX;
}
@ -123,7 +123,7 @@ class ChunkBase {
ChunkKind getKind() const {
MOZ_ASSERT_IF(storeBuffer, kind == ChunkKind::NurseryToSpace ||
kind == ChunkKind::NurseryFromSpace);
MOZ_ASSERT_IF(!storeBuffer, kind == ChunkKind::TenuredHeap);
MOZ_ASSERT_IF(!storeBuffer, kind == ChunkKind::TenuredArenas);
return kind;
}
@ -139,12 +139,12 @@ class ChunkBase {
uint8_t nurseryChunkIndex;
};
// Information about tenured heap chunks.
struct TenuredChunkInfo {
// Information about tenured heap chunks containing arenas.
struct ArenaChunkInfo {
private:
friend class ChunkPool;
TenuredChunk* next = nullptr;
TenuredChunk* prev = nullptr;
ArenaChunk* next = nullptr;
ArenaChunk* prev = nullptr;
public:
/* Number of free arenas, either committed or decommitted. */
@ -180,7 +180,7 @@ const size_t BitsPerPageWithHeaders =
(ArenaSize + ArenaBitmapBytes) * ArenasPerPage * CHAR_BIT + ArenasPerPage +
1;
const size_t ChunkBitsAvailable =
(ChunkSize - sizeof(ChunkBase) - sizeof(TenuredChunkInfo)) * CHAR_BIT;
(ChunkSize - sizeof(ChunkBase) - sizeof(ArenaChunkInfo)) * CHAR_BIT;
const size_t PagesPerChunk = ChunkBitsAvailable / BitsPerPageWithHeaders;
const size_t ArenasPerChunk = PagesPerChunk * ArenasPerPage;
const size_t FreeCommittedBits = ArenasPerChunk;
@ -190,7 +190,7 @@ const size_t BitsPerArenaWithHeaders =
(DecommitBits / ArenasPerChunk) + 1;
const size_t CalculatedChunkSizeRequired =
sizeof(ChunkBase) + sizeof(TenuredChunkInfo) +
sizeof(ChunkBase) + sizeof(ArenaChunkInfo) +
RoundUp(ArenasPerChunk * ArenaBitmapBytes, sizeof(uintptr_t)) +
RoundUp(FreeCommittedBits, sizeof(uint32_t) * CHAR_BIT) / CHAR_BIT +
RoundUp(DecommitBits, sizeof(uint32_t) * CHAR_BIT) / CHAR_BIT +
@ -205,10 +205,13 @@ static_assert(CalculatedChunkPadSize * CHAR_BIT < BitsPerArenaWithHeaders,
static_assert(ArenasPerChunk == 252,
"Do not accidentally change our heap's density.");
const size_t FirstArenaOffset = ChunkSize - ArenasPerChunk * ArenaSize;
// Mark bitmaps are atomic because they can be written by gray unmarking on the
// main thread while read by sweeping on a background thread. The former does
// not affect the result of the latter.
using MarkBitmapWord = mozilla::Atomic<uintptr_t, mozilla::Relaxed>;
static constexpr size_t MarkBitmapWordBits = sizeof(MarkBitmapWord) * CHAR_BIT;
/*
* Live objects are marked black or gray. Everything reachable from a JS root is
@ -227,19 +230,63 @@ enum class ColorBit : uint32_t { BlackBit = 0, GrayOrBlackBit = 1 };
enum class MarkColor : uint8_t { Gray = 1, Black = 2 };
// Mark bitmap for a tenured heap chunk.
template <size_t BytesPerMarkBit, size_t FirstThingOffset>
class alignas(TypicalCacheLineSize) MarkBitmap {
static constexpr size_t WordCount = ArenaBitmapWords * ArenasPerChunk;
static constexpr size_t ByteCount =
(ChunkSize - FirstThingOffset) / BytesPerMarkBit;
static constexpr size_t WordCount = HowMany(ByteCount, MarkBitmapWordBits);
MarkBitmapWord bitmap[WordCount];
public:
inline void getMarkWordAndMask(const TenuredCell* cell, ColorBit colorBit,
MarkBitmapWord** wordp, uintptr_t* maskp);
static constexpr size_t FirstThingAdjustmentBits =
FirstThingOffset / BytesPerMarkBit;
static constexpr size_t FirstThingAdjustmentWords =
FirstThingAdjustmentBits / MarkBitmapWordBits;
MOZ_ALWAYS_INLINE void getMarkWordAndMask(const TenuredCell* cell,
ColorBit colorBit,
MarkBitmapWord** wordp,
uintptr_t* maskp) {
// Note: the JIT pre-barrier trampolines inline this code. Update
// MacroAssembler::emitPreBarrierFastPath code too when making changes here!
MOZ_ASSERT(size_t(colorBit) < MarkBitsPerCell);
size_t offset = uintptr_t(cell) & ChunkMask;
MOZ_ASSERT(offset >= FirstThingOffset);
const size_t bit = offset / BytesPerMarkBit + size_t(colorBit);
size_t word = bit / MarkBitmapWordBits - FirstThingAdjustmentWords;
MOZ_ASSERT(word < WordCount);
*wordp = &bitmap[word];
*maskp = uintptr_t(1) << (bit % MarkBitmapWordBits);
}
// The following are not exported and are defined in gc/Heap.h:
inline bool markBit(const TenuredCell* cell, ColorBit colorBit);
inline bool isMarkedAny(const TenuredCell* cell);
inline bool isMarkedBlack(const TenuredCell* cell);
inline bool isMarkedGray(const TenuredCell* cell);
MOZ_ALWAYS_INLINE bool markBit(const TenuredCell* cell, ColorBit colorBit) {
MarkBitmapWord* word;
uintptr_t mask;
getMarkWordAndMask(cell, colorBit, &word, &mask);
return *word & mask;
}
MOZ_ALWAYS_INLINE bool isMarkedAny(const TenuredCell* cell) {
return markBit(cell, ColorBit::BlackBit) ||
markBit(cell, ColorBit::GrayOrBlackBit);
}
MOZ_ALWAYS_INLINE bool isMarkedBlack(const TenuredCell* cell) {
// Return true if BlackBit is set.
return markBit(cell, ColorBit::BlackBit);
}
MOZ_ALWAYS_INLINE bool isMarkedGray(const TenuredCell* cell) {
// Return true if GrayOrBlackBit is set and BlackBit is not set.
return !markBit(cell, ColorBit::BlackBit) &&
markBit(cell, ColorBit::GrayOrBlackBit);
}
inline bool markIfUnmarked(const TenuredCell* cell, MarkColor color);
inline bool markIfUnmarkedAtomic(const TenuredCell* cell, MarkColor color);
inline void markBlack(const TenuredCell* cell);
@ -252,8 +299,7 @@ class alignas(TypicalCacheLineSize) MarkBitmap {
inline void copyFrom(const MarkBitmap& other);
};
static_assert(ArenaBitmapBytes * ArenasPerChunk == sizeof(MarkBitmap),
"Ensure our MarkBitmap actually covers all arenas.");
using ChunkMarkBitmap = MarkBitmap<CellBytesPerMarkBit, FirstArenaOffset>;
// Bitmap with one bit per page used for decommitted page set.
using ChunkPageBitmap = mozilla::BitSet<PagesPerChunk, uint32_t>;
@ -261,21 +307,25 @@ using ChunkPageBitmap = mozilla::BitSet<PagesPerChunk, uint32_t>;
// Bitmap with one bit per arena used for free committed arena set.
using ChunkArenaBitmap = mozilla::BitSet<ArenasPerChunk, uint32_t>;
// Base class containing data members for a tenured heap chunk.
class TenuredChunkBase : public ChunkBase {
// Base class for a tenured heap chunk containing fixed size arenas.
class ArenaChunkBase : public ChunkBase {
public:
TenuredChunkInfo info;
MarkBitmap markBits;
ArenaChunkInfo info;
ChunkMarkBitmap markBits;
ChunkArenaBitmap freeCommittedArenas;
ChunkPageBitmap decommittedPages;
protected:
explicit TenuredChunkBase(JSRuntime* runtime) : ChunkBase(runtime) {
explicit ArenaChunkBase(JSRuntime* runtime) : ChunkBase(runtime) {
static_assert(sizeof(markBits) == ArenaBitmapBytes * ArenasPerChunk,
"Ensure our MarkBitmap actually covers all arenas.");
info.numArenasFree = ArenasPerChunk;
}
void initAsDecommitted();
};
static_assert(FirstArenaOffset ==
RoundUp(sizeof(gc::ArenaChunkBase), ArenaSize));
/*
* We sometimes use an index to refer to a cell in an arena. The index for a
@ -285,17 +335,8 @@ class TenuredChunkBase : public ChunkBase {
const size_t ArenaCellIndexBytes = CellAlignBytes;
const size_t MaxArenaCellIndex = ArenaSize / CellAlignBytes;
const size_t MarkBitmapWordBits = sizeof(MarkBitmapWord) * CHAR_BIT;
constexpr size_t FirstArenaAdjustmentBits =
RoundUp(sizeof(gc::TenuredChunkBase), ArenaSize) / gc::CellBytesPerMarkBit;
static_assert((FirstArenaAdjustmentBits % MarkBitmapWordBits) == 0);
constexpr size_t FirstArenaAdjustmentWords =
FirstArenaAdjustmentBits / MarkBitmapWordBits;
const size_t ChunkStoreBufferOffset = offsetof(ChunkBase, storeBuffer);
const size_t ChunkMarkBitmapOffset = offsetof(TenuredChunkBase, markBits);
const size_t ChunkMarkBitmapOffset = offsetof(ArenaChunkBase, markBits);
// Hardcoded offsets into Arena class.
const size_t ArenaZoneOffset = 2 * sizeof(uint32_t);
@ -535,48 +576,6 @@ inline bool operator!=(JS::GCCellPtr ptr1, JS::GCCellPtr ptr2) {
namespace js {
namespace gc {
/* static */
MOZ_ALWAYS_INLINE void MarkBitmap::getMarkWordAndMask(const TenuredCell* cell,
ColorBit colorBit,
MarkBitmapWord** wordp,
uintptr_t* maskp) {
// Note: the JIT pre-barrier trampolines inline this code. Update
// MacroAssembler::emitPreBarrierFastPath code too when making changes here!
MOZ_ASSERT(size_t(colorBit) < MarkBitsPerCell);
size_t offset = uintptr_t(cell) & ChunkMask;
const size_t bit = offset / CellBytesPerMarkBit + size_t(colorBit);
size_t word = bit / MarkBitmapWordBits - FirstArenaAdjustmentWords;
MOZ_ASSERT(word < WordCount);
*wordp = &bitmap[word];
*maskp = uintptr_t(1) << (bit % MarkBitmapWordBits);
}
MOZ_ALWAYS_INLINE bool MarkBitmap::markBit(const TenuredCell* cell,
ColorBit colorBit) {
MarkBitmapWord* word;
uintptr_t mask;
getMarkWordAndMask(cell, colorBit, &word, &mask);
return *word & mask;
}
MOZ_ALWAYS_INLINE bool MarkBitmap::isMarkedAny(const TenuredCell* cell) {
return markBit(cell, ColorBit::BlackBit) ||
markBit(cell, ColorBit::GrayOrBlackBit);
}
MOZ_ALWAYS_INLINE bool MarkBitmap::isMarkedBlack(const TenuredCell* cell) {
// Return true if BlackBit is set.
return markBit(cell, ColorBit::BlackBit);
}
MOZ_ALWAYS_INLINE bool MarkBitmap::isMarkedGray(const TenuredCell* cell) {
// Return true if GrayOrBlackBit is set and BlackBit is not set.
return !markBit(cell, ColorBit::BlackBit) &&
markBit(cell, ColorBit::GrayOrBlackBit);
}
namespace detail {
// `addr` must be an address within GC-controlled memory. Note that it cannot
@ -593,13 +592,12 @@ static MOZ_ALWAYS_INLINE ChunkBase* GetCellChunkBase(const Cell* cell) {
return GetGCAddressChunkBase(cell);
}
static MOZ_ALWAYS_INLINE TenuredChunkBase* GetCellChunkBase(
static MOZ_ALWAYS_INLINE ArenaChunkBase* GetCellChunkBase(
const TenuredCell* cell) {
MOZ_ASSERT(cell);
auto* chunk =
reinterpret_cast<TenuredChunkBase*>(uintptr_t(cell) & ~ChunkMask);
auto* chunk = reinterpret_cast<ArenaChunkBase*>(uintptr_t(cell) & ~ChunkMask);
MOZ_ASSERT(chunk->runtime);
MOZ_ASSERT(chunk->kind == ChunkKind::TenuredHeap);
MOZ_ASSERT(chunk->kind == ChunkKind::TenuredArenas);
return chunk;
}
@ -616,7 +614,7 @@ static MOZ_ALWAYS_INLINE bool TenuredCellIsMarkedBlack(
MOZ_ASSERT(cell);
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
TenuredChunkBase* chunk = GetCellChunkBase(cell);
ArenaChunkBase* chunk = GetCellChunkBase(cell);
return chunk->markBits.isMarkedBlack(cell);
}
@ -628,14 +626,14 @@ static MOZ_ALWAYS_INLINE bool NonBlackCellIsMarkedGray(
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
MOZ_ASSERT(!TenuredCellIsMarkedBlack(cell));
TenuredChunkBase* chunk = GetCellChunkBase(cell);
ArenaChunkBase* chunk = GetCellChunkBase(cell);
return chunk->markBits.markBit(cell, ColorBit::GrayOrBlackBit);
}
static MOZ_ALWAYS_INLINE bool TenuredCellIsMarkedGray(const TenuredCell* cell) {
MOZ_ASSERT(cell);
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
TenuredChunkBase* chunk = GetCellChunkBase(cell);
ArenaChunkBase* chunk = GetCellChunkBase(cell);
return chunk->markBits.isMarkedGray(cell);
}

View file

@ -1761,43 +1761,41 @@ bool BytecodeEmitter::emitNameIncDec(UnaryNode* incDec, ValueUsage valueUsage) {
return true;
}
bool BytecodeEmitter::emitObjAndKey(ParseNode* exprOrSuper, ParseNode* key,
ElemOpEmitter& eoe) {
if (exprOrSuper->isKind(ParseNodeKind::SuperBase)) {
if (!eoe.prepareForObj()) {
// [stack]
return false;
}
UnaryNode* base = &exprOrSuper->as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) {
// [stack] THIS
return false;
}
if (!eoe.prepareForKey()) {
// [stack] THIS
return false;
}
if (!emitTree(key)) {
// [stack] THIS KEY
return false;
}
return true;
}
bool BytecodeEmitter::emitElemObjAndKey(PropertyByValue* elem,
ElemOpEmitter& eoe) {
ParseNode* exprOrSuper = &elem->expression();
ParseNode* key = &elem->key();
if (!eoe.prepareForObj()) {
// [stack]
return false;
}
if (!emitTree(exprOrSuper)) {
// [stack] OBJ
return false;
if (elem->isSuper()) {
auto* base = &exprOrSuper->as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) {
// [stack] THIS
return false;
}
} else {
if (!emitTree(exprOrSuper)) {
// [stack] OBJ
return false;
}
}
if (!eoe.prepareForKey()) {
// [stack] # if Super
// [stack] THIS? THIS
// [stack] # otherwise
// [stack] OBJ? OBJ
return false;
}
if (!emitTree(key)) {
// [stack] # if Super
// [stack] THIS? THIS KEY
// [stack] # otherwise
// [stack] OBJ? OBJ KEY
return false;
}
@ -1813,12 +1811,6 @@ bool BytecodeEmitter::emitElemOpBase(JSOp op) {
return true;
}
bool BytecodeEmitter::emitElemObjAndKey(PropertyByValue* elem, bool isSuper,
ElemOpEmitter& eoe) {
MOZ_ASSERT(isSuper == elem->expression().isKind(ParseNodeKind::SuperBase));
return emitObjAndKey(&elem->expression(), &elem->key(), eoe);
}
static ElemOpEmitter::Kind ConvertIncDecKind(ParseNodeKind kind) {
switch (kind) {
case ParseNodeKind::PostIncrementExpr:
@ -1857,7 +1849,7 @@ bool BytecodeEmitter::emitElemIncDec(UnaryNode* incDec, ValueUsage valueUsage) {
ElemOpEmitter eoe(
this, ConvertIncDecKind(kind),
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
if (!emitElemObjAndKey(elemExpr, isSuper, eoe)) {
if (!emitElemObjAndKey(elemExpr, eoe)) {
// [stack] # if Super
// [stack] THIS KEY
// [stack] # otherwise
@ -2603,23 +2595,63 @@ bool BytecodeEmitter::emitFunctionScript(FunctionNode* funNode) {
return fse.intoStencil();
}
class js::frontend::DestructuringLHSRef {
struct None {
size_t numReferenceSlots() const { return 0; }
};
mozilla::Variant<None, NameOpEmitter, PropOpEmitter, ElemOpEmitter,
PrivateOpEmitter>
emitter_ = AsVariant(None{});
public:
template <typename T>
void from(T&& emitter) {
emitter_.emplace<T>(std::forward<T>(emitter));
}
template <typename T>
T& emitter() {
return emitter_.as<T>();
}
/**
* Return the number of values pushed onto the stack.
*/
size_t numReferenceSlots() const {
return emitter_.match([](auto& e) { return e.numReferenceSlots(); });
}
};
bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
size_t* emitted) {
DestructuringFlavor flav,
DestructuringLHSRef& lref) {
#ifdef DEBUG
int depth = bytecodeSection().stackDepth();
#endif
switch (target->getKind()) {
case ParseNodeKind::Name:
case ParseNodeKind::ArrayExpr:
case ParseNodeKind::ObjectExpr:
// No need to recurse into ParseNodeKind::Array and ParseNodeKind::Object
// subpatterns here, since emitSetOrInitializeDestructuring does the
// recursion when setting or initializing the value. Getting reference
// doesn't recurse.
*emitted = 0;
// recursion when setting or initializing the value.
break;
case ParseNodeKind::Name: {
auto* name = &target->as<NameNode>();
NameOpEmitter noe(this, name->atom(),
flav == DestructuringFlavor::Assignment
? NameOpEmitter::Kind::SimpleAssignment
: NameOpEmitter::Kind::Initialize);
if (!noe.prepareForRhs()) {
return false;
}
lref.from(std::move(noe));
return true;
}
case ParseNodeKind::ArgumentsLength:
case ParseNodeKind::DotExpr: {
PropertyAccess* prop = &target->as<PropertyAccess>();
@ -2650,8 +2682,7 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
return false;
}
// SUPERBASE was pushed onto THIS in poe.prepareForRhs above.
*emitted = 1 + isSuper;
lref.from(std::move(poe));
break;
}
@ -2662,7 +2693,7 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
isSuper ? ElemOpEmitter::ObjKind::Super
: ElemOpEmitter::ObjKind::Other);
if (!emitElemObjAndKey(elem, isSuper, eoe)) {
if (!emitElemObjAndKey(elem, eoe)) {
// [stack] # if Super
// [stack] THIS KEY
// [stack] # otherwise
@ -2677,8 +2708,7 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
return false;
}
// SUPERBASE was pushed onto KEY in eoe.prepareForRhs above.
*emitted = 2 + isSuper;
lref.from(std::move(eoe));
break;
}
@ -2694,7 +2724,8 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
// [stack] OBJ NAME
return false;
}
*emitted = xoe.numReferenceSlots();
lref.from(std::move(xoe));
break;
}
@ -2709,13 +2740,14 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
MOZ_CRASH("emitDestructuringLHSRef: bad lhs kind");
}
MOZ_ASSERT(bytecodeSection().stackDepth() == depth + int(*emitted));
MOZ_ASSERT(bytecodeSection().stackDepth() ==
depth + int(lref.numReferenceSlots()));
return true;
}
bool BytecodeEmitter::emitSetOrInitializeDestructuring(
ParseNode* target, DestructuringFlavor flav) {
ParseNode* target, DestructuringFlavor flav, DestructuringLHSRef& lref) {
// Now emit the lvalue opcode sequence. If the lvalue is a nested
// destructuring initialiser-form, call ourselves to handle it, then pop
// the matched value. Otherwise emit an lvalue bytecode sequence followed
@ -2732,51 +2764,14 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
break;
case ParseNodeKind::Name: {
auto name = target->as<NameNode>().name();
NameLocation loc = lookupName(name);
NameOpEmitter::Kind kind;
switch (flav) {
case DestructuringFlavor::Declaration:
kind = NameOpEmitter::Kind::Initialize;
break;
// The environment is already pushed by emitDestructuringLHSRef.
// [stack] ENV? VAL
auto& noe = lref.emitter<NameOpEmitter>();
case DestructuringFlavor::Assignment:
kind = NameOpEmitter::Kind::SimpleAssignment;
break;
}
NameOpEmitter noe(this, name, loc, kind);
if (!noe.prepareForRhs()) {
// [stack] V ENV?
return false;
}
if (noe.emittedBindOp()) {
// This is like ordinary assignment, but with one difference.
//
// In `a = b`, we first determine a binding for `a` (using
// JSOp::BindName or JSOp::BindGName), then we evaluate `b`, then
// a JSOp::SetName instruction.
//
// In `[a] = [b]`, per spec, `b` is evaluated first, then we
// determine a binding for `a`. Then we need to do assignment--
// but the operands are on the stack in the wrong order for
// JSOp::SetProp, so we have to add a JSOp::Swap.
//
// In the cases where we are emitting a name op, emit a swap
// because of this.
if (!emit1(JSOp::Swap)) {
// [stack] ENV V
return false;
}
} else {
// In cases of emitting a frame slot or environment slot,
// nothing needs be done.
}
if (!noe.emitAssignment()) {
// [stack] V
// [stack] VAL
return false;
}
break;
}
@ -2787,16 +2782,11 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
// [stack] THIS SUPERBASE VAL
// [stack] # otherwise
// [stack] OBJ VAL
PropertyAccess* prop = &target->as<PropertyAccess>();
bool isSuper = prop->isSuper();
PropOpEmitter poe(this, PropOpEmitter::Kind::SimpleAssignment,
isSuper ? PropOpEmitter::ObjKind::Super
: PropOpEmitter::ObjKind::Other);
if (!poe.skipObjAndRhs()) {
return false;
}
// [stack] # VAL
auto& poe = lref.emitter<PropOpEmitter>();
auto* prop = &target->as<PropertyAccess>();
if (!poe.emitAssignment(prop->key().atom())) {
// [stack] # VAL
return false;
}
break;
@ -2808,15 +2798,8 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
// [stack] THIS KEY SUPERBASE VAL
// [stack] # otherwise
// [stack] OBJ KEY VAL
PropertyByValue* elem = &target->as<PropertyByValue>();
bool isSuper = elem->isSuper();
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
isSuper ? ElemOpEmitter::ObjKind::Super
: ElemOpEmitter::ObjKind::Other);
if (!eoe.skipObjAndKeyAndRhs()) {
return false;
}
auto& eoe = lref.emitter<ElemOpEmitter>();
if (!eoe.emitAssignment()) {
// [stack] VAL
return false;
@ -2827,12 +2810,8 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
case ParseNodeKind::PrivateMemberExpr: {
// The reference is already pushed by emitDestructuringLHSRef.
// [stack] OBJ NAME VAL
PrivateMemberAccess* privateExpr = &target->as<PrivateMemberAccess>();
PrivateOpEmitter xoe(this, PrivateOpEmitter::Kind::SimpleAssignment,
privateExpr->privateName().name());
if (!xoe.skipReference()) {
return false;
}
auto& xoe = lref.emitter<PrivateOpEmitter>();
if (!xoe.emitAssignment()) {
// [stack] VAL
return false;
@ -3383,6 +3362,7 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
idx += 1;
continue;
}
MOZ_ASSERT(member->isKind(ParseNodeKind::Name));
if (!emit1(JSOp::Dup)) {
// [stack] LENGTH OBJ OBJ
@ -3440,7 +3420,13 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
return false;
}
if (!emitSetOrInitializeDestructuring(member, flav)) {
DestructuringLHSRef lref;
if (!emitDestructuringLHSRef(member, flav, lref)) {
// [stack] LENGTH OBJ
return false;
}
if (!emitSetOrInitializeDestructuring(member, flav, lref)) {
// [stack] LENGTH OBJ
return false;
}
@ -3527,14 +3513,12 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
pndefault = subpattern->as<AssignmentNode>().right();
}
// Number of stack slots emitted for the LHS reference.
size_t emitted = 0;
// Spec requires LHS reference to be evaluated first.
DestructuringLHSRef lref;
bool isElision = lhsPattern->isKind(ParseNodeKind::Elision);
if (!isElision) {
auto emitLHSRef = [lhsPattern, &emitted](BytecodeEmitter* bce) {
return bce->emitDestructuringLHSRef(lhsPattern, &emitted);
auto emitLHSRef = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
return bce->emitDestructuringLHSRef(lhsPattern, flav, lref);
// [stack] ... OBJ NEXT ITER DONE LREF*
};
if (!wrapWithDestructuringTryNote(tryNoteDepth, emitLHSRef)) {
@ -3542,6 +3526,9 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
}
}
// Number of stack slots emitted for the LHS reference.
size_t emitted = lref.numReferenceSlots();
// Pick the DONE value to the top of the stack.
if (emitted) {
if (!emitPickN(emitted)) {
@ -3624,8 +3611,8 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
return false;
}
auto emitAssignment = [lhsPattern, flav](BytecodeEmitter* bce) {
return bce->emitSetOrInitializeDestructuring(lhsPattern, flav);
auto emitAssignment = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
return bce->emitSetOrInitializeDestructuring(lhsPattern, flav, lref);
// [stack] ... OBJ NEXT ITER TRUE
};
if (!wrapWithDestructuringTryNote(tryNoteDepth, emitAssignment)) {
@ -3749,8 +3736,8 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
}
if (!isElision) {
auto emitAssignment = [lhsPattern, flav](BytecodeEmitter* bce) {
return bce->emitSetOrInitializeDestructuring(lhsPattern, flav);
auto emitAssignment = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
return bce->emitSetOrInitializeDestructuring(lhsPattern, flav, lref);
// [stack] ... OBJ NEXT ITER DONE
};
@ -3841,6 +3828,7 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
for (ParseNode* member : pattern->contents()) {
ParseNode* subpattern;
bool hasKeyOnStack = false;
if (member->isKind(ParseNodeKind::MutateProto) ||
member->isKind(ParseNodeKind::Spread)) {
subpattern = member->as<UnaryNode>().kid();
@ -3851,6 +3839,16 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
MOZ_ASSERT(member->isKind(ParseNodeKind::PropertyDefinition) ||
member->isKind(ParseNodeKind::Shorthand));
subpattern = member->as<BinaryNode>().right();
// Computed property names are evaluated before the subpattern.
ParseNode* key = member->as<BinaryNode>().left();
if (key->isKind(ParseNodeKind::ComputedName)) {
if (!emitComputedPropertyName(&key->as<UnaryNode>())) {
// [stack] ... SET? RHS KEY
return false;
}
hasKeyOnStack = true;
}
}
ParseNode* lhs = subpattern;
@ -3860,18 +3858,19 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
pndefault = subpattern->as<AssignmentNode>().right();
}
// Number of stack slots emitted for the LHS reference.
size_t emitted = 0;
// Spec requires LHS reference to be evaluated first.
if (!emitDestructuringLHSRef(lhs, &emitted)) {
// [stack] ... SET? RHS LREF*
DestructuringLHSRef lref;
if (!emitDestructuringLHSRef(lhs, flav, lref)) {
// [stack] ... SET? RHS KEY? LREF*
return false;
}
// Number of stack slots emitted for the LHS reference.
size_t emitted = lref.numReferenceSlots();
// Duplicate the value being destructured to use as a reference base.
if (!emitDupAt(emitted)) {
// [stack] ... SET? RHS LREF* RHS
if (!emitDupAt(emitted + hasKeyOnStack)) {
// [stack] ... SET? RHS KEY? LREF* RHS
return false;
}
@ -3908,7 +3907,7 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
}
// Destructure TARGET per this member's lhs.
if (!emitSetOrInitializeDestructuring(lhs, flav)) {
if (!emitSetOrInitializeDestructuring(lhs, flav, lref)) {
// [stack] ... RHS
return false;
}
@ -3947,8 +3946,9 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
// Otherwise this is a computed property name. BigInt keys are parsed
// as (synthetic) computed property names, too.
MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName));
MOZ_ASSERT(hasKeyOnStack);
if (!emitComputedPropertyName(&key->as<UnaryNode>())) {
if (!emit2(JSOp::Pick, emitted + 1)) {
// [stack] ... SET? RHS LREF* RHS KEY
return false;
}
@ -3994,7 +3994,7 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
}
// Destructure PROP per this member's lhs.
if (!emitSetOrInitializeDestructuring(lhs, flav)) {
if (!emitSetOrInitializeDestructuring(lhs, flav, lref)) {
// [stack] ... SET? RHS
return false;
}
@ -4447,7 +4447,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs,
: ElemOpEmitter::Kind::SimpleAssignment,
isSuper ? ElemOpEmitter::ObjKind::Super
: ElemOpEmitter::ObjKind::Other);
if (!emitElemObjAndKey(elem, isSuper, *eoe)) {
if (!emitElemObjAndKey(elem, *eoe)) {
// [stack] # if Super
// [stack] THIS KEY
// [stack] # otherwise
@ -4763,7 +4763,7 @@ bool BytecodeEmitter::emitShortCircuitAssignment(AssignmentNode* node) {
isSuper ? ElemOpEmitter::ObjKind::Super
: ElemOpEmitter::ObjKind::Other);
if (!emitElemObjAndKey(elem, isSuper, *eoe)) {
if (!emitElemObjAndKey(elem, *eoe)) {
// [stack] # if Super
// [stack] THIS KEY
// [stack] # otherwise
@ -7273,20 +7273,20 @@ bool BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode) {
propExpr->as<PropertyAccess>().isSuper()
? PropOpEmitter::ObjKind::Super
: PropOpEmitter::ObjKind::Other);
if (!poe.prepareForObj()) {
return false;
}
if (propExpr->isSuper()) {
// The expression |delete super.foo;| has to evaluate |super.foo|,
// which could throw if |this| hasn't yet been set by a |super(...)|
// call or the super-base is not an object, before throwing a
// ReferenceError for attempting to delete a super-reference.
UnaryNode* base = &propExpr->expression().as<UnaryNode>();
// The expression |delete super.foo;| has to evaluate |super.foo|, which
// could throw if |this| hasn't yet been set by a |super(...)| call.
auto* base = &propExpr->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) {
// [stack] THIS
return false;
}
} else {
if (!poe.prepareForObj()) {
return false;
}
if (!emitPropLHS(propExpr)) {
// [stack] OBJ
return false;
@ -7307,44 +7307,21 @@ bool BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode) {
bool BytecodeEmitter::emitDeleteElement(UnaryNode* deleteNode) {
MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteElemExpr));
PropertyByValue* elemExpr = &deleteNode->kid()->as<PropertyByValue>();
auto* elemExpr = &deleteNode->kid()->as<PropertyByValue>();
bool isSuper = elemExpr->isSuper();
DebugOnly<bool> isPrivate =
elemExpr->key().isKind(ParseNodeKind::PrivateName);
MOZ_ASSERT(!isPrivate);
MOZ_ASSERT(!elemExpr->key().isKind(ParseNodeKind::PrivateName));
ElemOpEmitter eoe(
this, ElemOpEmitter::Kind::Delete,
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
if (isSuper) {
// The expression |delete super[foo];| has to evaluate |super[foo]|,
// which could throw if |this| hasn't yet been set by a |super(...)|
// call, or trigger side-effects when evaluating ToPropertyKey(foo),
// or also throw when the super-base is not an object, before throwing
// a ReferenceError for attempting to delete a super-reference.
if (!eoe.prepareForObj()) {
// [stack]
return false;
}
UnaryNode* base = &elemExpr->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) {
// [stack] THIS
return false;
}
if (!eoe.prepareForKey()) {
// [stack] THIS
return false;
}
if (!emitTree(&elemExpr->key())) {
// [stack] THIS KEY
return false;
}
} else {
if (!emitElemObjAndKey(elemExpr, false, eoe)) {
// [stack] OBJ KEY
return false;
}
if (!emitElemObjAndKey(elemExpr, eoe)) {
// [stack] # if Super
// [stack] THIS KEY
// [stack] # otherwise
// [stack] OBJ KEY
return false;
}
if (!eoe.emitDelete()) {
// [stack] # if Super
// [stack] THIS
@ -8187,7 +8164,7 @@ bool BytecodeEmitter::emitCalleeAndThis(ParseNode* callee, CallNode* maybeCall,
bool isSuper = elem->isSuper();
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
if (!emitElemObjAndKey(elem, isSuper, eoe)) {
if (!emitElemObjAndKey(elem, eoe)) {
// [stack] # if Super
// [stack] THIS? THIS KEY
// [stack] # otherwise
@ -12740,7 +12717,7 @@ bool BytecodeEmitter::emitTree(
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
isSuper ? ElemOpEmitter::ObjKind::Super
: ElemOpEmitter::ObjKind::Other);
if (!emitElemObjAndKey(elem, isSuper, eoe)) {
if (!emitElemObjAndKey(elem, eoe)) {
// [stack] # if Super
// [stack] THIS KEY
// [stack] # otherwise

View file

@ -55,6 +55,7 @@ namespace frontend {
class BytecodeOffset;
class CallOrNewEmitter;
class ClassEmitter;
class DestructuringLHSRef;
class ElemOpEmitter;
class EmitterScope;
class ErrorReporter;
@ -751,9 +752,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
[[nodiscard]] bool emitComputedPropertyName(UnaryNode* computedPropName);
[[nodiscard]] bool emitObjAndKey(ParseNode* exprOrSuper, ParseNode* key,
ElemOpEmitter& eoe);
// Emit bytecode to put operands for a JSOp::GetElem/CallElem/SetElem/DelElem
// opcode onto the stack in the right order. In the case of SetElem, the
// value to be assigned must already be pushed.
@ -761,7 +759,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
[[nodiscard]] bool emitElemOperands(PropertyByValue* elem,
EmitElemOption opts);
[[nodiscard]] bool emitElemObjAndKey(PropertyByValue* elem, bool isSuper,
[[nodiscard]] bool emitElemObjAndKey(PropertyByValue* elem,
ElemOpEmitter& eoe);
[[nodiscard]] bool emitElemOpBase(JSOp op);
@ -790,16 +788,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
// If the lhs expression is object property |OBJ.prop|, it emits |OBJ|.
// If it's object element |OBJ[ELEM]|, it emits |OBJ| and |ELEM|.
// If there's nothing to evaluate for the reference, it emits nothing.
// |emitted| parameter receives the number of values pushed onto the stack.
[[nodiscard]] bool emitDestructuringLHSRef(ParseNode* target,
size_t* emitted);
DestructuringFlavor flav,
DestructuringLHSRef& lref);
// emitSetOrInitializeDestructuring assumes the lhs expression's reference
// and the to-be-destructured value has been pushed on the stack. It emits
// code to destructure a single lhs expression (either a name or a compound
// []/{} expression).
[[nodiscard]] bool emitSetOrInitializeDestructuring(ParseNode* target,
DestructuringFlavor flav);
[[nodiscard]] bool emitSetOrInitializeDestructuring(
ParseNode* target, DestructuringFlavor flav, DestructuringLHSRef& lref);
// emitDestructuringObjRestExclusionSet emits the property exclusion set
// for the rest-property in an object pattern.

View file

@ -48,31 +48,38 @@ bool ElemOpEmitter::prepareForKey() {
bool ElemOpEmitter::emitGet() {
MOZ_ASSERT(state_ == State::Key);
// Inc/dec and compound assignment use the KEY twice, but if it's an object,
// it must be converted ToPropertyKey only once, per spec.
if (isIncDec() || isCompoundAssignment()) {
if (!bce_->emit1(JSOp::ToPropertyKey)) {
// [stack] # if Super
// [stack] THIS KEY
// [stack] # otherwise
// [stack] OBJ KEY
return false;
}
}
if (isSuper()) {
if (!bce_->emitSuperBase()) {
// [stack] THIS? THIS KEY SUPERBASE
return false;
}
}
// Inc/dec and compound assignment use the KEY twice, but if it's an object,
// it must be converted by ToPropertyKey only once, per spec.
if (isIncDec() || isCompoundAssignment()) {
if (isSuper()) {
if (!bce_->emit1(JSOp::Swap)) {
// [stack] THIS SUPERBASE KEY
return false;
}
if (!bce_->emit1(JSOp::ToPropertyKey)) {
// [stack] THIS SUPERBASE KEY
return false;
}
if (!bce_->emit1(JSOp::Swap)) {
// [stack] THIS KEY SUPERBASE
return false;
}
if (!bce_->emitDupAt(2, 3)) {
// [stack] THIS KEY SUPERBASE THIS KEY SUPERBASE
return false;
}
} else {
if (!bce_->emit1(JSOp::ToPropertyKey)) {
// [stack] OBJ KEY
return false;
}
if (!bce_->emit1(JSOp::Dup2)) {
// [stack] OBJ KEY OBJ KEY
return false;
@ -131,25 +138,11 @@ bool ElemOpEmitter::prepareForRhs() {
return true;
}
bool ElemOpEmitter::skipObjAndKeyAndRhs() {
MOZ_ASSERT(state_ == State::Start);
MOZ_ASSERT(isSimpleAssignment() || isPropInit());
#ifdef DEBUG
state_ = State::Rhs;
#endif
return true;
}
bool ElemOpEmitter::emitDelete() {
MOZ_ASSERT(state_ == State::Key);
MOZ_ASSERT(isDelete());
if (isSuper()) {
if (!bce_->emit1(JSOp::ToPropertyKey)) {
// [stack] THIS KEY
return false;
}
if (!bce_->emitSuperBase()) {
// [stack] THIS KEY SUPERBASE
return false;

View file

@ -9,6 +9,8 @@
#include "mozilla/Attributes.h"
#include <stddef.h>
namespace js {
namespace frontend {
@ -142,38 +144,36 @@ class MOZ_STACK_CLASS ElemOpEmitter {
#ifdef DEBUG
// The state of this emitter.
//
// skipObjAndKeyAndRhs
// +------------------------------------------------+
// | |
// +-------+ | prepareForObj +-----+ prepareForKey +-----+ |
// | Start |-+-------------->| Obj |-------------->| Key |-+ |
// +-------+ +-----+ +-----+ | |
// | |
// +-------------------------------------------------------+ |
// | |
// | [Get] |
// | [Call] |
// | emitGet +-----+ |
// +---------->| Get | |
// | +-----+ |
// | |
// | [Delete] |
// | emitDelete +--------+ |
// +------------->| Delete | |
// | +--------+ |
// | |
// | [PostIncrement] |
// | [PreIncrement] |
// | [PostDecrement] |
// | [PreDecrement] |
// | emitIncDec +--------+ |
// +------------->| IncDec | |
// | +--------+ |
// | +-------------------+
// | [SimpleAssignment] |
// | [PropInit] |
// | prepareForRhs v +-----+
// +--------------------->+-------------->+->| Rhs |-+
//
// +-------+ prepareForObj +-----+ prepareForKey +-----+
// | Start |---------------->| Obj |-------------->| Key |-+
// +-------+ +-----+ +-----+ |
// |
// +-------------------------------------------------------+
// |
// | [Get]
// | [Call]
// | emitGet +-----+
// +---------->| Get |
// | +-----+
// |
// | [Delete]
// | emitDelete +--------+
// +------------->| Delete |
// | +--------+
// |
// | [PostIncrement]
// | [PreIncrement]
// | [PostDecrement]
// | [PreDecrement]
// | emitIncDec +--------+
// +------------->| IncDec |
// | +--------+
// |
// | [SimpleAssignment]
// | [PropInit]
// | prepareForRhs +-----+
// +--------------------->+----------------->| Rhs |-+
// | ^ +-----+ |
// | | |
// | | +-------------+
@ -200,7 +200,7 @@ class MOZ_STACK_CLASS ElemOpEmitter {
// After calling emitIncDec.
IncDec,
// After calling prepareForRhs or skipObjAndKeyAndRhs.
// After calling prepareForRhs.
Rhs,
// After calling emitAssignment.
@ -252,13 +252,14 @@ class MOZ_STACK_CLASS ElemOpEmitter {
[[nodiscard]] bool emitGet();
[[nodiscard]] bool prepareForRhs();
[[nodiscard]] bool skipObjAndKeyAndRhs();
[[nodiscard]] bool emitDelete();
[[nodiscard]] bool emitAssignment();
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
size_t numReferenceSlots() const { return 2 + isSuper(); }
};
} /* namespace frontend */

View file

@ -9,6 +9,8 @@
#include "mozilla/Attributes.h"
#include <stddef.h>
#include "frontend/NameAnalysisTypes.h"
#include "frontend/ParserAtom.h" // TaggedParserAtomIndex
#include "vm/SharedStencil.h" // GCThingIndex
@ -174,6 +176,8 @@ class MOZ_STACK_CLASS NameOpEmitter {
[[nodiscard]] bool prepareForRhs();
[[nodiscard]] bool emitAssignment();
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
size_t numReferenceSlots() const { return emittedBindOp(); }
};
} /* namespace frontend */

View file

@ -100,19 +100,6 @@ bool PrivateOpEmitter::emitReference() {
return true;
}
bool PrivateOpEmitter::skipReference() {
MOZ_ASSERT(state_ == State::Start);
if (!init()) {
return false;
}
#ifdef DEBUG
state_ = State::Reference;
#endif
return true;
}
bool PrivateOpEmitter::emitGet() {
MOZ_ASSERT(state_ == State::Reference);

View file

@ -114,8 +114,7 @@ class MOZ_STACK_CLASS PrivateOpEmitter {
#ifdef DEBUG
// The state of this emitter.
//
// emitReference
// +-------+ skipReference +-----------+
// +-------+ emitReference +-----------+
// | Start |---------------->| Reference |
// +-------+ +-----+-----+
// |
@ -144,7 +143,7 @@ class MOZ_STACK_CLASS PrivateOpEmitter {
// The initial state.
Start,
// After calling emitReference or skipReference.
// After calling emitReference.
Reference,
// After calling emitGet.
@ -216,13 +215,12 @@ class MOZ_STACK_CLASS PrivateOpEmitter {
[[nodiscard]] bool emitBrandCheck();
[[nodiscard]] bool emitReference();
[[nodiscard]] bool skipReference();
[[nodiscard]] bool emitGet();
[[nodiscard]] bool emitGetForCallOrNew();
[[nodiscard]] bool emitAssignment();
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
[[nodiscard]] size_t numReferenceSlots() { return 2; }
size_t numReferenceSlots() const { return 2; }
};
} /* namespace frontend */

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