diff --git a/Cargo.lock b/Cargo.lock index 209aebcf669..1a1b14d1546 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,9 +99,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38b6b6b79f671c25e1a3e785b7b82d7562ffc9cd3efdc98627e5668a2472490" +checksum = "4f7487a7cc86cea29c97c91007ad21294f9959949577b305ae118b8c11738ccf" dependencies = [ "derive_arbitrary", ] @@ -805,9 +805,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" dependencies = [ "os_str_bytes", ] @@ -1363,9 +1363,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98e23c06c035dac87bd802d98f368df73a7f2cb05a66ffbd1f377e821fac4af9" +checksum = "91d001046c3cc126eb2ee9bdc946d9f482fe9e74d4a5ef191a6834fdbf84d45c" dependencies = [ "proc-macro2", "quote", @@ -2112,13 +2112,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -2256,9 +2256,9 @@ dependencies = [ [[package]] name = "glean" -version = "50.0.1" +version = "50.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3a101f9b9ccffbbcb7fe5159aabc22f7a5b8a266a9a810abff92ffe4b7bfc1" +checksum = "0857be0c251ae1fc3b5672237c99f5115a6546cd8b171cb240173098ab5e9629" dependencies = [ "chrono", "crossbeam-channel", @@ -2276,9 +2276,9 @@ dependencies = [ [[package]] name = "glean-core" -version = "50.0.1" +version = "50.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e474434da0bdd88a97e06b9b47cd2eaa419e3707c21fee02f5c4d66577f3360" +checksum = "f1bdfa0e2e6476190b4762c4cdc87c1a7a0347f601864b091cf9ad674a909c68" dependencies = [ "android_logger", "bincode", @@ -4584,9 +4584,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.24.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2ee7337df68898256ad0d4af4aad178210d9e44d2ff900ce44064a97cd86530" +checksum = "34a3bb58e85333f1ab191bf979104b586ebd77475bc6681882825f4532dfe87c" dependencies = [ "arrayvec", "num-traits", @@ -4705,9 +4705,9 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" [[package]] name = "semver" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" dependencies = [ "serde", ] @@ -5251,7 +5251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", - "wasi", + "wasi 0.10.0+wasi-snapshot-preview999", "winapi", ] @@ -5637,9 +5637,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] name = "unicode-normalization" @@ -5843,9 +5843,16 @@ dependencies = [ [[package]] name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +version = "0.10.0+wasi-snapshot-preview999" +dependencies = [ + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" diff --git a/Cargo.toml b/Cargo.toml index 3af9a576f8c..7aca1c1071d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,6 +135,9 @@ parking_lot = { path = "build/rust/parking_lot" } # Override tinyvec with smallvec tinyvec = { path = "build/rust/tinyvec" } +# Patch wasi 0.10 to 0.11 +wasi = { path = "build/rust/wasi" } + # Patch autocfg to hide rustc output. Workaround for https://github.com/cuviper/autocfg/issues/30 autocfg = { path = "third_party/rust/autocfg" } diff --git a/accessible/base/EventQueue.cpp b/accessible/base/EventQueue.cpp index 238323e5958..e7902c2f618 100644 --- a/accessible/base/EventQueue.cpp +++ b/accessible/base/EventQueue.cpp @@ -9,6 +9,7 @@ #include "nsEventShell.h" #include "DocAccessible.h" #include "DocAccessibleChild.h" +#include "mozilla/StaticPrefs_accessibility.h" #include "nsAccessibilityService.h" #include "nsTextEquivUtils.h" #ifdef A11Y_LOG @@ -307,6 +308,9 @@ void EventQueue::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent, void EventQueue::ProcessEventQueue() { // Process only currently queued events. const nsTArray > events = std::move(mEvents); + nsTArray selectedIDs; + nsTArray unselectedIDs; + uint32_t eventCount = events.Length(); #ifdef A11Y_LOG if ((eventCount > 0 || mFocusEvent) && logging::IsEnabled(logging::eEvents)) { @@ -336,48 +340,81 @@ void EventQueue::ProcessEventQueue() { for (uint32_t idx = 0; idx < eventCount; idx++) { AccEvent* event = events[idx]; - if (event->mEventRule != AccEvent::eDoNotEmit) { - LocalAccessible* target = event->GetAccessible(); - if (!target || target->IsDefunct()) continue; + uint32_t eventType = event->mEventType; + LocalAccessible* target = event->GetAccessible(); + if (!target || target->IsDefunct()) continue; - // Dispatch caret moved and text selection change events. - if (event->mEventType == - nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED) { - SelectionMgr()->ProcessTextSelChangeEvent(event); - continue; - } - - // Fire selected state change events in support to selection events. - if (event->mEventType == nsIAccessibleEvent::EVENT_SELECTION_ADD) { - nsEventShell::FireEvent(event->mAccessible, states::SELECTED, true, - event->mIsFromUserInput); - - } else if (event->mEventType == - nsIAccessibleEvent::EVENT_SELECTION_REMOVE) { - nsEventShell::FireEvent(event->mAccessible, states::SELECTED, false, - event->mIsFromUserInput); - - } else if (event->mEventType == nsIAccessibleEvent::EVENT_SELECTION) { + // Collect select changes + if (IPCAccessibilityActive() && + StaticPrefs::accessibility_cache_enabled_AtStartup()) { + if ((event->mEventRule == AccEvent::eDoNotEmit && + (eventType == nsIAccessibleEvent::EVENT_SELECTION_ADD || + eventType == nsIAccessibleEvent::EVENT_SELECTION_REMOVE || + eventType == nsIAccessibleEvent::EVENT_SELECTION)) || + eventType == nsIAccessibleEvent::EVENT_SELECTION_WITHIN) { + // The selection even was either dropped or morphed to a + // selection-within. We need to collect the items from all these events + // and manually push their new state to the parent process. AccSelChangeEvent* selChangeEvent = downcast_accEvent(event); - nsEventShell::FireEvent(event->mAccessible, states::SELECTED, - (selChangeEvent->mSelChangeType == - AccSelChangeEvent::eSelectionAdd), - event->mIsFromUserInput); - - if (selChangeEvent->mPackedEvent) { - nsEventShell::FireEvent( - selChangeEvent->mPackedEvent->mAccessible, states::SELECTED, - (selChangeEvent->mPackedEvent->mSelChangeType == - AccSelChangeEvent::eSelectionAdd), - selChangeEvent->mPackedEvent->mIsFromUserInput); + LocalAccessible* item = selChangeEvent->mItem; + uint64_t itemID = + item->IsDoc() ? 0 : reinterpret_cast(item->UniqueID()); + bool selected = + selChangeEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd; + if (selected) { + selectedIDs.AppendElement(itemID); + } else { + unselectedIDs.AppendElement(itemID); } } - - nsEventShell::FireEvent(event); } + if (event->mEventRule == AccEvent::eDoNotEmit) { + continue; + } + + // Dispatch caret moved and text selection change events. + if (eventType == nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED) { + SelectionMgr()->ProcessTextSelChangeEvent(event); + continue; + } + + // Fire selected state change events in support to selection events. + if (eventType == nsIAccessibleEvent::EVENT_SELECTION_ADD) { + nsEventShell::FireEvent(event->mAccessible, states::SELECTED, true, + event->mIsFromUserInput); + + } else if (eventType == nsIAccessibleEvent::EVENT_SELECTION_REMOVE) { + nsEventShell::FireEvent(event->mAccessible, states::SELECTED, false, + event->mIsFromUserInput); + + } else if (eventType == nsIAccessibleEvent::EVENT_SELECTION) { + AccSelChangeEvent* selChangeEvent = downcast_accEvent(event); + nsEventShell::FireEvent( + event->mAccessible, states::SELECTED, + (selChangeEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd), + event->mIsFromUserInput); + + if (selChangeEvent->mPackedEvent) { + nsEventShell::FireEvent(selChangeEvent->mPackedEvent->mAccessible, + states::SELECTED, + (selChangeEvent->mPackedEvent->mSelChangeType == + AccSelChangeEvent::eSelectionAdd), + selChangeEvent->mPackedEvent->mIsFromUserInput); + } + } + + nsEventShell::FireEvent(event); + if (!mDocument) return; } + + if (mDocument && IPCAccessibilityActive() && + StaticPrefs::accessibility_cache_enabled_AtStartup() && + (!selectedIDs.IsEmpty() || !unselectedIDs.IsEmpty())) { + DocAccessibleChild* ipcDoc = mDocument->IPCDoc(); + ipcDoc->SendSelectedAccessiblesChanged(selectedIDs, unselectedIDs); + } } } // namespace a11y diff --git a/accessible/basetypes/Accessible.cpp b/accessible/basetypes/Accessible.cpp index aa60800483d..0699553cf3d 100644 --- a/accessible/basetypes/Accessible.cpp +++ b/accessible/basetypes/Accessible.cpp @@ -97,6 +97,10 @@ bool Accessible::HasGenericType(AccGenericType aType) const { (roleMapEntry && roleMapEntry->IsOfType(aType)); } +nsIntRect Accessible::BoundsInCSSPixels() const { + return BoundsInAppUnits().ToNearestPixels(AppUnitsPerCSSPixel()); +} + LayoutDeviceIntSize Accessible::Size() const { return Bounds().Size(); } LayoutDeviceIntPoint Accessible::Position(uint32_t aCoordType) { diff --git a/accessible/basetypes/Accessible.h b/accessible/basetypes/Accessible.h index 9842fec5654..70d9ed743f8 100644 --- a/accessible/basetypes/Accessible.h +++ b/accessible/basetypes/Accessible.h @@ -197,6 +197,16 @@ class Accessible { */ virtual LayoutDeviceIntRect Bounds() const = 0; + /** + * Return boundaries in screen coordinates in app units. + */ + virtual nsRect BoundsInAppUnits() const = 0; + + /** + * Return boundaries in screen coordinates in CSS pixels. + */ + virtual nsIntRect BoundsInCSSPixels() const; + /** * Returns text of accessible if accessible has text role otherwise empty * string. diff --git a/accessible/generic/LocalAccessible.cpp b/accessible/generic/LocalAccessible.cpp index 95f8b7f9f4c..18a3116d9e2 100644 --- a/accessible/generic/LocalAccessible.cpp +++ b/accessible/generic/LocalAccessible.cpp @@ -789,10 +789,6 @@ LayoutDeviceIntRect LocalAccessible::Bounds() const { BoundsInAppUnits(), mDoc->PresContext()->AppUnitsPerDevPixel()); } -nsIntRect LocalAccessible::BoundsInCSSPixels() const { - return BoundsInAppUnits().ToNearestPixels(AppUnitsPerCSSPixel()); -} - void LocalAccessible::SetSelected(bool aSelect) { if (!HasOwnContent()) return; diff --git a/accessible/generic/LocalAccessible.h b/accessible/generic/LocalAccessible.h index f16f02b4b20..1fbfcd3b72f 100644 --- a/accessible/generic/LocalAccessible.h +++ b/accessible/generic/LocalAccessible.h @@ -405,18 +405,10 @@ class LocalAccessible : public nsISupports, public Accessible { virtual void AppendTextTo(nsAString& aText, uint32_t aStartOffset = 0, uint32_t aLength = UINT32_MAX) override; - /** - * Return boundaries in screen coordinates in app units. - */ - virtual nsRect BoundsInAppUnits() const; + virtual nsRect BoundsInAppUnits() const override; virtual LayoutDeviceIntRect Bounds() const override; - /** - * Return boundaries in screen coordinates in CSS pixels. - */ - virtual nsIntRect BoundsInCSSPixels() const; - /** * Return boundaries rect relative the bounding frame. */ diff --git a/accessible/ipc/DocAccessibleParent.cpp b/accessible/ipc/DocAccessibleParent.cpp index 5a6f534fa06..f089261dddd 100644 --- a/accessible/ipc/DocAccessibleParent.cpp +++ b/accessible/ipc/DocAccessibleParent.cpp @@ -619,6 +619,41 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvCache( return IPC_OK(); } +mozilla::ipc::IPCResult DocAccessibleParent::RecvSelectedAccessiblesChanged( + nsTArray&& aSelectedIDs, nsTArray&& aUnselectedIDs) { + ACQUIRE_ANDROID_LOCK + if (mShutdown) { + return IPC_OK(); + } + + for (auto& id : aSelectedIDs) { + RemoteAccessible* remote = GetAccessible(id); + if (!remote) { + MOZ_ASSERT_UNREACHABLE("No remote found!"); + continue; + } + + remote->UpdateStateCache(states::SELECTED, true); + } + + for (auto& id : aUnselectedIDs) { + RemoteAccessible* remote = GetAccessible(id); + if (!remote) { + MOZ_ASSERT_UNREACHABLE("No remote found!"); + continue; + } + + remote->UpdateStateCache(states::SELECTED, false); + } + + if (nsCOMPtr obsService = + services::GetObserverService()) { + obsService->NotifyObservers(nullptr, NS_ACCESSIBLE_CACHE_TOPIC, nullptr); + } + + return IPC_OK(); +} + mozilla::ipc::IPCResult DocAccessibleParent::RecvAccessiblesWillMove( nsTArray&& aIDs) { for (uint64_t id : aIDs) { diff --git a/accessible/ipc/DocAccessibleParent.h b/accessible/ipc/DocAccessibleParent.h index c286c4616f3..55f36675694 100644 --- a/accessible/ipc/DocAccessibleParent.h +++ b/accessible/ipc/DocAccessibleParent.h @@ -138,6 +138,10 @@ class DocAccessibleParent : public RemoteAccessible, const mozilla::a11y::CacheUpdateType& aUpdateType, nsTArray&& aData, const bool& aFinal) override; + virtual mozilla::ipc::IPCResult RecvSelectedAccessiblesChanged( + nsTArray&& aSelectedIDs, + nsTArray&& aUnselectedIDs) override; + virtual mozilla::ipc::IPCResult RecvAccessiblesWillMove( nsTArray&& aIDs) override; diff --git a/accessible/ipc/RemoteAccessibleBase.cpp b/accessible/ipc/RemoteAccessibleBase.cpp index 8defd80a082..d343f5218ef 100644 --- a/accessible/ipc/RemoteAccessibleBase.cpp +++ b/accessible/ipc/RemoteAccessibleBase.cpp @@ -457,7 +457,7 @@ void RemoteAccessibleBase::ApplyScrollOffset(nsRect& aBounds) const { } template -nsRect RemoteAccessibleBase::GetBoundsInAppUnits() const { +nsRect RemoteAccessibleBase::BoundsInAppUnits() const { dom::CanonicalBrowsingContext* cbc = static_cast(mDoc->Manager()) ->GetBrowsingContext() diff --git a/accessible/ipc/RemoteAccessibleBase.h b/accessible/ipc/RemoteAccessibleBase.h index 56412be9511..269e9b7c59d 100644 --- a/accessible/ipc/RemoteAccessibleBase.h +++ b/accessible/ipc/RemoteAccessibleBase.h @@ -181,7 +181,7 @@ class RemoteAccessibleBase : public Accessible, public HyperTextAccessibleBase { virtual LayoutDeviceIntRect Bounds() const override; - nsRect GetBoundsInAppUnits() const; + virtual nsRect BoundsInAppUnits() const override; virtual uint64_t State() override; diff --git a/accessible/ipc/RemoteAccessibleShared.h b/accessible/ipc/RemoteAccessibleShared.h index f5562ba7301..2bfce2ad593 100644 --- a/accessible/ipc/RemoteAccessibleShared.h +++ b/accessible/ipc/RemoteAccessibleShared.h @@ -202,7 +202,7 @@ Accessible* ChildAtPoint( int32_t aX, int32_t aY, LocalAccessible::EWhichChildAtPoint aWhichChild) override; LayoutDeviceIntRect Bounds() const override; -nsIntRect BoundsInCSSPixels(); +virtual nsIntRect BoundsInCSSPixels() const override; void Language(nsString& aLocale); void DocType(nsString& aType); diff --git a/accessible/ipc/other/PDocAccessible.ipdl b/accessible/ipc/other/PDocAccessible.ipdl index a2c0be9a183..ffe4176d225 100644 --- a/accessible/ipc/other/PDocAccessible.ipdl +++ b/accessible/ipc/other/PDocAccessible.ipdl @@ -135,6 +135,11 @@ parent: */ async Cache(CacheUpdateType aUpdateType, CacheData[] aData, bool aFinal); + /* + * Lists of accessibles that either gained or lost a selected state. + */ + async SelectedAccessiblesChanged(uint64_t[] aSelectedIDs, uint64_t[] aUnselectedIDs); + /* * Tell the parent process that the given Accessibles are about to be moved * via subsequent hide and show events. diff --git a/accessible/ipc/other/RemoteAccessible.cpp b/accessible/ipc/other/RemoteAccessible.cpp index c34dd6dc7f2..18e747f3b37 100644 --- a/accessible/ipc/other/RemoteAccessible.cpp +++ b/accessible/ipc/other/RemoteAccessible.cpp @@ -989,7 +989,11 @@ LayoutDeviceIntRect RemoteAccessible::Bounds() const { return rect; } -nsIntRect RemoteAccessible::BoundsInCSSPixels() { +nsIntRect RemoteAccessible::BoundsInCSSPixels() const { + if (StaticPrefs::accessibility_cache_enabled_AtStartup()) { + return RemoteAccessibleBase::BoundsInCSSPixels(); + } + nsIntRect rect; Unused << mDoc->SendExtentsInCSSPixels(mID, &rect.x, &rect.y, &rect.width, &rect.height); diff --git a/accessible/ipc/win/PDocAccessible.ipdl b/accessible/ipc/win/PDocAccessible.ipdl index d1b0bc05658..5dde3bffe8e 100644 --- a/accessible/ipc/win/PDocAccessible.ipdl +++ b/accessible/ipc/win/PDocAccessible.ipdl @@ -102,6 +102,11 @@ parent: */ async Cache(CacheUpdateType aUpdateType, CacheData[] aData, bool aFinal); + /* + * Lists of accessibles that either gained or lost a selected state. + */ + async SelectedAccessiblesChanged(uint64_t[] aSelectedIDs, uint64_t[] aUnselectedIDs); + /* * Tell the parent process that the given Accessibles are about to be moved * via subsequent hide and show events. diff --git a/accessible/ipc/win/RemoteAccessible.cpp b/accessible/ipc/win/RemoteAccessible.cpp index f1fec834ac8..e1d1134b1a8 100644 --- a/accessible/ipc/win/RemoteAccessible.cpp +++ b/accessible/ipc/win/RemoteAccessible.cpp @@ -252,7 +252,11 @@ LayoutDeviceIntRect RemoteAccessible::Bounds() const { return rect; } -nsIntRect RemoteAccessible::BoundsInCSSPixels() { +nsIntRect RemoteAccessible::BoundsInCSSPixels() const { + if (StaticPrefs::accessibility_cache_enabled_AtStartup()) { + return RemoteAccessibleBase::BoundsInCSSPixels(); + } + RefPtr custom = QueryInterface(this); if (!custom) { return nsIntRect(); diff --git a/accessible/tests/browser/selectable/browser_test_select.js b/accessible/tests/browser/selectable/browser_test_select.js index bd1eff4ad79..5ea604b08d5 100644 --- a/accessible/tests/browser/selectable/browser_test_select.js +++ b/accessible/tests/browser/selectable/browser_test_select.js @@ -254,3 +254,46 @@ addAccessibleTask( remoteIframe: !isWinNoCache, } ); + +// //////////////////////////////////////////////////////////////////////// +// multiselect with coalesced selection event +addAccessibleTask( + ``, + async function(browser, docAcc) { + info("select@size='4' multiselect with coalesced selection event"); + let select = findAccessibleChildByID(docAcc, "listbox", [ + nsIAccessibleSelectable, + ]); + await testMultiSelectable( + select, + [ + "item1", + "item2", + "item3", + "item4", + "item5", + "item6", + "item7", + "item8", + "item9", + ], + "select@size='4' multiselect with coalesced selection event " + ); + }, + { + chrome: false, + topLevel: true, + iframe: false, + remoteIframe: false, + } +); diff --git a/accessible/tests/browser/selectable/head.js b/accessible/tests/browser/selectable/head.js index 1f3b52e1c74..0605313ddce 100644 --- a/accessible/tests/browser/selectable/head.js +++ b/accessible/tests/browser/selectable/head.js @@ -65,30 +65,25 @@ async function testMultiSelectable(widget, selectableChildren, msg = "") { promise = multipleSelectionChanged(widget, selectableChildren, true); let success = widget.selectAll(); ok(success, `${msg}: selectAll success`); - let coalesced = await promise; - if (isRemote && coalesced && isCacheEnabled) { - todo_is( - widget.selectedItemCount, + await promise; + if (isRemote && isCacheEnabled) { + await untilCacheIs( + () => widget.selectedItemCount, selectableChildren.length, - "Bug 1755377: Coalesced SELECTION_WITHIN doesn't update cache" + "Selection cache updated" ); - // We bail early here because the cache is out of sync. - return; } - testSelectableSelection(widget, selectableChildren, `${msg}: selectAll`); promise = multipleSelectionChanged(widget, selectableChildren, false); widget.unselectAll(); - coalesced = await promise; - if (isRemote && coalesced && isCacheEnabled) { - todo_is( - widget.selectedItemCount, + await promise; + if (isRemote && isCacheEnabled) { + await untilCacheIs( + () => widget.selectedItemCount, 0, - "Coalesced SELECTION_WITHIN doesn't update cache" + "Selection cache updated" ); - // We bail early here because the cache is out of sync. - return; } testSelectableSelection(widget, [], `${msg}: selectAll`); } diff --git a/accessible/xpcom/xpcAccessible.cpp b/accessible/xpcom/xpcAccessible.cpp index 574463f88ca..ccd28a72e55 100644 --- a/accessible/xpcom/xpcAccessible.cpp +++ b/accessible/xpcom/xpcAccessible.cpp @@ -435,13 +435,7 @@ xpcAccessible::GetBounds(int32_t* aX, int32_t* aY, int32_t* aWidth, if (!IntlGeneric()) return NS_ERROR_FAILURE; - LayoutDeviceIntRect rect; - if (LocalAccessible* acc = IntlGeneric()->AsLocal()) { - rect = acc->Bounds(); - } else { - rect = IntlGeneric()->AsRemote()->Bounds(); - } - + LayoutDeviceIntRect rect = IntlGeneric()->Bounds(); rect.GetRect(aX, aY, aWidth, aHeight); return NS_OK; } @@ -462,13 +456,7 @@ xpcAccessible::GetBoundsInCSSPixels(int32_t* aX, int32_t* aY, int32_t* aWidth, return NS_ERROR_FAILURE; } - nsIntRect rect; - if (LocalAccessible* acc = IntlGeneric()->AsLocal()) { - rect = acc->BoundsInCSSPixels(); - } else { - rect = IntlGeneric()->AsRemote()->BoundsInCSSPixels(); - } - + nsIntRect rect = IntlGeneric()->BoundsInCSSPixels(); rect.GetRect(aX, aY, aWidth, aHeight); return NS_OK; } diff --git a/browser/actors/AboutPrivateBrowsingChild.jsm b/browser/actors/AboutPrivateBrowsingChild.jsm index b1c185d63a9..3877039d525 100644 --- a/browser/actors/AboutPrivateBrowsingChild.jsm +++ b/browser/actors/AboutPrivateBrowsingChild.jsm @@ -27,9 +27,6 @@ class AboutPrivateBrowsingChild extends RemotePageChild { super.actorCreated(); let window = this.contentWindow; - Cu.exportFunction(this.PrivateBrowsingFeatureConfig.bind(this), window, { - defineAs: "PrivateBrowsingFeatureConfig", - }); Cu.exportFunction(this.PrivateBrowsingRecordClick.bind(this), window, { defineAs: "PrivateBrowsingRecordClick", }); @@ -48,10 +45,9 @@ class AboutPrivateBrowsingChild extends RemotePageChild { } PrivateBrowsingRecordClick(source) { - const experiment = - lazy.ExperimentAPI.getExperimentMetaData({ - featureId: "privatebrowsing", - }) || lazy.ExperimentAPI.getExperimentMetaData({ featureId: "pbNewtab" }); + const experiment = lazy.ExperimentAPI.getExperimentMetaData({ + featureId: "pbNewtab", + }); if (experiment) { Services.telemetry.recordEvent("aboutprivatebrowsing", "click", source); } @@ -66,19 +62,4 @@ class AboutPrivateBrowsingChild extends RemotePageChild { PrivateBrowsingExposureTelemetry() { lazy.NimbusFeatures.pbNewtab.recordExposureEvent({ once: false }); } - - PrivateBrowsingFeatureConfig() { - const config = lazy.NimbusFeatures.privatebrowsing.getAllVariables() || {}; - - lazy.NimbusFeatures.privatebrowsing.recordExposureEvent(); - - // Format urls if any are defined - ["infoLinkUrl", "promoLinkUrl"].forEach(key => { - if (config[key]) { - config[key] = Services.urlFormatter.formatURL(config[key]); - } - }); - - return Cu.cloneInto(config, this.contentWindow); - } } diff --git a/browser/actors/AboutProtectionsParent.jsm b/browser/actors/AboutProtectionsParent.jsm index 741f0592898..948644efa5e 100644 --- a/browser/actors/AboutProtectionsParent.jsm +++ b/browser/actors/AboutProtectionsParent.jsm @@ -4,8 +4,6 @@ "use strict"; -Cu.importGlobalProperties(["fetch"]); - var EXPORTED_SYMBOLS = ["AboutProtectionsParent"]; const { XPCOMUtils } = ChromeUtils.import( "resource://gre/modules/XPCOMUtils.jsm" diff --git a/browser/actors/ClickHandlerParent.jsm b/browser/actors/ClickHandlerParent.jsm index 5bf2ebaa5c6..9330ce5eeaa 100644 --- a/browser/actors/ClickHandlerParent.jsm +++ b/browser/actors/ClickHandlerParent.jsm @@ -115,6 +115,8 @@ class ClickHandlerParent extends JSWindowActorParent { csp: data.csp ? lazy.E10SUtils.deserializeCSP(data.csp) : null, frameID: data.frameID, openerBrowser: browser, + // The child ensures that untrusted events have a valid user activation. + hasValidUserGestureActivation: true, }; // The new tab/window must use the same userContextId. diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 603ca555c0d..c49a2014253 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1011,9 +1011,6 @@ pref("plugins.show_infobar", false); pref("plugin.default.state", 1); #endif -// Enables the download and use of the flash blocklists. -pref("plugins.flashBlock.enabled", true); - // Prefer HTML5 video over Flash content, and don't // load plugin instances with no src declared. // These prefs are documented in details on all.js. @@ -1223,8 +1220,6 @@ pref("browser.bookmarks.editDialog.maxRecentFolders", 7); // just save on Accept, once the project is complete. pref("browser.bookmarks.editDialog.delayedApply.enabled", false); -pref("dom.ipc.shims.enabledWarnings", false); - #if defined(XP_WIN) && defined(MOZ_SANDBOX) // This controls the strength of the Windows content process sandbox for // testing purposes. This will require a restart. @@ -1609,6 +1604,8 @@ pref("browser.aboutwelcome.enabled", true); // Used to set multistage welcome UX pref("browser.aboutwelcome.screens", ""); pref("browser.aboutwelcome.skipFocus", true); +// Used to enable template for MR 2022 Onboarding +pref("browser.aboutwelcome.templateMR", false); // The pref that controls if the What's New panel is enabled. pref("browser.messaging-system.whatsNewPanel.enabled", true); diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css index 03a778809dc..5e6cb606779 100644 --- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -176,8 +176,8 @@ panelview[mainview] > .panel-header { } #tabbrowser-tabs[hasadjacentnewtabbutton]:not([overflow="true"]) ~ #new-tab-button, -#tabbrowser-tabs[overflow="true"] > #tabbrowser-arrowscrollbox > #tabs-newtab-button, -#tabbrowser-tabs:not([hasadjacentnewtabbutton]) > #tabbrowser-arrowscrollbox > #tabs-newtab-button, +#tabbrowser-tabs[overflow="true"] > #tabbrowser-arrowscrollbox > #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button, +#tabbrowser-tabs:not([hasadjacentnewtabbutton]) > #tabbrowser-arrowscrollbox > #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button, #TabsToolbar[customizing="true"] #tabs-newtab-button { display: none; } diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 05d20e93a7b..ce10a28e622 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1508,11 +1508,13 @@ function _loadURI(browser, uri, params = {}) { userContextId, csp, remoteTypeOverride, + hasValidUserGestureActivation, } = params || {}; let loadFlags = params.loadFlags || params.flags || Ci.nsIWebNavigation.LOAD_FLAGS_NONE; - let hasValidUserGestureActivation = + hasValidUserGestureActivation ??= document.hasValidTransientUserGestureActivation; + if (!triggeringPrincipal) { throw new Error("Must load with a triggering Principal"); } @@ -2245,7 +2247,7 @@ var gBrowserInit = { }); } catch (e) {} } else if (window.arguments.length >= 3) { - // window.arguments[1]: unused (bug 871161) + // window.arguments[1]: extraOptions (nsIPropertyBag) // [2]: referrerInfo (nsIReferrerInfo) // [3]: postData (nsIInputStream) // [4]: allowThirdPartyFixup (bool) @@ -2260,23 +2262,50 @@ var gBrowserInit = { window.arguments[5] != undefined ? window.arguments[5] : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID; - loadURI( - uriToLoad, - window.arguments[2] || null, - window.arguments[3] || null, - window.arguments[4] || false, - userContextId, - // pass the origin principal (if any) and force its use to create - // an initial about:blank viewer if present: - window.arguments[6], - window.arguments[7], - !!window.arguments[6], - window.arguments[8], - // TODO fix allowInheritPrincipal to default to false. - // Default to true unless explicitly set to false because of bug 1475201. - window.arguments[9] !== false, - window.arguments[10] - ); + + let hasValidUserGestureActivation = undefined; + let fromExternal = undefined; + if (window.arguments[1]) { + if (!(window.arguments[1] instanceof Ci.nsIPropertyBag2)) { + throw new Error( + "window.arguments[1] must be null or Ci.nsIPropertyBag2!" + ); + } + + let extraOptions = window.arguments[1]; + if (extraOptions.hasKey("hasValidUserGestureActivation")) { + hasValidUserGestureActivation = extraOptions.getPropertyAsBool( + "hasValidUserGestureActivation" + ); + } + if (extraOptions.hasKey("fromExternal")) { + fromExternal = extraOptions.getPropertyAsBool("fromExternal"); + } + } + + try { + openLinkIn(uriToLoad, "current", { + referrerInfo: window.arguments[2] || null, + postData: window.arguments[3] || null, + allowThirdPartyFixup: window.arguments[4] || false, + userContextId, + // pass the origin principal (if any) and force its use to create + // an initial about:blank viewer if present: + originPrincipal: window.arguments[6], + originStoragePrincipal: window.arguments[7], + triggeringPrincipal: window.arguments[8], + // TODO fix allowInheritPrincipal to default to false. + // Default to true unless explicitly set to false because of bug 1475201. + allowInheritPrincipal: window.arguments[9] !== false, + csp: window.arguments[10], + forceAboutBlankViewerInCurrent: !!window.arguments[6], + hasValidUserGestureActivation, + fromExternal, + }); + } catch (e) { + Cu.reportError(e); + } + window.focus(); } else { // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3. @@ -6272,13 +6301,18 @@ nsBrowserAccess.prototype = { // Pass all params to openDialog to ensure that "url" isn't passed through // loadOneOrMoreURIs, which splits based on "|" try { + let extraOptions = Cc[ + "@mozilla.org/hash-property-bag;1" + ].createInstance(Ci.nsIWritablePropertyBag2); + extraOptions.setPropertyAsBool("fromExternal", isExternal); + openDialog( AppConstants.BROWSER_CHROME_URL, "_blank", features, // window.arguments url, - null, + extraOptions, null, null, null, diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml index 5f1113e1111..8ff95dfdf8c 100644 --- a/browser/base/content/navigator-toolbox.inc.xhtml +++ b/browser/base/content/navigator-toolbox.inc.xhtml @@ -55,12 +55,15 @@ # the current structure that we may want to revisit. - - + + + + +