Title: [110459] branches/chromium/1025

Diff

Copied: branches/chromium/1025/LayoutTests/editing/selection/first-letter-selection-crash-expected.txt (from rev 110323, trunk/LayoutTests/editing/selection/first-letter-selection-crash-expected.txt) (0 => 110459)


--- branches/chromium/1025/LayoutTests/editing/selection/first-letter-selection-crash-expected.txt	                        (rev 0)
+++ branches/chromium/1025/LayoutTests/editing/selection/first-letter-selection-crash-expected.txt	2012-03-12 19:47:16 UTC (rev 110459)
@@ -0,0 +1 @@
+PASS

Copied: branches/chromium/1025/LayoutTests/editing/selection/first-letter-selection-crash.html (from rev 110323, trunk/LayoutTests/editing/selection/first-letter-selection-crash.html) (0 => 110459)


--- branches/chromium/1025/LayoutTests/editing/selection/first-letter-selection-crash.html	                        (rev 0)
+++ branches/chromium/1025/LayoutTests/editing/selection/first-letter-selection-crash.html	2012-03-12 19:47:16 UTC (rev 110459)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<body>
+<style>
+#test2:first-letter { display: block; }
+</style>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+window._onload_ = function() {
+    test1 = document.createElement('div');
+    document.body.appendChild(test1);
+    test2 = document.createElement('div');
+    test2.setAttribute('id', 'test2');
+    test2.appendChild(document.createTextNode('aaa'));
+    test2.style.display = 'inline-block';
+    test1.appendChild(test2); 
+    test1.appendChild(document.createTextNode('a'));
+    document.execCommand('selectall');
+    document.body.offsetTop;
+    document.styleSheets[0].insertRule("#test2 { text-transform: uppercase }");
+    document.body.offsetTop;
+    document.body.innerHTML = "PASS";
+}
+</script>
+</body>
+</html>

Modified: branches/chromium/1025/Source/WebCore/rendering/RenderBoxModelObject.cpp (110458 => 110459)


--- branches/chromium/1025/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-03-12 19:44:37 UTC (rev 110458)
+++ branches/chromium/1025/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-03-12 19:47:16 UTC (rev 110459)
@@ -224,26 +224,23 @@
     return gImageQualityController;
 }
 
-void RenderBoxModelObject::setSelectionState(SelectionState s)
+void RenderBoxModelObject::setSelectionState(SelectionState state)
 {
-    if (selectionState() == s)
+    if (state == SelectionInside && selectionState() != SelectionNone)
         return;
-    
-    if (s == SelectionInside && selectionState() != SelectionNone)
-        return;
 
-    if ((s == SelectionStart && selectionState() == SelectionEnd)
-        || (s == SelectionEnd && selectionState() == SelectionStart))
+    if ((state == SelectionStart && selectionState() == SelectionEnd)
+        || (state == SelectionEnd && selectionState() == SelectionStart))
         RenderObject::setSelectionState(SelectionBoth);
     else
-        RenderObject::setSelectionState(s);
-    
-    // FIXME:
-    // We should consider whether it is OK propagating to ancestor RenderInlines.
+        RenderObject::setSelectionState(state);
+
+    // FIXME: We should consider whether it is OK propagating to ancestor RenderInlines.
     // This is a workaround for http://webkit.org/b/32123
-    RenderBlock* cb = containingBlock();
-    if (cb && !cb->isRenderView())
-        cb->setSelectionState(s);
+    // The containing block can be null in case of an orphaned tree.
+    RenderBlock* containingBlock = this->containingBlock();
+    if (containingBlock && !containingBlock->isRenderView())
+        containingBlock->setSelectionState(state);
 }
 
 bool RenderBoxModelObject::shouldPaintAtLowQuality(GraphicsContext* context, Image* image, const void* layer, const LayoutSize& size)

Modified: branches/chromium/1025/Source/WebCore/rendering/RenderListMarker.cpp (110458 => 110459)


--- branches/chromium/1025/Source/WebCore/rendering/RenderListMarker.cpp	2012-03-12 19:44:37 UTC (rev 110458)
+++ branches/chromium/1025/Source/WebCore/rendering/RenderListMarker.cpp	2012-03-12 19:47:16 UTC (rev 110459)
@@ -1694,11 +1694,12 @@
 
 void RenderListMarker::setSelectionState(SelectionState state)
 {
+    // The selection state for our containing block hierarchy is updated by the base class call.
     RenderBox::setSelectionState(state);
-    if (InlineBox* box = inlineBoxWrapper())
-        if (RootInlineBox* root = box->root())
+
+    if (m_inlineBoxWrapper && canUpdateSelectionOnRootLineBoxes())
+        if (RootInlineBox* root = m_inlineBoxWrapper->root())
             root->setHasSelectedChildren(state != SelectionNone);
-    containingBlock()->setSelectionState(state);
 }
 
 LayoutRect RenderListMarker::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent)

Modified: branches/chromium/1025/Source/WebCore/rendering/RenderObject.cpp (110458 => 110459)


--- branches/chromium/1025/Source/WebCore/rendering/RenderObject.cpp	2012-03-12 19:44:37 UTC (rev 110458)
+++ branches/chromium/1025/Source/WebCore/rendering/RenderObject.cpp	2012-03-12 19:47:16 UTC (rev 110459)
@@ -2786,6 +2786,12 @@
     return SetCursorBasedOnStyle;
 }
 
+bool RenderObject::canUpdateSelectionOnRootLineBoxes()
+{
+    RenderBlock* containingBlock = this->containingBlock();
+    return containingBlock ? !containingBlock->needsLayout() : true;
+}
+
 #if ENABLE(SVG)
 
 RenderSVGResourceContainer* RenderObject::toRenderSVGResourceContainer()

Modified: branches/chromium/1025/Source/WebCore/rendering/RenderObject.h (110458 => 110459)


--- branches/chromium/1025/Source/WebCore/rendering/RenderObject.h	2012-03-12 19:44:37 UTC (rev 110458)
+++ branches/chromium/1025/Source/WebCore/rendering/RenderObject.h	2012-03-12 19:47:16 UTC (rev 110459)
@@ -764,6 +764,8 @@
     // descendants (as described above in the SelectionState enum declaration).
     SelectionState selectionState() const { return m_bitfields.selectionState(); }
     virtual void setSelectionState(SelectionState state) { m_bitfields.setSelectionState(state); }
+    inline void setSelectionStateIfNeeded(SelectionState);
+    bool canUpdateSelectionOnRootLineBoxes();
 
     // A single rectangle that encompasses all of the selected objects within this object.  Used to determine the tightest
     // possible bounding box for the selection.
@@ -1105,6 +1107,14 @@
     return style()->preserveNewline();
 }
 
+inline void RenderObject::setSelectionStateIfNeeded(SelectionState state)
+{
+    if (selectionState() == state)
+        return;
+
+    setSelectionState(state);
+}
+
 inline void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering)
 {
 #if !ENABLE(3D_RENDERING)

Modified: branches/chromium/1025/Source/WebCore/rendering/RenderReplaced.cpp (110458 => 110459)


--- branches/chromium/1025/Source/WebCore/rendering/RenderReplaced.cpp	2012-03-12 19:44:37 UTC (rev 110458)
+++ branches/chromium/1025/Source/WebCore/rendering/RenderReplaced.cpp	2012-03-12 19:47:16 UTC (rev 110459)
@@ -500,14 +500,14 @@
     return IntRect(newLogicalTop, 0, root->selectionHeight(), height());
 }
 
-void RenderReplaced::setSelectionState(SelectionState s)
+void RenderReplaced::setSelectionState(SelectionState state)
 {
-    RenderBox::setSelectionState(s); // The selection state for our containing block hierarchy is updated by the base class call.
-    if (m_inlineBoxWrapper) {
-        RootInlineBox* line = m_inlineBoxWrapper->root();
-        if (line)
-            line->setHasSelectedChildren(isSelected());
-    }
+    // The selection state for our containing block hierarchy is updated by the base class call.
+    RenderBox::setSelectionState(state);
+
+    if (m_inlineBoxWrapper && canUpdateSelectionOnRootLineBoxes())
+        if (RootInlineBox* root = m_inlineBoxWrapper->root())
+            root->setHasSelectedChildren(isSelected());
 }
 
 bool RenderReplaced::isSelected() const

Modified: branches/chromium/1025/Source/WebCore/rendering/RenderText.cpp (110458 => 110459)


--- branches/chromium/1025/Source/WebCore/rendering/RenderText.cpp	2012-03-12 19:44:37 UTC (rev 110458)
+++ branches/chromium/1025/Source/WebCore/rendering/RenderText.cpp	2012-03-12 19:47:16 UTC (rev 110459)
@@ -1134,39 +1134,41 @@
     
 void RenderText::setSelectionState(SelectionState state)
 {
-    InlineTextBox* box;
-
     RenderObject::setSelectionState(state);
-    if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) {
-        int startPos, endPos;
-        selectionStartEnd(startPos, endPos);
-        if (selectionState() == SelectionStart) {
-            endPos = textLength();
 
-            // to handle selection from end of text to end of line
-            if (startPos != 0 && startPos == endPos)
-                startPos = endPos - 1;
-        } else if (selectionState() == SelectionEnd)
-            startPos = 0;
+    if (canUpdateSelectionOnRootLineBoxes()) {
+        if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) {
+            int startPos, endPos;
+            selectionStartEnd(startPos, endPos);
+            if (selectionState() == SelectionStart) {
+                endPos = textLength();
 
-        for (box = firstTextBox(); box; box = box->nextTextBox()) {
-            if (box->isSelected(startPos, endPos)) {
-                RootInlineBox* line = box->root();
-                if (line)
-                    line->setHasSelectedChildren(true);
+                // to handle selection from end of text to end of line
+                if (startPos && startPos == endPos)
+                    startPos = endPos - 1;
+            } else if (selectionState() == SelectionEnd)
+                startPos = 0;
+
+            for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
+                if (box->isSelected(startPos, endPos)) {
+                    RootInlineBox* root = box->root();
+                    if (root)
+                        root->setHasSelectedChildren(true);
+                }
             }
+        } else {
+            for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
+                RootInlineBox* root = box->root();
+                if (root)
+                    root->setHasSelectedChildren(state == SelectionInside);
+            }
         }
-    } else {
-        for (box = firstTextBox(); box; box = box->nextTextBox()) {
-            RootInlineBox* line = box->root();
-            if (line)
-                line->setHasSelectedChildren(state == SelectionInside);
-        }
     }
 
-    // The returned value can be null in case of an orphaned tree.
-    if (RenderBlock* cb = containingBlock())
-        cb->setSelectionState(state);
+    // The containing block can be null in case of an orphaned tree.
+    RenderBlock* containingBlock = this->containingBlock();
+    if (containingBlock && !containingBlock->isRenderView())
+        containingBlock->setSelectionState(state);
 }
 
 void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force)

Modified: branches/chromium/1025/Source/WebCore/rendering/RenderView.cpp (110458 => 110459)


--- branches/chromium/1025/Source/WebCore/rendering/RenderView.cpp	2012-03-12 19:44:37 UTC (rev 110458)
+++ branches/chromium/1025/Source/WebCore/rendering/RenderView.cpp	2012-03-12 19:47:16 UTC (rev 110459)
@@ -487,7 +487,7 @@
     // Now clear the selection.
     SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i)
-        i->first->setSelectionState(SelectionNone);
+        i->first->setSelectionStateIfNeeded(SelectionNone);
 
     // set selection start and end
     m_selectionStart = start;
@@ -497,12 +497,12 @@
 
     // Update the selection status of all objects between m_selectionStart and m_selectionEnd
     if (start && start == end)
-        start->setSelectionState(SelectionBoth);
+        start->setSelectionStateIfNeeded(SelectionBoth);
     else {
         if (start)
-            start->setSelectionState(SelectionStart);
+            start->setSelectionStateIfNeeded(SelectionStart);
         if (end)
-            end->setSelectionState(SelectionEnd);
+            end->setSelectionStateIfNeeded(SelectionEnd);
     }
 
     RenderObject* o = start;
@@ -510,7 +510,7 @@
 
     while (o && o != stop) {
         if (o != start && o != end && o->canBeSelectionLeaf())
-            o->setSelectionState(SelectionInside);
+            o->setSelectionStateIfNeeded(SelectionInside);
         o = o->nextInPreOrder();
     }
 

Modified: branches/chromium/1025/Source/WebCore/rendering/RenderWidget.cpp (110458 => 110459)


--- branches/chromium/1025/Source/WebCore/rendering/RenderWidget.cpp	2012-03-12 19:44:37 UTC (rev 110458)
+++ branches/chromium/1025/Source/WebCore/rendering/RenderWidget.cpp	2012-03-12 19:47:16 UTC (rev 110459)
@@ -359,11 +359,11 @@
 
 void RenderWidget::setSelectionState(SelectionState state)
 {
-    if (selectionState() != state) {
-        RenderReplaced::setSelectionState(state);
-        if (m_widget)
-            m_widget->setIsSelected(isSelected());
-    }
+    // The selection state for our containing block hierarchy is updated by the base class call.
+    RenderReplaced::setSelectionState(state);
+
+    if (m_widget)
+        m_widget->setIsSelected(isSelected());
 }
 
 void RenderWidget::clearWidget()
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to