ma1 pushed to branch mullvad-browser-115.13.0esr-13.5-1 at The Tor Project / Applications / Mullvad Browser
Commits:
-
55b8abf1
by Edgar Chen at 2024-07-09T16:29:04+02:00
-
0019972d
by Edgar Chen at 2024-07-09T16:31:30+02:00
-
84063db0
by Edgar Chen at 2024-07-09T16:31:36+02:00
-
f77f91b1
by Otto Länd at 2024-07-09T16:31:37+02:00
-
d2415441
by edgul at 2024-07-09T16:31:37+02:00
-
4f7651bf
by edgul at 2024-07-09T16:31:38+02:00
-
2e663f7b
by Ed at 2024-07-09T16:31:38+02:00
-
bb413ac1
by Julian Descottes at 2024-07-09T16:31:39+02:00
-
4e320ce3
by Edgar Chen at 2024-07-09T16:31:39+02:00
-
0c986a88
by Jan de Mooij at 2024-07-09T16:31:40+02:00
-
3716357a
by Jan de Mooij at 2024-07-09T16:31:40+02:00
22 changed files:
- browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js
- dom/base/PointerLockManager.cpp
- dom/base/PointerLockManager.h
- dom/html/HTMLDNSPrefetch.cpp
- dom/ipc/BrowserChild.cpp
- dom/ipc/BrowserChild.h
- dom/ipc/BrowserParent.cpp
- dom/ipc/PBrowser.ipdl
- + js/src/jit-test/tests/ion/bug1900523.js
- + js/src/jit-test/tests/ion/bug1902983.js
- js/src/jit/JSJitFrameIter.cpp
- js/src/jit/JSJitFrameIter.h
- layout/base/PresShell.cpp
- layout/base/PresShell.h
- layout/base/nsCaret.cpp
- layout/base/nsLayoutUtils.cpp
- layout/xul/nsXULPopupManager.cpp
- layout/xul/nsXULPopupManager.h
- modules/libpref/init/StaticPrefList.yaml
- netwerk/cookie/CookieService.cpp
- netwerk/cookie/CookieServiceChild.cpp
- testing/web-platform/meta/cookies/samesite/setcookie-navigation.https.html.ini
Changes:
... | ... | @@ -558,5 +558,7 @@ add_task(async function test_notificationDuringFullScreenTransition() { |
558 | 558 | info("Wait for full screen transition end.");
|
559 | 559 | await promiseFullScreenTransitionEnd;
|
560 | 560 | info("Full screen transition end");
|
561 | + |
|
562 | + await SpecialPowers.popPrefEnv();
|
|
561 | 563 | });
|
562 | 564 | }); |
... | ... | @@ -17,8 +17,10 @@ |
17 | 17 | #include "mozilla/dom/BrowsingContext.h"
|
18 | 18 | #include "mozilla/dom/Document.h"
|
19 | 19 | #include "mozilla/dom/Element.h"
|
20 | +#include "mozilla/dom/PointerEventHandler.h"
|
|
20 | 21 | #include "mozilla/dom/WindowContext.h"
|
21 | 22 | #include "nsCOMPtr.h"
|
23 | +#include "nsMenuPopupFrame.h"
|
|
22 | 24 | #include "nsSandboxFlags.h"
|
23 | 25 | |
24 | 26 | namespace mozilla {
|
... | ... | @@ -86,6 +88,25 @@ static void DispatchPointerLockError(Document* aTarget, const char* aMessage) { |
86 | 88 | aMessage);
|
87 | 89 | }
|
88 | 90 | |
91 | +static bool IsPopupOpened() {
|
|
92 | + // Check if any popup is open.
|
|
93 | + nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
|
94 | + if (!pm) {
|
|
95 | + return false;
|
|
96 | + }
|
|
97 | + |
|
98 | + nsTArray<nsMenuPopupFrame*> popups;
|
|
99 | + pm->GetVisiblePopups(popups, true);
|
|
100 | + |
|
101 | + for (nsMenuPopupFrame* popup : popups) {
|
|
102 | + if (popup->GetPopupType() != widget::PopupType::Tooltip) {
|
|
103 | + return true;
|
|
104 | + }
|
|
105 | + }
|
|
106 | + |
|
107 | + return false;
|
|
108 | +}
|
|
109 | + |
|
89 | 110 | static const char* GetPointerLockError(Element* aElement, Element* aCurrentLock,
|
90 | 111 | bool aNoFocusCheck = false) {
|
91 | 112 | // Check if pointer lock pref is enabled
|
... | ... | @@ -136,6 +157,10 @@ static const char* GetPointerLockError(Element* aElement, Element* aCurrentLock, |
136 | 157 | }
|
137 | 158 | }
|
138 | 159 | |
160 | + if (IsPopupOpened()) {
|
|
161 | + return "PointerLockDeniedFailedToLock";
|
|
162 | + }
|
|
163 | + |
|
139 | 164 | return nullptr;
|
140 | 165 | }
|
141 | 166 | |
... | ... | @@ -167,6 +192,14 @@ void PointerLockManager::RequestLock(Element* aElement, |
167 | 192 | |
168 | 193 | /* static */
|
169 | 194 | void PointerLockManager::Unlock(Document* aDoc) {
|
195 | + if (sLockedRemoteTarget) {
|
|
196 | + MOZ_ASSERT(XRE_IsParentProcess());
|
|
197 | + MOZ_ASSERT(!sIsLocked);
|
|
198 | + Unused << sLockedRemoteTarget->SendReleasePointerLock();
|
|
199 | + sLockedRemoteTarget = nullptr;
|
|
200 | + return;
|
|
201 | + }
|
|
202 | + |
|
170 | 203 | if (!sIsLocked) {
|
171 | 204 | return;
|
172 | 205 | }
|
... | ... | @@ -311,14 +344,24 @@ bool PointerLockManager::IsInLockContext(BrowsingContext* aContext) { |
311 | 344 | }
|
312 | 345 | |
313 | 346 | /* static */
|
314 | -bool PointerLockManager::SetLockedRemoteTarget(BrowserParent* aBrowserParent) {
|
|
347 | +void PointerLockManager::SetLockedRemoteTarget(BrowserParent* aBrowserParent,
|
|
348 | + nsACString& aError) {
|
|
315 | 349 | MOZ_ASSERT(XRE_IsParentProcess());
|
316 | 350 | if (sLockedRemoteTarget) {
|
317 | - return sLockedRemoteTarget == aBrowserParent;
|
|
351 | + if (sLockedRemoteTarget != aBrowserParent) {
|
|
352 | + aError = "PointerLockDeniedInUse"_ns;
|
|
353 | + }
|
|
354 | + return;
|
|
355 | + }
|
|
356 | + |
|
357 | + // Check if any popup is open.
|
|
358 | + if (IsPopupOpened()) {
|
|
359 | + aError = "PointerLockDeniedFailedToLock"_ns;
|
|
360 | + return;
|
|
318 | 361 | }
|
319 | 362 | |
320 | 363 | sLockedRemoteTarget = aBrowserParent;
|
321 | - return true;
|
|
364 | + PointerEventHandler::ReleaseAllPointerCaptureRemoteTarget();
|
|
322 | 365 | }
|
323 | 366 | |
324 | 367 | /* static */
|
... | ... | @@ -47,7 +47,8 @@ class PointerLockManager final { |
47 | 47 | |
48 | 48 | // Set/release pointer lock remote target. Should only be called in parent
|
49 | 49 | // process.
|
50 | - static bool SetLockedRemoteTarget(dom::BrowserParent* aBrowserParent);
|
|
50 | + static void SetLockedRemoteTarget(dom::BrowserParent* aBrowserParent,
|
|
51 | + nsACString& aError);
|
|
51 | 52 | static void ReleaseLockedRemoteTarget(dom::BrowserParent* aBrowserParent);
|
52 | 53 | |
53 | 54 | private:
|
... | ... | @@ -180,6 +180,13 @@ static bool EnsureDNSService() { |
180 | 180 | }
|
181 | 181 | |
182 | 182 | bool HTMLDNSPrefetch::IsAllowed(Document* aDocument) {
|
183 | + // Do not use prefetch if the document's node principal is the system
|
|
184 | + // principal.
|
|
185 | + nsCOMPtr<nsIPrincipal> principal = aDocument->NodePrincipal();
|
|
186 | + if (principal->IsSystemPrincipal()) {
|
|
187 | + return false;
|
|
188 | + }
|
|
189 | + |
|
183 | 190 | // There is no need to do prefetch on non UI scenarios such as XMLHttpRequest.
|
184 | 191 | return aDocument->IsDNSPrefetchAllowed() && aDocument->GetWindow();
|
185 | 192 | }
|
... | ... | @@ -39,6 +39,7 @@ |
39 | 39 | #include "mozilla/MouseEvents.h"
|
40 | 40 | #include "mozilla/NativeKeyBindingsType.h"
|
41 | 41 | #include "mozilla/NullPrincipal.h"
|
42 | +#include "mozilla/PointerLockManager.h"
|
|
42 | 43 | #include "mozilla/Preferences.h"
|
43 | 44 | #include "mozilla/PresShell.h"
|
44 | 45 | #include "mozilla/ProcessHangMonitor.h"
|
... | ... | @@ -3184,6 +3185,11 @@ mozilla::ipc::IPCResult BrowserChild::RecvReleaseAllPointerCapture() { |
3184 | 3185 | return IPC_OK();
|
3185 | 3186 | }
|
3186 | 3187 | |
3188 | +mozilla::ipc::IPCResult BrowserChild::RecvReleasePointerLock() {
|
|
3189 | + PointerLockManager::Unlock();
|
|
3190 | + return IPC_OK();
|
|
3191 | +}
|
|
3192 | + |
|
3187 | 3193 | PPaymentRequestChild* BrowserChild::AllocPPaymentRequestChild() {
|
3188 | 3194 | MOZ_CRASH(
|
3189 | 3195 | "We should never be manually allocating PPaymentRequestChild actors");
|
... | ... | @@ -696,6 +696,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor, |
696 | 696 | |
697 | 697 | mozilla::ipc::IPCResult RecvReleaseAllPointerCapture();
|
698 | 698 | |
699 | + mozilla::ipc::IPCResult RecvReleasePointerLock();
|
|
700 | + |
|
699 | 701 | private:
|
700 | 702 | void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
|
701 | 703 | const ScrollableLayerGuid& aGuid);
|
... | ... | @@ -4067,15 +4067,14 @@ static BrowserParent* GetTopLevelBrowserParent(BrowserParent* aBrowserParent) { |
4067 | 4067 | |
4068 | 4068 | mozilla::ipc::IPCResult BrowserParent::RecvRequestPointerLock(
|
4069 | 4069 | RequestPointerLockResolver&& aResolve) {
|
4070 | - nsCString error;
|
|
4071 | 4070 | if (sTopLevelWebFocus != GetTopLevelBrowserParent(this)) {
|
4072 | - error = "PointerLockDeniedNotFocused";
|
|
4073 | - } else if (!PointerLockManager::SetLockedRemoteTarget(this)) {
|
|
4074 | - error = "PointerLockDeniedInUse";
|
|
4075 | - } else {
|
|
4076 | - PointerEventHandler::ReleaseAllPointerCaptureRemoteTarget();
|
|
4071 | + aResolve("PointerLockDeniedNotFocused"_ns);
|
|
4072 | + return IPC_OK();
|
|
4077 | 4073 | }
|
4078 | - aResolve(error);
|
|
4074 | + |
|
4075 | + nsCString error;
|
|
4076 | + PointerLockManager::SetLockedRemoteTarget(this, error);
|
|
4077 | + aResolve(std::move(error));
|
|
4079 | 4078 | return IPC_OK();
|
4080 | 4079 | }
|
4081 | 4080 |
... | ... | @@ -557,18 +557,18 @@ parent: |
557 | 557 | |
558 | 558 | async ImageLoadComplete(nsresult aResult);
|
559 | 559 | |
560 | - /**
|
|
561 | - * Child informs the parent that a pointer lock has requested/released.
|
|
562 | - */
|
|
563 | - async RequestPointerLock() returns (nsCString error);
|
|
564 | - async ReleasePointerLock();
|
|
565 | - |
|
566 | 560 | /**
|
567 | 561 | * Child informs the parent that a pointer capture has requested/released.
|
568 | 562 | */
|
569 | 563 | async RequestPointerCapture(uint32_t aPointerId) returns (bool aSuccess);
|
570 | 564 | async ReleasePointerCapture(uint32_t aPointerId);
|
571 | 565 | |
566 | +both:
|
|
567 | + /**
|
|
568 | + * informs that a pointer lock has released.
|
|
569 | + */
|
|
570 | + async ReleasePointerLock();
|
|
571 | + |
|
572 | 572 | child:
|
573 | 573 | async NativeSynthesisResponse(uint64_t aObserverId, nsCString aResponse);
|
574 | 574 | async UpdateSHistory();
|
1 | +// |jit-test| --fast-warmup; --no-threads; skip-if: !wasmIsSupported()
|
|
2 | +function f1() {
|
|
3 | + Promise.allSettled().catch(e => null);
|
|
4 | + do {
|
|
5 | + f2(10n, -1n);
|
|
6 | + try {
|
|
7 | + f2(-2147483648n);
|
|
8 | + } catch {}
|
|
9 | + } while (!inIon());
|
|
10 | +}
|
|
11 | +function f2(x, y) {
|
|
12 | + const z = x >> x;
|
|
13 | + z <= z ? z : z;
|
|
14 | + y ^ y;
|
|
15 | +}
|
|
16 | +const binary = wasmTextToBinary(`
|
|
17 | + (module
|
|
18 | + (import "m" "f" (func $f))
|
|
19 | + (func (export "test")
|
|
20 | + (call $f)
|
|
21 | + )
|
|
22 | + )
|
|
23 | +`);
|
|
24 | +const mod = new WebAssembly.Module(binary);
|
|
25 | +const inst = new WebAssembly.Instance(mod, {"m": {"f": f1}});
|
|
26 | +for (let i = 0; i < 6; i++) {
|
|
27 | + inst.exports.test();
|
|
28 | +} |
1 | +// |jit-test| --fast-warmup; --gc-zeal=21,100; skip-if: !wasmIsSupported()
|
|
2 | +let counter = 0;
|
|
3 | +function g() {
|
|
4 | + counter++;
|
|
5 | + const y = BigInt.asIntN(counter, -883678545n);
|
|
6 | + const z = y >> y;
|
|
7 | + BigInt.asUintN(2 ** counter, 883678545n);
|
|
8 | + try { g(); } catch (e) { }
|
|
9 | +}
|
|
10 | +function f() {
|
|
11 | + for (let i = 0; i < 5; i++) {
|
|
12 | + for (let j = 0; j < 30; j++) { }
|
|
13 | + Promise.allSettled().catch(e => null);
|
|
14 | + counter = 0;
|
|
15 | + g();
|
|
16 | + }
|
|
17 | +}
|
|
18 | +const binary = wasmTextToBinary(`(module (import "m" "f" (func $f)) (func (export "test") (call $f)))`);
|
|
19 | +const mod = new WebAssembly.Module(binary);
|
|
20 | +const inst = new WebAssembly.Instance(mod, { m: { f: f } });
|
|
21 | +for (let i = 0; i < 100; i++) { }
|
|
22 | +for (let i = 0; i < 5; i++) {
|
|
23 | + inst.exports.test();
|
|
24 | +} |
... | ... | @@ -26,22 +26,29 @@ using namespace js; |
26 | 26 | using namespace js::jit;
|
27 | 27 | |
28 | 28 | JSJitFrameIter::JSJitFrameIter(const JitActivation* activation)
|
29 | - : JSJitFrameIter(activation, FrameType::Exit, activation->jsExitFP()) {}
|
|
30 | - |
|
31 | -JSJitFrameIter::JSJitFrameIter(const JitActivation* activation,
|
|
32 | - FrameType frameType, uint8_t* fp)
|
|
33 | - : current_(fp),
|
|
34 | - type_(frameType),
|
|
35 | - resumePCinCurrentFrame_(nullptr),
|
|
36 | - cachedSafepointIndex_(nullptr),
|
|
29 | + : current_(activation->jsExitFP()),
|
|
30 | + type_(FrameType::Exit),
|
|
37 | 31 | activation_(activation) {
|
38 | - MOZ_ASSERT(type_ == FrameType::JSJitToWasm || type_ == FrameType::Exit);
|
|
32 | + // If we're currently performing a bailout, we have to use the activation's
|
|
33 | + // bailout data when we start iterating over the activation's frames.
|
|
39 | 34 | if (activation_->bailoutData()) {
|
40 | 35 | current_ = activation_->bailoutData()->fp();
|
41 | 36 | type_ = FrameType::Bailout;
|
42 | - } else {
|
|
43 | - MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
|
|
44 | 37 | }
|
38 | + MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
|
|
39 | +}
|
|
40 | + |
|
41 | +JSJitFrameIter::JSJitFrameIter(const JitActivation* activation,
|
|
42 | + FrameType frameType, uint8_t* fp)
|
|
43 | + : current_(fp), type_(frameType), activation_(activation) {
|
|
44 | + // This constructor is only used when resuming iteration after iterating Wasm
|
|
45 | + // frames in the same JitActivation so ignore activation_->bailoutData().
|
|
46 | + //
|
|
47 | + // Note: FrameType::JSJitToWasm is used for JIT => Wasm calls through the Wasm
|
|
48 | + // JIT entry trampoline. FrameType::Exit is used for direct Ion => Wasm calls.
|
|
49 | + MOZ_ASSERT(fp > activation->jsOrWasmExitFP());
|
|
50 | + MOZ_ASSERT(type_ == FrameType::JSJitToWasm || type_ == FrameType::Exit);
|
|
51 | + MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
|
|
45 | 52 | }
|
46 | 53 | |
47 | 54 | bool JSJitFrameIter::checkInvalidation() const {
|
... | ... | @@ -111,14 +111,14 @@ class JSJitFrameIter { |
111 | 111 | protected:
|
112 | 112 | uint8_t* current_;
|
113 | 113 | FrameType type_;
|
114 | - uint8_t* resumePCinCurrentFrame_;
|
|
114 | + uint8_t* resumePCinCurrentFrame_ = nullptr;
|
|
115 | 115 | |
116 | 116 | // Size of the current Baseline frame. Equivalent to
|
117 | 117 | // BaselineFrame::debugFrameSize_ in debug builds.
|
118 | 118 | mozilla::Maybe<uint32_t> baselineFrameSize_;
|
119 | 119 | |
120 | 120 | private:
|
121 | - mutable const SafepointIndex* cachedSafepointIndex_;
|
|
121 | + mutable const SafepointIndex* cachedSafepointIndex_ = nullptr;
|
|
122 | 122 | const JitActivation* activation_;
|
123 | 123 | |
124 | 124 | void dumpBaseline() const;
|
... | ... | @@ -8463,24 +8463,46 @@ void PresShell::EventHandler::MaybeHandleKeyboardEventBeforeDispatch( |
8463 | 8463 | |
8464 | 8464 | // The event listeners in chrome can prevent this ESC behavior by
|
8465 | 8465 | // calling prevent default on the preceding keydown/press events.
|
8466 | - if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed &&
|
|
8467 | - aKeyboardEvent->mMessage == eKeyUp) {
|
|
8468 | - // ESC key released while in DOM fullscreen mode.
|
|
8469 | - // Fully exit all browser windows and documents from
|
|
8470 | - // fullscreen mode.
|
|
8471 | - Document::AsyncExitFullscreen(nullptr);
|
|
8466 | + if (aKeyboardEvent->mMessage == eKeyUp) {
|
|
8467 | + bool shouldExitFullscreen =
|
|
8468 | + !mPresShell->mIsLastChromeOnlyEscapeKeyConsumed;
|
|
8469 | + if (!shouldExitFullscreen) {
|
|
8470 | + if (mPresShell->mLastConsumedEscapeKeyUpForFullscreen &&
|
|
8471 | + (aKeyboardEvent->mTimeStamp -
|
|
8472 | + mPresShell->mLastConsumedEscapeKeyUpForFullscreen) <=
|
|
8473 | + TimeDuration::FromMilliseconds(
|
|
8474 | + StaticPrefs::
|
|
8475 | + dom_fullscreen_force_exit_on_multiple_escape_interval())) {
|
|
8476 | + shouldExitFullscreen = true;
|
|
8477 | + mPresShell->mLastConsumedEscapeKeyUpForFullscreen = TimeStamp();
|
|
8478 | + } else {
|
|
8479 | + mPresShell->mLastConsumedEscapeKeyUpForFullscreen =
|
|
8480 | + aKeyboardEvent->mTimeStamp;
|
|
8481 | + }
|
|
8482 | + }
|
|
8483 | + |
|
8484 | + if (shouldExitFullscreen) {
|
|
8485 | + // ESC key released while in DOM fullscreen mode.
|
|
8486 | + // Fully exit all browser windows and documents from
|
|
8487 | + // fullscreen mode.
|
|
8488 | + Document::AsyncExitFullscreen(nullptr);
|
|
8489 | + }
|
|
8472 | 8490 | }
|
8473 | 8491 | }
|
8474 | 8492 | |
8475 | - nsCOMPtr<Document> pointerLockedDoc = PointerLockManager::GetLockedDocument();
|
|
8476 | - if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed && pointerLockedDoc) {
|
|
8477 | - // XXX See above comment to understand the reason why this needs
|
|
8478 | - // to claim that the Escape key event is consumed by content
|
|
8479 | - // even though it will be dispatched only into chrome.
|
|
8480 | - aKeyboardEvent->PreventDefaultBeforeDispatch(CrossProcessForwarding::eStop);
|
|
8481 | - aKeyboardEvent->mFlags.mOnlyChromeDispatch = true;
|
|
8482 | - if (aKeyboardEvent->mMessage == eKeyUp) {
|
|
8483 | - PointerLockManager::Unlock();
|
|
8493 | + if (XRE_IsParentProcess() &&
|
|
8494 | + !mPresShell->mIsLastChromeOnlyEscapeKeyConsumed) {
|
|
8495 | + if (PointerLockManager::GetLockedRemoteTarget() ||
|
|
8496 | + PointerLockManager::IsLocked()) {
|
|
8497 | + // XXX See above comment to understand the reason why this needs
|
|
8498 | + // to claim that the Escape key event is consumed by content
|
|
8499 | + // even though it will be dispatched only into chrome.
|
|
8500 | + aKeyboardEvent->PreventDefaultBeforeDispatch(
|
|
8501 | + CrossProcessForwarding::eStop);
|
|
8502 | + aKeyboardEvent->mFlags.mOnlyChromeDispatch = true;
|
|
8503 | + if (aKeyboardEvent->mMessage == eKeyUp) {
|
|
8504 | + PointerLockManager::Unlock();
|
|
8505 | + }
|
|
8484 | 8506 | }
|
8485 | 8507 | }
|
8486 | 8508 | }
|
... | ... | @@ -3209,6 +3209,10 @@ class PresShell final : public nsStubDocumentObserver, |
3209 | 3209 | bool mProcessingReflowCommands : 1;
|
3210 | 3210 | bool mPendingDidDoReflow : 1;
|
3211 | 3211 | |
3212 | + // The last TimeStamp when the keyup event did not exit fullscreen because it
|
|
3213 | + // was consumed.
|
|
3214 | + TimeStamp mLastConsumedEscapeKeyUpForFullscreen;
|
|
3215 | + |
|
3212 | 3216 | struct CapturingContentInfo final {
|
3213 | 3217 | CapturingContentInfo()
|
3214 | 3218 | : mRemoteTarget(nullptr),
|
... | ... | @@ -855,7 +855,7 @@ size_t nsCaret::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { |
855 | 855 | bool nsCaret::IsMenuPopupHidingCaret() {
|
856 | 856 | // Check if there are open popups.
|
857 | 857 | nsXULPopupManager* popMgr = nsXULPopupManager::GetInstance();
|
858 | - nsTArray<nsIFrame*> popups;
|
|
858 | + nsTArray<nsMenuPopupFrame*> popups;
|
|
859 | 859 | popMgr->GetVisiblePopups(popups);
|
860 | 860 | |
861 | 861 | if (popups.Length() == 0)
|
... | ... | @@ -873,7 +873,7 @@ bool nsCaret::IsMenuPopupHidingCaret() { |
873 | 873 | // If there's a menu popup open before the popup with
|
874 | 874 | // the caret, don't show the caret.
|
875 | 875 | for (uint32_t i = 0; i < popups.Length(); i++) {
|
876 | - nsMenuPopupFrame* popupFrame = static_cast<nsMenuPopupFrame*>(popups[i]);
|
|
876 | + nsMenuPopupFrame* popupFrame = popups[i];
|
|
877 | 877 | nsIContent* popupContent = popupFrame->GetContent();
|
878 | 878 | |
879 | 879 | if (caretContent->IsInclusiveDescendantOf(popupContent)) {
|
... | ... | @@ -138,6 +138,7 @@ |
138 | 138 | #include "nsIScrollableFrame.h"
|
139 | 139 | #include "nsIWidget.h"
|
140 | 140 | #include "nsListControlFrame.h"
|
141 | +#include "nsMenuPopupFrame.h"
|
|
141 | 142 | #include "nsPIDOMWindow.h"
|
142 | 143 | #include "nsPlaceholderFrame.h"
|
143 | 144 | #include "nsPresContext.h"
|
... | ... | @@ -1757,10 +1758,10 @@ nsIFrame* nsLayoutUtils::GetPopupFrameForPoint( |
1757 | 1758 | if (!pm) {
|
1758 | 1759 | return nullptr;
|
1759 | 1760 | }
|
1760 | - nsTArray<nsIFrame*> popups;
|
|
1761 | + nsTArray<nsMenuPopupFrame*> popups;
|
|
1761 | 1762 | pm->GetVisiblePopups(popups);
|
1762 | 1763 | // Search from top to bottom
|
1763 | - for (nsIFrame* popup : popups) {
|
|
1764 | + for (nsMenuPopupFrame* popup : popups) {
|
|
1764 | 1765 | if (popup->PresContext()->GetRootPresContext() != aRootPresContext) {
|
1765 | 1766 | continue;
|
1766 | 1767 | }
|
... | ... | @@ -53,6 +53,7 @@ |
53 | 53 | #include "mozilla/EventStateManager.h"
|
54 | 54 | #include "mozilla/LookAndFeel.h"
|
55 | 55 | #include "mozilla/MouseEvents.h"
|
56 | +#include "mozilla/PointerLockManager.h"
|
|
56 | 57 | #include "mozilla/PresShell.h"
|
57 | 58 | #include "mozilla/Services.h"
|
58 | 59 | #include "mozilla/StaticPrefs_layout.h"
|
... | ... | @@ -987,6 +988,7 @@ bool nsXULPopupManager::ShowPopupAsNativeMenu(Element* aPopup, int32_t aXPos, |
987 | 988 | EventStateManager::ClearGlobalActiveContent(activeESM);
|
988 | 989 | activeESM->StopTrackingDragGesture(true);
|
989 | 990 | }
|
991 | + PointerLockManager::Unlock();
|
|
990 | 992 | PresShell::ReleaseCapturingContent();
|
991 | 993 | |
992 | 994 | return true;
|
... | ... | @@ -1201,6 +1203,10 @@ void nsXULPopupManager::ShowPopupCallback(Element* aPopup, |
1201 | 1203 | // Caret visibility may have been affected, ensure that
|
1202 | 1204 | // the caret isn't now drawn when it shouldn't be.
|
1203 | 1205 | CheckCaretDrawingState();
|
1206 | + |
|
1207 | + if (popupType != PopupType::Tooltip) {
|
|
1208 | + PointerLockManager::Unlock();
|
|
1209 | + }
|
|
1204 | 1210 | }
|
1205 | 1211 | |
1206 | 1212 | nsMenuChainItem* nsXULPopupManager::FindPopup(Element* aPopup) const {
|
... | ... | @@ -1851,8 +1857,17 @@ nsIContent* nsXULPopupManager::GetTopActiveMenuItemContent() { |
1851 | 1857 | return nullptr;
|
1852 | 1858 | }
|
1853 | 1859 | |
1854 | -void nsXULPopupManager::GetVisiblePopups(nsTArray<nsIFrame*>& aPopups) {
|
|
1860 | +void nsXULPopupManager::GetVisiblePopups(nsTArray<nsMenuPopupFrame*>& aPopups,
|
|
1861 | + bool aIncludeNativeMenu) {
|
|
1855 | 1862 | aPopups.Clear();
|
1863 | + if (aIncludeNativeMenu && mNativeMenu) {
|
|
1864 | + nsCOMPtr<nsIContent> popup = mNativeMenu->Element();
|
|
1865 | + nsMenuPopupFrame* popupFrame = GetPopupFrameForContent(popup, true);
|
|
1866 | + if (popupFrame && popupFrame->IsVisible() &&
|
|
1867 | + !popupFrame->IsMouseTransparent()) {
|
|
1868 | + aPopups.AppendElement(popupFrame);
|
|
1869 | + }
|
|
1870 | + }
|
|
1856 | 1871 | for (nsMenuChainItem* item = mPopups.get(); item; item = item->GetParent()) {
|
1857 | 1872 | // Skip panels which are not visible as well as popups that are transparent
|
1858 | 1873 | // to mouse events.
|
... | ... | @@ -184,10 +184,10 @@ using HidePopupOptions = mozilla::EnumSet<HidePopupOption>; |
184 | 184 | */
|
185 | 185 | extern const nsNavigationDirection DirectionFromKeyCodeTable[2][6];
|
186 | 186 | |
187 | -#define NS_DIRECTION_FROM_KEY_CODE(frame, keycode) \
|
|
188 | - (DirectionFromKeyCodeTable[static_cast<uint8_t>( \
|
|
189 | - (frame)->StyleVisibility()->mDirection)][( \
|
|
190 | - keycode)-mozilla::dom::KeyboardEvent_Binding::DOM_VK_END])
|
|
187 | +#define NS_DIRECTION_FROM_KEY_CODE(frame, keycode) \
|
|
188 | + (DirectionFromKeyCodeTable \
|
|
189 | + [static_cast<uint8_t>((frame)->StyleVisibility()->mDirection)] \
|
|
190 | + [(keycode) - mozilla::dom::KeyboardEvent_Binding::DOM_VK_END])
|
|
191 | 191 | |
192 | 192 | // Used to hold information about a popup that is about to be opened.
|
193 | 193 | struct PendingPopup {
|
... | ... | @@ -601,8 +601,10 @@ class nsXULPopupManager final : public nsIDOMEventListener, |
601 | 601 | /**
|
602 | 602 | * Return an array of all the open and visible popup frames for
|
603 | 603 | * menus, in order from top to bottom.
|
604 | + * XXX should we always include native menu?
|
|
604 | 605 | */
|
605 | - void GetVisiblePopups(nsTArray<nsIFrame*>& aPopups);
|
|
606 | + void GetVisiblePopups(nsTArray<nsMenuPopupFrame*>& aPopups,
|
|
607 | + bool aIncludeNativeMenu = false);
|
|
606 | 608 | |
607 | 609 | /**
|
608 | 610 | * Get the node that last triggered a popup or tooltip in the document
|
... | ... | @@ -2701,6 +2701,13 @@ |
2701 | 2701 | value: false
|
2702 | 2702 | mirror: always
|
2703 | 2703 | |
2704 | +# The interval in milliseconds between two Escape key events where the second
|
|
2705 | +# key event will exit fullscreen, even if it is consumed.
|
|
2706 | +- name: dom.fullscreen.force_exit_on_multiple_escape_interval
|
|
2707 | + type: uint32_t
|
|
2708 | + value: 500
|
|
2709 | + mirror: always
|
|
2710 | + |
|
2704 | 2711 | # Whether fullscreen should make the rest of the document inert.
|
2705 | 2712 | # This matches other browsers but historically not Gecko.
|
2706 | 2713 | - name: dom.fullscreen.modal
|
... | ... | @@ -11417,6 +11424,11 @@ |
11417 | 11424 | value: false
|
11418 | 11425 | mirror: always
|
11419 | 11426 | |
11427 | +- name: network.cookie.sameSite.crossSiteIframeSetCheck
|
|
11428 | + type: bool
|
|
11429 | + value: true
|
|
11430 | + mirror: always
|
|
11431 | + |
|
11420 | 11432 | - name: network.cookie.thirdparty.sessionOnly
|
11421 | 11433 | type: bool
|
11422 | 11434 | value: false
|
... | ... | @@ -675,6 +675,18 @@ CookieService::SetCookieStringFromHttp(nsIURI* aHostURI, |
675 | 675 | if (!addonAllowsLoad) {
|
676 | 676 | mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI,
|
677 | 677 | &isForeignAndNotAddon);
|
678 | + |
|
679 | + // include sub-document navigations from cross-site to same-site
|
|
680 | + // wrt top-level in our check for thirdparty-ness
|
|
681 | + if (StaticPrefs::network_cookie_sameSite_crossSiteIframeSetCheck() &&
|
|
682 | + !isForeignAndNotAddon &&
|
|
683 | + loadInfo->GetExternalContentPolicyType() ==
|
|
684 | + ExtContentPolicy::TYPE_SUBDOCUMENT) {
|
|
685 | + bool triggeringPrincipalIsThirdParty = false;
|
|
686 | + BasePrincipal::Cast(loadInfo->TriggeringPrincipal())
|
|
687 | + ->IsThirdPartyURI(channelURI, &triggeringPrincipalIsThirdParty);
|
|
688 | + isForeignAndNotAddon |= triggeringPrincipalIsThirdParty;
|
|
689 | + }
|
|
678 | 690 | }
|
679 | 691 | |
680 | 692 | nsCString cookieHeader(aCookieHeader);
|
... | ... | @@ -517,6 +517,18 @@ CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI, |
517 | 517 | if (!addonAllowsLoad) {
|
518 | 518 | mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI,
|
519 | 519 | &isForeignAndNotAddon);
|
520 | + |
|
521 | + // include sub-document navigations from cross-site to same-site
|
|
522 | + // wrt top-level in our check for thirdparty-ness
|
|
523 | + if (StaticPrefs::network_cookie_sameSite_crossSiteIframeSetCheck() &&
|
|
524 | + !isForeignAndNotAddon &&
|
|
525 | + loadInfo->GetExternalContentPolicyType() ==
|
|
526 | + ExtContentPolicy::TYPE_SUBDOCUMENT) {
|
|
527 | + bool triggeringPrincipalIsThirdParty = false;
|
|
528 | + BasePrincipal::Cast(loadInfo->TriggeringPrincipal())
|
|
529 | + ->IsThirdPartyURI(finalChannelURI, &triggeringPrincipalIsThirdParty);
|
|
530 | + isForeignAndNotAddon |= triggeringPrincipalIsThirdParty;
|
|
531 | + }
|
|
520 | 532 | }
|
521 | 533 | |
522 | 534 | bool moreCookies;
|
1 | 1 | [setcookie-navigation.https.html]
|
2 | + prefs: [network.cookie.sameSite.laxByDefault:true, network.cookie.sameSite.noneRequiresSecure:true]
|
|
2 | 3 | expected:
|
3 | 4 | if (os == "android") and fission: [OK, TIMEOUT] |
4 | - [Cross-site to same-site iframe navigation should only be able to set SameSite=None cookies.]
|
|
5 | - expected: FAIL
|
|
6 | - |
|
7 | - [Same-site to cross-site-site iframe navigation should only be able to set SameSite=None cookies.]
|
|
8 | - expected: FAIL
|
|
9 | - |
|
10 | - [Cross-site to cross-site iframe navigation should only be able to set SameSite=None cookies.]
|
|
11 | - expected: FAIL |