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