Bug 1457336: Teach nsFind about display in general. r=mats

I ended up not using the nsIFrame methods both for consistency with the plain
text serializer and because of include hell due to nsStyleStructInlines /
nsIFrameInlines.

Find doesn't care about nodes with no frames anyway, so it didn't seem worth
doing the fallback if there's no style information.

I'll file a bug for IsHTMLBlock.

MozReview-Commit-ID: 3T317a4xCB
This commit is contained in:
Emilio Cobos Álvarez 2018-04-27 01:55:48 +02:00
Родитель 340d7141bb
Коммит cb363f61b7
3 изменённых файлов: 83 добавлений и 5 удалений

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

@ -652,6 +652,8 @@ skip-if = toolkit == 'android' #bug 904183
[test_eventsource_event_listener_leaks.html]
[test_explicit_user_agent.html]
skip-if = (toolkit == 'android') # Android: Bug 775227
[test_find.html]
skip-if = (toolkit == 'android') # Android: Bug 1465387
[test_getAttribute_after_createAttribute.html]
[test_getElementById.html]
[test_getTranslationNodes.html]

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

@ -0,0 +1,74 @@
<!doctype html>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const t = async_test("Test window.find / nsFind");
function testFindable(isFindable, textToFind, docText, description) {
try{
const iframe = document.querySelector("iframe")
iframe.contentDocument.documentElement.innerHTML = docText;
iframe.contentWindow.getSelection().removeAllRanges();
assert_equals(
isFindable,
iframe.contentWindow.find(textToFind),
"Should be " + (isFindable ? "" : "not ") + "findable: " + description + ", text: " + textToFind
);
} catch (ex) {
assert_unreached(ex);
}
}
const INLINE_LIKE_DISPLAY_VALUES = [
"inline",
"inline-grid",
"inline-block",
"inline-flex",
];
const BLOCK_LIKE_DISPLAY_VALUES = [
"block",
"table",
"list-item",
"grid",
"flex",
];
window.runTests = t.step_func_done(function() {
testFindable(true, "me and me", `
me <div style="display: contents">and</div> me
`, "display: contents");
testFindable(true, "me me", `
me <div style="display: none">and</div> me
`, "display: none");
testFindable(false, "me and me", `
me <div style="display: none">and</div> me
`, "display: none");
for (const display of INLINE_LIKE_DISPLAY_VALUES) {
testFindable(true, "me and me", `
me <div style="display: ${display}">and</div> me
`, "div display: " + display);
testFindable(true, "me and me", `
me <span style="display: ${display}">and</span> me
`, "span display: " + display);
}
for (const display of BLOCK_LIKE_DISPLAY_VALUES) {
testFindable(false, "me and me", `
me <div style="display: ${display}">and</div> me
`, "div display: " + display);
testFindable(false, "me and me", `
me <span style="display: ${display}">and</span> me
`, "span display: " + display);
}
testFindable(false, "me and me", `
me <fieldset>and</fieldset> me
`);
});
</script>
<iframe onload="runTests()" srcdoc="<!doctype html><html></html>"></iframe>

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

@ -660,8 +660,7 @@ nsFind::NextNode(nsRange* aSearchRange,
printf(":::::: Got the first node ");
DumpNode(content);
#endif
if (content && content->IsText() &&
!SkipNode(content)) {
if (content && content->IsText() && !SkipNode(content)) {
mIterNode = content;
// Also set mIterOffset if appropriate:
nsCOMPtr<nsINode> node;
@ -815,13 +814,14 @@ nsFind::PeekNextChar(nsRange* aSearchRange,
return t1b ? CHAR_TO_UNICHAR(t1b[index]) : t2b[index];
}
// FIXME(emilio): This very probably wants to look at frames instead.
bool
nsFind::IsBlockNode(nsIContent* aContent)
{
if (aContent->IsElement() && aContent->AsElement()->IsDisplayContents()) {
return false;
}
// FIXME(emilio): This is dubious...
if (aContent->IsAnyOfHTMLElements(nsGkAtoms::img,
nsGkAtoms::hr,
nsGkAtoms::th,
@ -829,7 +829,8 @@ nsFind::IsBlockNode(nsIContent* aContent)
return true;
}
return nsContentUtils::IsHTMLBlock(aContent);
nsIFrame* frame = aContent->GetPrimaryFrame();
return frame && frame->StyleDisplay()->IsBlockOutsideStyle();
}
bool
@ -864,7 +865,8 @@ nsFind::SkipNode(nsIContent* aContent)
nsIContent* content = aContent;
while (content) {
if (aContent->IsComment() ||
if (!IsVisibleNode(content) ||
content->IsComment() ||
content->IsAnyOfHTMLElements(nsGkAtoms::script,
nsGkAtoms::noframes,
nsGkAtoms::select)) {