WebCore:
Reviewed by Hyatt.
Fix for <rdar://problem/5399614> anchor tag is not rendered without
text content, works in Firefox with CSS background-image (13237)
This patch allows empty inlines that have box decorations or width
from border/padding/margin to have line boxes.
* rendering/bidi.cpp:
(WebCore::inlineFlowAllowsLineBox): Convenience function that
defines when we allow an inline flow to have a line box.
(WebCore::requiresLineBox): Call inlineFlowAllowsLineBox.
(WebCore::shouldSkipWhitespaceAfterStartObject): New function to
merge some shared code between list markers and empty inline flows
that fall at the beginning of a line.
(WebCore::RenderBlock::findNextLineBreak): Make flows more like
list markers.
One interesting side effect of this bug appeared in our xhtml/svg
tests that generate parser error tags. The tag we generate was
actually an empty inline with box decorations. This patch causes
those inlines to draw now, and the parser errors looked strange. So
I changed it so that the parsererror tag is display:block. This
matches Firefox, and I think was the original intent of the tag
since that causes its red background and border to show up.
* dom/XMLTokenizer.cpp:
(WebCore::createXHTMLParserErrorHeader):
LayoutTests:
Reviewed by Hyatt.
New tests and new results for old tests for <rdar://problem/
5399614> anchor tag is not rendered without text content, works in
Firefox with CSS background-image (13237)
New tests:
* fast/inline/drawStyledEmptyInlines.html: Added.
* fast/inline/drawStyledEmptyInlinesWithWS.html: Added.
* fast/inline/emptyInlinesWithinLists.html: Added.
* fast/inline/styledEmptyInlinesWithBRs.html: Added.
* platform/mac/fast/inline/drawStyledEmptyInlines-expected.checksum: Added.
* platform/mac/fast/inline/drawStyledEmptyInlines-expected.png: Added.
* platform/mac/fast/inline/drawStyledEmptyInlines-expected.txt: Added.
* platform/mac/fast/inline/drawStyledEmptyInlinesWithWS-expected.checksum: Added.
* platform/mac/fast/inline/drawStyledEmptyInlinesWithWS-expected.png: Added.
* platform/mac/fast/inline/drawStyledEmptyInlinesWithWS-expected.txt: Added.
* platform/mac/fast/inline/emptyInlinesWithinLists-expected.checksum: Added.
* platform/mac/fast/inline/emptyInlinesWithinLists-expected.png: Added.
* platform/mac/fast/inline/emptyInlinesWithinLists-expected.txt: Added.
* platform/mac/fast/inline/styledEmptyInlinesWithBRs-expected.checksum: Added.
* platform/mac/fast/inline/styledEmptyInlinesWithBRs-expected.png: Added.
* platform/mac/fast/inline/styledEmptyInlinesWithBRs-expected.txt: Added.
New results for tests with <paserererrors> since <parsererror> is
now block.
* platform/mac/fast/invalid/junk-data-expected.checksum: Replaced.
* platform/mac/fast/invalid/junk-data-expected.png: Replaced.
* platform/mac/fast/invalid/junk-data-expected.txt:
* platform/mac/fast/invalid/missing-end-tag-expected.checksum: Replaced.
* platform/mac/fast/invalid/missing-end-tag-expected.png: Replaced.
* platform/mac/fast/invalid/missing-end-tag-expected.txt:
* platform/mac/fast/parser/xhtml-alternate-entities-expected.checksum: Replaced.
* platform/mac/fast/parser/xhtml-alternate-entities-expected.png: Replaced.
* platform/mac/fast/parser/xhtml-alternate-entities-expected.txt:
* platform/mac/fast/xsl/xslt-extra-content-at-end-expected.checksum: Replaced.
* platform/mac/fast/xsl/xslt-extra-content-at-end-expected.png: Replaced.
* platform/mac/fast/xsl/xslt-extra-content-at-end-expected.txt: Removed.
* platform/mac/svg/custom/junk-data-expected.checksum: Replaced.
* platform/mac/svg/custom/junk-data-expected.png: Replaced.
* platform/mac/svg/custom/junk-data-expected.txt:
* platform/mac/svg/custom/missing-xlink-expected.checksum: Replaced.
* platform/mac/svg/custom/missing-xlink-expected.png: Replaced.
* platform/mac/svg/custom/missing-xlink-expected.txt:
* platform/mac/svg/hixie/error/012-expected.checksum: Replaced.
* platform/mac/svg/hixie/error/012-expected.png: Replaced.
* platform/mac/svg/hixie/error/012-expected.txt:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@27254 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/rendering/bidi.cpp b/WebCore/rendering/bidi.cpp
index eb3766f..97bfe1d 100644
--- a/WebCore/rendering/bidi.cpp
+++ b/WebCore/rendering/bidi.cpp
@@ -1244,10 +1244,32 @@
return object->style()->preserveNewline();
}
+static bool inlineFlowRequiresLineBox(RenderObject* flow)
+{
+ // FIXME: Right now, we only allow line boxes for inlines that are truly empty.
+ // We need to fix this, though, because at the very least, inlines with only text
+ // children that is all whitespace should should also have line boxes.
+ if (!flow->isInlineFlow() || flow->firstChild())
+ return false;
+
+ bool hasPaddingOrMargin = !(flow->paddingLeft() == 0 && flow->paddingRight() == 0
+ && flow->paddingTop() == 0 && flow->paddingBottom() == 0
+ && flow->marginLeft() == 0 && flow->marginRight() == 0
+ && flow->marginTop() == 0 && flow->marginBottom() == 0);
+ if (flow->hasBoxDecorations() || hasPaddingOrMargin)
+ return true;
+
+ return false;
+}
+
static inline bool requiresLineBox(BidiIterator& it)
{
- if (it.obj->isFloatingOrPositioned() || it.obj->isInlineFlow())
+ if (it.obj->isFloatingOrPositioned())
return false;
+
+ if (it.obj->isInlineFlow() && !inlineFlowRequiresLineBox(it.obj))
+ return false;
+
if (!shouldCollapseWhiteSpace(it.obj->style()) || it.obj->isBR())
return true;
@@ -1320,6 +1342,24 @@
return w;
}
+// This is currently just used for list markers and inline flows that have line boxes. Neither should
+// have an effect on whitespace at the start of the line.
+static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObject* o, BidiState &bidi)
+{
+ RenderObject* next = bidiNext(block, o, bidi);
+ if (next && !next->isBR() && next->isText() && static_cast<RenderText*>(next)->textLength() > 0) {
+ RenderText* nextText = static_cast<RenderText*>(next);
+ UChar nextChar = nextText->characters()[0];
+ if (nextText->style()->isCollapsibleWhiteSpace(nextChar)) {
+ BidiIterator endMid(0, o, 0);
+ addMidpoint(endMid);
+ return true;
+ }
+ }
+
+ return false;
+}
+
BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi)
{
// eliminate spaces at beginning of line
@@ -1448,8 +1488,28 @@
}
}
} else if (o->isInlineFlow()) {
- // Only empty inlines matter. We treat those similarly to replaced elements.
+ // Right now, we should only encounter empty inlines here.
ASSERT(!o->firstChild());
+
+ // Now that some inline flows have line boxes, if we are already ignoring spaces, we need
+ // to make sure that we stop to include this object and then start ignoring spaces again.
+ // If this object is at the start of the line, we need to behave like list markers and
+ // start ignoring spaces.
+ if (inlineFlowRequiresLineBox(o)) {
+ if (ignoringSpaces) {
+ trailingSpaceObject = 0;
+ addMidpoint(BidiIterator(0, o, 0)); // Stop ignoring spaces.
+ addMidpoint(BidiIterator(0, o, 0)); // Start ignoring again.
+ } else if (style()->collapseWhiteSpace() && start.obj == o
+ && shouldSkipWhitespaceAfterStartObject(start.block, o, bidi)) {
+ // Like with list markers, we start ignoring spaces to make sure that any
+ // additional spaces we see will be discarded.
+ currentCharacterIsSpace = true;
+ currentCharacterIsWS = true;
+ ignoringSpaces = true;
+ }
+ }
+
if (static_cast<RenderFlow*>(o)->isWordBreak()) {
w += tmpW;
tmpW = 0;
@@ -1477,24 +1537,15 @@
currentCharacterIsWS = false;
trailingSpaceObject = 0;
+ // Optimize for a common case. If we can't find whitespace after the list
+ // item, then this is all moot. -dwh
if (o->isListMarker() && !static_cast<RenderListMarker*>(o)->isInside()) {
- // The marker must not have an effect on whitespace at the start
- // of the line. We start ignoring spaces to make sure that any additional
- // spaces we see will be discarded.
- //
- // Optimize for a common case. If we can't find whitespace after the list
- // item, then this is all moot. -dwh
- RenderObject* next = bidiNext(start.block, o, bidi);
- if (style()->collapseWhiteSpace() && next && !next->isBR() && next->isText() && static_cast<RenderText*>(next)->textLength() > 0) {
- RenderText *nextText = static_cast<RenderText*>(next);
- UChar nextChar = nextText->characters()[0];
- if (nextText->style()->isCollapsibleWhiteSpace(nextChar)) {
- currentCharacterIsSpace = true;
- currentCharacterIsWS = true;
- ignoringSpaces = true;
- BidiIterator endMid( 0, o, 0 );
- addMidpoint(endMid);
- }
+ if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(start.block, o, bidi)) {
+ // Like with inline flows, we start ignoring spaces to make sure that any
+ // additional spaces we see will be discarded.
+ currentCharacterIsSpace = true;
+ currentCharacterIsWS = true;
+ ignoringSpaces = true;
}
} else
tmpW += o->width() + o->marginLeft() + o->marginRight() + inlineWidth(o);