Title: [182188] trunk
Revision
182188
Author
[email protected]
Date
2015-03-31 10:42:24 -0700 (Tue, 31 Mar 2015)

Log Message

[New Block-Inside-Inline Model] Make sure line breaks occur before and after the anonymous inline-block.
https://bugs.webkit.org/show_bug.cgi?id=143238.

Reviewed by Dean Jackson.

Source/WebCore:

Added fast/blocks/inside-inlines/breaking-behavior.html (and new-model equivalent).

* rendering/InlineFlowBox.h:
(WebCore::InlineFlowBox::InlineFlowBox):
(WebCore::InlineFlowBox::hasAnonymousInlineBlock):
(WebCore::InlineFlowBox::setHasAnonymousInlineBlock):
Add a bit to root line boxes (stored in the InlineFlowBox since it has free bits) that indicates whether
or not a line is an anonymous inline-block line.

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::computeInlinePreferredLogicalWidths):
Patch the preferred logical width computation to break both before and after an anonymous inline-block.
Also make sure to strip trailing spaces from the line before the anonymous inline-block.

* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlockFlow::constructLine):
Patch line construction so that no intermediate boxes are constructed between the InlineBox for the anonymous
inline-block and the root line box.

* rendering/RootInlineBox.cpp:
(WebCore::RootInlineBox::ascentAndDescentForBox):
The height of a "line" that holds an anonymous inline-block should ignore line-box-contain and also make sure
that the margins of the replaced element are "outside" the line, since those margins will collapse.

* rendering/line/BreakingContext.h:
(WebCore::BreakingContext::handleReplaced):
Patch handleReplaced to make sure breaks occur both before and after an anonymous inline-block. In the case of
a break after the block, we setPreviousLineBrokeCleanly to true so that <br>s that follow the anonymous inline-block
are respected.

LayoutTests:

* fast/block/inside-inlines/breaking-behavior-expected.html: Added.
* fast/block/inside-inlines/breaking-behavior.html: Added.
* fast/block/inside-inlines/new-model/breaking-behavior-expected.html: Added.
* fast/block/inside-inlines/new-model/breaking-behavior.html: Added.
* fast/block/inside-inlines/new-model/empty-block.html:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (182187 => 182188)


--- trunk/LayoutTests/ChangeLog	2015-03-31 17:32:46 UTC (rev 182187)
+++ trunk/LayoutTests/ChangeLog	2015-03-31 17:42:24 UTC (rev 182188)
@@ -1,3 +1,16 @@
+2015-03-30  David Hyatt  <[email protected]>
+
+        [New Block-Inside-Inline Model] Make sure line breaks occur before and after the anonymous inline-block.
+        https://bugs.webkit.org/show_bug.cgi?id=143238.
+
+        Reviewed by Dean Jackson.
+
+        * fast/block/inside-inlines/breaking-behavior-expected.html: Added.
+        * fast/block/inside-inlines/breaking-behavior.html: Added.
+        * fast/block/inside-inlines/new-model/breaking-behavior-expected.html: Added.
+        * fast/block/inside-inlines/new-model/breaking-behavior.html: Added.
+        * fast/block/inside-inlines/new-model/empty-block.html:
+
 2015-03-31  Marcos Chavarría Teijeiro  <[email protected]>
 
         GTK+ Gardening 30th March

Added: trunk/LayoutTests/fast/block/inside-inlines/breaking-behavior-expected.html (0 => 182188)


--- trunk/LayoutTests/fast/block/inside-inlines/breaking-behavior-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/inside-inlines/breaking-behavior-expected.html	2015-03-31 17:42:24 UTC (rev 182188)
@@ -0,0 +1,16 @@
+<!doctype html>
+<head>
+<style>
+.box { border:1px solid black; padding:3px; margin:3px }
+.nowrap { white-space: nowrap; }
+.float { float: left; }
+</style>
+<body>
+
+<div class="box"><a>One <br> Two</a></div>
+
+<div class="box"><a>One<br><br>Two</a></div>
+
+<div class="box nowrap"><a>One <br> Two</a></div>
+
+<div class="box float"><a>One<br> Two</a></div>
\ No newline at end of file

Added: trunk/LayoutTests/fast/block/inside-inlines/breaking-behavior.html (0 => 182188)


--- trunk/LayoutTests/fast/block/inside-inlines/breaking-behavior.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/inside-inlines/breaking-behavior.html	2015-03-31 17:42:24 UTC (rev 182188)
@@ -0,0 +1,16 @@
+<!doctype html>
+<head>
+<style>
+.box { border:1px solid black; padding:3px; margin:3px }
+.nowrap { white-space: nowrap; }
+.float { float: left; }
+</style>
+<body>
+
+<div class="box"><a>One <div></div> Two</a></div>
+
+<div class="box"><a>One<br><div></div><br>Two</a></div>
+
+<div class="box nowrap"><a>One <div></div> Two</a></div>
+
+<div class="box float"><a>One <div></div> Two</a></div>
\ No newline at end of file

Added: trunk/LayoutTests/fast/block/inside-inlines/new-model/breaking-behavior-expected.html (0 => 182188)


--- trunk/LayoutTests/fast/block/inside-inlines/new-model/breaking-behavior-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/inside-inlines/new-model/breaking-behavior-expected.html	2015-03-31 17:42:24 UTC (rev 182188)
@@ -0,0 +1,16 @@
+<!doctype html>
+<head>
+<style>
+.box { border:1px solid black; padding:3px; margin:3px }
+.nowrap { white-space: nowrap; }
+.float { float: left; }
+</style>
+<body>
+
+<div class="box"><a>One <br> Two</a></div>
+
+<div class="box"><a>One<br><br>Two</a></div>
+
+<div class="box nowrap"><a>One <br> Two</a></div>
+
+<div class="box float"><a>One<br> Two</a></div>
\ No newline at end of file

Added: trunk/LayoutTests/fast/block/inside-inlines/new-model/breaking-behavior.html (0 => 182188)


--- trunk/LayoutTests/fast/block/inside-inlines/new-model/breaking-behavior.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/inside-inlines/new-model/breaking-behavior.html	2015-03-31 17:42:24 UTC (rev 182188)
@@ -0,0 +1,21 @@
+<!doctype html>
+<head>
+<style>
+.box { border:1px solid black; padding:3px; margin:3px }
+.nowrap { white-space: nowrap; }
+.float { float: left; }
+</style>
+<script>
+if (window.internals)
+    window.internals.settings.setNewBlockInsideInlineModelEnabled(true)
+</script>
+</head>
+<body>
+
+<div class="box"><a>One <div></div> Two</a></div>
+
+<div class="box"><a>One<br><div></div><br>Two</a></div>
+
+<div class="box nowrap"><a>One <div></div> Two</a></div>
+
+<div class="box float"><a>One <div></div> Two</a></div>
\ No newline at end of file

Modified: trunk/LayoutTests/fast/block/inside-inlines/new-model/empty-block.html (182187 => 182188)


--- trunk/LayoutTests/fast/block/inside-inlines/new-model/empty-block.html	2015-03-31 17:32:46 UTC (rev 182187)
+++ trunk/LayoutTests/fast/block/inside-inlines/new-model/empty-block.html	2015-03-31 17:42:24 UTC (rev 182188)
@@ -1,7 +1,8 @@
 <!doctype html>
 <head>
 <script>
-window.internals.settings.setNewBlockInsideInlineModelEnabled(true)
+if (window.internals)
+    window.internals.settings.setNewBlockInsideInlineModelEnabled(true)
 </script>
 </head>
 

Modified: trunk/Source/WebCore/ChangeLog (182187 => 182188)


--- trunk/Source/WebCore/ChangeLog	2015-03-31 17:32:46 UTC (rev 182187)
+++ trunk/Source/WebCore/ChangeLog	2015-03-31 17:42:24 UTC (rev 182188)
@@ -1,3 +1,40 @@
+2015-03-30  David Hyatt  <[email protected]>
+
+        [New Block-Inside-Inline Model] Make sure line breaks occur before and after the anonymous inline-block.
+        https://bugs.webkit.org/show_bug.cgi?id=143238.
+
+        Reviewed by Dean Jackson.
+
+        Added fast/blocks/inside-inlines/breaking-behavior.html (and new-model equivalent).
+
+        * rendering/InlineFlowBox.h:
+        (WebCore::InlineFlowBox::InlineFlowBox):
+        (WebCore::InlineFlowBox::hasAnonymousInlineBlock):
+        (WebCore::InlineFlowBox::setHasAnonymousInlineBlock):
+        Add a bit to root line boxes (stored in the InlineFlowBox since it has free bits) that indicates whether
+        or not a line is an anonymous inline-block line.
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::computeInlinePreferredLogicalWidths):
+        Patch the preferred logical width computation to break both before and after an anonymous inline-block.
+        Also make sure to strip trailing spaces from the line before the anonymous inline-block.
+
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlockFlow::constructLine):
+        Patch line construction so that no intermediate boxes are constructed between the InlineBox for the anonymous
+        inline-block and the root line box.
+
+        * rendering/RootInlineBox.cpp:
+        (WebCore::RootInlineBox::ascentAndDescentForBox):
+        The height of a "line" that holds an anonymous inline-block should ignore line-box-contain and also make sure
+        that the margins of the replaced element are "outside" the line, since those margins will collapse.
+
+        * rendering/line/BreakingContext.h:
+        (WebCore::BreakingContext::handleReplaced):
+        Patch handleReplaced to make sure breaks occur both before and after an anonymous inline-block. In the case of
+        a break after the block, we setPreviousLineBrokeCleanly to true so that <br>s that follow the anonymous inline-block
+        are respected.
+
 2015-03-31  Csaba Osztrogonác  <[email protected]>
 
         [EFL] Add nullptr check to GraphicsContext3D::makeContextCurrent()

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.h (182187 => 182188)


--- trunk/Source/WebCore/rendering/InlineFlowBox.h	2015-03-31 17:32:46 UTC (rev 182187)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.h	2015-03-31 17:42:24 UTC (rev 182188)
@@ -53,6 +53,7 @@
         , m_hasAnnotationsBefore(false)
         , m_hasAnnotationsAfter(false)
         , m_isFirstAfterPageBreak(false)
+        , m_hasAnonymousInlineBlock(false)
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
         , m_hasBadChildList(false)
 #endif
@@ -211,6 +212,9 @@
     void setHasTextChildren() { m_hasTextChildren = true; setHasTextDescendants(); }
     void setHasTextDescendants() { m_hasTextDescendants = true; }
     
+    bool hasAnonymousInlineBlock() const { return m_hasAnonymousInlineBlock; }
+    void setHasAnonymousInlineBlock(bool b) { m_hasAnonymousInlineBlock = b; }
+
     void checkConsistency() const;
     void setHasBadChildList();
 
@@ -338,6 +342,7 @@
     unsigned m_lineBreakBidiStatusLast : 5; // UCharDirection
 
     unsigned m_isFirstAfterPageBreak : 1;
+    unsigned m_hasAnonymousInlineBlock : 1;
 
     // End of RootInlineBox-specific members.
 

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (182187 => 182188)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2015-03-31 17:32:46 UTC (rev 182187)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2015-03-31 17:42:24 UTC (rev 182188)
@@ -4024,7 +4024,8 @@
     while (RenderObject* child = childIterator.next()) {
         bool autoWrap = child->isReplaced() ? child->parent()->style().autoWrap() :
             child->style().autoWrap();
-
+        bool isAnonymousInlineBlock = child->isAnonymousInlineBlock();
+        
         if (!child->isBR()) {
             // Step One: determine whether or not we need to go ahead and
             // terminate our current line. Each discrete chunk can become
@@ -4114,19 +4115,21 @@
                     clearPreviousFloat = false;
 
                 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
-                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
+                if (((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) || isAnonymousInlineBlock) {
+                    if (child->isAnonymousInlineBlock() && styleToUse.collapseWhiteSpace())
+                        stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
                     minLogicalWidth = preferredWidth(minLogicalWidth, inlineMin);
                     inlineMin = 0;
                 }
 
                 // If we're supposed to clear the previous float, then terminate maxwidth as well.
-                if (clearPreviousFloat) {
+                if (clearPreviousFloat || isAnonymousInlineBlock) {
                     maxLogicalWidth = preferredWidth(maxLogicalWidth, inlineMax);
                     inlineMax = 0;
                 }
 
                 // Add in text-indent. This is added in only once.
-                if (!addedTextIndent && !child->isFloating()) {
+                if (!addedTextIndent && !child->isFloating() && !isAnonymousInlineBlock) {
                     LayoutUnit ceiledIndent = textIndent.ceilToFloat();
                     childMin += ceiledIndent;
                     childMax += ceiledIndent;
@@ -4140,7 +4143,7 @@
                 // Add our width to the max.
                 inlineMax += std::max<float>(0, childMax);
 
-                if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
+                if ((!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) && !isAnonymousInlineBlock) {
                     if (child->isFloating())
                         minLogicalWidth = preferredWidth(minLogicalWidth, childMin);
                     else
@@ -4151,6 +4154,12 @@
 
                     // Now start a new line.
                     inlineMin = 0;
+                    
+                    if (child->isAnonymousInlineBlock()) {
+                        // Terminate max width as well.
+                        maxLogicalWidth = preferredWidth(maxLogicalWidth, childMax);
+                        inlineMax = 0;
+                    }
                 }
 
                 if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
@@ -4261,8 +4270,8 @@
                     inlineMax += std::max<float>(0, childMax);
             }
 
-            // Ignore spaces after a list marker.
-            if (child->isListMarker())
+            // Ignore spaces after a list marker and also after an anonymous inline block.
+            if (child->isListMarker() || isAnonymousInlineBlock)
                 stripFrontSpaces = true;
         } else {
             minLogicalWidth = preferredWidth(minLogicalWidth, inlineMin);

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (182187 => 182188)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2015-03-31 17:32:46 UTC (rev 182187)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2015-03-31 17:42:24 UTC (rev 182188)
@@ -283,6 +283,8 @@
     bool rootHasSelectedChildren = false;
     InlineFlowBox* parentBox = 0;
     int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace();
+    
+    bool isAnonymousInlineBlock = false;
     for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) {
         // Create a box for our object.
         bool isOnlyRun = (runCount == 1);
@@ -297,14 +299,19 @@
 
         if (!rootHasSelectedChildren && box->renderer().selectionState() != RenderObject::SelectionNone)
             rootHasSelectedChildren = true;
-
+    
+        isAnonymousInlineBlock = r->renderer().isAnonymousInlineBlock();
+        
         // If we have no parent box yet, or if the run is not simply a sibling,
         // then we need to construct inline boxes as necessary to properly enclose the
         // run's inline box. Segments can only be siblings at the root level, as
         // they are positioned separately.
         if (!parentBox || &parentBox->renderer() != r->renderer().parent()) {
             // Create new inline boxes all the way back to the appropriate insertion point.
-            parentBox = createLineBoxes(r->renderer().parent(), lineInfo, box);
+            // For anonymous inline blocks, we never create intermediate line boxes for the inlines, since
+            // we want to pretend like they don't exist on the line.
+            RenderObject* parentToUse = isAnonymousInlineBlock ? this : r->renderer().parent();
+            parentBox = createLineBoxes(parentToUse, lineInfo, box);
         } else {
             // Append the inline box to this line.
             parentBox->addToLine(box);
@@ -341,6 +348,8 @@
 
     // Now mark the line boxes as being constructed.
     lastRootBox()->setConstructed();
+    
+    lastRootBox()->setHasAnonymousInlineBlock(isAnonymousInlineBlock);
 
     // Return the last line.
     return lastRootBox();

Modified: trunk/Source/WebCore/rendering/RootInlineBox.cpp (182187 => 182188)


--- trunk/Source/WebCore/rendering/RootInlineBox.cpp	2015-03-31 17:32:46 UTC (rev 182187)
+++ trunk/Source/WebCore/rendering/RootInlineBox.cpp	2015-03-31 17:42:24 UTC (rev 182188)
@@ -872,6 +872,14 @@
     // Replaced boxes will return 0 for the line-height if line-box-contain says they are
     // not to be included.
     if (box.renderer().isReplaced()) {
+        if (hasAnonymousInlineBlock()) {
+            ascent = box.logicalHeight(); // Margins exist "outside" the line, since they have to collapse.
+            descent = 0;
+            affectsAscent = true;
+            affectsDescent = true;
+            return;
+        }
+            
         if (lineStyle().lineBoxContain() & LineBoxContainReplaced) {
             ascent = box.baselinePosition(baselineType());
             descent = box.lineHeight() - ascent;
@@ -882,6 +890,9 @@
         }
         return;
     }
+    
+    if (hasAnonymousInlineBlock())
+        return;
 
     Vector<const Font*>* usedFonts = nullptr;
     GlyphOverflow* glyphOverflow = nullptr;

Modified: trunk/Source/WebCore/rendering/line/BreakingContext.h (182187 => 182188)


--- trunk/Source/WebCore/rendering/line/BreakingContext.h	2015-03-31 17:32:46 UTC (rev 182187)
+++ trunk/Source/WebCore/rendering/line/BreakingContext.h	2015-03-31 17:42:24 UTC (rev 182188)
@@ -490,9 +490,15 @@
         m_width.updateAvailableWidth(replacedBox.logicalHeight());
 
     // Break on replaced elements if either has normal white-space.
-    if ((m_autoWrap || RenderStyle::autoWrap(m_lastWS)) && (!m_current.renderer()->isImage() || m_allowImagesToBreak)
-        && (!m_current.renderer()->isRubyRun() || downcast<RenderRubyRun>(m_current.renderer())->canBreakBefore(m_renderTextInfo.m_lineBreakIterator))) {
+    if (((m_autoWrap || RenderStyle::autoWrap(m_lastWS)) && (!m_current.renderer()->isImage() || m_allowImagesToBreak)
+        && (!m_current.renderer()->isRubyRun() || downcast<RenderRubyRun>(m_current.renderer())->canBreakBefore(m_renderTextInfo.m_lineBreakIterator))) || replacedBox.isAnonymousInlineBlock()) {
         commitLineBreakAtCurrentWidth(*m_current.renderer());
+        if (m_width.committedWidth() && replacedBox.isAnonymousInlineBlock()) {
+            // Always force a break before an anonymous inline block if there is content on the line
+            // already.
+            m_atEnd = true;
+            return;
+        }
     }
 
     if (m_ignoringSpaces)
@@ -526,6 +532,11 @@
         // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for replaced element.
         m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter);
     }
+    
+    if (replacedBox.isAnonymousInlineBlock()) {
+        m_atEnd = true;
+        m_lineInfo.setPreviousLineBrokeCleanly(true);
+    }
 }
 
 inline float firstPositiveWidth(const WordMeasurements& wordMeasurements)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to