Merge mozilla-central to inbound. a=merge CLOSED TREE

This commit is contained in:
Bogdan Tara 2018-09-05 02:45:18 +03:00
Родитель 5d72990251 f302cbb0b3
Коммит ba6cae21b7
239 изменённых файлов: 1601 добавлений и 1721 удалений

Просмотреть файл

@ -22,7 +22,6 @@ gfx/layers/**
gfx/tests/browser/**
gfx/tests/chrome/**
gfx/tests/mochitest/**
gfx/tests/unit/**
image/**
layout/**
memory/replace/dmd/test/**
@ -38,7 +37,6 @@ netwerk/test/mochitests/**
netwerk/test/unit*/**
netwerk/wifi/**
parser/**
rdf/**
tools/update-packaging/**
uriloader/exthandler/**
uriloader/exthandler/tests/mochitest/**
@ -57,7 +55,6 @@ mfbt/**
mozglue/**
nsprpub/**
other-licenses/**
probes/**
startupcache/**
xpfe/**
@ -104,8 +101,6 @@ devtools/client/performance/components/test/test_jit_optimizations_01.html
devtools/client/responsive.html/test/browser/touch.html
devtools/client/shared/components/test/mochitest/*.html
!devtools/client/shared/components/test/mochitest/test_stack-trace.html
devtools/client/shared/shim/test/test_*.html
devtools/client/shared/test/browser_toolbar_webconsole_errors_count.html
devtools/client/storage/test/*.html
!devtools/client/storage/test/storage-cookies.html
!devtools/client/storage/test/storage-overflow.html
@ -176,7 +171,6 @@ devtools/server/tests/unit/xpcshell_debugging_script.js
# dom/ exclusions
dom/abort/**
dom/animation/**
dom/archivereader/**
dom/asmjscache/**
dom/audiochannel/**
dom/base/**
@ -190,7 +184,6 @@ dom/canvas/**
dom/commandhandler/**
dom/console/**
dom/crypto/**
dom/devicestorage/**
dom/encoding/**
dom/events/**
dom/fetch/**
@ -198,7 +191,6 @@ dom/file/**
dom/filehandle/**
dom/filesystem/**
dom/flex/**
dom/flyweb/**
dom/gamepad/**
dom/geolocation/**
dom/grid/**
@ -206,7 +198,6 @@ dom/html/**
dom/imptests/**
dom/interfaces/**
dom/ipc/**
dom/json/**
dom/jsurl/**
dom/locales/**
dom/manifest/**
@ -233,12 +224,9 @@ dom/promise/**
dom/push/**
dom/quota/**
dom/res/**
dom/secureelement/**
dom/security/test/contentverifier/**
dom/security/test/cors/**
dom/security/test/csp/**
dom/security/test/general/**
dom/security/test/hsts/**
dom/security/test/mixedcontentblocker/**
dom/security/test/sri/**
dom/security/test/unit/**
@ -252,7 +240,6 @@ dom/tests/html/**
dom/tests/js/**
dom/tests/mochitest/**
dom/tests/unit/**
dom/time/**
dom/u2f/**
dom/url/**
dom/vr/**
@ -353,7 +340,6 @@ testing/mozbase/mozprofile/tests/files/prefs_with_comments.js
testing/talos/talos/scripts/jszip.min.js
testing/talos/talos/startup_test/sessionrestore/profile/sessionstore.js
testing/talos/talos/startup_test/sessionrestore/profile-manywindows/sessionstore.js
testing/talos/talos/tests/canvasmark/**
testing/talos/talos/tests/devtools/addon/content/pages/**
testing/talos/talos/tests/dromaeo/**
testing/talos/talos/tests/v8_7/**
@ -371,9 +357,6 @@ services/common/kinto-offline-client.js
# toolkit/ exclusions
# Not part of the default build
toolkit/components/help/**
# Intentionally invalid JS
toolkit/components/workerloader/tests/moduleF-syntax-error.js

Просмотреть файл

@ -146,3 +146,4 @@ ccfd7b716a91241ddbc084cb7116ec561e56d5d1 FIREFOX_BETA_61_BASE
9b74b9f2939a7ae3a0ea6e711dc32ed5203e03ff FIREFOX_BETA_62_BASE
4f6e597104dabedfecfafa2ab63dc79fd7f8bc7a FIREFOX_NIGHTLY_62_END
190b827aaa2b5e6fb9af7a0defb238ccc35f8b9e FIREFOX_BETA_63_BASE
034c5ef24e98b0ce85fa849face079f568eb397c FIREFOX_NIGHTLY_63_END

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1346211 - Modifying ICU data file requires a clobber.
Merge day clobber

Просмотреть файл

@ -32,15 +32,12 @@ module.exports = {
"new-cap": ["error", {"capIsNew": false}],
"new-parens": "error",
"no-bitwise": "off",
"no-catch-shadow": "error",
"no-comma-dangle": "off",
"no-console": "off",
"no-constant-condition": "off",
"no-continue": "off",
"no-div-regex": "off",
"no-extend-native": "error",
"no-extra-parens": "off",
"no-extra-strict": "off",
"no-fallthrough": "error",
"no-floating-decimal": "off",
"no-inline-comments": "off",
@ -54,12 +51,10 @@ module.exports = {
"no-process-env": "off",
"no-process-exit": "off",
"no-proto": "error",
"no-reserved-keys": "off",
"no-restricted-modules": "off",
"no-return-assign": "error",
"no-script-url": "off",
"no-shadow": "error",
"no-space-before-semi": "off",
"no-sync": "off",
"no-ternary": "off",
"no-throw-literal": "error",
@ -76,9 +71,7 @@ module.exports = {
"radix": "error",
"semi-spacing": ["error", {"before": false, "after": true}],
"sort-vars": "off",
"space-in-brackets": "off",
"space-in-parens": ["error", "never"],
"space-unary-word-ops": "off",
"strict": ["error", "global"],
"valid-jsdoc": "off",
"vars-on-top": "off",
@ -86,7 +79,6 @@ module.exports = {
"wrap-regex": "off",
"yoda": "error",
"guard-for-in": "off",
"newline-after-var": "off",
"no-alert": "off",
"no-eq-null": "off",
"no-func-assign": "off",
@ -98,7 +90,6 @@ module.exports = {
"no-label-var": "off",
"no-lone-blocks": "off",
"no-loop-func": "off",
"no-negated-in-lhs": "off",
"no-new": "off",
"no-new-func": "off",
"no-new-object": "off",
@ -108,7 +99,6 @@ module.exports = {
"object-curly-spacing": "off",
"no-unused-expressions": "off",
"no-void": "off",
"no-wrap-func": "off",
"operator-assignment": "off",
"operator-linebreak": ["error", "after"]
}

Просмотреть файл

@ -271,6 +271,12 @@ pref("browser.urlbar.doubleClickSelectsAll", true);
pref("browser.urlbar.doubleClickSelectsAll", false);
#endif
// Whether using `ctrl` when hitting return/enter in the URL bar
// (or clicking 'go') should prefix 'www.' and suffix
// browser.fixup.alternate.suffix to the URL bar value prior to
// navigating.
pref("browser.urlbar.ctrlCanonizesURLs", true);
// Control autoFill behavior
pref("browser.urlbar.autoFill", true);
pref("browser.urlbar.speculativeConnect.enabled", true);

Просмотреть файл

@ -219,7 +219,7 @@ LauncherMain(int argc, wchar_t* argv[])
}
const Maybe<bool> isSafeMode = IsSafeModeRequested(argc, argv,
SafeModeFlag::None);
SafeModeFlag::NoKeyPressCheck);
if (!isSafeMode) {
ShowError(ERROR_INVALID_PARAMETER);
return 1;

Просмотреть файл

@ -267,7 +267,7 @@
accesskey="&sendPageToDevice.accesskey;"
hidden="true">
<menupopup id="context-sendpagetodevice-popup"
onpopupshowing="(() => { gSync.populateSendTabToDevicesMenu(event.target, gBrowser.currentURI.spec, gBrowser.contentTitle); })()"/>
onpopupshowing="(() => { gSync.populateSendTabToDevicesMenu(event.target, gBrowser.selectedTab); })()"/>
</menu>
<menuseparator id="context-sep-viewbgimage"/>
<menuitem id="context-viewbgimage"

Просмотреть файл

@ -58,11 +58,22 @@ var BrowserPageActions = {
_onPanelShowing() {
this.placeLazyActionsInPanel();
for (let action of PageActions.actionsInPanel(window)) {
if (action.id == "sendToDevice") {
this.panelNode.removeAttribute(action.getTitle());
action.setTitle(this.getSendToDeviceString(), window);
}
let buttonNode = this.panelButtonNodeForActionID(action.id);
action.onShowingInPanel(buttonNode);
}
},
getSendToDeviceString() {
let tabCount = gBrowser.multiSelectedTabsCount || 1;
return PluralForm.get(tabCount,
gNavigatorBundle.getString("pageAction.sendTabsToDevice.label"))
.replace("#1", tabCount.toLocaleString());
},
placeLazyActionsInPanel() {
let actions = this._actionsToLazilyPlaceInPanel;
this._actionsToLazilyPlaceInPanel = [];
@ -1023,16 +1034,12 @@ BrowserPageActions.sendToDevice = {
},
onShowingSubview(panelViewNode) {
let browser = gBrowser.selectedBrowser;
let url = browser.currentURI.spec;
let title = browser.contentTitle;
let bodyNode = panelViewNode.querySelector(".panel-subview-body");
let panelNode = panelViewNode.closest("panel");
// This is on top because it also clears the device list between state
// changes.
gSync.populateSendTabToDevicesMenu(bodyNode, url, title, (clientId, name, clientType, lastModified) => {
gSync.populateSendTabToDevicesMenu(bodyNode, gBrowser.selectedTab, (clientId, name, clientType, lastModified) => {
if (!name) {
return document.createXULElement("toolbarseparator");
}

Просмотреть файл

@ -361,7 +361,7 @@ var gSync = {
}
},
populateSendTabToDevicesMenu(devicesPopup, url, title, createDeviceNodeFn) {
populateSendTabToDevicesMenu(devicesPopup, aTab, createDeviceNodeFn) {
if (!createDeviceNodeFn) {
createDeviceNodeFn = (clientId, name, clientType, lastModified) => {
let eltName = name ? "menuitem" : "menuseparator";
@ -386,7 +386,7 @@ var gSync = {
const state = UIState.get();
if (state.status == UIState.STATUS_SIGNED_IN && this.remoteClients.length > 0) {
this._appendSendTabDeviceList(fragment, createDeviceNodeFn, url, title);
this._appendSendTabDeviceList(fragment, createDeviceNodeFn, aTab);
} else if (state.status == UIState.STATUS_SIGNED_IN) {
this._appendSendTabSingleDevice(fragment, createDeviceNodeFn);
} else if (state.status == UIState.STATUS_NOT_VERIFIED ||
@ -402,14 +402,27 @@ var gSync = {
// TODO: once our transition from the old-send tab world is complete,
// this list should be built using the FxA device list instead of the client
// collection.
_appendSendTabDeviceList(fragment, createDeviceNodeFn, url, title) {
_appendSendTabDeviceList(fragment, createDeviceNodeFn, tab) {
let tabsToSend = tab.multiselected ? gBrowser.selectedTabs : [tab];
function getTabUrl(t) {
return t.linkedBrowser.currentURI.spec;
}
function getTabTitle(t) {
return t.linkedBrowser.contentTitle;
}
const onSendAllCommand = (event) => {
this.sendTabToDevice(url, this.remoteClients, title);
for (let t of tabsToSend) {
this.sendTabToDevice(getTabUrl(t), this.remoteClients, getTabTitle(t));
}
};
const onTargetDeviceCommand = (event) => {
const clientId = event.target.getAttribute("clientId");
const client = this.remoteClients.find(c => c.id == clientId);
this.sendTabToDevice(url, [client], title);
for (let t of tabsToSend) {
this.sendTabToDevice(getTabUrl(t), [client], getTabTitle(t));
}
};
function addTargetDevice(clientId, name, clientType, lastModified) {
@ -516,14 +529,31 @@ var gSync = {
// "Send Tab to Device" menu item
updateTabContextMenu(aPopupMenu, aTargetTab) {
// We may get here before initialisation. This situation
// can lead to a empty label for 'Send To Device' Menu.
this.init();
if (!this.SYNC_ENABLED) {
// These items are hidden in onSyncDisabled(). No need to do anything.
return;
}
const enabled = !this.syncConfiguredAndLoading &&
this.isSendableURI(aTargetTab.linkedBrowser.currentURI.spec);
let hasASendableURI = false;
for (let tab of aTargetTab.multiselected ? gBrowser.selectedTabs : [aTargetTab]) {
if (this.isSendableURI(tab.linkedBrowser.currentURI.spec)) {
hasASendableURI = true;
break;
}
}
const enabled = !this.syncConfiguredAndLoading && hasASendableURI;
document.getElementById("context_sendTabToDevice").disabled = !enabled;
let sendTabsToDevice = document.getElementById("context_sendTabToDevice");
sendTabsToDevice.disabled = !enabled;
let tabCount = aTargetTab.multiselected ? gBrowser.multiSelectedTabsCount : 1;
sendTabsToDevice.label = PluralForm.get(tabCount,
gNavigatorBundle.getString("sendTabsToDevice.label"))
.replace("#1", tabCount.toLocaleString());
sendTabsToDevice.accessKey = gNavigatorBundle.getString("sendTabsToDevice.accesskey");
},
// "Send Page to Device" and "Send Link to Device" menu items

Просмотреть файл

@ -5313,32 +5313,6 @@ var TabsProgressListener = {
TelemetryStopwatch.cancel("FX_PAGE_LOAD_MS", aBrowser);
}
}
// We used to listen for clicks in the browser here, but when that
// became unnecessary, removing the code below caused focus issues.
// This code should be removed. Tracked in bug 1337794.
let isRemoteBrowser = aBrowser.isRemoteBrowser;
// We check isRemoteBrowser here to avoid requesting the doc CPOW
let doc = isRemoteBrowser ? null : aWebProgress.DOMWindow.document;
if (!isRemoteBrowser &&
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
Components.isSuccessCode(aStatus) &&
doc.documentURI.startsWith("about:") &&
!doc.documentURI.toLowerCase().startsWith("about:blank") &&
!doc.documentURI.toLowerCase().startsWith("about:home") &&
!doc.documentElement.hasAttribute("hasBrowserHandlers")) {
// STATE_STOP may be received twice for documents, thus store an
// attribute to ensure handling it just once.
doc.documentElement.setAttribute("hasBrowserHandlers", "true");
aBrowser.addEventListener("pagehide", function onPageHide(event) {
if (event.target.defaultView.frameElement)
return;
aBrowser.removeEventListener("pagehide", onPageHide, true);
if (event.target.documentElement)
event.target.documentElement.removeAttribute("hasBrowserHandlers");
}, true);
}
},
onLocationChange(aBrowser, aWebProgress, aRequest, aLocationURI, aFlags) {

Просмотреть файл

@ -142,11 +142,10 @@ xmlns="http://www.w3.org/1999/xhtml"
tbattr="tabbrowser-multiple"
oncommand="gBrowser.replaceTabsWithWindow(TabContextMenu.contextTab);"/>
<menuseparator id="context_sendTabToDevice_separator" class="sync-ui-item"/>
<menu id="context_sendTabToDevice" label="&sendTabToDevice.label;"
class="sync-ui-item"
accesskey="&sendTabToDevice.accesskey;">
<menu id="context_sendTabToDevice"
class="sync-ui-item">
<menupopup id="context_sendTabToDevicePopupMenu"
onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab.linkedBrowser.currentURI.spec, TabContextMenu.contextTab.linkedBrowser.contentTitle);"/>
onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab);"/>
</menu>
<menuseparator/>
<menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
@ -488,7 +487,7 @@ xmlns="http://www.w3.org/1999/xhtml"
noautofocus="true"
copyURL-title="&pageAction.copyLink.label;"
emailLink-title="&emailPageCmd.label;"
sendToDevice-title="&pageAction.sendTabToDevice.label;"
sendToDevice-title=""
sendToDevice-notReadyTitle="&sendToDevice.syncNotReady.label;"
shareURL-title="&pageAction.shareUrl.label;"
shareMore-label="&pageAction.shareMore.label;">

Просмотреть файл

@ -27,9 +27,9 @@ add_task(async function test_opening_blocked_popups() {
await ContentTask.spawn(tab.linkedBrowser, baseURL, async function(uri) {
let iframe = content.document.createElement("iframe");
iframe.src = uri;
let pageHideHappened = ContentTaskUtils.waitForEvent(this, "pagehide", true);
content.document.body.appendChild(iframe);
iframe.src = uri;
await pageHideHappened;
});

Просмотреть файл

@ -63,6 +63,7 @@ skip-if = (verify && (os == 'win' || os == 'mac'))
[browser_reload_deleted_file.js]
skip-if = (debug && os == 'mac') || (debug && os == 'linux' && bits == 64) #Bug 1421183, disabled on Linux/OSX for leaked windows
[browser_tabCloseProbes.js]
[browser_tabContextMenu_keyboard.js]
[browser_tabReorder_overflow.js]
[browser_tabReorder.js]
[browser_tabSpinnerProbe.js]

Просмотреть файл

@ -0,0 +1,53 @@
/* 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/. */
async function openContextMenu() {
let contextMenu = document.getElementById("tabContextMenu");
let popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
EventUtils.synthesizeMouseAtCenter(gBrowser.selectedTab, {type: "contextmenu", button: 2});
await popupShown;
}
async function closeContextMenu() {
let contextMenu = document.getElementById("tabContextMenu");
let popupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
EventUtils.synthesizeKey("KEY_Escape");
await popupHidden;
}
add_task(async function test() {
// Ensure tabs are focusable.
await SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
// There should be one tab when we start the test.
let tab1 = gBrowser.selectedTab;
let tab2 = BrowserTestUtils.addTab(gBrowser);
tab1.focus();
is(document.activeElement, tab1, "tab1 should be focused");
// Ensure that DownArrow doesn't switch to tab2 while the context menu is open.
await openContextMenu();
EventUtils.synthesizeKey("KEY_ArrowDown");
await closeContextMenu();
is(gBrowser.selectedTab, tab1, "tab1 should still be active");
if (AppConstants.platform == "macosx") {
// On Mac, focus doesn't return to the tab after dismissing the context menu.
// Since we're not testing that here, work around it by just focusing again.
tab1.focus();
}
is(document.activeElement, tab1, "tab1 should be focused");
// Switch to tab2 by pressing DownArrow.
await BrowserTestUtils.switchTab(gBrowser,
() => EventUtils.synthesizeKey("KEY_ArrowDown"));
is(gBrowser.selectedTab, tab2, "should have switched to tab2");
is(document.activeElement, tab2, "tab2 should now be focused");
// Ensure that UpArrow doesn't switch to tab1 while the context menu is open.
await openContextMenu();
EventUtils.synthesizeKey("KEY_ArrowUp");
await closeContextMenu();
is(gBrowser.selectedTab, tab2, "tab2 should still be active");
gBrowser.removeTab(tab2);
});

Просмотреть файл

@ -1,29 +1,34 @@
add_task(async function() {
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
add_task(async function checkCtrlWorks() {
let testcases = [
["example", "http://www.example.net/", { shiftKey: true }],
["example", "http://www.example.com/", { ctrlKey: true }],
// Check that a direct load is not overwritten by a previous canonization.
["http://example.com/test/", "http://example.com/test/", {}],
["ex-ample", "http://www.ex-ample.net/", { shiftKey: true }],
[" example ", "http://www.example.net/", { shiftKey: true }],
[" example/foo ", "http://www.example.net/foo", { shiftKey: true }],
[" example/foo bar ", "http://www.example.net/foo%20bar", { shiftKey: true }],
["example.net", "http://example.net/", { shiftKey: true }],
["http://example", "http://example/", { shiftKey: true }],
["example:8080", "http://example:8080/", { shiftKey: true }],
["ex-ample.foo", "http://ex-ample.foo/", { shiftKey: true }],
["example.foo/bar ", "http://example.foo/bar", { shiftKey: true }],
["1.1.1.1", "http://1.1.1.1/", { shiftKey: true }],
["ftp://example", "ftp://example/", { shiftKey: true }],
["ftp.example.bar", "http://ftp.example.bar/", { shiftKey: true }],
["ex ample", Services.search.defaultEngine.getSubmission("ex ample", null, "keyword").uri.spec, { shiftKey: true }],
["ex-ample", "http://www.ex-ample.com/", { ctrlKey: true }],
[" example ", "http://www.example.com/", { ctrlKey: true }],
[" example/foo ", "http://www.example.com/foo", { ctrlKey: true }],
[" example/foo bar ", "http://www.example.com/foo%20bar", { ctrlKey: true }],
["example.net", "http://example.net/", { ctrlKey: true }],
["http://example", "http://example/", { ctrlKey: true }],
["example:8080", "http://example:8080/", { ctrlKey: true }],
["ex-ample.foo", "http://ex-ample.foo/", { ctrlKey: true }],
["example.foo/bar ", "http://example.foo/bar", { ctrlKey: true }],
["1.1.1.1", "http://1.1.1.1/", { ctrlKey: true }],
["ftp://example", "ftp://example/", { ctrlKey: true }],
["ftp.example.bar", "http://ftp.example.bar/", { ctrlKey: true }],
["ex ample", Services.search.defaultEngine.getSubmission("ex ample", null, "keyword").uri.spec, { ctrlKey: true }],
];
// Disable autoFill for this test, since it could mess up the results.
let autoFill = Preferences.get("browser.urlbar.autoFill");
Preferences.set("browser.urlbar.autoFill", false);
registerCleanupFunction(() => {
Preferences.set("browser.urlbar.autoFill", autoFill);
});
await SpecialPowers.pushPrefEnv({set: [
["browser.urlbar.autoFill", false],
["browser.urlbar.ctrlCanonizesURLs", true],
]});
for (let [inputValue, expectedURL, options] of testcases) {
let promiseLoad = waitForDocLoadAndStopIt(expectedURL);
@ -40,3 +45,38 @@ add_task(async function() {
await promiseLoad;
}
});
add_task(async function checkPrefTurnsOffCanonize() {
// Add a dummy search engine to avoid hitting the network.
let engine = await SearchTestUtils.promiseNewSearchEngine(
getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME);
let oldCurrentEngine = Services.search.currentEngine;
Services.search.currentEngine = engine;
registerCleanupFunction(() => { Services.search.currentEngine = oldCurrentEngine; });
let tabsToClose = [];
// Ensure we don't end up loading something in the current tab becuase it's empty:
if (isTabEmpty(gBrowser.selectedTab)) {
tabsToClose.push(await BrowserTestUtils.openNewForegroundTab({gBrowser, opening: "about:mozilla"}));
}
let initialTabURL = gBrowser.selectedBrowser.currentURI.spec;
let initialTab = gBrowser.selectedTab;
await SpecialPowers.pushPrefEnv({set: [["browser.urlbar.ctrlCanonizesURLs", false]]});
let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser);
gURLBar.focus();
gURLBar.selectionStart = gURLBar.selectionEnd =
gURLBar.inputField.value.length;
gURLBar.inputField.value = "exampl";
EventUtils.sendString("e");
EventUtils.synthesizeKey("KEY_Enter", AppConstants.platform == "macosx" ?
{metaKey: true} : {ctrlKey: true});
tabsToClose.push(await promiseTabOpened);
is(initialTab.linkedBrowser.currentURI.spec, initialTabURL,
"Original tab shouldn't have navigated");
for (let t of tabsToClose) {
gBrowser.removeTab(t);
}
});

Просмотреть файл

@ -70,10 +70,7 @@ add_task(async function plainEnterOnSuggestion() {
});
add_task(async function ctrlEnterOnSuggestion() {
await testPressEnterOnSuggestion("http://www.foofoo.com/",
AppConstants.platform === "macosx" ?
{ metaKey: true } :
{ ctrlKey: true });
await testPressEnterOnSuggestion("http://www.foofoo.com/", { ctrlKey: true });
});
add_task(async function copySuggestionText() {

Просмотреть файл

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* This test ensures that pressing ctrl/shift+enter bypasses the autoFilled
/* This test ensures that pressing ctrl+enter bypasses the autoFilled
* value, and only considers what the user typed (but not just enter).
*/
@ -49,16 +49,6 @@ add_task(async function() {
autofilled: "example.com/",
modified: "www.exam.com",
waitForUrl: "http://www.exam.com/",
keys: [["KEY_Enter", AppConstants.platform === "macosx" ?
{metaKey: true} :
{ctrlKey: true}]],
});
await test_autocomplete({ desc: "SHIFT+ENTER on the autofilled part should bypass autofill",
typed: "exam",
autofilled: "example.com/",
modified: "www.exam.net",
waitForUrl: "http://www.exam.net/",
keys: [["KEY_Enter", {shiftKey: true}]],
keys: [["KEY_Enter", {ctrlKey: true}]],
});
});

Просмотреть файл

@ -85,6 +85,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
this._formattingEnabled = this._prefs.getBoolPref("formatting.enabled");
this._mayTrimURLs = this._prefs.getBoolPref("trimURLs");
this._adoptIntoActiveWindow = this._prefs.getBoolPref("switchTabs.adoptIntoActiveWindow");
this._ctrlCanonizesURLs = this._prefs.getBoolPref("ctrlCanonizesURLs");
this.inputField.controllers.insertControllerAt(0, this._copyCutController);
this.inputField.addEventListener("paste", this);
this.inputField.addEventListener("mousedown", this);
@ -713,11 +714,16 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
let isMouseEvent = event instanceof MouseEvent;
let reuseEmpty = !isMouseEvent;
let where = undefined;
if (isMouseEvent) {
where = whereToOpenLink(event, false, false);
if (!isMouseEvent && event && event.altKey) {
// We support using 'alt' to open in a tab, because ctrl/shift
// might be used for canonizing URLs:
where = event.shiftKey ? "tabshifted" : "tab";
} else if (!isMouseEvent && this._ctrlCanonizesURLs && event && event.ctrlKey) {
// If we're allowing canonization, and this is a key event with ctrl
// pressed, open in current tab to allow ctrl-enter to canonize URL.
where = "current";
} else {
let altEnter = event && event.altKey;
where = altEnter ? "tab" : "current";
where = whereToOpenLink(event, false, false);
}
if (this.openInTab) {
if (where == "current") {
@ -848,6 +854,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
}
return;
}
// Once we get here, we got a switchtab action but the user
// bypassed it by pressing shift/meta/ctrl. Those modifiers
// might otherwise affect where we open - we always want to
// open in the current tab.
where = "current";
break;
case "searchengine":
if (selectedOneOff && selectedOneOff.engine) {
@ -1027,40 +1039,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Only add the suffix when the URL bar value isn't already "URL-like",
// and only if we get a keyboard event, to match user expectations.
if (!/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(aUrl) ||
!(aTriggeringEvent instanceof KeyboardEvent)) {
!this._ctrlCanonizesURLs ||
!(aTriggeringEvent instanceof KeyboardEvent) ||
!aTriggeringEvent.ctrlKey) {
return;
}
let url = aUrl;
let accel = AppConstants.platform == "macosx" ?
aTriggeringEvent.metaKey :
aTriggeringEvent.ctrlKey;
let shift = aTriggeringEvent.shiftKey;
let suffix = "";
switch (true) {
case (accel && shift):
suffix = ".org/";
break;
case (shift):
suffix = ".net/";
break;
case (accel):
try {
suffix = Services.prefs.getCharPref("browser.fixup.alternate.suffix");
if (suffix.charAt(suffix.length - 1) != "/")
suffix += "/";
} catch (e) {
suffix = ".com/";
}
break;
let suffix = Services.prefs.getCharPref("browser.fixup.alternate.suffix", ".com/");
if (!suffix.endsWith("/")) {
suffix += "/";
}
if (!suffix)
return;
// trim leading/trailing spaces (bug 233205)
url = url.trim();
let url = aUrl.trim();
// Tack www. and suffix on. If user has appended directories, insert
// suffix before them (bug 279035). Be careful not to get two slashes.
@ -1331,6 +1322,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
case "formatting.enabled":
this._formattingEnabled = this._prefs.getBoolPref(aData);
break;
case "ctrlCanonizesURLs":
this._ctrlCanonizesURLs = this._prefs.getBoolPref(aData);
break;
case "speculativeConnect.enabled":
this.speculativeConnectEnabled = this._prefs.getBoolPref(aData);
break;
@ -1657,9 +1651,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
}
let canonizeValue = this.value;
if (event.shiftKey || (AppConstants.platform === "macosx" ?
event.metaKey :
event.ctrlKey)) {
if (event.ctrlKey) {
let action = this._parseActionUrl(canonizeValue);
if (action && "searchSuggestion" in action.params) {
canonizeValue = action.params.searchSuggestion;

Просмотреть файл

@ -229,6 +229,12 @@ function generateDocumentation() {
let new_cont = document.getElementById("documentationContent");
new_cont.setAttribute("id", "documentationContent");
// map specific policies to a different string ID, to allow updates to
// existing descriptions
let string_mapping = {
"DisableSetDesktopBackground": "DisableSetAsDesktopBackground",
};
for (let policyName in schema.properties) {
let main_tbody = document.createElement("tbody");
main_tbody.classList.add("collapsible");
@ -244,7 +250,8 @@ function generateDocumentation() {
row.appendChild(col(policyName));
}
let descriptionColumn = col("");
descriptionColumn.setAttribute("data-l10n-id", `policy-${policyName}`);
let stringID = string_mapping[policyName] || policyName;
descriptionColumn.setAttribute("data-l10n-id", `policy-${stringID}`);
row.appendChild(descriptionColumn);
main_tbody.appendChild(row);
let sec_tbody = document.createElement("tbody");

Просмотреть файл

@ -1047,6 +1047,8 @@ BrowserGlue.prototype = {
toolbar_field_border: "rgba(249, 249, 250, 0.2)",
ntp_background: "#2A2A2E",
ntp_text: "rgb(249, 249, 250)",
sidebar: "#19191a",
sidebar_text: "rgb(249, 249, 250)",
author: vendorShortName,
}, {
useInDarkMode: true,

Просмотреть файл

@ -60,12 +60,26 @@ add_task(async function testContentBlockingToggle() {
add_task(async function testContentBlockingMainCategory() {
SpecialPowers.pushPrefEnv({set: [
[CB_UI_PREF, true],
]});
let prefs = [
[CB_PREF, true],
[FB_PREF, true],
[TP_PREF, false],
[TP_PBM_PREF, true],
[NCB_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER],
]});
];
for (let pref of prefs) {
switch (typeof pref[1]) {
case "boolean":
SpecialPowers.setBoolPref(pref[0], pref[1]);
break;
case "number":
SpecialPowers.setIntPref(pref[0], pref[1]);
break;
}
}
let checkboxes = [
"#contentBlockingFastBlockCheckbox",
@ -115,6 +129,10 @@ add_task(async function testContentBlockingMainCategory() {
checkControlStateWorker(doc, alwaysEnabledControls, true);
gBrowser.removeCurrentTab();
for (let pref of prefs) {
SpecialPowers.clearUserPref(pref[0]);
}
});
// Tests that the content blocking "Restore Defaults" button does what it's supposed to.

Просмотреть файл

@ -1 +1 @@
63.0a1
64.0a1

Просмотреть файл

@ -1 +1 @@
63.0a1
64.0a1

Просмотреть файл

@ -60,26 +60,32 @@ policy-DisableSafeMode = Disable the feature to restart in Safe Mode. Note: the
policy-DisableSecurityBypass = Prevent the user from bypassing certain security warnings.
policy-DisableSetDesktopBackground = Disable the menu command Set Image as Desktop Background.
policy-DisableSetAsDesktopBackground = Disable the menu command Set as Desktop Background for images.
policy-DisableSystemAddonUpdate = Prevent the browser from installing and updating system add-ons.
policy-DisableTelemetry = Turn off Telemetry.
policy-DisplayBookmarksToolbar = Display the Bookmark Toolbar by default.
policy-DisplayBookmarksToolbar = Display the Bookmarks Toolbar by default.
policy-DisplayMenuBar = Display the Menu Bar by default.
policy-DontCheckDefaultBrowser = Disable check for default browser on startup.
# “lock” means that the user wont be able to change this setting
policy-EnableTrackingProtection = Enable or disable Content Blocking and optionally lock it.
# A “locked” extension cant be disabled or removed by the user. This policy
# takes 3 keys (“Install”, ”Uninstall”, ”Locked”), you can either keep them in
# English or translate them as verbs. See also:
# https://github.com/mozilla/policy-templates/blob/master/README.md#extensions-machine-only
policy-Extensions = Install, uninstall or lock extensions. The Install option takes URLs or paths as parameters. The Uninstall and Locked options take extension IDs.
policy-FlashPlugin = Allow or deny usage of the Flash plugin.
policy-HardwareAcceleration = If false, turn off hardware acceleration.
# “lock” means that the user wont be able to change this setting
policy-Homepage = Set and optionally lock the homepage.
policy-InstallAddonsPermission = Allow certain websites to install add-ons.
@ -90,7 +96,7 @@ policy-OfferToSaveLogins = Enforce the setting to allow { -brand-short-name } to
policy-OverrideFirstRunPage = Override the first run page. Set this policy to blank if you want to disable the first run page.
policy-OverridePostUpdatePage = Override the post-update "Whats New" page. Set this policy to blank if you want to disable the post-update page.
policy-OverridePostUpdatePage = Override the post-update “Whats New” page. Set this policy to blank if you want to disable the post-update page.
policy-Permissions = Configure permissions for camera, microphone, location and notifications.
@ -104,4 +110,6 @@ policy-SearchBar = Set the default location of the search bar. The user is still
policy-SearchEngines = Configure search engine settings. This policy is only available on the Extended Support Release (ESR) version.
# “format” refers to the format used for the value of this policy. See also:
# https://github.com/mozilla/policy-templates/blob/master/README.md#websitefilter-machine-only
policy-WebsiteFilter = Block websites from being visited. See documentation for more details on the format.

Просмотреть файл

@ -32,4 +32,4 @@
<!ENTITY trackingProtection.startTour1 "See how it works">
<!ENTITY contentBlocking.title "Content Blocking">
<!ENTITY contentBlocking.description "Some websites use trackers that can monitor your activity across the Internet. In private windows Firefox Content Blocking automatically blocks many trackers that can collect information about your browsing behavior.">
<!ENTITY contentBlocking.description "Some websites use trackers that can monitor your activity across the Internet. In private windows, Firefox Content Blocking automatically blocks many trackers that can collect information about your browsing behavior.">

Просмотреть файл

@ -61,8 +61,6 @@ can reach it easily. -->
<!ENTITY pinTab.accesskey "P">
<!ENTITY unpinTab.label "Unpin Tab">
<!ENTITY unpinTab.accesskey "b">
<!ENTITY sendTabToDevice.label "Send Tab to Device">
<!ENTITY sendTabToDevice.accesskey "n">
<!ENTITY sendPageToDevice.label "Send Page to Device">
<!ENTITY sendPageToDevice.accesskey "n">
<!ENTITY sendLinkToDevice.label "Send Link to Device">
@ -1088,7 +1086,6 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY pageAction.disallowInUrlbar.label "Dont Show in Address Bar">
<!ENTITY pageAction.manageExtension.label "Manage Extension…">
<!ENTITY pageAction.sendTabToDevice.label "Send Tab to Device">
<!ENTITY sendToDevice.syncNotReady.label "Syncing Devices…">
<!ENTITY pageAction.shareUrl.label "Share">

Просмотреть файл

@ -905,6 +905,19 @@ unmuteSelectedTabs.accesskey = b
playTabs.label = Play Tabs
playTabs.accesskey = y
# LOCALIZATION NOTE (sendTabsToDevice.label):
# Semi-colon list of plural forms.
# See: https://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is the number of tabs sent to the device.
sendTabsToDevice.label = Send Tab to Device;Send #1 Tabs to Device
sendTabsToDevice.accesskey = n
# LOCALIZATION NOTE (pageAction.sendTabsToDevice.label):
# Semi-colon list of plural forms.
# See: https://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is the number of tabs sent to the device.
pageAction.sendTabsToDevice.label = Send Tab to Device;Send #1 Tabs to Device
# LOCALIZATION NOTE (certErrorDetails*.label): These are text strings that
# appear in the about:certerror page, so that the user can copy and send them to
# the server administrators for troubleshooting.

Просмотреть файл

@ -26,12 +26,12 @@
margin: 0 10px;
}
.sidebar-placesTreechildren::-moz-tree-row(selected) {
.sidebar-panel:not([lwt-sidebar]) .sidebar-placesTreechildren::-moz-tree-row(selected) {
-moz-appearance: -moz-mac-source-list-selection;
-moz-font-smoothing-background-color: -moz-mac-source-list-selection;
}
.sidebar-placesTreechildren::-moz-tree-row(selected,focus) {
.sidebar-panel:not([lwt-sidebar-highlight]) .sidebar-placesTreechildren::-moz-tree-row(selected,focus) {
-moz-appearance: -moz-mac-active-source-list-selection;
-moz-font-smoothing-background-color: -moz-mac-active-source-list-selection;
}

Просмотреть файл

@ -19,7 +19,6 @@
}
.sidebar-panel[lwt-sidebar-brighttext] .sidebar-placesTreechildren::-moz-tree-row(selected) {
-moz-appearance: none;
background-color: rgba(249,249,250,.1);
}
@ -30,7 +29,6 @@
}
.sidebar-panel[lwt-sidebar-highlight] .sidebar-placesTreechildren::-moz-tree-row(selected,focus) {
-moz-appearance: none;
background-color: var(--lwt-sidebar-highlight-background-color);
}

Просмотреть файл

@ -26,7 +26,7 @@
-moz-appearance: none;
border: 0 solid;
border-inline-end-width: 1px;
border-inline-end-color: var(--sidebar-border-color);
border-color: var(--sidebar-border-color);
min-width: 1px;
width: 4px;
background-image: none !important;

Просмотреть файл

@ -82,7 +82,7 @@ function do_run_test() {
}
if (typeof run_test === "undefined") {
// eslint-disable-next-line no-native-reassign
// eslint-disable-next-line no-global-assign
run_test = function() {
do_run_test();
};

Просмотреть файл

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
63.0a1
64.0a1

Просмотреть файл

@ -253,6 +253,8 @@ module.exports = {
// Allow using == instead of ===, in the interest of landing something since
// the devtools codebase is split on convention here.
"eqeqeq": "off",
// Disallow space between function identifier and application.
"func-call-spacing": "error",
// Don't require function expressions to have a name.
// This makes the code more verbose and hard to read. Our engine already
// does a fantastic job assigning a name to the function, which includes
@ -288,9 +290,6 @@ module.exports = {
"new-parens": "error",
// Allow use of bitwise operators.
"no-bitwise": "off",
// Disallow the catch clause parameter name being the same as a variable in
// the outer scope, to avoid confusion.
"no-catch-shadow": "error",
// Allow using the console API.
"no-console": "off",
// Allow using constant expressions in conditions like while (true)
@ -341,8 +340,6 @@ module.exports = {
"no-proto": "error",
// Disallow multiple spaces in a regular expression literal.
"no-regex-spaces": "off",
// Allow reserved words being used as object literal keys.
"no-reserved-keys": "off",
// Don't restrict usage of specified node modules (not a node environment).
"no-restricted-modules": "off",
// Disallow use of assignment in return statement. It is preferable for a
@ -356,8 +353,6 @@ module.exports = {
// random name.
// Still, making this a warning can help people avoid being confused.
"no-shadow": "error",
// Disallow space between function identifier and application.
"no-spaced-func": "error",
// Allow use of synchronous methods (not a node environment).
"no-sync": "off",
// Allow the use of ternary operators.
@ -398,10 +393,6 @@ module.exports = {
// Don't require to sort variables within the same declaration block.
// Anyway, one-var is disabled.
"sort-vars": "off",
// Disable the rule that checks if spaces inside {} and [] are there or not.
// Our code is split on conventions, and it'd be nice to have "error" rules
// instead, one for [] and one for {}. So, disabling until we write them.
"space-in-brackets": "off",
// Disallow spaces inside parentheses.
"space-in-parens": ["error", "never"],
// Require spaces before/after unary operators (words on by default,
@ -433,8 +424,6 @@ module.exports = {
"computed-property-spacing": "off",
// Require for-in loops to have an if statement.
"guard-for-in": "off",
// allow/disallow an empty newline after var statement
"newline-after-var": "off",
// disallow the use of alert, confirm, and prompt
"no-alert": "off",
// disallow comparisons to null without a type-checking operator
@ -455,8 +444,6 @@ module.exports = {
"no-lone-blocks": "off",
// disallow creation of functions within loops
"no-loop-func": "off",
// disallow negation of the left operand of an in expression
"no-negated-in-lhs": "off",
// disallow use of new operator when not part of the assignment or
// comparison
"no-new": "off",
@ -480,8 +467,6 @@ module.exports = {
"no-useless-concat": "off",
// disallow use of void operator
"no-void": "off",
// disallow wrapping of non-IIFE statements in parens
"no-wrap-func": "off",
// require assignment operator shorthand where possible or prohibit it
// entirely
"operator-assignment": "off",

Просмотреть файл

@ -11,7 +11,6 @@ module.exports = {
"synthesizeKeyFromKeyTag": true,
"TargetFactory": true,
"waitForTick": true,
"waitUntilState": true,
},
"parserOptions": {

Просмотреть файл

@ -227,7 +227,6 @@ button {
height: 24px;
background-image: url(chrome://devtools/skin/images/help.svg);
background-repeat: no-repeat;
background-size: 24px;
flex-shrink: 0;
margin-inline-end: 8px;
}

Просмотреть файл

@ -116,6 +116,7 @@ body {
width: 16px;
height: 16px;
mask: url("chrome://devtools/skin/images/help.svg") no-repeat;
mask-size: contain;
}
.devtools-toolbar .help:focus {

Просмотреть файл

@ -3766,6 +3766,7 @@ img.skipPausing {
.command-bar img.shortcuts {
mask: url("chrome://devtools/skin/images/help.svg") no-repeat;
mask-size: contain;
}
.command-bar .replay-inactive {

Просмотреть файл

@ -6,11 +6,10 @@
"use strict";
const promise = require("promise");
const flags = require("devtools/shared/flags");
const ToolDefinitions = require("devtools/client/definitions").Tools;
const CssLogic = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const promise = require("promise");
const OutputParser = require("devtools/client/shared/output-parser");
const {PrefObserver} = require("devtools/client/shared/prefs");
const {createChild} = require("devtools/client/inspector/shared/utils");
@ -184,20 +183,14 @@ function CssComputedView(inspector, document, pageStyle) {
this.styleDocument.addEventListener("mousedown", this.focusWindow);
this.element.addEventListener("click", this._onClick);
this.element.addEventListener("contextmenu", this._onContextMenu);
this.element.addEventListener("mousemove", () => {
this.addHighlightersToView();
}, { once: true });
this.searchField.addEventListener("input", this._onFilterStyles);
this.searchClearButton.addEventListener("click", this._onClearSearch);
this.includeBrowserStylesCheckbox.addEventListener("input",
this._onIncludeBrowserStyles);
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
this.highlighters.addToView(this);
} else {
this.element.addEventListener("mousemove", () => {
this.highlighters.addToView(this);
}, { once: true });
}
this.searchClearButton.hidden = true;
// No results text.
@ -739,6 +732,14 @@ CssComputedView.prototype = {
}
},
/**
* Adds the highlighters overlay to the computed view. This is called by the "mousemove"
* event handler and in shared-head.js when opening and selecting the computed view.
*/
addHighlightersToView() {
this.highlighters.addToView(this);
},
/**
* Destructor for CssComputedView.
*/

Просмотреть файл

@ -5,7 +5,6 @@
"use strict";
const { throttle } = require("devtools/client/inspector/shared/utils");
const flags = require("devtools/shared/flags");
const {
clearFlexbox,
@ -63,16 +62,10 @@ class FlexboxInspector {
return;
}
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
this.document.addEventListener("mousemove", () => {
this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden);
this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown);
} else {
this.document.addEventListener("mousemove", () => {
this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden);
this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown);
}, { once: true });
}
}, { once: true });
this.inspector.sidebar.on("select", this.onSidebarSelect);
@ -311,77 +304,99 @@ class FlexboxInspector {
async update(flexboxFront) {
// Stop refreshing if the inspector or store is already destroyed or no node is
// selected.
if (!this.inspector ||
!this.store ||
!this.inspector.selection.nodeFront ||
!this.hasGetCurrentFlexbox) {
if (!this.inspector || !this.store || !this.inspector.selection.nodeFront) {
return;
}
try {
// Fetch the current flexbox if no flexbox front was passed into this update.
if (!flexboxFront) {
flexboxFront = await this.layoutInspector.getCurrentFlexbox(
this.inspector.selection.nodeFront);
}
// Clear the flexbox panel if there is no flex container for the current node
// selection.
if (!flexboxFront) {
this.store.dispatch(clearFlexbox());
return;
}
// If the FlexboxFront doesn't yet have access to the NodeFront for its container,
// then get it from the walker. This happens when the walker hasn't seen this
// particular DOM Node in the tree yet or when we are connected to an older server.
let containerNodeFront = flexboxFront.containerNodeFront;
if (!containerNodeFront) {
containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID,
["containerEl"]);
}
// Fetch the flex items for the given flex container and the flex item NodeFronts.
const flexItems = [];
const flexItemFronts = await flexboxFront.getFlexItems();
for (const flexItemFront of flexItemFronts) {
let itemNodeFront = flexItemFront.nodeFront;
if (!itemNodeFront) {
itemNodeFront = await this.walker.getNodeFromActor(flexItemFront.actorID,
["element"]);
// Fetch the current flexbox if no flexbox front was passed into this update.
if (!flexboxFront) {
try {
if (!this.hasGetCurrentFlexbox) {
return;
}
flexItems.push({
actorID: flexItemFront.actorID,
shown: false,
flexItemSizing: flexItemFront.flexItemSizing,
nodeFront: itemNodeFront,
properties: flexItemFront.properties,
});
flexboxFront = await this.layoutInspector.getCurrentFlexbox(
this.inspector.selection.nodeFront);
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
return;
}
}
// Clear the flexbox panel if there is no flex container for the current node
// selection.
if (!flexboxFront) {
try {
this.store.dispatch(clearFlexbox());
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
}
return;
}
let containerNodeFront = flexboxFront.containerNodeFront;
// If the FlexboxFront doesn't yet have access to the NodeFront for its container,
// then get it from the walker. This happens when the walker hasn't seen this
// particular DOM Node in the tree yet or when we are connected to an older server.
if (!containerNodeFront) {
try {
containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID,
["containerEl"]);
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
return;
}
}
const highlighted = this._highlighters &&
containerNodeFront == this.highlighters.flexboxHighlighterShown;
// Fetch the flex items for the given flex container and the flex item NodeFronts.
const flexItems = [];
const flexItemFronts = await flexboxFront.getFlexItems();
for (const flexItemFront of flexItemFronts) {
let itemNodeFront = flexItemFront.nodeFront;
if (!itemNodeFront) {
try {
itemNodeFront = await this.walker.getNodeFromActor(flexItemFront.actorID,
["element"]);
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
return;
}
}
const highlighted = this._highlighters &&
containerNodeFront == this.highlighters.flexboxHighlighterShown;
const currentUrl = this.inspector.target.url;
// Get the hostname, if there is no hostname, fall back on protocol
// ex: `data:` uri, and `about:` pages
const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
const customColors = await this.getCustomFlexboxColors();
const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR;
this.store.dispatch(updateFlexbox({
actorID: flexboxFront.actorID,
color,
flexItems,
highlighted,
nodeFront: containerNodeFront,
properties: flexboxFront.properties,
}));
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
flexItems.push({
actorID: flexItemFront.actorID,
shown: false,
flexItemSizing: flexItemFront.flexItemSizing,
nodeFront: itemNodeFront,
properties: flexItemFront.properties,
});
}
const currentUrl = this.inspector.target.url;
// Get the hostname, if there is no hostname, fall back on protocol
// ex: `data:` uri, and `about:` pages
const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
const customColors = await this.getCustomFlexboxColors();
const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR;
this.store.dispatch(updateFlexbox({
actorID: flexboxFront.actorID,
color,
flexItems,
highlighted,
nodeFront: containerNodeFront,
properties: flexboxFront.properties,
}));
}
}

Просмотреть файл

@ -85,7 +85,7 @@ class FontInspector {
this.onNewNode = this.onNewNode.bind(this);
this.onPreviewTextChange = debounce(this.onPreviewTextChange, 100, this);
this.onPropertyChange = this.onPropertyChange.bind(this);
this.onRulePropertyUpdated = debounce(this.onRulePropertyUpdated, 100, this);
this.onRulePropertyUpdated = debounce(this.onRulePropertyUpdated, 300, this);
this.onToggleFontHighlight = this.onToggleFontHighlight.bind(this);
this.onThemeChanged = this.onThemeChanged.bind(this);
this.update = this.update.bind(this);
@ -598,22 +598,23 @@ class FontInspector {
* @param {String} value
* CSS property value
*/
syncChanges(name, value) {
async syncChanges(name, value) {
const textProperty = this.getTextProperty(name, value);
if (textProperty) {
// This method may be called after the connection to the page style actor is closed.
// For example, during teardown of automated tests. Here, we catch any failure that
// may occur because of that. We're not interested in handling the error.
textProperty.setValue(value).catch(error => {
try {
await textProperty.setValue(value, "", true);
this.ruleView.on("property-value-updated", this.onRulePropertyUpdated);
} catch (error) {
// Because setValue() does an asynchronous call to the server, there is a chance
// the font editor was destroyed while we were waiting. If that happened, just
// bail out silently.
if (!this.document) {
return;
}
throw error;
});
}
}
this.ruleView.on("property-value-updated", this.onRulePropertyUpdated);
}
/**

Просмотреть файл

@ -6,7 +6,6 @@
const Services = require("Services");
const { throttle } = require("devtools/client/inspector/shared/utils");
const flags = require("devtools/shared/flags");
const {
updateGridColor,
@ -98,16 +97,10 @@ class GridInspector {
return;
}
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
this.document.addEventListener("mousemove", () => {
this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden);
this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown);
} else {
this.document.addEventListener("mousemove", () => {
this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden);
this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown);
}, { once: true });
}
}, { once: true });
this.inspector.sidebar.on("select", this.onSidebarSelect);
this.inspector.on("new-root", this.onNavigate);

Просмотреть файл

@ -3,4 +3,7 @@
module.exports = {
// Extend from the shared list of defined globals for mochitests.
"extends": "../../../../.eslintrc.mochitests.js",
"globals": {
"waitUntilState": true
}
};

Просмотреть файл

@ -2,5 +2,5 @@
module.exports = {
// Extend from the shared list of defined globals for mochitests.
"extends": "../../../../.eslintrc.mochitests.js",
"extends": "../../../../.eslintrc.mochitests.js"
};

Просмотреть файл

@ -73,7 +73,6 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/shared-redux-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js
@ -131,8 +130,6 @@ skip-if = true # Bug 1177550
[browser_markup_events_react_production_16.2.0_jsx.js]
[browser_markup_events_source_map.js]
[browser_markup_events-windowed-host.js]
[browser_markup_flex_display_badge.js]
[browser_markup_grid_display_badge.js]
[browser_markup_links_01.js]
[browser_markup_links_02.js]
[browser_markup_links_03.js]

Просмотреть файл

@ -1,60 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the grid display badge toggles on the grid highlighter.
const TEST_URI = `
<style type="text/css">
#grid {
display: grid;
}
</style>
<div id="grid"></div>
`;
const HIGHLIGHTER_TYPE = "CssGridHighlighter";
add_task(async function() {
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
const { inspector } = await openLayoutView();
const { highlighters, store } = inspector;
info("Check the grid display badge is shown and not active.");
await selectNode("#grid", inspector);
const gridContainer = await getContainerForSelector("#grid", inspector);
const gridDisplayBadge = gridContainer.elt.querySelector(".markup-badge[data-display]");
ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active.");
info("Check the initial state of the grid highlighter.");
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No CSS grid highlighter exists in the highlighters overlay.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
info("Toggling ON the CSS grid highlighter from the grid display badge.");
const onHighlighterShown = highlighters.once("grid-highlighter-shown");
let onCheckboxChange = waitUntilState(store, state =>
state.grids.length === 1 &&
state.grids[0].highlighted);
gridDisplayBadge.click();
await onHighlighterShown;
await onCheckboxChange;
info("Check the CSS grid highlighter is created and grid display badge state.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"CSS grid highlighter is created in the highlighters overlay.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
ok(gridDisplayBadge.classList.contains("active"), "grid display badge is active.");
info("Toggling OFF the CSS grid highlighter from the grid display badge.");
const onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 1 &&
!state.grids[0].highlighted);
gridDisplayBadge.click();
await onHighlighterHidden;
await onCheckboxChange;
ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active.");
});

Просмотреть файл

@ -1,3 +1,4 @@
/* 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/. */
@ -10,11 +11,6 @@ Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
this);
// Load the shared Redux helpers into this compartment.
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/shared/test/shared-redux-head.js",
this);
var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor");
var clipboard = require("devtools/shared/platform/clipboard");

Просмотреть файл

@ -8,7 +8,6 @@
const promise = require("promise");
const Services = require("Services");
const flags = require("devtools/shared/flags");
const {l10n} = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const OutputParser = require("devtools/client/shared/output-parser");
@ -152,6 +151,9 @@ function CssRuleView(inspector, document, store, pageStyle) {
this.shortcuts.on("CmdOrCtrl+F", event => this._onShortcut("CmdOrCtrl+F", event));
this.element.addEventListener("copy", this._onCopy);
this.element.addEventListener("contextmenu", this._onContextMenu);
this.element.addEventListener("mousemove", () => {
this.addHighlightersToView();
}, { once: true });
this.addRuleButton.addEventListener("click", this._onAddRule);
this.searchField.addEventListener("input", this._onFilterStyles);
this.searchClearButton.addEventListener("click", this._onClearSearch);
@ -161,15 +163,6 @@ function CssRuleView(inspector, document, store, pageStyle) {
this.activeCheckbox.addEventListener("click", this._onTogglePseudoClass);
this.focusCheckbox.addEventListener("click", this._onTogglePseudoClass);
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
this.highlighters.addToView(this);
} else {
this.element.addEventListener("mousemove", () => {
this.highlighters.addToView(this);
}, { once: true });
}
this._handlePrefChange = this._handlePrefChange.bind(this);
this._handleUAStylePrefChange = this._handleUAStylePrefChange.bind(this);
this._handleDefaultColorUnitPrefChange =
@ -1644,6 +1637,14 @@ CssRuleView.prototype = {
event.stopPropagation();
}
},
/**
* Adds the highlighters overlay to the rule view. This is called by the "mousemove"
* event handler and in shared-head.js when opening and selecting the rule view.
*/
addHighlightersToView() {
this.highlighters.addToView(this);
},
};
/**

Просмотреть файл

@ -91,6 +91,9 @@ function openRuleView() {
// through an additional ".flush()" property.
view.debounce = manualDebounce();
// Adds the highlighters overlay in the rule view.
view.addHighlightersToView();
return {
toolbox: data.toolbox,
inspector: data.inspector,
@ -110,6 +113,8 @@ function openRuleView() {
function openComputedView() {
return openInspectorSidebarTab("computedview").then(data => {
const view = data.inspector.getPanel("computedview").computedView;
// Adds the highlighters overlay in the computed view.
view.addHighlightersToView();
return {
toolbox: data.toolbox,
@ -160,7 +165,9 @@ function openLayoutView() {
* @return {CssRuleView} the rule view
*/
function selectRuleView(inspector) {
return inspector.getPanel("ruleview").view;
const view = inspector.getPanel("ruleview").view;
view.addHighlightersToView();
return view;
}
/**
@ -172,7 +179,9 @@ function selectRuleView(inspector) {
*/
function selectComputedView(inspector) {
inspector.sidebar.select("computedview");
return inspector.getPanel("computedview").computedView;
const view = inspector.getPanel("computedview").computedView;
view.addHighlightersToView();
return view;
}
/**

Просмотреть файл

@ -453,6 +453,7 @@ exports.openFilePicker = function({ title, filters, defaultName, mode }) {
*/
exports.formatNumber = function(number, showSign = false) {
const rounded = Math.round(number);
// eslint-disable-next-line no-compare-neg-zero
if (rounded === 0 || rounded === -0) {
return "0";
}

Просмотреть файл

@ -6,6 +6,7 @@
.network-monitor .learn-more-link::before {
background-image: url(chrome://devtools/skin/images/help.svg);
background-size: contain;
}
.network-monitor .tree-container .treeTable tr .learn-more-link {

Просмотреть файл

@ -8,6 +8,7 @@ module.exports = {
"run_next_test": true,
"equal": true,
"do_print": true,
"waitUntilState": true
},
"rules": {
// Stop giving errors for run_test

Просмотреть файл

@ -1,6 +1,7 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="context-fill" d="M8 1a7 7 0 1 0 7 7 7.008 7.008 0 0 0-7-7zm0 13a6 6 0 1 1 6-6 6.007 6.007 0 0 1-6 6zM8 3.125A2.7 2.7 0 0 0 5.125 6a.875.875 0 0 0 1.75 0c0-1 .6-1.125 1.125-1.125a1.105 1.105 0 0 1 1.13.744.894.894 0 0 1-.53 1.016A2.738 2.738 0 0 0 7.125 9v.337a.875.875 0 0 0 1.75 0v-.37a1.041 1.041 0 0 1 .609-.824A2.637 2.637 0 0 0 10.82 5.16 2.838 2.838 0 0 0 8 3.125zm0 7.625A1.25 1.25 0 1 0 9.25 12 1.25 1.25 0 0 0 8 10.75z"></path>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="context-fill" d="M13.15 17a1.15 1.15 0 1 1-2.3 0 1.15 1.15 0 0 1 2.3 0zM10.5 9.5c0-.764.616-1.5 1.5-1.5s1.5.736 1.5 1.5c0 .311-.144.635-.408.974-.199.254-.386.43-.57.6-.077.072-.153.143-.23.219a1.676 1.676 0 0 1-.048.045c-.13.117-.466.42-.698.757C11.22 12.569 11 13.18 11 14a1 1 0 1 0 2 0c0-.431.106-.645.194-.772.051-.074.114-.144.197-.225.04-.039.08-.075.129-.12l.003-.002.009-.008c.05-.045.114-.104.175-.166l.086-.08a8.13 8.13 0 0 0 .876-.924c.4-.512.831-1.264.831-2.203C15.5 7.764 14.116 6 12 6S8.5 7.764 8.5 9.5a1 1 0 1 0 2 0z"></path>
<path fill="context-fill" fill-rule="evenodd" clip-rule="evenodd" d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16z"></path>
</svg>

До

Ширина:  |  Высота:  |  Размер: 754 B

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

Просмотреть файл

@ -111,3 +111,4 @@ MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR, 0, JSEXN_RANGEERR, "The
MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR, 0, JSEXN_RANGEERR, "The end time for an AudioParam method must be non-negative.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_VALUE_ERROR, 0, JSEXN_RANGEERR, "The value passed to exponentialRampToValueAtTime must be positive.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_CONSTANT_ERROR, 0, JSEXN_RANGEERR, "The exponential constant passed to setTargetAtTime must be non-negative.")
MSG_DEF(MSG_VALUE_OUT_OF_RANGE, 1, JSEXN_RANGEERR, "The value for the {0} is outside the valid range.")

Просмотреть файл

@ -17,7 +17,7 @@ var testGenerator = testSteps();
// is whether the property is read-only or not.
var c = Object.getOwnPropertyDescriptor(this, "Components");
if ((!c || !c.value || c.writable) && typeof SpecialPowers === "object") {
// eslint-disable-next-line no-native-reassign
// eslint-disable-next-line no-global-assign
Components = SpecialPowers.wrap(SpecialPowers.Components);
}

Просмотреть файл

@ -699,9 +699,16 @@ void
AudioBufferSourceNode::Start(double aWhen, double aOffset,
const Optional<double>& aDuration, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aWhen) || aOffset < 0 ||
(aDuration.WasPassed() && !WebAudioUtils::IsTimeValid(aDuration.Value()))) {
aRv.Throw(NS_ERROR_RANGE_ERR);
if (!WebAudioUtils::IsTimeValid(aWhen)) {
aRv.ThrowRangeError<MSG_VALUE_OUT_OF_RANGE>(NS_LITERAL_STRING("start time"));
return;
}
if (aOffset < 0) {
aRv.ThrowRangeError<MSG_VALUE_OUT_OF_RANGE>(NS_LITERAL_STRING("offset"));
return;
}
if (aDuration.WasPassed() && !WebAudioUtils::IsTimeValid(aDuration.Value())) {
aRv.ThrowRangeError<MSG_VALUE_OUT_OF_RANGE>(NS_LITERAL_STRING("duration"));
return;
}
@ -802,7 +809,7 @@ void
AudioBufferSourceNode::Stop(double aWhen, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aWhen)) {
aRv.Throw(NS_ERROR_RANGE_ERR);
aRv.ThrowRangeError<MSG_VALUE_OUT_OF_RANGE>(NS_LITERAL_STRING("stop time"));
return;
}

Просмотреть файл

@ -228,7 +228,7 @@ void
ConstantSourceNode::Start(double aWhen, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aWhen)) {
aRv.Throw(NS_ERROR_RANGE_ERR);
aRv.ThrowRangeError<MSG_VALUE_OUT_OF_RANGE>(NS_LITERAL_STRING("start time"));
return;
}
@ -252,7 +252,7 @@ void
ConstantSourceNode::Stop(double aWhen, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aWhen)) {
aRv.Throw(NS_ERROR_RANGE_ERR);
aRv.ThrowRangeError<MSG_VALUE_OUT_OF_RANGE>(NS_LITERAL_STRING("stop time"));
return;
}

Просмотреть файл

@ -36,7 +36,7 @@ function loadPrivilegedScriptTest() {
handlers[type].forEach(handler => handler.apply(null, args));
};
var handlers = {};
/* eslint-disable-next-line no-native-reassign */
/* eslint-disable-next-line no-global-assign */
addMessageListener = function(message, handler) {
if (handlers.hasOwnProperty(message)) {
handlers[message].push(handler);
@ -44,7 +44,7 @@ function loadPrivilegedScriptTest() {
handlers[message] = [handler];
}
};
/* eslint-disable-next-line no-native-reassign */
/* eslint-disable-next-line no-global-assign */
removeMessageListener = function(message, handler) {
if (!handler || !handlers.hasOwnProperty(message)) {
return;

Просмотреть файл

@ -662,8 +662,11 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
{
MOZ_ASSERT(aGlobalObject);
if (aIsMainThread && gRunToCompletionListeners > 0) {
mDocShellEntryMonitor.emplace(cx(), aReason);
if (aIsMainThread) {
if (gRunToCompletionListeners > 0) {
mDocShellEntryMonitor.emplace(cx(), aReason);
}
mScriptActivity.emplace(true);
}
}
@ -815,11 +818,12 @@ AutoSafeJSContext::AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMP
}
AutoSlowOperation::AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
: AutoJSAPI()
: mIsMainThread(NS_IsMainThread())
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
Init();
if (mIsMainThread) {
mScriptActivity.emplace(true);
}
}
void
@ -828,8 +832,10 @@ AutoSlowOperation::CheckForInterrupt()
// For now we support only main thread!
if (mIsMainThread) {
// JS_CheckForInterrupt expects us to be in a realm.
JSAutoRealm ar(cx(), xpc::UnprivilegedJunkScope());
JS_CheckForInterrupt(cx());
AutoJSAPI jsapi;
if (jsapi.Init(xpc::UnprivilegedJunkScope())) {
JS_CheckForInterrupt(jsapi.cx());
}
}
}

Просмотреть файл

@ -12,6 +12,7 @@
#include "MainThreadUtils.h"
#include "nsIGlobalObject.h"
#include "nsIPrincipal.h"
#include "xpcpublic.h"
#include "mozilla/Maybe.h"
@ -383,6 +384,7 @@ private:
friend nsIPrincipal* GetWebIDLCallerPrincipal();
Maybe<DocshellEntryMonitor> mDocShellEntryMonitor;
Maybe<xpc::AutoScriptActivity> mScriptActivity;
JS::AutoHideScriptedCaller mCallerOverride;
#ifdef MOZ_GECKO_PROFILER
AutoProfilerLabel mAutoProfilerLabel;
@ -455,17 +457,21 @@ private:
* Use AutoSlowOperation when native side calls many JS callbacks in a row
* and slow script dialog should be activated if too much time is spent going
* through those callbacks.
* AutoSlowOperation puts a JSAutoRequest on the stack so that we don't continue
* to reset the watchdog and CheckForInterrupt can be then used to check whether
* JS execution should be interrupted.
* AutoSlowOperation puts an AutoScriptActivity on the stack so that we don't
* continue to reset the watchdog. CheckForInterrupt can then be used to check
* whether JS execution should be interrupted.
* This class (including CheckForInterrupt) is a no-op when used off the main
* thread.
*/
class MOZ_RAII AutoSlowOperation : public dom::AutoJSAPI
class MOZ_RAII AutoSlowOperation
{
public:
explicit AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
void CheckForInterrupt();
private:
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
bool mIsMainThread;
Maybe<xpc::AutoScriptActivity> mScriptActivity;
};
/**

Просмотреть файл

@ -10,10 +10,10 @@
clearInterval(interval);
}
interval = setInterval(doSomething, 10);
interval = setInterval(doSomething, 1);
</script>
</head>
<body>
<h1>A page with setInterval() calls</h1>
<h1>A page with a setInterval() call</h1>
</body>
</html>

Просмотреть файл

@ -8,9 +8,10 @@
console.log("We are doing something here");
}
setTimeout(doSomething, 1);
</script>
</head>
<body onload="setTimeout(doSomething, 10)">
<h1>A page with setInterval() calls</h1>
<body>
<h1>A page with a setTimeout() call</h1>
</body>
</html>

Просмотреть файл

@ -11,6 +11,7 @@
#include "client/ClientLayerManager.h" // for ClientLayerManager, etc
#include "gfxContext.h" // for gfxContext
#include "gfx2DGlue.h"
#include "gfxEnv.h" // for gfxEnv
#include "gfxRect.h" // for gfxRect
#include "gfxPrefs.h" // for gfxPrefs
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
@ -155,13 +156,15 @@ ClientPaintedLayer::RenderLayerWithReadback(ReadbackProcessor *aReadback)
RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(target);
MOZ_ASSERT(ctx); // already checked the target above
ClientManager()->GetPaintedLayerCallback()(this,
ctx,
iter.mDrawRegion,
iter.mDrawRegion,
state.mClip,
state.mRegionToInvalidate,
ClientManager()->GetPaintedLayerCallbackData());
if (!gfxEnv::SkipRasterization()) {
ClientManager()->GetPaintedLayerCallback()(this,
ctx,
iter.mDrawRegion,
iter.mDrawRegion,
state.mClip,
state.mRegionToInvalidate,
ClientManager()->GetPaintedLayerCallbackData());
}
ctx = nullptr;
mContentClient->ReturnDrawTarget(target);

Просмотреть файл

@ -24,6 +24,7 @@
#include "Units.h" // for ScreenIntRect
#include "UnitTransforms.h" // for ViewAs
#include "apz/src/AsyncPanZoomController.h" // for AsyncPanZoomController
#include "gfxEnv.h" // for gfxEnv
#include "gfxPrefs.h" // for gfxPrefs
#ifdef XP_MACOSX
#include "gfxPlatformMac.h"
@ -477,6 +478,11 @@ LayerManagerComposite::EndTransaction(const TimeStamp& aTimeStamp,
void
LayerManagerComposite::UpdateAndRender()
{
if (gfxEnv::SkipComposition()) {
mInvalidRegion.SetEmpty();
return;
}
nsIntRegion invalid;
// The results of our drawing always go directly into a pixel buffer,
// so we don't need to pass any global transform here.

Просмотреть файл

@ -151,7 +151,6 @@ union SurfaceDescriptor {
SurfaceDescriptorMacIOSurface;
SurfaceDescriptorSharedGLTexture;
SurfaceDescriptorGPUVideo;
SurfaceDescriptorShared;
null_t;
};

Просмотреть файл

@ -10,6 +10,7 @@
#include "ImageLayerMLGPU.h"
#include "CanvasLayerMLGPU.h"
#include "GeckoProfiler.h" // for profiler_*
#include "gfxEnv.h" // for gfxEnv
#include "MLGDevice.h"
#include "RenderPassMLGPU.h"
#include "RenderViewMLGPU.h"
@ -276,6 +277,10 @@ LayerManagerMLGPU::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFla
void
LayerManagerMLGPU::Composite()
{
if (gfxEnv::SkipComposition()) {
return;
}
AUTO_PROFILER_LABEL("LayerManagerMLGPU::Composite", GRAPHICS);
// Don't composite if we're minimized/hidden, or if there is nothing to draw.

Просмотреть файл

@ -101,6 +101,12 @@ public:
// Offscreen GL context for main layer manager
DECL_GFX_ENV("MOZ_LAYERS_PREFER_OFFSCREEN", LayersPreferOffscreen);
// Skip final window composition
DECL_GFX_ENV("MOZ_SKIPCOMPOSITION", SkipComposition);
// Skip rasterizing painted layer contents
DECL_GFX_ENV("MOZ_SKIPRASTERIZATION", SkipRasterization);
// Stop the VR rendering
DECL_GFX_ENV("NO_VR_RENDERING", NoVRRendering);

Просмотреть файл

@ -95,26 +95,18 @@ const L10nRegistry = {
const sourcesOrder = Array.from(this.sources.keys()).reverse();
const pseudoNameFromPref = Services.prefs.getStringPref("intl.l10n.pseudo", "");
for (const locale of requestedLangs) {
for (const fetchPromises of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) {
const ctx = await Promise.all(fetchPromises).then(
dataSets => {
const ctx = new MessageContext(locale, {
...MSG_CONTEXT_OPTIONS,
transform: PSEUDO_STRATEGIES[pseudoNameFromPref],
});
for (const data of dataSets) {
if (data === null) {
return null;
}
ctx.addResource(data);
}
return ctx;
},
() => null
);
if (ctx !== null) {
yield ctx;
for await (const dataSets of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) {
const ctx = new MessageContext(locale, {
...MSG_CONTEXT_OPTIONS,
transform: PSEUDO_STRATEGIES[pseudoNameFromPref],
});
for (const data of dataSets) {
if (data === null) {
return;
}
ctx.addResource(data);
}
yield ctx;
}
}
},
@ -190,7 +182,7 @@ const L10nRegistry = {
* @param {Array} [resolvedOrder]
* @returns {AsyncIterator<MessageContext>}
*/
function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) {
async function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) {
const resolvedLength = resolvedOrder.length;
const resourcesLength = resourceIds.length;
@ -200,18 +192,36 @@ function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resol
for (const sourceName of sourcesOrder) {
const order = resolvedOrder.concat(sourceName);
// We bail only if the hasFile returns a strict false here,
// because for FileSource it may also return undefined, which means
// that we simply don't know if the source contains the file and we'll
// have to perform the I/O to learn.
if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[resolvedOrder.length]) === false) {
continue;
// We want to bail out early if we know that any of
// the (res)x(source) combinations in the permutation
// are unavailable.
// The combination may have been `undefined` when we
// stepped into this branch, and now is resolved to
// `false`.
//
// If the combination resolved to `false` is the last
// in the resolvedOrder, we want to continue in this
// loop, but if it's somewhere in the middle, we can
// safely bail from the whole branch.
for (let [idx, sourceName] of order.entries()) {
if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[idx]) === false) {
if (idx === order.length - 1) {
continue;
} else {
return;
}
}
}
// If the number of resolved sources equals the number of resources,
// create the right context and return it if it loads.
if (resolvedLength + 1 === resourcesLength) {
yield generateResourceSet(locale, order, resourceIds);
let dataSet = await generateResourceSet(locale, order, resourceIds);
// Here we check again to see if the newly resolved
// resources returned `false` on any position.
if (!dataSet.includes(false)) {
yield dataSet;
}
} else if (resolvedLength < resourcesLength) {
// otherwise recursively load another generator that walks over the
// partially resolved list of sources.
@ -346,10 +356,10 @@ const PSEUDO_STRATEGIES = {
* @param {Array} resourceIds
* @returns {Promise<MessageContext>}
*/
function generateResourceSet(locale, sourcesOrder, resourceIds) {
return resourceIds.map((resourceId, i) => {
async function generateResourceSet(locale, sourcesOrder, resourceIds) {
return Promise.all(resourceIds.map((resourceId, i) => {
return L10nRegistry.sources.get(sourcesOrder[i]).fetchFile(locale, resourceId);
});
}));
}
/**
@ -420,14 +430,14 @@ class FileSource {
fetchFile(locale, path) {
if (!this.locales.includes(locale)) {
return Promise.reject(`The source has no resources for locale "${locale}"`);
return false;
}
const fullPath = this.getPath(locale, path);
if (this.cache.hasOwnProperty(fullPath)) {
if (this.cache[fullPath] === false) {
return Promise.reject(`The source has no resources for path "${fullPath}"`);
return false;
}
// `true` means that the file is indexed, but hasn't
// been fetched yet.
@ -435,7 +445,7 @@ class FileSource {
return this.cache[fullPath];
}
} else if (this.indexed) {
return Promise.reject(`The source has no resources for path "${fullPath}"`);
return false;
}
return this.cache[fullPath] = L10nRegistry.load(fullPath).then(
data => {
@ -443,7 +453,7 @@ class FileSource {
},
err => {
this.cache[fullPath] = false;
return Promise.reject(err);
return false;
}
);
}

Просмотреть файл

@ -97,7 +97,7 @@ class CachedAsyncIterable extends CachedIterable {
return {
async next() {
if (cached.length <= cur) {
cached.push(await cached.iterator.next());
cached.push(cached.iterator.next());
}
return cached[cur++];
}
@ -114,10 +114,10 @@ class CachedAsyncIterable extends CachedIterable {
let idx = 0;
while (idx++ < count) {
const last = this[this.length - 1];
if (last && last.done) {
if (last && await (last).done) {
break;
}
this.push(await this.iterator.next());
this.push(this.iterator.next());
}
// Return the last cached {value, done} object to allow the calling
// code to decide if it needs to call touchNext again.
@ -322,7 +322,6 @@ class Localization {
onChange() {
this.ctxs = CachedAsyncIterable.from(
this.generateMessages(this.resourceIds));
this.ctxs.touchNext(2);
}
}

Просмотреть файл

@ -1,6 +1,7 @@
{
const { DOMLocalization } =
ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {});
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
/**
* Polyfill for document.ready polyfill.
@ -46,8 +47,9 @@
document.l10n = new DOMLocalization(resourceIds);
// Trigger the first two contexts to be loaded eagerly.
document.l10n.ctxs.touchNext(2);
const appLocales = Services.locale.getAppLocalesAsBCP47();
const prefetchCount = appLocales.length > 1 ? 2 : 1;
document.l10n.ctxs.touchNext(prefetchCount);
document.l10n.ready = documentReady().then(() => {
document.l10n.registerObservers();

Просмотреть файл

@ -971,6 +971,7 @@ function ArraySpeciesCreate(originalArray, length) {
assert(length >= 0, "length should be a non-negative number");
// Step 2.
// eslint-disable-next-line no-compare-neg-zero
if (length === -0)
length = 0;

Просмотреть файл

@ -24,7 +24,6 @@ const startId = 8;
const elemId = 9;
const codeId = 10;
const dataId = 11;
const gcFeatureOptInId = 42;
// User-defined section names
const nameName = "name";
@ -178,10 +177,6 @@ function moduleWithSections(sectionArray) {
return toU8(bytes);
}
function gcFeatureOptInSection(version) {
return { name: gcFeatureOptInId, body: [ version & 0x7F ] }
}
function sigSection(sigs) {
var body = [];
body.push(...varU32(sigs.length));

Просмотреть файл

@ -0,0 +1,3 @@
// |jit-test| error: TypeError
var x = newGlobal({sameCompartmentAs: this});
x instanceof x.Map.prototype.set;

Просмотреть файл

@ -47,9 +47,9 @@ assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(codeId))), CompileError,
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(dataId))), CompileError, sectionError("data"));
// unknown sections are unconditionally rejected
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37))), CompileError, unknownSection);
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37, 0))), CompileError, unknownSection);
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37, 1, 0))), CompileError, unknownSection);
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42))), CompileError, unknownSection);
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42, 0))), CompileError, unknownSection);
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42, 1, 0))), CompileError, unknownSection);
// user sections have special rules
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0))), CompileError, sectionError("custom")); // no length

Просмотреть файл

@ -12,7 +12,6 @@ function Baguette(calories) {
// Ensure the baseline compiler sync's before the postbarrier.
(function() {
wasmEvalText(`(module
(gc_feature_opt_in 1)
(global (mut anyref) (ref.null anyref))
(func (export "f")
get_global 0
@ -24,7 +23,6 @@ function Baguette(calories) {
})();
let exportsPlain = wasmEvalText(`(module
(gc_feature_opt_in 1)
(global i32 (i32.const 42))
(global $g (mut anyref) (ref.null anyref))
(func (export "set") (param anyref) get_local 0 set_global $g)
@ -32,7 +30,6 @@ let exportsPlain = wasmEvalText(`(module
)`).exports;
let exportsObj = wasmEvalText(`(module
(gc_feature_opt_in 1)
(global $g (export "g") (mut anyref) (ref.null anyref))
(func (export "set") (param anyref) get_local 0 set_global $g)
(func (export "get") (result anyref) get_global $g)

Просмотреть файл

@ -5,7 +5,6 @@ if (!wasmGcEnabled()) {
const { startProfiling, endProfiling, assertEqPreciseStacks, isSingleStepProfilingEnabled } = WasmHelpers;
let e = wasmEvalText(`(module
(gc_feature_opt_in 1)
(global $g (mut anyref) (ref.null anyref))
(func (export "set") (param anyref) get_local 0 set_global $g)
)`).exports;

Просмотреть файл

@ -4,7 +4,6 @@ if (!wasmGcEnabled()) {
gczeal(14, 1);
let { exports } = wasmEvalText(`(module
(gc_feature_opt_in 1)
(global $anyref (import "glob" "anyref") anyref)
(func (export "get") (result anyref) get_global $anyref)
)`, {

Просмотреть файл

@ -14,14 +14,12 @@ function Baguette(calories) {
const { validate, CompileError } = WebAssembly;
assertErrorMessage(() => wasmEvalText(`(module
(gc_feature_opt_in 1)
(func (result anyref)
i32.const 42
)
)`), CompileError, mismatchError('i32', 'anyref'));
assertErrorMessage(() => wasmEvalText(`(module
(gc_feature_opt_in 1)
(func (result anyref)
i32.const 0
ref.null anyref
@ -31,7 +29,6 @@ assertErrorMessage(() => wasmEvalText(`(module
)`), CompileError, /select operand types/);
assertErrorMessage(() => wasmEvalText(`(module
(gc_feature_opt_in 1)
(func (result i32)
ref.null anyref
if
@ -44,16 +41,16 @@ assertErrorMessage(() => wasmEvalText(`(module
// Basic compilation tests.
let simpleTests = [
"(module (gc_feature_opt_in 1) (func (drop (ref.null anyref))))",
"(module (gc_feature_opt_in 1) (func $test (local anyref)))",
"(module (gc_feature_opt_in 1) (func $test (param anyref)))",
"(module (gc_feature_opt_in 1) (func $test (result anyref) (ref.null anyref)))",
"(module (gc_feature_opt_in 1) (func $test (block anyref (unreachable)) unreachable))",
"(module (gc_feature_opt_in 1) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))",
`(module (gc_feature_opt_in 1) (import "a" "b" (param anyref)))`,
`(module (gc_feature_opt_in 1) (import "a" "b" (result anyref)))`,
`(module (gc_feature_opt_in 1) (global anyref (ref.null anyref)))`,
`(module (gc_feature_opt_in 1) (global (mut anyref) (ref.null anyref)))`,
"(module (func (drop (ref.null anyref))))",
"(module (func $test (local anyref)))",
"(module (func $test (param anyref)))",
"(module (func $test (result anyref) (ref.null anyref)))",
"(module (func $test (block anyref (unreachable)) unreachable))",
"(module (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))",
`(module (import "a" "b" (param anyref)))`,
`(module (import "a" "b" (result anyref)))`,
`(module (global anyref (ref.null anyref)))`,
`(module (global (mut anyref) (ref.null anyref)))`,
];
for (let src of simpleTests) {
@ -64,7 +61,6 @@ for (let src of simpleTests) {
// Basic behavioral tests.
let { exports } = wasmEvalText(`(module
(gc_feature_opt_in 1)
(func (export "is_null") (result i32)
ref.null anyref
ref.is_null
@ -102,7 +98,6 @@ assertEq(exports.is_null_local(), 1);
// Anyref param and result in wasm functions.
exports = wasmEvalText(`(module
(gc_feature_opt_in 1)
(func (export "is_null") (result i32) (param $ref anyref)
get_local $ref
ref.is_null
@ -160,7 +155,6 @@ assertEq(ref.calories, baguette.calories);
// Make sure grow-memory isn't blocked by the lack of gc.
(function() {
assertEq(wasmEvalText(`(module
(gc_feature_opt_in 1)
(memory 0 64)
(func (export "f") (param anyref) (result i32)
i32.const 10
@ -176,7 +170,6 @@ assertEq(ref.calories, baguette.calories);
function assertJoin(body) {
let val = { i: -1 };
assertEq(wasmEvalText(`(module
(gc_feature_opt_in 1)
(func (export "test") (param $ref anyref) (param $i i32) (result anyref)
${body}
)
@ -243,7 +236,6 @@ assertJoin(`(block $out anyref (block $unreachable anyref (loop $top
let x = { i: 42 }, y = { f: 53 };
exports = wasmEvalText(`(module
(gc_feature_opt_in 1)
(func (export "test") (param $lhs anyref) (param $rhs anyref) (param $i i32) (result anyref)
get_local $lhs
get_local $rhs
@ -298,7 +290,6 @@ let imports = {
};
exports = wasmEvalText(`(module
(gc_feature_opt_in 1)
(import $ret "funcs" "ret" (result anyref))
(import $param "funcs" "param" (param anyref))
@ -327,7 +318,6 @@ assertEq(exports.ret(), imports.myBaguette);
// Check lazy stubs generation.
exports = wasmEvalText(`(module
(gc_feature_opt_in 1)
(import $mirror "funcs" "mirror" (param anyref) (result anyref))
(import $augment "funcs" "augment" (param anyref) (result anyref))
@ -411,15 +401,15 @@ assertEq(exports.count_g(), 1);
// Anyref globals in wasm modules.
assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "anyref") anyref))`, { glob: { anyref: 42 } }),
assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "anyref") anyref))`, { glob: { anyref: 42 } }),
WebAssembly.LinkError,
/import object field 'anyref' is not a Object-or-null/);
assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }),
assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }),
WebAssembly.LinkError,
/imported global type mismatch/);
assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "i32") i32))`, { glob: { i32: {} } }),
assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "i32") i32))`, { glob: { i32: {} } }),
WebAssembly.LinkError,
/import object field 'i32' is not a Number/);
@ -433,7 +423,6 @@ imports = {
};
exports = wasmEvalText(`(module
(gc_feature_opt_in 1)
(global $g_imp_imm_null (import "constants" "imm_null") anyref)
(global $g_imp_imm_bread (import "constants" "imm_bread") anyref)

Просмотреть файл

@ -8,10 +8,7 @@ const v2vSig = {args:[], ret:VoidCode};
const v2vSigSection = sigSection([v2vSig]);
function checkInvalid(body, errorMessage) {
assertErrorMessage(() => new WebAssembly.Module(
moduleWithSections([gcFeatureOptInSection(1), v2vSigSection, declSection([0]), bodySection([body])])),
WebAssembly.CompileError,
errorMessage);
assertErrorMessage(() => new WebAssembly.Module(moduleWithSections([v2vSigSection, declSection([0]), bodySection([body])])), WebAssembly.CompileError, errorMessage);
}
const invalidRefNullBody = funcBody({locals:[], body:[

Просмотреть файл

@ -5,7 +5,7 @@ if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) {
(function() {
let g = newGlobal();
let dbg = new Debugger(g);
g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (gc_feature_opt_in 1) (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`);
g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`);
})();
(function() {
@ -14,7 +14,6 @@ if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) {
let src = `
(module
(gc_feature_opt_in 1)
(func (export "func") (result anyref) (param $ref anyref)
get_local $ref
)

Просмотреть файл

@ -4,21 +4,21 @@ if (wasmGcEnabled()) {
const { CompileError, validate } = WebAssembly;
const UNRECOGNIZED_OPCODE_OR_BAD_TYPE = /unrecognized opcode|reference types not enabled|invalid inline block type/;
const UNRECOGNIZED_OPCODE_OR_BAD_TYPE = /(unrecognized opcode|bad type|invalid inline block type)/;
function assertValidateError(text) {
assertEq(validate(wasmTextToBinary(text)), false);
}
let simpleTests = [
"(module (gc_feature_opt_in 1) (func (drop (ref.null anyref))))",
"(module (gc_feature_opt_in 1) (func $test (local anyref)))",
"(module (gc_feature_opt_in 1) (func $test (param anyref)))",
"(module (gc_feature_opt_in 1) (func $test (result anyref) (ref.null anyref)))",
"(module (gc_feature_opt_in 1) (func $test (block anyref (unreachable)) unreachable))",
"(module (gc_feature_opt_in 1) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))",
`(module (gc_feature_opt_in 1) (import "a" "b" (param anyref)))`,
`(module (gc_feature_opt_in 1) (import "a" "b" (result anyref)))`,
"(module (func (drop (ref.null anyref))))",
"(module (func $test (local anyref)))",
"(module (func $test (param anyref)))",
"(module (func $test (result anyref) (ref.null anyref)))",
"(module (func $test (block anyref (unreachable)) unreachable))",
"(module (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))",
`(module (import "a" "b" (param anyref)))`,
`(module (import "a" "b" (result anyref)))`,
];
for (let src of simpleTests) {

Просмотреть файл

@ -1,120 +0,0 @@
if (!wasmGcEnabled()) {
quit(0);
}
// Encoding. If the section is present it must be first.
var bad_order =
new Uint8Array([0x00, 0x61, 0x73, 0x6d,
0x01, 0x00, 0x00, 0x00,
0x01, // Type section
0x01, // Section size
0x00, // Zero types
0x2a, // GcFeatureOptIn section
0x01, // Section size
0x01]); // Version
assertErrorMessage(() => new WebAssembly.Module(bad_order),
WebAssembly.CompileError,
/expected custom section/);
// Version numbers. Version 1 is good, version 2 is bad.
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 1))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 2))`)),
WebAssembly.CompileError,
/unsupported version of the gc feature/);
// Struct types are only available if we opt in.
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(type (struct (field i32))))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(type (struct (field i32))))`)),
WebAssembly.CompileError,
/Structure types not enabled/);
// Parameters of ref type are only available if we opt in.
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(type (func (param anyref))))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(type (func (param anyref))))`)),
WebAssembly.CompileError,
/reference types not enabled/);
// Ditto returns
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(type (func (result anyref))))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(type (func (result anyref))))`)),
WebAssembly.CompileError,
/reference types not enabled/);
// Ditto locals
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(func (result i32)
(local anyref)
(i32.const 0)))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (result i32)
(local anyref)
(i32.const 0)))`)),
WebAssembly.CompileError,
/reference types not enabled/);
// Ditto globals
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(global (mut anyref) (ref.null anyref)))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(global (mut anyref) (ref.null anyref)))`)),
WebAssembly.CompileError,
/reference types not enabled/);
// Ref instructions are only available if we opt in.
//
// When testing these we need to avoid struct types or parameters, locals,
// returns, or globals of ref type, or guards on those will preempt the guards
// on the instructions.
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (ref.null anyref)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func ref.is_null))`)),
WebAssembly.CompileError,
/unrecognized opcode/);

Просмотреть файл

@ -7,7 +7,6 @@ if (!wasmGcEnabled())
{
let bin = wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(type $point (struct
(field $x f64)
@ -43,7 +42,6 @@ if (!wasmGcEnabled())
{
let bin = wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(import "m" "g" (global (mut (ref $box)))))`);
@ -58,7 +56,6 @@ if (!wasmGcEnabled())
{
let bin = wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(global $boxg (export "box") (mut (ref $box)) (ref.null (ref $box))))`);

Просмотреть файл

@ -52,7 +52,6 @@ function wasmCompile(text) {
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $x i32)))
(func (export "f") (param (ref $box)) (unreachable)))`),
WebAssembly.CompileError,
@ -60,7 +59,6 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(func (export "f") (param anyref) (unreachable)))`),
"object");
@ -68,7 +66,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $x i32)))
(func (export "f") (result (ref $box)) (ref.null (ref $box))))`),
WebAssembly.CompileError,
@ -76,7 +73,6 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(func (export "f") (result anyref) (ref.null anyref)))`),
"object");
@ -84,7 +80,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $x i32)))
(import "m" "f" (param (ref $box))))`),
WebAssembly.CompileError,
@ -92,7 +87,6 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(import "m" "f" (param anyref)))`),
"object");
@ -100,7 +94,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $x i32)))
(import "m" "f" (param i32) (result (ref $box))))`),
WebAssembly.CompileError,
@ -108,7 +101,6 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(import "m" "f" (param i32) (result anyref)))`),
"object");
@ -116,7 +108,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(import "m" "g" (global (mut (ref $box)))))`),
WebAssembly.CompileError,
@ -124,7 +115,6 @@ assertErrorMessage(() => wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(import "m" "g" (global (ref $box))))`),
WebAssembly.CompileError,
@ -132,13 +122,11 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(import "m" "g" (global (mut anyref))))`),
"object");
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(import "m" "g" (global anyref)))`),
"object");
@ -146,7 +134,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(global $boxg (export "box") (mut (ref $box)) (ref.null (ref $box))))`),
WebAssembly.CompileError,
@ -154,7 +141,6 @@ assertErrorMessage(() => wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(global $boxg (export "box") (ref $box) (ref.null (ref $box))))`),
WebAssembly.CompileError,
@ -162,13 +148,11 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(global $boxg (export "box") (mut anyref) (ref.null anyref)))`),
"object");
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(global $boxg (export "box") anyref (ref.null anyref)))`),
"object");
@ -176,7 +160,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(table (export "tbl") 1 anyfunc)
(elem (i32.const 0) $f1)
@ -186,7 +169,6 @@ assertErrorMessage(() => wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(table (export "tbl") 1 anyfunc)
(elem (i32.const 0) $f1)
@ -196,7 +178,6 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(table (export "tbl") 1 anyfunc)
(elem (i32.const 0) $f1)
(func $f1 (param anyref) (unreachable)))`),
@ -204,7 +185,6 @@ assertEq(typeof wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(table (export "tbl") 1 anyfunc)
(elem (i32.const 0) $f1)
(func $f1 (result anyref) (ref.null anyref)))`),
@ -214,7 +194,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(import "m" "tbl" (table 1 anyfunc))
(elem (i32.const 0) $f1)
@ -224,7 +203,6 @@ assertErrorMessage(() => wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(import "m" "tbl" (table 1 anyfunc))
(elem (i32.const 0) $f1)
@ -234,7 +212,6 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(import "m" "tbl" (table 1 anyfunc))
(elem (i32.const 0) $f1)
(func $f1 (param anyref) (unreachable)))`),
@ -242,7 +219,6 @@ assertEq(typeof wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(import "m" "tbl" (table 1 anyfunc))
(elem (i32.const 0) $f1)
(func $f1 (result anyref) (ref.null anyref)))`),
@ -252,7 +228,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(type $fn (func (param (ref $box))))
(table (export "tbl") 1 anyfunc)
@ -263,7 +238,6 @@ assertErrorMessage(() => wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(type $fn (func (result (ref $box))))
(table (export "tbl") 1 anyfunc)
@ -274,7 +248,6 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $fn (func (param anyref)))
(table (export "tbl") 1 anyfunc)
(func (param i32)
@ -283,7 +256,6 @@ assertEq(typeof wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $fn (func (result anyref)))
(table (export "tbl") 1 anyfunc)
(func (param i32) (result anyref)
@ -294,7 +266,6 @@ assertEq(typeof wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(type $fn (func (param (ref $box))))
(import "m" "tbl" (table 1 anyfunc))
@ -305,7 +276,6 @@ assertErrorMessage(() => wasmCompile(
assertErrorMessage(() => wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(type $fn (func (result (ref $box))))
(import "m" "tbl" (table 1 anyfunc))
@ -316,7 +286,6 @@ assertErrorMessage(() => wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $fn (func (param anyref)))
(import "m" "tbl" (table 1 anyfunc))
(func (param i32)
@ -325,7 +294,6 @@ assertEq(typeof wasmCompile(
assertEq(typeof wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $fn (func (result anyref)))
(import "m" "tbl" (table 1 anyfunc))
(func (param i32) (result anyref)
@ -337,7 +305,6 @@ assertEq(typeof wasmCompile(
{
let m = wasmCompile(
`(module
(gc_feature_opt_in 1)
(type $box (struct (field $val i32)))
(type $fn (func (param (ref $box)) (result i32)))
(table 1 anyfunc)

Просмотреть файл

@ -1,6 +1,6 @@
if (!wasmGcEnabled()) {
assertErrorMessage(() => wasmEvalText(`(module (func (param (ref 0)) (unreachable)))`),
WebAssembly.CompileError, /reference types not enabled/);
WebAssembly.CompileError, /bad type/);
quit(0);
}
@ -8,7 +8,6 @@ if (!wasmGcEnabled()) {
var bin = wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(type $cons (struct
(field $car i32)
(field $cdr (ref $cons))))
@ -68,7 +67,6 @@ assertEq(WebAssembly.validate(bin), true);
new WebAssembly.Module(wasmTextToBinary(`
(module
(gc_feature_opt_in 1)
(type $s (struct))
(func $null (param (ref $s)) (result i32)
(ref.is_null (get_local 0))))
@ -78,7 +76,6 @@ new WebAssembly.Module(wasmTextToBinary(`
new WebAssembly.Module(wasmTextToBinary(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(func $f (param (ref $s)) (call $g (get_local 0)))
(func $g (param anyref) (unreachable)))
@ -88,8 +85,7 @@ new WebAssembly.Module(wasmTextToBinary(`
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(func (param (ref $odd)) (unreachable)))
(func (param (ref $odd)) (unreachable)))
`),
SyntaxError, /Type label.*not found/);
@ -98,7 +94,6 @@ SyntaxError, /Type label.*not found/);
wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field i32)))
(func $f (param (ref $s)) (unreachable))
@ -107,7 +102,6 @@ wasmEvalText(`
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field f32))) ;; Incompatible type
(func $f (param (ref $s)) (unreachable))
@ -117,7 +111,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field (mut i32)))) ;; Incompatible mutability
(func $f (param (ref $s)) (unreachable))
@ -130,7 +123,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/);
wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field i32)))
(func $f (param (ref $s)) (local (ref $t)) (set_local 1 (get_local 0))))
@ -138,7 +130,6 @@ wasmEvalText(`
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field f32)))
(func $f (param (ref $s)) (local (ref $t)) (set_local 1 (get_local 0))))
@ -147,7 +138,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field (mut i32))))
(func $f (param (ref $s)) (unreachable))
@ -160,7 +150,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/);
wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field i32)))
(func $f (param (ref $s)) (result (ref $t)) (get_local 0)))
@ -168,7 +157,6 @@ wasmEvalText(`
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field f32)))
(func $f (param (ref $s)) (result (ref $t)) (get_local 0)))
@ -177,7 +165,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(type $t (struct (field (mut i32))))
(func $f (param (ref $s)) (result (ref $t)) (get_local 0)))
@ -188,7 +175,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $x (func (param i32)))
(func $f (param (ref $x)) (unreachable)))
`),
@ -196,7 +182,6 @@ SyntaxError, /Type label.*not found/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type (func (param i32)))
(func $f (param (ref 0)) (unreachable)))
`),
@ -206,7 +191,6 @@ WebAssembly.CompileError, /does not reference a struct type/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32)))
(func $f (param anyref) (call $g (get_local 0)))
(func $g (param (ref $s)) (unreachable)))

Просмотреть файл

@ -1,14 +1,11 @@
if (!wasmGcEnabled()) {
assertErrorMessage(() => wasmEvalText(`(module
(gc_feature_opt_in 1)
(type $s (struct)))`),
assertErrorMessage(() => wasmEvalText(`(module (type $s (struct)))`),
WebAssembly.CompileError, /Structure types not enabled/);
quit();
}
var bin = wasmTextToBinary(
`(module
(gc_feature_opt_in 1)
(table 2 anyfunc)
(elem (i32.const 0) $doit $doitagain)
@ -76,7 +73,6 @@ assertEq(ins.x2(8), Math.PI)
wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field i32))))
`)
@ -84,7 +80,6 @@ wasmEvalText(`
wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct)))
`)
@ -92,7 +87,6 @@ wasmEvalText(`
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field $x i32)))
(type $s (struct (field $y i32))))
`),
@ -102,35 +96,30 @@ SyntaxError, /duplicate type name/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s))
`),
SyntaxError, /parsing wasm text/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (field $x i32)))
`),
SyntaxError, /bad type definition/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (field $x i31))))
`),
SyntaxError, /parsing wasm text/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct (fjeld $x i32))))
`),
SyntaxError, /parsing wasm text/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct abracadabra)))
`),
SyntaxError, /parsing wasm text/);
@ -139,7 +128,6 @@ SyntaxError, /parsing wasm text/);
assertErrorMessage(() => wasmEvalText(`
(module
(gc_feature_opt_in 1)
(type $s (struct))
(type $f (func (param i32) (result i32)))
(func (type 0) (param i32) (result i32) (unreachable)))
@ -151,10 +139,6 @@ WebAssembly.CompileError, /signature index references non-signature/);
var bad = new Uint8Array([0x00, 0x61, 0x73, 0x6d,
0x01, 0x00, 0x00, 0x00,
0x2a, // GcFeatureOptIn section
0x01, // Section size
0x01, // Version
0x01, // Type section
0x03, // Section size
0x01, // One type

Просмотреть файл

@ -123,6 +123,33 @@ static Atomic<JS::ReduceMicrosecondTimePrecisionCallback, Relaxed> sReduceMicros
* hashCode
*/
namespace
{
class DateTimeHelper
{
private:
#if ENABLE_INTL_API && !MOZ_SYSTEM_ICU
static double localTZA(double t, DateTimeInfo::TimeZoneOffset offset);
#else
static int equivalentYearForDST(int year);
static bool isRepresentableAsTime32(double t);
static double daylightSavingTA(double t);
static double adjustTime(double date);
static PRMJTime toPRMJTime(double localTime, double utcTime);
#endif
public:
static double localTime(double t);
static double UTC(double t);
static JSString* timeZoneComment(JSContext* cx, double utcTime, double localTime);
#if !ENABLE_INTL_API || MOZ_SYSTEM_ICU
static size_t formatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime);
#endif
};
}
// ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557
// 5.2.5 Mathematical Operations
static inline double
@ -440,8 +467,8 @@ JS::SetTimeResolutionUsec(uint32_t resolution, bool jitter)
#if ENABLE_INTL_API && !MOZ_SYSTEM_ICU
// ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557
// 20.3.1.7 LocalTZA ( t, isUTC )
static double
LocalTZA(double t, DateTimeInfo::TimeZoneOffset offset)
double
DateTimeHelper::localTZA(double t, DateTimeInfo::TimeZoneOffset offset)
{
MOZ_ASSERT(IsFinite(t));
@ -452,20 +479,20 @@ LocalTZA(double t, DateTimeInfo::TimeZoneOffset offset)
// ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557
// 20.3.1.8 LocalTime ( t )
static double
LocalTime(double t)
double
DateTimeHelper::localTime(double t)
{
if (!IsFinite(t))
return GenericNaN();
MOZ_ASSERT(StartOfTime <= t && t <= EndOfTime);
return t + LocalTZA(t, DateTimeInfo::TimeZoneOffset::UTC);
return t + localTZA(t, DateTimeInfo::TimeZoneOffset::UTC);
}
// ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557
// 20.3.1.9 UTC ( t )
static double
UTC(double t)
double
DateTimeHelper::UTC(double t)
{
if (!IsFinite(t))
return GenericNaN();
@ -473,7 +500,7 @@ UTC(double t)
if (t < (StartOfTime - msPerDay) || t > (EndOfTime + msPerDay))
return GenericNaN();
return t - LocalTZA(t, DateTimeInfo::TimeZoneOffset::Local);
return t - localTZA(t, DateTimeInfo::TimeZoneOffset::Local);
}
#else
/*
@ -483,8 +510,8 @@ UTC(double t)
* for determining DST; it hasn't been proven not to produce an
* incorrect year for times near year boundaries.
*/
static int
EquivalentYearForDST(int year)
int
DateTimeHelper::equivalentYearForDST(int year)
{
/*
* Years and leap years on which Jan 1 is a Sunday, Monday, etc.
@ -517,15 +544,15 @@ EquivalentYearForDST(int year)
// Return true if |t| is representable as a 32-bit time_t variable, that means
// the year is in [1970, 2038).
static bool
IsRepresentableAsTime32(double t)
bool
DateTimeHelper::isRepresentableAsTime32(double t)
{
return 0.0 <= t && t < 2145916800000.0;
}
/* ES5 15.9.1.8. */
static double
DaylightSavingTA(double t)
double
DateTimeHelper::daylightSavingTA(double t)
{
if (!IsFinite(t))
return GenericNaN();
@ -534,8 +561,8 @@ DaylightSavingTA(double t)
* If earlier than 1970 or after 2038, potentially beyond the ken of
* many OSes, map it to an equivalent year before asking.
*/
if (!IsRepresentableAsTime32(t)) {
int year = EquivalentYearForDST(int(YearFromTime(t)));
if (!isRepresentableAsTime32(t)) {
int year = equivalentYearForDST(int(YearFromTime(t)));
double day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
t = MakeDate(day, TimeWithinDay(t));
}
@ -545,24 +572,24 @@ DaylightSavingTA(double t)
return static_cast<double>(offsetMilliseconds);
}
static double
AdjustTime(double date)
double
DateTimeHelper::adjustTime(double date)
{
double localTZA = DateTimeInfo::localTZA();
double t = DaylightSavingTA(date) + localTZA;
double t = daylightSavingTA(date) + localTZA;
t = (localTZA >= 0) ? fmod(t, msPerDay) : -fmod(msPerDay - t, msPerDay);
return t;
}
/* ES5 15.9.1.9. */
static double
LocalTime(double t)
double
DateTimeHelper::localTime(double t)
{
return t + AdjustTime(t);
return t + adjustTime(t);
}
static double
UTC(double t)
double
DateTimeHelper::UTC(double t)
{
// Following the ES2017 specification creates undesirable results at DST
// transitions. For example when transitioning from PST to PDT,
@ -571,10 +598,22 @@ UTC(double t)
// V8 and subtract one hour before computing the offset.
// Spec bug: https://bugs.ecmascript.org/show_bug.cgi?id=4007
return t - AdjustTime(t - DateTimeInfo::localTZA() - msPerHour);
return t - adjustTime(t - DateTimeInfo::localTZA() - msPerHour);
}
#endif /* ENABLE_INTL_API && !MOZ_SYSTEM_ICU */
static double
LocalTime(double t)
{
return DateTimeHelper::localTime(t);
}
static double
UTC(double t)
{
return DateTimeHelper::UTC(t);
}
/* ES5 15.9.1.10. */
static double
HourFromTime(double t)
@ -2712,8 +2751,8 @@ date_toJSON(JSContext* cx, unsigned argc, Value* vp)
}
#if ENABLE_INTL_API && !MOZ_SYSTEM_ICU
static JSString*
TimeZoneComment(JSContext* cx, double utcTime, double localTime)
JSString*
DateTimeHelper::timeZoneComment(JSContext* cx, double utcTime, double localTime)
{
const char* locale = cx->runtime()->getDefaultLocale();
if (!locale) {
@ -2747,8 +2786,8 @@ TimeZoneComment(JSContext* cx, double utcTime, double localTime)
}
#else
/* Interface to PRMJTime date struct. */
static PRMJTime
ToPRMJTime(double localTime, double utcTime)
PRMJTime
DateTimeHelper::toPRMJTime(double localTime, double utcTime)
{
double year = YearFromTime(localTime);
@ -2762,33 +2801,33 @@ ToPRMJTime(double localTime, double utcTime)
prtm.tm_wday = int8_t(WeekDay(localTime));
prtm.tm_year = year;
prtm.tm_yday = int16_t(DayWithinYear(localTime, year));
prtm.tm_isdst = (DaylightSavingTA(utcTime) != 0);
prtm.tm_isdst = (daylightSavingTA(utcTime) != 0);
return prtm;
}
static size_t
FormatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime)
size_t
DateTimeHelper::formatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime)
{
PRMJTime prtm = ToPRMJTime(localTime, utcTime);
PRMJTime prtm = toPRMJTime(localTime, utcTime);
// If an equivalent year was used to compute the date/time components, use
// the same equivalent year to determine the time zone name and offset in
// PRMJ_FormatTime(...).
int timeZoneYear = IsRepresentableAsTime32(utcTime)
int timeZoneYear = isRepresentableAsTime32(utcTime)
? prtm.tm_year
: EquivalentYearForDST(prtm.tm_year);
: equivalentYearForDST(prtm.tm_year);
int offsetInSeconds = (int) floor((localTime - utcTime) / msPerSecond);
return PRMJ_FormatTime(buf, buflen, fmt, &prtm, timeZoneYear, offsetInSeconds);
}
static JSString*
TimeZoneComment(JSContext* cx, double utcTime, double localTime)
JSString*
DateTimeHelper::timeZoneComment(JSContext* cx, double utcTime, double localTime)
{
char tzbuf[100];
size_t tzlen = FormatTime(tzbuf, sizeof tzbuf, " (%Z)", utcTime, localTime);
size_t tzlen = formatTime(tzbuf, sizeof tzbuf, " (%Z)", utcTime, localTime);
if (tzlen != 0) {
// Decide whether to use the resulting time zone string.
//
@ -2816,6 +2855,12 @@ TimeZoneComment(JSContext* cx, double utcTime, double localTime)
}
#endif /* ENABLE_INTL_API && !MOZ_SYSTEM_ICU */
static JSString*
TimeZoneComment(JSContext* cx, double utcTime, double localTime)
{
return DateTimeHelper::timeZoneComment(cx, utcTime, localTime);
}
enum class FormatSpec {
DateTime,
Date,
@ -2924,7 +2969,7 @@ ToLocaleFormatHelper(JSContext* cx, HandleObject obj, const char* format, Mutabl
double localTime = LocalTime(utcTime);
/* Let PRMJTime format it. */
size_t result_len = FormatTime(buf, sizeof buf, format, utcTime, localTime);
size_t result_len = DateTimeHelper::formatTime(buf, sizeof buf, format, utcTime, localTime);
/* If it failed, default to toString. */
if (result_len == 0)

Просмотреть файл

@ -2258,7 +2258,7 @@ DecompileExpressionFromStack(JSContext* cx, int spindex, int skipStackHits, Hand
FrameIter frameIter(cx);
if (frameIter.done() || !frameIter.hasScript() || frameIter.compartment() != cx->compartment())
if (frameIter.done() || !frameIter.hasScript() || frameIter.realm() != cx->realm())
return true;
/*
@ -2348,7 +2348,7 @@ DecompileArgumentFromStack(JSContext* cx, int formalIndex, UniqueChars* res)
if (frameIter.done() ||
!frameIter.hasScript() ||
frameIter.script()->selfHosted() ||
frameIter.compartment() != cx->compartment())
frameIter.realm() != cx->realm())
{
return true;
}

Просмотреть файл

@ -1233,9 +1233,6 @@ class AstModule : public AstNode
NameVector funcImportNames_;
AstResizableVector tables_;
AstResizableVector memories_;
#ifdef ENABLE_WASM_GC
uint32_t gcFeatureOptIn_;
#endif
ExportVector exports_;
Maybe<AstStartFunc> startFunc_;
FuncVector funcs_;
@ -1254,9 +1251,6 @@ class AstModule : public AstNode
funcImportNames_(lifo),
tables_(lifo),
memories_(lifo),
#ifdef ENABLE_WASM_GC
gcFeatureOptIn_(0),
#endif
exports_(lifo),
funcs_(lifo),
dataSegments_(lifo),
@ -1273,15 +1267,6 @@ class AstModule : public AstNode
const AstResizableVector& memories() const {
return memories_;
}
#ifdef ENABLE_WASM_GC
bool addGcFeatureOptIn(uint32_t version) {
gcFeatureOptIn_ = version;
return true;
}
uint32_t gcFeatureOptIn() const {
return gcFeatureOptIn_;
}
#endif
bool addTable(AstName name, const Limits& table) {
return tables_.append(AstResizable(table, false, name));
}

Просмотреть файл

@ -9967,12 +9967,12 @@ BaseCompiler::emitBody()
#ifdef ENABLE_WASM_GC
case uint16_t(Op::RefNull):
if (env_.gcTypesEnabled() == HasGcTypes::False)
if (env_.gcTypesEnabled == HasGcTypes::False)
return iter_.unrecognizedOpcode(&op);
CHECK_NEXT(emitRefNull());
break;
case uint16_t(Op::RefIsNull):
if (env_.gcTypesEnabled() == HasGcTypes::False)
if (env_.gcTypesEnabled == HasGcTypes::False)
return iter_.unrecognizedOpcode(&op);
CHECK_NEXT(emitConversion(emitRefIsNull, ValType::AnyRef, ValType::I32));
break;
@ -10375,7 +10375,7 @@ js::wasm::BaselineCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo
ValTypeVector locals;
if (!locals.appendAll(env.funcTypes[func.index]->args()))
return false;
if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled(), &locals))
if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled, &locals))
return false;
// One-pass baseline compilation.

Просмотреть файл

@ -38,10 +38,7 @@ enum class SectionId
Start = 8,
Elem = 9,
Code = 10,
Data = 11,
#ifdef ENABLE_WASM_GC
GcFeatureOptIn = 42 // Arbitrary, but fits in 7 bits
#endif
Data = 11
};
enum class TypeCode

Просмотреть файл

@ -695,7 +695,7 @@ struct ProjectLazyFuncIndex
static constexpr unsigned LAZY_STUB_LIFO_DEFAULT_CHUNK_SIZE = 8 * 1024;
bool
LazyStubTier::createMany(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices,
LazyStubTier::createMany(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices,
const CodeTier& codeTier, size_t* stubSegmentIndex)
{
MOZ_ASSERT(funcExportIndices.length());
@ -719,7 +719,7 @@ LazyStubTier::createMany(HasGcTypes gcTypesConfigured, const Uint32Vector& funcE
Maybe<ImmPtr> callee;
callee.emplace(calleePtr, ImmPtr::NoCheckToken());
if (!GenerateEntryStubs(masm, funcExportIndex, fe, callee, /* asmjs */ false,
gcTypesConfigured, &codeRanges))
gcTypesEnabled, &codeRanges))
{
return false;
}
@ -801,7 +801,7 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier)
return false;
size_t stubSegmentIndex;
if (!createMany(codeTier.code().metadata().temporaryGcTypesConfigured, funcExportIndexes, codeTier,
if (!createMany(codeTier.code().metadata().temporaryHasGcTypes, funcExportIndexes, codeTier,
&stubSegmentIndex))
{
return false;
@ -828,14 +828,14 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier)
}
bool
LazyStubTier::createTier2(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices,
LazyStubTier::createTier2(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices,
const CodeTier& codeTier, Maybe<size_t>* outStubSegmentIndex)
{
if (!funcExportIndices.length())
return true;
size_t stubSegmentIndex;
if (!createMany(gcTypesConfigured, funcExportIndices, codeTier, &stubSegmentIndex))
if (!createMany(gcTypesEnabled, funcExportIndices, codeTier, &stubSegmentIndex))
return false;
outStubSegmentIndex->emplace(stubSegmentIndex);

Просмотреть файл

@ -409,7 +409,7 @@ struct MetadataCacheablePod
{
ModuleKind kind;
MemoryUsage memoryUsage;
HasGcTypes temporaryGcTypesConfigured;
HasGcTypes temporaryHasGcTypes;
uint32_t minMemoryLength;
uint32_t globalDataLength;
Maybe<uint32_t> maxMemoryLength;
@ -420,7 +420,7 @@ struct MetadataCacheablePod
explicit MetadataCacheablePod(ModuleKind kind)
: kind(kind),
memoryUsage(MemoryUsage::None),
temporaryGcTypesConfigured(HasGcTypes::False),
temporaryHasGcTypes(HasGcTypes::False),
minMemoryLength(0),
globalDataLength(0),
filenameIsURL(false)
@ -617,7 +617,7 @@ class LazyStubTier
// them in a single stub. Jit entries won't be used until
// setJitEntries() is actually called, after the Code owner has committed
// tier2.
bool createTier2(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices,
bool createTier2(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices,
const CodeTier& codeTier, Maybe<size_t>* stubSegmentIndex);
void setJitEntries(const Maybe<size_t>& stubSegmentIndex, const Code& code);

Просмотреть файл

@ -84,7 +84,7 @@ CompileArgs::CompileArgs(JSContext* cx, ScriptedCaller&& scriptedCaller)
baselineEnabled = cx->options().wasmBaseline() || gcEnabled;
ionEnabled = cx->options().wasmIon() && !gcEnabled;
sharedMemoryEnabled = cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled();
gcTypesConfigured = gcEnabled ? HasGcTypes::True : HasGcTypes::False;
gcTypesEnabled = gcEnabled ? HasGcTypes::True : HasGcTypes::False;
testTiering = (cx->options().testWasmAwaitTier2() || JitOptions.wasmDelayTier2) && !gcEnabled;
// Debug information such as source view or debug traps will require
@ -467,7 +467,7 @@ wasm::CompileBuffer(const CompileArgs& args, const ShareableBytes& bytecode, Uni
DebugEnabled debug;
InitialCompileFlags(args, d, &mode, &tier, &debug);
ModuleEnvironment env(mode, tier, debug, args.gcTypesConfigured,
ModuleEnvironment env(mode, tier, debug, args.gcTypesEnabled,
args.sharedMemoryEnabled ? Shareable::True : Shareable::False);
if (!DecodeModuleEnvironment(d, &env))
return nullptr;
@ -493,7 +493,7 @@ wasm::CompileTier2(const CompileArgs& args, Module& module, Atomic<bool>* cancel
UniqueChars error;
Decoder d(module.bytecode().bytes, 0, &error);
MOZ_ASSERT(args.gcTypesConfigured == HasGcTypes::False, "can't ion-compile with gc types yet");
MOZ_ASSERT(args.gcTypesEnabled == HasGcTypes::False, "can't ion-compile with gc types yet");
ModuleEnvironment env(CompileMode::Tier2, Tier::Ion, DebugEnabled::False, HasGcTypes::False,
args.sharedMemoryEnabled ? Shareable::True : Shareable::False);
@ -622,7 +622,7 @@ wasm::CompileStreaming(const CompileArgs& args,
DebugEnabled debug;
InitialCompileFlags(args, d, &mode, &tier, &debug);
env.emplace(mode, tier, debug, args.gcTypesConfigured,
env.emplace(mode, tier, debug, args.gcTypesEnabled,
args.sharedMemoryEnabled ? Shareable::True : Shareable::False);
if (!DecodeModuleEnvironment(d, env.ptr()))
return nullptr;

Просмотреть файл

@ -52,7 +52,7 @@ struct CompileArgs : ShareableBase<CompileArgs>
bool debugEnabled;
bool ionEnabled;
bool sharedMemoryEnabled;
HasGcTypes gcTypesConfigured;
HasGcTypes gcTypesEnabled;
bool testTiering;
explicit CompileArgs(ScriptedCaller&& scriptedCaller)
@ -61,7 +61,7 @@ struct CompileArgs : ShareableBase<CompileArgs>
debugEnabled(false),
ionEnabled(false),
sharedMemoryEnabled(false),
gcTypesConfigured(HasGcTypes::False),
gcTypesEnabled(HasGcTypes::False),
testTiering(false)
{}

Просмотреть файл

@ -829,7 +829,7 @@ ModuleGenerator::finishMetadata(const ShareableBytes& bytecode)
// Copy over data from the ModuleEnvironment.
metadata_->memoryUsage = env_->memoryUsage;
metadata_->temporaryGcTypesConfigured = env_->gcTypesConfigured;
metadata_->temporaryHasGcTypes = env_->gcTypesEnabled;
metadata_->minMemoryLength = env_->minMemoryLength;
metadata_->maxMemoryLength = env_->maxMemoryLength;
metadata_->startFuncIndex = env_->startFuncIndex;

Просмотреть файл

@ -3503,7 +3503,7 @@ wasm::IonCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo,
ValTypeVector locals;
if (!locals.appendAll(env.funcTypes[func.index]->args()))
return false;
if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled(), &locals))
if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled, &locals))
return false;
// Set up for Ion compilation.

Просмотреть файл

@ -120,11 +120,11 @@ Module::finishTier2(const LinkData& linkData, UniqueCodeTier tier2Arg, ModuleEnv
return false;
}
HasGcTypes gcTypesConfigured = code().metadata().temporaryGcTypesConfigured;
HasGcTypes gcTypesEnabled = code().metadata().temporaryHasGcTypes;
const CodeTier& tier2 = code().codeTier(Tier::Ion);
Maybe<size_t> stub2Index;
if (!stubs2->createTier2(gcTypesConfigured, funcExportIndices, tier2, &stub2Index))
if (!stubs2->createTier2(gcTypesEnabled, funcExportIndices, tier2, &stub2Index))
return false;
// Now that we can't fail or otherwise abort tier2, make it live.

Просмотреть файл

@ -632,7 +632,7 @@ OpIter<Policy>::Unify(StackType observed, StackType expected, StackType* result)
return true;
}
if (env_.gcTypesEnabled() == HasGcTypes::True && observed.isRefOrAnyRef() &&
if (env_.gcTypesEnabled == HasGcTypes::True && observed.isRefOrAnyRef() &&
expected.isRefOrAnyRef() && IsSubtypeOf(observed, expected))
{
*result = expected;
@ -661,7 +661,7 @@ OpIter<Policy>::Join(StackType one, StackType two, StackType* result)
return true;
}
if (env_.gcTypesEnabled() == HasGcTypes::True && one.isRefOrAnyRef() && two.isRefOrAnyRef()) {
if (env_.gcTypesEnabled == HasGcTypes::True && one.isRefOrAnyRef() && two.isRefOrAnyRef()) {
if (IsSubtypeOf(two, one)) {
*result = one;
return true;
@ -901,12 +901,12 @@ OpIter<Policy>::readBlockType(ExprType* type)
known = true;
break;
case uint8_t(ExprType::Ref):
known = env_.gcTypesEnabled() == HasGcTypes::True &&
known = env_.gcTypesEnabled == HasGcTypes::True &&
uncheckedRefTypeIndex < MaxTypes &&
uncheckedRefTypeIndex < env_.types.length();
break;
case uint8_t(ExprType::AnyRef):
known = env_.gcTypesEnabled() == HasGcTypes::True;
known = env_.gcTypesEnabled == HasGcTypes::True;
break;
case uint8_t(ExprType::Limit):
break;

Просмотреть файл

@ -297,7 +297,7 @@ CallFuncExport(MacroAssembler& masm, const FuncExport& fe, const Maybe<ImmPtr>&
// must map from the ABI of ExportFuncPtr to the export's signature's ABI.
static bool
GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe<ImmPtr>& funcPtr,
HasGcTypes gcTypesConfigured, Offsets* offsets)
HasGcTypes gcTypesEnabled, Offsets* offsets)
{
AssertExpectedSP(masm);
masm.haltingAlign(CodeAlignment);
@ -352,7 +352,7 @@ GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe<ImmP
#ifdef ENABLE_WASM_GC
WasmPush(masm, WasmTlsReg);
if (gcTypesConfigured == HasGcTypes::True)
if (gcTypesEnabled == HasGcTypes::True)
SuppressGC(masm, 1, scratch);
#endif
@ -411,7 +411,7 @@ GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe<ImmP
#ifdef ENABLE_WASM_GC
WasmPop(masm, WasmTlsReg);
if (gcTypesConfigured == HasGcTypes::True)
if (gcTypesEnabled == HasGcTypes::True)
SuppressGC(masm, -1, WasmTlsReg);
#endif
@ -519,7 +519,7 @@ GenerateJitEntryThrow(MacroAssembler& masm, unsigned frameSize)
static bool
GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& fe,
const Maybe<ImmPtr>& funcPtr, HasGcTypes gcTypesConfigured, Offsets* offsets)
const Maybe<ImmPtr>& funcPtr, HasGcTypes gcTypesEnabled, Offsets* offsets)
{
AssertExpectedSP(masm);
@ -732,7 +732,7 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport&
masm.loadWasmPinnedRegsFromTls();
#ifdef ENABLE_WASM_GC
if (gcTypesConfigured == HasGcTypes::True) {
if (gcTypesEnabled == HasGcTypes::True) {
masm.storePtr(WasmTlsReg, Address(sp, savedTlsOffset));
SuppressGC(masm, 1, ScratchIonEntry);
}
@ -745,7 +745,7 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport&
masm.assertStackAlignment(WasmStackAlignment);
#ifdef ENABLE_WASM_GC
if (gcTypesConfigured == HasGcTypes::True) {
if (gcTypesEnabled == HasGcTypes::True) {
masm.loadPtr(Address(sp, savedTlsOffset), WasmTlsReg);
SuppressGC(masm, -1, WasmTlsReg);
}
@ -1848,14 +1848,14 @@ GenerateDebugTrapStub(MacroAssembler& masm, Label* throwLabel, CallableOffsets*
bool
wasm::GenerateEntryStubs(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& fe,
const Maybe<ImmPtr>& callee, bool isAsmJS, HasGcTypes gcTypesConfigured,
const Maybe<ImmPtr>& callee, bool isAsmJS, HasGcTypes gcTypesEnabled,
CodeRangeVector* codeRanges)
{
MOZ_ASSERT(!callee == fe.hasEagerStubs());
MOZ_ASSERT_IF(isAsmJS, fe.hasEagerStubs());
Offsets offsets;
if (!GenerateInterpEntry(masm, fe, callee, gcTypesConfigured, &offsets))
if (!GenerateInterpEntry(masm, fe, callee, gcTypesEnabled, &offsets))
return false;
if (!codeRanges->emplaceBack(CodeRange::InterpEntry, fe.funcIndex(), offsets))
return false;
@ -1863,7 +1863,7 @@ wasm::GenerateEntryStubs(MacroAssembler& masm, size_t funcExportIndex, const Fun
if (isAsmJS || fe.funcType().temporarilyUnsupportedAnyRef())
return true;
if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, gcTypesConfigured, &offsets))
if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, gcTypesEnabled, &offsets))
return false;
if (!codeRanges->emplaceBack(CodeRange::JitEntry, fe.funcIndex(), offsets))
return false;
@ -1914,7 +1914,7 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import
if (!fe.hasEagerStubs())
continue;
if (!GenerateEntryStubs(masm, i, fe, noAbsolute, env.isAsmJS(),
env.gcTypesConfigured, &code->codeRanges))
env.gcTypesEnabled, &code->codeRanges))
{
return false;
}

Просмотреть файл

@ -39,7 +39,7 @@ GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& imports,
extern bool
GenerateEntryStubs(jit::MacroAssembler& masm, size_t funcExportIndex,
const FuncExport& funcExport, const Maybe<jit::ImmPtr>& callee,
bool isAsmJS, HasGcTypes gcTypesConfigured, CodeRangeVector* codeRanges);
bool isAsmJS, HasGcTypes gcTypesEnabled, CodeRangeVector* codeRanges);
// An argument that will end up on the stack according to the system ABI, to be
// passed to GenerateDirectCallFromJit. Since the direct JIT call creates its

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше