Reviewed by darin
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Oct 2004 01:08:56 +0000 (01:08 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Oct 2004 01:08:56 +0000 (01:08 +0000)
Clean up the inline run function so that it doesn't return incorrect answers when making children non-inline.

<rdar://problem/3848724> REGRESSION (166-168u): RenderText::layout called, firing assertion that kills Mail
<rdar://problem/3848357> RenderText::layout called, firing assertion that kills Safari (www.apple.com/downloads/macosx)

        * khtml/rendering/render_block.cpp:
        (khtml::getInlineRun):
        (khtml::RenderBlock::makeChildrenNonInline):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7878 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/fast/dynamic/noninlinebadness-expected.txt [new file with mode: 0644]
LayoutTests/fast/dynamic/noninlinebadness.html [new file with mode: 0644]
WebCore/ChangeLog-2005-08-23
WebCore/khtml/rendering/render_block.cpp

diff --git a/LayoutTests/fast/dynamic/noninlinebadness-expected.txt b/LayoutTests/fast/dynamic/noninlinebadness-expected.txt
new file mode 100644 (file)
index 0000000..67334cd
--- /dev/null
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {DIV} at (0,0) size 784x236
+        RenderBlock (floating) {DIV} at (0,0) size 200x200
+        RenderBlock {DIV} at (0,0) size 200x200 [bgcolor=#00FF00]
+        RenderBlock (anonymous) at (0,200) size 784x36
+          RenderText {TEXT} at (0,0) size 725x36
+            text run at (0,0) width 233: "This text should be underneath a 200"
+            text run at (233,0) width 103: "x200 lime float. "
+            text run at (336,0) width 389: "We are making sure that the code that wraps inline children in"
+            text run at (0,18) width 608: "anonymous blocks does the right thing when blocks are inserted in between a float and an inline."
diff --git a/LayoutTests/fast/dynamic/noninlinebadness.html b/LayoutTests/fast/dynamic/noninlinebadness.html
new file mode 100644 (file)
index 0000000..7c51c5e
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+<body><div><div style="float:left; width:200px;height:200px;"></div>
+This text should be underneath a 200x200 lime float.  We are making sure that the code that wraps
+inline children in anonymous blocks does the right thing when blocks are inserted in between a float
+and an inline.
+</div>
+<script>
+var floatDiv = document.createElement("div");
+floatDiv.setAttribute("style", "width:200px; height:200px; background-color:lime");
+document.body.firstChild.insertBefore(floatDiv, document.body.firstChild.childNodes[1]);
+</script>
+</body>
index 340b7e99e3adfb056bc625745bcadbecb02d3744..d24638e1a4cb9ffd1105d52dd3227a40c77b3623 100644 (file)
@@ -1,3 +1,16 @@
+2004-10-21  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by darin
+       
+       Clean up the inline run function so that it doesn't return incorrect answers when making children non-inline.
+       
+       <rdar://problem/3848724> REGRESSION (166-168u): RenderText::layout called, firing assertion that kills Mail
+       <rdar://problem/3848357> RenderText::layout called, firing assertion that kills Safari (www.apple.com/downloads/macosx)
+       
+        * khtml/rendering/render_block.cpp:
+        (khtml::getInlineRun):
+        (khtml::RenderBlock::makeChildrenNonInline):
+
 2004-10-21  David Hyatt  <hyatt@apple.com>
 
        Fix for 3810389, crash because of continuation() craziness.  Revert back to the old behavior of
index 0c7c61217cca7564464aec4ac2f61475256c9ec6..cc8328a122f313a7594492bfa3352ebc478cee90 100644 (file)
@@ -213,7 +213,7 @@ void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChi
         removeLeftoverAnonymousBoxes();
 }
 
-static void getInlineRun(RenderObject* start, RenderObject* stop,
+static void getInlineRun(RenderObject* start, RenderObject* boundary,
                          RenderObject*& inlineRunStart,
                          RenderObject*& inlineRunEnd)
 {
@@ -225,22 +225,36 @@ static void getInlineRun(RenderObject* start, RenderObject* stop,
     // We skip any non-inlines we encounter as long as we haven't found any
     // inlines yet.
     //
-    // |stop| indicates a non-inclusive stop point.  Regardless of whether |stop|
-    // is inline or not, we will not include it.  It's as though we encountered
+    // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
+    // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
     // a non-inline.
-    inlineRunStart = inlineRunEnd = 0;
-    for (RenderObject* curr = start;
-         curr && curr != stop && (!inlineRunStart || curr->isInline() || curr->isFloatingOrPositioned());
-         curr = curr->nextSibling()) {
-        if (inlineRunStart)
+    
+    // Start by skipping as many non-inlines as we can.
+    RenderObject * curr = start;
+    bool sawInline;
+    do {
+        while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
+            curr = curr->nextSibling();
+        
+        inlineRunStart = inlineRunEnd = curr;
+        
+        if (!curr)
+            return; // No more inline children to be found.
+        
+        sawInline = curr->isInline();
+        
+        curr = curr->nextSibling();
+        while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
             inlineRunEnd = curr;
-        else if (curr->isInline())
-            inlineRunStart = inlineRunEnd = curr;
-    }
+            if (curr->isInline())
+                sawInline = true;
+            curr = curr->nextSibling();
+        }
+    } while (!sawInline);
 }
 
 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
-{
+{    
     // makeChildrenNonInline takes a block whose children are *all* inline and it
     // makes sure that inline children are coalesced under anonymous
     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
@@ -275,6 +289,11 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
         }
         box->appendChildNode(removeChildNode(inlineRunEnd));
     }
+
+#ifndef NDEBUG
+    for (RenderObject *c = firstChild(); c; c = c->nextSibling())
+        KHTMLAssert(!c->isInline());
+#endif
 }
 
 void RenderBlock::removeChild(RenderObject *oldChild)