diff --git a/accessible/base/nsTextEquivUtils.cpp b/accessible/base/nsTextEquivUtils.cpp index e693bb349f49..d2985c940841 100644 --- a/accessible/base/nsTextEquivUtils.cpp +++ b/accessible/base/nsTextEquivUtils.cpp @@ -105,26 +105,6 @@ nsresult nsTextEquivUtils::AppendTextEquivFromContent( nsresult nsTextEquivUtils::AppendTextEquivFromTextContent(nsIContent* aContent, nsAString* aString) { if (aContent->IsText()) { - bool isHTMLBlock = false; - - nsIContent* parentContent = aContent->GetFlattenedTreeParent(); - if (parentContent) { - nsIFrame* frame = parentContent->GetPrimaryFrame(); - if (frame) { - // If this text is inside a block level frame (as opposed to span - // level), we need to add spaces around that block's text, so we don't - // get words jammed together in final name. - const nsStyleDisplay* display = frame->StyleDisplay(); - if (display->IsBlockOutsideStyle() || - display->mDisplay == StyleDisplay::TableCell) { - isHTMLBlock = true; - if (!aString->IsEmpty()) { - aString->Append(char16_t(' ')); - } - } - } - } - if (aContent->TextLength() > 0) { nsIFrame* frame = aContent->GetPrimaryFrame(); if (frame) { @@ -136,9 +116,6 @@ nsresult nsTextEquivUtils::AppendTextEquivFromTextContent(nsIContent* aContent, // If aContent is an object that is display: none, we have no a frame. aContent->GetAsText()->AppendTextTo(*aString); } - if (isHTMLBlock && !aString->IsEmpty()) { - aString->Append(char16_t(' ')); - } } return NS_OK; @@ -184,10 +161,27 @@ nsresult nsTextEquivUtils::AppendFromAccessibleChildren( nsresult nsTextEquivUtils::AppendFromAccessible(Accessible* aAccessible, nsAString* aString) { // XXX: is it necessary to care the accessible is not a document? + bool isHTMLBlock = false; if (aAccessible->IsLocal() && aAccessible->AsLocal()->IsContent()) { - nsresult rv = AppendTextEquivFromTextContent( - aAccessible->AsLocal()->GetContent(), aString); + nsIContent* content = aAccessible->AsLocal()->GetContent(); + nsresult rv = AppendTextEquivFromTextContent(content, aString); if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED) return rv; + if (!content->IsText()) { + nsIFrame* frame = content->GetPrimaryFrame(); + if (frame) { + // If this is a block level frame (as opposed to span level), we need to + // add spaces around that block's text, so we don't get words jammed + // together in final name. + const nsStyleDisplay* display = frame->StyleDisplay(); + if (display->IsBlockOutsideStyle() || + display->mDisplay == StyleDisplay::TableCell) { + isHTMLBlock = true; + if (!aString->IsEmpty()) { + aString->Append(char16_t(' ')); + } + } + } + } } bool isEmptyTextEquiv = true; @@ -220,9 +214,15 @@ nsresult nsTextEquivUtils::AppendFromAccessible(Accessible* aAccessible, // Implementation of h. step if (isEmptyTextEquiv && !text.IsEmpty()) { AppendString(aString, text); + if (isHTMLBlock) { + aString->Append(char16_t(' ')); + } return NS_OK; } + if (!isEmptyTextEquiv && isHTMLBlock) { + aString->Append(char16_t(' ')); + } return rv; } diff --git a/accessible/generic/LocalAccessible.cpp b/accessible/generic/LocalAccessible.cpp index 3a4bba8dccad..270ccb69927b 100644 --- a/accessible/generic/LocalAccessible.cpp +++ b/accessible/generic/LocalAccessible.cpp @@ -3366,6 +3366,15 @@ already_AddRefed LocalAccessible::BundleFieldsForCache( mStateFlags &= ~eOldFrameHasValidTransformStyle; } } + + if (IsDoc()) { + if (PresShell* presShell = AsDoc()->PresShellPtr()) { + // Send the initial resolution of the document. When this changes, we + // will ne notified via nsAS::NotifyOfResolutionChange + float resolution = presShell->GetResolution(); + fields->SetAttribute(nsGkAtoms::resolution, resolution); + } + } } return fields.forget(); diff --git a/accessible/ipc/RemoteAccessibleBase.cpp b/accessible/ipc/RemoteAccessibleBase.cpp index b930957a59c6..22ba6325cb89 100644 --- a/accessible/ipc/RemoteAccessibleBase.cpp +++ b/accessible/ipc/RemoteAccessibleBase.cpp @@ -423,6 +423,7 @@ LayoutDeviceIntRect RemoteAccessibleBase::Bounds() const { // be scaled relative to its parent doc. res = remoteAcc->AsDoc()->mCachedFields->GetAttribute( nsGkAtoms::resolution); + MOZ_ASSERT(res, "No cached document resolution found."); bounds.ScaleRoundOut(res.valueOr(1.0f)); } diff --git a/accessible/tests/mochitest/name/test_general.html b/accessible/tests/mochitest/name/test_general.html index 552929893625..89314712fb0b 100644 --- a/accessible/tests/mochitest/name/test_general.html +++ b/accessible/tests/mochitest/name/test_general.html @@ -58,10 +58,9 @@ // spaces) testName("btn_labelledby_mixed_block", "text more text"); - // Gets the name from text nodes contained by html:td (every text node - // value in the name should be devided by spaces). - // XXX: this case is rather a feature than strong wanted behaviour. - testName("btn_labelledby_mixed_table", "text space text"); + // Gets the name from text nodes contained by html:td. The text nodes + // should not be divided by spaces. + testName("btn_labelledby_mixed_table", "textTEXTtext"); // Gets the name from image accessible. testName("btn_labelledby_mixed_img", "text image"); @@ -251,6 +250,17 @@ // Name from subtree of grouping labelled by an ancestor. testName("grouping_labelledby_ancestor", "label"); + // Name from subtree of a container containing text nodes and inline + // elements. There should be no spaces because everyhing is inline. + testName("container_text_inline", "abc"); + // Name from subtree of a container containing text nodes and block + // elements. There should be a space on both sides of the block. + testName("container_text_block", "a b c"); + // Name from subtree of a container containing text nodes and empty + // block elements. There should be space on either side of the blocks, but + // not a double space. + testName("container_text_emptyblock", "a b"); + SimpleTest.finish(); } @@ -387,7 +397,7 @@ - +
textspacetexttextTEXTtext
@@ -711,5 +721,12 @@ This content should not be included in the grouping's label. + + +
abc
+ +
a

b

c
+ +
a

b
diff --git a/browser/base/content/test/webrtc/browser.ini b/browser/base/content/test/webrtc/browser.ini index 01222001f4dc..1aa9f8c8ddb4 100644 --- a/browser/base/content/test/webrtc/browser.ini +++ b/browser/base/content/test/webrtc/browser.ini @@ -70,6 +70,8 @@ skip-if = apple_catalina # platform migration apple_silicon # bug 1707735 [browser_devices_get_user_media_unprompted_access.js] +skip-if = + os == "linux" && bits == 64 && !debug # Bug 1712012 https_first_disabled = true [browser_devices_get_user_media_unprompted_access_in_frame.js] https_first_disabled = true diff --git a/browser/components/downloads/test/browser/browser.ini b/browser/components/downloads/test/browser/browser.ini index 408ca2f6f469..32ddfa3ce014 100644 --- a/browser/components/downloads/test/browser/browser.ini +++ b/browser/components/downloads/test/browser/browser.ini @@ -28,7 +28,8 @@ skip-if = (os == 'win' && os_version == '10.0' && ccov) # Bug 1306510 [browser_library_clearall.js] [browser_download_opens_on_click.js] [browser_download_spam_protection.js] -skip-if = os == "linux" && bits == 64 && !debug # bug 1743263 +skip-if = + os == "linux" && bits == 64 # bug 1743263 & Bug 1742678 support-files = test_spammy_page.html [browser_download_is_clickable.js] [browser_downloads_keynav.js] diff --git a/browser/components/extensions/parent/ext-tabs.js b/browser/components/extensions/parent/ext-tabs.js index c54a0fd3cf6d..84b8cc260a24 100644 --- a/browser/components/extensions/parent/ext-tabs.js +++ b/browser/components/extensions/parent/ext-tabs.js @@ -802,6 +802,10 @@ this.tabs = class extends ExtensionAPI { tabListener.initializingTabs.add(nativeTab); } + if (createProperties.muted) { + nativeTab.toggleMuteAudio(extension.id); + } + return tabManager.convert(nativeTab, currentTabSize); }); }, diff --git a/browser/components/extensions/schemas/tabs.json b/browser/components/extensions/schemas/tabs.json index e3b212e50ec2..862add6fb037 100644 --- a/browser/components/extensions/schemas/tabs.json +++ b/browser/components/extensions/schemas/tabs.json @@ -612,6 +612,11 @@ "type": "string", "optional": true, "description": "The title used for display if the tab is created in discarded mode." + }, + "muted": { + "type": "boolean", + "optional": true, + "description": "Whether the tab should be muted when created." } } }, diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_create.js b/browser/components/extensions/test/browser/browser_ext_tabs_create.js index a207868ae6d1..b463ba7ad4da 100644 --- a/browser/components/extensions/test/browser/browser_ext_tabs_create.js +++ b/browser/components/extensions/test/browser/browser_ext_tabs_create.js @@ -50,6 +50,11 @@ add_task(async function test_create_options() { // 'selected' is marked as unsupported in schema, so we've removed it. // For more details, see bug 1337509 selected: undefined, + mutedInfo: { + muted: false, + extensionId: undefined, + reason: undefined, + }, }; let tests = [ @@ -132,6 +137,26 @@ add_task(async function test_create_options() { )}`, }, }, + { + create: { muted: true }, + result: { + mutedInfo: { + muted: true, + extensionId: browser.runtime.id, + reason: "extension", + }, + }, + }, + { + create: { muted: false }, + result: { + mutedInfo: { + muted: false, + extensionId: undefined, + reason: undefined, + }, + }, + }, ]; async function nextTest() { @@ -182,11 +207,21 @@ add_task(async function test_create_options() { continue; } - browser.test.assertEq( - expected[key], - tab[key], - `Expected value for tab.${key}` - ); + if (key === "mutedInfo") { + for (let key of Object.keys(expected.mutedInfo)) { + browser.test.assertEq( + expected.mutedInfo[key], + tab.mutedInfo[key], + `Expected value for tab.mutedInfo.${key}` + ); + } + } else { + browser.test.assertEq( + expected[key], + tab[key], + `Expected value for tab.${key}` + ); + } } let updated = await updatedPromise; diff --git a/browser/components/newtab/test/xpcshell/xpcshell.ini b/browser/components/newtab/test/xpcshell/xpcshell.ini index 65e3ef0e3c63..18cb85af2a88 100644 --- a/browser/components/newtab/test/xpcshell/xpcshell.ini +++ b/browser/components/newtab/test/xpcshell/xpcshell.ini @@ -11,6 +11,8 @@ prefs = support-files = ds_layout.json topstories.json +skip-if = + socketprocess_networking # Bug 1759035 [test_AboutNewTab.js] [test_AboutWelcomeAttribution.js] diff --git a/browser/components/places/Snapshots.jsm b/browser/components/places/Snapshots.jsm index 8f803e3c6046..625b3111edd1 100644 --- a/browser/components/places/Snapshots.jsm +++ b/browser/components/places/Snapshots.jsm @@ -295,7 +295,7 @@ const Snapshots = new (class Snapshots { * The url up until, but not including, any fragments */ stripFragments(url) { - return url.split("#")[0]; + return url?.split("#")[0]; } /** diff --git a/browser/components/places/tests/unit/interactions/test_snapshots_fragments.js b/browser/components/places/tests/unit/interactions/test_snapshots_fragments.js index 4745cc367642..6d4de46c5119 100644 --- a/browser/components/places/tests/unit/interactions/test_snapshots_fragments.js +++ b/browser/components/places/tests/unit/interactions/test_snapshots_fragments.js @@ -38,6 +38,11 @@ add_setup(async () => { }); add_task(async function test_stripFragments() { + Assert.equal( + Snapshots.stripFragments(), + undefined, + "stripFragments should handle undefined as an argument" + ); Assert.equal( Snapshots.stripFragments(TEST_FRAGMENT_URL1), TEST_URL1, diff --git a/browser/components/places/tests/unit/interactions/test_snapshotselection_fragments.js b/browser/components/places/tests/unit/interactions/test_snapshotselection_fragments.js index b74012c8844d..f149aea2f4df 100644 --- a/browser/components/places/tests/unit/interactions/test_snapshotselection_fragments.js +++ b/browser/components/places/tests/unit/interactions/test_snapshotselection_fragments.js @@ -2,8 +2,7 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ /** - * Tests that we adult sites are correctly filtered from snapshot selections - * when requested. + * Test that we correctly handle urls with fragments in snapshot selection */ const TEST_URL1 = "https://example.com/"; diff --git a/browser/components/urlbar/tests/browser/browser_autocomplete_a11y_label.js b/browser/components/urlbar/tests/browser/browser_autocomplete_a11y_label.js index c92773ebf16d..ee2747e9989e 100644 --- a/browser/components/urlbar/tests/browser/browser_autocomplete_a11y_label.js +++ b/browser/components/urlbar/tests/browser/browser_autocomplete_a11y_label.js @@ -78,7 +78,7 @@ add_task(async function switchToTab() { // before the result. await getResultText( element, - "Firefox Suggest about: robots— Switch to Tab", + "Firefox Suggest about:robots — Switch to Tab", "Result a11y text is correct" ); @@ -116,9 +116,8 @@ add_task(async function searchSuggestions() { ); // The first expected search is the search term itself since the heuristic // result will come before the search suggestions. - // The extra spaces are here due to bug 1550644. - let searchTerm = "foo "; - let expectedSearches = [searchTerm, "foo foo", "foo bar"]; + let searchTerm = "foo"; + let expectedSearches = [searchTerm, "foofoo", "foobar"]; for (let i = 0; i < length; i++) { let result = await UrlbarTestUtils.getDetailsOfResultAt(window, i); if (result.type === UrlbarUtils.RESULT_TYPE.SEARCH) { @@ -140,7 +139,7 @@ add_task(async function searchSuggestions() { if (result.searchParams.inPrivateWindow) { await getResultText( element, - searchTerm + "— Search in a Private Window", + searchTerm + " — Search in a Private Window", "Check result label" ); } else { @@ -148,7 +147,7 @@ add_task(async function searchSuggestions() { await getResultText( element, suggestion + - "— Search with browser_searchSuggestionEngine searchSuggestionEngine.xml", + " — Search with browser_searchSuggestionEngine searchSuggestionEngine.xml", "Check result label" ); } diff --git a/browser/extensions/webcompat/data/injections.js b/browser/extensions/webcompat/data/injections.js index 9c33de32237c..57e5b7625197 100644 --- a/browser/extensions/webcompat/data/injections.js +++ b/browser/extensions/webcompat/data/injections.js @@ -609,6 +609,20 @@ const AVAILABLE_INJECTIONS = [ ], }, }, + { + id: "bug1739489", + platform: "desktop", + domain: "draft.js", + bug: "1739489", + contentScripts: { + matches: ["*://draftjs.org/*", "*://www.facebook.com/*"], + js: [ + { + file: "injections/js/bug1739489-draftjs-beforeinput.js", + }, + ], + }, + }, ]; module.exports = AVAILABLE_INJECTIONS; diff --git a/browser/extensions/webcompat/injections/js/bug1739489-draftjs-beforeinput.js b/browser/extensions/webcompat/injections/js/bug1739489-draftjs-beforeinput.js new file mode 100644 index 000000000000..39ce2edf2a6d --- /dev/null +++ b/browser/extensions/webcompat/injections/js/bug1739489-draftjs-beforeinput.js @@ -0,0 +1,35 @@ +"use strict"; + +/** + * Bug 1739489 - Entering an emoji using the MacOS IME "crashes" Draft.js editors. + */ + +/* globals exportFunction */ + +console.info( + "textInput event has been remapped to beforeinput for compatibility reasons. See https://bugzilla.mozilla.org/show_bug.cgi?id=1739489 for details." +); + +window.wrappedJSObject.TextEvent = window.wrappedJSObject.InputEvent; + +const { CustomEvent, Event, EventTarget } = window.wrappedJSObject; +var Remapped = [ + [CustomEvent, "constructor"], + [Event, "constructor"], + [Event, "initEvent"], + [EventTarget, "addEventListener"], + [EventTarget, "removeEventListener"], +]; + +for (const [obj, name] of Remapped) { + const { prototype } = obj; + const orig = prototype[name]; + Object.defineProperty(prototype, name, { + value: exportFunction(function(type, b, c, d) { + if (type?.toLowerCase() === "textinput") { + type = "beforeinput"; + } + return orig.call(this, type, b, c, d); + }, window), + }); +} diff --git a/browser/extensions/webcompat/manifest.json b/browser/extensions/webcompat/manifest.json index d8ee726cd792..df084dbde614 100644 --- a/browser/extensions/webcompat/manifest.json +++ b/browser/extensions/webcompat/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "Web Compatibility Interventions", "description": "Urgent post-release fixes for web compatibility.", - "version": "31.0.0", + "version": "31.1.0", "applications": { "gecko": { "id": "webcompat@mozilla.org", diff --git a/browser/extensions/webcompat/moz.build b/browser/extensions/webcompat/moz.build index f4d0508f3b8f..a71b6878a7d9 100644 --- a/browser/extensions/webcompat/moz.build +++ b/browser/extensions/webcompat/moz.build @@ -83,6 +83,7 @@ FINAL_TARGET_FILES.features["webcompat@mozilla.org"]["injections"]["js"] += [ "injections/js/bug1724764-amextravel.com-window-print.js", "injections/js/bug1724868-news.yahoo.co.jp-ua-override.js", "injections/js/bug1731825-office365-email-handling-prompt-autohide.js", + "injections/js/bug1739489-draftjs-beforeinput.js", "injections/js/bug1756692-effectiveType-shim.js", ] diff --git a/devtools/client/debugger/test/mochitest/browser.ini b/devtools/client/debugger/test/mochitest/browser.ini index 2a22ecf0dba5..ac66232a69ab 100644 --- a/devtools/client/debugger/test/mochitest/browser.ini +++ b/devtools/client/debugger/test/mochitest/browser.ini @@ -64,6 +64,8 @@ skip-if = debug # Window leaks: bug 1575332 [browser_dbg-breakpoints-in-evaled-sources.js] [browser_dbg-breakpoints-list.js] [browser_dbg-breakpoints-popup.js] +skip-if = + os == 'linux' && bits == 64 && debug # Bug 1750199 [browser_dbg-browser-content-toolbox.js] skip-if = !e10s || verify # This test is only valid in e10s [browser_dbg-continue-to-here.js] diff --git a/devtools/client/inspector/test/browser.ini b/devtools/client/inspector/test/browser.ini index 1120be3f9eda..4d2167da6554 100644 --- a/devtools/client/inspector/test/browser.ini +++ b/devtools/client/inspector/test/browser.ini @@ -211,6 +211,7 @@ skip-if = (os == 'win' && processor == 'aarch64') # bug 1533492 [browser_inspector_picker-shift-key.js] [browser_inspector_picker-stop-on-eyedropper.js] [browser_inspector_picker-stop-on-tool-change.js] +[browser_inspector_picker-useragent-widget.js] [browser_inspector_portrait_mode.js] [browser_inspector_pseudoclass-lock.js] [browser_inspector_pseudoclass-menu.js] diff --git a/devtools/client/inspector/test/browser_inspector_picker-useragent-widget.js b/devtools/client/inspector/test/browser_inspector_picker-useragent-widget.js new file mode 100644 index 000000000000..1bdd63ebb60f --- /dev/null +++ b/devtools/client/inspector/test/browser_inspector_picker-useragent-widget.js @@ -0,0 +1,73 @@ +/* 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"; + +const TEST_URI = `data:text/html;charset=utf-8, + + `; + +// Test that using the node picker on user agent widgets only selects shadow dom +// elements if `devtools.inspector.showAllAnonymousContent` is true. +// If not, we should only surface the host, in this case, the