Bug 1782142 - Use unretargeted element to specify the active element for touch; r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D153514
This commit is contained in:
Edgar Chen 2022-08-08 11:22:01 +00:00
Родитель 215af10b6a
Коммит 0c6ca7991f
5 изменённых файлов: 80 добавлений и 4 удалений

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

@ -102,15 +102,23 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(Touch)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Touch)
EventTarget* Touch::GetTarget() const {
nsIContent* content = nsIContent::FromEventTargetOrNull(mTarget);
static EventTarget* FindFirstNonChromeOnlyAccessContent(EventTarget* aTarget) {
nsIContent* content = nsIContent::FromEventTargetOrNull(aTarget);
if (content && content->ChromeOnlyAccess() &&
!nsContentUtils::LegacyIsCallerNativeCode() &&
!nsContentUtils::CanAccessNativeAnon()) {
return content->FindFirstNonChromeOnlyAccessContent();
}
return mTarget;
return aTarget;
}
EventTarget* Touch::GetTarget() const {
return FindFirstNonChromeOnlyAccessContent(mTarget);
}
EventTarget* Touch::GetOriginalTarget() const {
return FindFirstNonChromeOnlyAccessContent(mOriginalTarget);
}
int32_t Touch::ScreenX(CallerType aCallerType) const {

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

@ -70,6 +70,8 @@ class Touch final : public nsISupports,
float RotationAngle(CallerType aCallerType) const;
float Force(CallerType aCallerType) const;
EventTarget* GetOriginalTarget() const;
nsCOMPtr<EventTarget> mOriginalTarget;
nsCOMPtr<EventTarget> mTarget;
LayoutDeviceIntPoint mRefPoint;

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

@ -36,6 +36,9 @@ support-files =
[test_event_stopping.html]
[test_template.html]
[test_template_xhtml.html]
[test_shadowdom_active_pseudo_class.html]
support-files =
!/gfx/layers/apz/test/mochitest/apz_test_utils.js
[test_shadowdom_ime.html]
[test_shadowroot.html]
[test_shadowroot_clonenode.html]

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

@ -0,0 +1,62 @@
<!DOCTYPE HTML>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1782142
-->
<title>Test :active pseudo-class in shadow DOM</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<script src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1062578">Bug 1782142</a>
<div id="host"></div>
<script>
let { ContentTaskUtils } = SpecialPowers.ChromeUtils.import(
"resource://testing-common/ContentTaskUtils.jsm"
);
// Setup shadow DOM
const host = document.querySelector("#host");
const sr = host.attachShadow({mode: "closed"});
const button = document.createElement("button");
button.innerText = "button";
sr.appendChild(button);
add_task(async function init() {
await SpecialPowers.pushPrefEnv({set: [["test.events.async.enabled", true]]});
await waitUntilApzStable();
});
add_task(async function mouse_input() {
ok(!button.matches(":active"), "Button should not be active initially");
synthesizeMouseAtCenter(button, { type: "mousedown" });
await ContentTaskUtils.waitForCondition(() => {
return button.matches(":active");
}, "Button should be active");
synthesizeMouseAtCenter(button, { type: "mouseup" });
await ContentTaskUtils.waitForCondition(() => {
return !button.matches(":active");
}, "Button should not be active");
});
add_task(async function touch_input() {
// To avoid contextmenu showing up during test.
document.addEventListener("contextmenu", (e) => {
e.preventDefault();
}, { once: true });
ok(!button.matches(":active"), "Button should not be active initially");
synthesizeTouchAtCenter(button, { type: "touchstart" });
await ContentTaskUtils.waitForCondition(() => {
return button.matches(":active");
}, "Button should be active");
synthesizeTouchAtCenter(button, { type: "touchend" });
await ContentTaskUtils.waitForCondition(() => {
return !button.matches(":active");
}, "Button should not be active");
});
</script>

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

@ -338,7 +338,8 @@ void APZEventState::ProcessTouchEvent(
nsEventStatus aContentResponse,
nsTArray<TouchBehaviorFlags>&& aAllowedTouchBehaviors) {
if (aEvent.mMessage == eTouchStart && aEvent.mTouches.Length() > 0) {
mActiveElementManager->SetTargetElement(aEvent.mTouches[0]->GetTarget());
mActiveElementManager->SetTargetElement(
aEvent.mTouches[0]->GetOriginalTarget());
mLastTouchIdentifier = aEvent.mTouches[0]->Identifier();
}
if (aEvent.mMessage == eTouchStart) {