Commit 1e834a22 authored by Yoshifumi Inoue's avatar Yoshifumi Inoue Committed by Commit Bot

[LayoutNG] Create box fragment for inlines with collapsed space

This patch chagnes |NGInlineItemsBuilder| to mark empty inlines due by white
space collapsing by following node, e.g. <div>ab<span> </span></div>.

Note: This patch is follow-up of the CL[1] creates box fragment for empty
inlines before processing closing tag, e.g. <div>ab <span> </span></div>.

[1] http://crrev.com/c/1774418 [LayoutNG] Fixes positions/sizes of empty inline
boxes

Bug: 707656, 997705
Change-Id: I0bdce9ec2bc073faa05155d6dcd5f8dbec9580be
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2249269
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Auto-Submit: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#779636}
parent 8d817553
......@@ -187,6 +187,10 @@ class CORE_EXPORT NGInlineItem {
(Type() == NGInlineItem::kControl && type == kCollapsible));
end_collapse_type_ = type;
}
bool IsCollapsibleSpaceOnly() const {
return Type() == NGInlineItem::kText &&
end_collapse_type_ == kCollapsible && Length() == 1u;
}
// True if this item was generated (not in DOM).
// NGInlineItemsBuilder may generate break opportunitites to express the
......
......@@ -981,7 +981,7 @@ void NGInlineItemsBuilderTemplate<
// Keep the item even if the length became zero. This is not needed for
// the layout purposes, but needed to maintain LayoutObject states. See
// |AddEmptyTextItem()|.
// |AppendEmptyTextItem()|.
item->SetEndOffset(item->EndOffset() - 1);
item->SetEndCollapseType(NGInlineItem::kCollapsed);
......@@ -1189,8 +1189,20 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::ExitInline(
break;
}
DCHECK_GT(i, current_box->item_index);
if (!item.IsEmptyItem())
break;
if (item.IsEmptyItem()) {
// float, abspos, collapsed space(<div>ab <span> </span>).
// See editing/caret/empty_inlines.html
// See also [1] for empty line box.
// [1] https://drafts.csswg.org/css2/visuren.html#phantom-line-box
continue;
}
if (item.IsCollapsibleSpaceOnly()) {
// Because we can't collapse trailing spaces until next node, we
// create box fragment for it: <div>ab<span> </span></div>
// See editing/selection/mixed-editability-10.html
continue;
}
break;
}
}
......
<!doctype html>
<script src="../../resources/ahem.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../assert_selection.js"></script>
<script>
const kLineHeight = 20;
const kStyle = `font: 10px/${kLineHeight}px Ahem; padding: 5px;`;
function checkBox(content, style = '') {
const sample = [
`<div style="${kStyle}style">`,
content,
'</div>',
].join('');
selection_test(
sample,
selection => {
const target = selection.document.querySelector('span');
assert_not_equals(`${target.offsetLeft},${target.offsetTop}`,
'8,8');
},
sample,
style ? `"${content}" with ${style}` : `"${content}"`);
}
// Note: We don't have test cases for empty line box, e.g.
// - <div><span> </span></div>
// - <div><span> </span><b style="float:left">x</b></div>
// - <div><span> </span><b style="position:absolute">x</b></div>
// See [1] for empty line box.
// [1] https://drafts.csswg.org/css2/visuren.html#phantom-line-box
checkBox('ab<span></span>');
checkBox('ab<span> </span>');
checkBox('ab <span></span>');
checkBox('ab <span> </span>');
checkBox('ab<span></span> ');
checkBox('ab<span> </span> ');
checkBox('<span></span>xy');
checkBox('<span> </span>xy');
checkBox(' <span></span>xy');
checkBox(' <span> </span>xy');
checkBox('<span></span> xy');
checkBox('<span> </span> xy');
checkBox('ab<span></span>xy');
checkBox('ab<span> </span>xy');
checkBox('ab <span></span>xy');
checkBox('ab <span> </span>xy');
checkBox('ab<span></span> xy');
checkBox('ab<span> </span> xy');
// Soft line wrap at <span>
checkBox('ab<span></span>xy', `width: 2ch;`);
checkBox('ab<span> </span>xy', `width: 3ch;`);
</script>
This is a testharness.js-based test.
PASS "ab<span></span>"
PASS "ab<span> </span>"
FAIL "ab <span></span>" assert_not_equals: got disallowed value "8,8"
FAIL "ab <span> </span>" assert_not_equals: got disallowed value "8,8"
PASS "ab<span></span> "
PASS "ab<span> </span> "
FAIL "<span></span>xy" assert_not_equals: got disallowed value "8,8"
FAIL "<span> </span>xy" assert_not_equals: got disallowed value "8,8"
FAIL " <span></span>xy" assert_not_equals: got disallowed value "8,8"
FAIL " <span> </span>xy" assert_not_equals: got disallowed value "8,8"
FAIL "<span></span> xy" assert_not_equals: got disallowed value "8,8"
FAIL "<span> </span> xy" assert_not_equals: got disallowed value "8,8"
PASS "ab<span></span>xy"
PASS "ab<span> </span>xy"
PASS "ab <span></span>xy"
FAIL "ab <span> </span>xy" assert_not_equals: got disallowed value "8,8"
PASS "ab<span></span> xy"
PASS "ab<span> </span> xy"
PASS "ab<span></span>xy" with width: 2ch;
PASS "ab<span> </span>xy" with width: 3ch;
Harness: the test ran to completion.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment