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
|
// 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);
|
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
|
// Spin the cursor while the page is loading
|
||||||
pref("browser.spin_cursor_while_busy", false);
|
pref("browser.spin_cursor_while_busy", false);
|
||||||
|
|
||||||
|
@ -947,9 +950,6 @@ pref("browser.tabs.tabMinWidth", 76);
|
||||||
// of the text at small font sizes.
|
// 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");
|
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
|
// 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
|
// browser.link.open_newwindow being set to 3 and target="_blank" etc are
|
||||||
// closed:
|
// closed:
|
||||||
|
@ -1230,15 +1230,9 @@ pref("network.manage-offline-status", true);
|
||||||
|
|
||||||
// We want to make sure mail URLs are handled externally...
|
// We want to make sure mail URLs are handled externally...
|
||||||
pref("network.protocol-handler.external.mailto", true); // for mail
|
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
|
// ...without warning dialogs
|
||||||
pref("network.protocol-handler.warn-external.mailto", false);
|
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
|
// By default, all protocol handlers are exposed. This means that
|
||||||
// the browser will respond to openURL commands for all URL types.
|
// 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.
|
// Activates preloading of the new tab url.
|
||||||
pref("browser.newtab.preload", true);
|
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
|
// Weather widget for newtab
|
||||||
pref("browser.newtabpage.activity-stream.showWeather", true);
|
pref("browser.newtabpage.activity-stream.showWeather", true);
|
||||||
pref("browser.newtabpage.activity-stream.weather.query", "");
|
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(
|
customElements.define(
|
||||||
"addon-progress-notification",
|
"addon-progress-notification",
|
||||||
class MozAddonProgressNotification extends customElements.get(
|
class MozAddonProgressNotification extends customElements.get(
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<hbox flex="1" id="browser">
|
<hbox flex="1" id="browser">
|
||||||
<box context="sidebar-context-menu" id="sidebar-main" hidden="true">
|
<box context="sidebar-context-menu" id="sidebar-main" hidden="true">
|
||||||
<html:sidebar-main flex="1">
|
<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>
|
</html:sidebar-main>
|
||||||
</box>
|
</box>
|
||||||
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
|
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
|
||||||
|
|
|
@ -111,20 +111,14 @@
|
||||||
<popupnotificationcontent id="addon-install-confirmation-content" orient="vertical"/>
|
<popupnotificationcontent id="addon-install-confirmation-content" orient="vertical"/>
|
||||||
</popupnotification>
|
</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">
|
<popupnotificationcontent class="addon-webext-perm-notification-content" orient="vertical">
|
||||||
<description id="addon-webext-perm-text" class="addon-webext-perm-text"/>
|
<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-intro" class="addon-webext-perm-text"/>
|
||||||
<label id="addon-webext-perm-single-entry" class="addon-webext-perm-single-entry"/>
|
<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"/>
|
<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>
|
</popupnotificationcontent>
|
||||||
</popupnotification>
|
</popupnotification>
|
||||||
|
|
||||||
|
|
|
@ -244,11 +244,11 @@ skip-if = ["os == 'linux' && !debug"] # Bug 1556066
|
||||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||||
|
|
||||||
["browser_bug1261299.js"]
|
["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.
|
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||||
|
|
||||||
["browser_bug1297539.js"]
|
["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.
|
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||||
|
|
||||||
["browser_bug1299667.js"]
|
["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.
|
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||||
|
|
||||||
["browser_datachoices_notification.js"]
|
["browser_datachoices_notification.js"]
|
||||||
skip-if = [
|
run-if = ["datareporting"]
|
||||||
"!datareporting",
|
skip-if = ["verify && !debug && os == 'win'"]
|
||||||
"verify && !debug && os == 'win'",
|
|
||||||
]
|
|
||||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||||
|
|
||||||
["browser_documentnavigation.js"]
|
["browser_documentnavigation.js"]
|
||||||
|
@ -397,10 +395,8 @@ support-files = [
|
||||||
|
|
||||||
["browser_remoteTroubleshoot.js"]
|
["browser_remoteTroubleshoot.js"]
|
||||||
https_first_disabled = true
|
https_first_disabled = true
|
||||||
skip-if = [
|
run-if = ["updater"]
|
||||||
"!updater",
|
skip-if = ["os == 'linux' && asan"] # Bug 1711507
|
||||||
"os == 'linux' && asan", # Bug 1711507
|
|
||||||
]
|
|
||||||
reason = "depends on UpdateUtils .Locale"
|
reason = "depends on UpdateUtils .Locale"
|
||||||
support-files = ["test_remoteTroubleshoot.html"]
|
support-files = ["test_remoteTroubleshoot.html"]
|
||||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
# 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.
|
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||||
|
|
||||||
["browser_restore_isAppTab.js"]
|
["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.
|
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||||
|
|
||||||
["browser_save_link-perwindowpb.js"]
|
["browser_save_link-perwindowpb.js"]
|
||||||
|
|
|
@ -14,7 +14,10 @@ https_first_disabled = true
|
||||||
run-if = ["os == 'mac'"] # Mac only feature
|
run-if = ["os == 'mac'"] # Mac only feature
|
||||||
|
|
||||||
["browser_history_recently_closed_tabs.js"]
|
["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"]
|
support-files = ["file_shareurl.html"]
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,8 @@ support-files = ["!/browser/components/downloads/test/browser/head.js"]
|
||||||
|
|
||||||
["browser_preferences_usage.js"]
|
["browser_preferences_usage.js"]
|
||||||
https_first_disabled = true
|
https_first_disabled = true
|
||||||
|
run-if = ["debug"]
|
||||||
skip-if = [
|
skip-if = [
|
||||||
"!debug",
|
|
||||||
"apple_catalina", # platform migration
|
"apple_catalina", # platform migration
|
||||||
"socketprocess_networking",
|
"socketprocess_networking",
|
||||||
]
|
]
|
||||||
|
@ -52,7 +52,7 @@ skip-if = [
|
||||||
support-files = ["file_empty.html"]
|
support-files = ["file_empty.html"]
|
||||||
|
|
||||||
["browser_startup_content_subframe.js"]
|
["browser_startup_content_subframe.js"]
|
||||||
skip-if = ["!fission"]
|
run-if = ["fission"]
|
||||||
support-files = [
|
support-files = [
|
||||||
"file_empty.html",
|
"file_empty.html",
|
||||||
"StartupContentSubframe.sys.mjs",
|
"StartupContentSubframe.sys.mjs",
|
||||||
|
@ -65,7 +65,10 @@ run-if = [
|
||||||
]
|
]
|
||||||
|
|
||||||
["browser_startup_hiddenwindow.js"]
|
["browser_startup_hiddenwindow.js"]
|
||||||
skip-if = ["os == 'mac'"]
|
run-if = [
|
||||||
|
"os == 'linux'",
|
||||||
|
"os == 'win'",
|
||||||
|
]
|
||||||
|
|
||||||
["browser_tabclose.js"]
|
["browser_tabclose.js"]
|
||||||
skip-if = [
|
skip-if = [
|
||||||
|
|
|
@ -5,4 +5,4 @@ prefs = [
|
||||||
]
|
]
|
||||||
|
|
||||||
["../browser_startup_images.js"]
|
["../browser_startup_images.js"]
|
||||||
skip-if = ["!debug"]
|
run-if = ["debug"]
|
||||||
|
|
|
@ -5,4 +5,4 @@ prefs = [
|
||||||
]
|
]
|
||||||
|
|
||||||
["../browser_startup_images.js"]
|
["../browser_startup_images.js"]
|
||||||
skip-if = ["!debug"]
|
run-if = ["debug"]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
skip-if = ["!crashreporter"]
|
run-if = ["crashreporter"]
|
||||||
support-files = [
|
support-files = [
|
||||||
"head.js",
|
"head.js",
|
||||||
"file_contains_emptyiframe.html",
|
"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_pointerevent.js"]
|
||||||
|
|
||||||
["browser_permissions_unsigned.js"]
|
["browser_permissions_unsigned.js"]
|
||||||
skip-if = [
|
run-if = ["!require_signing"]
|
||||||
"require_signing",
|
skip-if = ["a11y_checks"] # Bugs 1858041 and 1854461 to investigate intermittent a11y_checks results (fails on Autoland, passes on Try)
|
||||||
"a11y_checks", # Bugs 1858041 and 1854461 to investigate intermittent a11y_checks results (fails on Autoland, passes on Try)
|
|
||||||
]
|
|
||||||
|
|
||||||
["browser_update_checkForUpdates.js"]
|
["browser_update_checkForUpdates.js"]
|
||||||
|
|
||||||
|
|
|
@ -49,14 +49,12 @@ add_task(async function test_tab_switch_dismiss() {
|
||||||
content.wrappedJSObject.installMozAM(url);
|
content.wrappedJSObject.installMozAM(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
await promisePopupNotificationShown("addon-webext-permissions");
|
const panel = await promisePopupNotificationShown("addon-webext-permissions");
|
||||||
|
|
||||||
assertPermissionsListCount({ grantedPermissionsCount: 5 });
|
assertPermissionsListCount({ grantedPermissionsCount: 5 });
|
||||||
|
|
||||||
let permsLearnMore = document.getElementById("addon-webext-perm-info");
|
let permsLearnMore = panel.querySelector(
|
||||||
ok(
|
".popup-notification-learnmore-link"
|
||||||
BrowserTestUtils.isVisible(permsLearnMore),
|
|
||||||
"Learn more link is shown on Permission popup"
|
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
permsLearnMore.href,
|
permsLearnMore.href,
|
||||||
|
@ -64,6 +62,10 @@ add_task(async function test_tab_switch_dismiss() {
|
||||||
"extension-permissions",
|
"extension-permissions",
|
||||||
"Learn more link has desired URL"
|
"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.
|
// Switching tabs dismisses the notification and cancels the install.
|
||||||
let switchTo = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
let switchTo = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
||||||
|
|
|
@ -230,9 +230,9 @@ function checkNotification(
|
||||||
expectIncognitoCheckboxHidden
|
expectIncognitoCheckboxHidden
|
||||||
) {
|
) {
|
||||||
let icon = panel.getAttribute("icon");
|
let icon = panel.getAttribute("icon");
|
||||||
|
let learnMoreLink = panel.querySelector(".popup-notification-learnmore-link");
|
||||||
let ul = document.getElementById("addon-webext-perm-list");
|
let ul = document.getElementById("addon-webext-perm-list");
|
||||||
let singleDataEl = document.getElementById("addon-webext-perm-single-entry");
|
let singleDataEl = document.getElementById("addon-webext-perm-single-entry");
|
||||||
let learnMoreLink = document.getElementById("addon-webext-perm-info");
|
|
||||||
|
|
||||||
if (checkIcon instanceof RegExp) {
|
if (checkIcon instanceof RegExp) {
|
||||||
ok(
|
ok(
|
||||||
|
|
|
@ -110,7 +110,8 @@ export var ToolbarContextMenu = {
|
||||||
parent.classList.contains("customization-target") ||
|
parent.classList.contains("customization-target") ||
|
||||||
parent.getAttribute("overflowfortoolbar") || // Needs to work in the overflow list as well.
|
parent.getAttribute("overflowfortoolbar") || // Needs to work in the overflow list as well.
|
||||||
parent.localName == "toolbarpaletteitem" ||
|
parent.localName == "toolbarpaletteitem" ||
|
||||||
parent.localName == "toolbar"
|
parent.localName == "toolbar" ||
|
||||||
|
parent.id == "vertical-tabs"
|
||||||
) {
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -126,36 +127,50 @@ export var ToolbarContextMenu = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MozXULElement.insertFTLIfNeeded("browser/toolbarContextMenu.ftl");
|
let showTabStripItems = toolbarItem?.id == "tabbrowser-tabs";
|
||||||
let firstMenuItem = aInsertPoint || popup.firstElementChild;
|
let isVerticalTabStripMenu =
|
||||||
let toolbarNodes = gNavToolbox.querySelectorAll("toolbar");
|
showTabStripItems && toolbarItem.parentElement.id == "vertical-tabs";
|
||||||
for (let toolbar of toolbarNodes) {
|
|
||||||
if (!toolbar.hasAttribute("toolbarname")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toolbar.id == "PersonalToolbar") {
|
if (aInsertPoint) {
|
||||||
let menu = BookmarkingUI.buildBookmarksToolbarSubmenu(toolbar);
|
aInsertPoint.hidden = isVerticalTabStripMenu;
|
||||||
popup.insertBefore(menu, firstMenuItem);
|
}
|
||||||
} else {
|
document.getElementById("toolbar-context-customize").hidden =
|
||||||
let menuItem = document.createXULElement("menuitem");
|
isVerticalTabStripMenu;
|
||||||
menuItem.setAttribute("id", "toggle_" + toolbar.id);
|
|
||||||
menuItem.setAttribute("toolbarId", toolbar.id);
|
if (!isVerticalTabStripMenu) {
|
||||||
menuItem.setAttribute("type", "checkbox");
|
MozXULElement.insertFTLIfNeeded("browser/toolbarContextMenu.ftl");
|
||||||
menuItem.setAttribute("label", toolbar.getAttribute("toolbarname"));
|
let firstMenuItem = aInsertPoint || popup.firstElementChild;
|
||||||
let hidingAttribute =
|
let toolbarNodes = gNavToolbox.querySelectorAll("toolbar");
|
||||||
toolbar.getAttribute("type") == "menubar" ? "autohide" : "collapsed";
|
for (let toolbar of toolbarNodes) {
|
||||||
menuItem.setAttribute(
|
if (!toolbar.hasAttribute("toolbarname")) {
|
||||||
"checked",
|
continue;
|
||||||
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);
|
if (toolbar.id == "PersonalToolbar") {
|
||||||
menuItem.addEventListener("command", onViewToolbarCommand);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let showTabStripItems = toolbarItem?.id == "tabbrowser-tabs";
|
|
||||||
for (let node of popup.querySelectorAll(
|
for (let node of popup.querySelectorAll(
|
||||||
'menuitem[contexttype="toolbaritem"]'
|
'menuitem[contexttype="toolbaritem"]'
|
||||||
)) {
|
)) {
|
||||||
|
|
|
@ -316,6 +316,17 @@ export class ExtensionControlledPopup {
|
||||||
anchorButton = action || doc.getElementById("PanelUI-menu-button");
|
anchorButton = action || doc.getElementById("PanelUI-menu-button");
|
||||||
}
|
}
|
||||||
let anchor = anchorButton.icon;
|
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();
|
popupnotification.show();
|
||||||
panel.openPopup(anchor);
|
panel.openPopup(anchor);
|
||||||
}
|
}
|
||||||
|
@ -349,11 +360,6 @@ export class ExtensionControlledPopup {
|
||||||
lazy.BrowserUIUtils.getLocalizedFragment(doc, message, addonDetails)
|
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) {
|
async _ensureWindowReady(win) {
|
||||||
|
|
|
@ -162,14 +162,23 @@ add_task(async function testExtensionControlledPopup() {
|
||||||
let description = doc.getElementById("extension-controlled-description");
|
let description = doc.getElementById("extension-controlled-description");
|
||||||
is(
|
is(
|
||||||
description.textContent,
|
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"
|
"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(
|
is(
|
||||||
link.href,
|
learnMoreEl.getAttribute("href"),
|
||||||
"http://127.0.0.1:8888/support-dummy/extension-controlled",
|
Services.urlFormatter.formatURLPref("app.support.baseURL") +
|
||||||
"The link has the href set from learnMoreLink"
|
"extension-controlled",
|
||||||
|
"learnmore link should have the expected url set"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Force close the popup, as if a user clicked away from it.
|
// 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() {
|
function background() {
|
||||||
browser.test.onMessage.addListener(async msg => {
|
browser.test.onMessage.addListener(async msg => {
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case "checkHomepage":
|
case "checkHomepage": {
|
||||||
let homepage = await browser.browserSettings.homepageOverride.get({});
|
let homepage = await browser.browserSettings.homepageOverride.get({});
|
||||||
browser.test.sendMessage("homepage", homepage);
|
browser.test.sendMessage("homepage", homepage);
|
||||||
break;
|
break;
|
||||||
case "trySet":
|
}
|
||||||
|
case "trySet": {
|
||||||
let setResult = await browser.browserSettings.homepageOverride.set({
|
let setResult = await browser.browserSettings.homepageOverride.set({
|
||||||
value: "foo",
|
value: "foo",
|
||||||
});
|
});
|
||||||
|
@ -80,7 +81,8 @@ add_task(async function test_multiple_extensions_overriding_home_page() {
|
||||||
);
|
);
|
||||||
browser.test.sendMessage("homepageSet");
|
browser.test.sendMessage("homepageSet");
|
||||||
break;
|
break;
|
||||||
case "tryClear":
|
}
|
||||||
|
case "tryClear": {
|
||||||
let clearResult =
|
let clearResult =
|
||||||
await browser.browserSettings.homepageOverride.clear({});
|
await browser.browserSettings.homepageOverride.clear({});
|
||||||
browser.test.assertFalse(
|
browser.test.assertFalse(
|
||||||
|
@ -89,6 +91,7 @@ add_task(async function test_multiple_extensions_overriding_home_page() {
|
||||||
);
|
);
|
||||||
browser.test.sendMessage("homepageCleared");
|
browser.test.sendMessage("homepageCleared");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -489,13 +492,28 @@ add_task(async function test_doorhanger_new_window() {
|
||||||
|
|
||||||
is(
|
is(
|
||||||
description.textContent,
|
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"
|
"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.
|
// Click Manage.
|
||||||
let popupHidden = promisePopupHidden(panel);
|
let popupHidden = promisePopupHidden(panel);
|
||||||
let popupnotification = doc.getElementById("extension-homepage-notification");
|
|
||||||
popupnotification.secondaryButton.click();
|
popupnotification.secondaryButton.click();
|
||||||
await popupHidden;
|
await popupHidden;
|
||||||
|
|
||||||
|
@ -518,7 +536,7 @@ add_task(async function test_doorhanger_new_window() {
|
||||||
|
|
||||||
is(
|
is(
|
||||||
description.textContent,
|
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"
|
"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");
|
let popupnotification = description.closest("popupnotification");
|
||||||
is(
|
is(
|
||||||
description.textContent,
|
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"
|
"The extension name is in the popup"
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
|
|
|
@ -73,10 +73,34 @@ add_task(function test_doorhanger_keep() {
|
||||||
"The doorhanger is anchored to the all tabs button"
|
"The doorhanger is anchored to the all tabs button"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Click the Keep Tabs Hidden button.
|
let description = panel.querySelector(
|
||||||
let popupnotification = document.getElementById(
|
"#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"
|
"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);
|
let popupHidden = promisePopupHidden(panel);
|
||||||
popupnotification.button.click();
|
popupnotification.button.click();
|
||||||
await popupHidden;
|
await popupHidden;
|
||||||
|
@ -227,17 +251,6 @@ add_task(async function test_tabs_showhide() {
|
||||||
SessionStore.setBrowserState(JSON.stringify(sessData));
|
SessionStore.setBrowserState(JSON.stringify(sessData));
|
||||||
await restored;
|
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
|
// Attempt to hide all the tabs, however the active tab in each window cannot
|
||||||
// be hidden, so the result will be 3 hidden tabs.
|
// be hidden, so the result will be 3 hidden tabs.
|
||||||
extension.sendMessage("hideall");
|
extension.sendMessage("hideall");
|
||||||
|
|
|
@ -258,10 +258,25 @@ add_task(async function test_new_tab_keep_settings() {
|
||||||
is(
|
is(
|
||||||
panel.querySelector("#extension-new-tab-notification-description")
|
panel.querySelector("#extension-new-tab-notification-description")
|
||||||
.textContent,
|
.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"
|
"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.
|
// Click the Keep Changes button.
|
||||||
let confirmationSaved = TestUtils.waitForCondition(() => {
|
let confirmationSaved = TestUtils.waitForCondition(() => {
|
||||||
return ExtensionSettingsStore.getSetting(
|
return ExtensionSettingsStore.getSetting(
|
||||||
|
|
|
@ -210,6 +210,20 @@ export const PREFS_CONFIG = new Map([
|
||||||
value: true,
|
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",
|
"system.showWeather",
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,21 +115,13 @@ var TabStateCacheInternal = {
|
||||||
}
|
}
|
||||||
|
|
||||||
let history = data.history;
|
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)) {
|
for (let key of Object.keys(change)) {
|
||||||
if (key == "entries") {
|
if (key == "entries") {
|
||||||
if (change.fromIdx != kLastIndex) {
|
if (change.fromIdx != kLastIndex) {
|
||||||
let start = change.fromIdx + 1;
|
let start = change.fromIdx + 1;
|
||||||
history.entries.splice.apply(
|
history.entries.splice(start, Infinity, ...change.entries);
|
||||||
history.entries,
|
|
||||||
[start, toIdx - start].concat(change.entries)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (key != "fromIdx" && key != "toIdx") {
|
} else if (key != "fromIdx") {
|
||||||
history[key] = change[key];
|
history[key] = change[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ export class SidebarHistory extends SidebarPage {
|
||||||
this._menuSortBySite = doc.getElementById("sidebar-history-sort-by-site");
|
this._menuSortBySite = doc.getElementById("sidebar-history-sort-by-site");
|
||||||
this._menu.addEventListener("command", this);
|
this._menu.addEventListener("command", this);
|
||||||
this.addContextMenuListeners();
|
this.addContextMenuListeners();
|
||||||
|
this.addSidebarFocusedListeners();
|
||||||
this.controller.updateCache();
|
this.controller.updateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ export class SidebarHistory extends SidebarPage {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
this._menu.removeEventListener("command", this);
|
this._menu.removeEventListener("command", this);
|
||||||
this.removeContextMenuListeners();
|
this.removeContextMenuListeners();
|
||||||
|
this.removeSidebarFocusedListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleContextMenuEvent(e) {
|
handleContextMenuEvent(e) {
|
||||||
|
@ -74,6 +76,10 @@ export class SidebarHistory extends SidebarPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleSidebarFocusedEvent() {
|
||||||
|
this.searchTextbox?.focus();
|
||||||
|
}
|
||||||
|
|
||||||
onPrimaryAction(e) {
|
onPrimaryAction(e) {
|
||||||
navigateToLink(e);
|
navigateToLink(e);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +266,6 @@ export class SidebarHistory extends SidebarPage {
|
||||||
data-l10n-attrs="placeholder"
|
data-l10n-attrs="placeholder"
|
||||||
@fxview-search-textbox-query=${this.onSearchQuery}
|
@fxview-search-textbox-query=${this.onSearchQuery}
|
||||||
.size=${15}
|
.size=${15}
|
||||||
autofocus
|
|
||||||
></fxview-search-textbox>
|
></fxview-search-textbox>
|
||||||
<moz-button
|
<moz-button
|
||||||
class="menu-button"
|
class="menu-button"
|
||||||
|
|
|
@ -93,7 +93,10 @@ export default class SidebarMain extends MozLitElement {
|
||||||
event.explicitOriginalTarget.flattenedTreeParentNode;
|
event.explicitOriginalTarget.flattenedTreeParentNode;
|
||||||
if (
|
if (
|
||||||
this.contextMenuTarget.getAttribute("extensionId") ||
|
this.contextMenuTarget.getAttribute("extensionId") ||
|
||||||
this.contextMenuTarget.className.includes("tab")
|
this.contextMenuTarget.className.includes("tab") ||
|
||||||
|
document
|
||||||
|
.getElementById("vertical-tabs")
|
||||||
|
.contains(this.contextMenuTarget.flattenedTreeParentNode)
|
||||||
) {
|
) {
|
||||||
this.updateExtensionContextMenuItems();
|
this.updateExtensionContextMenuItems();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -56,6 +56,14 @@ export class SidebarPage extends MozLitElement {
|
||||||
this._contextMenu.removeEventListener("command", this);
|
this._contextMenu.removeEventListener("command", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addSidebarFocusedListeners() {
|
||||||
|
this.topWindow.addEventListener("SidebarFocused", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeSidebarFocusedListeners() {
|
||||||
|
this.topWindow.removeEventListener("SidebarFocused", this);
|
||||||
|
}
|
||||||
|
|
||||||
handleEvent(e) {
|
handleEvent(e) {
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case "contextmenu":
|
case "contextmenu":
|
||||||
|
@ -64,6 +72,9 @@ export class SidebarPage extends MozLitElement {
|
||||||
case "command":
|
case "command":
|
||||||
this.handleCommandEvent?.(e);
|
this.handleCommandEvent?.(e);
|
||||||
break;
|
break;
|
||||||
|
case "SidebarFocused":
|
||||||
|
this.handleSidebarFocusedEvent?.(e);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ class SyncedTabsInSidebar extends SidebarPage {
|
||||||
|
|
||||||
static queries = {
|
static queries = {
|
||||||
cards: { all: "moz-card" },
|
cards: { all: "moz-card" },
|
||||||
|
searchTextbox: "fxview-search-textbox",
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -36,12 +37,14 @@ class SyncedTabsInSidebar extends SidebarPage {
|
||||||
this.controller.addSyncObservers();
|
this.controller.addSyncObservers();
|
||||||
this.controller.updateStates();
|
this.controller.updateStates();
|
||||||
this.addContextMenuListeners();
|
this.addContextMenuListeners();
|
||||||
|
this.addSidebarFocusedListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
this.controller.removeSyncObservers();
|
this.controller.removeSyncObservers();
|
||||||
this.removeContextMenuListeners();
|
this.removeContextMenuListeners();
|
||||||
|
this.removeSidebarFocusedListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleContextMenuEvent(e) {
|
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
|
* The template shown when the list of synced devices is currently
|
||||||
* unavailable.
|
* unavailable.
|
||||||
|
@ -208,7 +215,6 @@ class SyncedTabsInSidebar extends SidebarPage {
|
||||||
>
|
>
|
||||||
</sidebar-panel-header>
|
</sidebar-panel-header>
|
||||||
<fxview-search-textbox
|
<fxview-search-textbox
|
||||||
autofocus
|
|
||||||
data-l10n-id="firefoxview-search-text-box-syncedtabs"
|
data-l10n-id="firefoxview-search-text-box-syncedtabs"
|
||||||
data-l10n-attrs="placeholder"
|
data-l10n-attrs="placeholder"
|
||||||
@fxview-search-textbox-query=${this.onSearchQuery}
|
@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
|
// Check category of new window sidebar is that of opener window sidebar
|
||||||
let newSidebarBox = document.getElementById("sidebar-box");
|
let newSidebarBox;
|
||||||
await BrowserTestUtils.waitForCondition(
|
await BrowserTestUtils.waitForCondition(() => {
|
||||||
() => BrowserTestUtils.isVisible(newSidebarBox),
|
newSidebarBox = newWin.document.getElementById("sidebar-box");
|
||||||
"New sidebar box is visible"
|
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(
|
await BrowserTestUtils.waitForCondition(
|
||||||
() => !!newSidebarBox.getAttribute("sidebarcommand"),
|
() => !!newSidebarBox.getAttribute("sidebarcommand"),
|
||||||
"Category has been set"
|
"Category has been set"
|
||||||
|
@ -60,3 +67,61 @@ add_task(async function test_adopt_from_window() {
|
||||||
await BrowserTestUtils.closeWindow(newWin);
|
await BrowserTestUtils.closeWindow(newWin);
|
||||||
await BrowserTestUtils.closeWindow(win);
|
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() {
|
add_task(async function test_history_search() {
|
||||||
const { component, contentWindow } = await showHistorySidebar();
|
const { component, contentWindow } = await showHistorySidebar();
|
||||||
const { searchTextbox } = component;
|
const { searchTextbox } = component;
|
||||||
|
|
|
@ -119,3 +119,17 @@ add_task(async function test_tabs() {
|
||||||
SidebarController.hide();
|
SidebarController.hide();
|
||||||
sandbox.restore();
|
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");
|
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
|
// flip the pref to move the tabstrip horizontally
|
||||||
await SpecialPowers.pushPrefEnv({ set: [["sidebar.verticalTabs", false]] });
|
await SpecialPowers.pushPrefEnv({ set: [["sidebar.verticalTabs", false]] });
|
||||||
|
|
||||||
|
|
|
@ -59,14 +59,10 @@ var gTabsPanel = {
|
||||||
insertBefore: document.getElementById("allTabsMenu-tabsSeparator"),
|
insertBefore: document.getElementById("allTabsMenu-tabsSeparator"),
|
||||||
filterFn: tab => tab.hidden && tab.soundPlaying,
|
filterFn: tab => tab.hidden && tab.soundPlaying,
|
||||||
});
|
});
|
||||||
let showPinnedTabs = Services.prefs.getBoolPref(
|
|
||||||
"browser.tabs.tabmanager.enabled"
|
|
||||||
);
|
|
||||||
this.allTabsPanel = new TabsPanel({
|
this.allTabsPanel = new TabsPanel({
|
||||||
view: this.allTabsView,
|
view: this.allTabsView,
|
||||||
containerNode: this.allTabsViewTabs,
|
containerNode: this.allTabsViewTabs,
|
||||||
filterFn: tab =>
|
filterFn: tab => !tab.hidden,
|
||||||
!tab.hidden && (!tab.pinned || (showPinnedTabs && tab.pinned)),
|
|
||||||
dropIndicator: this.dropIndicator,
|
dropIndicator: this.dropIndicator,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -327,8 +327,6 @@ skip-if = ["true"] # Bug 1616418 Bug 1549985
|
||||||
["browser_tab_manager_keyboard_access.js"]
|
["browser_tab_manager_keyboard_access.js"]
|
||||||
skip-if = ["true"] # Bug 1900477
|
skip-if = ["true"] # Bug 1900477
|
||||||
|
|
||||||
["browser_tab_manager_visibility.js"]
|
|
||||||
|
|
||||||
["browser_tab_move_to_new_window_reload.js"]
|
["browser_tab_move_to_new_window_reload.js"]
|
||||||
|
|
||||||
["browser_tab_play.js"]
|
["browser_tab_play.js"]
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
add_setup(async function () {
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [["browser.tabs.tabmanager.enabled", true]],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
async function openAllTabsPanel(win) {
|
async function openAllTabsPanel(win) {
|
||||||
const button = win.document.getElementById("alltabs-button");
|
const button = win.document.getElementById("alltabs-button");
|
||||||
const allTabsView = win.document.getElementById("allTabsMenu-allTabsView");
|
const allTabsView = win.document.getElementById("allTabsMenu-allTabsView");
|
||||||
|
|
|
@ -9,12 +9,6 @@ const URL3 = "data:text/plain,tab3";
|
||||||
const URL4 = "data:text/plain,tab4";
|
const URL4 = "data:text/plain,tab4";
|
||||||
const URL5 = "data:text/plain,tab5";
|
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.
|
* 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) {
|
async function testWithNewWindow(func) {
|
||||||
Services.prefs.setBoolPref("browser.tabs.tabmanager.enabled", true);
|
|
||||||
|
|
||||||
const newWindow = await BrowserTestUtils.openNewBrowserWindow();
|
const newWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
@ -75,8 +73,6 @@ async function testWithNewWindow(func) {
|
||||||
await func(newWindow);
|
await func(newWindow);
|
||||||
|
|
||||||
await BrowserTestUtils.closeWindow(newWindow);
|
await BrowserTestUtils.closeWindow(newWindow);
|
||||||
|
|
||||||
Services.prefs.clearUserPref("browser.tabs.tabmanager.enabled");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_task(async function test_reorder() {
|
add_task(async function test_reorder() {
|
||||||
|
|
|
@ -25,9 +25,6 @@ async function waitForAllTabsMenu(window = window) {
|
||||||
* by other tests.
|
* by other tests.
|
||||||
*/
|
*/
|
||||||
add_task(async function test_open_tabmanager_keyboard() {
|
add_task(async function test_open_tabmanager_keyboard() {
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [["browser.tabs.tabmanager.enabled", true]],
|
|
||||||
});
|
|
||||||
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
|
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
let elem = newWindow.document.getElementById("alltabs-button");
|
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-number" },
|
||||||
{ fieldName: "cc-exp-month" },
|
{ fieldName: "cc-exp-month" },
|
||||||
{ fieldName: "cc-exp-year" },
|
{ fieldName: "cc-exp-year" },
|
||||||
|
{ fieldName: "cc-csc" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -47,6 +48,7 @@ add_heuristic_tests(
|
||||||
{ fieldName: "cc-number", reason: "autocomplete" },
|
{ fieldName: "cc-number", reason: "autocomplete" },
|
||||||
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-exp-year", reason: "update-heuristic" },
|
{ fieldName: "cc-exp-year", reason: "update-heuristic" },
|
||||||
|
{ fieldName: "cc-csc", reason: "regex-heuristic" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -14,6 +14,7 @@ add_heuristic_tests(
|
||||||
fields: [
|
fields: [
|
||||||
{ fieldName: "cc-number", reason: "fathom" },
|
{ fieldName: "cc-number", reason: "fathom" },
|
||||||
{ fieldName: "cc-exp", reason: "update-heuristic" },
|
{ fieldName: "cc-exp", reason: "update-heuristic" },
|
||||||
|
{ fieldName: "cc-csc", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-name", reason: "regex-heuristic" },
|
{ fieldName: "cc-name", reason: "regex-heuristic" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -70,7 +70,7 @@ add_heuristic_tests([
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
{ fieldName: "cc-number", reason: "autocomplete" },
|
{ 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-number", reason: "fathom" }, // ac-off
|
||||||
{ fieldName: "cc-exp-month" },
|
{ fieldName: "cc-exp-month" },
|
||||||
{ fieldName: "cc-exp-year" },
|
{ fieldName: "cc-exp-year" },
|
||||||
// { fieldName: "cc-csc"}, // ac-off
|
{ fieldName: "cc-csc"}, // ac-off
|
||||||
{ fieldName: "cc-name", reason: "fathom" }, // ac-off
|
{ fieldName: "cc-name", reason: "fathom" }, // ac-off
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,6 +14,7 @@ add_heuristic_tests(
|
||||||
fields: [
|
fields: [
|
||||||
{ fieldName: "cc-number" },
|
{ fieldName: "cc-number" },
|
||||||
{ fieldName: "cc-name" },
|
{ fieldName: "cc-name" },
|
||||||
|
{ fieldName: "cc-csc", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-exp-year", reason: "regex-heuristic" },
|
{ fieldName: "cc-exp-year", reason: "regex-heuristic" },
|
||||||
],
|
],
|
||||||
|
|
|
@ -14,6 +14,7 @@ add_heuristic_tests(
|
||||||
fields: [
|
fields: [
|
||||||
{ fieldName: "cc-number" },
|
{ fieldName: "cc-number" },
|
||||||
{ fieldName: "cc-exp" },
|
{ fieldName: "cc-exp" },
|
||||||
|
{ fieldName: "cc-csc" },
|
||||||
{ fieldName: "cc-given-name" },
|
{ fieldName: "cc-given-name" },
|
||||||
{ fieldName: "cc-family-name" },
|
{ fieldName: "cc-family-name" },
|
||||||
],
|
],
|
||||||
|
|
|
@ -13,10 +13,10 @@ add_heuristic_tests(
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
{ fieldName: "cc-number" },
|
{ fieldName: "cc-number" },
|
||||||
//{ fieldName: "cc-cvc" },
|
{ fieldName: "cc-csc", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-exp-month" },
|
{ fieldName: "cc-exp-month" },
|
||||||
{ fieldName: "cc-exp-year" },
|
{ 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-number", reason: "fathom" },
|
||||||
{ fieldName: "cc-exp-month" },
|
{ fieldName: "cc-exp-month" },
|
||||||
{ fieldName: "cc-exp-year" },
|
{ fieldName: "cc-exp-year" },
|
||||||
|
{ fieldName: "cc-csc" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -45,6 +45,7 @@ add_heuristic_tests(
|
||||||
fields: [
|
fields: [
|
||||||
{ fieldName: "cc-exp-month", reason: "regex-heuristic" }, // invisible
|
{ fieldName: "cc-exp-month", reason: "regex-heuristic" }, // invisible
|
||||||
{ fieldName: "cc-exp-year", 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-number", part: 4 },
|
||||||
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-exp-year", 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
|
// 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
|
// 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
|
// instead of depending on the order of we perform the matching
|
||||||
//{
|
{
|
||||||
//invalid: true,
|
invalid: true,
|
||||||
//fields: [
|
fields: [
|
||||||
//{ fieldName: "email", reason: "regex-heuristic"},
|
{ fieldName: "cc-csc", reason: "regex-heuristic"},
|
||||||
//],
|
],
|
||||||
//},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -36,6 +36,7 @@ add_heuristic_tests(
|
||||||
fields: [
|
fields: [
|
||||||
{ fieldName: "cc-name" },
|
{ fieldName: "cc-name" },
|
||||||
{ fieldName: "cc-number" }, // ac-off
|
{ 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-number" }, // ac-off
|
||||||
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-exp-year", 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-month" },
|
||||||
{ fieldName: "cc-exp-year" },
|
{ fieldName: "cc-exp-year" },
|
||||||
{ fieldName: "cc-number" },
|
{ fieldName: "cc-number" },
|
||||||
|
{ fieldName: "cc-csc" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@ add_heuristic_tests(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
// { fieldName: "cc-csc"},
|
{ fieldName: "cc-csc", reason: "regex-heuristic"},
|
||||||
{ fieldName: "cc-type", reason: "regex-heuristic" },
|
{ fieldName: "cc-type", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-number", reason: "fathom" },
|
{ fieldName: "cc-number", reason: "fathom" },
|
||||||
{ fieldName: "cc-exp", reason: "update-heuristic" },
|
{ fieldName: "cc-exp", reason: "update-heuristic" },
|
||||||
|
@ -28,6 +28,7 @@ add_heuristic_tests(
|
||||||
{
|
{
|
||||||
invalid: true,
|
invalid: true,
|
||||||
fields: [
|
fields: [
|
||||||
|
{ fieldName: "cc-csc", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-number", reason: "regex-heuristic" }, // txtQvcGiftCardNumber
|
{ fieldName: "cc-number", reason: "regex-heuristic" }, // txtQvcGiftCardNumber
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -58,15 +59,16 @@ add_heuristic_tests(
|
||||||
reason: "fathom",
|
reason: "fathom",
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
|
{ fieldName: "cc-csc", reason: "regex-heuristic"},
|
||||||
{ fieldName: "cc-type", reason: "regex-heuristic" }, // ac-off
|
{ fieldName: "cc-type", reason: "regex-heuristic" }, // ac-off
|
||||||
{ fieldName: "cc-number" }, // ac-off
|
{ fieldName: "cc-number" }, // ac-off
|
||||||
{ fieldName: "cc-exp", reason: "update-heuristic" },
|
{ fieldName: "cc-exp", reason: "update-heuristic" },
|
||||||
// { fieldName: "cc-csc"},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
invalid: true,
|
invalid: true,
|
||||||
fields: [
|
fields: [
|
||||||
|
{ fieldName: "cc-csc", reason: "regex-heuristic" },
|
||||||
{ fieldName: "cc-number", reason: "regex-heuristic" }, // txtQvcGiftCardNumbe, ac-off
|
{ fieldName: "cc-number", reason: "regex-heuristic" }, // txtQvcGiftCardNumbe, ac-off
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -212,6 +212,8 @@ this.addonsSearchDetection = class extends ExtensionAPI {
|
||||||
fire.sync({ addonId, firstUrl, lastUrl });
|
fire.sync({ addonId, firstUrl, lastUrl });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const remoteTab = context.xulBrowser.frameLoader.remoteTab;
|
||||||
|
|
||||||
const listener = ({ requestId, url, originUrl }) => {
|
const listener = ({ requestId, url, originUrl }) => {
|
||||||
// We exclude requests not originating from the location bar,
|
// We exclude requests not originating from the location bar,
|
||||||
// bookmarks and other "system-ish" requests.
|
// bookmarks and other "system-ish" requests.
|
||||||
|
@ -227,20 +229,47 @@ this.addonsSearchDetection = class extends ExtensionAPI {
|
||||||
const wrapper = ChannelWrapper.getRegisteredChannel(
|
const wrapper = ChannelWrapper.getRegisteredChannel(
|
||||||
requestId,
|
requestId,
|
||||||
context.extension.policy,
|
context.extension.policy,
|
||||||
context.xulBrowser.frameLoader.remoteTab
|
remoteTab
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.addEventListener("stop", stopListener);
|
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(
|
WebRequest.onBeforeRedirect.addListener(
|
||||||
listener,
|
listener,
|
||||||
// filter
|
parsedFilter,
|
||||||
{
|
|
||||||
types: ["main_frame"],
|
|
||||||
urls: ExtensionUtils.parseMatchPatterns(filter.urls),
|
|
||||||
},
|
|
||||||
// info
|
// info
|
||||||
[],
|
[],
|
||||||
// listener details
|
// listener details
|
||||||
|
@ -252,6 +281,7 @@ this.addonsSearchDetection = class extends ExtensionAPI {
|
||||||
);
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
WebRequest.onBeforeRequest.removeListener(ensureRegisterChannel);
|
||||||
WebRequest.onBeforeRedirect.removeListener(listener);
|
WebRequest.onBeforeRedirect.removeListener(listener);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -47,12 +47,6 @@ class AddonsSearchDetection {
|
||||||
this.onRedirectedListener
|
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.
|
// Retrieve the list of URL patterns to monitor with our listener.
|
||||||
//
|
//
|
||||||
|
@ -65,23 +59,12 @@ class AddonsSearchDetection {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.webRequest.onBeforeRequest.addListener(
|
|
||||||
this.noOpListener,
|
|
||||||
{ types: ["main_frame"], urls: patterns },
|
|
||||||
["blocking"]
|
|
||||||
);
|
|
||||||
|
|
||||||
browser.addonsSearchDetection.onRedirected.addListener(
|
browser.addonsSearchDetection.onRedirected.addListener(
|
||||||
this.onRedirectedListener,
|
this.onRedirectedListener,
|
||||||
{ urls: patterns }
|
{ urls: patterns }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This listener is required to force the registration of traceable channels.
|
|
||||||
noOpListener() {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
async onRedirectedListener({ addonId, firstUrl, lastUrl }) {
|
async onRedirectedListener({ addonId, firstUrl, lastUrl }) {
|
||||||
// When we do not have an add-on ID (in the request property bag), we
|
// When we do not have an add-on ID (in the request property bag), we
|
||||||
// likely detected a search server-side redirect.
|
// likely detected a search server-side redirect.
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"af": {
|
"af": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"an": {
|
"an": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ar": {
|
"ar": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ast": {
|
"ast": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"az": {
|
"az": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"be": {
|
"be": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"bg": {
|
"bg": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"bn": {
|
"bn": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"bo": {
|
"bo": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -187,7 +187,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"br": {
|
"br": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -206,7 +206,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"brx": {
|
"brx": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -225,7 +225,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"bs": {
|
"bs": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -244,7 +244,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ca": {
|
"ca": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -263,7 +263,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ca-valencia": {
|
"ca-valencia": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -282,7 +282,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"cak": {
|
"cak": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -301,7 +301,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ckb": {
|
"ckb": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -320,7 +320,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"cs": {
|
"cs": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -339,7 +339,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"cy": {
|
"cy": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -358,7 +358,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"da": {
|
"da": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -377,7 +377,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"de": {
|
"de": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -396,7 +396,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"dsb": {
|
"dsb": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -415,7 +415,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"el": {
|
"el": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -434,7 +434,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"en-CA": {
|
"en-CA": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -453,7 +453,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"en-GB": {
|
"en-GB": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -472,7 +472,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"eo": {
|
"eo": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -491,7 +491,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"es-AR": {
|
"es-AR": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -510,7 +510,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"es-CL": {
|
"es-CL": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -529,7 +529,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"es-ES": {
|
"es-ES": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -548,7 +548,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"es-MX": {
|
"es-MX": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -567,7 +567,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"et": {
|
"et": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -586,7 +586,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"eu": {
|
"eu": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -605,7 +605,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"fa": {
|
"fa": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -624,7 +624,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ff": {
|
"ff": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -643,7 +643,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"fi": {
|
"fi": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -662,7 +662,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"fr": {
|
"fr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -681,7 +681,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"fur": {
|
"fur": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -700,7 +700,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"fy-NL": {
|
"fy-NL": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -719,7 +719,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ga-IE": {
|
"ga-IE": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -738,7 +738,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"gd": {
|
"gd": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -757,7 +757,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"gl": {
|
"gl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -776,7 +776,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"gn": {
|
"gn": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -795,7 +795,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"gu-IN": {
|
"gu-IN": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -814,7 +814,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"he": {
|
"he": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -833,7 +833,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"hi-IN": {
|
"hi-IN": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -852,7 +852,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"hr": {
|
"hr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -871,7 +871,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"hsb": {
|
"hsb": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -890,7 +890,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"hu": {
|
"hu": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -909,7 +909,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"hy-AM": {
|
"hy-AM": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -928,7 +928,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"hye": {
|
"hye": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -947,7 +947,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ia": {
|
"ia": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -966,7 +966,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -985,7 +985,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"is": {
|
"is": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1004,7 +1004,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"it": {
|
"it": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1023,7 +1023,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ja": {
|
"ja": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1040,7 +1040,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ja-JP-mac": {
|
"ja-JP-mac": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1048,7 +1048,7 @@
|
||||||
"macosx64",
|
"macosx64",
|
||||||
"macosx64-devedition"
|
"macosx64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ka": {
|
"ka": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1067,7 +1067,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"kab": {
|
"kab": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1086,7 +1086,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"kk": {
|
"kk": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1105,7 +1105,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"km": {
|
"km": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1124,7 +1124,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"kn": {
|
"kn": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1143,7 +1143,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ko": {
|
"ko": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1162,7 +1162,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"lij": {
|
"lij": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1181,7 +1181,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"lo": {
|
"lo": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1200,7 +1200,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"lt": {
|
"lt": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1219,7 +1219,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ltg": {
|
"ltg": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1238,7 +1238,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"lv": {
|
"lv": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1257,7 +1257,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"meh": {
|
"meh": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1276,7 +1276,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"mk": {
|
"mk": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1295,7 +1295,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"mr": {
|
"mr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1314,7 +1314,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1333,7 +1333,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"my": {
|
"my": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1352,7 +1352,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"nb-NO": {
|
"nb-NO": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1371,7 +1371,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ne-NP": {
|
"ne-NP": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1390,7 +1390,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"nl": {
|
"nl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1409,7 +1409,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"nn-NO": {
|
"nn-NO": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1428,7 +1428,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"oc": {
|
"oc": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1447,7 +1447,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"pa-IN": {
|
"pa-IN": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1466,7 +1466,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"pl": {
|
"pl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1485,7 +1485,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"pt-BR": {
|
"pt-BR": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1504,7 +1504,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"pt-PT": {
|
"pt-PT": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1523,7 +1523,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"rm": {
|
"rm": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1542,7 +1542,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ro": {
|
"ro": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1561,7 +1561,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ru": {
|
"ru": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1580,7 +1580,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"sat": {
|
"sat": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1599,7 +1599,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"sc": {
|
"sc": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1618,7 +1618,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"scn": {
|
"scn": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1637,7 +1637,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"sco": {
|
"sco": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1656,7 +1656,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"si": {
|
"si": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1675,7 +1675,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"sk": {
|
"sk": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1694,7 +1694,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"skr": {
|
"skr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1713,7 +1713,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"sl": {
|
"sl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1732,7 +1732,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"son": {
|
"son": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1751,7 +1751,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"sq": {
|
"sq": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1770,7 +1770,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"sr": {
|
"sr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1789,7 +1789,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"sv-SE": {
|
"sv-SE": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1808,7 +1808,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"szl": {
|
"szl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1827,7 +1827,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ta": {
|
"ta": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1846,7 +1846,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"te": {
|
"te": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1865,7 +1865,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"tg": {
|
"tg": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1884,7 +1884,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"th": {
|
"th": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1903,7 +1903,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"tl": {
|
"tl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1922,7 +1922,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"tr": {
|
"tr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1941,7 +1941,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"trs": {
|
"trs": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1960,7 +1960,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"uk": {
|
"uk": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1979,7 +1979,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"ur": {
|
"ur": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1998,7 +1998,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"uz": {
|
"uz": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2017,7 +2017,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"vi": {
|
"vi": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2036,7 +2036,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"wo": {
|
"wo": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2055,7 +2055,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"xh": {
|
"xh": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2074,7 +2074,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"zh-CN": {
|
"zh-CN": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2093,7 +2093,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
},
|
},
|
||||||
"zh-TW": {
|
"zh-TW": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2112,6 +2112,6 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "aea3843a8a961607b1c86af8741670b3fce0bb0a"
|
"revision": "9f4b4cc220a63529fa7cd67cc8f6479dfc33ab64"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -43,8 +43,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
const DEFAULT_EXTENSION_ICON =
|
const DEFAULT_EXTENSION_ICON =
|
||||||
"chrome://mozapps/skin/extensions/extensionGeneric.svg";
|
"chrome://mozapps/skin/extensions/extensionGeneric.svg";
|
||||||
|
|
||||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
||||||
|
|
||||||
function getTabBrowser(browser) {
|
function getTabBrowser(browser) {
|
||||||
while (browser.ownerGlobal.docShell.itemType !== Ci.nsIDocShell.typeChrome) {
|
while (browser.ownerGlobal.docShell.itemType !== Ci.nsIDocShell.typeChrome) {
|
||||||
browser = browser.ownerGlobal.docShell.chromeEventHandler;
|
browser = browser.ownerGlobal.docShell.chromeEventHandler;
|
||||||
|
@ -397,8 +395,6 @@ export var ExtensionsUI = {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let checkbox;
|
|
||||||
|
|
||||||
const incognitoPermissionName = "internal:privateBrowsingAllowed";
|
const incognitoPermissionName = "internal:privateBrowsingAllowed";
|
||||||
let grantPrivateBrowsingAllowed = false;
|
let grantPrivateBrowsingAllowed = false;
|
||||||
if (showIncognitoCheckbox) {
|
if (showIncognitoCheckbox) {
|
||||||
|
@ -416,79 +412,7 @@ export var ExtensionsUI = {
|
||||||
|
|
||||||
let promise = new Promise(resolve => {
|
let promise = new Promise(resolve => {
|
||||||
function eventCallback(topic) {
|
function eventCallback(topic) {
|
||||||
let doc = this.browser.ownerDocument;
|
if (topic == "swapping") {
|
||||||
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") {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (topic == "removed") {
|
if (topic == "removed") {
|
||||||
|
@ -499,16 +423,38 @@ export var ExtensionsUI = {
|
||||||
return false;
|
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 = {
|
let options = {
|
||||||
hideClose: true,
|
hideClose: true,
|
||||||
popupIconURL: icon || DEFAULT_EXTENSION_ICON,
|
popupIconURL: icon || DEFAULT_EXTENSION_ICON,
|
||||||
popupIconClass: icon ? "" : "addon-warning-icon",
|
popupIconClass: icon ? "" : "addon-warning-icon",
|
||||||
|
learnMoreURL,
|
||||||
persistent: true,
|
persistent: true,
|
||||||
eventCallback,
|
eventCallback,
|
||||||
removeOnDismissal: true,
|
removeOnDismissal: true,
|
||||||
popupOptions: {
|
popupOptions: {
|
||||||
position: "bottomright topright",
|
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
|
// The prompt/notification machinery has a special affordance wherein
|
||||||
// certain subsets of the header string can be designated "names", and
|
// certain subsets of the header string can be designated "names", and
|
||||||
|
@ -529,9 +475,6 @@ export var ExtensionsUI = {
|
||||||
label: strings.acceptText,
|
label: strings.acceptText,
|
||||||
accessKey: strings.acceptKey,
|
accessKey: strings.acceptKey,
|
||||||
callback: () => {
|
callback: () => {
|
||||||
grantPrivateBrowsingAllowed = showIncognitoCheckbox
|
|
||||||
? checkbox.checked
|
|
||||||
: undefined;
|
|
||||||
resolve(true);
|
resolve(true);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -125,12 +125,15 @@
|
||||||
|
|
||||||
/* Content area */
|
/* Content area */
|
||||||
|
|
||||||
.sidebar-splitter {
|
/* stylelint-disable-next-line media-query-no-invalid */
|
||||||
appearance: none;
|
@media not (-moz-bool-pref: "sidebar.revamp") {
|
||||||
width: 6px;
|
.sidebar-splitter {
|
||||||
background-color: -moz-dialog;
|
appearance: none;
|
||||||
border: 1px ThreeDShadow;
|
width: 6px;
|
||||||
border-style: none solid;
|
background-color: -moz-dialog;
|
||||||
|
border: 1px ThreeDShadow;
|
||||||
|
border-style: none solid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tabstrip */
|
/* Tabstrip */
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
html|*.addon-webext-perm-list {
|
html|*.addon-webext-perm-list {
|
||||||
margin-block-end: 0;
|
margin-block-end: 0;
|
||||||
padding-inline-start: 10px;
|
padding-inline-start: 0;
|
||||||
|
|
||||||
> html|li {
|
> html|li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
|
@ -195,6 +195,23 @@ body {
|
||||||
margin: 0;
|
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 */
|
/* Toolbox and Toolbars */
|
||||||
|
|
||||||
#navigator-toolbox {
|
#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.
|
/* 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
|
* (That is, if the menu bar doesn't autohide, and we're not in a fullscreen or
|
||||||
* popup window.) */
|
* popup window.) */
|
||||||
|
|
|
@ -78,7 +78,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-splitter {
|
.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
|
/* We don't let the splitter overlap the sidebar on Linux since the sidebar's
|
||||||
scrollbar is too narrow on Linux. */
|
scrollbar is too narrow on Linux. */
|
||||||
appearance: none;
|
appearance: none;
|
||||||
|
@ -86,22 +89,23 @@
|
||||||
border-inline-end-width: 1px;
|
border-inline-end-width: 1px;
|
||||||
border-color: var(--sidebar-border-color);
|
border-color: var(--sidebar-border-color);
|
||||||
min-width: 1px;
|
min-width: 1px;
|
||||||
width: 4px;
|
width: var(--splitter-width);
|
||||||
background-image: none !important;
|
background-image: none !important;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
margin-inline-start: -4px;
|
margin-inline-start: calc(-1 * var(--splitter-width));
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
#sidebar-box[positionend] + & {
|
#sidebar-box[positionend] + & {
|
||||||
border-inline-width: 1px 0;
|
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 */
|
/* stylelint-disable-next-line media-query-no-invalid */
|
||||||
@media (-moz-bool-pref: "sidebar.revamp") {
|
@media (-moz-bool-pref: "sidebar.revamp") {
|
||||||
|
--splitter-width: 6px;
|
||||||
transition: background-color 0.5s ease-in-out;
|
transition: background-color 0.5s ease-in-out;
|
||||||
border-color: transparent;
|
border-style: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--focus-outline-color);
|
background-color: var(--focus-outline-color);
|
||||||
|
|
|
@ -832,8 +832,6 @@ sidebar-main[expanded] > #vertical-tabs > #tabbrowser-tabs[orient="vertical"] .t
|
||||||
|
|
||||||
&[visible] {
|
&[visible] {
|
||||||
display: flex;
|
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 {
|
#alltabs-button {
|
||||||
list-style-image: url(chrome://global/skin/icons/arrow-down.svg);
|
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 {
|
#tabbrowser-tabs[hiddensoundplaying] ~ & > .toolbarbutton-badge-stack > .toolbarbutton-badge {
|
||||||
background: transparent url(chrome://browser/skin/tabbrowser/tab-audio-playing-small.svg);
|
background: transparent url(chrome://browser/skin/tabbrowser/tab-audio-playing-small.svg);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
|
@ -317,5 +317,4 @@ def googlevr_sdk(value, target):
|
||||||
|
|
||||||
set_define("MOZ_ANDROID_GOOGLE_VR", googlevr_sdk.enabled)
|
set_define("MOZ_ANDROID_GOOGLE_VR", googlevr_sdk.enabled)
|
||||||
set_config("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)
|
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_config("ENABLE_MOZSEARCH_PLUGIN", True, when="--enable-mozsearch-plugin")
|
||||||
set_define("MOZ_MOZSEARCH_PLUGIN", True, when="--enable-mozsearch-plugin")
|
|
||||||
|
|
||||||
|
|
||||||
@depends(
|
@depends(
|
||||||
|
|
|
@ -76,42 +76,3 @@ set_define(
|
||||||
check_msg="for memfd_create in sys/mman.h",
|
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", virtualenv_python3.path)
|
||||||
set_config("PYTHON3_VERSION", virtualenv_python3.str_version)
|
|
||||||
|
|
||||||
|
|
||||||
# Inject mozconfig options
|
# 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)
|
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
|
# The application/project to build
|
||||||
# ==============================================================
|
# ==============================================================
|
||||||
option(
|
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("EARLY_BETA_OR_EARLIER", milestone.is_early_beta_or_earlier)
|
||||||
set_define("MOZILLA_VERSION", depends(milestone)(lambda m: '"%s"' % m.version))
|
set_define("MOZILLA_VERSION", depends(milestone)(lambda m: '"%s"' % m.version))
|
||||||
set_config("MOZILLA_VERSION", milestone.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_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", milestone.app_version)
|
||||||
set_config("MOZ_APP_VERSION_DISPLAY", milestone.app_version_display)
|
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_optional = check_std_atomic_requirements()
|
||||||
is_libatomic_required = 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)
|
@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
|
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)
|
set_define("JS_WITHOUT_NSPR", True, when=js_without_nspr)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -406,9 +406,6 @@ def hazard_analysis(value):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
set_config("MOZ_HAZARD", hazard_analysis)
|
|
||||||
|
|
||||||
|
|
||||||
# Cross-compilation related things.
|
# Cross-compilation related things.
|
||||||
# ==============================================================
|
# ==============================================================
|
||||||
option(
|
option(
|
||||||
|
@ -428,20 +425,6 @@ def toolchain_prefix(value, host, target, cross_compiling):
|
||||||
return ("%s-" % target.toolchain, "%s-" % target.alias)
|
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
|
# Compilers
|
||||||
# ==============================================================
|
# ==============================================================
|
||||||
include("compilers-util.configure")
|
include("compilers-util.configure")
|
||||||
|
@ -1069,14 +1052,6 @@ def compiler_wrapper(wrapper, ccache):
|
||||||
return tuple(wrapper)
|
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
|
@dependable
|
||||||
def wasm():
|
def wasm():
|
||||||
return split_triplet("wasm32-wasi", allow_wasi=True)
|
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)
|
select_linker = select_linker_tmpl(target)
|
||||||
set_config("LINKER_KIND", select_linker.KIND)
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
@template
|
||||||
|
@ -2758,10 +2732,6 @@ def ub_signed_overflow_san_flags(
|
||||||
linker_flags.ldflags.extend(["-fsanitize=signed-integer-overflow", "-rdynamic"])
|
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(
|
option(
|
||||||
"--enable-unsigned-overflow-sanitizer",
|
"--enable-unsigned-overflow-sanitizer",
|
||||||
help="Enable UndefinedBehavior Sanitizer (Unsigned Integer Overflow Parts)",
|
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
|
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/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
import errno
|
|
||||||
import io
|
import io
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
|
@ -154,12 +153,7 @@ def main(argv):
|
||||||
js_config = config.copy()
|
js_config = config.copy()
|
||||||
pwd = os.getcwd()
|
pwd = os.getcwd()
|
||||||
try:
|
try:
|
||||||
try:
|
os.makedirs("js/src", exist_ok=True)
|
||||||
os.makedirs("js/src")
|
|
||||||
except OSError as e:
|
|
||||||
if e.errno != errno.EEXIST:
|
|
||||||
raise
|
|
||||||
|
|
||||||
os.chdir("js/src")
|
os.chdir("js/src")
|
||||||
js_config["OLD_CONFIGURE_SUBSTS"] = old_js_configure_substs
|
js_config["OLD_CONFIGURE_SUBSTS"] = old_js_configure_substs
|
||||||
js_config["OLD_CONFIGURE_DEFINES"] = old_js_configure_defines
|
js_config["OLD_CONFIGURE_DEFINES"] = old_js_configure_defines
|
||||||
|
|
|
@ -140,6 +140,9 @@ support-files = [
|
||||||
"test-network-exceptions.html",
|
"test-network-exceptions.html",
|
||||||
"test-network-request.html",
|
"test-network-request.html",
|
||||||
"test-network.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.html",
|
||||||
"test-non-javascript-mime.js",
|
"test-non-javascript-mime.js",
|
||||||
"test-non-javascript-mime.js^headers^",
|
"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_non_javascript_mime_warning.js"]
|
||||||
|
|
||||||
|
["browser_webconsole_json_mime_warning.js"]
|
||||||
|
|
||||||
["browser_webconsole_non_javascript_mime_worker_error.js"]
|
["browser_webconsole_non_javascript_mime_worker_error.js"]
|
||||||
|
|
||||||
["browser_webconsole_non_standard_doctype_errors.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
|
// XXXbz mTiming should know what channel it's for, so we don't
|
||||||
// need this hackery.
|
// need this hackery.
|
||||||
bool toBeReset = false;
|
const bool isJavaScript = SchemeIsJavascript(aLoadState->URI());
|
||||||
bool isJavaScript = SchemeIsJavascript(aLoadState->URI());
|
const bool isDownload = !aLoadState->FileName().IsVoid();
|
||||||
|
const bool toBeReset = !isJavaScript && MaybeInitTiming();
|
||||||
|
|
||||||
if (!isJavaScript) {
|
// FIXME(emilio): Should this be done by javascript: uris? What about external
|
||||||
toBeReset = MaybeInitTiming();
|
// protocols?
|
||||||
}
|
if (mTiming && !isDownload) {
|
||||||
bool isNotDownload = aLoadState->FileName().IsVoid();
|
|
||||||
if (mTiming && isNotDownload) {
|
|
||||||
mTiming->NotifyBeforeUnload();
|
mTiming->NotifyBeforeUnload();
|
||||||
}
|
}
|
||||||
// Check if the page doesn't want to be unloaded. The javascript:
|
// Check if the page doesn't want to be unloaded. The javascript:
|
||||||
// protocol handler deals with this for javascript: URLs.
|
// protocol handler deals with this for javascript: URLs.
|
||||||
if (!isJavaScript && isNotDownload &&
|
if (!isJavaScript && !isDownload &&
|
||||||
!aLoadState->NotifiedBeforeUnloadListeners() && mDocumentViewer) {
|
!aLoadState->NotifiedBeforeUnloadListeners() && mDocumentViewer) {
|
||||||
bool okToUnload;
|
|
||||||
|
|
||||||
// Check if request is exempted from HTTPSOnlyMode and if https-first is
|
// Check if request is exempted from HTTPSOnlyMode and if https-first is
|
||||||
// enabled, if so it means:
|
// enabled, if so it means:
|
||||||
// * https-first failed to upgrade request to https
|
// * https-first failed to upgrade request to https
|
||||||
// * we already asked for permission to unload and the user accepted
|
// * we already asked for permission to unload and the user accepted
|
||||||
// otherwise we wouldn't be here.
|
// otherwise we wouldn't be here.
|
||||||
bool isPrivateWin = GetOriginAttributes().IsPrivateBrowsing();
|
const bool isPrivateWin = GetOriginAttributes().IsPrivateBrowsing();
|
||||||
bool isHistoryOrReload = false;
|
const uint32_t loadType = aLoadState->LoadType();
|
||||||
uint32_t loadType = aLoadState->LoadType();
|
|
||||||
|
|
||||||
// Check if request is a reload.
|
// 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_CACHE ||
|
||||||
loadType == LOAD_RELOAD_BYPASS_PROXY ||
|
loadType == LOAD_RELOAD_BYPASS_PROXY ||
|
||||||
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE ||
|
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE ||
|
||||||
loadType == LOAD_HISTORY) {
|
loadType == LOAD_HISTORY;
|
||||||
isHistoryOrReload = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it isn't a reload, the request already failed to be upgraded and
|
// 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
|
// https-first is enabled then don't ask the user again for permission to
|
||||||
// unload and just unload.
|
// unload and just unload.
|
||||||
|
bool okToUnload;
|
||||||
if (!isHistoryOrReload && aLoadState->IsExemptFromHTTPSFirstMode() &&
|
if (!isHistoryOrReload && aLoadState->IsExemptFromHTTPSFirstMode() &&
|
||||||
nsHTTPSOnlyUtils::IsHttpsFirstModeEnabled(isPrivateWin)) {
|
nsHTTPSOnlyUtils::IsHttpsFirstModeEnabled(isPrivateWin)) {
|
||||||
rv = mDocumentViewer->PermitUnload(
|
rv = mDocumentViewer->PermitUnload(
|
||||||
|
@ -9324,7 +9320,7 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTiming && isNotDownload) {
|
if (mTiming && !isDownload) {
|
||||||
mTiming->NotifyUnloadAccepted(mCurrentURI);
|
mTiming->NotifyUnloadAccepted(mCurrentURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9358,7 +9354,7 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
|
||||||
// new request parameter.
|
// new request parameter.
|
||||||
// Also pass nullptr for the document, since it doesn't affect the return
|
// Also pass nullptr for the document, since it doesn't affect the return
|
||||||
// value for our purposes here.
|
// value for our purposes here.
|
||||||
bool savePresentation =
|
const bool savePresentation =
|
||||||
CanSavePresentation(aLoadState->LoadType(), nullptr, nullptr,
|
CanSavePresentation(aLoadState->LoadType(), nullptr, nullptr,
|
||||||
/* aReportBFCacheComboTelemetry */ true);
|
/* aReportBFCacheComboTelemetry */ true);
|
||||||
|
|
||||||
|
@ -9379,12 +9375,12 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't stop current network activity for javascript: URL's since
|
// Don't stop current network activity for javascript: URL's since they might
|
||||||
// they might not result in any data, and thus nothing should be
|
// not result in any data, and thus nothing should be stopped in those cases.
|
||||||
// stopped in those cases. In the case where they do result in
|
// In the case where they do result in data, the javascript: URL channel takes
|
||||||
// data, the javascript: URL channel takes care of stopping
|
// care of stopping current network activity. Similarly, downloads don't
|
||||||
// current network activity.
|
// unload this document...
|
||||||
if (!isJavaScript && isNotDownload) {
|
if (!isJavaScript && !isDownload) {
|
||||||
// Stop any current network activity.
|
// Stop any current network activity.
|
||||||
// Also stop content if this is a zombie doc. otherwise
|
// Also stop content if this is a zombie doc. otherwise
|
||||||
// the onload will be delayed by other loads initiated in the
|
// 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.
|
// didn't fully load before the next load was initiated.
|
||||||
// If not a zombie, don't stop content until data
|
// If not a zombie, don't stop content until data
|
||||||
// starts arriving from the new URI...
|
// starts arriving from the new URI...
|
||||||
|
|
||||||
if ((mDocumentViewer && mDocumentViewer->GetPreviousViewer()) ||
|
if ((mDocumentViewer && mDocumentViewer->GetPreviousViewer()) ||
|
||||||
LOAD_TYPE_HAS_FLAGS(aLoadState->LoadType(), LOAD_FLAGS_STOP_CONTENT)) {
|
LOAD_TYPE_HAS_FLAGS(aLoadState->LoadType(), LOAD_FLAGS_STOP_CONTENT)) {
|
||||||
rv = Stop(nsIWebNavigation::STOP_ALL);
|
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
|
* AbortSignalImpl is a minimal implementation without an associated global
|
||||||
* and without event dispatching, those are added in AbortSignal.
|
* and without event dispatching, those are added in AbortSignal.
|
||||||
* See Bug 1478101
|
* See Bug 1478101
|
||||||
|
@ -60,7 +63,7 @@ class AbortSignalImpl : public nsISupports, public SupportsWeakPtr {
|
||||||
// Helper for other DOM code
|
// Helper for other DOM code
|
||||||
JS::Value RawReason() const;
|
JS::Value RawReason() const;
|
||||||
|
|
||||||
virtual void SignalAbort(JS::Handle<JS::Value> aReason);
|
void SignalAbort(JS::Handle<JS::Value> aReason);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Subclasses of this class must call these Traverse and Unlink functions
|
// 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 ~AbortSignalImpl() { UnlinkFollowers(); }
|
||||||
|
|
||||||
|
virtual void SignalAbortWithDependents();
|
||||||
|
|
||||||
|
virtual void RunAbortSteps();
|
||||||
|
|
||||||
void SetAborted(JS::Handle<JS::Value> aReason);
|
void SetAborted(JS::Handle<JS::Value> aReason);
|
||||||
|
|
||||||
JS::Heap<JS::Value> mReason;
|
JS::Heap<JS::Value> mReason;
|
||||||
|
@ -83,7 +90,10 @@ class AbortSignalImpl : public nsISupports, public SupportsWeakPtr {
|
||||||
|
|
||||||
void UnlinkFollowers();
|
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
|
// |AbortFollower::Unfollow| (also called by the destructor) will remove
|
||||||
// from this array. Finally, calling |SignalAbort()| will (after running all
|
// from this array. Finally, calling |SignalAbort()| will (after running all
|
||||||
// abort algorithms) empty this and make all contained followers |Unfollow()|.
|
// 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(); }
|
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) {
|
void AbortSignalImpl::SignalAbort(JS::Handle<JS::Value> aReason) {
|
||||||
// Step 1.
|
// Step 1: If signal is aborted, then return.
|
||||||
if (mAborted) {
|
if (mAborted) {
|
||||||
return;
|
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);
|
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
|
// When there are multiple followers, the follower removal algorithm
|
||||||
// https://dom.spec.whatwg.org/#abortsignal-remove could be invoked in an
|
// https://dom.spec.whatwg.org/#abortsignal-remove could be invoked in an
|
||||||
// earlier algorithm to remove a later algorithm, so |mFollowers| must be a
|
// 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();
|
follower->RunAbortAlgorithm();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4.
|
// Step 2: Empty signal’s abort algorithms.
|
||||||
UnlinkFollowers();
|
UnlinkFollowers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,14 +295,26 @@ already_AddRefed<AbortSignal> AbortSignal::Any(
|
||||||
RefPtr<AbortSignal> resultSignal =
|
RefPtr<AbortSignal> resultSignal =
|
||||||
new AbortSignal(aGlobal, false, JS::UndefinedHandleValue);
|
new AbortSignal(aGlobal, false, JS::UndefinedHandleValue);
|
||||||
|
|
||||||
// Step 2. For each signal of signals: if signal is aborted, then set
|
if (!aSignals.IsEmpty()) {
|
||||||
// resultSignal's abort reason to signal's abort reason and return
|
// (Prepare for step 2 which uses the reason of this. Cannot use
|
||||||
// resultSignal.
|
// RawReason because that can cause constructing new DOMException for each
|
||||||
for (const auto& signal : aSignals) {
|
// dependent signal instead of sharing the single one.)
|
||||||
if (signal->Aborted()) {
|
AutoJSAPI jsapi;
|
||||||
JS::Rooted<JS::Value> reason(RootingCx(), signal->RawReason());
|
if (!jsapi.Init(aGlobal)) {
|
||||||
resultSignal->SetAborted(reason);
|
return nullptr;
|
||||||
return resultSignal.forget();
|
}
|
||||||
|
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
|
// Step 3 - 6 of https://dom.spec.whatwg.org/#abortsignal-signal-abort
|
||||||
void AbortSignal::SignalAbort(JS::Handle<JS::Value> aReason) {
|
void AbortSignal::SignalAbortWithDependents() {
|
||||||
// Step 1, in case "signal abort" algorithm is called directly
|
// Step 3: Let dependentSignalsToAbort be a new list.
|
||||||
if (Aborted()) {
|
nsTArray<RefPtr<AbortSignal>> dependentSignalsToAbort;
|
||||||
return;
|
|
||||||
|
// 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.
|
// Step 5: Run the abort steps for signal.
|
||||||
AbortSignalImpl::SignalAbort(aReason);
|
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;
|
EventInit init;
|
||||||
init.mBubbles = false;
|
init.mBubbles = false;
|
||||||
init.mCancelable = false;
|
init.mCancelable = false;
|
||||||
|
@ -358,14 +427,6 @@ void AbortSignal::SignalAbort(JS::Handle<JS::Value> aReason) {
|
||||||
event->SetTrusted(true);
|
event->SetTrusted(true);
|
||||||
|
|
||||||
DispatchEvent(*event);
|
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; }
|
bool AbortSignal::Dependent() const { return mDependent; }
|
||||||
|
|
|
@ -55,9 +55,6 @@ class AbortSignal : public DOMEventTargetHelper, public AbortSignalImpl {
|
||||||
|
|
||||||
void ThrowIfAborted(JSContext* aCx, ErrorResult& aRv);
|
void ThrowIfAborted(JSContext* aCx, ErrorResult& aRv);
|
||||||
|
|
||||||
// AbortSignalImpl
|
|
||||||
void SignalAbort(JS::Handle<JS::Value> aReason) override;
|
|
||||||
|
|
||||||
virtual bool IsTaskSignal() const { return false; }
|
virtual bool IsTaskSignal() const { return false; }
|
||||||
|
|
||||||
bool Dependent() const;
|
bool Dependent() const;
|
||||||
|
@ -67,6 +64,10 @@ class AbortSignal : public DOMEventTargetHelper, public AbortSignalImpl {
|
||||||
|
|
||||||
void MakeDependentOn(AbortSignal* aSignal);
|
void MakeDependentOn(AbortSignal* aSignal);
|
||||||
|
|
||||||
|
void SignalAbortWithDependents() override;
|
||||||
|
|
||||||
|
void RunAbortSteps() override;
|
||||||
|
|
||||||
nsTArray<WeakPtr<AbortSignal>> mSourceSignals;
|
nsTArray<WeakPtr<AbortSignal>> mSourceSignals;
|
||||||
nsTArray<RefPtr<AbortSignal>> mDependentSignals;
|
nsTArray<RefPtr<AbortSignal>> mDependentSignals;
|
||||||
|
|
||||||
|
|
|
@ -1493,7 +1493,7 @@ inline Maybe<Enum> StringToEnum(const StringT& aString) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Enum>
|
template <typename Enum>
|
||||||
inline const nsCString& GetEnumString(Enum stringId) {
|
inline constexpr const nsLiteralCString& GetEnumString(Enum stringId) {
|
||||||
MOZ_RELEASE_ASSERT(
|
MOZ_RELEASE_ASSERT(
|
||||||
static_cast<size_t>(stringId) <
|
static_cast<size_t>(stringId) <
|
||||||
mozilla::ArrayLength(binding_detail::EnumStrings<Enum>::Values));
|
mozilla::ArrayLength(binding_detail::EnumStrings<Enum>::Values));
|
||||||
|
|
|
@ -12458,22 +12458,22 @@ class CGEnum(CGThing):
|
||||||
declare=fill(
|
declare=fill(
|
||||||
"""
|
"""
|
||||||
template <> struct EnumStrings<${name}> {
|
template <> struct EnumStrings<${name}> {
|
||||||
static const nsLiteralCString Values[${count}];
|
static constexpr nsLiteralCString Values[${count}] {
|
||||||
};
|
$*{entries}
|
||||||
""",
|
};
|
||||||
name=self.enum.identifier.name,
|
|
||||||
count=self.nEnumStrings(),
|
|
||||||
),
|
|
||||||
define=fill(
|
|
||||||
"""
|
|
||||||
const nsLiteralCString EnumStrings<${name}>::Values[${count}] = {
|
|
||||||
$*{entries}
|
|
||||||
};
|
};
|
||||||
""",
|
""",
|
||||||
name=self.enum.identifier.name,
|
name=self.enum.identifier.name,
|
||||||
count=self.nEnumStrings(),
|
count=self.nEnumStrings(),
|
||||||
entries="".join('"%s"_ns,\n' % val for val in self.enum.values()),
|
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)
|
toJSValue = CGEnumToJSValue(enum)
|
||||||
|
|
|
@ -2598,24 +2598,91 @@ bool SharedContextWebgl::PruneTextureMemory(size_t aMargin, bool aPruneUnused) {
|
||||||
return mNumTextureHandles < oldItems;
|
return mNumTextureHandles < oldItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawTargetWebgl::FillRect(const Rect& aRect, const Pattern& aPattern,
|
// Attempt to convert a linear gradient to a 1D ramp texture.
|
||||||
const DrawOptions& aOptions) {
|
Maybe<SurfacePattern> DrawTargetWebgl::LinearGradientToSurface(
|
||||||
if (SupportsPattern(aPattern)) {
|
const RectDouble& aBounds, const Pattern& aPattern) {
|
||||||
RectDouble xformRect = TransformDouble(aRect);
|
MOZ_ASSERT(aPattern.GetType() == PatternType::LINEAR_GRADIENT);
|
||||||
if (aPattern.GetType() == PatternType::COLOR) {
|
const auto& gradient = static_cast<const LinearGradientPattern&>(aPattern);
|
||||||
if (Maybe<Rect> clipped = RectClippedToViewport(xformRect)) {
|
// The gradient points must be transformed by the gradient's matrix.
|
||||||
// If the pattern is transform-invariant and the rect clips to the
|
Point gradBegin = gradient.mMatrix.TransformPoint(gradient.mBegin);
|
||||||
// viewport, just clip drawing to the viewport to avoid transform
|
Point gradEnd = gradient.mMatrix.TransformPoint(gradient.mEnd);
|
||||||
// issues.
|
// Get the gradient points in user-space.
|
||||||
DrawRect(*clipped, aPattern, aOptions, Nothing(), nullptr, false);
|
Point begin = mTransform.TransformPoint(gradBegin);
|
||||||
return;
|
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;
|
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) {
|
if (!mWebglValid) {
|
||||||
MarkSkiaChanged(aOptions);
|
MarkSkiaChanged(aOptions);
|
||||||
mSkia->FillRect(aRect, aPattern, 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();
|
const SkPath& skiaPath = static_cast<const PathSkia*>(aPath)->GetPath();
|
||||||
SkRect skiaRect = SkRect::MakeEmpty();
|
SkRect skiaRect = SkRect::MakeEmpty();
|
||||||
// Draw the path as a simple rectangle with a supported pattern when possible.
|
// 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 rect = SkRectToRectDouble(skiaRect);
|
||||||
RectDouble xformRect = TransformDouble(rect);
|
RectDouble xformRect = TransformDouble(rect);
|
||||||
if (aPattern.GetType() == PatternType::COLOR) {
|
if (aPattern.GetType() == PatternType::COLOR) {
|
||||||
|
@ -2784,9 +2851,21 @@ void DrawTargetWebgl::Fill(const Path* aPath, const Pattern& aPattern,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RectInsidePrecisionLimits(xformRect)) {
|
if (RectInsidePrecisionLimits(xformRect)) {
|
||||||
DrawRect(NarrowToFloat(rect), aPattern, aOptions);
|
if (SupportsPattern(aPattern)) {
|
||||||
return;
|
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 aTransformed = true, bool aClipped = true,
|
||||||
bool aAccelOnly = false, bool aForceUpdate = false,
|
bool aAccelOnly = false, bool aForceUpdate = false,
|
||||||
const StrokeOptions* aStrokeOptions = nullptr);
|
const StrokeOptions* aStrokeOptions = nullptr);
|
||||||
|
Maybe<SurfacePattern> LinearGradientToSurface(const RectDouble& aBounds,
|
||||||
|
const Pattern& aPattern);
|
||||||
|
|
||||||
ColorPattern GetClearPattern() const;
|
ColorPattern GetClearPattern() const;
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
const char* kFetchPriorityAttributeValueHigh = "high";
|
|
||||||
const char* kFetchPriorityAttributeValueLow = "low";
|
|
||||||
const char* kFetchPriorityAttributeValueAuto = "auto";
|
|
||||||
|
|
||||||
FetchPriority ToFetchPriority(RequestPriority aRequestPriority) {
|
FetchPriority ToFetchPriority(RequestPriority aRequestPriority) {
|
||||||
switch (aRequestPriority) {
|
switch (aRequestPriority) {
|
||||||
|
|
|
@ -37,9 +37,9 @@ void LogPriorityMapping(LazyLogModule& aLazyLogModule,
|
||||||
FetchPriority aFetchPriority,
|
FetchPriority aFetchPriority,
|
||||||
int32_t aSupportsPriority);
|
int32_t aSupportsPriority);
|
||||||
|
|
||||||
extern const char* kFetchPriorityAttributeValueHigh;
|
constexpr const char kFetchPriorityAttributeValueHigh[] = "high";
|
||||||
extern const char* kFetchPriorityAttributeValueLow;
|
constexpr const char kFetchPriorityAttributeValueLow[] = "low";
|
||||||
extern const char* kFetchPriorityAttributeValueAuto;
|
constexpr const char kFetchPriorityAttributeValueAuto[] = "auto";
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -229,10 +229,10 @@ nsresult HTMLDNSPrefetch::Prefetch(
|
||||||
const OriginAttributes& aPartitionedPrincipalOriginAttributes,
|
const OriginAttributes& aPartitionedPrincipalOriginAttributes,
|
||||||
nsIDNSService::DNSFlags flags) {
|
nsIDNSService::DNSFlags flags) {
|
||||||
if (IsNeckoChild()) {
|
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
|
// considers empty strings to be valid hostnames
|
||||||
if (!hostname.IsEmpty() &&
|
if (!hostname.IsEmpty() &&
|
||||||
net_IsValidHostName(NS_ConvertUTF16toUTF8(hostname))) {
|
net_IsValidDNSHost(NS_ConvertUTF16toUTF8(hostname))) {
|
||||||
// during shutdown gNeckoChild might be null
|
// during shutdown gNeckoChild might be null
|
||||||
if (gNeckoChild) {
|
if (gNeckoChild) {
|
||||||
gNeckoChild->SendHTMLDNSPrefetch(
|
gNeckoChild->SendHTMLDNSPrefetch(
|
||||||
|
@ -312,10 +312,10 @@ nsresult HTMLDNSPrefetch::CancelPrefetch(
|
||||||
nsIDNSService::DNSFlags flags, nsresult aReason) {
|
nsIDNSService::DNSFlags flags, nsresult aReason) {
|
||||||
// Forward this request to Necko Parent if we're a child process
|
// Forward this request to Necko Parent if we're a child process
|
||||||
if (IsNeckoChild()) {
|
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
|
// considers empty strings to be valid hostnames
|
||||||
if (!hostname.IsEmpty() &&
|
if (!hostname.IsEmpty() &&
|
||||||
net_IsValidHostName(NS_ConvertUTF16toUTF8(hostname))) {
|
net_IsValidDNSHost(NS_ConvertUTF16toUTF8(hostname))) {
|
||||||
// during shutdown gNeckoChild might be null
|
// during shutdown gNeckoChild might be null
|
||||||
if (gNeckoChild && gNeckoChild->CanSend()) {
|
if (gNeckoChild && gNeckoChild->CanSend()) {
|
||||||
gNeckoChild->SendCancelHTMLDNSPrefetch(
|
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_DECIMAL = 7;
|
||||||
static const uint8_t NS_INPUTMODE_SEARCH = 8;
|
static const uint8_t NS_INPUTMODE_SEARCH = 8;
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kInputmodeTable[] = {
|
static constexpr nsAttrValue::EnumTable kInputmodeTable[] = {
|
||||||
{"none", NS_INPUTMODE_NONE},
|
{"none", NS_INPUTMODE_NONE},
|
||||||
{"text", NS_INPUTMODE_TEXT},
|
{"text", NS_INPUTMODE_TEXT},
|
||||||
{"tel", NS_INPUTMODE_TEL},
|
{"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_SEARCH = 6;
|
||||||
static const uint8_t NS_ENTERKEYHINT_SEND = 7;
|
static const uint8_t NS_ENTERKEYHINT_SEND = 7;
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kEnterKeyHintTable[] = {
|
static constexpr nsAttrValue::EnumTable kEnterKeyHintTable[] = {
|
||||||
{"enter", NS_ENTERKEYHINT_ENTER},
|
{"enter", NS_ENTERKEYHINT_ENTER},
|
||||||
{"done", NS_ENTERKEYHINT_DONE},
|
{"done", NS_ENTERKEYHINT_DONE},
|
||||||
{"go", NS_ENTERKEYHINT_GO},
|
{"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_WORDS = 3;
|
||||||
static const uint8_t NS_AUTOCAPITALIZE_CHARACTERS = 4;
|
static const uint8_t NS_AUTOCAPITALIZE_CHARACTERS = 4;
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kAutocapitalizeTable[] = {
|
static constexpr nsAttrValue::EnumTable kAutocapitalizeTable[] = {
|
||||||
{"none", NS_AUTOCAPITALIZE_NONE},
|
{"none", NS_AUTOCAPITALIZE_NONE},
|
||||||
{"sentences", NS_AUTOCAPITALIZE_SENTENCES},
|
{"sentences", NS_AUTOCAPITALIZE_SENTENCES},
|
||||||
{"words", NS_AUTOCAPITALIZE_WORDS},
|
{"words", NS_AUTOCAPITALIZE_WORDS},
|
||||||
|
@ -168,7 +168,7 @@ nsresult nsGenericHTMLElement::CopyInnerTo(Element* aDst) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kDirTable[] = {
|
static constexpr nsAttrValue::EnumTable kDirTable[] = {
|
||||||
{"ltr", Directionality::Ltr},
|
{"ltr", Directionality::Ltr},
|
||||||
{"rtl", Directionality::Rtl},
|
{"rtl", Directionality::Rtl},
|
||||||
{"auto", Directionality::Auto},
|
{"auto", Directionality::Auto},
|
||||||
|
@ -179,11 +179,11 @@ namespace {
|
||||||
// See <https://html.spec.whatwg.org/#the-popover-attribute>.
|
// See <https://html.spec.whatwg.org/#the-popover-attribute>.
|
||||||
enum class PopoverAttributeKeyword : uint8_t { Auto, EmptyString, Manual };
|
enum class PopoverAttributeKeyword : uint8_t { Auto, EmptyString, Manual };
|
||||||
|
|
||||||
static const char* kPopoverAttributeValueAuto = "auto";
|
static constexpr const char kPopoverAttributeValueAuto[] = "auto";
|
||||||
static const char* kPopoverAttributeValueEmptyString = "";
|
static constexpr const char kPopoverAttributeValueEmptyString[] = "";
|
||||||
static const char* kPopoverAttributeValueManual = "manual";
|
static constexpr const char kPopoverAttributeValueManual[] = "manual";
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kPopoverTable[] = {
|
static constexpr nsAttrValue::EnumTable kPopoverTable[] = {
|
||||||
{kPopoverAttributeValueAuto, PopoverAttributeKeyword::Auto},
|
{kPopoverAttributeValueAuto, PopoverAttributeKeyword::Auto},
|
||||||
{kPopoverAttributeValueEmptyString, PopoverAttributeKeyword::EmptyString},
|
{kPopoverAttributeValueEmptyString, PopoverAttributeKeyword::EmptyString},
|
||||||
{kPopoverAttributeValueManual, PopoverAttributeKeyword::Manual},
|
{kPopoverAttributeValueManual, PopoverAttributeKeyword::Manual},
|
||||||
|
@ -210,7 +210,7 @@ FetchPriority nsGenericHTMLElement::ToFetchPriority(const nsAString& aValue) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// <https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fetch-priority-attributes>.
|
// <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},
|
{kFetchPriorityAttributeValueHigh, FetchPriority::High},
|
||||||
{kFetchPriorityAttributeValueLow, FetchPriority::Low},
|
{kFetchPriorityAttributeValueLow, FetchPriority::Low},
|
||||||
{kFetchPriorityAttributeValueAuto, FetchPriority::Auto},
|
{kFetchPriorityAttributeValueAuto, FetchPriority::Auto},
|
||||||
|
@ -1109,7 +1109,7 @@ nsMapRuleToAttributesFunc nsGenericHTMLElement::GetAttributeMappingFunction()
|
||||||
return &MapCommonAttributesInto;
|
return &MapCommonAttributesInto;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kDivAlignTable[] = {
|
static constexpr nsAttrValue::EnumTable kDivAlignTable[] = {
|
||||||
{"left", StyleTextAlign::MozLeft},
|
{"left", StyleTextAlign::MozLeft},
|
||||||
{"right", StyleTextAlign::MozRight},
|
{"right", StyleTextAlign::MozRight},
|
||||||
{"center", StyleTextAlign::MozCenter},
|
{"center", StyleTextAlign::MozCenter},
|
||||||
|
@ -1117,7 +1117,7 @@ static const nsAttrValue::EnumTable kDivAlignTable[] = {
|
||||||
{"justify", StyleTextAlign::Justify},
|
{"justify", StyleTextAlign::Justify},
|
||||||
{nullptr, 0}};
|
{nullptr, 0}};
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kFrameborderTable[] = {
|
static constexpr nsAttrValue::EnumTable kFrameborderTable[] = {
|
||||||
{"yes", FrameBorderProperty::Yes},
|
{"yes", FrameBorderProperty::Yes},
|
||||||
{"no", FrameBorderProperty::No},
|
{"no", FrameBorderProperty::No},
|
||||||
{"1", FrameBorderProperty::One},
|
{"1", FrameBorderProperty::One},
|
||||||
|
@ -1125,7 +1125,7 @@ static const nsAttrValue::EnumTable kFrameborderTable[] = {
|
||||||
{nullptr, 0}};
|
{nullptr, 0}};
|
||||||
|
|
||||||
// TODO(emilio): Nobody uses the parsed attribute here.
|
// TODO(emilio): Nobody uses the parsed attribute here.
|
||||||
static const nsAttrValue::EnumTable kScrollingTable[] = {
|
static constexpr nsAttrValue::EnumTable kScrollingTable[] = {
|
||||||
{"yes", ScrollingAttribute::Yes},
|
{"yes", ScrollingAttribute::Yes},
|
||||||
{"no", ScrollingAttribute::No},
|
{"no", ScrollingAttribute::No},
|
||||||
{"on", ScrollingAttribute::On},
|
{"on", ScrollingAttribute::On},
|
||||||
|
@ -1135,7 +1135,7 @@ static const nsAttrValue::EnumTable kScrollingTable[] = {
|
||||||
{"auto", ScrollingAttribute::Auto},
|
{"auto", ScrollingAttribute::Auto},
|
||||||
{nullptr, 0}};
|
{nullptr, 0}};
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kTableVAlignTable[] = {
|
static constexpr nsAttrValue::EnumTable kTableVAlignTable[] = {
|
||||||
{"top", StyleVerticalAlignKeyword::Top},
|
{"top", StyleVerticalAlignKeyword::Top},
|
||||||
{"middle", StyleVerticalAlignKeyword::Middle},
|
{"middle", StyleVerticalAlignKeyword::Middle},
|
||||||
{"bottom", StyleVerticalAlignKeyword::Bottom},
|
{"bottom", StyleVerticalAlignKeyword::Bottom},
|
||||||
|
@ -1144,7 +1144,7 @@ static const nsAttrValue::EnumTable kTableVAlignTable[] = {
|
||||||
|
|
||||||
bool nsGenericHTMLElement::ParseAlignValue(const nsAString& aString,
|
bool nsGenericHTMLElement::ParseAlignValue(const nsAString& aString,
|
||||||
nsAttrValue& aResult) {
|
nsAttrValue& aResult) {
|
||||||
static const nsAttrValue::EnumTable kAlignTable[] = {
|
static constexpr nsAttrValue::EnumTable kAlignTable[] = {
|
||||||
{"left", StyleTextAlign::Left},
|
{"left", StyleTextAlign::Left},
|
||||||
{"right", StyleTextAlign::Right},
|
{"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},
|
{"left", StyleTextAlign::Left},
|
||||||
{"right", StyleTextAlign::Right},
|
{"right", StyleTextAlign::Right},
|
||||||
{"center", StyleTextAlign::Center},
|
{"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.
|
// 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},
|
{"left", StyleTextAlign::MozLeft},
|
||||||
{"right", StyleTextAlign::MozRight},
|
{"right", StyleTextAlign::MozRight},
|
||||||
{"center", StyleTextAlign::MozCenter},
|
{"center", StyleTextAlign::MozCenter},
|
||||||
|
@ -1251,9 +1251,7 @@ bool nsGenericHTMLElement::ParseImageAttribute(nsAtom* aAttribute,
|
||||||
bool nsGenericHTMLElement::ParseReferrerAttribute(const nsAString& aString,
|
bool nsGenericHTMLElement::ParseReferrerAttribute(const nsAString& aString,
|
||||||
nsAttrValue& aResult) {
|
nsAttrValue& aResult) {
|
||||||
using mozilla::dom::ReferrerInfo;
|
using mozilla::dom::ReferrerInfo;
|
||||||
// This is a bit sketchy, we assume GetEnumString(…).get() points to a static
|
static constexpr nsAttrValue::EnumTable kReferrerPolicyTable[] = {
|
||||||
// buffer, relying on the fact that GetEnumString(…) returns a literal string.
|
|
||||||
static const nsAttrValue::EnumTable kReferrerPolicyTable[] = {
|
|
||||||
{GetEnumString(ReferrerPolicy::No_referrer).get(),
|
{GetEnumString(ReferrerPolicy::No_referrer).get(),
|
||||||
static_cast<int16_t>(ReferrerPolicy::No_referrer)},
|
static_cast<int16_t>(ReferrerPolicy::No_referrer)},
|
||||||
{GetEnumString(ReferrerPolicy::Origin).get(),
|
{GetEnumString(ReferrerPolicy::Origin).get(),
|
||||||
|
@ -2770,7 +2768,7 @@ void nsGenericHTMLFormControlElement::SetFormAutofillState(
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
static const nsAttrValue::EnumTable kPopoverTargetActionTable[] = {
|
static constexpr nsAttrValue::EnumTable kPopoverTargetActionTable[] = {
|
||||||
{"toggle", PopoverTargetAction::Toggle},
|
{"toggle", PopoverTargetAction::Toggle},
|
||||||
{"show", PopoverTargetAction::Show},
|
{"show", PopoverTargetAction::Show},
|
||||||
{"hide", PopoverTargetAction::Hide},
|
{"hide", PopoverTargetAction::Hide},
|
||||||
|
|
|
@ -53,7 +53,7 @@ bool PrivateAttribution::GetSourceHostIfNonPrivate(nsACString& aSourceHost,
|
||||||
|
|
||||||
[[nodiscard]] static bool ValidateHost(const nsACString& aHost,
|
[[nodiscard]] static bool ValidateHost(const nsACString& aHost,
|
||||||
ErrorResult& aRv) {
|
ErrorResult& aRv) {
|
||||||
if (!net_IsValidHostName(aHost)) {
|
if (!net_IsValidDNSHost(aHost)) {
|
||||||
aRv.ThrowSyntaxError(aHost + " is not a valid host name"_ns);
|
aRv.ThrowSyntaxError(aHost + " is not a valid host name"_ns);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "SVGPolyElement.h"
|
#include "SVGPolyElement.h"
|
||||||
#include "DOMSVGPointList.h"
|
#include "DOMSVGPointList.h"
|
||||||
|
#include "mozilla/dom/SVGAnimatedLength.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "SVGContentUtils.h"
|
#include "SVGContentUtils.h"
|
||||||
|
|
||||||
|
@ -48,13 +49,15 @@ void SVGPolyElement::GetMarkPoints(nsTArray<SVGMark>* aMarks) {
|
||||||
|
|
||||||
if (!points.Length()) return;
|
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));
|
aMarks->AppendElement(SVGMark(px, py, 0, SVGMark::eStart));
|
||||||
|
|
||||||
for (uint32_t i = 1; i < points.Length(); ++i) {
|
for (uint32_t i = 1; i < points.Length(); ++i) {
|
||||||
float x = points[i].mX;
|
float x = points[i].mX * zoom;
|
||||||
float y = points[i].mY;
|
float y = points[i].mY * zoom;
|
||||||
float angle = std::atan2(y - py, x - px);
|
float angle = std::atan2(y - py, x - px);
|
||||||
|
|
||||||
// Vertex marker.
|
// Vertex marker.
|
||||||
|
@ -93,18 +96,20 @@ bool SVGPolyElement::GetGeometryBounds(Rect* aBounds,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float zoom = UserSpaceMetrics::GetZoom(this);
|
||||||
|
|
||||||
if (aToBoundsSpace.IsRectilinear()) {
|
if (aToBoundsSpace.IsRectilinear()) {
|
||||||
// We can avoid transforming each point and just transform the result.
|
// We can avoid transforming each point and just transform the result.
|
||||||
// Important for large point lists.
|
// 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) {
|
for (uint32_t i = 1; i < points.Length(); ++i) {
|
||||||
bounds.ExpandToEnclose(points[i]);
|
bounds.ExpandToEnclose(points[i] * zoom);
|
||||||
}
|
}
|
||||||
*aBounds = aToBoundsSpace.TransformBounds(bounds);
|
*aBounds = aToBoundsSpace.TransformBounds(bounds);
|
||||||
} else {
|
} 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) {
|
for (uint32_t i = 1; i < points.Length(); ++i) {
|
||||||
aBounds->ExpandToEnclose(aToBoundsSpace.TransformPoint(points[i]));
|
aBounds->ExpandToEnclose(aToBoundsSpace.TransformPoint(points[i] * zoom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "mozilla/dom/SVGPolygonElement.h"
|
#include "mozilla/dom/SVGPolygonElement.h"
|
||||||
#include "mozilla/dom/SVGPolygonElementBinding.h"
|
#include "mozilla/dom/SVGPolygonElementBinding.h"
|
||||||
|
#include "mozilla/dom/SVGAnimatedLength.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "SVGContentUtils.h"
|
#include "SVGContentUtils.h"
|
||||||
|
|
||||||
|
@ -64,9 +65,11 @@ already_AddRefed<Path> SVGPolygonElement::BuildPath(PathBuilder* aBuilder) {
|
||||||
return nullptr;
|
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) {
|
for (uint32_t i = 1; i < points.Length(); ++i) {
|
||||||
aBuilder->LineTo(points[i]);
|
aBuilder->LineTo(points[i] * zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
aBuilder->Close();
|
aBuilder->Close();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "mozilla/dom/SVGPolylineElement.h"
|
#include "mozilla/dom/SVGPolylineElement.h"
|
||||||
#include "mozilla/dom/SVGPolylineElementBinding.h"
|
#include "mozilla/dom/SVGPolylineElementBinding.h"
|
||||||
|
#include "mozilla/dom/SVGAnimatedLength.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
@ -41,9 +42,11 @@ already_AddRefed<Path> SVGPolylineElement::BuildPath(PathBuilder* aBuilder) {
|
||||||
return nullptr;
|
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) {
|
for (uint32_t i = 1; i < points.Length(); ++i) {
|
||||||
aBuilder->LineTo(points[i]);
|
aBuilder->LineTo(points[i] * zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
return aBuilder->Finish();
|
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
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
7
gradlew
vendored
7
gradlew
vendored
|
@ -15,6 +15,8 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
|
@ -55,7 +57,7 @@
|
||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (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.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
@ -84,7 +86,8 @@ done
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
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 See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace gc {
|
||||||
|
|
||||||
class Arena;
|
class Arena;
|
||||||
struct Cell;
|
struct Cell;
|
||||||
class TenuredChunk;
|
class ArenaChunk;
|
||||||
class StoreBuffer;
|
class StoreBuffer;
|
||||||
class TenuredCell;
|
class TenuredCell;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ const size_t ArenaBitmapWords = HowMany(ArenaBitmapBits, JS_BITS_PER_WORD);
|
||||||
|
|
||||||
enum class ChunkKind : uint8_t {
|
enum class ChunkKind : uint8_t {
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
TenuredHeap,
|
TenuredArenas,
|
||||||
NurseryToSpace,
|
NurseryToSpace,
|
||||||
NurseryFromSpace
|
NurseryFromSpace
|
||||||
};
|
};
|
||||||
|
@ -97,13 +97,13 @@ class ChunkBase {
|
||||||
// Initialize a tenured heap chunk.
|
// Initialize a tenured heap chunk.
|
||||||
explicit ChunkBase(JSRuntime* rt) {
|
explicit ChunkBase(JSRuntime* rt) {
|
||||||
MOZ_ASSERT((uintptr_t(this) & ChunkMask) == 0);
|
MOZ_ASSERT((uintptr_t(this) & ChunkMask) == 0);
|
||||||
initBaseForTenuredChunk(rt);
|
initBaseForArenaChunk(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initBaseForTenuredChunk(JSRuntime* rt) {
|
void initBaseForArenaChunk(JSRuntime* rt) {
|
||||||
runtime = rt;
|
runtime = rt;
|
||||||
storeBuffer = nullptr;
|
storeBuffer = nullptr;
|
||||||
kind = ChunkKind::TenuredHeap;
|
kind = ChunkKind::TenuredArenas;
|
||||||
nurseryChunkIndex = UINT8_MAX;
|
nurseryChunkIndex = UINT8_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ class ChunkBase {
|
||||||
ChunkKind getKind() const {
|
ChunkKind getKind() const {
|
||||||
MOZ_ASSERT_IF(storeBuffer, kind == ChunkKind::NurseryToSpace ||
|
MOZ_ASSERT_IF(storeBuffer, kind == ChunkKind::NurseryToSpace ||
|
||||||
kind == ChunkKind::NurseryFromSpace);
|
kind == ChunkKind::NurseryFromSpace);
|
||||||
MOZ_ASSERT_IF(!storeBuffer, kind == ChunkKind::TenuredHeap);
|
MOZ_ASSERT_IF(!storeBuffer, kind == ChunkKind::TenuredArenas);
|
||||||
return kind;
|
return kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,12 +139,12 @@ class ChunkBase {
|
||||||
uint8_t nurseryChunkIndex;
|
uint8_t nurseryChunkIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information about tenured heap chunks.
|
// Information about tenured heap chunks containing arenas.
|
||||||
struct TenuredChunkInfo {
|
struct ArenaChunkInfo {
|
||||||
private:
|
private:
|
||||||
friend class ChunkPool;
|
friend class ChunkPool;
|
||||||
TenuredChunk* next = nullptr;
|
ArenaChunk* next = nullptr;
|
||||||
TenuredChunk* prev = nullptr;
|
ArenaChunk* prev = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Number of free arenas, either committed or decommitted. */
|
/* Number of free arenas, either committed or decommitted. */
|
||||||
|
@ -180,7 +180,7 @@ const size_t BitsPerPageWithHeaders =
|
||||||
(ArenaSize + ArenaBitmapBytes) * ArenasPerPage * CHAR_BIT + ArenasPerPage +
|
(ArenaSize + ArenaBitmapBytes) * ArenasPerPage * CHAR_BIT + ArenasPerPage +
|
||||||
1;
|
1;
|
||||||
const size_t ChunkBitsAvailable =
|
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 PagesPerChunk = ChunkBitsAvailable / BitsPerPageWithHeaders;
|
||||||
const size_t ArenasPerChunk = PagesPerChunk * ArenasPerPage;
|
const size_t ArenasPerChunk = PagesPerChunk * ArenasPerPage;
|
||||||
const size_t FreeCommittedBits = ArenasPerChunk;
|
const size_t FreeCommittedBits = ArenasPerChunk;
|
||||||
|
@ -190,7 +190,7 @@ const size_t BitsPerArenaWithHeaders =
|
||||||
(DecommitBits / ArenasPerChunk) + 1;
|
(DecommitBits / ArenasPerChunk) + 1;
|
||||||
|
|
||||||
const size_t CalculatedChunkSizeRequired =
|
const size_t CalculatedChunkSizeRequired =
|
||||||
sizeof(ChunkBase) + sizeof(TenuredChunkInfo) +
|
sizeof(ChunkBase) + sizeof(ArenaChunkInfo) +
|
||||||
RoundUp(ArenasPerChunk * ArenaBitmapBytes, sizeof(uintptr_t)) +
|
RoundUp(ArenasPerChunk * ArenaBitmapBytes, sizeof(uintptr_t)) +
|
||||||
RoundUp(FreeCommittedBits, sizeof(uint32_t) * CHAR_BIT) / CHAR_BIT +
|
RoundUp(FreeCommittedBits, sizeof(uint32_t) * CHAR_BIT) / CHAR_BIT +
|
||||||
RoundUp(DecommitBits, 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,
|
static_assert(ArenasPerChunk == 252,
|
||||||
"Do not accidentally change our heap's density.");
|
"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
|
// 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
|
// main thread while read by sweeping on a background thread. The former does
|
||||||
// not affect the result of the latter.
|
// not affect the result of the latter.
|
||||||
using MarkBitmapWord = mozilla::Atomic<uintptr_t, mozilla::Relaxed>;
|
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
|
* 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 };
|
enum class MarkColor : uint8_t { Gray = 1, Black = 2 };
|
||||||
|
|
||||||
// Mark bitmap for a tenured heap chunk.
|
// Mark bitmap for a tenured heap chunk.
|
||||||
|
template <size_t BytesPerMarkBit, size_t FirstThingOffset>
|
||||||
class alignas(TypicalCacheLineSize) MarkBitmap {
|
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];
|
MarkBitmapWord bitmap[WordCount];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline void getMarkWordAndMask(const TenuredCell* cell, ColorBit colorBit,
|
static constexpr size_t FirstThingAdjustmentBits =
|
||||||
MarkBitmapWord** wordp, uintptr_t* maskp);
|
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:
|
// The following are not exported and are defined in gc/Heap.h:
|
||||||
inline bool markBit(const TenuredCell* cell, ColorBit colorBit);
|
MOZ_ALWAYS_INLINE bool markBit(const TenuredCell* cell, ColorBit colorBit) {
|
||||||
inline bool isMarkedAny(const TenuredCell* cell);
|
MarkBitmapWord* word;
|
||||||
inline bool isMarkedBlack(const TenuredCell* cell);
|
uintptr_t mask;
|
||||||
inline bool isMarkedGray(const TenuredCell* cell);
|
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 markIfUnmarked(const TenuredCell* cell, MarkColor color);
|
||||||
inline bool markIfUnmarkedAtomic(const TenuredCell* cell, MarkColor color);
|
inline bool markIfUnmarkedAtomic(const TenuredCell* cell, MarkColor color);
|
||||||
inline void markBlack(const TenuredCell* cell);
|
inline void markBlack(const TenuredCell* cell);
|
||||||
|
@ -252,8 +299,7 @@ class alignas(TypicalCacheLineSize) MarkBitmap {
|
||||||
inline void copyFrom(const MarkBitmap& other);
|
inline void copyFrom(const MarkBitmap& other);
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(ArenaBitmapBytes * ArenasPerChunk == sizeof(MarkBitmap),
|
using ChunkMarkBitmap = MarkBitmap<CellBytesPerMarkBit, FirstArenaOffset>;
|
||||||
"Ensure our MarkBitmap actually covers all arenas.");
|
|
||||||
|
|
||||||
// Bitmap with one bit per page used for decommitted page set.
|
// Bitmap with one bit per page used for decommitted page set.
|
||||||
using ChunkPageBitmap = mozilla::BitSet<PagesPerChunk, uint32_t>;
|
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.
|
// Bitmap with one bit per arena used for free committed arena set.
|
||||||
using ChunkArenaBitmap = mozilla::BitSet<ArenasPerChunk, uint32_t>;
|
using ChunkArenaBitmap = mozilla::BitSet<ArenasPerChunk, uint32_t>;
|
||||||
|
|
||||||
// Base class containing data members for a tenured heap chunk.
|
// Base class for a tenured heap chunk containing fixed size arenas.
|
||||||
class TenuredChunkBase : public ChunkBase {
|
class ArenaChunkBase : public ChunkBase {
|
||||||
public:
|
public:
|
||||||
TenuredChunkInfo info;
|
ArenaChunkInfo info;
|
||||||
MarkBitmap markBits;
|
ChunkMarkBitmap markBits;
|
||||||
ChunkArenaBitmap freeCommittedArenas;
|
ChunkArenaBitmap freeCommittedArenas;
|
||||||
ChunkPageBitmap decommittedPages;
|
ChunkPageBitmap decommittedPages;
|
||||||
|
|
||||||
protected:
|
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;
|
info.numArenasFree = ArenasPerChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initAsDecommitted();
|
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
|
* 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 ArenaCellIndexBytes = CellAlignBytes;
|
||||||
const size_t MaxArenaCellIndex = ArenaSize / 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 ChunkStoreBufferOffset = offsetof(ChunkBase, storeBuffer);
|
||||||
const size_t ChunkMarkBitmapOffset = offsetof(TenuredChunkBase, markBits);
|
const size_t ChunkMarkBitmapOffset = offsetof(ArenaChunkBase, markBits);
|
||||||
|
|
||||||
// Hardcoded offsets into Arena class.
|
// Hardcoded offsets into Arena class.
|
||||||
const size_t ArenaZoneOffset = 2 * sizeof(uint32_t);
|
const size_t ArenaZoneOffset = 2 * sizeof(uint32_t);
|
||||||
|
@ -535,48 +576,6 @@ inline bool operator!=(JS::GCCellPtr ptr1, JS::GCCellPtr ptr2) {
|
||||||
namespace js {
|
namespace js {
|
||||||
namespace gc {
|
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 {
|
namespace detail {
|
||||||
|
|
||||||
// `addr` must be an address within GC-controlled memory. Note that it cannot
|
// `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);
|
return GetGCAddressChunkBase(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE TenuredChunkBase* GetCellChunkBase(
|
static MOZ_ALWAYS_INLINE ArenaChunkBase* GetCellChunkBase(
|
||||||
const TenuredCell* cell) {
|
const TenuredCell* cell) {
|
||||||
MOZ_ASSERT(cell);
|
MOZ_ASSERT(cell);
|
||||||
auto* chunk =
|
auto* chunk = reinterpret_cast<ArenaChunkBase*>(uintptr_t(cell) & ~ChunkMask);
|
||||||
reinterpret_cast<TenuredChunkBase*>(uintptr_t(cell) & ~ChunkMask);
|
|
||||||
MOZ_ASSERT(chunk->runtime);
|
MOZ_ASSERT(chunk->runtime);
|
||||||
MOZ_ASSERT(chunk->kind == ChunkKind::TenuredHeap);
|
MOZ_ASSERT(chunk->kind == ChunkKind::TenuredArenas);
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +614,7 @@ static MOZ_ALWAYS_INLINE bool TenuredCellIsMarkedBlack(
|
||||||
MOZ_ASSERT(cell);
|
MOZ_ASSERT(cell);
|
||||||
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
|
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
|
||||||
|
|
||||||
TenuredChunkBase* chunk = GetCellChunkBase(cell);
|
ArenaChunkBase* chunk = GetCellChunkBase(cell);
|
||||||
return chunk->markBits.isMarkedBlack(cell);
|
return chunk->markBits.isMarkedBlack(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,14 +626,14 @@ static MOZ_ALWAYS_INLINE bool NonBlackCellIsMarkedGray(
|
||||||
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
|
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
|
||||||
MOZ_ASSERT(!TenuredCellIsMarkedBlack(cell));
|
MOZ_ASSERT(!TenuredCellIsMarkedBlack(cell));
|
||||||
|
|
||||||
TenuredChunkBase* chunk = GetCellChunkBase(cell);
|
ArenaChunkBase* chunk = GetCellChunkBase(cell);
|
||||||
return chunk->markBits.markBit(cell, ColorBit::GrayOrBlackBit);
|
return chunk->markBits.markBit(cell, ColorBit::GrayOrBlackBit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool TenuredCellIsMarkedGray(const TenuredCell* cell) {
|
static MOZ_ALWAYS_INLINE bool TenuredCellIsMarkedGray(const TenuredCell* cell) {
|
||||||
MOZ_ASSERT(cell);
|
MOZ_ASSERT(cell);
|
||||||
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
|
MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
|
||||||
TenuredChunkBase* chunk = GetCellChunkBase(cell);
|
ArenaChunkBase* chunk = GetCellChunkBase(cell);
|
||||||
return chunk->markBits.isMarkedGray(cell);
|
return chunk->markBits.isMarkedGray(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1761,43 +1761,41 @@ bool BytecodeEmitter::emitNameIncDec(UnaryNode* incDec, ValueUsage valueUsage) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BytecodeEmitter::emitObjAndKey(ParseNode* exprOrSuper, ParseNode* key,
|
bool BytecodeEmitter::emitElemObjAndKey(PropertyByValue* elem,
|
||||||
ElemOpEmitter& eoe) {
|
ElemOpEmitter& eoe) {
|
||||||
if (exprOrSuper->isKind(ParseNodeKind::SuperBase)) {
|
ParseNode* exprOrSuper = &elem->expression();
|
||||||
if (!eoe.prepareForObj()) {
|
ParseNode* key = &elem->key();
|
||||||
// [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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!eoe.prepareForObj()) {
|
if (!eoe.prepareForObj()) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!emitTree(exprOrSuper)) {
|
|
||||||
// [stack] OBJ
|
if (elem->isSuper()) {
|
||||||
return false;
|
auto* base = &exprOrSuper->as<UnaryNode>();
|
||||||
|
if (!emitGetThisForSuperBase(base)) {
|
||||||
|
// [stack] THIS
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!emitTree(exprOrSuper)) {
|
||||||
|
// [stack] OBJ
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eoe.prepareForKey()) {
|
if (!eoe.prepareForKey()) {
|
||||||
|
// [stack] # if Super
|
||||||
|
// [stack] THIS? THIS
|
||||||
|
// [stack] # otherwise
|
||||||
// [stack] OBJ? OBJ
|
// [stack] OBJ? OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!emitTree(key)) {
|
if (!emitTree(key)) {
|
||||||
|
// [stack] # if Super
|
||||||
|
// [stack] THIS? THIS KEY
|
||||||
|
// [stack] # otherwise
|
||||||
// [stack] OBJ? OBJ KEY
|
// [stack] OBJ? OBJ KEY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1813,12 +1811,6 @@ bool BytecodeEmitter::emitElemOpBase(JSOp op) {
|
||||||
return true;
|
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) {
|
static ElemOpEmitter::Kind ConvertIncDecKind(ParseNodeKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case ParseNodeKind::PostIncrementExpr:
|
case ParseNodeKind::PostIncrementExpr:
|
||||||
|
@ -1857,7 +1849,7 @@ bool BytecodeEmitter::emitElemIncDec(UnaryNode* incDec, ValueUsage valueUsage) {
|
||||||
ElemOpEmitter eoe(
|
ElemOpEmitter eoe(
|
||||||
this, ConvertIncDecKind(kind),
|
this, ConvertIncDecKind(kind),
|
||||||
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
|
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
|
||||||
if (!emitElemObjAndKey(elemExpr, isSuper, eoe)) {
|
if (!emitElemObjAndKey(elemExpr, eoe)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS KEY
|
// [stack] THIS KEY
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
|
@ -2603,23 +2595,63 @@ bool BytecodeEmitter::emitFunctionScript(FunctionNode* funNode) {
|
||||||
return fse.intoStencil();
|
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,
|
bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
|
||||||
size_t* emitted) {
|
DestructuringFlavor flav,
|
||||||
|
DestructuringLHSRef& lref) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int depth = bytecodeSection().stackDepth();
|
int depth = bytecodeSection().stackDepth();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (target->getKind()) {
|
switch (target->getKind()) {
|
||||||
case ParseNodeKind::Name:
|
|
||||||
case ParseNodeKind::ArrayExpr:
|
case ParseNodeKind::ArrayExpr:
|
||||||
case ParseNodeKind::ObjectExpr:
|
case ParseNodeKind::ObjectExpr:
|
||||||
// No need to recurse into ParseNodeKind::Array and ParseNodeKind::Object
|
// No need to recurse into ParseNodeKind::Array and ParseNodeKind::Object
|
||||||
// subpatterns here, since emitSetOrInitializeDestructuring does the
|
// subpatterns here, since emitSetOrInitializeDestructuring does the
|
||||||
// recursion when setting or initializing the value. Getting reference
|
// recursion when setting or initializing the value.
|
||||||
// doesn't recurse.
|
|
||||||
*emitted = 0;
|
|
||||||
break;
|
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::ArgumentsLength:
|
||||||
case ParseNodeKind::DotExpr: {
|
case ParseNodeKind::DotExpr: {
|
||||||
PropertyAccess* prop = &target->as<PropertyAccess>();
|
PropertyAccess* prop = &target->as<PropertyAccess>();
|
||||||
|
@ -2650,8 +2682,7 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUPERBASE was pushed onto THIS in poe.prepareForRhs above.
|
lref.from(std::move(poe));
|
||||||
*emitted = 1 + isSuper;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2662,7 +2693,7 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
|
||||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
|
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
|
||||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||||
: ElemOpEmitter::ObjKind::Other);
|
: ElemOpEmitter::ObjKind::Other);
|
||||||
if (!emitElemObjAndKey(elem, isSuper, eoe)) {
|
if (!emitElemObjAndKey(elem, eoe)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS KEY
|
// [stack] THIS KEY
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
|
@ -2677,8 +2708,7 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUPERBASE was pushed onto KEY in eoe.prepareForRhs above.
|
lref.from(std::move(eoe));
|
||||||
*emitted = 2 + isSuper;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2694,7 +2724,8 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
|
||||||
// [stack] OBJ NAME
|
// [stack] OBJ NAME
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*emitted = xoe.numReferenceSlots();
|
|
||||||
|
lref.from(std::move(xoe));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2709,13 +2740,14 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
|
||||||
MOZ_CRASH("emitDestructuringLHSRef: bad lhs kind");
|
MOZ_CRASH("emitDestructuringLHSRef: bad lhs kind");
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(bytecodeSection().stackDepth() == depth + int(*emitted));
|
MOZ_ASSERT(bytecodeSection().stackDepth() ==
|
||||||
|
depth + int(lref.numReferenceSlots()));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BytecodeEmitter::emitSetOrInitializeDestructuring(
|
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
|
// Now emit the lvalue opcode sequence. If the lvalue is a nested
|
||||||
// destructuring initialiser-form, call ourselves to handle it, then pop
|
// destructuring initialiser-form, call ourselves to handle it, then pop
|
||||||
// the matched value. Otherwise emit an lvalue bytecode sequence followed
|
// the matched value. Otherwise emit an lvalue bytecode sequence followed
|
||||||
|
@ -2732,51 +2764,14 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ParseNodeKind::Name: {
|
case ParseNodeKind::Name: {
|
||||||
auto name = target->as<NameNode>().name();
|
// The environment is already pushed by emitDestructuringLHSRef.
|
||||||
NameLocation loc = lookupName(name);
|
// [stack] ENV? VAL
|
||||||
NameOpEmitter::Kind kind;
|
auto& noe = lref.emitter<NameOpEmitter>();
|
||||||
switch (flav) {
|
|
||||||
case DestructuringFlavor::Declaration:
|
|
||||||
kind = NameOpEmitter::Kind::Initialize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
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()) {
|
if (!noe.emitAssignment()) {
|
||||||
// [stack] V
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2787,16 +2782,11 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
|
||||||
// [stack] THIS SUPERBASE VAL
|
// [stack] THIS SUPERBASE VAL
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
// [stack] OBJ VAL
|
// [stack] OBJ VAL
|
||||||
PropertyAccess* prop = &target->as<PropertyAccess>();
|
auto& poe = lref.emitter<PropOpEmitter>();
|
||||||
bool isSuper = prop->isSuper();
|
auto* prop = &target->as<PropertyAccess>();
|
||||||
PropOpEmitter poe(this, PropOpEmitter::Kind::SimpleAssignment,
|
|
||||||
isSuper ? PropOpEmitter::ObjKind::Super
|
|
||||||
: PropOpEmitter::ObjKind::Other);
|
|
||||||
if (!poe.skipObjAndRhs()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// [stack] # VAL
|
|
||||||
if (!poe.emitAssignment(prop->key().atom())) {
|
if (!poe.emitAssignment(prop->key().atom())) {
|
||||||
|
// [stack] # VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2808,15 +2798,8 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
|
||||||
// [stack] THIS KEY SUPERBASE VAL
|
// [stack] THIS KEY SUPERBASE VAL
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
// [stack] OBJ KEY VAL
|
// [stack] OBJ KEY VAL
|
||||||
PropertyByValue* elem = &target->as<PropertyByValue>();
|
auto& eoe = lref.emitter<ElemOpEmitter>();
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (!eoe.emitAssignment()) {
|
if (!eoe.emitAssignment()) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
|
@ -2827,12 +2810,8 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
|
||||||
case ParseNodeKind::PrivateMemberExpr: {
|
case ParseNodeKind::PrivateMemberExpr: {
|
||||||
// The reference is already pushed by emitDestructuringLHSRef.
|
// The reference is already pushed by emitDestructuringLHSRef.
|
||||||
// [stack] OBJ NAME VAL
|
// [stack] OBJ NAME VAL
|
||||||
PrivateMemberAccess* privateExpr = &target->as<PrivateMemberAccess>();
|
auto& xoe = lref.emitter<PrivateOpEmitter>();
|
||||||
PrivateOpEmitter xoe(this, PrivateOpEmitter::Kind::SimpleAssignment,
|
|
||||||
privateExpr->privateName().name());
|
|
||||||
if (!xoe.skipReference()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!xoe.emitAssignment()) {
|
if (!xoe.emitAssignment()) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
|
@ -3383,6 +3362,7 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
|
||||||
idx += 1;
|
idx += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(member->isKind(ParseNodeKind::Name));
|
||||||
|
|
||||||
if (!emit1(JSOp::Dup)) {
|
if (!emit1(JSOp::Dup)) {
|
||||||
// [stack] LENGTH OBJ OBJ
|
// [stack] LENGTH OBJ OBJ
|
||||||
|
@ -3440,7 +3420,13 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
|
||||||
return false;
|
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
|
// [stack] LENGTH OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3527,14 +3513,12 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
|
||||||
pndefault = subpattern->as<AssignmentNode>().right();
|
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.
|
// Spec requires LHS reference to be evaluated first.
|
||||||
|
DestructuringLHSRef lref;
|
||||||
bool isElision = lhsPattern->isKind(ParseNodeKind::Elision);
|
bool isElision = lhsPattern->isKind(ParseNodeKind::Elision);
|
||||||
if (!isElision) {
|
if (!isElision) {
|
||||||
auto emitLHSRef = [lhsPattern, &emitted](BytecodeEmitter* bce) {
|
auto emitLHSRef = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
|
||||||
return bce->emitDestructuringLHSRef(lhsPattern, &emitted);
|
return bce->emitDestructuringLHSRef(lhsPattern, flav, lref);
|
||||||
// [stack] ... OBJ NEXT ITER DONE LREF*
|
// [stack] ... OBJ NEXT ITER DONE LREF*
|
||||||
};
|
};
|
||||||
if (!wrapWithDestructuringTryNote(tryNoteDepth, emitLHSRef)) {
|
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.
|
// Pick the DONE value to the top of the stack.
|
||||||
if (emitted) {
|
if (emitted) {
|
||||||
if (!emitPickN(emitted)) {
|
if (!emitPickN(emitted)) {
|
||||||
|
@ -3624,8 +3611,8 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto emitAssignment = [lhsPattern, flav](BytecodeEmitter* bce) {
|
auto emitAssignment = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
|
||||||
return bce->emitSetOrInitializeDestructuring(lhsPattern, flav);
|
return bce->emitSetOrInitializeDestructuring(lhsPattern, flav, lref);
|
||||||
// [stack] ... OBJ NEXT ITER TRUE
|
// [stack] ... OBJ NEXT ITER TRUE
|
||||||
};
|
};
|
||||||
if (!wrapWithDestructuringTryNote(tryNoteDepth, emitAssignment)) {
|
if (!wrapWithDestructuringTryNote(tryNoteDepth, emitAssignment)) {
|
||||||
|
@ -3749,8 +3736,8 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isElision) {
|
if (!isElision) {
|
||||||
auto emitAssignment = [lhsPattern, flav](BytecodeEmitter* bce) {
|
auto emitAssignment = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
|
||||||
return bce->emitSetOrInitializeDestructuring(lhsPattern, flav);
|
return bce->emitSetOrInitializeDestructuring(lhsPattern, flav, lref);
|
||||||
// [stack] ... OBJ NEXT ITER DONE
|
// [stack] ... OBJ NEXT ITER DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3841,6 +3828,7 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
|
||||||
|
|
||||||
for (ParseNode* member : pattern->contents()) {
|
for (ParseNode* member : pattern->contents()) {
|
||||||
ParseNode* subpattern;
|
ParseNode* subpattern;
|
||||||
|
bool hasKeyOnStack = false;
|
||||||
if (member->isKind(ParseNodeKind::MutateProto) ||
|
if (member->isKind(ParseNodeKind::MutateProto) ||
|
||||||
member->isKind(ParseNodeKind::Spread)) {
|
member->isKind(ParseNodeKind::Spread)) {
|
||||||
subpattern = member->as<UnaryNode>().kid();
|
subpattern = member->as<UnaryNode>().kid();
|
||||||
|
@ -3851,6 +3839,16 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
|
||||||
MOZ_ASSERT(member->isKind(ParseNodeKind::PropertyDefinition) ||
|
MOZ_ASSERT(member->isKind(ParseNodeKind::PropertyDefinition) ||
|
||||||
member->isKind(ParseNodeKind::Shorthand));
|
member->isKind(ParseNodeKind::Shorthand));
|
||||||
subpattern = member->as<BinaryNode>().right();
|
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;
|
ParseNode* lhs = subpattern;
|
||||||
|
@ -3860,18 +3858,19 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
|
||||||
pndefault = subpattern->as<AssignmentNode>().right();
|
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.
|
// Spec requires LHS reference to be evaluated first.
|
||||||
if (!emitDestructuringLHSRef(lhs, &emitted)) {
|
DestructuringLHSRef lref;
|
||||||
// [stack] ... SET? RHS LREF*
|
if (!emitDestructuringLHSRef(lhs, flav, lref)) {
|
||||||
|
// [stack] ... SET? RHS KEY? LREF*
|
||||||
return false;
|
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.
|
// Duplicate the value being destructured to use as a reference base.
|
||||||
if (!emitDupAt(emitted)) {
|
if (!emitDupAt(emitted + hasKeyOnStack)) {
|
||||||
// [stack] ... SET? RHS LREF* RHS
|
// [stack] ... SET? RHS KEY? LREF* RHS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3908,7 +3907,7 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructure TARGET per this member's lhs.
|
// Destructure TARGET per this member's lhs.
|
||||||
if (!emitSetOrInitializeDestructuring(lhs, flav)) {
|
if (!emitSetOrInitializeDestructuring(lhs, flav, lref)) {
|
||||||
// [stack] ... RHS
|
// [stack] ... RHS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3947,8 +3946,9 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
|
||||||
// Otherwise this is a computed property name. BigInt keys are parsed
|
// Otherwise this is a computed property name. BigInt keys are parsed
|
||||||
// as (synthetic) computed property names, too.
|
// as (synthetic) computed property names, too.
|
||||||
MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName));
|
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
|
// [stack] ... SET? RHS LREF* RHS KEY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3994,7 +3994,7 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructure PROP per this member's lhs.
|
// Destructure PROP per this member's lhs.
|
||||||
if (!emitSetOrInitializeDestructuring(lhs, flav)) {
|
if (!emitSetOrInitializeDestructuring(lhs, flav, lref)) {
|
||||||
// [stack] ... SET? RHS
|
// [stack] ... SET? RHS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4447,7 +4447,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs,
|
||||||
: ElemOpEmitter::Kind::SimpleAssignment,
|
: ElemOpEmitter::Kind::SimpleAssignment,
|
||||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||||
: ElemOpEmitter::ObjKind::Other);
|
: ElemOpEmitter::ObjKind::Other);
|
||||||
if (!emitElemObjAndKey(elem, isSuper, *eoe)) {
|
if (!emitElemObjAndKey(elem, *eoe)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS KEY
|
// [stack] THIS KEY
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
|
@ -4763,7 +4763,7 @@ bool BytecodeEmitter::emitShortCircuitAssignment(AssignmentNode* node) {
|
||||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||||
: ElemOpEmitter::ObjKind::Other);
|
: ElemOpEmitter::ObjKind::Other);
|
||||||
|
|
||||||
if (!emitElemObjAndKey(elem, isSuper, *eoe)) {
|
if (!emitElemObjAndKey(elem, *eoe)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS KEY
|
// [stack] THIS KEY
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
|
@ -7273,20 +7273,20 @@ bool BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode) {
|
||||||
propExpr->as<PropertyAccess>().isSuper()
|
propExpr->as<PropertyAccess>().isSuper()
|
||||||
? PropOpEmitter::ObjKind::Super
|
? PropOpEmitter::ObjKind::Super
|
||||||
: PropOpEmitter::ObjKind::Other);
|
: PropOpEmitter::ObjKind::Other);
|
||||||
|
|
||||||
|
if (!poe.prepareForObj()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (propExpr->isSuper()) {
|
if (propExpr->isSuper()) {
|
||||||
// The expression |delete super.foo;| has to evaluate |super.foo|,
|
// The expression |delete super.foo;| has to evaluate |super.foo|, which
|
||||||
// which could throw if |this| hasn't yet been set by a |super(...)|
|
// could throw if |this| hasn't yet been set by a |super(...)| call.
|
||||||
// call or the super-base is not an object, before throwing a
|
auto* base = &propExpr->expression().as<UnaryNode>();
|
||||||
// ReferenceError for attempting to delete a super-reference.
|
|
||||||
UnaryNode* base = &propExpr->expression().as<UnaryNode>();
|
|
||||||
if (!emitGetThisForSuperBase(base)) {
|
if (!emitGetThisForSuperBase(base)) {
|
||||||
// [stack] THIS
|
// [stack] THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!poe.prepareForObj()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!emitPropLHS(propExpr)) {
|
if (!emitPropLHS(propExpr)) {
|
||||||
// [stack] OBJ
|
// [stack] OBJ
|
||||||
return false;
|
return false;
|
||||||
|
@ -7307,44 +7307,21 @@ bool BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode) {
|
||||||
bool BytecodeEmitter::emitDeleteElement(UnaryNode* deleteNode) {
|
bool BytecodeEmitter::emitDeleteElement(UnaryNode* deleteNode) {
|
||||||
MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteElemExpr));
|
MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteElemExpr));
|
||||||
|
|
||||||
PropertyByValue* elemExpr = &deleteNode->kid()->as<PropertyByValue>();
|
auto* elemExpr = &deleteNode->kid()->as<PropertyByValue>();
|
||||||
bool isSuper = elemExpr->isSuper();
|
bool isSuper = elemExpr->isSuper();
|
||||||
DebugOnly<bool> isPrivate =
|
MOZ_ASSERT(!elemExpr->key().isKind(ParseNodeKind::PrivateName));
|
||||||
elemExpr->key().isKind(ParseNodeKind::PrivateName);
|
|
||||||
MOZ_ASSERT(!isPrivate);
|
|
||||||
ElemOpEmitter eoe(
|
ElemOpEmitter eoe(
|
||||||
this, ElemOpEmitter::Kind::Delete,
|
this, ElemOpEmitter::Kind::Delete,
|
||||||
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
|
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 (!emitElemObjAndKey(elemExpr, eoe)) {
|
||||||
if (!emitGetThisForSuperBase(base)) {
|
// [stack] # if Super
|
||||||
// [stack] THIS
|
// [stack] THIS KEY
|
||||||
return false;
|
// [stack] # otherwise
|
||||||
}
|
// [stack] OBJ KEY
|
||||||
if (!eoe.prepareForKey()) {
|
return false;
|
||||||
// [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 (!eoe.emitDelete()) {
|
if (!eoe.emitDelete()) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS
|
// [stack] THIS
|
||||||
|
@ -8187,7 +8164,7 @@ bool BytecodeEmitter::emitCalleeAndThis(ParseNode* callee, CallNode* maybeCall,
|
||||||
bool isSuper = elem->isSuper();
|
bool isSuper = elem->isSuper();
|
||||||
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
|
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
|
||||||
ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
|
ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
|
||||||
if (!emitElemObjAndKey(elem, isSuper, eoe)) {
|
if (!emitElemObjAndKey(elem, eoe)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS? THIS KEY
|
// [stack] THIS? THIS KEY
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
|
@ -12740,7 +12717,7 @@ bool BytecodeEmitter::emitTree(
|
||||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
|
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
|
||||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||||
: ElemOpEmitter::ObjKind::Other);
|
: ElemOpEmitter::ObjKind::Other);
|
||||||
if (!emitElemObjAndKey(elem, isSuper, eoe)) {
|
if (!emitElemObjAndKey(elem, eoe)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS KEY
|
// [stack] THIS KEY
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
|
|
|
@ -55,6 +55,7 @@ namespace frontend {
|
||||||
class BytecodeOffset;
|
class BytecodeOffset;
|
||||||
class CallOrNewEmitter;
|
class CallOrNewEmitter;
|
||||||
class ClassEmitter;
|
class ClassEmitter;
|
||||||
|
class DestructuringLHSRef;
|
||||||
class ElemOpEmitter;
|
class ElemOpEmitter;
|
||||||
class EmitterScope;
|
class EmitterScope;
|
||||||
class ErrorReporter;
|
class ErrorReporter;
|
||||||
|
@ -751,9 +752,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
|
||||||
|
|
||||||
[[nodiscard]] bool emitComputedPropertyName(UnaryNode* computedPropName);
|
[[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
|
// 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
|
// opcode onto the stack in the right order. In the case of SetElem, the
|
||||||
// value to be assigned must already be pushed.
|
// value to be assigned must already be pushed.
|
||||||
|
@ -761,7 +759,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
|
||||||
[[nodiscard]] bool emitElemOperands(PropertyByValue* elem,
|
[[nodiscard]] bool emitElemOperands(PropertyByValue* elem,
|
||||||
EmitElemOption opts);
|
EmitElemOption opts);
|
||||||
|
|
||||||
[[nodiscard]] bool emitElemObjAndKey(PropertyByValue* elem, bool isSuper,
|
[[nodiscard]] bool emitElemObjAndKey(PropertyByValue* elem,
|
||||||
ElemOpEmitter& eoe);
|
ElemOpEmitter& eoe);
|
||||||
[[nodiscard]] bool emitElemOpBase(JSOp op);
|
[[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 the lhs expression is object property |OBJ.prop|, it emits |OBJ|.
|
||||||
// If it's object element |OBJ[ELEM]|, it emits |OBJ| and |ELEM|.
|
// If it's object element |OBJ[ELEM]|, it emits |OBJ| and |ELEM|.
|
||||||
// If there's nothing to evaluate for the reference, it emits nothing.
|
// 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,
|
[[nodiscard]] bool emitDestructuringLHSRef(ParseNode* target,
|
||||||
size_t* emitted);
|
DestructuringFlavor flav,
|
||||||
|
DestructuringLHSRef& lref);
|
||||||
|
|
||||||
// emitSetOrInitializeDestructuring assumes the lhs expression's reference
|
// emitSetOrInitializeDestructuring assumes the lhs expression's reference
|
||||||
// and the to-be-destructured value has been pushed on the stack. It emits
|
// 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
|
// code to destructure a single lhs expression (either a name or a compound
|
||||||
// []/{} expression).
|
// []/{} expression).
|
||||||
[[nodiscard]] bool emitSetOrInitializeDestructuring(ParseNode* target,
|
[[nodiscard]] bool emitSetOrInitializeDestructuring(
|
||||||
DestructuringFlavor flav);
|
ParseNode* target, DestructuringFlavor flav, DestructuringLHSRef& lref);
|
||||||
|
|
||||||
// emitDestructuringObjRestExclusionSet emits the property exclusion set
|
// emitDestructuringObjRestExclusionSet emits the property exclusion set
|
||||||
// for the rest-property in an object pattern.
|
// for the rest-property in an object pattern.
|
||||||
|
|
|
@ -48,31 +48,38 @@ bool ElemOpEmitter::prepareForKey() {
|
||||||
bool ElemOpEmitter::emitGet() {
|
bool ElemOpEmitter::emitGet() {
|
||||||
MOZ_ASSERT(state_ == State::Key);
|
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 (isSuper()) {
|
||||||
if (!bce_->emitSuperBase()) {
|
if (!bce_->emitSuperBase()) {
|
||||||
// [stack] THIS? THIS KEY SUPERBASE
|
// [stack] THIS? THIS KEY SUPERBASE
|
||||||
return false;
|
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 (isIncDec() || isCompoundAssignment()) {
|
||||||
if (isSuper()) {
|
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)) {
|
if (!bce_->emitDupAt(2, 3)) {
|
||||||
// [stack] THIS KEY SUPERBASE THIS KEY SUPERBASE
|
// [stack] THIS KEY SUPERBASE THIS KEY SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!bce_->emit1(JSOp::ToPropertyKey)) {
|
||||||
|
// [stack] OBJ KEY
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!bce_->emit1(JSOp::Dup2)) {
|
if (!bce_->emit1(JSOp::Dup2)) {
|
||||||
// [stack] OBJ KEY OBJ KEY
|
// [stack] OBJ KEY OBJ KEY
|
||||||
return false;
|
return false;
|
||||||
|
@ -131,25 +138,11 @@ bool ElemOpEmitter::prepareForRhs() {
|
||||||
return true;
|
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() {
|
bool ElemOpEmitter::emitDelete() {
|
||||||
MOZ_ASSERT(state_ == State::Key);
|
MOZ_ASSERT(state_ == State::Key);
|
||||||
MOZ_ASSERT(isDelete());
|
MOZ_ASSERT(isDelete());
|
||||||
|
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
if (!bce_->emit1(JSOp::ToPropertyKey)) {
|
|
||||||
// [stack] THIS KEY
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!bce_->emitSuperBase()) {
|
if (!bce_->emitSuperBase()) {
|
||||||
// [stack] THIS KEY SUPERBASE
|
// [stack] THIS KEY SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
|
@ -142,38 +144,36 @@ class MOZ_STACK_CLASS ElemOpEmitter {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// The state of this emitter.
|
// The state of this emitter.
|
||||||
//
|
//
|
||||||
// skipObjAndKeyAndRhs
|
//
|
||||||
// +------------------------------------------------+
|
// +-------+ prepareForObj +-----+ prepareForKey +-----+
|
||||||
// | |
|
// | Start |---------------->| Obj |-------------->| Key |-+
|
||||||
// +-------+ | prepareForObj +-----+ prepareForKey +-----+ |
|
// +-------+ +-----+ +-----+ |
|
||||||
// | Start |-+-------------->| Obj |-------------->| Key |-+ |
|
// |
|
||||||
// +-------+ +-----+ +-----+ | |
|
// +-------------------------------------------------------+
|
||||||
// | |
|
// |
|
||||||
// +-------------------------------------------------------+ |
|
// | [Get]
|
||||||
// | |
|
// | [Call]
|
||||||
// | [Get] |
|
// | emitGet +-----+
|
||||||
// | [Call] |
|
// +---------->| Get |
|
||||||
// | emitGet +-----+ |
|
// | +-----+
|
||||||
// +---------->| Get | |
|
// |
|
||||||
// | +-----+ |
|
// | [Delete]
|
||||||
// | |
|
// | emitDelete +--------+
|
||||||
// | [Delete] |
|
// +------------->| Delete |
|
||||||
// | emitDelete +--------+ |
|
// | +--------+
|
||||||
// +------------->| Delete | |
|
// |
|
||||||
// | +--------+ |
|
// | [PostIncrement]
|
||||||
// | |
|
// | [PreIncrement]
|
||||||
// | [PostIncrement] |
|
// | [PostDecrement]
|
||||||
// | [PreIncrement] |
|
// | [PreDecrement]
|
||||||
// | [PostDecrement] |
|
// | emitIncDec +--------+
|
||||||
// | [PreDecrement] |
|
// +------------->| IncDec |
|
||||||
// | emitIncDec +--------+ |
|
// | +--------+
|
||||||
// +------------->| IncDec | |
|
// |
|
||||||
// | +--------+ |
|
// | [SimpleAssignment]
|
||||||
// | +-------------------+
|
// | [PropInit]
|
||||||
// | [SimpleAssignment] |
|
// | prepareForRhs +-----+
|
||||||
// | [PropInit] |
|
// +--------------------->+----------------->| Rhs |-+
|
||||||
// | prepareForRhs v +-----+
|
|
||||||
// +--------------------->+-------------->+->| Rhs |-+
|
|
||||||
// | ^ +-----+ |
|
// | ^ +-----+ |
|
||||||
// | | |
|
// | | |
|
||||||
// | | +-------------+
|
// | | +-------------+
|
||||||
|
@ -200,7 +200,7 @@ class MOZ_STACK_CLASS ElemOpEmitter {
|
||||||
// After calling emitIncDec.
|
// After calling emitIncDec.
|
||||||
IncDec,
|
IncDec,
|
||||||
|
|
||||||
// After calling prepareForRhs or skipObjAndKeyAndRhs.
|
// After calling prepareForRhs.
|
||||||
Rhs,
|
Rhs,
|
||||||
|
|
||||||
// After calling emitAssignment.
|
// After calling emitAssignment.
|
||||||
|
@ -252,13 +252,14 @@ class MOZ_STACK_CLASS ElemOpEmitter {
|
||||||
[[nodiscard]] bool emitGet();
|
[[nodiscard]] bool emitGet();
|
||||||
|
|
||||||
[[nodiscard]] bool prepareForRhs();
|
[[nodiscard]] bool prepareForRhs();
|
||||||
[[nodiscard]] bool skipObjAndKeyAndRhs();
|
|
||||||
|
|
||||||
[[nodiscard]] bool emitDelete();
|
[[nodiscard]] bool emitDelete();
|
||||||
|
|
||||||
[[nodiscard]] bool emitAssignment();
|
[[nodiscard]] bool emitAssignment();
|
||||||
|
|
||||||
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
|
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
|
||||||
|
|
||||||
|
size_t numReferenceSlots() const { return 2 + isSuper(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace frontend */
|
} /* namespace frontend */
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "frontend/NameAnalysisTypes.h"
|
#include "frontend/NameAnalysisTypes.h"
|
||||||
#include "frontend/ParserAtom.h" // TaggedParserAtomIndex
|
#include "frontend/ParserAtom.h" // TaggedParserAtomIndex
|
||||||
#include "vm/SharedStencil.h" // GCThingIndex
|
#include "vm/SharedStencil.h" // GCThingIndex
|
||||||
|
@ -174,6 +176,8 @@ class MOZ_STACK_CLASS NameOpEmitter {
|
||||||
[[nodiscard]] bool prepareForRhs();
|
[[nodiscard]] bool prepareForRhs();
|
||||||
[[nodiscard]] bool emitAssignment();
|
[[nodiscard]] bool emitAssignment();
|
||||||
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
|
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
|
||||||
|
|
||||||
|
size_t numReferenceSlots() const { return emittedBindOp(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace frontend */
|
} /* namespace frontend */
|
||||||
|
|
|
@ -100,19 +100,6 @@ bool PrivateOpEmitter::emitReference() {
|
||||||
return true;
|
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() {
|
bool PrivateOpEmitter::emitGet() {
|
||||||
MOZ_ASSERT(state_ == State::Reference);
|
MOZ_ASSERT(state_ == State::Reference);
|
||||||
|
|
||||||
|
|
|
@ -114,8 +114,7 @@ class MOZ_STACK_CLASS PrivateOpEmitter {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// The state of this emitter.
|
// The state of this emitter.
|
||||||
//
|
//
|
||||||
// emitReference
|
// +-------+ emitReference +-----------+
|
||||||
// +-------+ skipReference +-----------+
|
|
||||||
// | Start |---------------->| Reference |
|
// | Start |---------------->| Reference |
|
||||||
// +-------+ +-----+-----+
|
// +-------+ +-----+-----+
|
||||||
// |
|
// |
|
||||||
|
@ -144,7 +143,7 @@ class MOZ_STACK_CLASS PrivateOpEmitter {
|
||||||
// The initial state.
|
// The initial state.
|
||||||
Start,
|
Start,
|
||||||
|
|
||||||
// After calling emitReference or skipReference.
|
// After calling emitReference.
|
||||||
Reference,
|
Reference,
|
||||||
|
|
||||||
// After calling emitGet.
|
// After calling emitGet.
|
||||||
|
@ -216,13 +215,12 @@ class MOZ_STACK_CLASS PrivateOpEmitter {
|
||||||
[[nodiscard]] bool emitBrandCheck();
|
[[nodiscard]] bool emitBrandCheck();
|
||||||
|
|
||||||
[[nodiscard]] bool emitReference();
|
[[nodiscard]] bool emitReference();
|
||||||
[[nodiscard]] bool skipReference();
|
|
||||||
[[nodiscard]] bool emitGet();
|
[[nodiscard]] bool emitGet();
|
||||||
[[nodiscard]] bool emitGetForCallOrNew();
|
[[nodiscard]] bool emitGetForCallOrNew();
|
||||||
[[nodiscard]] bool emitAssignment();
|
[[nodiscard]] bool emitAssignment();
|
||||||
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
|
[[nodiscard]] bool emitIncDec(ValueUsage valueUsage);
|
||||||
|
|
||||||
[[nodiscard]] size_t numReferenceSlots() { return 2; }
|
size_t numReferenceSlots() const { return 2; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace frontend */
|
} /* 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