Reviewed by John.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Mar 2005 03:19:17 +0000 (03:19 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Mar 2005 03:19:17 +0000 (03:19 +0000)
<rdar://problem/4053266> Pressing return a few times right after a link makes the new blank lines part of the link

        * khtml/editing/htmlediting.cpp:
(khtml::InsertLineBreakCommand::doApply): Use
positionOutsideContainingSpecialElement in the right two places.
        (khtml::InsertParagraphSeparatorCommand::doApply): Ditto.

- move all these helper functions higher in the file

        * khtml/editing/htmlediting.cpp:
        (khtml::isSpecialElement):
        (khtml::isFirstVisiblePositionInSpecialElement):
        (khtml::positionBeforeNode):
        (khtml::positionBeforeContainingSpecialElement):
        (khtml::maxRangeOffset):
        (khtml::isLastVisiblePositionInSpecialElement):
        (khtml::positionAfterNode):
        (khtml::positionAfterContainingSpecialElement):
        (khtml::positionOutsideContainingSpecialElement):

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

WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/htmlediting.cpp

index 268a4ec335ef5dd0a762957b12cf407742a7c158..b41e40c96f8cec990d70b0f2676492da63094a25 100644 (file)
@@ -1,3 +1,45 @@
+2005-03-15  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by John.
+
+       <rdar://problem/4053266> Pressing return a few times right after a link makes the new blank lines part of the link
+       
+        * khtml/editing/htmlediting.cpp:
+       (khtml::InsertLineBreakCommand::doApply): Use
+       positionOutsideContainingSpecialElement in the right two places.
+        (khtml::InsertParagraphSeparatorCommand::doApply): Ditto.
+
+       - move all these helper functions higher in the file
+       
+        * khtml/editing/htmlediting.cpp:
+        (khtml::isSpecialElement):
+        (khtml::isFirstVisiblePositionInSpecialElement):
+        (khtml::positionBeforeNode):
+        (khtml::positionBeforeContainingSpecialElement):
+        (khtml::maxRangeOffset):
+        (khtml::isLastVisiblePositionInSpecialElement):
+        (khtml::positionAfterNode):
+        (khtml::positionAfterContainingSpecialElement):
+        (khtml::positionOutsideContainingSpecialElement):
+
+2005-03-14  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Ken.
+
+       <rdar://problem/4049925> Pasting right after a link makes pasted content part of the link (without visible style change)
+        
+        * khtml/editing/htmlediting.cpp:
+        (khtml::positionOutsideContainingSpecialElement): made a helper
+       function that computes a position outside the outermost containing
+       special element if the passed in position is right at the start or
+       end of it
+        (khtml::InsertTextCommand::prepareForTextInsertion): use new helper here
+        (khtml::ReplaceSelectionCommand::doApply): use it here too: this is the fix
+        (khtml::positionBeforeNode): made static
+        (khtml::positionBeforeContainingSpecialElement): made static
+        (khtml::positionAfterNode): made static
+        (khtml::positionAfterContainingSpecialElement): made static
+
 2005-03-15  Richard Williamson   <rjw@apple.com>
 
        Fixed <rdar://problem/4053658> Crash getting direction at maps.google.com
@@ -26,6 +68,7 @@
         * khtml/xml/dom_docimpl.cpp:
         (DocumentImpl::detach): Took out the call to removeAllEventListenersFromAllNodes(). If we remove all event listeners here then when KHTMLPart::closeURL() checks for even listeners, it will never have any because they'll already be gone. 
 
+>>>>>>> 1.4064
 2005-03-15  Ken Kocienda  <kocienda@apple.com>
 
         Reviewed by Vicki
index cf19d9af3331311e6f7ddfa59478e4821c746f57..f51728444eb05acf9f4fac489281474b9d71de1c 100644 (file)
@@ -1229,6 +1229,120 @@ void CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary(const Posi
     }
 }
 
+static bool isSpecialElement(NodeImpl *n)
+{
+    if (!n->isHTMLElement())
+        return false;
+
+    if (n->id() == ID_A && n->hasAnchor())
+        return true;
+
+    return false;
+}
+
+static bool isFirstVisiblePositionInSpecialElement(const Position& pos)
+{
+    VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
+
+    for (NodeImpl *n = pos.node(); n; n = n->parentNode()) {
+        if (VisiblePosition(n, 0, DOWNSTREAM) != vPos)
+            return false;
+        if (n->rootEditableElement() == NULL)
+            return false;
+        if (isSpecialElement(n))
+            return true;
+    }
+
+    return false;
+}
+
+static Position positionBeforeNode(NodeImpl *node)
+{
+    return Position(node->parentNode(), node->nodeIndex());
+}
+
+static Position positionBeforeContainingSpecialElement(const Position& pos)
+{
+    ASSERT(isFirstVisiblePositionInSpecialElement(pos));
+
+    VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
+    
+    NodeImpl *outermostSpecialElement = NULL;
+
+    for (NodeImpl *n = pos.node(); n; n = n->parentNode()) {
+        if (VisiblePosition(n, 0, DOWNSTREAM) != vPos)
+            break;
+        if (n->rootEditableElement() == NULL)
+            break;
+        if (isSpecialElement(n))
+            outermostSpecialElement = n;
+    }
+    
+    ASSERT(outermostSpecialElement);
+
+    return positionBeforeNode(outermostSpecialElement);
+}
+
+static bool isLastVisiblePositionInSpecialElement(const Position& pos)
+{
+    // make sure to get a range-compliant version of the position
+    Position rangePos = VisiblePosition(pos, DOWNSTREAM).position();
+
+    VisiblePosition vPos = VisiblePosition(rangePos, DOWNSTREAM);
+
+    for (NodeImpl *n = rangePos.node(); n; n = n->parentNode()) {
+        if (VisiblePosition(n, maxRangeOffset(n), DOWNSTREAM) != vPos)
+            return false;
+        if (n->rootEditableElement() == NULL)
+            return false;
+        if (isSpecialElement(n))
+            return true;
+    }
+
+    return false;
+}
+
+static Position positionAfterNode(NodeImpl *node)
+{
+    return Position(node->parentNode(), node->nodeIndex() + 1);
+}
+
+static Position positionAfterContainingSpecialElement(const Position& pos)
+{
+    ASSERT(isLastVisiblePositionInSpecialElement(pos));
+
+    // make sure to get a range-compliant version of the position
+    Position rangePos = VisiblePosition(pos, DOWNSTREAM).position();
+
+    VisiblePosition vPos = VisiblePosition(rangePos, DOWNSTREAM);
+
+    NodeImpl *outermostSpecialElement = NULL;
+
+    for (NodeImpl *n = rangePos.node(); n; n = n->parentNode()) {
+        if (VisiblePosition(n, maxRangeOffset(n), DOWNSTREAM) != vPos)
+            break;
+        if (n->rootEditableElement() == NULL)
+            break;
+        if (isSpecialElement(n))
+            outermostSpecialElement = n;
+    }
+    
+    ASSERT(outermostSpecialElement);
+
+    return positionAfterNode(outermostSpecialElement);
+}
+
+static Position positionOutsideContainingSpecialElement(const Position &pos)
+{
+    if (isFirstVisiblePositionInSpecialElement(pos)) {
+        return positionBeforeContainingSpecialElement(pos);
+    } else if (isLastVisiblePositionInSpecialElement(pos)) {
+        return positionAfterContainingSpecialElement(pos);
+    }
+
+    return pos;
+}
+
 //==========================================================================================
 // Concrete commands
 //------------------------------------------------------------------------------------------
@@ -3028,6 +3142,9 @@ void InsertLineBreakCommand::doApply()
     NodeImpl *nodeToInsert = breakNode;
     
     Position pos(selection.start().upstream(StayInBlock));
+
+    pos = positionOutsideContainingSpecialElement(pos);
+
     bool atStart = pos.offset() <= pos.node()->caretMinOffset();
     bool atEnd = pos.offset() >= pos.node()->caretMaxOffset();
     bool atEndOfBlock = isLastVisiblePositionInBlock(VisiblePosition(pos, selection.startAffinity()));
@@ -3240,6 +3357,8 @@ void InsertParagraphSeparatorCommand::doApply()
         affinity = endingSelection().startAffinity();
     }
 
+    pos = positionOutsideContainingSpecialElement(pos);
+
     calculateStyleBeforeInsertion(pos);
 
     // Find the start block.
@@ -3282,6 +3401,7 @@ void InsertParagraphSeparatorCommand::doApply()
     if (upstreamInDifferentBlock || isFirstInBlock) {
         LOG(Editing, "insert paragraph separator: first in block case");
         pos = pos.downstream(StayInBlock);
+        pos = positionOutsideContainingSpecialElement(pos);
         NodeImpl *refNode = isFirstInBlock && !startBlockIsRoot ? startBlock : pos.node();
         insertNodeBefore(blockToInsert, refNode);
         appendBlockPlaceholder(blockToInsert);
@@ -3577,109 +3697,6 @@ void InsertTextCommand::doApply()
 {
 }
 
-static bool isSpecialElement(NodeImpl *n)
-{
-    if (!n->isHTMLElement())
-        return false;
-
-    if (n->id() == ID_A && n->hasAnchor())
-        return true;
-
-    return false;
-}
-
-static bool isFirstVisiblePositionInSpecialElement(const Position& pos)
-{
-    VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
-
-    for (NodeImpl *n = pos.node(); n; n = n->parentNode()) {
-        if (VisiblePosition(n, 0, DOWNSTREAM) != vPos)
-            return false;
-        if (n->rootEditableElement() == NULL)
-            return false;
-        if (isSpecialElement(n))
-            return true;
-    }
-
-    return false;
-}
-
-Position positionBeforeNode(NodeImpl *node)
-{
-    return Position(node->parentNode(), node->nodeIndex());
-}
-
-Position positionBeforeContainingSpecialElement(const Position& pos)
-{
-    ASSERT(isFirstVisiblePositionInSpecialElement(pos));
-
-    VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
-    
-    NodeImpl *outermostSpecialElement = NULL;
-
-    for (NodeImpl *n = pos.node(); n; n = n->parentNode()) {
-        if (VisiblePosition(n, 0, DOWNSTREAM) != vPos)
-            break;
-        if (n->rootEditableElement() == NULL)
-            break;
-        if (isSpecialElement(n))
-            outermostSpecialElement = n;
-    }
-    
-    ASSERT(outermostSpecialElement);
-
-    return positionBeforeNode(outermostSpecialElement);
-}
-
-static bool isLastVisiblePositionInSpecialElement(const Position& pos)
-{
-    // make sure to get a range-compliant version of the position
-    Position rangePos = VisiblePosition(pos, DOWNSTREAM).position();
-
-    VisiblePosition vPos = VisiblePosition(rangePos, DOWNSTREAM);
-
-    for (NodeImpl *n = rangePos.node(); n; n = n->parentNode()) {
-        if (VisiblePosition(n, maxRangeOffset(n), DOWNSTREAM) != vPos)
-            return false;
-        if (n->rootEditableElement() == NULL)
-            return false;
-        if (isSpecialElement(n))
-            return true;
-    }
-
-    return false;
-}
-
-Position positionAfterNode(NodeImpl *node)
-{
-    return Position(node->parentNode(), node->nodeIndex() + 1);
-}
-
-Position positionAfterContainingSpecialElement(const Position& pos)
-{
-    ASSERT(isLastVisiblePositionInSpecialElement(pos));
-
-    // make sure to get a range-compliant version of the position
-    Position rangePos = VisiblePosition(pos, DOWNSTREAM).position();
-
-    VisiblePosition vPos = VisiblePosition(rangePos, DOWNSTREAM);
-
-    NodeImpl *outermostSpecialElement = NULL;
-
-    for (NodeImpl *n = rangePos.node(); n; n = n->parentNode()) {
-        if (VisiblePosition(n, maxRangeOffset(n), DOWNSTREAM) != vPos)
-            break;
-        if (n->rootEditableElement() == NULL)
-            break;
-        if (isSpecialElement(n))
-            outermostSpecialElement = n;
-    }
-    
-    ASSERT(outermostSpecialElement);
-
-    return positionAfterNode(outermostSpecialElement);
-}
-
 Position InsertTextCommand::prepareForTextInsertion(bool adjustDownstream)
 {
     // Prepare for text input by looking at the current position.
@@ -3695,11 +3712,7 @@ Position InsertTextCommand::prepareForTextInsertion(bool adjustDownstream)
     
     Selection typingStyleRange;
 
-    if (isFirstVisiblePositionInSpecialElement(pos)) {
-        pos = positionBeforeContainingSpecialElement(pos);
-    } else if (isLastVisiblePositionInSpecialElement(pos)) {
-        pos = positionAfterContainingSpecialElement(pos);
-    }
+    pos = positionOutsideContainingSpecialElement(pos);
 
     if (!pos.node()->isTextNode()) {
         NodeImpl *textNode = document()->createEditingTextNode("");
@@ -4623,6 +4636,7 @@ void ReplaceSelectionCommand::doApply()
     // collect information about the current selection, prior to deleting the selection
     Selection selection = endingSelection();
     ASSERT(selection.isCaretOrRange());
+
     VisiblePosition visibleStart(selection.start(), selection.startAffinity());
     VisiblePosition visibleEnd(selection.end(), selection.endAffinity());
     bool startAtStartOfBlock = isFirstVisiblePositionInBlock(visibleStart);
@@ -4701,6 +4715,8 @@ void ReplaceSelectionCommand::doApply()
     if (startAtStartOfBlock && startBlock->inDocument())
         startPos = Position(startBlock, 0);
 
+    startPos = positionOutsideContainingSpecialElement(startPos);
+
     KHTMLPart *part = document()->part();
     if (m_matchStyle) {
         m_insertionStyle = styleAtPosition(startPos);