Skip to content

Commit 22d6d63

Browse files
committed
Inputs within inline-block containers shift vertically when text is deleted and re-entered into an input
https://bugs.webkit.org/show_bug.cgi?id=294558 <rdar://problem/154094432> Reviewed by Antti Koivisto. 1. RenderTextControlSingleLine's inner renderer is vertically centered. 2. RenderTextControlSingleLine's inner renderer provides the baseline position for the input box. 3. The baseline position is passed to inline layout and is used to align other content on the line (when baseline alignment applies). As text is appended to the input box: 1. An empty RenderText is constructed and inserted into the tree. 2. InsertIntoTextNodeCommand::doApply() is called. 3. RenderText is populated by calling setText. In step #2, layout is prematurely run on the content (see passwordEchoEnabled) before it is populated in step #3. This layout generates an empty inline display content with a 0px-tall line box, which gets vertically centered. This "centered line" then becomes the baseline for the rest of the content. In step #3, another layout is run on the input box, this time with populated content, but the layout is limited to the input only, so adjacent content does not get alignment treatment. This is how the offset occurs (result of the premature layout). There are a few issues here: 1. We should not run layout on the empty content before RenderText is populated (webkit.org/b/294880). 2. RenderTextControlSingleLine should not center the inner renderer when it has no content (webkit.org/b/294881). 3. IFC should not report valid line boxes when there’s no content at all (i.e., when no display boxes are generated). This patch addresses issue #3. * LayoutTests/fast/editing/incorrect-baseline-for-input-adjacent-content-expected.html: Added. * LayoutTests/fast/editing/incorrect-baseline-for-input-adjacent-content.html: Added. * Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp: (WebCore::LayoutIntegration::LineLayout::firstLineBox const): (WebCore::LayoutIntegration::LineLayout::lastLineBox const): Canonical link: https://commits.webkit.org/296569@main
1 parent ba0fd77 commit 22d6d63

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<style>
2+
div {
3+
display: inline-block;
4+
}
5+
input {
6+
font-size: 40px;
7+
}
8+
</style>
9+
PASS if this and<div><input id=foobar type=text value="this"></div>are vertically aligned.
10+
<script>
11+
foobar.focus();
12+
foobar.setSelectionRange(4, 4);
13+
</script>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<style>
2+
div {
3+
display: inline-block;
4+
}
5+
input {
6+
font-size: 40px;
7+
}
8+
</style>
9+
PASS if this and<div><input id=change_this type=text value="test"></div>are vertically aligned.
10+
<script>
11+
change_this.focus();
12+
change_this.setSelectionRange(0, 4);
13+
document.execCommand('Delete', false, null);
14+
document.execCommand("InsertText", true, "this");
15+
</script>

Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,15 +1027,15 @@ InlineIterator::InlineBoxIterator LineLayout::firstRootInlineBox() const
10271027

10281028
InlineIterator::LineBoxIterator LineLayout::firstLineBox() const
10291029
{
1030-
if (!m_inlineContent)
1030+
if (!m_inlineContent || !m_inlineContent->hasContent())
10311031
return { };
10321032

10331033
return { InlineIterator::LineBoxIteratorModernPath(*m_inlineContent, 0) };
10341034
}
10351035

10361036
InlineIterator::LineBoxIterator LineLayout::lastLineBox() const
10371037
{
1038-
if (!m_inlineContent)
1038+
if (!m_inlineContent || !m_inlineContent->hasContent())
10391039
return { };
10401040

10411041
return { InlineIterator::LineBoxIteratorModernPath(*m_inlineContent, m_inlineContent->displayContent().lines.isEmpty() ? 0 : m_inlineContent->displayContent().lines.size() - 1) };

0 commit comments

Comments
 (0)