Title: [89952] trunk/Source/WebCore
Revision
89952
Author
[email protected]
Date
2011-06-28 13:07:31 -0700 (Tue, 28 Jun 2011)

Log Message

2011-06-28  Ryosuke Niwa  <[email protected]>

        Reviewed by Darin Adler.

        Stop instantiating Position with PositionIsOffsetInAnchor in various files
        https://bugs.webkit.org/show_bug.cgi?id=63384

        Refactoring.

        Removed many if conditions that compared the anchor type to Position::PositionIsOffsetInAnchor
        because there were also checking that containerNode is a text node.

        Also added Position::containerText() to avoid manually casting containerNode().

        * dom/Position.cpp:
        (WebCore::Position::Position): Added an assertion to ensure BeforeChildren/AfterChildren
        anchor type won't be used for a node whose contents is ignored by editing.
        (WebCore::Position::containerText): Added.
        * dom/Position.h:
        * editing/ApplyBlockElementCommand.cpp:
        (WebCore::isNewLineAtPosition): Removed a redundant comparison of anchor type.
        (WebCore::ApplyBlockElementCommand::rangeForParagraphSplittingTextNodesIfNeeded): Since containerNode
        is always a text node when renderStyleOfEnclosingTextNode returns a render style, use new Position
        constructor that takes Text* and offset.
        (WebCore::ApplyBlockElementCommand::endOfNextParagrahSplittingTextNodesIfNeeded): Removed redundant
        comparison of anchor type and use new Position constructor that takes Text* and offset.
        * editing/ApplyStyleCommand.cpp:
        (WebCore::ApplyStyleCommand::splitTextAtStart): Replaced an assertion that compared anchor type by
        an assertion that the container node is a text node; use new constructor.
        (WebCore::ApplyStyleCommand::splitTextAtEnd): Ditto; also added early exits in the case script
        modified DOM.
        (WebCore::ApplyStyleCommand::splitTextElementAtStart): Ditto.
        (WebCore::ApplyStyleCommand::splitTextElementAtEnd): Ditto.
        (WebCore::ApplyStyleCommand::joinChildTextNodes): Use new constructor.
        * editing/CompositeEditCommand.cpp:
        (WebCore::Editor::replaceSelectedTextInNode): Calls containerText instead of manually casting containerNode.
        * editing/Editor.cpp:
        (WebCore::Editor::canDeleteRange): Call Range::startPosition instead of manually instantiating Position
        by calling startContainer and startOffset.
        * editing/FrameSelection.cpp:
        (WebCore::FrameSelection::setSelectedRange): Ditto.
        * editing/InsertTextCommand.cpp:
        (WebCore::InsertTextCommand::input): Calls containerText instead of manually casting containerNode.
        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplaceSelectionCommand::doApply): Calls containerText instead of manually casting containerNode.
        * editing/VisiblePosition.cpp:
        (WebCore::VisiblePosition::characterAfter): Removed a redundant anchor type comparison.
        (WebCore::startVisiblePosition): Call Range::startPosition instead of startContainer and startOffset.
        (WebCore::endVisiblePosition): Call Range::endPosition instead of endContainer and endOffset.
        * editing/htmlediting.cpp:
        (WebCore::firstInSpecialElement): Call containerNode() to address <rdar://problem/5027702>.
        (WebCore::lastInSpecialElement): Ditto; use new constructor.
        * editing/visible_units.cpp:
        (WebCore::endPositionForLine): Use new constructor.
        (WebCore::startOfParagraph): Ditto.
        (WebCore::endOfParagraph): Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (89951 => 89952)


--- trunk/Source/WebCore/ChangeLog	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/ChangeLog	2011-06-28 20:07:31 UTC (rev 89952)
@@ -1,3 +1,60 @@
+2011-06-28  Ryosuke Niwa  <[email protected]>
+
+        Reviewed by Darin Adler.
+
+        Stop instantiating Position with PositionIsOffsetInAnchor in various files
+        https://bugs.webkit.org/show_bug.cgi?id=63384
+
+        Refactoring.
+
+        Removed many if conditions that compared the anchor type to Position::PositionIsOffsetInAnchor
+        because there were also checking that containerNode is a text node.
+
+        Also added Position::containerText() to avoid manually casting containerNode().
+
+        * dom/Position.cpp:
+        (WebCore::Position::Position): Added an assertion to ensure BeforeChildren/AfterChildren
+        anchor type won't be used for a node whose contents is ignored by editing.
+        (WebCore::Position::containerText): Added.
+        * dom/Position.h:
+        * editing/ApplyBlockElementCommand.cpp:
+        (WebCore::isNewLineAtPosition): Removed a redundant comparison of anchor type.
+        (WebCore::ApplyBlockElementCommand::rangeForParagraphSplittingTextNodesIfNeeded): Since containerNode
+        is always a text node when renderStyleOfEnclosingTextNode returns a render style, use new Position
+        constructor that takes Text* and offset.
+        (WebCore::ApplyBlockElementCommand::endOfNextParagrahSplittingTextNodesIfNeeded): Removed redundant
+        comparison of anchor type and use new Position constructor that takes Text* and offset.
+        * editing/ApplyStyleCommand.cpp:
+        (WebCore::ApplyStyleCommand::splitTextAtStart): Replaced an assertion that compared anchor type by
+        an assertion that the container node is a text node; use new constructor.
+        (WebCore::ApplyStyleCommand::splitTextAtEnd): Ditto; also added early exits in the case script
+        modified DOM.
+        (WebCore::ApplyStyleCommand::splitTextElementAtStart): Ditto.
+        (WebCore::ApplyStyleCommand::splitTextElementAtEnd): Ditto.
+        (WebCore::ApplyStyleCommand::joinChildTextNodes): Use new constructor.
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::Editor::replaceSelectedTextInNode): Calls containerText instead of manually casting containerNode.
+        * editing/Editor.cpp:
+        (WebCore::Editor::canDeleteRange): Call Range::startPosition instead of manually instantiating Position
+        by calling startContainer and startOffset.
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::setSelectedRange): Ditto.
+        * editing/InsertTextCommand.cpp:
+        (WebCore::InsertTextCommand::input): Calls containerText instead of manually casting containerNode.
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::doApply): Calls containerText instead of manually casting containerNode.
+        * editing/VisiblePosition.cpp:
+        (WebCore::VisiblePosition::characterAfter): Removed a redundant anchor type comparison.
+        (WebCore::startVisiblePosition): Call Range::startPosition instead of startContainer and startOffset.
+        (WebCore::endVisiblePosition): Call Range::endPosition instead of endContainer and endOffset.
+        * editing/htmlediting.cpp:
+        (WebCore::firstInSpecialElement): Call containerNode() to address <rdar://problem/5027702>.
+        (WebCore::lastInSpecialElement): Ditto; use new constructor.
+        * editing/visible_units.cpp:
+        (WebCore::endPositionForLine): Use new constructor.
+        (WebCore::startOfParagraph): Ditto.
+        (WebCore::endOfParagraph): Ditto.
+
 2011-06-28  Rob Buis  <[email protected]>
 
         Reviewed by Nikolas Zimmermann.

Modified: trunk/Source/WebCore/dom/Position.cpp (89951 => 89952)


--- trunk/Source/WebCore/dom/Position.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/dom/Position.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -91,7 +91,8 @@
 {
     ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot());
     ASSERT(anchorType != PositionIsOffsetInAnchor);
-    ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren) && m_anchorNode->isTextNode()));
+    ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren)
+        && (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
 }
 
 Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorType)
@@ -148,6 +149,23 @@
     return 0;
 }
 
+Text* Position::containerText() const
+{
+    switch (anchorType()) {
+    case PositionIsOffsetInAnchor:
+        return m_anchorNode && m_anchorNode->isTextNode() ? static_cast<Text*>(m_anchorNode.get()) : 0;
+    case PositionIsBeforeAnchor:
+    case PositionIsAfterAnchor:
+        return 0;
+    case PositionIsBeforeChildren:
+    case PositionIsAfterChildren:
+        ASSERT(!m_anchorNode || !m_anchorNode->isTextNode());
+        return 0;
+    }
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
 int Position::computeOffsetInContainerNode() const
 {
     if (!m_anchorNode)

Modified: trunk/Source/WebCore/dom/Position.h (89951 => 89952)


--- trunk/Source/WebCore/dom/Position.h	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/dom/Position.h	2011-06-28 20:07:31 UTC (rev 89952)
@@ -96,6 +96,8 @@
     // These are always DOM compliant values.  Editing positions like [img, 0] (aka [img, before])
     // will return img->parentNode() and img->nodeIndex() from these functions.
     Node* containerNode() const; // NULL for a before/after position anchored to a node with no parent
+    Text* containerText() const;
+
     int computeOffsetInContainerNode() const;  // O(n) for before/after-anchored positions, O(1) for parent-anchored positions
     Position parentAnchoredEquivalent() const; // Convenience method for DOM positions that also fixes up some positions for editing
 

Modified: trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -150,9 +150,6 @@
 
 static bool isNewLineAtPosition(const Position& position)
 {
-    if (position.anchorType() != Position::PositionIsOffsetInAnchor)
-        return false;
-
     Node* textNode = position.containerNode();
     int offset = position.offsetInContainerNode();
     if (!textNode || !textNode->isTextNode() || offset < 0 || offset >= textNode->maxCharacterOffset())
@@ -181,11 +178,10 @@
     start = startOfParagraph(endOfCurrentParagraph).deepEquivalent();
     end = endOfCurrentParagraph.deepEquivalent();
 
-    RenderStyle* startStyle = renderStyleOfEnclosingTextNode(start);
     bool isStartAndEndOnSameNode = false;
-    if (startStyle) {
-        isStartAndEndOnSameNode = renderStyleOfEnclosingTextNode(end) && start.deprecatedNode() == end.deprecatedNode();
-        bool isStartAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && start.deprecatedNode() == m_endOfLastParagraph.deprecatedNode();
+    if (RenderStyle* startStyle = renderStyleOfEnclosingTextNode(start)) {
+        isStartAndEndOnSameNode = renderStyleOfEnclosingTextNode(end) && start.containerNode() == end.containerNode();
+        bool isStartAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && start.containerNode() == m_endOfLastParagraph.containerNode();
 
         // Avoid obtanining the start of next paragraph for start
         if (startStyle->preserveNewline() && isNewLineAtPosition(start) && !isNewLineAtPosition(start.previous()) && start.offsetInContainerNode() > 0)
@@ -194,47 +190,44 @@
         // If start is in the middle of a text node, split.
         if (!startStyle->collapseWhiteSpace() && start.offsetInContainerNode() > 0) {
             int startOffset = start.offsetInContainerNode();
-            splitTextNode(static_cast<Text*>(start.deprecatedNode()), startOffset);
-            start = firstPositionInOrBeforeNode(start.deprecatedNode());
+            Text* startText = start.containerText();
+            splitTextNode(startText, startOffset);
+            start = firstPositionInNode(startText);
             if (isStartAndEndOnSameNode) {
                 ASSERT(end.offsetInContainerNode() >= startOffset);
-                end = Position(end.deprecatedNode(), end.offsetInContainerNode() - startOffset, Position::PositionIsOffsetInAnchor);
+                end = Position(startText, end.offsetInContainerNode() - startOffset);
             }
             if (isStartAndEndOfLastParagraphOnSameNode) {
                 ASSERT(m_endOfLastParagraph.offsetInContainerNode() >= startOffset);
-                m_endOfLastParagraph = Position(m_endOfLastParagraph.deprecatedNode(), m_endOfLastParagraph.offsetInContainerNode() - startOffset,
-                    Position::PositionIsOffsetInAnchor);
+                m_endOfLastParagraph = Position(startText, m_endOfLastParagraph.offsetInContainerNode() - startOffset);
             }
         }
     }
 
-    RenderStyle* endStyle = renderStyleOfEnclosingTextNode(end);
-    if (endStyle) {
+    if (RenderStyle* endStyle = renderStyleOfEnclosingTextNode(end)) {
         bool isEndAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && end.deprecatedNode() == m_endOfLastParagraph.deprecatedNode();
         // Include \n at the end of line if we're at an empty paragraph
-        if (endStyle->preserveNewline() && start == end
-            && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
+        if (endStyle->preserveNewline() && start == end && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
             int endOffset = end.offsetInContainerNode();
             if (!isNewLineAtPosition(end.previous()) && isNewLineAtPosition(end))
-                end = Position(end.deprecatedNode(), endOffset + 1, Position::PositionIsOffsetInAnchor);
+                end = Position(end.containerText(), endOffset + 1);
             if (isEndAndEndOfLastParagraphOnSameNode && end.offsetInContainerNode() >= m_endOfLastParagraph.offsetInContainerNode())
                 m_endOfLastParagraph = end;
         }
 
         // If end is in the middle of a text node, split.
-        if (!endStyle->collapseWhiteSpace() && end.offsetInContainerNode()
-            && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
-            splitTextNode(static_cast<Text*>(end.deprecatedNode()), end.offsetInContainerNode());
+        if (!endStyle->collapseWhiteSpace() && end.offsetInContainerNode() && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
+            RefPtr<Text> endContainer = end.containerText();
+            splitTextNode(endContainer, end.offsetInContainerNode());
             if (isStartAndEndOnSameNode)
-                start = firstPositionInOrBeforeNode(end.deprecatedNode()->previousSibling());
+                start = firstPositionInOrBeforeNode(endContainer->previousSibling());
             if (isEndAndEndOfLastParagraphOnSameNode) {
                 if (m_endOfLastParagraph.offsetInContainerNode() == end.offsetInContainerNode())
-                    m_endOfLastParagraph = lastPositionInNode(end.deprecatedNode()->previousSibling());
+                    m_endOfLastParagraph = lastPositionInOrAfterNode(endContainer->previousSibling());
                 else
-                    m_endOfLastParagraph = Position(end.deprecatedNode(), m_endOfLastParagraph.offsetInContainerNode() - end.offsetInContainerNode(),
-                                                    Position::PositionIsOffsetInAnchor);
+                    m_endOfLastParagraph = Position(endContainer, m_endOfLastParagraph.offsetInContainerNode() - end.offsetInContainerNode());
             }
-            end = lastPositionInNode(end.deprecatedNode()->previousSibling());
+            end = lastPositionInNode(endContainer->previousSibling());
         }
     }
 }
@@ -247,32 +240,34 @@
     if (!style)
         return endOfNextParagraph;
 
-    RefPtr<Node> containerNode = position.containerNode();
-    if (!style->preserveNewline() || !position.offsetInContainerNode()
-        || !isNewLineAtPosition(Position(containerNode.get(), 0, Position::PositionIsOffsetInAnchor)))
+    RefPtr<Text> text = position.containerText();
+    if (!style->preserveNewline() || !position.offsetInContainerNode() || !isNewLineAtPosition(firstPositionInNode(text.get())))
         return endOfNextParagraph;
 
     // \n at the beginning of the text node immediately following the current paragraph is trimmed by moveParagraphWithClones.
     // If endOfNextParagraph was pointing at this same text node, endOfNextParagraph will be shifted by one paragraph.
     // Avoid this by splitting "\n"
-    splitTextNode(static_cast<Text*>(containerNode.get()), 1);
+    splitTextNode(text, 1);
 
-    if (start.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == start.containerNode()) {
+    if (text == start.containerNode() && text->previousSibling() && text->previousSibling()->isTextNode()) {
         ASSERT(start.offsetInContainerNode() < position.offsetInContainerNode());
-        start = Position(containerNode->previousSibling(), start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+        start = Position(static_cast<Text*>(text->previousSibling()), start.offsetInContainerNode());
     }
-    if (end.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == end.containerNode()) {
+    if (text == end.containerNode() && text->previousSibling() && text->previousSibling()->isTextNode()) {
         ASSERT(end.offsetInContainerNode() < position.offsetInContainerNode());
-        end = Position(containerNode->previousSibling(), end.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+        end = Position(static_cast<Text*>(text->previousSibling()), end.offsetInContainerNode());
     }
-    if (m_endOfLastParagraph.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == m_endOfLastParagraph.containerNode()) {
-        if (m_endOfLastParagraph.offsetInContainerNode() < position.offsetInContainerNode())
-            m_endOfLastParagraph = Position(containerNode->previousSibling(), m_endOfLastParagraph.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
-        else
-            m_endOfLastParagraph = Position(containerNode, m_endOfLastParagraph.offsetInContainerNode() - 1, Position::PositionIsOffsetInAnchor);
+    if (text == m_endOfLastParagraph.containerNode()) {
+        if (m_endOfLastParagraph.offsetInContainerNode() < position.offsetInContainerNode()) {
+            // We can only fix endOfLastParagraph if the previous node was still text and hasn't been modified by script.
+            if (text->previousSibling()->isTextNode()
+                && static_cast<unsigned>(m_endOfLastParagraph.offsetInContainerNode()) <= static_cast<Text*>(text->previousSibling())->length())
+                m_endOfLastParagraph = Position(static_cast<Text*>(text->previousSibling()), m_endOfLastParagraph.offsetInContainerNode());
+        } else
+            m_endOfLastParagraph = Position(text.get(), m_endOfLastParagraph.offsetInContainerNode() - 1);
     }
 
-    return Position(containerNode.get(), position.offsetInContainerNode() - 1, Position::PositionIsOffsetInAnchor);
+    return Position(text.get(), position.offsetInContainerNode() - 1);
 }
 
 PassRefPtr<Element> ApplyBlockElementCommand::createBlockElement() const

Modified: trunk/Source/WebCore/editing/ApplyStyleCommand.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/ApplyStyleCommand.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/ApplyStyleCommand.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -1117,60 +1117,65 @@
 
 void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end)
 {
-    ASSERT(start.anchorType() == Position::PositionIsOffsetInAnchor);
+    ASSERT(start.containerNode()->isTextNode());
 
     Position newEnd;
     if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode())
-        newEnd = Position(end.containerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+        newEnd = Position(end.containerText(), end.offsetInContainerNode() - start.offsetInContainerNode());
     else
         newEnd = end;
 
-    Text* text = static_cast<Text*>(start.deprecatedNode());
+    RefPtr<Text> text = start.containerText();
     splitTextNode(text, start.offsetInContainerNode());
-    updateStartEnd(firstPositionInNode(start.deprecatedNode()), newEnd);
+    updateStartEnd(firstPositionInNode(text.get()), newEnd);
 }
 
 void ApplyStyleCommand::splitTextAtEnd(const Position& start, const Position& end)
 {
-    ASSERT(end.anchorType() == Position::PositionIsOffsetInAnchor);
+    ASSERT(end.containerNode()->isTextNode());
 
     bool shouldUpdateStart = start.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode();
     Text* text = static_cast<Text *>(end.deprecatedNode());
     splitTextNode(text, end.offsetInContainerNode());
 
     Node* prevNode = text->previousSibling();
-    ASSERT(prevNode);
-    Position newStart = shouldUpdateStart ? Position(prevNode, start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor) : start;
+    if (!prevNode || !prevNode->isTextNode())
+        return;
+
+    Position newStart = shouldUpdateStart ? Position(static_cast<Text*>(prevNode), start.offsetInContainerNode()) : start;
     updateStartEnd(newStart, lastPositionInNode(prevNode));
 }
 
 void ApplyStyleCommand::splitTextElementAtStart(const Position& start, const Position& end)
 {
-    ASSERT(start.anchorType() == Position::PositionIsOffsetInAnchor);
+    ASSERT(start.containerNode()->isTextNode());
 
     Position newEnd;
-    if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode())
-        newEnd = Position(end.containerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+    if (start.containerNode() == end.containerNode())
+        newEnd = Position(end.containerText(), end.offsetInContainerNode() - start.offsetInContainerNode());
     else
         newEnd = end;
 
-    Text* text = static_cast<Text*>(start.deprecatedNode());
-    splitTextNodeContainingElement(text, start.deprecatedEditingOffset());
-    updateStartEnd(Position(start.deprecatedNode()->parentNode(), start.deprecatedNode()->nodeIndex(), Position::PositionIsOffsetInAnchor), newEnd);
+    splitTextNodeContainingElement(start.containerText(), start.offsetInContainerNode());
+    updateStartEnd(positionBeforeNode(start.containerNode()), newEnd);
 }
 
 void ApplyStyleCommand::splitTextElementAtEnd(const Position& start, const Position& end)
 {
-    ASSERT(end.anchorType() == Position::PositionIsOffsetInAnchor);
+    ASSERT(end.containerNode()->isTextNode());
 
-    bool shouldUpdateStart = start.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode();
-    Text* text = static_cast<Text*>(end.deprecatedNode());
-    splitTextNodeContainingElement(text, end.deprecatedEditingOffset());
+    bool shouldUpdateStart = start.containerNode() == end.containerNode();
+    splitTextNodeContainingElement(end.containerText(), end.offsetInContainerNode());
 
-    Node* prevNode = text->parentNode()->previousSibling()->lastChild();
-    ASSERT(prevNode);
-    Position newStart = shouldUpdateStart ? Position(prevNode, start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor) : start;
-    updateStartEnd(newStart, Position(prevNode->parentNode(), prevNode->nodeIndex() + 1, Position::PositionIsOffsetInAnchor));
+    Node* parentElement = end.containerNode()->parentNode();
+    if (!parentElement || !parentElement->previousSibling())
+        return;
+    Node* firstTextNode = parentElement->previousSibling()->lastChild();
+    if (!firstTextNode || !firstTextNode->isTextNode())
+        return;
+
+    Position newStart = shouldUpdateStart ? Position(static_cast<Text*>(firstTextNode), start.offsetInContainerNode()) : start;
+    updateStartEnd(newStart, positionAfterNode(firstTextNode));
 }
 
 bool ApplyStyleCommand::shouldSplitTextElement(Element* element, EditingStyle* style)
@@ -1480,9 +1485,9 @@
             Text* childText = static_cast<Text *>(child);
             Text* nextText = static_cast<Text *>(next);
             if (start.anchorType() == Position::PositionIsOffsetInAnchor && next == start.containerNode())
-                newStart = Position(childText, childText->length() + start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+                newStart = Position(childText, childText->length() + start.offsetInContainerNode());
             if (end.anchorType() == Position::PositionIsOffsetInAnchor && next == end.containerNode())
-                newEnd = Position(childText, childText->length() + end.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+                newEnd = Position(childText, childText->length() + end.offsetInContainerNode());
             String textToMove = nextText->data();
             insertTextIntoNode(childText, childText->length(), textToMove);
             removeNode(next);

Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -320,7 +320,7 @@
     if (start.containerNode() != end.containerNode() || !start.containerNode()->isTextNode() || isTabSpanTextNode(start.containerNode()))
         return Position();
 
-    RefPtr<Text> textNode = static_cast<Text*>(start.containerNode());
+    RefPtr<Text> textNode = start.containerText();
     replaceTextInNode(textNode, start.offsetInContainerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), text);
 
     return Position(textNode.release(), start.offsetInContainerNode() + text.length());

Modified: trunk/Source/WebCore/editing/Editor.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/Editor.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/Editor.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -266,7 +266,7 @@
         return false;
     
     if (range->collapsed(ec)) {
-        VisiblePosition start(Position(startContainer, range->startOffset(ec), Position::PositionIsOffsetInAnchor), DOWNSTREAM);
+        VisiblePosition start(range->startPosition(), DOWNSTREAM);
         VisiblePosition previous = start.previous();
         // FIXME: We sometimes allow deletions at the start of editable roots, like when the caret is in an empty list item.
         if (previous.isNull() || previous.deepEquivalent().deprecatedNode()->rootEditableElement() != startContainer->rootEditableElement())

Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/FrameSelection.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -1462,45 +1462,23 @@
 
 bool FrameSelection::setSelectedRange(Range* range, EAffinity affinity, bool closeTyping)
 {
-    if (!range)
+    if (!range || !range->startContainer() || !range->endContainer())
         return false;
+    ASSERT(range->startContainer()->document() == range->endContainer()->document());
 
-    ExceptionCode ec = 0;
-    Node* startContainer = range->startContainer(ec);
-    if (ec)
-        return false;
-
-    Node* endContainer = range->endContainer(ec);
-    if (ec)
-        return false;
-    
-    ASSERT(startContainer);
-    ASSERT(endContainer);
-    ASSERT(startContainer->document() == endContainer->document());
-    
     m_frame->document()->updateLayoutIgnorePendingStylesheets();
 
     // Non-collapsed ranges are not allowed to start at the end of a line that is wrapped,
     // they start at the beginning of the next line instead
+    ExceptionCode ec = 0;
     bool collapsed = range->collapsed(ec);
     if (ec)
         return false;
-    
-    int startOffset = range->startOffset(ec);
-    if (ec)
-        return false;
 
-    int endOffset = range->endOffset(ec);
-    if (ec)
-        return false;
-    
     // FIXME: Can we provide extentAffinity?
-    VisiblePosition visibleStart(Position(startContainer, startOffset, Position::PositionIsOffsetInAnchor), collapsed ? affinity : DOWNSTREAM);
-    VisiblePosition visibleEnd(Position(endContainer, endOffset, Position::PositionIsOffsetInAnchor), SEL_DEFAULT_AFFINITY);
-    SetSelectionOptions options = ClearTypingStyle;
-    if (closeTyping)
-        options |= CloseTyping;
-    setSelection(VisibleSelection(visibleStart, visibleEnd), options);
+    VisiblePosition visibleStart(range->startPosition(), collapsed ? affinity : DOWNSTREAM);
+    VisiblePosition visibleEnd(range->endPosition(), SEL_DEFAULT_AFFINITY);
+    setSelection(VisibleSelection(visibleStart, visibleEnd), ClearTypingStyle | (closeTyping ? CloseTyping : 0));
     return true;
 }
 

Modified: trunk/Source/WebCore/editing/InsertTextCommand.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/InsertTextCommand.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/InsertTextCommand.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -157,7 +157,7 @@
         ASSERT(startPosition.containerNode()->isTextNode());
         if (placeholder.isNotNull())
             removePlaceholderAt(placeholder);
-        RefPtr<Text> textNode = static_cast<Text*>(startPosition.containerNode());
+        RefPtr<Text> textNode = startPosition.containerText();
         const unsigned offset = startPosition.offsetInContainerNode();
 
         insertTextIntoNode(textNode, offset, text);

Modified: trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -939,7 +939,7 @@
     // since insertAsListItems already does the right thing.
     if (!m_matchStyle && !enclosingList(insertionPos.containerNode()) && isStyleSpan(fragment.firstChild())) {
         if (insertionPos.containerNode()->isTextNode() && insertionPos.offsetInContainerNode() && !insertionPos.atLastEditingPositionForNode()) {
-            splitTextNodeContainingElement(static_cast<Text*>(insertionPos.containerNode()), insertionPos.offsetInContainerNode());
+            splitTextNodeContainingElement(insertionPos.containerText(), insertionPos.offsetInContainerNode());
             insertionPos = firstPositionInNode(insertionPos.containerNode());
         }
 

Modified: trunk/Source/WebCore/editing/VisiblePosition.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/VisiblePosition.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/VisiblePosition.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -552,8 +552,8 @@
     case Position::PositionIsOffsetInAnchor:
         break;
     }
-    Text* textNode = static_cast<Text*>(pos.containerNode());
-    unsigned offset = pos.anchorType() == Position::PositionIsOffsetInAnchor ? pos.offsetInContainerNode() : 0;
+    unsigned offset = static_cast<unsigned>(pos.offsetInContainerNode());
+    Text* textNode = pos.containerText();
     unsigned length = textNode->length();
     if (offset >= length)
         return 0;
@@ -649,14 +649,12 @@
 
 VisiblePosition startVisiblePosition(const Range *r, EAffinity affinity)
 {
-    int exception = 0;
-    return VisiblePosition(Position(r->startContainer(exception), r->startOffset(exception), Position::PositionIsOffsetInAnchor), affinity);
+    return VisiblePosition(r->startPosition(), affinity);
 }
 
 VisiblePosition endVisiblePosition(const Range *r, EAffinity affinity)
 {
-    int exception = 0;
-    return VisiblePosition(Position(r->endContainer(exception), r->endOffset(exception), Position::PositionIsOffsetInAnchor), affinity);
+    return VisiblePosition(r->endPosition(), affinity);
 }
 
 bool setStart(Range *r, const VisiblePosition &visiblePosition)

Modified: trunk/Source/WebCore/editing/htmlediting.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/htmlediting.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/htmlediting.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -402,8 +402,7 @@
 
 static Node* firstInSpecialElement(const Position& pos)
 {
-    // FIXME: This begins at pos.deprecatedNode(), which doesn't necessarily contain pos (suppose pos was [img, 0]).  See <rdar://problem/5027702>.
-    Node* rootEditableElement = pos.deprecatedNode()->rootEditableElement();
+    Node* rootEditableElement = pos.containerNode()->rootEditableElement();
     for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
         if (isSpecialElement(n)) {
             VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
@@ -418,12 +417,11 @@
 
 static Node* lastInSpecialElement(const Position& pos)
 {
-    // FIXME: This begins at pos.deprecatedNode(), which doesn't necessarily contain pos (suppose pos was [img, 0]).  See <rdar://problem/5027702>.
-    Node* rootEditableElement = pos.deprecatedNode()->rootEditableElement();
+    Node* rootEditableElement = pos.containerNode()->rootEditableElement();
     for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
         if (isSpecialElement(n)) {
             VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
-            VisiblePosition lastInElement = VisiblePosition(Position(n, n->childNodeCount(), Position::PositionIsOffsetInAnchor), DOWNSTREAM);
+            VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfterNode(n), DOWNSTREAM);
             if (isTableElement(n) && vPos == lastInElement.previous())
                 return n;
             if (vPos == lastInElement)

Modified: trunk/Source/WebCore/editing/visible_units.cpp (89951 => 89952)


--- trunk/Source/WebCore/editing/visible_units.cpp	2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/visible_units.cpp	2011-06-28 20:07:31 UTC (rev 89952)
@@ -437,12 +437,12 @@
     Position pos;
     if (endNode->hasTagName(brTag)) {
         pos = positionBeforeNode(endNode);
-    } else if (endBox->isInlineTextBox()) {
-        InlineTextBox *endTextBox = static_cast<InlineTextBox *>(endBox);
+    } else if (endBox->isInlineTextBox() && endNode->isTextNode()) {
+        InlineTextBox* endTextBox = static_cast<InlineTextBox *>(endBox);
         int endOffset = endTextBox->start();
         if (!endTextBox->isLineBreak())
             endOffset += endTextBox->len();
-        pos = Position(endNode, endOffset, Position::PositionIsOffsetInAnchor);
+        pos = Position(static_cast<Text*>(endNode), endOffset);
     } else
         pos = positionAfterNode(endNode);
     
@@ -793,6 +793,7 @@
             break;
 
         if (r->isText() && r->caretMaxRenderedOffset() > 0) {
+            ASSERT(n->isTextNode());
             type = Position::PositionIsOffsetInAnchor;
             if (style->preserveNewline()) {
                 const UChar* chars = toRenderText(r)->characters();
@@ -800,9 +801,10 @@
                 int o = offset;
                 if (n == startNode && o < i)
                     i = max(0, o);
-                while (--i >= 0)
+                while (--i >= 0) {
                     if (chars[i] == '\n')
-                        return VisiblePosition(Position(n, i + 1, Position::PositionIsOffsetInAnchor), DOWNSTREAM);
+                        return VisiblePosition(Position(static_cast<Text*>(n), i + 1), DOWNSTREAM);
+                }
             }
             node = n;
             offset = 0;
@@ -815,9 +817,11 @@
             n = n->traversePreviousNodePostOrder(startBlock);
     }
 
-    if (type == Position::PositionIsOffsetInAnchor)
+    if (type == Position::PositionIsOffsetInAnchor) {
+        ASSERT(type != Position::PositionIsOffsetInAnchor || !offset);
         return VisiblePosition(Position(node, offset, type), DOWNSTREAM);
-    
+    }
+
     return VisiblePosition(Position(node, type), DOWNSTREAM);
 }
 
@@ -867,14 +871,16 @@
 
         // FIXME: We avoid returning a position where the renderer can't accept the caret.
         if (r->isText() && r->caretMaxRenderedOffset() > 0) {
+            ASSERT(n->isTextNode());
             int length = toRenderText(r)->textLength();
             type = Position::PositionIsOffsetInAnchor;
             if (style->preserveNewline()) {
                 const UChar* chars = toRenderText(r)->characters();
                 int o = n == startNode ? offset : 0;
-                for (int i = o; i < length; ++i)
+                for (int i = o; i < length; ++i) {
                     if (chars[i] == '\n')
-                        return VisiblePosition(Position(n, i, Position::PositionIsOffsetInAnchor), DOWNSTREAM);
+                        return VisiblePosition(Position(static_cast<Text*>(n), i), DOWNSTREAM);
+                }
             }
             node = n;
             offset = r->caretMaxOffset();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to