More work to fix 10145, regression where form elements don't break properly. Make sure to really use
the parent of the replaced element's whitespace value everywhere.
Reviewed by olliej
fast/replaced/three-selects-break.html
* rendering/bidi.cpp:
(WebCore::RenderBlock::findNextLineBreak):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@18851 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/rendering/bidi.cpp b/WebCore/rendering/bidi.cpp
index a890cff..136e5be 100644
--- a/WebCore/rendering/bidi.cpp
+++ b/WebCore/rendering/bidi.cpp
@@ -1998,7 +1998,16 @@
bool prevLineBrokeCleanly = previousLineBrokeCleanly;
previousLineBrokeCleanly = false;
+ EWhiteSpace currWS = style()->whiteSpace();
+ EWhiteSpace lastWS = currWS;
while (o) {
+ currWS = o->isReplaced() ? o->parent()->style()->whiteSpace() : o->style()->whiteSpace();
+ lastWS = last->isReplaced() ? last->parent()->style()->whiteSpace() : last->style()->whiteSpace();
+
+ bool autoWrap = RenderStyle::autoWrap(currWS);
+ bool preserveNewline = RenderStyle::preserveNewline(currWS);
+ bool collapseWhiteSpace = RenderStyle::collapseWhiteSpace(currWS);
+
if (o->isBR()) {
if (w + tmpW <= width) {
lBreak.obj = o;
@@ -2024,6 +2033,7 @@
}
goto end;
}
+
if (o->isFloatingOrPositioned()) {
// add to special objects...
if (o->isFloating()) {
@@ -2031,7 +2041,7 @@
// check if it fits in the current line.
// If it does, position it now, otherwise, position
// it after moving to next line (in newLine() func)
- if (o->width()+o->marginLeft()+o->marginRight()+w+tmpW <= width) {
+ if (o->width() + o->marginLeft() + o->marginRight() + w + tmpW <= width) {
positionNewFloats();
width = lineWidth(m_height);
}
@@ -2042,8 +2052,8 @@
bool needToSetStaticX = o->hasStaticX();
if (o->hasStaticX() && !isInlineType) {
o->setStaticX(o->parent()->style()->direction() == LTR ?
- borderLeft()+paddingLeft() :
- borderRight()+paddingRight());
+ borderLeft() + paddingLeft() :
+ borderRight() + paddingRight());
needToSetStaticX = false;
}
@@ -2076,14 +2086,11 @@
} else if (o->isInlineFlow()) {
// Only empty inlines matter. We treat those similarly to replaced elements.
assert(!o->firstChild());
- tmpW += o->marginLeft()+o->borderLeft()+o->paddingLeft()+
- o->marginRight()+o->borderRight()+o->paddingRight();
+ tmpW += o->marginLeft() + o->borderLeft() + o->paddingLeft() +
+ o->marginRight() + o->borderRight() + o->paddingRight();
} else if (o->isReplaced()) {
- EWhiteSpace currWS = o->parent()->style()->whiteSpace();
- EWhiteSpace lastWS = last->isReplaced() ? last->parent()->style()->whiteSpace() : last->style()->whiteSpace();
-
// Break on replaced elements if either has normal white-space.
- if (RenderStyle::autoWrap(currWS) || RenderStyle::autoWrap(lastWS)) {
+ if (autoWrap || RenderStyle::autoWrap(lastWS)) {
w += tmpW;
tmpW = 0;
lBreak.obj = o;
@@ -2120,7 +2127,7 @@
}
}
} else
- tmpW += o->width()+o->marginLeft()+o->marginRight()+inlineWidth(o);
+ tmpW += o->width() + o->marginLeft() + o->marginRight() + inlineWidth(o);
} else if (o->isText()) {
RenderText *t = static_cast<RenderText *>(o);
int strlen = t->stringLength();
@@ -2137,14 +2144,14 @@
// then assume the start width has been applied.
int wrapW = tmpW + inlineWidth(o, !appliedStartWidth, true);
int nextBreakable = -1;
-
+
while (len) {
bool previousCharacterIsSpace = currentCharacterIsSpace;
bool previousCharacterIsWS = currentCharacterIsWS;
UChar c = str[pos];
- currentCharacterIsSpace = c == ' ' || c == '\t' || (!o->style()->preserveNewline() && (c == '\n'));
+ currentCharacterIsSpace = c == ' ' || c == '\t' || (!preserveNewline && (c == '\n'));
- if (!o->style()->collapseWhiteSpace() || !currentCharacterIsSpace)
+ if (!collapseWhiteSpace || !currentCharacterIsSpace)
isLineEmpty = false;
// Check for soft hyphens. Go ahead and ignore them.
@@ -2167,7 +2174,7 @@
// For wrapping text only, include the hyphen. We need to ensure it will fit
// on the line if it shows when we break.
- if (o->style()->autoWrap())
+ if (autoWrap)
tmpW += t->width(pos, 1, f, w+tmpW);
BidiIterator startMid(0, o, pos+1);
@@ -2182,11 +2189,10 @@
}
bool applyWordSpacing = false;
- bool allowBreak = o->style()->autoWrap();
- bool breakNBSP = allowBreak && o->style()->nbspMode() == SPACE;
+ bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE;
// FIXME: This check looks suspicious. Why does w have to be 0?
- bool breakWords = o->style()->wordWrap() == BREAK_WORD && ((allowBreak && w == 0) || o->style()->whiteSpace() == PRE);
+ bool breakWords = o->style()->wordWrap() == BREAK_WORD && ((autoWrap && w == 0) || currWS == PRE);
currentCharacterIsWS = currentCharacterIsSpace || (breakNBSP && c == noBreakSpace);
@@ -2194,7 +2200,7 @@
wrapW += t->width(pos, 1, f, w+wrapW);
bool midWordBreak = breakWords && (w + wrapW > width);
- if (c == '\n' || (o->style()->whiteSpace() != PRE && isBreakable(str, pos, strlen, nextBreakable, breakNBSP)) || midWordBreak) {
+ if (c == '\n' || (currWS != PRE && isBreakable(str, pos, strlen, nextBreakable, breakNBSP)) || midWordBreak) {
bool stoppedIgnoringSpaces = false;
if (ignoringSpaces) {
if (!currentCharacterIsSpace) {
@@ -2223,7 +2229,7 @@
applyWordSpacing = wordSpacing && currentCharacterIsSpace && !previousCharacterIsSpace;
- if (o->style()->autoWrap() && w + tmpW > width && w == 0) {
+ if (autoWrap && w + tmpW > width && w == 0) {
int fb = nearestFloatBottom(m_height);
int newLineWidth = lineWidth(fb);
// See if |tmpW| will fit on the new line. As long as it does not,
@@ -2241,7 +2247,7 @@
}
}
- if (o->style()->autoWrap() || breakWords) {
+ if (autoWrap || breakWords) {
// If we break only after white-space, consider the current character
// as candidate width for this line.
bool lineWasTooWide = false;
@@ -2287,7 +2293,7 @@
}
}
- if (c == '\n' && o->style()->preserveNewline()) {
+ if (c == '\n' && preserveNewline) {
if (!stoppedIgnoringSpaces && pos > 0) {
// We need to stop right before the newline and then start up again.
BidiIterator midpoint(0, o, pos);
@@ -2301,7 +2307,7 @@
return lBreak;
}
- if (o->style()->autoWrap()) {
+ if (autoWrap) {
w += tmpW;
tmpW = 0;
lBreak.obj = o;
@@ -2347,13 +2353,13 @@
}
if (!currentCharacterIsWS && previousCharacterIsWS) {
- if (o->style()->autoWrap() && o->style()->breakOnlyAfterWhiteSpace()) {
+ if (autoWrap && o->style()->breakOnlyAfterWhiteSpace()) {
lBreak.obj = o;
lBreak.pos = pos;
}
}
- if (o->style()->collapseWhiteSpace() && currentCharacterIsSpace && !ignoringSpaces)
+ if (collapseWhiteSpace && currentCharacterIsSpace && !ignoringSpaces)
trailingSpaceObject = o;
else if (!o->style()->collapseWhiteSpace() || !currentCharacterIsSpace)
trailingSpaceObject = 0;
@@ -2372,9 +2378,8 @@
ASSERT( false );
RenderObject* next = bidiNext(start.block, o, bidi);
- bool autoWrap = o->style()->autoWrap();
bool checkForBreak = autoWrap;
- if (w && w + tmpW > width && lBreak.obj && o->style()->whiteSpace() == NOWRAP)
+ if (w && w + tmpW > width && lBreak.obj && currWS == NOWRAP)
checkForBreak = true;
else if (next && o->isText() && next->isText() && !next->isBR()) {
if (autoWrap || (next->style()->autoWrap())) {
@@ -2434,7 +2439,7 @@
previous = o;
o = next;
- if (!last->isFloatingOrPositioned() && last->isReplaced() && last->style()->autoWrap() &&
+ if (!last->isFloatingOrPositioned() && last->isReplaced() && autoWrap &&
(!last->isListMarker() || last->style()->listStylePosition()==INSIDE)) {
// Go ahead and add in tmpW.
w += tmpW;
@@ -2445,13 +2450,14 @@
// Clear out our character space bool, since inline <pre>s don't collapse whitespace
// with adjacent inline normal/nowrap spans.
- if (!last->style()->collapseWhiteSpace())
+ if (!collapseWhiteSpace)
currentCharacterIsSpace = false;
pos = 0;
}
- if (w + tmpW <= width || (last && last->style()->whiteSpace() == NOWRAP)) {
+
+ if (w + tmpW <= width || lastWS == NOWRAP) {
lBreak.obj = 0;
lBreak.pos = 0;
}