Update On Wed Jan 12 19:28:29 CET 2022

This commit is contained in:
github-action[bot] 2022-01-12 19:28:29 +01:00
parent 6692978efa
commit d4fe6f9463
2833 changed files with 15216 additions and 11071 deletions

View file

@ -487,13 +487,13 @@ already_AddRefed<AccAttributes> RemoteAccessibleBase<Derived>::Attributes() {
GroupPos groupPos = GroupPosition();
nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level, groupPos.setSize,
groupPos.posInSet);
groupPos.posInSet);
bool hierarchical = false;
uint32_t itemCount = AccGroupInfo::TotalItemCount(this, &hierarchical);
if (itemCount) {
attributes->SetAttribute(nsGkAtoms::child_item_count,
static_cast<int32_t>(itemCount));
static_cast<int32_t>(itemCount));
}
if (hierarchical) {

View file

@ -30,7 +30,6 @@ var DevelopmentHelpers = {
let command = document.createXULElement("command");
command.setAttribute("id", "cmd_quickRestart");
command.addEventListener("command", this.quickRestart, true);
command.setAttribute("oncommand", "void 0;"); // Needed - bug 371900
document.getElementById("mainCommandSet").prepend(command);
let key = document.createXULElement("key");
@ -38,7 +37,6 @@ var DevelopmentHelpers = {
key.setAttribute("key", "r");
key.setAttribute("modifiers", "accel,alt");
key.setAttribute("command", "cmd_quickRestart");
key.setAttribute("oncommand", "void 0;"); // Needed - bug 371900
document.getElementById("mainKeyset").prepend(key);
let menuitem = document.createXULElement("menuitem");

View file

@ -170,7 +170,8 @@
<key id="key_toggleMute" data-l10n-id="mute-toggle-shortcut" command="cmd_toggleMute" modifiers="control"/>
<key id="key_undo"
data-l10n-id="text-action-undo-shortcut"
modifiers="accel"/>
modifiers="accel"
internal="true"/>
<key id="key_redo"
#ifdef XP_UNIX
data-l10n-id="text-action-undo-shortcut"
@ -179,18 +180,21 @@
data-l10n-id="text-action-redo-shortcut"
modifiers="accel"
#endif
/>
internal="true"/>
<key id="key_cut"
data-l10n-id="text-action-cut-shortcut"
modifiers="accel"/>
modifiers="accel"
internal="true"/>
<key id="key_copy"
data-l10n-id="text-action-copy-shortcut"
modifiers="accel"/>
modifiers="accel"
internal="true"/>
<key id="key_paste"
data-l10n-id="text-action-paste-shortcut"
modifiers="accel"/>
modifiers="accel"
internal="true"/>
<key id="key_delete" keycode="VK_DELETE" command="cmd_delete" reserved="false"/>
<key id="key_selectAll" data-l10n-id="text-action-select-all-shortcut" modifiers="accel"/>
<key id="key_selectAll" data-l10n-id="text-action-select-all-shortcut" modifiers="accel" internal="true"/>
<key keycode="VK_BACK" command="cmd_handleBackspace" reserved="false"/>
<key keycode="VK_BACK" command="cmd_handleShiftBackspace" modifiers="shift" reserved="false"/>
@ -310,7 +314,9 @@
# On OS X, dark voodoo magic invokes the quit code for this key.
# So we're not adding the attribute on OSX because of backwards/add-on compat.
# See bug 1369909 for background on this.
#ifndef XP_MACOSX
#ifdef XP_MACOSX
internal="true"
#else
command="cmd_quitApplication"
#endif
reserved="true"/>
@ -361,20 +367,25 @@
<key id="key_minimizeWindow"
command="minimizeWindow"
data-l10n-id="window-minimize-shortcut"
modifiers="accel"/>
modifiers="accel"
internal="true"/>
<key id="key_openHelpMac"
oncommand="openHelpLink('firefox-osxkey');"
data-l10n-id="help-shortcut"
modifiers="accel"/>
modifiers="accel"
internal="true"/>
<!-- These are used to build the Application menu -->
<key id="key_preferencesCmdMac"
data-l10n-id="preferences-shortcut"
modifiers="accel"/>
modifiers="accel"
internal="true"/>
<key id="key_hideThisAppCmdMac"
data-l10n-id="hide-app-shortcut"
modifiers="accel"/>
modifiers="accel"
internal="true"/>
<key id="key_hideOtherAppsCmdMac"
data-l10n-id="hide-other-apps-shortcut"
modifiers="accel,alt"/>
modifiers="accel,alt"
internal="true"/>
#endif
</keyset>

View file

@ -17,12 +17,16 @@ support-files =
https_first_disabled = true
skip-if =
os == 'win' && bits == 64 # Bug 1719856
os == 'linux' && socketprocess_networking
[browser_contextmenu_inspect.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_contextmenu_keyword.js]
skip-if = toolkit == "gtk" || (os == "win" && processor == "aarch64") # disabled on Linux due to bug 513558, aarch64 due to 1533161
[browser_contextmenu_loadblobinnewtab.js]
support-files = browser_contextmenu_loadblobinnewtab.html
skip-if = os == 'linux' && socketprocess_networking
[browser_contextmenu_save_blocked.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_contextmenu_share_macosx.js]
support-files =
browser_contextmenu_shareurl.html
@ -38,13 +42,20 @@ skip-if = toolkit == "gtk" || (os == "win" && processor == "aarch64") # disabled
[browser_contextmenu_touch.js]
skip-if = true # Bug 1424433, disable due to very high frequency failure rate also on Windows 10
[browser_contextmenu_linkopen.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_contextmenu_iframe.js]
support-files =
test_contextmenu_iframe.html
skip-if = os == 'linux' && socketprocess_networking
[browser_contextmenu_childprocess.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_contextmenu.js]
tags = fullscreen
skip-if = toolkit == "gtk" || verify || (os == "win" && processor == "aarch64") # disabled on Linux due to bug 513558, aarch64 due to 1531590
skip-if =
toolkit == "gtk"
verify
os == "win" && processor == "aarch64" # disabled on Linux due to bug 513558, aarch64 due to 1531590
os == 'linux' && socketprocess_networking
[browser_contextmenu_input.js]
skip-if = toolkit == "gtk" || (os == "win" && processor == "aarch64") # disabled on Linux due to bug 513558, aarch64 due to 1533161
[browser_copy_image_link.js]
@ -52,10 +63,13 @@ support-files =
doggy.png
firebird.png
firebird.png^headers^
skip-if = os == 'linux' && socketprocess_networking
[browser_utilityOverlay.js]
https_first_disabled = true
skip-if = os == 'linux' && socketprocess_networking
[browser_utilityOverlayPrincipal.js]
https_first_disabled = true
[browser_view_image.js]
support-files =
test_view_image_revoked_cached_blob.html
skip-if = os == 'linux' && socketprocess_networking

View file

@ -224,6 +224,7 @@ skip-if = e10s # Bug 863514 - no gesture support.
[browser_homeDrop.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_invalid_uri_back_forward_manipulation.js]
skip-if = os == 'mac' && socketprocess_networking
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_lastAccessedTab.js]
skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bug 969405)

View file

@ -23,13 +23,18 @@ support-files =
[browser_appmenu.js]
skip-if =
asan || debug || (os == 'win' && bits == 32) || (os == 'win' && processor == 'aarch64') # Bug 1382809, bug 1369959, Win32 because of intermittent OOM failures, bug 1533141 for aarch64
asan
debug
(os == 'win' && bits == 32)
(os == 'win' && processor == 'aarch64')
(os == 'linux' && socketprocess_networking) # Bug 1382809, bug 1369959, Win32 because of intermittent OOM failures, bug 1533141 for aarch64
[browser_preferences_usage.js]
https_first_disabled = true
skip-if =
!debug
apple_catalina # platform migration
os == 'win' && fission # Bug 1713890 - new Fission platform triage
socketprocess_networking
[browser_startup.js]
[browser_startup_content.js]
skip-if = !e10s

View file

@ -473,8 +473,8 @@ const startupPhases = {
ignoreIfUnused: true,
stat: 4,
fsync: 3,
read: 48,
write: 172,
read: 51,
write: 178,
},
{
// bug 1391590
@ -490,7 +490,7 @@ const startupPhases = {
fsync: 2,
read: 4,
stat: 3,
write: 1321,
write: 1324,
},
{
// bug 1391590

View file

@ -25,5 +25,6 @@ environment =
skip-if =
apple_silicon # bug 1707724
os == "win" && bits == 32
socketprocess_networking
[../browser_startup_content_mainthreadio.js]
[../browser_startup_syncIPC.js]

View file

@ -42,6 +42,7 @@ tags = openwindow
skip-if =
(verify && debug && (os == 'linux'))
apple_silicon # Disabled due to bleedover with other tests when run in regular suites; passes in "failures" jobs
os == 'linux' && socketprocess_networking
[browser_imageCache.js]
skip-if = (verify && debug && (os == 'win'))
[browser_count_and_remove.js]

View file

@ -2,6 +2,7 @@
head = head.js
[browser_cleanFlow.js]
skip-if = socketprocess_networking
[browser_dirtyEnable.js]
[browser_doorhangerUserReject.js]
[browser_localStorageMigration.js]

View file

@ -15,15 +15,11 @@
%editMenuDTD;
]>
<!-- @CSP: We have to whitelist the 'oncommand' handler for all the cmd_* fields within
- editMenuOverlay.js until Bug 371900 is fixed using
- sha512-4o5Uf4E4EG+90Mb820FH2YFDf4IuX4bfUwQC7reK1ZhgcXWJBKMK2330XIELaFJJ8HiPffS9mP60MPjuXMIrHA==
-->
<window id="contentAreaDownloadsView"
data-l10n-id="downloads-window"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
csp="default-src chrome:; script-src chrome: 'sha512-4o5Uf4E4EG+90Mb820FH2YFDf4IuX4bfUwQC7reK1ZhgcXWJBKMK2330XIELaFJJ8HiPffS9mP60MPjuXMIrHA=='; img-src chrome: moz-icon:; object-src 'none'">
csp="default-src chrome:; img-src chrome: moz-icon:; object-src 'none'">
<linkset>
<html:link rel="localization" href="toolkit/global/textActions.ftl"/>

View file

@ -60,7 +60,9 @@ disabled = bug 1438663 # same focus issue as Bug 1438663
[browser_ext_browserAction_click_types.js]
[browser_ext_browserAction_context.js]
https_first_disabled = true
skip-if = os == 'linux' && debug # Bug 1504096
skip-if =
os == 'linux' && debug # Bug 1504096
os == 'linux' && socketprocess_networking
[browser_ext_browserAction_contextMenu.js]
skip-if = os == 'linux' # bug 1369197
[browser_ext_browserAction_disabled.js]

View file

@ -10,6 +10,7 @@ const BOOKMARKS_COUNT = 4;
const TEST_PARENT_FOLDER = "testParentFolder";
const TEST_SIF_URL = "http://testsif.example.com/";
const TEST_SIF_TITLE = "TestSIF";
const TEST_NEW_TITLE = "NewTestSIF";
function assertBookmarks(searchValue) {
let found = 0;
@ -38,7 +39,7 @@ function assertBookmarks(searchValue) {
is(found, BOOKMARKS_COUNT, "found expected site");
}
function showInFolder(aSearchStr, aParentFolderGuid) {
async function showInFolder(aSearchStr, aParentFolderGuid) {
let searchBox = sidebar.contentDocument.getElementById("search-box");
searchBox.value = aSearchStr;
@ -70,9 +71,20 @@ function showInFolder(aSearchStr, aParentFolderGuid) {
TEST_SIF_URL,
"The searched bookmark URL matches selected node"
);
info("Check the title will be applied the item when changing it");
await PlacesUtils.bookmarks.update({
guid: theNode.bookmarkGuid,
title: TEST_NEW_TITLE,
});
Assert.equal(
treeNode.title,
TEST_NEW_TITLE,
"New title is applied to the node"
);
}
add_task(async function test() {
add_task(async function testTree() {
// Add bookmarks and tags.
for (let i = 0; i < BOOKMARKS_COUNT; i++) {
let url = Services.io.newURI(TEST_URI + i);
@ -94,9 +106,10 @@ add_task(async function test() {
// Cleanup before testing Show in Folder.
await PlacesUtils.bookmarks.eraseEverything();
});
add_task(async function testShowInFolder() {
// Now test Show in Folder
info("Test Show in Folder");
let parentFolder = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER,
@ -109,10 +122,68 @@ add_task(async function test() {
url: TEST_SIF_URL,
});
await withSidebarTree("bookmarks", function() {
showInFolder(TEST_SIF_TITLE, parentFolder.guid);
await withSidebarTree("bookmarks", async function() {
await showInFolder(TEST_SIF_TITLE, parentFolder.guid);
});
// Cleanup
await PlacesUtils.bookmarks.eraseEverything();
});
add_task(async function testRenameOnQueryResult() {
await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
title: TEST_SIF_TITLE,
url: TEST_SIF_URL,
});
await withSidebarTree("bookmarks", async function() {
const searchBox = sidebar.contentDocument.getElementById("search-box");
searchBox.value = TEST_SIF_TITLE;
searchBox.doCommand();
const tree = sidebar.contentDocument.getElementById("bookmarks-view");
const theNode = tree.view._getNodeForRow(0);
info("Check the found bookmark");
Assert.equal(theNode.uri, TEST_SIF_URL, "URI of bookmark found is correct");
Assert.equal(
theNode.title,
TEST_SIF_TITLE,
"Title of bookmark found is correct"
);
info("Check the title will be applied the item when changing it");
await PlacesUtils.bookmarks.update({
guid: theNode.bookmarkGuid,
title: TEST_NEW_TITLE,
});
// As the query result is refreshed once then the node also is regenerated,
// need to get the result node from the tree again.
const newNode = tree.view._getNodeForRow(0);
Assert.equal(
newNode.bookmarkGuid,
theNode.bookmarkGuid,
"GUID of node regenerated is correct"
);
Assert.equal(
newNode.uri,
theNode.uri,
"URI of node regenerated is correct"
);
Assert.equal(
newNode.parentGuid,
theNode.parentGuid,
"parentGuid of node regenerated is correct"
);
Assert.equal(
newNode.title,
TEST_NEW_TITLE,
"New title is applied to the node"
);
});
// Cleanup before testing Show in Folder.
await PlacesUtils.bookmarks.eraseEverything();
});

View file

@ -74,8 +74,9 @@ add_task(async function test_create_and_remove_bookmarks() {
"places"
);
// Execute the delete command and check bookmark has been removed.
PO._places.controller.doCommand("cmd_delete");
// Press the delete key and check that the bookmark has been removed.
gLibrary.document.getElementById("placesList").focus();
EventUtils.synthesizeKey("VK_DELETE", {}, gLibrary);
await promiseItemRemovedNotification;

View file

@ -238,6 +238,10 @@ function init_all() {
window.addEventListener("hashchange", onHashChange);
document.getElementById("focusSearch1").addEventListener("command", () => {
gSearchResultsPane.searchInput.focus();
});
gotoPref().then(() => {
let helpButton = document.getElementById("helpButton");
let helpUrl =

View file

@ -22,11 +22,8 @@
id="preferences-root">
<head>
<!-- @CSP: The 'oncommand' handler for 'focusSearch1' can not easily be rewritten (see Bug 371900)
hence we are allowing the inline handler in the script-src directive using the hash
sha512-X8+p/CqXeMdssOoFOf5RV+RpkvnN9pukQ20acGc7LqMgfYLW+lR0WAYT66OtSTpFHE/Qgx/ZCBs2RMc4QrA8FQ==
Additionally we should remove 'unsafe-inline' from style-src, see Bug 1579160 -->
<meta http-equiv="Content-Security-Policy" content="default-src chrome:; script-src chrome: 'sha512-X8+p/CqXeMdssOoFOf5RV+RpkvnN9pukQ20acGc7LqMgfYLW+lR0WAYT66OtSTpFHE/Qgx/ZCBs2RMc4QrA8FQ=='; img-src chrome: moz-icon: https: data:; style-src chrome: data: 'unsafe-inline'; object-src 'none'" />
<!-- @CSP: We should remove 'unsafe-inline' from style-src, see Bug 1579160 -->
<meta http-equiv="Content-Security-Policy" content="default-src chrome:; img-src chrome: moz-icon: https: data:; style-src chrome: data: 'unsafe-inline'; object-src 'none'" />
<title data-l10n-id="settings-page-title"></title>
@ -182,9 +179,7 @@
</vbox>
<keyset>
<!-- If you change the code within the oncommand handler of 'focusSearch1' you have to update the current hash of
sha512-X8+p/CqXeMdssOoFOf5RV+RpkvnN9pukQ20acGc7LqMgfYLW+lR0WAYT66OtSTpFHE/Qgx/ZCBs2RMc4QrA8FQ== within the CSP above. -->
<key data-l10n-id="focus-search" key="" modifiers="accel" id="focusSearch1" oncommand="gSearchResultsPane.searchInput.focus();"/>
<key data-l10n-id="focus-search" key="" modifiers="accel" id="focusSearch1"/>
</keyset>
<vbox class="main-content" flex="1" align="start">

View file

@ -67,6 +67,7 @@ skip-if =
os == 'win' && bits == 64 && !debug # Bug 1741554
[browser_contentblocking_categories.js]
[browser_contentblocking.js]
skip-if = socketprocess_networking
[browser_contentblocking_standard_tcp_toggle.js]
[browser_cookies_exceptions.js]
[browser_defaultbrowser_alwayscheck.js]

View file

@ -35,12 +35,17 @@ https_first_disabled = true
[browser_roundedWindow_open_mid_inner.js]
[browser_roundedWindow_open_min_inner.js]
[browser_roundedWindow_windowSetting_max_inner.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_roundedWindow_windowSetting_max_outer.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_roundedWindow_windowSetting_mid_inner.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_roundedWindow_windowSetting_mid_outer.js]
skip-if = os == "linux" && bits == 64 && os_version == "18.04"
[browser_roundedWindow_windowSetting_min_inner.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_roundedWindow_windowSetting_min_outer.js]
skip-if = os == 'linux' && socketprocess_networking
[browser_spoofing_keyboard_event.js]
skip-if = (debug || asan) && os == "linux" && bits == 64 #Bug 1518179
[browser_timezone.js]

View file

@ -112,7 +112,7 @@ class UrlbarView {
}
get allowEmptySelection() {
let { heuristicResult } = this._queryContext;
let { heuristicResult } = this._queryContext || {};
return !heuristicResult || !this._shouldShowHeuristic(heuristicResult);
}

View file

@ -210,6 +210,7 @@ support-files =
support-files =
searchSuggestionEngine.xml
searchSuggestionEngine.sjs
[browser_searchMode_newWindow.js]
[browser_searchMode_no_results.js]
[browser_searchMode_oneOffButton.js]
[browser_searchMode_pickResult.js]

View file

@ -0,0 +1,40 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests immediately entering search mode in a new window and then exiting it.
// No errors should be thrown and search mode should be exited successfully.
"use strict";
add_task(async function escape() {
await doTest(win =>
EventUtils.synthesizeKey("KEY_Escape", { repeat: 2 }, win)
);
});
add_task(async function backspace() {
await doTest(win => EventUtils.synthesizeKey("KEY_Backspace", {}, win));
});
async function doTest(exitSearchMode) {
let win = await BrowserTestUtils.openNewBrowserWindow();
// Press accel+K to enter search mode.
await UrlbarTestUtils.promisePopupOpen(win, () =>
EventUtils.synthesizeKey("k", { accelKey: true }, win)
);
await UrlbarTestUtils.assertSearchMode(win, {
engineName: Services.search.defaultEngine.name,
isGeneralPurposeEngine: true,
source: UrlbarUtils.RESULT_SOURCE.SEARCH,
isPreview: false,
entry: "shortcut",
});
// Exit search mode.
await exitSearchMode(win);
await UrlbarTestUtils.assertSearchMode(win, null);
await UrlbarTestUtils.promisePopupClose(win);
await BrowserTestUtils.closeWindow(win);
}

View file

@ -585,6 +585,20 @@ const AVAILABLE_SHIMS = [
],
onlyIfDFPIActive: true,
},
{
id: "Crave.ca",
platform: "all",
name: "Crave.ca",
bug: "1746439",
contentScripts: [
{
js: "crave-ca.js",
matches: ["*://account.bellmedia.ca/login*"],
runAt: "document_start",
},
],
onlyIfDFPIActive: true,
},
];
module.exports = AVAILABLE_SHIMS;

View file

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Web Compatibility Interventions",
"description": "Urgent post-release fixes for web compatibility.",
"version": "29.7.0",
"version": "29.8.0",
"applications": {
"gecko": {
"id": "webcompat@mozilla.org",
@ -98,6 +98,7 @@
"shims/apstag.js",
"shims/bmauth.js",
"shims/chartbeat.js",
"shims/crave-ca.js",
"shims/criteo.js",
"shims/cxense.js",
"shims/eluminate.js",

View file

@ -96,6 +96,7 @@ FINAL_TARGET_FILES.features["webcompat@mozilla.org"]["shims"] += [
"shims/apstag.js",
"shims/bmauth.js",
"shims/chartbeat.js",
"shims/crave-ca.js",
"shims/criteo.js",
"shims/cxense.js",
"shims/eluminate.js",

View file

@ -0,0 +1,56 @@
/* 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/. */
"use strict";
/*
* Bug 1746439 - crave.ca login broken with dFPI enabled
*
* Crave.ca relies upon a login page that is out-of-origin. That login page
* sets a cookie for https://www.crave.ca, which is then used as an proof of
* authentication on redirect back to the main site. This shim adds a request
* for storage access for https://www.crave.ca when the user tries to log in.
*/
console.warn(
`When logging in, Firefox calls the Storage Access API on behalf of the site. See https://bugzilla.mozilla.org/show_bug.cgi?id=1746439 for details.`
);
// Third-party origin we need to request storage access for.
const STORAGE_ACCESS_ORIGIN = "https://www.crave.ca";
document.documentElement.addEventListener(
"click",
e => {
const { target, isTrusted } = e;
if (!isTrusted) {
return;
}
const button = target.closest("button");
if (!button) {
return;
}
const form = target.closest(".login-form");
if (!form) {
return;
}
console.warn(
"Calling the Storage Access API on behalf of " + STORAGE_ACCESS_ORIGIN
);
button.disabled = true;
e.stopPropagation();
e.preventDefault();
document
.requestStorageAccessForOrigin(STORAGE_ACCESS_ORIGIN)
.then(() => {
button.disabled = false;
target.click();
})
.catch(() => {
button.disabled = false;
});
},
true
);

View file

@ -6,9 +6,6 @@
%include addons/extension-controlled.inc.css
%filter substitution
%define themeTransition background-color 0.1s cubic-bezier(.17,.67,.83,.67)
%define urlbarBreakoutExtend 2px
:root {
--toolbar-bgcolor: var(--toolbar-non-lwt-bgcolor);
--toolbar-bgimage: var(--toolbar-non-lwt-bgimage);
@ -68,6 +65,8 @@
--lwt-background-alignment: right top;
--lwt-background-tiling: no-repeat;
--lwt-brighttext-url-color: #00ddff;
--ext-theme-background-transition: background-color 0.1s cubic-bezier(.17,.67,.83,.67);
}
@media (prefers-contrast) {
@ -179,7 +178,7 @@ panel .text-link:-moz-lwtheme:not(:hover) {
}
:root[sessionrestored] #nav-bar:-moz-lwtheme {
transition: @themeTransition@;
transition: var(--ext-theme-background-transition);
}
/* Places tooltips */
@ -199,7 +198,7 @@ panel .text-link:-moz-lwtheme:not(:hover) {
}
:root[sessionrestored] #PersonalToolbar:not(.instant) {
transition: min-height 170ms ease-out, max-height 170ms ease-out, @themeTransition@;
transition: min-height 170ms ease-out, max-height 170ms ease-out, var(--ext-theme-background-transition);
}
#PersonalToolbar[collapsed=true] {

View file

@ -15,7 +15,6 @@
%define menuStateActive :not([disabled])[_moz-menuactive]:active
%define menuStateMenuActive :not([disabled])[_moz-menuactive]
%define inAnyPanel :is(:not([cui-areatype="toolbar"]), [overflowedItem=true])
%define panelPaletteIconSize 16px
%define appmenuWarningBackgroundColor #FFEFBF
%define appmenuWarningBackgroundColorHover #FFE8A2
@ -45,6 +44,8 @@
--panel-separator-margin-horizontal: 8px;
--panel-separator-margin: var(--panel-separator-margin-vertical) var(--panel-separator-margin-horizontal);
--panel-subview-body-padding: 8px 0;
--panel-and-palette-icon-size: 16px;
}
:root:not(:-moz-lwtheme) {
@ -433,8 +434,8 @@ toolbarpaletteitem[place="palette"] > toolbarbutton[constrain-size="true"] > .to
toolbarpaletteitem[place="palette"] > toolbarbutton[constrain-size="true"] > .toolbarbutton-badge-stack > .toolbarbutton-icon,
toolbarbutton[constrain-size="true"][cui-areatype="menu-panel"] > .toolbarbutton-icon,
toolbarbutton[constrain-size="true"][cui-areatype="menu-panel"] > .toolbarbutton-badge-stack > .toolbarbutton-icon {
height: @panelPaletteIconSize@;
width: @panelPaletteIconSize@;
height: var(--panel-and-palette-icon-size);
width: var(--panel-and-palette-icon-size);
}
#customization-palette .toolbarbutton-1 {
@ -448,10 +449,10 @@ toolbarbutton[constrain-size="true"][cui-areatype="menu-panel"] > .toolbarbutton
/* badge itself is positioned correctly. Here we make sure that the icon itself
/* has the minimum size we want, but no padding/margin. */
.customization-palette .toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbarbutton-icon {
width: @panelPaletteIconSize@;
height: @panelPaletteIconSize@;
min-width: @panelPaletteIconSize@;
min-height: @panelPaletteIconSize@;
width: var(--panel-and-palette-icon-size);
height: var(--panel-and-palette-icon-size);
min-width: var(--panel-and-palette-icon-size);
min-height: var(--panel-and-palette-icon-size);
margin: 0;
padding: 0;
}

View file

@ -42,6 +42,12 @@ allprojects {
" found ${getRustVersionFor("glean")}")
}
artifactSuffix = getArtifactSuffix()
versionName = getVersionName()
versionCode = computeVersionCode()
versionNumber = getVersionNumber()
buildId = getBuildId()
buildToolsVersion = mozconfig.substs.ANDROID_BUILD_TOOLS_VERSION
compileSdkVersion = tryInt(mozconfig.substs.ANDROID_TARGET_SDK)
targetSdkVersion = tryInt(mozconfig.substs.ANDROID_TARGET_SDK)
@ -57,6 +63,9 @@ allprojects {
gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORIES.each { repository ->
maven {
url repository
if (gradle.mozconfig.substs.ALLOW_INSECURE_GRADLE_REPOSITORIES) {
allowInsecureProtocol = true
}
}
}
}
@ -94,15 +103,18 @@ buildscript {
gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORIES.each { repository ->
maven {
url repository
if (gradle.mozconfig.substs.ALLOW_INSECURE_GRADLE_REPOSITORIES) {
allowInsecureProtocol = true
}
}
}
}
ext.kotlin_version = '1.5.20'
ext.kotlin_version = '1.5.31'
dependencies {
classpath 'org.mozilla.apilint:apilint:0.4.4'
classpath 'com.android.tools.build:gradle:4.2.0'
classpath 'org.mozilla.apilint:apilint:0.5.1'
classpath 'com.android.tools.build:gradle:7.0.3'
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2'
classpath 'org.apache.commons:commons-exec:1.3'
classpath 'com.diffplug.spotless:spotless-plugin-gradle:5.16.0'
@ -159,6 +171,79 @@ ext.geckoBinariesOnlyIf = { task ->
return true
}
// Non-official versions are like "61.0a1", where "a1" is the milestone.
// This simply strips that off, leaving "61.0" in this example.
def getAppVersionWithoutMilestone() {
return project.ext.mozconfig.substs.MOZ_APP_VERSION.replaceFirst(/a[0-9]/, "")
}
// This converts MOZ_APP_VERSION into an integer
// version code.
//
// We take something like 58.1.2a1 and come out with 5800102
// This gives us 3 digits for the major number, and 2 digits
// each for the minor and build number. Beta and Release
//
// This must be synchronized with _compute_gecko_version(...) in /taskcluster/gecko_taskgraph/transforms/task.py
def computeVersionCode() {
String appVersion = getAppVersionWithoutMilestone()
// Split on the dot delimiter, e.g. 58.1.1a1 -> ["58, "1", "1a1"]
String[] parts = appVersion.split('\\.')
assert parts.size() == 2 || parts.size() == 3
// Major
int code = Integer.parseInt(parts[0]) * 100000
// Minor
code += Integer.parseInt(parts[1]) * 100
// Build
if (parts.size() == 3) {
code += Integer.parseInt(parts[2])
}
return code;
}
def getVersionName() {
return "${mozconfig.substs.MOZ_APP_VERSION}-${mozconfig.substs.MOZ_UPDATE_CHANNEL}"
}
// Mimic Python: open(os.path.join(buildconfig.topobjdir, 'buildid.h')).readline().split()[2]
def getBuildId() {
return file("${topobjdir}/buildid.h").getText('utf-8').split()[2]
}
def getVersionNumber() {
def appVersion = getAppVersionWithoutMilestone()
def parts = appVersion.split('\\.')
def version = parts[0] + "." + parts[1] + "." + getBuildId()
def substs = project.ext.mozconfig.substs
if (!substs.MOZILLA_OFFICIAL && !substs.MOZ_ANDROID_FAT_AAR_ARCHITECTURES) {
// Use -SNAPSHOT versions locally to enable the local GeckoView substitution flow.
version += "-SNAPSHOT"
}
return version
}
def getArtifactSuffix() {
def substs = project.ext.mozconfig.substs
def suffix = ""
// Release artifacts don't specify the channel, for the sake of simplicity.
if (substs.MOZ_UPDATE_CHANNEL != 'release') {
suffix += "-${mozconfig.substs.MOZ_UPDATE_CHANNEL}"
}
if (!substs.MOZ_ANDROID_GECKOVIEW_LITE) {
suffix += "-omni"
}
return suffix
}
class MachExec extends Exec {
def MachExec() {
// Bug 1543982: When invoking `mach build` recursively, the outer `mach

View file

@ -17,6 +17,22 @@
# and not quoting it ensures that each of those arguments is passed
# as a separate argument to the actual LD.
#
# * In rare cases, we also need MOZ_CARGO_WRAP_LD_CXX, which is the
# equivalent of CXX, when linking C++ code. Usually, this should
# simply work by the use of CC and -lstdc++ (added by cc-rs).
# However, in the case of sanitizer runtimes, there is a separate
# runtime for C and C++ and linking C++ code with the C runtime can
# fail if the requested feature is in the C++ runtime only (bug 1747298).
#
# $@ is doubly quoted for the eval. See bug 1418598.
eval ${MOZ_CARGO_WRAP_LD} ${MOZ_CARGO_WRAP_LDFLAGS} '"$@"'
WRAP_LD=${MOZ_CARGO_WRAP_LD}
for opt; do
case "$opt" in
-lc++|-lstdc++)
WRAP_LD=${MOZ_CARGO_WRAP_LD_CXX};
break;
;;
esac
done
eval ${WRAP_LD} ${MOZ_CARGO_WRAP_LDFLAGS} '"$@"'

View file

@ -244,6 +244,21 @@ void FuncSetCallback::run(const MatchFinder::MatchResult &Result) {
return;
} else {
Func = Result.Nodes.getNodeAs<FunctionDecl>("canRunScriptFunction");
const char *ErrorAttrInDefinition =
"MOZ_CAN_RUN_SCRIPT must be put in front "
"of the declaration, not the definition";
const char *NoteAttrInDefinition = "The first declaration exists here";
if (!Func->isFirstDecl() &&
!hasCustomAttribute<moz_can_run_script_for_definition>(Func)) {
const FunctionDecl *FirstDecl = Func->getFirstDecl();
if (!hasCustomAttribute<moz_can_run_script>(FirstDecl)) {
Checker.diag(Func->getLocation(), ErrorAttrInDefinition,
DiagnosticIDs::Error);
Checker.diag(FirstDecl->getLocation(), NoteAttrInDefinition,
DiagnosticIDs::Note);
}
}
}
CanRunScriptFuncs.insert(Func);

View file

@ -1,5 +1,6 @@
ATTR(moz_allow_temporary)
ATTR(moz_can_run_script)
ATTR(moz_can_run_script_for_definition)
ATTR(moz_can_run_script_boundary)
ATTR(moz_global_class)
ATTR(moz_heap_allocator)

View file

@ -652,3 +652,7 @@ struct DisallowMozKnownLiveMemberNotFromKnownLive {
foo(mMember->mWhatever); // expected-error {{arguments must all be strong refs or caller's parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument). 'mMember->mWhatever' is neither.}}
}
};
void IncorrectlyUnmarkedEarlyDeclaration(); // expected-note {{The first declaration exists here}}
MOZ_CAN_RUN_SCRIPT void IncorrectlyUnmarkedEarlyDeclaration() {}; // expected-error {{MOZ_CAN_RUN_SCRIPT must be put in front of the declaration, not the definition}}

View file

@ -58,8 +58,8 @@ def android_sdk_version(geckoview_lite):
# If you think you can't handle the whole set of changes, please reach out to the Release
# Engineering team.
return namespace(
build_tools_version="30.0.2",
target_sdk_version="30",
build_tools_version="31.0.0",
target_sdk_version="31",
min_sdk_version="16" if geckoview_lite else "21",
)

View file

@ -318,8 +318,10 @@ cargo_linker_env_var := CARGO_TARGET_$(call varize,$(RUST_TARGET))_LINKER
export MOZ_CARGO_WRAP_LDFLAGS
export MOZ_CARGO_WRAP_LD
export MOZ_CARGO_WRAP_LD_CXX
export MOZ_CARGO_WRAP_HOST_LDFLAGS
export MOZ_CARGO_WRAP_HOST_LD
export MOZ_CARGO_WRAP_HOST_LD_CXX
# Exporting from make always exports a value. Setting a value per-recipe
# would export an empty value for the host recipes. When not doing a
# cross-compile, the --target for those is the same, and cargo will use
@ -382,16 +384,22 @@ $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LDFLAGS:=$(HOST_LDFLAGS)
ifeq (,$(filter clang-cl,$(CC_TYPE)))
$(TARGET_RECIPES): MOZ_CARGO_WRAP_LD:=$(CC)
$(TARGET_RECIPES): MOZ_CARGO_WRAP_LD_CXX:=$(CXX)
else
$(TARGET_RECIPES): MOZ_CARGO_WRAP_LD:=$(LINKER)
$(TARGET_RECIPES): MOZ_CARGO_WRAP_LD_CXX:=$(LINKER)
endif
ifeq (,$(filter clang-cl,$(HOST_CC_TYPE)))
$(HOST_RECIPES): MOZ_CARGO_WRAP_LD:=$(HOST_CC)
$(HOST_RECIPES): MOZ_CARGO_WRAP_LD_CXX:=$(HOST_CXX)
$(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD:=$(HOST_CC)
$(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD_CXX:=$(HOST_CXX)
else
$(HOST_RECIPES): MOZ_CARGO_WRAP_LD:=$(HOST_LINKER)
$(HOST_RECIPES): MOZ_CARGO_WRAP_LD_CXX:=$(HOST_LINKER)
$(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD:=$(HOST_LINKER)
$(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD_CXX:=$(HOST_LINKER)
endif
ifdef RUST_LIBRARY_FILE

View file

@ -2405,7 +2405,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}
@ -2426,7 +2426,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}

View file

@ -94,91 +94,6 @@ module.exports = {
workerUtils
};
/***/ }),
/***/ 562:
/***/ (function(module, exports, __webpack_require__) {
var freeGlobal = __webpack_require__(589);
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
module.exports = root;
/***/ }),
/***/ 563:
/***/ (function(module, exports) {
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
module.exports = isArray;
/***/ }),
/***/ 565:
/***/ (function(module, exports) {
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
module.exports = isObjectLike;
/***/ }),
/***/ 567:
@ -382,165 +297,6 @@ module.exports = {
workerHandler
};
/***/ }),
/***/ 569:
/***/ (function(module, exports, __webpack_require__) {
var Symbol = __webpack_require__(570),
getRawTag = __webpack_require__(615),
objectToString = __webpack_require__(616);
/** `Object#toString` result references. */
var nullTag = '[object Null]',
undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
module.exports = baseGetTag;
/***/ }),
/***/ 570:
/***/ (function(module, exports, __webpack_require__) {
var root = __webpack_require__(562);
/** Built-in value references. */
var Symbol = root.Symbol;
module.exports = Symbol;
/***/ }),
/***/ 577:
/***/ (function(module, exports, __webpack_require__) {
var baseGetTag = __webpack_require__(569),
isObjectLike = __webpack_require__(565);
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
module.exports = isSymbol;
/***/ }),
/***/ 589:
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
module.exports = freeGlobal;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(590)))
/***/ }),
/***/ 590:
/***/ (function(module, exports) {
var g;
// This works in non-strict mode
g = (function() {
return this;
})();
try {
// This works if eval is allowed (see CSP)
g = g || Function("return this")() || (1,eval)("this");
} catch(e) {
// This works if the window reference is available
if(typeof window === "object")
g = window;
}
// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}
module.exports = g;
/***/ }),
/***/ 605:
/***/ (function(module, exports, __webpack_require__) {
var baseToString = __webpack_require__(639);
/**
* Converts `value` to a string. An empty string is returned for `null`
* and `undefined` values. The sign of `-0` is preserved.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
* @example
*
* _.toString(null);
* // => ''
*
* _.toString(-0);
* // => '-0'
*
* _.toString([1, 2, 3]);
* // => '1,2,3'
*/
function toString(value) {
return value == null ? '' : baseToString(value);
}
module.exports = toString;
/***/ }),
/***/ 607:
@ -732,160 +488,6 @@ process.chdir = function (dir) {
process.umask = function() { return 0; };
/***/ }),
/***/ 615:
/***/ (function(module, exports, __webpack_require__) {
var Symbol = __webpack_require__(570);
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/** Built-in value references. */
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag),
tag = value[symToStringTag];
try {
value[symToStringTag] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag] = tag;
} else {
delete value[symToStringTag];
}
}
return result;
}
module.exports = getRawTag;
/***/ }),
/***/ 616:
/***/ (function(module, exports) {
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
module.exports = objectToString;
/***/ }),
/***/ 639:
/***/ (function(module, exports, __webpack_require__) {
var Symbol = __webpack_require__(570),
arrayMap = __webpack_require__(640),
isArray = __webpack_require__(563),
isSymbol = __webpack_require__(577);
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol ? Symbol.prototype : undefined,
symbolToString = symbolProto ? symbolProto.toString : undefined;
/**
* The base implementation of `_.toString` which doesn't convert nullish
* values to empty strings.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/
function baseToString(value) {
// Exit early for strings to avoid a performance hit in some environments.
if (typeof value == 'string') {
return value;
}
if (isArray(value)) {
// Recursively convert values (susceptible to call stack limits).
return arrayMap(value, baseToString) + '';
}
if (isSymbol(value)) {
return symbolToString ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
module.exports = baseToString;
/***/ }),
/***/ 640:
/***/ (function(module, exports) {
/**
* A specialized version of `_.map` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
function arrayMap(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length,
result = Array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
module.exports = arrayMap;
/***/ }),
/***/ 701:
@ -1018,20 +620,21 @@ Object.defineProperty(exports, "__esModule", {
});
exports.default = buildQuery;
var _escapeRegExp = _interopRequireDefault(__webpack_require__(908));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
function escapeRegExp(str) {
const reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
return str.replace(reRegExpChar, "\\$&");
}
/**
* Ignore doing outline matches for less than 3 whitespaces
*
* @memberof utils/source-search
* @static
*/
function ignoreWhiteSpace(str) {
return /^\s{0,2}$/.test(str) ? "(?!\\s*.*)" : str;
}
@ -1072,16 +675,20 @@ function buildQuery(originalQuery, modifiers, {
return new RegExp(originalQuery);
}
let query = originalQuery;
let query = originalQuery; // If we don't want to do a regexMatch, we need to escape all regex related characters
// so they would actually match.
if (!regexMatch) {
query = escapeRegExp(query);
} // ignoreWhiteSpace might return a negative lookbehind, and in such case, we want it
// to be consumed as a RegExp part by the callsite, so this needs to be called after
// the regexp is escaped.
if (ignoreSpaces) {
query = ignoreWhiteSpace(query);
}
if (!regexMatch) {
query = (0, _escapeRegExp.default)(query);
}
query = wholeMatch(query, wholeWord);
const flags = buildFlags(caseSensitive, isGlobal);
@ -1092,45 +699,6 @@ function buildQuery(originalQuery, modifiers, {
return new RegExp(query);
}
/***/ }),
/***/ 908:
/***/ (function(module, exports, __webpack_require__) {
var toString = __webpack_require__(605);
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
reHasRegExpChar = RegExp(reRegExpChar.source);
/**
* Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
* "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
*
* @static
* @memberOf _
* @since 3.0.0
* @category String
* @param {string} [string=''] The string to escape.
* @returns {string} Returns the escaped string.
* @example
*
* _.escapeRegExp('[lodash](https://lodash.com/)');
* // => '\[lodash\]\(https://lodash\.com/\)'
*/
function escapeRegExp(string) {
string = toString(string);
return (string && reHasRegExpChar.test(string))
? string.replace(reRegExpChar, '\\$&')
: string;
}
module.exports = escapeRegExp;
/***/ }),
/***/ 909:

View file

@ -121,9 +121,14 @@ add_task(async function() {
await removeTab(gBrowser.selectedTab);
});
// Test setting breakpoints while the service worker is starting up.
add_task(async function() {
info("Subtest #4");
if (Services.appinfo.fissionAutostart) {
// Disabled when serviceworker isolation is used due to bug 1749341
return;
}
const toolbox = await openNewTabAndToolbox(
EXAMPLE_URL + "doc-service-workers.html",

View file

@ -73,7 +73,6 @@ class WindowGlobalTargetFront extends TargetMixin(
const event = Object.create(null);
event.url = packet.url;
event.title = packet.title;
event.nativeConsoleAPI = packet.nativeConsoleAPI;
event.isFrameSwitching = packet.isFrameSwitching;
// Keep the title unmodified when a developer toolbox switches frame

View file

@ -291,23 +291,6 @@ class WebConsoleFront extends FrontClassWithSpec(webconsoleSpec) {
return this._client.request(packet, onResponse);
}
/**
* Start the given Web Console listeners.
* TODO: remove once the front is retrieved via getFront, and we use form()
*
* @see this.LISTENERS
* @param array listeners
* Array of listeners you want to start. See this.LISTENERS for
* known listeners.
* @return request
* Request object that implements both Promise and EventEmitter interfaces
*/
async startListeners(listeners) {
const response = await super.startListeners(listeners);
this.hasNativeConsoleAPI = response.nativeConsoleAPI;
return response;
}
/**
* Close the WebConsoleFront.
*

View file

@ -283,7 +283,6 @@ skip-if = win10_2004 # Bug 1723573
[browser_net_ws-clear.js]
[browser_net_ws-connection-closed.js]
[browser_net_ws-early-connection.js]
skip-if = socketprocess_networking
[browser_net_ws-filter-dropdown.js]
[browser_net_ws-filter-regex.js]
[browser_net_ws-json-action-cable-payload.js]
@ -296,5 +295,4 @@ skip-if = socketprocess_networking
[browser_net_ws-sse-persist-columns.js]
[browser_net_ws-stomp-payload.js]
[browser_net-ws-filter-freetext.js]
skip-if = socketprocess_networking
[browser_net_image_cache.js]

View file

@ -23,7 +23,7 @@ const TEST_IMAGE =
"test/test-image.png";
add_task(async function() {
// Needed for the execute() function below
// Needed for the execute() call in `testMessages`.
await pushPref("security.allow_parent_unrestricted_js_loads", true);
await pushPref("devtools.browserconsole.contentMessages", true);
const tab = await addTab(TEST_URI);
@ -48,12 +48,31 @@ async function testMessages() {
const opened = waitForBrowserConsole();
let hud = BrowserConsoleManager.getBrowserConsole();
ok(!hud, "browser console is not open");
// The test harness does override the global's console property to replace it with
// a Console.jsm instance (https://searchfox.org/mozilla-central/rev/618f9970972adc5a21194d39d690ec0865f26024/testing/mochitest/api.js#75-80)
// So here we reset the console property with the native console (which is luckily
// stored in `nativeConsole`).
const overriddenConsole = globalThis.console;
globalThis.console = globalThis.nativeConsole;
info("wait for the browser console to open with ctrl-shift-j");
EventUtils.synthesizeKey("j", { accelKey: true, shiftKey: true }, window);
hud = await opened;
ok(hud, "browser console opened");
info("Check that we don't display the non-native console API warning");
// Wait a bit to let room for the message to be displayed
await wait(1000);
is(
findMessage(hud, "The Web Console logging API", ".warn"),
undefined,
"The message about disabled console API is not displayed"
);
// Set the overidden console back.
globalThis.console = overriddenConsole;
await clearOutput(hud);
await setFilterState(hud, {

View file

@ -132,7 +132,7 @@ const App = React.createClass({
If you are using something like Redux to manage state this is handled
automatically for you with the library you use to bind Redux with
React. See more in [Redux](redux.html).
React. See more in [Redux](redux.md).
## DOM Diffing
@ -154,4 +154,4 @@ just make sure the virtual DOM has what it should.
## Next
Read the [React Guidelines](react-guidelines.md) next to learn how to
write React code specifically for the devtools.
write React code specifically for the devtools.

View file

@ -5,7 +5,7 @@ concepts, so go read them.
# Quick Intro
Just like the [React introduction](react.html), this is a quick
Just like the [React introduction](react.md), this is a quick
introduction to redux, focusing on how it fits into React and why we
chose it.
@ -157,4 +157,4 @@ rendered with react.
## Next
Read the [Redux Guidelines](redux-guidelines.md) next to learn how to
write React code specifically for the devtools.
write React code specifically for the devtools.

View file

@ -304,7 +304,7 @@ Notes:
The code for the tabs uses their ids to automatically report telemetry when you switch between panels, so you don't need to explicitly call `toolOpened` and `toolClosed` on top level panels.
You will still need to call those functions on subpanels, or tools such as about:debugging which are not opened as tabs.
You will still need to call those functions on subpanels, or tools such as `about:debugging` which are not opened as tabs.
#### Testing
@ -426,7 +426,7 @@ Click [here](https://wiki.mozilla.org/Firefox/Data_Collection#Requesting_Data_Co
### Local data
Go to [about:telemetry](about:telemetry) to see stats relating to your local instance.
Go to `about:telemetry` to see stats relating to your local instance.
### Global data

View file

@ -39,7 +39,7 @@ Create a new profile, and name it `development`. Then start Firefox by clicking
Next time you start Firefox with `./mach run -P development`, the new profile will be automatically used, and settings will persist between browser launches.
It's now time to [start contributing](../contributing.html)! 😃
It's now time to [start contributing](../contributing.md)! 😃
---

View file

@ -1,6 +1,6 @@
# Writing new DAMP performance tests
See [DAMP Performance tests](performance-tests.md) for an overall description of our performance tests.
See [DAMP Performance tests](performance-tests-damp.md) for an overall description of our performance tests.
Here, we will describe how to write a new test and register it to run in DAMP.
```note::
@ -16,8 +16,8 @@ Here, we will describe how to write a new test and register it to run in DAMP.
```
This page contains the general documentation for writing DAMP tests. See also:
- [Performance test writing example](./writing-perf-tests-example.html) for a practical example of creating a new test
- [Performance test writing tips](./writing-perf-tests-tips.html) for detailed tips on how to write a good and efficient test
- [Performance test writing example](writing-perf-tests-example.md) for a practical example of creating a new test
- [Performance test writing tips](writing-perf-tests-tips.md) for detailed tips on how to write a good and efficient test
## Test location

View file

@ -17,7 +17,7 @@ But there can be a wide variety of highlighters. In particular, highlighters are
## Using highlighters
Highlighters run on the debuggee side, not on the toolbox side. This is so that it's possible to highlight elements on a remote device for instance. This means you need to go through the [Remote Debugging Protocol](protocol.md) to use a highlighter.
Highlighters run on the debuggee side, not on the toolbox side. This is so that it's possible to highlight elements on a remote device for instance. This means you need to go through the [Remote Debugging Protocol](../backend/protocol.md) to use a highlighter.
The InspectorFront provides the following method:

View file

@ -22,14 +22,16 @@ The memory tool is built of three main elements:
Unlike other tools (such as the JavaScript debugger), the memory tool makes very
little use of the Remote DevTools Server and the actors that reside in it. Use
of the [`MemoryActor`](devtools/server/actors/memory.js) is limited to toggling
allocation stack recording on and off, and transferring heap snapshots from the
debuggee (which is on the server) to the `HeapAnalysesWorker` (which is on the
client). A nice benefit that naturally emerges, is that supporting "legacy"
servers (eg, using Firefox Developer Edition as a client to remote debug a
release Firefox for Android server) is a no-op. As we add new analyses, we can
run them on snapshots taken on old servers no problem. The only requirement is
that changes to the snapshot format itself remain backwards compatible.
of the
[`MemoryActor`](https://searchfox.org/mozilla-central/source/devtools/server/actors/memory.js)
is limited to toggling allocation stack recording on and off, and transferring
heap snapshots from the debuggee (which is on the server) to the
`HeapAnalysesWorker` (which is on the client). A nice benefit that naturally
emerges, is that supporting "legacy" servers (eg, using Firefox Developer
Edition as a client to remote debug a release Firefox for Android server) is a
no-op. As we add new analyses, we can run them on snapshots taken on old servers
no problem. The only requirement is that changes to the snapshot format itself
remain backwards compatible.
## `JS::ubi::Node`
@ -103,9 +105,9 @@ The `DeserializedNode` and `DeserializedEdge` classes implement the
than the live heap graph operate on these classes (unknowingly, of course).
For more details, see the
[`mozilla::devtools::HeapSnapshot`](devtools/shared/heapsnapshot/HeapSnapshot.cpp)
[`mozilla::devtools::HeapSnapshot`](https://searchfox.org/mozilla-central/source/devtools/shared/heapsnapshot/HeapSnapshot.cpp)
and
[`mozilla::devtools::Deserialized{Node,Edge}`](devtools/shared/heapsnapshot/DeserializedNode.h)
[`mozilla::devtools::Deserialized{Node,Edge}`](https://searchfox.org/mozilla-central/source/devtools/shared/heapsnapshot/DeserializedNode.h)
classes.
### Heap Analyses
@ -114,14 +116,15 @@ Heap analyses operate on `JS::ubi::Node` graphs without knowledge of whether
that graph is backed by the live heap graph or an offline heap snapshot. They
must make sure never to allocate GC things or modify the live heap graph.
In general, analyses are implemented in their own `js/public/Ubi{AnalysisName}.h`
header (eg `js/public/UbiCensus.h`), and are exposed to chrome JavaScript code
via a method on the [`HeapSnapshot`](dom/webidl/HeapSnapshot.webidl) webidl
interface.
In general, analyses are implemented in their own
`js/public/Ubi{AnalysisName}.h` header (eg `js/public/UbiCensus.h`), and are
exposed to chrome JavaScript code via a method on the
[`HeapSnapshot`](https://searchfox.org/mozilla-central/source/dom/webidl/HeapSnapshot.webidl)
webidl interface.
For each analysis we expose to chrome JavaScript on the `HeapSnapshot` webidl
interface, there is a small amount of glue code in Gecko. The
[`mozilla::devtools::HeapSnapshot`](devtools/shared/heapsnapshot/HeapSnapshot.h)
[`mozilla::devtools::HeapSnapshot`](https://searchfox.org/mozilla-central/source/devtools/shared/heapsnapshot/HeapSnapshot.h)
C++ class implements the webidl interface. The analyses methods (eg
`ComputeDominatorTree`) take the deserialized nodes and edges from the heap
snapshot, create `JS::ubi::Node`s from them, call the analyses from
@ -129,7 +132,8 @@ snapshot, create `JS::ubi::Node`s from them, call the analyses from
JavaScript.
For API documentation on running specific analyses, see the
[`HeapSnapshot`](dom/webidl/HeapSnapshot.webidl) webidl interface.
[`HeapSnapshot`](https://searchfox.org/mozilla-central/source/dom/webidl/HeapSnapshot.webidl)
webidl interface.
### Testing `JS::ubi::Node`, Snapshots, and Analyses

View file

@ -107,12 +107,11 @@ The reply is:
"NetworkActivity",
"FileActivity"
],
"nativeConsoleAPI": true,
"from": "conn0.console9"
}
The reply tells which listeners were started and it includes a flag ``nativeConsoleAPI`` which tells if the ``window.console`` object was overridden by the scripts in the page or not.
The reply tells which listeners were started.
Tab navigation
@ -133,11 +132,10 @@ When page navigation starts the following packet is sent from the tab actor:
"type": "tabNavigated",
"state": "start",
"url": newURL,
"nativeConsoleAPI": true
}
The ``nativeConsoleAPI`` property tells if the ``window.console`` object is native or not for the top level window object for the given tab - this is always ``true`` when navigation starts. When navigation stops the following packet is sent:
When navigation stops the following packet is sent:
.. code-block::
@ -147,7 +145,6 @@ The ``nativeConsoleAPI`` property tells if the ``window.console`` object is nati
"state": "stop",
"url": newURL,
"title": newTitle,
"nativeConsoleAPI": true|false
}

View file

@ -4,8 +4,6 @@
"use strict";
/* global XPCNativeWrapper */
// protocol.js uses objects as exceptions in order to define
// error packets.
/* eslint-disable no-throw-literal */
@ -159,9 +157,6 @@ const windowGlobalTargetPrototype = {
* This event contains the following attributes:
* * url (string)
* The new URI being loaded.
* * nativeConsoleAPI (boolean)
* `false` if the console API of the page has been overridden (e.g. by Firebug)
* `true` if the Gecko implementation is used
* * state (string)
* `start` if we just start requesting the new URL
* `stop` if the new URL is done loading
@ -1535,7 +1530,6 @@ const windowGlobalTargetPrototype = {
if (!this.followWindowGlobalLifeCycle) {
this.emit("tabNavigated", {
url: newURI,
nativeConsoleAPI: true,
state: "start",
isFrameSwitching,
});
@ -1586,34 +1580,11 @@ const windowGlobalTargetPrototype = {
this.emit("tabNavigated", {
url: this.url,
title: this.title,
nativeConsoleAPI: this.hasNativeConsoleAPI(this.window),
state: "stop",
isFrameSwitching: isFrameSwitching,
});
},
/**
* Tells if the window.console object is native or overwritten by script in
* the page.
*
* @param nsIDOMWindow window
* The window object you want to check.
* @return boolean
* True if the window.console object is native, or false otherwise.
*/
hasNativeConsoleAPI(window) {
let isNative = false;
try {
// We are very explicitly examining the "console" property of
// the non-Xrayed object here.
const console = window.wrappedJSObject.console;
isNative = new XPCNativeWrapper(console).IS_NATIVE_CONSOLE;
} catch (ex) {
// ignore
}
return isNative;
},
/**
* Create or return the StyleSheetActor for a style sheet. This method
* is here because the Style Editor and Inspector share style sheet actors.

View file

@ -4,7 +4,6 @@
"use strict";
/* global XPCNativeWrapper */
const { ActorClassWithSpec, Actor } = require("devtools/shared/protocol");
const { webconsoleSpec } = require("devtools/shared/specs/webconsole");
@ -377,28 +376,6 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
return { actor: this.actorID };
},
hasNativeConsoleAPI: function(window) {
if (isWorker || !(window instanceof Ci.nsIDOMWindow)) {
// We can only use XPCNativeWrapper on non-worker nsIDOMWindow.
return true;
}
let isNative = false;
try {
// We are very explicitly examining the "console" property of
// the non-Xrayed object here.
const console = window.wrappedJSObject.console;
// In xpcshell tests, console ends up being undefined and XPCNativeWrapper
// crashes in debug builds.
if (console) {
isNative = new XPCNativeWrapper(console).IS_NATIVE_CONSOLE;
}
} catch (ex) {
// ignored
}
return isNative;
},
_findProtoChain: ThreadActor.prototype._findProtoChain,
_removeFromProtoChain: ThreadActor.prototype._removeFromProtoChain,
@ -789,8 +766,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
startedListeners.forEach(this._listeners.add, this._listeners);
return {
startedListeners: startedListeners,
nativeConsoleAPI: this.hasNativeConsoleAPI(this.global),
startedListeners,
};
},
@ -1818,8 +1794,11 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
* - dom-complete
* @param {Number} time
* The time that the event is fired.
* @param {Boolean} hasNativeConsoleAPI
* Tells if the window.console object is native or overwritten by script in the page.
* Only passed when `name` is "dom-complete" (see devtools/server/actors/webconsole/listeners/document-events.js).
*/
onDocumentEvent: function(name, { time }) {
onDocumentEvent: function(name, { time, hasNativeConsoleAPI }) {
// will-navigate event has been added in Fx91 and is only expected to be used
// by DOCUMENT_EVENT watcher. For toolbox still not using watcher actor and DOCUMENT_EVENT watcher
// will-navigate will be emitted based on target actor's will-navigate events.
@ -1829,6 +1808,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
this.emit("documentEvent", {
name,
time,
hasNativeConsoleAPI,
});
},

View file

@ -242,14 +242,27 @@ class DevToolsFrameChild extends JSWindowActorChild {
// This will destroy the content process one
this._destroyTargetActor(watcherActorID);
// And this will destroy the parent process one
this.sendAsyncMessage("DevToolsFrameChild:destroy", {
actors: [
{
watcherActorID,
form,
},
],
});
try {
this.sendAsyncMessage("DevToolsFrameChild:destroy", {
actors: [
{
watcherActorID,
form,
},
],
});
} catch (e) {
// Ignore exception when the JSWindowActorChild has already been destroyed.
// We often try to emit this message while the WindowGlobal is in the process of being
// destroyed. We eagerly destroy the target actor during reloads,
// just before the WindowGlobal starts destroying, but sendAsyncMessage
// doesn't have time to complete and throws.
if (
!e.message.includes("JSWindowActorChild cannot send at the moment")
) {
throw e;
}
}
});
this._connections.set(watcherActorID, {
connection,

View file

@ -51,7 +51,6 @@ function assertEvent(event, data) {
);
is(data.state, "start", "state is start");
is(data.url, URL2, "url property is correct");
is(data.nativeConsoleAPI, true, "nativeConsoleAPI is correct");
break;
case isE10s ? 5 : 4:
is(
@ -80,7 +79,6 @@ function assertEvent(event, data) {
is(event, "tabNavigated", "Finally, the receive the client event");
is(data.state, "stop", "state is stop");
is(data.url, URL2, "url property is correct");
is(data.nativeConsoleAPI, true, "nativeConsoleAPI is correct");
signalAllEventsReceived();
break;

View file

@ -1,7 +1,7 @@
[DEFAULT]
tags = devtools
head = head_dbg.js
skip-if = toolkit == 'android' || socketprocess_networking
skip-if = toolkit == 'android'
firefox-appdir = browser
support-files=

View file

@ -138,7 +138,6 @@ const windowGlobalTargetSpecPrototype = {
type: "tabNavigated",
url: Option(0, "string"),
title: Option(0, "string"),
nativeConsoleAPI: Option(0, "boolean"),
state: Option(0, "string"),
isFrameSwitching: Option(0, "boolean"),
},

View file

@ -14,7 +14,6 @@ const {
types.addDictType("console.startlisteners", {
startedListeners: "array:string",
nativeConsoleAPI: "nullable:boolean",
});
types.addDictType("console.stoplisteners", {
@ -96,6 +95,7 @@ const webconsoleSpecPrototype = {
documentEvent: {
name: Option(0, "string"),
time: Option(0, "string"),
hasNativeConsoleAPI: Option(0, "boolean"),
},
},

View file

@ -23,7 +23,6 @@ async function startTest()
let {state, response} = await attachConsoleToTab(["PageError"]);
is(response.startedListeners.length, 1, "startedListeners.length");
is(response.startedListeners[0], "PageError", "startedListeners: PageError");
ok(response.nativeConsoleAPI, "nativeConsoleAPI");
await closeDebugger(state);
top.console_ = top.console;
@ -36,7 +35,6 @@ async function startTest()
isnot(startedListeners.indexOf("ConsoleAPI"), -1,
"startedListeners: ConsoleAPI");
is(startedListeners.indexOf("foo"), -1, "startedListeners: no foo");
ok(!response.nativeConsoleAPI, "!nativeConsoleAPI");
top.console = top.console_;
response = await state.webConsoleFront.stopListeners(["ConsoleAPI", "foo"]);
@ -48,7 +46,6 @@ async function startTest()
is(response.startedListeners.length, 1, "startedListeners.length");
is(response.startedListeners[0], "ConsoleAPI", "startedListeners: ConsoleAPI");
ok(response.nativeConsoleAPI, "nativeConsoleAPI");
top.console = top.console_;
delete top.console_;

View file

@ -908,8 +908,6 @@ DevToolsStartup.prototype = {
k.setAttribute("modifiers", mod);
}
// Bug 371900: command event is fired only if "oncommand" attribute is set.
k.setAttribute("oncommand", ";");
k.addEventListener("command", oncommand);
return k;

View file

@ -93,3 +93,5 @@ redirects:
tools/static-analysis/index.html: code-quality/static-analysis.html
xpcom/xpcom: xpcom
fatal warnings:
- "WARNING: '([^']*)' reference target not found:"

View file

@ -5,9 +5,8 @@ asynchronous and massively parallel architecture.
## Tools
PIX - Can do timing of Direct3D calls. Works reasonably well with
Firefox. See also [Debugging With
PIX](/en/Debugging_With_PIX "en/Debugging With PIX").
[PIX](https://devblogs.microsoft.com/pix/introduction/) - Can do
timing of Direct3D calls. Works reasonably well with Firefox.
NVIDIA PerfHUD - Last I checked required a special build to be used.

View file

@ -15,7 +15,7 @@ degree):
- [Talos](https://wiki.mozilla.org/TestEngineering/Performance/Talos): The main
performance system, run on virtually every check-in to an
integration branch
- [build_metrics](/setup/configuring_build_options.html):
- [build_metrics](/setup/configuring_build_options.rst):
A grab bag of performance metrics generated by the build system
- [AreWeFastYet](https://arewefastyet.com/): A generic JavaScript and
Web benchmarking system

View file

@ -5,8 +5,7 @@ be used to profile wakeups. This article provides a light introduction
to it.
:::
**Note**: The [power profiling
overview](/en-US/docs/Mozilla/Performance/Power_profiling_overview) is
**Note**: The [power profiling overview](power_profiling_overview.md) is
worth reading at this point if you haven't already. It may make parts
of this document easier to understand.
:::
@ -16,7 +15,7 @@ of this document easier to understand.
`dtrace` must be invoked as the super-user. A good starting command for
profiling wakeups is the following.
```
```
sudo dtrace -n 'mach_kernel::wakeup { @[ustack()] = count(); }' -p $FIREFOX_PID > $OUTPUT_FILE
```

View file

@ -2,13 +2,13 @@
This page explains how optimize the performance the Firefox code base
The [test documentation](../../testing/perfdocs/)
explains how to test for performance in Firefox.
The [profiler documentation](../../tools/profiler/)
explains how to use the Gecko profiler.
The [test documentation](/testing/perfdocs/index.rst)
explains how to test for performance in Firefox.
The [profiler documentation](/tools/profiler/index.rst)
explains how to use the Gecko profiler.
## General Performance references
* Tips on generating valid performance metrics by [benchmarking](benchmarking.md)
* Tips on generating valid performance metrics by [benchmarking](Benchmarking.md)
* [GPU Performance](GPU_performance.md) Tips for reducing impacts on browser performance in front-end code.
* [Automated Performance testing and Sheriffing](automated_performance_testing_and_sheriffing.md) Information on automated performance testing and sheriffing at Mozilla.
* [Performance best practices for Firefox front-end engineers](bestpractices.md) Tips for reducing impacts on browser performance in front-end code.

View file

@ -12,7 +12,7 @@ of this document easier to understand.
## Invocation
First, do a [standard build of Firefox](../setup/index.html).
First, do a [standard build of Firefox](/setup/index.rst).
### Mac

View file

@ -2,8 +2,8 @@
This page explains how to test and debug Rust code in Firefox.
The [build documentation](../build/buildsystem/rust.html) explains how to add
new Rust code to Firefox. The [code documentation](../writing-rust-code)
The [build documentation](/build/buildsystem/rust.rst) explains how to add
new Rust code to Firefox. The [code documentation](/writing-rust-code/index.md)
explains how to write and work with Rust code in Firefox.
## Testing Mozilla crates
@ -31,7 +31,7 @@ It's also possible to use `RUST_TESTS` in a different `moz.build` file. See
`testing/geckodriver/moz.build` and the [geckodriver testing docs] for an
example.
[geckodriver testing docs]: ../testing/geckodriver/Testing.html
[geckodriver testing docs]: /testing/geckodriver/Testing.md
### GTests
@ -102,7 +102,7 @@ To restrict logging to child processes, use `RUST_LOG_CHILD` instead of
Rust logging can also be forwarded to the [Gecko logger] for capture via
`MOZ_LOG` and `MOZ_LOG_FILE`.
[Gecko logger]: /xpcom/logging.html
[Gecko logger]: /xpcom/logging.rst
- When parsing modules from `MOZ_LOG`, modules containing `::` are considered
to be Rust modules. To log everything in a top-level module like

View file

@ -3,8 +3,8 @@
This page explains how to write and work with Rust code in Firefox, with an
emphasis on interoperation with C++ code.
The [build documentation](../build/buildsystem/rust.html) explains how to add
new Rust code to Firefox. The [test documentation](../testing-rust-code)
The [build documentation](/build/buildsystem/rust.rst) explains how to add
new Rust code to Firefox. The [test documentation](/testing-rust-code/index.md)
explains how to test and debug Rust code in Firefox.
```{toctree}

View file

@ -21,7 +21,7 @@ xpcom = { path = "../../../xpcom/rust/xpcom" }
file hierarchy.)
Next hook it into the build system according to the [build
documentation](../build/buildsystem/rust.html).
documentation](/build/buildsystem/rust.rst).
The Rust code will need to import some basic types. `xpcom::interfaces`
contains all the usual `nsI` interfaces.
@ -33,7 +33,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use xpcom::{interfaces::nsISupports, RefPtr};
```
The next part declares the implementation.
The next part declares the implementation.
```rust
#[derive(xpcom)]
@ -110,11 +110,11 @@ The following XPCOM components are written in Rust.
- [bookmark_sync](https://searchfox.org/mozilla-central/source/toolkit/components/places/bookmark_sync),
which [merges](https://mozilla.github.io/dogear) bookmarks from Firefox Sync
with bookmarks in the Places database.
[There's also some docs on how Rust interacts with Sync](../services/sync/rust-engines.html)
[There's also some docs on how Rust interacts with Sync](/services/sync/rust-engines.rst)
- [webext_storage_bridge](https://searchfox.org/mozilla-central/source/toolkit/components/extensions/storage/webext_storage_bridge),
which powers the WebExtension storage.sync API. It's a self-contained example
that pulls in a crate from application-services for the heavy lifting, wraps
that up in a Rust XPCOM component, and then wraps the component in a JS
interface. There's also some boilerplate there around adding a
`components.conf` file, and a dummy C++ header that declares the component
constructor. [It has some in-depth documentation on how it hangs together](../toolkit/components/extensions/webextensions/webext-storage.html).
constructor. [It has some in-depth documentation on how it hangs together](../toolkit/components/extensions/webextensions/webext-storage.rst).

View file

@ -287,7 +287,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void SetRestoreData(SessionStoreRestoreData* aData, ErrorResult& aError);
void ClearRestoreState();
void RequestRestoreTabContent(WindowGlobalParent* aWindow);
MOZ_CAN_RUN_SCRIPT_BOUNDARY void RequestRestoreTabContent(
WindowGlobalParent* aWindow);
already_AddRefed<Promise> GetRestorePromise();
nsresult WriteSessionStorageToSessionStore(

View file

@ -315,7 +315,10 @@ bool CCGCScheduler::GCRunnerFiredDoGC(TimeStamp aDeadline,
if (!aDeadline.IsNull()) {
if (aDeadline < now) {
// This slice overflowed the idle period.
idleDuration = aDeadline - startTimeStamp;
if (aDeadline > startTimeStamp) {
idleDuration = aDeadline - startTimeStamp;
}
// Otherwise the whole slice was done outside the idle period.
} else {
// Note, we don't want to use duration here, since it may contain
// data also from JS engine triggered GC slices.

View file

@ -2051,6 +2051,7 @@ already_AddRefed<EventSource> EventSource::Constructor(
}
eventSource->mReadyState = EventSourceImpl::CONNECTING;
guardESImpl.release();
return eventSource.forget();
}

View file

@ -80,7 +80,10 @@ support-files =
file_bug1700871.html
[browser_inputStream_structuredClone.js]
[browser_multiple_popups.js]
skip-if = (os == 'win' && !debug) || (os == "mac" && !debug) # Bug 1505235, Bug 1661132 (osx)
skip-if =
(os == 'win' && !debug)
(os == "mac" && !debug) # Bug 1505235, Bug 1661132 (osx)
socketprocess_networking
support-files = browser_multiple_popups.html
[browser_bug1554070.js]
support-files =

View file

@ -93,8 +93,7 @@ static std::string ChooseDeviceReplacement(const std::string& str) {
static const std::string GEFORCE_480 = "GeForce GTX 480";
static const std::string GEFORCE_980 = "GeForce GTX 980";
if (Contains(str, "NVIDIA") ||
Contains(str, "GeForce") ||
if (Contains(str, "NVIDIA") || Contains(str, "GeForce") ||
Contains(str, "Quadro")) {
auto ret = std::invoke([&]() {
static const std::regex kGeForce("GeForce.*?([0-9][0-9][0-9]+)");
@ -276,7 +275,8 @@ static std::string ChooseDeviceReplacement(const std::string& str) {
std::string SanitizeRenderer(const std::string& str) {
std::smatch m;
// e.g. "ANGLE (AMD, AMD Radeon(TM) Graphics Direct3D11 vs_5_0 ps_5_0, D3D11-27.20.1020.2002)"
// e.g. "ANGLE (AMD, AMD Radeon(TM) Graphics Direct3D11 vs_5_0 ps_5_0,
// D3D11-27.20.1020.2002)"
static const std::regex kReAngle(
"ANGLE [(]([^,]*), ([^,]*)( Direct3D[^,]*), .*[)]");
if (std::regex_match(str, m, kReAngle)) {

View file

@ -266,9 +266,7 @@ class UniqueBuffer final {
UniqueBuffer() = default;
~UniqueBuffer() {
reset();
}
~UniqueBuffer() { reset(); }
UniqueBuffer(UniqueBuffer&& rhs) { *this = std::move(rhs); }

View file

@ -202,41 +202,49 @@ TEST(SanitizeRenderer, TestAdreno512)
}
// -
// Keep gtests for our known CI RENDERER strings (see test_renderer_strings.html)
// otherwise the first time we know we messed up is in CI results after an hour,
// instead of after running gtests locally.
// Keep gtests for our known CI RENDERER strings (see
// test_renderer_strings.html) otherwise the first time we know we messed up is
// in CI results after an hour, instead of after running gtests locally.
TEST(SanitizeRenderer, TestCiAndroid) {
TEST(SanitizeRenderer, TestCiAndroid)
{
const std::string renderer("Adreno (TM) 540");
const std::string expectation("Adreno (TM) 540");
const auto sanitized = mozilla::webgl::SanitizeRenderer(renderer);
EXPECT_EQ(sanitized, expectation);
}
TEST(SanitizeRenderer, TestCiLinux) {
TEST(SanitizeRenderer, TestCiLinux)
{
const std::string renderer("llvmpipe (LLVM 10.0.0, 256 bits)");
const std::string expectation("llvmpipe");
const auto sanitized = mozilla::webgl::SanitizeRenderer(renderer);
EXPECT_EQ(sanitized, expectation);
}
TEST(SanitizeRenderer, TestCiMac) {
TEST(SanitizeRenderer, TestCiMac)
{
const std::string renderer("Intel(R) UHD Graphics 630");
const std::string expectation("Intel(R) HD Graphics 400");
const auto sanitized = mozilla::webgl::SanitizeRenderer(renderer);
EXPECT_EQ(sanitized, expectation);
}
TEST(SanitizeRenderer, TestCiMac2) {
TEST(SanitizeRenderer, TestCiMac2)
{
const std::string renderer("Apple M1");
const std::string expectation("Apple M1");
const auto sanitized = mozilla::webgl::SanitizeRenderer(renderer);
EXPECT_EQ(sanitized, expectation);
}
TEST(SanitizeRenderer, TestCiWindows) {
const std::string renderer("ANGLE (NVIDIA, NVIDIA Tesla M60 Direct3D11 vs_5_0 ps_5_0, D3D11-23.21.13.9181)");
const std::string expectation("ANGLE (NVIDIA, NVIDIA GeForce 8800 GTX Direct3D11 vs_5_0 ps_5_0)");
TEST(SanitizeRenderer, TestCiWindows)
{
const std::string renderer(
"ANGLE (NVIDIA, NVIDIA Tesla M60 Direct3D11 vs_5_0 ps_5_0, "
"D3D11-23.21.13.9181)");
const std::string expectation(
"ANGLE (NVIDIA, NVIDIA GeForce 8800 GTX Direct3D11 vs_5_0 ps_5_0)");
const auto sanitized = mozilla::webgl::SanitizeRenderer(renderer);
EXPECT_EQ(sanitized, expectation);
}

View file

@ -1361,7 +1361,7 @@ Multiple `[Alias]` extended attribute can be used on the one method.
global interface (such as `Window`).
Aside from regular property names, the name of an alias can be
[Symbol.iterator](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Well-known_symbols).
[Symbol.iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator).
This is specified by writing `[Alias="@@iterator"]`.
### `[BindingAlias=propName]`
@ -1757,7 +1757,7 @@ the cached value.
### `[Frozen]`
Used to flag attributes that, when their getter is called, will call
[`Object.freeze`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
[`Object.freeze`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
on the return value before returning it. This extended attribute is only
allowed on attributes that return sequences, dictionaries and
`MozMap`, and corresponds to returning a frozen `Array` (for the
@ -2184,15 +2184,13 @@ interface MyNumber {
};
```
Next, create an XPCOM component that implements this interface. [Basic
directions](/en-US/docs/How_to_Build_an_XPCOM_Component_in_Javascript)
for how to do this can be found elsewhere on MDN. Use the same contract
ID as you specified in the Web IDL file. The class ID doesn't matter,
except that it should be a newly generated one. For `QueryInterface`,
you only need to implement `nsISupports`, not anything corresponding
to the Web IDL interface. The name you use for the XPCOM component should
be distinct from the name of the interface, to avoid confusing error
messages.
Next, create an XPCOM component that implements this interface. Use
the same contract ID as you specified in the Web IDL file. The class
ID doesn't matter, except that it should be a newly generated one. For
`QueryInterface`, you only need to implement `nsISupports`, not
anything corresponding to the Web IDL interface. The name you use for
the XPCOM component should be distinct from the name of the interface,
to avoid confusing error messages.
Web IDL attributes are implemented as properties on the JS object or its
prototype chain, whereas Web IDL methods are implemented as methods on

View file

@ -584,8 +584,13 @@ bool XULKeySetGlobalKeyListener::IsExecutableElement(
return false;
}
aElement->GetAttr(nsGkAtoms::oncommand, value);
return !value.IsEmpty();
// Internal keys are defined as <key> elements so that the menu label
// and disabled state can be updated properly, but the command is executed
// by some other means. This will typically be because the key is defined
// as a shortcut defined in ShortcutKeyDefinitions.cpp instead, or on Mac,
// some special system defined keys.
return !aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::internal,
nsGkAtoms::_true, eCaseMatters);
}
already_AddRefed<dom::EventTarget> XULKeySetGlobalKeyListener::GetHandlerTarget(

View file

@ -466,7 +466,6 @@ nsresult HTMLCanvasElement::DispatchPrintCallback(nsITimerCallback* aCallback) {
return OwnerDoc()->Dispatch(TaskCategory::Other, renderEvent.forget());
}
MOZ_CAN_RUN_SCRIPT
void HTMLCanvasElement::CallPrintCallback() {
if (!mPrintState) {
// `mPrintState` might have been destroyed by cancelling the previous

View file

@ -334,7 +334,7 @@ class HTMLCanvasElement final : public nsGenericHTMLElement,
const JS::Value& aEncoderOptions, nsAString& aDataURL);
nsresult MozGetAsFileImpl(const nsAString& aName, const nsAString& aType,
nsIPrincipal& aSubjectPrincipal, File** aResult);
void CallPrintCallback();
MOZ_CAN_RUN_SCRIPT void CallPrintCallback();
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
const nsAttrValue* aValue,

View file

@ -1561,7 +1561,7 @@ Decimal HTMLInputElement::StringToDecimal(const nsAString& aValue) {
return Decimal::nan();
}
NS_LossyConvertUTF16toASCII asciiString(aValue);
std::string stdString = asciiString.get();
std::string stdString(asciiString.get(), asciiString.Length());
return Decimal::fromString(stdString);
}

View file

@ -95,12 +95,7 @@ nsresult NumericInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
bool NumericInputTypeBase::ConvertStringToNumber(nsAString& aValue,
Decimal& aResultValue) const {
ICUUtils::LanguageTagIterForContent langTagIter(mInputElement);
aResultValue =
Decimal::fromDouble(ICUUtils::ParseNumber(aValue, langTagIter));
if (!aResultValue.isFinite()) {
aResultValue = HTMLInputElement::StringToDecimal(aValue);
}
aResultValue = HTMLInputElement::StringToDecimal(aValue);
return aResultValue.isFinite();
}
@ -138,6 +133,17 @@ bool NumberInputType::HasBadInput() const {
return !value.IsEmpty() && mInputElement->GetValueAsDecimal().isNaN();
}
bool NumberInputType::ConvertStringToNumber(nsAString& aValue,
Decimal& aResultValue) const {
ICUUtils::LanguageTagIterForContent langTagIter(mInputElement);
aResultValue =
Decimal::fromDouble(ICUUtils::ParseNumber(aValue, langTagIter));
if (aResultValue.isFinite()) {
return true;
}
return NumericInputTypeBase::ConvertStringToNumber(aValue, aResultValue);
}
bool NumberInputType::ConvertNumberToString(Decimal aValue,
nsAString& aResultString) const {
MOZ_ASSERT(aValue.isFinite(), "aValue must be a valid non-Infinite number.");

View file

@ -46,6 +46,8 @@ class NumberInputType final : public NumericInputTypeBase {
nsresult GetValueMissingMessage(nsAString& aMessage) override;
nsresult GetBadInputMessage(nsAString& aMessage) override;
bool ConvertStringToNumber(nsAString& aValue,
Decimal& aResultValue) const override;
bool ConvertNumberToString(Decimal aValue,
nsAString& aResultString) const override;

View file

@ -311,7 +311,7 @@ bool ClonedErrorHolder::ToErrorValue(JSContext* aCx,
if (mTokenOffset >= sourceLine.Length()) {
// Corrupt data, leave linebuf unset.
} else if (JS::UniqueTwoByteChars buffer =
ToNullTerminatedJSStringBuffer(aCx, sourceLine)) {
ToNullTerminatedJSStringBuffer(aCx, sourceLine)) {
err->initOwnedLinebuf(buffer.release(), sourceLine.Length(),
mTokenOffset);
} else {

View file

@ -187,7 +187,8 @@ class WindowGlobalChild final : public WindowGlobalActor,
const dom::sessionstore::DocShellRestoreState& aState,
RestoreDocShellStateResolver&& aResolve);
mozilla::ipc::IPCResult RecvRestoreTabContent(
// TODO: Use MOZ_CAN_RUN_SCRIPT when it gains IPDL support (bug 1539864)
MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvRestoreTabContent(
dom::SessionStoreRestoreData* aData,
RestoreTabContentResolver&& aResolve);

View file

@ -266,9 +266,8 @@ class AudioInputTrack : public ProcessedMediaTrack {
}
// Get the data in [aFrom, aTo) from aPort->GetSource() to aOutput. aOutput
// needs to be empty.
void GetInputSourceData(AudioSegment& aOutput,
const MediaInputPort* aPort, GraphTime aFrom,
GraphTime aTo) const;
void GetInputSourceData(AudioSegment& aOutput, const MediaInputPort* aPort,
GraphTime aFrom, GraphTime aTo) const;
// Any thread
AudioInputTrack* AsAudioInputTrack() override { return this; }

View file

@ -71,9 +71,12 @@ void MIDIOutput::Send(const Sequence<uint8_t>& aData,
}
nsTArray<MIDIMessage> msgArray;
MIDIUtils::ParseMessages(aData, timestamp, msgArray);
// Our translation of the spec is that invalid messages in a multi-message
// sequence will be thrown out, but that valid messages will still be used.
bool ret = MIDIUtils::ParseMessages(aData, timestamp, msgArray);
if (!ret) {
aRv.ThrowTypeError("Invalid MIDI message");
return;
}
if (msgArray.IsEmpty()) {
aRv.ThrowTypeError("Empty message array");
return;

View file

@ -21,33 +21,65 @@ static const uint8_t kCommandLengths[] = {3, 3, 3, 3, 2, 2, 3};
// messages is variable, so we just put zero since it won't be checked anyways.
// Taken from MIDI Spec v1.0, Pg. 105, Table 5
static const uint8_t kSystemLengths[] = {0, 2, 3, 2, 1, 1, 1, 1};
static const uint8_t kReservedStatuses[] = {0xf4, 0xf5, 0xf9, 0xfd};
namespace mozilla::dom::MIDIUtils {
static bool IsSystemRealtimeMessage(uint8_t aByte) {
return (aByte & kSystemRealtimeMessage) == kSystemRealtimeMessage;
}
static bool IsCommandByte(uint8_t aByte) {
return (aByte & kCommandByte) == kCommandByte;
}
static bool IsReservedStatus(uint8_t aByte) {
for (const auto& msg : kReservedStatuses) {
if (aByte == msg) {
return true;
}
}
return false;
}
// Checks validity of MIDIMessage passed to it. Throws debug warnings and
// returns false if message is not valid.
bool IsValidMessage(const MIDIMessage* aMsg) {
if (NS_WARN_IF(!aMsg)) {
if (aMsg->data().Length() == 0) {
return false;
}
// Assert on parser problems
MOZ_ASSERT(aMsg->data().Length() > 0,
"Created a MIDI Message of Length 0. This should never happen!");
uint8_t cmd = aMsg->data()[0];
// If first byte isn't a command, something is definitely wrong.
MOZ_ASSERT((cmd & kCommandByte) == kCommandByte,
"Constructed a MIDI packet where first byte is not command!");
if (!IsCommandByte(cmd)) {
NS_WARNING("Constructed a MIDI packet where first byte is not command!");
return false;
}
if (IsReservedStatus(cmd)) {
NS_WARNING("Using a reserved message");
return false;
}
if (cmd == kSysexMessageStart) {
// All we can do with sysex is make sure it starts and ends with the
// correct command bytes.
// All we can do with sysex is make sure it starts and ends with the
// correct command bytes and that it does not contain other command bytes.
if (aMsg->data()[aMsg->data().Length() - 1] != kSysexMessageEnd) {
NS_WARNING("Last byte of Sysex Message not 0xF7!");
return false;
}
for (size_t i = 1; i < aMsg->data().Length() - 2; i++) {
if (IsCommandByte(aMsg->data()[i])) {
return false;
}
}
return true;
}
// For system realtime messages, the length should always be 1.
if ((cmd & kSystemRealtimeMessage) == kSystemRealtimeMessage) {
if (IsSystemRealtimeMessage(cmd)) {
return aMsg->data().Length() == 1;
}
// Otherwise, just use the correct array for testing lengths. We can't tell
@ -72,44 +104,66 @@ bool IsValidMessage(const MIDIMessage* aMsg) {
return aMsg->data().Length() == kCommandLengths[cmdIndex];
}
uint32_t ParseMessages(const nsTArray<uint8_t>& aByteBuffer,
const TimeStamp& aTimestamp,
nsTArray<MIDIMessage>& aMsgArray) {
bool ParseMessages(const nsTArray<uint8_t>& aByteBuffer,
const TimeStamp& aTimestamp,
nsTArray<MIDIMessage>& aMsgArray) {
uint32_t bytesRead = 0;
bool inSysexMessage = false;
UniquePtr<MIDIMessage> currentMsg;
UniquePtr<MIDIMessage> currentMsg = nullptr;
for (const auto& byte : aByteBuffer) {
bytesRead++;
if ((byte & kSystemRealtimeMessage) == kSystemRealtimeMessage) {
if (IsSystemRealtimeMessage(byte)) {
MIDIMessage rt_msg;
rt_msg.data().AppendElement(byte);
rt_msg.timestamp() = aTimestamp;
if (!IsValidMessage(&rt_msg)) {
return false;
}
aMsgArray.AppendElement(rt_msg);
continue;
}
if (byte == kSysexMessageEnd) {
if (!inSysexMessage) {
MOZ_ASSERT(inSysexMessage);
NS_WARNING(
"Got sysex message end with no sysex message being processed!");
return false;
}
inSysexMessage = false;
} else if (byte & kCommandByte) {
if (currentMsg && IsValidMessage(currentMsg.get())) {
} else if (IsCommandByte(byte)) {
if (currentMsg) {
if (!IsValidMessage(currentMsg.get())) {
return false;
}
aMsgArray.AppendElement(*currentMsg);
}
currentMsg = MakeUnique<MIDIMessage>();
currentMsg->timestamp() = aTimestamp;
}
if (!currentMsg) {
NS_WARNING("No command byte has been encountered yet!");
return false;
}
currentMsg->data().AppendElement(byte);
if (byte == kSysexMessageStart) {
inSysexMessage = true;
}
}
if (currentMsg && IsValidMessage(currentMsg.get())) {
if (currentMsg) {
if (!IsValidMessage(currentMsg.get())) {
return false;
}
aMsgArray.AppendElement(*currentMsg);
}
return bytesRead;
return true;
}
bool IsSysexMessage(const MIDIMessage& aMsg) {

View file

@ -17,10 +17,10 @@ class MIDIMessage;
namespace MIDIUtils {
// Takes a nsTArray of bytes and parses it into zero or more MIDI messages.
// Returns number of bytes parsed.
uint32_t ParseMessages(const nsTArray<uint8_t>& aByteBuffer,
const TimeStamp& aTimestamp,
nsTArray<MIDIMessage>& aMsgArray);
// Returns true if no errors were encountered, false otherwise.
bool ParseMessages(const nsTArray<uint8_t>& aByteBuffer,
const TimeStamp& aTimestamp,
nsTArray<MIDIMessage>& aMsgArray);
// Returns true if a message is a sysex message.
bool IsSysexMessage(const MIDIMessage& a);
} // namespace MIDIUtils

View file

@ -107,6 +107,7 @@ void TestMIDIPlatformService::Init() {
MIDIPlatformService::Get()->AddPortInfo(mControlInputPort);
MIDIPlatformService::Get()->AddPortInfo(mControlOutputPort);
MIDIPlatformService::Get()->AddPortInfo(mAlwaysClosedTestOutputPort);
MIDIPlatformService::Get()->AddPortInfo(mStateTestOutputPort);
nsCOMPtr<nsIRunnable> r(new SendPortListRunnable());
// Start the IO Thread.
@ -220,8 +221,8 @@ void TestMIDIPlatformService::ProcessMessages(const nsAString& aPortId) {
// messages.
case 0x01: {
nsTArray<uint8_t> msgs;
const uint8_t msg[] = {0xF0, 0x01, 0xF8, 0x02, 0x03,
0x04, 0xF9, 0x05, 0xF7};
const uint8_t msg[] = {0xF0, 0x01, 0xFA, 0x02, 0x03,
0x04, 0xF8, 0x05, 0xF7};
// Can't use AppendElements on an array here, so just do range
// based loading.
for (const auto& s : msg) {

View file

@ -19,3 +19,4 @@ skip-if = os == 'android' || os == 'linux' || os == 'mac' #Bug 1747637
disabled = Bug 1437204
[test_midi_device_pending.html]
disabled = Bug 1437204
[test_midi_send_messages.html]

View file

@ -31,7 +31,7 @@
var inputs = access.inputs;
var outputs = access.outputs;
is(inputs.size, 1, "Should have one input");
is(outputs.size, 2, "Should have two outputs");
is(outputs.size, 3, "Should have three outputs");
ok(inputs.has(input_id), "input list should contain input id");
ok(outputs.has(output_id), "output list should contain output id");
var input = access.inputs.get(input_id);

View file

@ -18,9 +18,9 @@
function checkReturn(msg) {
checkCount++;
if (checkCount == 1) {
MIDITestUtils.checkPacket(msg.data, [0xF8]);
MIDITestUtils.checkPacket(msg.data, [0xFA]);
} else if (checkCount == 2) {
MIDITestUtils.checkPacket(msg.data, [0xF9]);
MIDITestUtils.checkPacket(msg.data, [0xF8]);
} else if (checkCount == 3) {
MIDITestUtils.checkPacket(msg.data, [0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xF7]);
SimpleTest.finish();

View file

@ -0,0 +1,114 @@
<html>
<head>
<title>WebMIDI Send Test</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="application/javascript" src="MIDITestUtils.js"></script>
</head>
<body onload="runTests()">
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
async function runTests() {
await MIDITestUtils.permissionSetup(true);
const access = await navigator.requestMIDIAccess({ sysex: true });
const output = access.outputs.get(MIDITestUtils.stateTestOutputInfo.id);
dump("output = " + JSON.stringify(output, null, " ") + "\n");
// Note on(off).
output.send([0xff, 0x90, 0x00, 0x00, 0x90, 0x07, 0x00]);
try {
output.send([0x00, 0x01])
} catch (ex) {
dump("Caught exception");
ok(true, "Caught exception");
}
// Running status is not allowed in Web MIDI API.
SimpleTest.doesThrow(() => output.send([0x00, 0x01]), "Running status is not allowed in Web MIDI API.");
// Unexpected End of Sysex.
SimpleTest.doesThrow(() => output.send([0xf7]), "Unexpected End of Sysex.");
// Unexpected reserved status bytes.
SimpleTest.doesThrow(() => output.send([0xf4]), "Unexpected reserved status byte 0xf4.");
SimpleTest.doesThrow(() => output.send([0xf5]), "Unexpected reserved status byte 0xf5.");
SimpleTest.doesThrow(() => output.send([0xf9]), "Unexpected reserved status byte 0xf9.");
SimpleTest.doesThrow(() => output.send([0xfd]), "Unexpected reserved status byte 0xfd.");
// Incomplete channel messages.
SimpleTest.doesThrow(() => output.send([0x80]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0x80, 0x00]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0x90]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0x90, 0x00]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0xa0]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0xa0, 0x00]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0xb0]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0xb0, 0x00]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0xc0]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0xd0]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0xe0]), "Incomplete channel message.");
SimpleTest.doesThrow(() => output.send([0xe0, 0x00]), "Incomplete channel message.");
// Incomplete system messages.
SimpleTest.doesThrow(() => output.send([0xf1]), "Incomplete system message.");
SimpleTest.doesThrow(() => output.send([0xf2]), "Incomplete system message.");
SimpleTest.doesThrow(() => output.send([0xf2, 0x00]), "Incomplete system message.");
SimpleTest.doesThrow(() => output.send([0xf3]), "Incomplete system message.");
// Invalid data bytes.
SimpleTest.doesThrow(() => output.send([0x80, 0x80, 0x00]), "Incomplete system message.");
SimpleTest.doesThrow(() => output.send([0x80, 0x00, 0x80]), "Incomplete system message.");
// Complete messages.
output.send([0x80, 0x00, 0x00]);
output.send([0x90, 0x00, 0x00]);
output.send([0xa0, 0x00, 0x00]);
output.send([0xb0, 0x00, 0x00]);
output.send([0xc0, 0x00]);
output.send([0xd0, 0x00]);
output.send([0xe0, 0x00, 0x00]);
// Real-Time messages.
output.send([0xf8]);
output.send([0xfa]);
output.send([0xfb]);
output.send([0xfc]);
output.send([0xfe]);
output.send([0xff]);
// Valid messages with Real-Time messages.
output.send([0x90, 0xff, 0xff, 0x00, 0xff, 0x01, 0xff, 0x80, 0xff, 0x00,
0xff, 0xff, 0x00, 0xff, 0xff]);
// Sysex messages.
output.send([0xf0, 0x00, 0x01, 0x02, 0x03, 0xf7]);
output.send([0xf0, 0xf8, 0xf7, 0xff]);
SimpleTest.doesThrow(() => output.send([0xf0, 0x80, 0xf7]), "Invalid sysex message.");
SimpleTest.doesThrow(() => output.send([0xf0, 0xf0, 0xf7]), "Double begin sysex message.");
SimpleTest.doesThrow(() => output.send([0xf0, 0xff, 0xf7, 0xf7]), "Double end sysex message.");
// Reserved status bytes.
SimpleTest.doesThrow(() => output.send([0xf4, 0x80, 0x00, 0x00]), "Reserved status byte.");
SimpleTest.doesThrow(() => output.send([0x80, 0xf4, 0x00, 0x00]), "Reserved status byte.");
SimpleTest.doesThrow(() => output.send([0x80, 0x00, 0xf4, 0x00]), "Reserved status byte.");
SimpleTest.doesThrow(() => output.send([0x80, 0x00, 0x00, 0xf4]), "Reserved status byte.");
SimpleTest.doesThrow(() => output.send([0xf0, 0xff, 0xf4, 0xf7]), "Reserved status byte.");
// Invalid timestamps.
SimpleTest.doesThrow(() => output.send([], NaN), "NaN timestamp.");
SimpleTest.doesThrow(() => output.send([], Infinity), "Infinity timestamp.");
SimpleTest.doesThrow(() => output.send(new Uint8Array(), NaN), "NaN timestamp.");
SimpleTest.doesThrow(() => output.send(new Uint8Array(), Infinity), "Infinity timestamp.");
SimpleTest.finish();
}
</script>
</body>
</html>

View file

@ -1383,16 +1383,6 @@ bool nsContentSecurityUtils::ValidateScriptFilename(JSContext* cx,
}
#endif
// If we got here we are going to return false, so set the error context
const char* utf8Filename;
if (mozilla::IsUtf8(mozilla::MakeStringSpan(aFilename))) {
utf8Filename = aFilename;
} else {
utf8Filename = "(invalid UTF-8 filename)";
}
JS_ReportErrorNumberUTF8(cx, js::GetErrorMessage, nullptr,
JSMSG_UNSAFE_FILENAME, utf8Filename);
// Presently we are only enforcing restrictions for the script filename
// on Nightly. On all channels we are reporting Telemetry. In the future we
// will assert in debug builds and return false to prevent execution in

View file

@ -27,7 +27,16 @@ struct ValueWithSize : LinkedListElement<ValueWithSize> {
double mSize = 0.0f;
};
using QueueWithSizes = LinkedList<ValueWithSize>;
// This type is a little tricky lifetime wise: Despite the fact that we're
// talking about linked list of VaueWithSize, what is actually stored in the
// list are dynamically allocated ValueWithSize*. As a result, these have to be
// deleted. There are two ways this lifetime is managed:
//
// 1. In DequeueValue we pop the first element into a UniquePtr, so that it is
// correctly cleaned up at destruction time.
// 2. We use an AutoCleanLinkedList which will delete elements when destroyed
// or `clear`ed.
using QueueWithSizes = AutoCleanLinkedList<ValueWithSize>;
// https://streams.spec.whatwg.org/#is-non-negative-number
inline bool IsNonNegativeNumber(double v) {
@ -59,7 +68,8 @@ inline void EnqueueValueWithSize(QueueContainingClass aContainer,
return;
}
// Step 4.
// Step 4. See the comment on QueueWithSizes for the lifetime reasoning
// around this allocation.
ValueWithSize* valueWithSize = new ValueWithSize(aValue, aSize);
aContainer->Queue().insertBack(valueWithSize);
// Step 5.

View file

@ -485,7 +485,7 @@ var interfaceNamesInGlobalScope = [
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "HTMLDetailsElement", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "HTMLDialogElement", insecureContext: true, nightly: true },
{ name: "HTMLDialogElement", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "HTMLDirectoryElement", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!

View file

@ -65,7 +65,6 @@
#include "nsXPCOMPrivate.h"
#include "OSFileConstants.h"
#include "xpcpublic.h"
#include "XPCPrefableContextOptions.h"
#include "XPCSelfHostedShmem.h"
#if defined(XP_MACOSX)
@ -132,9 +131,8 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
// Prefixes for observing preference changes.
#define PREF_JS_OPTIONS_PREFIX "javascript.options."
#define PREF_WORKERS_OPTIONS_PREFIX PREF_WORKERS_PREFIX "options."
#define PREF_MEM_OPTIONS_PREFIX "mem."
#define PREF_GCZEAL "gcZeal"
#define PREF_GCZEAL "gczeal"
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
@ -165,8 +163,6 @@ template <>
struct PrefTraits<bool> {
using PrefValueType = bool;
static const PrefValueType kDefaultValue = false;
static inline PrefValueType Get(const char* aPref) {
AssertIsOnMainThread();
return Preferences::GetBool(aPref);
@ -194,9 +190,7 @@ struct PrefTraits<int32_t> {
};
template <typename T>
T GetWorkerPref(const nsACString& aPref,
const T aDefault = PrefTraits<T>::kDefaultValue,
bool* aPresent = nullptr) {
T GetPref(const char* aFullPref, const T aDefault, bool* aPresent = nullptr) {
AssertIsOnMainThread();
using PrefHelper = PrefTraits<T>;
@ -204,22 +198,11 @@ T GetWorkerPref(const nsACString& aPref,
T result;
bool present = true;
nsAutoCString prefName;
prefName.AssignLiteral(PREF_WORKERS_OPTIONS_PREFIX);
prefName.Append(aPref);
if (PrefHelper::Exists(prefName.get())) {
result = PrefHelper::Get(prefName.get());
if (PrefHelper::Exists(aFullPref)) {
result = PrefHelper::Get(aFullPref);
} else {
prefName.AssignLiteral(PREF_JS_OPTIONS_PREFIX);
prefName.Append(aPref);
if (PrefHelper::Exists(prefName.get())) {
result = PrefHelper::Get(prefName.get());
} else {
result = aDefault;
present = false;
}
result = aDefault;
present = false;
}
if (aPresent) {
@ -228,23 +211,6 @@ T GetWorkerPref(const nsACString& aPref,
return result;
}
// Optimized version for bool that receives already-concatenated pref names.
//
// Used by xpc::SetPrefableContextOptions.
bool GetWorkerBoolPref(const char* jsPref, const char* workerPref) {
using PrefHelper = PrefTraits<bool>;
if (PrefHelper::Exists(workerPref)) {
return PrefHelper::Get(workerPref);
}
if (PrefHelper::Exists(jsPref)) {
return PrefHelper::Get(jsPref);
}
return PrefHelper::kDefaultValue;
}
void LoadContextOptions(const char* aPrefName, void* /* aClosure */) {
AssertIsOnMainThread();
@ -260,22 +226,18 @@ void LoadContextOptions(const char* aPrefName, void* /* aClosure */) {
// another callback that will handle this change.
if (StringBeginsWith(
prefName,
nsLiteralCString(PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX)) ||
StringBeginsWith(
prefName, nsLiteralCString(
PREF_WORKERS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX))) {
nsLiteralCString(PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX))) {
return;
}
#ifdef JS_GC_ZEAL
if (prefName.EqualsLiteral(PREF_JS_OPTIONS_PREFIX PREF_GCZEAL) ||
prefName.EqualsLiteral(PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL)) {
if (prefName.EqualsLiteral(PREF_JS_OPTIONS_PREFIX PREF_GCZEAL)) {
return;
}
#endif
JS::ContextOptions contextOptions;
xpc::SetPrefableContextOptions(contextOptions, GetWorkerBoolPref);
xpc::SetPrefableContextOptions(contextOptions);
nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
if (xr) {
@ -303,12 +265,13 @@ void LoadGCZealOptions(const char* /* aPrefName */, void* /* aClosure */) {
return;
}
int32_t gczeal = GetWorkerPref<int32_t>(nsLiteralCString(PREF_GCZEAL), -1);
int32_t gczeal = GetPref<int32_t>(PREF_JS_OPTIONS_PREFIX PREF_GCZEAL, -1);
if (gczeal < 0) {
gczeal = 0;
}
int32_t frequency = GetWorkerPref<int32_t>("gcZeal.frequency"_ns, -1);
int32_t frequency =
GetPref<int32_t>(PREF_JS_OPTIONS_PREFIX PREF_GCZEAL ".frequency", -1);
if (frequency < 0) {
frequency = JS_DEFAULT_ZEAL_FREQ;
}
@ -322,12 +285,11 @@ void LoadGCZealOptions(const char* /* aPrefName */, void* /* aClosure */) {
#endif
void UpdateCommonJSGCMemoryOption(RuntimeService* aRuntimeService,
const nsACString& aPrefName,
JSGCParamKey aKey) {
const char* aPrefName, JSGCParamKey aKey) {
AssertIsOnMainThread();
NS_ASSERTION(!aPrefName.IsEmpty(), "Empty pref name!");
NS_ASSERTION(aPrefName, "Null pref name!");
int32_t prefValue = GetWorkerPref(aPrefName, -1);
int32_t prefValue = GetPref(aPrefName, -1);
Maybe<uint32_t> value = (prefValue < 0 || prefValue >= 10000)
? Nothing()
: Some(uint32_t(prefValue));
@ -360,30 +322,31 @@ void LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */) {
return;
}
constexpr auto jsPrefix = nsLiteralCString{PREF_JS_OPTIONS_PREFIX};
constexpr auto workersPrefix = nsLiteralCString{PREF_WORKERS_OPTIONS_PREFIX};
constexpr auto memPrefix =
nsLiteralCString{PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX};
const nsDependentCString fullPrefName(aPrefName);
// Pull out the string that actually distinguishes the parameter we need to
// change.
nsDependentCSubstring memPrefName;
if (StringBeginsWith(fullPrefName, jsPrefix)) {
memPrefName.Rebind(fullPrefName, jsPrefix.Length());
} else if (StringBeginsWith(fullPrefName, workersPrefix)) {
memPrefName.Rebind(fullPrefName, workersPrefix.Length());
if (StringBeginsWith(fullPrefName, memPrefix)) {
memPrefName.Rebind(fullPrefName, memPrefix.Length());
} else {
NS_ERROR("Unknown pref name!");
return;
}
struct WorkerGCPref {
nsLiteralCString name;
nsLiteralCString memName;
const char* fullName;
JSGCParamKey key;
};
#define PREF(suffix_, key_) \
{ nsLiteralCString(PREF_MEM_OPTIONS_PREFIX suffix_), key_ }
#define PREF(suffix_, key_) \
{ \
nsLiteralCString(PREF_MEM_OPTIONS_PREFIX suffix_), \
PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX suffix_, key_ \
}
constexpr WorkerGCPref kWorkerPrefs[] = {
PREF("max", JSGC_MAX_BYTES),
PREF("gc_high_frequency_time_limit_ms", JSGC_HIGH_FREQUENCY_TIME_LIMIT),
@ -413,12 +376,12 @@ void LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */) {
if (gRuntimeServiceDuringInit) {
// During init, we want to update every pref in kWorkerPrefs.
MOZ_ASSERT(memPrefName.EqualsLiteral(PREF_MEM_OPTIONS_PREFIX),
MOZ_ASSERT(memPrefName.IsEmpty(),
"Pref branch prefix only expected during init");
} else {
// Otherwise, find the single pref that changed.
while (pref != end) {
if (pref->name == memPrefName) {
if (pref->memName == memPrefName) {
end = pref + 1;
break;
}
@ -437,7 +400,7 @@ void LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */) {
while (pref != end) {
switch (pref->key) {
case JSGC_MAX_BYTES: {
int32_t prefValue = GetWorkerPref(pref->name, -1);
int32_t prefValue = GetPref(pref->fullName, -1);
Maybe<uint32_t> value = (prefValue <= 0 || prefValue >= 0x1000)
? Nothing()
: Some(uint32_t(prefValue) * 1024 * 1024);
@ -445,7 +408,7 @@ void LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */) {
break;
}
case JSGC_SLICE_TIME_BUDGET_MS: {
int32_t prefValue = GetWorkerPref(pref->name, -1);
int32_t prefValue = GetPref(pref->fullName, -1);
Maybe<uint32_t> value = (prefValue <= 0 || prefValue >= 100000)
? Nothing()
: Some(uint32_t(prefValue));
@ -454,7 +417,7 @@ void LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */) {
}
case JSGC_COMPACTING_ENABLED: {
bool present;
bool prefValue = GetWorkerPref(pref->name, false, &present);
bool prefValue = GetPref(pref->fullName, false, &present);
Maybe<uint32_t> value = present ? Some(prefValue ? 1 : 0) : Nothing();
UpdateOtherJSGCMemoryOption(rts, pref->key, value);
break;
@ -472,7 +435,7 @@ void LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */) {
case JSGC_URGENT_THRESHOLD_MB:
case JSGC_MIN_EMPTY_CHUNK_COUNT:
case JSGC_MAX_EMPTY_CHUNK_COUNT:
UpdateCommonJSGCMemoryOption(rts, pref->name, pref->key);
UpdateCommonJSGCMemoryOption(rts, pref->fullName, pref->key);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unknown JSGCParamKey value");
@ -1485,12 +1448,9 @@ nsresult RuntimeService::Init() {
#define WORKER_PREF(name, callback) \
NS_FAILED(Preferences::RegisterCallbackAndCall(callback, name))
if (NS_FAILED(Preferences::RegisterPrefixCallback(
if (NS_FAILED(Preferences::RegisterPrefixCallbackAndCall(
LoadJSGCMemoryOptions,
PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX)) ||
NS_FAILED(Preferences::RegisterPrefixCallbackAndCall(
LoadJSGCMemoryOptions,
PREF_WORKERS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX)) ||
#ifdef JS_GC_ZEAL
NS_FAILED(Preferences::RegisterCallback(
LoadGCZealOptions, PREF_JS_OPTIONS_PREFIX PREF_GCZEAL)) ||
@ -1499,13 +1459,8 @@ nsresult RuntimeService::Init() {
WORKER_PREF("general.appname.override", AppNameOverrideChanged) ||
WORKER_PREF("general.appversion.override", AppVersionOverrideChanged) ||
WORKER_PREF("general.platform.override", PlatformOverrideChanged) ||
#ifdef JS_GC_ZEAL
WORKER_PREF("dom.workers.options.gcZeal", LoadGCZealOptions) ||
#endif
NS_FAILED(Preferences::RegisterPrefixCallbackAndCall(
LoadContextOptions, PREF_WORKERS_OPTIONS_PREFIX)) ||
NS_FAILED(Preferences::RegisterPrefixCallback(LoadContextOptions,
PREF_JS_OPTIONS_PREFIX))) {
LoadContextOptions, PREF_JS_OPTIONS_PREFIX))) {
NS_WARNING("Failed to register pref callbacks!");
}
@ -1767,23 +1722,17 @@ void RuntimeService::Cleanup() {
if (mObserved) {
if (NS_FAILED(Preferences::UnregisterPrefixCallback(
LoadContextOptions, PREF_JS_OPTIONS_PREFIX)) ||
NS_FAILED(Preferences::UnregisterPrefixCallback(
LoadContextOptions, PREF_WORKERS_OPTIONS_PREFIX)) ||
WORKER_PREF("intl.accept_languages", PrefLanguagesChanged) ||
WORKER_PREF("general.appname.override", AppNameOverrideChanged) ||
WORKER_PREF("general.appversion.override", AppVersionOverrideChanged) ||
WORKER_PREF("general.platform.override", PlatformOverrideChanged) ||
#ifdef JS_GC_ZEAL
WORKER_PREF("dom.workers.options.gcZeal", LoadGCZealOptions) ||
NS_FAILED(Preferences::UnregisterCallback(
LoadGCZealOptions, PREF_JS_OPTIONS_PREFIX PREF_GCZEAL)) ||
#endif
NS_FAILED(Preferences::UnregisterPrefixCallback(
LoadJSGCMemoryOptions,
PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX)) ||
NS_FAILED(Preferences::UnregisterPrefixCallback(
LoadJSGCMemoryOptions,
PREF_WORKERS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX))) {
PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX))) {
NS_WARNING("Failed to unregister pref callbacks!");
}

View file

@ -322,28 +322,9 @@ add_task(async function test() {
// ## Fission Isolation
if (Services.appinfo.fissionAutostart) {
const fissionUrl = "example.com";
const fissionRemoteType = `webIsolated=https://example.com`;
await do_test_sw(fissionUrl, fissionRemoteType, "synthetic", null);
await do_test_sw(fissionUrl, fissionRemoteType, "synthetic", fileBlob);
// ## ServiceWorker isolation via allow-list
// ## ServiceWorker isolation
const isolateUrl = "example.com";
const isolateRemoteType = `webServiceWorker=https://` + isolateUrl;
await SpecialPowers.pushPrefEnv({
set: [
[
"browser.tabs.remote.serviceWorkerIsolationList",
"https://" + isolateUrl,
],
[
"browser.tabs.remote.separatePrivilegedMozillaWebContentProcess",
false,
],
["browser.tabs.remote.separatedMozillaDomains", ""],
],
});
await do_test_sw(isolateUrl, isolateRemoteType, "synthetic", null);
await do_test_sw(isolateUrl, isolateRemoteType, "synthetic", fileBlob);
}

View file

@ -319,6 +319,10 @@ class GetNextTokenCompleteEvent final : public nsIRunnable,
nsCOMPtr<nsISupports> mContinuationState;
};
inline nsISupports* ToSupports(GetNextTokenCompleteEvent* aEvent) {
return static_cast<nsIRunnable*>(aEvent);
}
NS_IMPL_ISUPPORTS(GetNextTokenCompleteEvent, nsIRunnable, nsICancelable)
//
@ -336,7 +340,7 @@ class GetNextTokenRunnable final : public mozilla::Runnable {
const nsACString& challenge, bool isProxyAuth, const nsAString& domain,
const nsAString& username, const nsAString& password,
nsISupports* sessionState, nsISupports* continuationState,
GetNextTokenCompleteEvent* aCompleteEvent)
nsMainThreadPtrHandle<GetNextTokenCompleteEvent>& aCompleteEvent)
: mozilla::Runnable("GetNextTokenRunnable"),
mAuthChannel(authChannel),
mChallenge(challenge),
@ -413,7 +417,7 @@ class GetNextTokenRunnable final : public mozilla::Runnable {
nsString mPassword;
nsCOMPtr<nsISupports> mSessionState;
nsCOMPtr<nsISupports> mContinuationState;
RefPtr<GetNextTokenCompleteEvent> mCompleteEvent;
nsMainThreadPtrHandle<GetNextTokenCompleteEvent> mCompleteEvent;
};
} // anonymous namespace
@ -428,12 +432,13 @@ nsHttpNegotiateAuth::GenerateCredentialsAsync(
NS_ENSURE_ARG(aCallback);
NS_ENSURE_ARG_POINTER(aCancelable);
RefPtr<GetNextTokenCompleteEvent> cancelEvent =
new GetNextTokenCompleteEvent(aCallback);
nsMainThreadPtrHandle<nsIHttpAuthenticableChannel> handle(
new nsMainThreadPtrHolder<nsIHttpAuthenticableChannel>(
"nsIHttpAuthenticableChannel", authChannel, false));
nsMainThreadPtrHandle<GetNextTokenCompleteEvent> cancelEvent(
new nsMainThreadPtrHolder<GetNextTokenCompleteEvent>(
"GetNextTokenCompleteEvent", new GetNextTokenCompleteEvent(aCallback),
false));
nsCOMPtr<nsIRunnable> getNextTokenRunnable = new GetNextTokenRunnable(
handle, challenge, isProxyAuth, domain, username, password, sessionState,
continuationState, cancelEvent);
@ -442,7 +447,8 @@ nsHttpNegotiateAuth::GenerateCredentialsAsync(
getNextTokenRunnable, nsIEventTarget::DISPATCH_EVENT_MAY_BLOCK);
NS_ENSURE_SUCCESS(rv, rv);
cancelEvent.forget(aCancelable);
RefPtr<GetNextTokenCompleteEvent> cancelable(cancelEvent.get());
cancelable.forget(aCancelable);
return NS_OK;
}

View file

@ -11,6 +11,28 @@
#include <ostream>
namespace mozilla {
std::ostream& operator<<(std::ostream& aOut, const Side& aSide) {
#define Emit(x) \
case x: \
aOut << #x; \
break
switch (aSide) {
Emit(eSideTop);
Emit(eSideBottom);
Emit(eSideLeft);
Emit(eSideRight);
default:
NS_ERROR("unknown side");
aOut << int(aSide);
break;
}
#undef Emit
return aOut;
}
namespace gfx {
std::ostream& operator<<(std::ostream& aOut, const SurfaceFormat& aFormat) {

View file

@ -858,6 +858,8 @@ namespace mozilla {
// Side constants for use in various places.
enum Side : uint8_t { eSideTop, eSideRight, eSideBottom, eSideLeft };
std::ostream& operator<<(std::ostream&, const mozilla::Side&);
constexpr auto AllPhysicalSides() {
return mozilla::MakeInclusiveEnumeratedRange(eSideTop, eSideLeft);
}

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