Update On Fri Sep 6 20:50:23 CEST 2024
This commit is contained in:
parent
5822b45acc
commit
b3a8d77781
2384 changed files with 7853 additions and 3542 deletions
|
@ -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", "");
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"]
|
||||
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -5,4 +5,4 @@ prefs = [
|
|||
]
|
||||
|
||||
["../browser_startup_images.js"]
|
||||
skip-if = ["!debug"]
|
||||
run-if = ["debug"]
|
||||
|
|
|
@ -5,4 +5,4 @@ prefs = [
|
|||
]
|
||||
|
||||
["../browser_startup_images.js"]
|
||||
skip-if = ["!debug"]
|
||||
run-if = ["debug"]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[DEFAULT]
|
||||
skip-if = ["!crashreporter"]
|
||||
run-if = ["crashreporter"]
|
||||
support-files = [
|
||||
"head.js",
|
||||
"file_contains_emptyiframe.html",
|
||||
|
|
|
@ -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"]
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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"]'
|
||||
)) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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",
|
||||
{
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -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]] });
|
||||
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
|
@ -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" },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -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" },
|
||||
],
|
||||
},
|
||||
|
|
|
@ -70,7 +70,7 @@ add_heuristic_tests([
|
|||
{
|
||||
fields: [
|
||||
{ fieldName: "cc-number", reason: "autocomplete" },
|
||||
//{ fieldName: "cc-csc", reason: "autocomplete" },
|
||||
{ fieldName: "cc-csc", reason: "autocomplete" },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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
|
||||
],
|
||||
},
|
||||
|
|
|
@ -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" },
|
||||
],
|
||||
|
|
|
@ -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" },
|
||||
],
|
||||
|
|
|
@ -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" },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@ add_heuristic_tests(
|
|||
{ fieldName: "cc-number", reason: "fathom" },
|
||||
{ fieldName: "cc-exp-month" },
|
||||
{ fieldName: "cc-exp-year" },
|
||||
{ fieldName: "cc-csc" },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -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" },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -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" },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -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"},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -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"},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -42,6 +42,7 @@ add_heuristic_tests(
|
|||
{ fieldName: "cc-exp-month" },
|
||||
{ fieldName: "cc-exp-year" },
|
||||
{ fieldName: "cc-number" },
|
||||
{ fieldName: "cc-csc" },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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
|
||||
],
|
||||
},
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
},
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.) */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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");
|
||||
});
|
13
devtools/client/webconsole/test/browser/test-json-mime.html
Normal file
13
devtools/client/webconsole/test/browser/test-json-mime.html
Normal 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>
|
|
@ -0,0 +1 @@
|
|||
{ "test": 123 }
|
|
@ -0,0 +1 @@
|
|||
Content-Type: application/json
|
|
@ -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);
|
||||
|
|
|
@ -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()|.
|
||||
|
|
|
@ -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 signal’s 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 signal’s 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 signal’s 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 signal’s 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 dependentSignal’s abort reason to signal’s 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; }
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -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
7
gradlew
vendored
|
@ -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
2
gradlew.bat
vendored
|
@ -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 ##########################################################################
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue