- Revision
- 156536
- Author
- [email protected]
- Date
- 2013-09-27 05:47:52 -0700 (Fri, 27 Sep 2013)
Log Message
Unexpected word wrapping for wrapped content then raw content.
https://bugs.webkit.org/show_bug.cgi?id=121130
Reviewed by Darin Adler.
When deciding whether a line is considered empty, we need to check if the current
object is fully responsible for the currently uncommitted width. It helps differentiating
<span></span><span>abcd</span> from <span>a</span><span>bcd</span>, where in the first
case when we hit the second <span> the line is still considered empty, as opposed to the
second example.
This patch introduces a map to keep track of the uncommitted widths.
Source/WebCore:
Test: fast/css/unexpected-word-wrapping-with-non-empty-spans.html
* rendering/LineWidth.cpp:
(WebCore::LineWidth::uncommittedWidthForObject):
(WebCore::LineWidth::addUncommittedWidth):
* rendering/LineWidth.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::LineBreaker::nextSegmentBreak):
LayoutTests:
* fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html: Added.
* fast/css/unexpected-word-wrapping-with-non-empty-spans.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (156535 => 156536)
--- trunk/LayoutTests/ChangeLog 2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/LayoutTests/ChangeLog 2013-09-27 12:47:52 UTC (rev 156536)
@@ -1,3 +1,20 @@
+2013-09-27 Zalan Bujtas <[email protected]>
+
+ Unexpected word wrapping for wrapped content then raw content.
+ https://bugs.webkit.org/show_bug.cgi?id=121130
+
+ Reviewed by Darin Adler.
+
+ When deciding whether a line is considered empty, we need to check if the current
+ object is fully responsible for the currently uncommitted width. It helps differentiating
+ <span></span><span>abcd</span> from <span>a</span><span>bcd</span>, where in the first
+ case when we hit the second <span> the line is still considered empty, as opposed to the
+ second example.
+ This patch introduces a map to keep track of the uncommitted widths.
+
+ * fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html: Added.
+ * fast/css/unexpected-word-wrapping-with-non-empty-spans.html: Added.
+
2013-09-27 Mario Sanchez Prada <[email protected]>
[ATK] Protect entry points in the ATK wrapper against outdated render trees
Added: trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html (0 => 156536)
--- trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html 2013-09-27 12:47:52 UTC (rev 156536)
@@ -0,0 +1,23 @@
+<html>
+<head>
+ <style>
+ div {
+ border: 1px solid red;
+ width: 16px;
+ word-wrap: break-word;
+ }
+ </style>
+</head>
+<body>
+<p>This tests if non-empty spans changes word wrapping.</p>
+<div>
+ 1234
+</div>
+<div>
+ 1234
+</div>
+<div>
+ 12345678
+ 12345678
+</div>
+</html>
Added: trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans.html (0 => 156536)
--- trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans.html (rev 0)
+++ trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans.html 2013-09-27 12:47:52 UTC (rev 156536)
@@ -0,0 +1,23 @@
+<html>
+<head>
+ <style>
+ div {
+ border: 1px solid red;
+ width: 16px;
+ word-wrap: break-word;
+ }
+ </style>
+</head>
+<body>
+<p>This tests if non-empty spans changes word wrapping.</p>
+<div>
+ <span>123</span><span></span><span>4</span>
+</div>
+<div>
+ <span></span><span>123</span><span>4</span>
+</div>
+<div>
+ 12345678
+ <span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span>
+</div>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (156535 => 156536)
--- trunk/Source/WebCore/ChangeLog 2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/Source/WebCore/ChangeLog 2013-09-27 12:47:52 UTC (rev 156536)
@@ -1,3 +1,26 @@
+2013-09-27 Zalan Bujtas <[email protected]>
+
+ Unexpected word wrapping for wrapped content then raw content.
+ https://bugs.webkit.org/show_bug.cgi?id=121130
+
+ Reviewed by Darin Adler.
+
+ When deciding whether a line is considered empty, we need to check if the current
+ object is fully responsible for the currently uncommitted width. It helps differentiating
+ <span></span><span>abcd</span> from <span>a</span><span>bcd</span>, where in the first
+ case when we hit the second <span> the line is still considered empty, as opposed to the
+ second example.
+ This patch introduces a map to keep track of the uncommitted widths.
+
+ Test: fast/css/unexpected-word-wrapping-with-non-empty-spans.html
+
+ * rendering/LineWidth.cpp:
+ (WebCore::LineWidth::uncommittedWidthForObject):
+ (WebCore::LineWidth::addUncommittedWidth):
+ * rendering/LineWidth.h:
+ * rendering/RenderBlockLineLayout.cpp:
+ (WebCore::LineBreaker::nextSegmentBreak):
+
2013-09-27 Mario Sanchez Prada <[email protected]>
[ATK] Protect entry points in the ATK wrapper against outdated render trees
Modified: trunk/Source/WebCore/rendering/LineWidth.cpp (156535 => 156536)
--- trunk/Source/WebCore/rendering/LineWidth.cpp 2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/Source/WebCore/rendering/LineWidth.cpp 2013-09-27 12:47:52 UTC (rev 156536)
@@ -150,6 +150,23 @@
computeAvailableWidthFromLeftAndRight();
}
+float LineWidth::uncommittedWidthForObject(const RenderObject& object) const
+{
+ auto result = m_uncommittedWidthMap.find(&object);
+ if (result != m_uncommittedWidthMap.end())
+ return result->value;
+ return -1;
+}
+
+void LineWidth::addUncommittedWidth(float delta, const RenderObject& current)
+{
+ m_uncommittedWidth += delta;
+
+ auto result = m_uncommittedWidthMap.add(¤t, delta);
+ if (!result.isNewEntry)
+ result.iterator->value += delta;
+}
+
void LineWidth::commit()
{
m_committedWidth += m_uncommittedWidth;
Modified: trunk/Source/WebCore/rendering/LineWidth.h (156535 => 156536)
--- trunk/Source/WebCore/rendering/LineWidth.h 2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/Source/WebCore/rendering/LineWidth.h 2013-09-27 12:47:52 UTC (rev 156536)
@@ -31,6 +31,7 @@
#define LineWidth_h
#include "LayoutUnit.h"
+#include <wtf/HashMap.h>
namespace WebCore {
@@ -53,12 +54,13 @@
float currentWidth() const { return m_committedWidth + m_uncommittedWidth; }
// FIXME: We should eventually replace these three functions by ones that work on a higher abstraction.
float uncommittedWidth() const { return m_uncommittedWidth; }
+ float uncommittedWidthForObject(const RenderObject&) const;
float committedWidth() const { return m_committedWidth; }
float availableWidth() const { return m_availableWidth; }
void updateAvailableWidth(LayoutUnit minimumHeight = 0);
void shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject*);
- void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
+ void addUncommittedWidth(float delta, const RenderObject&);
void commit();
void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
void fitBelowFloats();
@@ -88,6 +90,7 @@
#endif
bool m_isFirstLine;
IndentTextOrNot m_shouldIndentText;
+ HashMap<const RenderObject*, float> m_uncommittedWidthMap;
};
}
Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (156535 => 156536)
--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp 2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp 2013-09-27 12:47:52 UTC (rev 156536)
@@ -2789,7 +2789,7 @@
trailingObjects.appendBoxIfNeeded(box);
} else
m_positionedObjects.append(box);
- width.addUncommittedWidth(inlineLogicalWidth(current.m_obj));
+ width.addUncommittedWidth(inlineLogicalWidth(current.m_obj), *current.m_obj);
// Reset prior line break context characters.
renderTextInfo.m_lineBreakIterator.resetPriorContext();
} else if (current.m_obj->isFloating()) {
@@ -2840,7 +2840,7 @@
}
}
- width.addUncommittedWidth(inlineLogicalWidth(current.m_obj) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox));
+ width.addUncommittedWidth(inlineLogicalWidth(current.m_obj) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox), *current.m_obj);
} else if (current.m_obj->isReplaced()) {
RenderBox* replacedBox = toRenderBox(current.m_obj);
@@ -2872,9 +2872,9 @@
ignoringSpaces = true;
}
if (toRenderListMarker(*current.m_obj).isInside())
- width.addUncommittedWidth(replacedLogicalWidth);
+ width.addUncommittedWidth(replacedLogicalWidth, *current.m_obj);
} else
- width.addUncommittedWidth(replacedLogicalWidth);
+ width.addUncommittedWidth(replacedLogicalWidth, *current.m_obj);
if (current.m_obj->isRubyRun())
width.applyOverhang(toRenderRubyRun(current.m_obj), last, next);
// Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for replaced element.
@@ -2962,7 +2962,7 @@
if (c == softHyphen && autoWrap && !hyphenWidth && style->hyphens() != HyphensNone) {
hyphenWidth = measureHyphenWidth(t, f, &fallbackFonts);
- width.addUncommittedWidth(hyphenWidth);
+ width.addUncommittedWidth(hyphenWidth, *current.m_obj);
}
bool applyWordSpacing = false;
@@ -3016,13 +3016,13 @@
wordMeasurement.width = additionalTempWidth + wordSpacingForWordMeasurement;
additionalTempWidth += lastSpaceWordSpacing;
- width.addUncommittedWidth(additionalTempWidth);
+ width.addUncommittedWidth(additionalTempWidth, *current.m_obj);
if (collapseWhiteSpace && previousCharacterIsSpace && currentCharacterIsSpace && additionalTempWidth)
width.setTrailingWhitespaceWidth(additionalTempWidth);
if (!appliedStartWidth) {
- width.addUncommittedWidth(inlineLogicalWidth(current.m_obj, true, false));
+ width.addUncommittedWidth(inlineLogicalWidth(current.m_obj, true, false), *current.m_obj);
appliedStartWidth = true;
}
@@ -3078,10 +3078,10 @@
goto end;
} else {
if (!betweenWords || (midWordBreak && !autoWrap))
- width.addUncommittedWidth(-additionalTempWidth);
+ width.addUncommittedWidth(-additionalTempWidth, *current.m_obj);
if (hyphenWidth) {
// Subtract the width of the soft hyphen out since we fit on a line.
- width.addUncommittedWidth(-hyphenWidth);
+ width.addUncommittedWidth(-hyphenWidth, *current.m_obj);
hyphenWidth = 0;
}
}
@@ -3193,7 +3193,7 @@
additionalTempWidth += lastSpaceWordSpacing;
float inlineLogicalTempWidth = inlineLogicalWidth(current.m_obj, !appliedStartWidth, includeEndWidth);
- width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth);
+ width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth, *current.m_obj);
if (wordMeasurement.fallbackFonts.isEmpty() && !fallbackFonts.isEmpty())
wordMeasurement.fallbackFonts.swap(fallbackFonts);
@@ -3283,7 +3283,7 @@
// make sure we consume at least one char/object.
if (lBreak == resolver.position())
lBreak.increment();
- } else if (!width.committedWidth() && (!current.m_obj || !current.m_obj->isBR()) && !current.m_pos) {
+ } else if (!current.m_pos && !width.committedWidth() && current.m_obj && width.uncommittedWidthForObject(*current.m_obj) == width.uncommittedWidth()) {
// Do not push the current object to the next line, when this line has some content, but it is still considered empty.
// Empty inline elements like <span></span> can produce such lines and now we just ignore these break opportunities
// at the start of a line, if no width has been committed yet.