Title: [105350] branches/chromium/912

Diff

Copied: branches/chromium/912/LayoutTests/fast/css/first-letter-inline-flow-split-table-crash-expected.txt (from rev 104123, trunk/LayoutTests/fast/css/first-letter-inline-flow-split-table-crash-expected.txt) (0 => 105350)


--- branches/chromium/912/LayoutTests/fast/css/first-letter-inline-flow-split-table-crash-expected.txt	                        (rev 0)
+++ branches/chromium/912/LayoutTests/fast/css/first-letter-inline-flow-split-table-crash-expected.txt	2012-01-19 00:34:44 UTC (rev 105350)
@@ -0,0 +1 @@
+PASS, if no exception or crash in debug

Copied: branches/chromium/912/LayoutTests/fast/css/first-letter-inline-flow-split-table-crash.html (from rev 104123, trunk/LayoutTests/fast/css/first-letter-inline-flow-split-table-crash.html) (0 => 105350)


--- branches/chromium/912/LayoutTests/fast/css/first-letter-inline-flow-split-table-crash.html	                        (rev 0)
+++ branches/chromium/912/LayoutTests/fast/css/first-letter-inline-flow-split-table-crash.html	2012-01-19 00:34:44 UTC (rev 105350)
@@ -0,0 +1,47 @@
+<style>
+.noFloat:empty { float: none; }
+.theadStyle:nth-last-child(odd) { display: table-header-group; float: right; }
+.pSpanStyle { overflow: hidden; -webkit-appearance: button; }
+.pSpanStyle:first-letter { text-align: -webkit-left; content: counter(section); }
+</style>
+<script>
+var parentSpan =  document.createElement('span');
+var childSpan =  document.createElement('span');
+var thead = document.createElement('thead');
+var textNode = document.createTextNode('abc');
+
+function removeTextNode() {
+    childSpan.removeChild(textNode);
+    delete textNode;
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function changeClass() {
+    thead.setAttribute('class', 'noFloat');
+    setTimeout("removeTable()", 10);
+}
+
+function removeTable() {
+    childSpan.removeChild(thead);
+    setTimeout('removeTextNode();', 10);
+}
+
+function runTest() {
+    parentSpan.setAttribute('class', 'pSpanStyle');
+    document.documentElement.appendChild(parentSpan);
+    childSpan.setAttribute('class', 'noFloat');
+    parentSpan.appendChild(childSpan);
+    thead.setAttribute('class', 'theadStyle');
+    childSpan.appendChild(thead);
+    childSpan.appendChild(textNode);
+    setTimeout('changeClass();', 10);
+
+    if (window.layoutTestController) {
+        layoutTestController.waitUntilDone();
+        layoutTestController.dumpAsText();
+    }
+}
+window._onload_ = runTest;
+</script>
+PASS, if no exception or crash in debug

Modified: branches/chromium/912/Source/WebCore/rendering/RenderBlock.cpp (105349 => 105350)


--- branches/chromium/912/Source/WebCore/rendering/RenderBlock.cpp	2012-01-19 00:34:24 UTC (rev 105349)
+++ branches/chromium/912/Source/WebCore/rendering/RenderBlock.cpp	2012-01-19 00:34:44 UTC (rev 105350)
@@ -5616,38 +5616,14 @@
 
             RenderTextFragment* remainingText = 0;
             RenderObject* nextSibling = firstLetter->nextSibling();
-            RenderObject* next = nextSibling;
-            while (next) {
-                if (next->isText() && toRenderText(next)->isTextFragment()) {
-                    remainingText = toRenderTextFragment(next);
-                    break;
-                }
-                next = next->nextSibling();
-            }
-            if (!remainingText && firstLetterContainer->isAnonymousBlock()) {
-                // The remaining text fragment could have been wrapped in a different anonymous block since creation
-                RenderObject* nextChild;
-                next = firstLetterContainer->nextSibling();
-                while (next && !remainingText) {
-                    if (next->isAnonymousBlock()) {
-                        nextChild = next->firstChild();
-                        while (nextChild) {
-                            if (nextChild->isText() && toRenderText(nextChild)->isTextFragment()
-                                && (toRenderTextFragment(nextChild)->firstLetter() == firstLetter)) {
-                                remainingText = toRenderTextFragment(nextChild);
-                                break;
-                            }
-                            nextChild = nextChild->nextSibling();
-                        }
-                    } else
-                        break;
-                    next = next->nextSibling();
-                }
-            }
+            RenderObject* remainingTextObject = toRenderBoxModelObject(firstLetter)->firstLetterRemainingText();
+            if (remainingTextObject && remainingTextObject->isText() && toRenderText(remainingTextObject)->isTextFragment())
+                remainingText = toRenderTextFragment(remainingTextObject);
             if (remainingText) {
                 ASSERT(remainingText->isAnonymous() || remainingText->node()->renderer() == remainingText);
                 // Replace the old renderer with the new one.
                 remainingText->setFirstLetter(newFirstLetter);
+                toRenderBoxModelObject(newFirstLetter)->setFirstLetterRemainingText(remainingText);
             }
             firstLetter->destroy();
             firstLetter = newFirstLetter;
@@ -5725,6 +5701,7 @@
         firstLetterContainer->addChild(remainingText, textObj);
         firstLetterContainer->removeChild(textObj);
         remainingText->setFirstLetter(firstLetter);
+        toRenderBoxModelObject(firstLetter)->setFirstLetterRemainingText(remainingText);
         
         // construct text fragment for the first letter
         RenderTextFragment* letter = 

Modified: branches/chromium/912/Source/WebCore/rendering/RenderBoxModelObject.cpp (105349 => 105350)


--- branches/chromium/912/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-01-19 00:34:24 UTC (rev 105349)
+++ branches/chromium/912/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-01-19 00:34:44 UTC (rev 105350)
@@ -64,6 +64,11 @@
 typedef HashMap<const RenderBoxModelObject*, RenderBoxModelObject*> ContinuationMap;
 static ContinuationMap* continuationMap = 0;
 
+// This HashMap is similar to the continuation map, but connects first-letter
+// renderers to their remaining text fragments.
+typedef HashMap<const RenderBoxModelObject*, RenderObject*> FirstLetterRemainingTextMap;
+static FirstLetterRemainingTextMap* firstLetterRemainingTextMap = 0;
+
 class ImageQualityController {
     WTF_MAKE_NONCOPYABLE(ImageQualityController); WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -281,6 +286,11 @@
     // A continuation of this RenderObject should be destroyed at subclasses.
     ASSERT(!continuation());
 
+    // If this is a first-letter object with a remaining text fragment then the
+    // entry needs to be cleared from the map.
+    if (firstLetterRemainingText())
+        setFirstLetterRemainingText(0);
+
     // RenderObject::willBeDestroyed calls back to destroyLayer() for layer destruction
     RenderObject::willBeDestroyed();
 }
@@ -2573,6 +2583,23 @@
     }
 }
 
+RenderObject* RenderBoxModelObject::firstLetterRemainingText() const
+{
+    if (!firstLetterRemainingTextMap)
+        return 0;
+    return firstLetterRemainingTextMap->get(this);
+}
+
+void RenderBoxModelObject::setFirstLetterRemainingText(RenderObject* remainingText)
+{
+    if (remainingText) {
+        if (!firstLetterRemainingTextMap)
+            firstLetterRemainingTextMap = new FirstLetterRemainingTextMap;
+        firstLetterRemainingTextMap->set(this, remainingText);
+    } else if (firstLetterRemainingTextMap)
+        firstLetterRemainingTextMap->remove(this);
+}
+
 bool RenderBoxModelObject::shouldAntialiasLines(GraphicsContext* context)
 {
     // FIXME: We may want to not antialias when scaled by an integral value,

Modified: branches/chromium/912/Source/WebCore/rendering/RenderBoxModelObject.h (105349 => 105350)


--- branches/chromium/912/Source/WebCore/rendering/RenderBoxModelObject.h	2012-01-19 00:34:24 UTC (rev 105349)
+++ branches/chromium/912/Source/WebCore/rendering/RenderBoxModelObject.h	2012-01-19 00:34:44 UTC (rev 105350)
@@ -192,6 +192,11 @@
 
     static bool shouldAntialiasLines(GraphicsContext*);
 
+public:
+    // For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments
+    RenderObject* firstLetterRemainingText() const;
+    void setFirstLetterRemainingText(RenderObject*);
+
 private:
     virtual bool isBoxModelObject() const { return true; }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to