mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1790253: Check whether elements having 'display: contents' style is apz aware. r=botond,smaug,emilio
Differential Revision: https://phabricator.services.mozilla.com/D159378
This commit is contained in:
parent
5804f40537
commit
6f6246b2a2
@ -115,6 +115,9 @@ support-files =
|
||||
engine2/manifest.json
|
||||
[browser_searchFindMoreLink.js]
|
||||
[browser_searchRestoreDefaults.js]
|
||||
[browser_searchScroll.js]
|
||||
support-files =
|
||||
!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
|
||||
[browser_searchShowSuggestionsFirst.js]
|
||||
[browser_searchsuggestions.js]
|
||||
[browser_security-1.js]
|
||||
|
67
browser/components/preferences/tests/browser_searchScroll.js
Normal file
67
browser/components/preferences/tests/browser_searchScroll.js
Normal file
@ -0,0 +1,67 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* import-globals-from ../../../../gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js",
|
||||
this
|
||||
);
|
||||
|
||||
const { AddonTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/AddonTestUtils.jsm"
|
||||
);
|
||||
const { SearchTestUtils } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/SearchTestUtils.sys.mjs"
|
||||
);
|
||||
const { SearchUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/SearchUtils.sys.mjs"
|
||||
);
|
||||
|
||||
AddonTestUtils.initMochitest(this);
|
||||
SearchTestUtils.init(this);
|
||||
|
||||
add_setup(async function() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["dom.w3c_touch_events.enabled", 0]],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_scroll() {
|
||||
info("Open preferences page for search");
|
||||
await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
|
||||
|
||||
const doc = gBrowser.selectedBrowser.contentDocument;
|
||||
const tree = doc.querySelector("#engineList");
|
||||
|
||||
info("Add engines to make the tree scrollable");
|
||||
for (let i = 0, n = parseInt(tree.getAttribute("rows")); i < n; i++) {
|
||||
let extension = await SearchTestUtils.installSearchExtension({
|
||||
id: `${i}@tests.mozilla.org`,
|
||||
name: `example${i}`,
|
||||
version: "1.0",
|
||||
keyword: `example${i}`,
|
||||
});
|
||||
await AddonTestUtils.waitForSearchProviderStartup(extension);
|
||||
}
|
||||
|
||||
info("Make tree element move into viewport");
|
||||
const mainContent = doc.querySelector(".main-content");
|
||||
const readyForScrollIntoView = new Promise(r => {
|
||||
mainContent.addEventListener("scroll", r, { once: true });
|
||||
});
|
||||
tree.scrollIntoView();
|
||||
await readyForScrollIntoView;
|
||||
|
||||
const previousScroll = mainContent.scrollTop;
|
||||
|
||||
await promiseMoveMouseAndScrollWheelOver(tree, 1, 1, false);
|
||||
|
||||
Assert.equal(
|
||||
previousScroll,
|
||||
mainContent.scrollTop,
|
||||
"Container element does not scroll"
|
||||
);
|
||||
|
||||
info("Clean up");
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
@ -2833,18 +2833,37 @@ class AutoSaveRestoreContainsBlendMode {
|
||||
}
|
||||
};
|
||||
|
||||
static bool IsFrameOrAncestorApzAware(nsIFrame* aFrame) {
|
||||
nsIContent* node = aFrame->GetContent();
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if (node->IsNodeApzAware()) {
|
||||
return true;
|
||||
}
|
||||
nsIContent* shadowRoot = node->GetShadowRoot();
|
||||
if (shadowRoot && shadowRoot->IsNodeApzAware()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Even if the node owning aFrame doesn't have apz-aware event listeners
|
||||
// itself, its shadow root or display: contents ancestors (which have no
|
||||
// frames) might, so we need to account for them too.
|
||||
} while ((node = node->GetFlattenedTreeParent()) && node->IsElement() &&
|
||||
node->AsElement()->IsDisplayContents());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void CheckForApzAwareEventHandlers(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame) {
|
||||
if (aBuilder->GetAncestorHasApzAwareEventHandler()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (content->IsNodeApzAware()) {
|
||||
if (IsFrameOrAncestorApzAware(aFrame)) {
|
||||
aBuilder->SetAncestorHasApzAwareEventHandler(true);
|
||||
}
|
||||
}
|
||||
|
@ -154,3 +154,5 @@ support-files =
|
||||
file_reframe_for_lazy_load_image.html
|
||||
[test_bug1655135.html]
|
||||
[test_bug1756831.html]
|
||||
[test_scroll_on_display_contents.html]
|
||||
support-files = !/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
|
||||
|
187
layout/generic/test/test_scroll_on_display_contents.html
Normal file
187
layout/generic/test/test_scroll_on_display_contents.html
Normal file
@ -0,0 +1,187 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1790253
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1790253</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<script src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
|
||||
<script src="/tests/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1790253">Mozilla Bug 1790253</a>
|
||||
<p id="display"></p>
|
||||
<style>
|
||||
.container {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
overflow: scroll;
|
||||
background-color: gray;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await testShadowRoot();
|
||||
await testShadowRootInDisplayContent();
|
||||
await testNestedShadowRoot();
|
||||
await testDisplayContent();
|
||||
await testNestedDisplayContent();
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
async function testShadowRoot() {
|
||||
// Structure:
|
||||
// <div class="container">
|
||||
// #ShadowRoot - Listener
|
||||
// <div style="height: 300px; background: linear-gradient(#e66465, #9198e5);">
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("container");
|
||||
container.attachShadow({ mode: "open" });
|
||||
container.shadowRoot.innerHTML = `
|
||||
<div style="height: 300px; background: linear-gradient(#e66465, #9198e5);"></div>
|
||||
`;
|
||||
|
||||
container.shadowRoot.addEventListener("wheel", e => { e.preventDefault(); });
|
||||
|
||||
document.body.append(container);
|
||||
await doTest(container);
|
||||
container.remove();
|
||||
}
|
||||
|
||||
async function testShadowRootInDisplayContent() {
|
||||
// Structure:
|
||||
// <div class="container">
|
||||
// <div style="display: contents">
|
||||
// #ShadowRoot - Listener
|
||||
// <div style="display: contents">
|
||||
// <div style="display: contents">
|
||||
// <div style="height: 300px; background: linear-gradient(#e66465, #9198e5);">
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("container");
|
||||
container.innerHTML = `
|
||||
<div style="display: contents"></div>
|
||||
`;
|
||||
const displayContent = container.querySelector("div");
|
||||
displayContent.attachShadow({ mode: "open" });
|
||||
displayContent.shadowRoot.innerHTML = `
|
||||
<div style="display: contents">
|
||||
<div style="display: contents">
|
||||
<div style="height: 300px; background: linear-gradient(#e66465, #9198e5);"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
displayContent.shadowRoot.addEventListener("wheel", e => { e.preventDefault(); });
|
||||
|
||||
document.body.append(container);
|
||||
await doTest(container);
|
||||
container.remove();
|
||||
}
|
||||
|
||||
async function testNestedShadowRoot() {
|
||||
// Structure:
|
||||
// <div class="container">
|
||||
// <div style="display: contents">
|
||||
// #ShadowRoot - Listener
|
||||
// <div style="display: contents">
|
||||
// #ShadowRoot
|
||||
// <div style="display: contents">
|
||||
// <div style="display: contents">
|
||||
// <div style="height: 300px; background: linear-gradient(#e66465, #9198e5);">
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("container");
|
||||
container.innerHTML = `
|
||||
<div style="display: contents"></div>
|
||||
`;
|
||||
|
||||
const firstDisplayContent = container.querySelector("div");
|
||||
firstDisplayContent.attachShadow({ mode: "open" });
|
||||
firstDisplayContent.shadowRoot.innerHTML = `
|
||||
<div style="display: contents"></div>
|
||||
`;
|
||||
firstDisplayContent.shadowRoot.addEventListener("wheel", e => { e.preventDefault(); });
|
||||
|
||||
const secondDisplayContent = firstDisplayContent.shadowRoot.querySelector("div");
|
||||
secondDisplayContent.attachShadow({ mode: "open" });
|
||||
firstDisplayContent.shadowRoot.innerHTML = `
|
||||
<div style="display: contents">
|
||||
<div style="display: contents">
|
||||
<div style="height: 300px; background: linear-gradient(#e66465, #9198e5);"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.append(container);
|
||||
await doTest(container);
|
||||
container.remove();
|
||||
}
|
||||
|
||||
async function testDisplayContent() {
|
||||
// Structure:
|
||||
// <div class="container">
|
||||
// <div style="display: contents"> - Listener
|
||||
// <div style="height: 300px; background: linear-gradient(#e66465, #9198e5);">
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("container");
|
||||
container.innerHTML = `
|
||||
<div style="display: contents">
|
||||
<div style="height: 300px; background: linear-gradient(#e66465, #9198e5);"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const displayContent = container.querySelector("div");
|
||||
displayContent.addEventListener("wheel", e => { e.preventDefault(); });
|
||||
|
||||
document.body.append(container);
|
||||
await doTest(container);
|
||||
container.remove();
|
||||
}
|
||||
|
||||
async function testNestedDisplayContent() {
|
||||
// Structure:
|
||||
// <div class="container">
|
||||
// <div style="display: contents"> - Listener
|
||||
// <div style="display: contents">
|
||||
// <div style="height: 300px; background: linear-gradient(#e66465, #9198e5);">
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("container");
|
||||
container.innerHTML = `
|
||||
<div style="display: contents">
|
||||
<div style="display: contents">
|
||||
<div style="height: 300px; background: linear-gradient(#e66465, #9198e5);"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const displayContent = container.querySelector("div");
|
||||
displayContent.addEventListener("wheel", e => { e.preventDefault(); });
|
||||
|
||||
document.body.append(container);
|
||||
await doTest(container);
|
||||
container.remove();
|
||||
}
|
||||
|
||||
async function doTest(target) {
|
||||
await promiseAllPaintsDone();
|
||||
|
||||
const previousScroll = target.scrollTop;
|
||||
|
||||
await promiseMoveMouseAndScrollWheelOver(target, 1, 1, false);
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
is(previousScroll, target.scrollTop, "The target should not be scrolled");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user