Turn avoidIntersectionWithNode into Editor member functions to encapsulate delete...
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Feb 2013 02:39:22 +0000 (02:39 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Feb 2013 02:39:22 +0000 (02:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109549

Reviewed by Tony Chang.

Renamed avoidIntersectionWithNode to Editor::avoidIntersectionWithDeleteButtonController and added trivial
implementations when delete button controllers are disabled (ENABLE_DELETION_UI is 0).

* editing/DeleteButtonController.cpp:
* editing/EditCommand.cpp:
(WebCore::EditCommand::EditCommand):
* editing/Editor.cpp:
(WebCore::Editor::avoidIntersectionWithDeleteButtonController): Moved from htmlediting.cpp and renamed.
The version that takes VisibleSelection has been updated to use updatePositionForNodeRemoval to share
mode code with that function.
(WebCore::Editor::rangeForPoint):
* editing/Editor.h:
(WebCore::Editor::avoidIntersectionWithDeleteButtonController): Added; trivial implementations.
* editing/htmlediting.cpp:
* editing/htmlediting.h:
* editing/markup.cpp:
(WebCore::createMarkupInternal): Extracted from createMarkup.
(WebCore::createMarkup):

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

Source/WebCore/ChangeLog
Source/WebCore/editing/EditCommand.cpp
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/Editor.h
Source/WebCore/editing/htmlediting.cpp
Source/WebCore/editing/htmlediting.h
Source/WebCore/editing/markup.cpp

index b60c0ac028629c1f77f6fd70bec6d63993931eb5..23b61832870987a75e0769b3c343eff808a48477 100644 (file)
@@ -1,3 +1,29 @@
+2013-02-12  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Turn avoidIntersectionWithNode into Editor member functions to encapsulate delete button controller
+        https://bugs.webkit.org/show_bug.cgi?id=109549
+
+        Reviewed by Tony Chang.
+
+        Renamed avoidIntersectionWithNode to Editor::avoidIntersectionWithDeleteButtonController and added trivial
+        implementations when delete button controllers are disabled (ENABLE_DELETION_UI is 0).
+
+        * editing/DeleteButtonController.cpp:
+        * editing/EditCommand.cpp:
+        (WebCore::EditCommand::EditCommand):
+        * editing/Editor.cpp:
+        (WebCore::Editor::avoidIntersectionWithDeleteButtonController): Moved from htmlediting.cpp and renamed.
+        The version that takes VisibleSelection has been updated to use updatePositionForNodeRemoval to share
+        mode code with that function.
+        (WebCore::Editor::rangeForPoint):
+        * editing/Editor.h:
+        (WebCore::Editor::avoidIntersectionWithDeleteButtonController): Added; trivial implementations.
+        * editing/htmlediting.cpp:
+        * editing/htmlediting.h:
+        * editing/markup.cpp:
+        (WebCore::createMarkupInternal): Extracted from createMarkup.
+        (WebCore::createMarkup):
+
 2013-02-12  Joseph Pecoraro  <pecoraro@apple.com>
 
         [iOS] Enable PAGE_VISIBILITY_API
index 527580e74ed78901e3e5a26052fce797df5c78d9..be5ef1566fec7c2afce26d07a6710f367128b72d 100644 (file)
@@ -27,9 +27,6 @@
 #include "EditCommand.h"
 
 #include "CompositeEditCommand.h"
-#if ENABLE(DELETION_UI)
-#include "DeleteButtonController.h"
-#endif
 #include "Document.h"
 #include "Editor.h"
 #include "Element.h"
@@ -48,11 +45,7 @@ EditCommand::EditCommand(Document* document)
 {
     ASSERT(m_document);
     ASSERT(m_document->frame());
-#if ENABLE(DELETION_UI)
-    setStartingSelection(avoidIntersectionWithNode(m_document->frame()->selection()->selection(), m_document->frame()->editor()->deleteButtonController()->containerElement()));
-#else
-    setStartingSelection(m_document->frame()->selection()->selection());
-#endif
+    setStartingSelection(m_document->frame()->editor()->avoidIntersectionWithDeleteButtonController(m_document->frame()->selection()->selection()));
     setEndingSelection(m_startingSelection);
 }
 
index 91f56c74fd62976515f77b2f40a32954ebf9740e..763de7155994a9b2c60ef270b82adcccbfec587d 100644 (file)
@@ -104,6 +104,65 @@ using namespace HTMLNames;
 using namespace WTF;
 using namespace Unicode;
 
+#if ENABLE(DELETION_UI)
+PassRefPtr<Range> Editor::avoidIntersectionWithDeleteButtonController(const Range* range) const
+{
+    DeleteButtonController* controller = deleteButtonController();
+    if (!range || !controller)
+        return 0;
+
+    Document* document = range->ownerDocument();
+
+    Node* startContainer = range->startContainer();
+    int startOffset = range->startOffset();
+    Node* endContainer = range->endContainer();
+    int endOffset = range->endOffset();
+
+    if (!startContainer)
+        return 0;
+
+    ASSERT(endContainer);
+
+    Element* element = controller->containerElement();
+    if (startContainer == element || startContainer->isDescendantOf(element)) {
+        ASSERT(element->parentNode());
+        startContainer = element->parentNode();
+        startOffset = element->nodeIndex();
+    }
+    if (endContainer == element || endContainer->isDescendantOf(element)) {
+        ASSERT(element->parentNode());
+        endContainer = element->parentNode();
+        endOffset = element->nodeIndex();
+    }
+
+    return Range::create(document, startContainer, startOffset, endContainer, endOffset);
+}
+
+VisibleSelection Editor::avoidIntersectionWithDeleteButtonController(const VisibleSelection& selection) const
+{
+    DeleteButtonController* controller = deleteButtonController();
+    if (selection.isNone() || !controller)
+        return selection;
+
+    Element* element = controller->containerElement();
+    if (!element)
+        return selection;
+    VisibleSelection updatedSelection = selection;
+
+    Position updatedBase = selection.base();
+    updatePositionForNodeRemoval(updatedBase, element);
+    if (updatedBase != selection.base())
+        updatedSelection.setBase(updatedBase);
+
+    Position updatedExtent = selection.base();
+    updatePositionForNodeRemoval(updatedExtent, element);
+    if (updatedExtent != selection.extent())
+        updatedSelection.setExtent(updatedExtent);
+
+    return updatedSelection;
+}
+#endif
+
 // When an event handler has moved the selection outside of a text control
 // we should use the target control's selection for this editing operation.
 VisibleSelection Editor::selectionForCommand(Event* event)
@@ -2387,11 +2446,8 @@ PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
         return 0;
     IntPoint framePoint = frameView->windowToContents(windowPoint);
     VisibleSelection selection(frame->visiblePositionForPoint(framePoint));
-#if ENABLE(DELETION_UI)
-    return avoidIntersectionWithNode(selection.toNormalizedRange().get(), m_deleteButtonController->containerElement());
-#else
-    return selection.toNormalizedRange();
-#endif
+
+    return avoidIntersectionWithDeleteButtonController(selection.toNormalizedRange().get());
 }
 
 void Editor::revealSelectionAfterEditingOperation(const ScrollAlignment& alignment, RevealExtentOption revealExtentOption)
index 4cda99a741979581d54690bda55a8a6833478f43..1abe3c14ae8ac87639cac2e983e04f14c6ebfea6 100644 (file)
@@ -96,9 +96,15 @@ public:
     TextCheckerClient* textChecker() const;
 
     Frame* frame() const { return m_frame; }
+
 #if ENABLE(DELETION_UI)
     DeleteButtonController* deleteButtonController() const { return m_deleteButtonController.get(); }
+    PassRefPtr<Range> avoidIntersectionWithDeleteButtonController(const Range*) const;
+    VisibleSelection avoidIntersectionWithDeleteButtonController(const VisibleSelection&) const;
+#else
+    VisibleSelection avoidIntersectionWithDeleteButtonController(const VisibleSelection& selection) const { return selection; }
 #endif
+
     CompositeEditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
 
     void handleKeyboardEvent(KeyboardEvent*);
index 1bf3936f9bfdc697d714f8949edf1d6794dddf21..6538268aa7cda9ab379126ec87181742ee51c9be 100644 (file)
@@ -1182,63 +1182,6 @@ bool isNonTableCellHTMLBlockElement(const Node* node)
         || node->hasTagName(h4Tag)
         || node->hasTagName(h5Tag);
 }
-
-#if ENABLE(DELETION_UI)
-PassRefPtr<Range> avoidIntersectionWithNode(const Range* range, Node* node)
-{
-    if (!range)
-        return 0;
-
-    Document* document = range->ownerDocument();
-
-    Node* startContainer = range->startContainer();
-    int startOffset = range->startOffset();
-    Node* endContainer = range->endContainer();
-    int endOffset = range->endOffset();
-
-    if (!startContainer)
-        return 0;
-
-    ASSERT(endContainer);
-
-    if (startContainer == node || startContainer->isDescendantOf(node)) {
-        ASSERT(node->parentNode());
-        startContainer = node->parentNode();
-        startOffset = node->nodeIndex();
-    }
-    if (endContainer == node || endContainer->isDescendantOf(node)) {
-        ASSERT(node->parentNode());
-        endContainer = node->parentNode();
-        endOffset = node->nodeIndex();
-    }
-
-    return Range::create(document, startContainer, startOffset, endContainer, endOffset);
-}
-
-VisibleSelection avoidIntersectionWithNode(const VisibleSelection& selection, Node* node)
-{
-    if (selection.isNone())
-        return VisibleSelection(selection);
-
-    VisibleSelection updatedSelection(selection);
-    Node* base = selection.base().deprecatedNode();
-    Node* extent = selection.extent().deprecatedNode();
-    ASSERT(base);
-    ASSERT(extent);
-
-    if (base == node || base->isDescendantOf(node)) {
-        ASSERT(node->parentNode());
-        updatedSelection.setBase(positionInParentBeforeNode(node));
-    }
-
-    if (extent == node || extent->isDescendantOf(node)) {
-        ASSERT(node->parentNode());
-        updatedSelection.setExtent(positionInParentBeforeNode(node));
-    }
-
-    return updatedSelection;
-}
-#endif
     
 Position adjustedSelectionStartForStyleComputation(const VisibleSelection& selection)
 {
index ca1f0f72bbe77d4844fc482b83a8198a54d383a6..88c6bb00239aeb6882c4ed24f0c288ab53f8bbc3 100644 (file)
@@ -192,9 +192,6 @@ VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope);
 
 PassRefPtr<Range> createRange(PassRefPtr<Document>, const VisiblePosition& start, const VisiblePosition& end, ExceptionCode&);
 PassRefPtr<Range> extendRangeToWrappingNodes(PassRefPtr<Range> rangeToExtend, const Range* maximumRange, const Node* rootNode);
-#if ENABLE(DELETION_UI)
-PassRefPtr<Range> avoidIntersectionWithNode(const Range*, Node*);
-#endif
 
 // -------------------------------------------------------------------------
 // HTMLElement
@@ -237,9 +234,6 @@ bool canMergeLists(Element* firstList, Element* secondList);
 // -------------------------------------------------------------------------
 
 // Functions returning VisibleSelection
-#if ENABLE(DELETION_UI)
-VisibleSelection avoidIntersectionWithNode(const VisibleSelection&, Node*);
-#endif
 VisibleSelection selectionForParagraphIteration(const VisibleSelection&);
 
 Position adjustedSelectionStartForStyleComputation(const VisibleSelection&);
index 3e142965397f330d4701cb72ad18cd49fa5d4ef2..ce4c73ce625c70f067a033b7d2fe3de0c64beaf7 100644 (file)
@@ -544,38 +544,20 @@ static Node* highestAncestorToWrapMarkup(const Range* range, EAnnotateForInterch
 
 // FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange? 
 // FIXME: At least, annotation and style info should probably not be included in range.markupString()
-String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
+static String createMarkupInternal(Document* document, const Range* range, const Range* updatedRange, Vector<Node*>* nodes,
+    EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
 {
+    ASSERT(document);
+    ASSERT(range);
+    ASSERT(updatedRange);
     DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, (ASCIILiteral("<br class=\"" AppleInterchangeNewline "\">")));
 
-    if (!range)
-        return "";
-
-    Document* document = range->ownerDocument();
-    if (!document)
-        return "";
-
-    // Disable the delete button so it's elements are not serialized into the markup,
-    // but make sure neither endpoint is inside the delete user interface.
-    RefPtr<Range> updatedRange;
-#if ENABLE(DELETION_UI)
-    Frame* frame = document->frame();
-    DeleteButtonController* deleteButton = frame ? frame->editor()->deleteButtonController() : 0;
-    updatedRange = avoidIntersectionWithNode(range, deleteButton ? deleteButton->containerElement() : 0);
-    if (!updatedRange)
-        return "";
-    if (deleteButton)
-        deleteButton->disable();
-#else
-    updatedRange = Range::create(range->ownerDocument(), range->startContainer(), range->startOffset(), range->endContainer(), range->endOffset());
-#endif
-
     bool collapsed = updatedRange->collapsed(ASSERT_NO_EXCEPTION);
     if (collapsed)
-        return "";
+        return emptyString();
     Node* commonAncestor = updatedRange->commonAncestorContainer(ASSERT_NO_EXCEPTION);
     if (!commonAncestor)
-        return "";
+        return emptyString();
 
     document->updateLayoutIgnorePendingStylesheets();
 
@@ -584,32 +566,22 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
     // FIXME: Do this for all fully selected blocks, not just the body.
     if (body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange().get(), range))
         fullySelectedRoot = body;
-    Node* specialCommonAncestor = highestAncestorToWrapMarkup(updatedRange.get(), shouldAnnotate);
-    StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, updatedRange.get(), specialCommonAncestor);
+    Node* specialCommonAncestor = highestAncestorToWrapMarkup(updatedRange, shouldAnnotate);
+    StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, updatedRange, specialCommonAncestor);
     Node* pastEnd = updatedRange->pastLastNode();
 
     Node* startNode = updatedRange->firstNode();
     VisiblePosition visibleStart(updatedRange->startPosition(), VP_DEFAULT_AFFINITY);
     VisiblePosition visibleEnd(updatedRange->endPosition(), VP_DEFAULT_AFFINITY);
     if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleStart)) {
-        if (visibleStart == visibleEnd.previous()) {
-#if ENABLE(DELETION_UI)
-            if (deleteButton)
-                deleteButton->enable();
-#endif
+        if (visibleStart == visibleEnd.previous())
             return interchangeNewlineString;
-        }
 
         accumulator.appendString(interchangeNewlineString);
         startNode = visibleStart.next().deepEquivalent().deprecatedNode();
 
-        if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, ASSERT_NO_EXCEPTION) >= 0) {
-#if ENABLE(DELETION_UI)
-            if (deleteButton)
-                deleteButton->enable();
-#endif
+        if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, ASSERT_NO_EXCEPTION) >= 0)
             return interchangeNewlineString;
-        }
     }
 
     Node* lastClosed = accumulator.serializeNodes(startNode, pastEnd);
@@ -655,11 +627,37 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
     if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleEnd.previous()))
         accumulator.appendString(interchangeNewlineString);
 
+    return accumulator.takeResults();
+}
+
+String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
+{
+    if (!range)
+        return emptyString();
+
+    Document* document = range->ownerDocument();
+    if (!document)
+        return emptyString();
+
+    // Disable the delete button so it's elements are not serialized into the markup,
+    // but make sure neither endpoint is inside the delete user interface.
 #if ENABLE(DELETION_UI)
-    if (deleteButton)
+    Frame* frame = document->frame();
+    if (DeleteButtonController* deleteButton = frame ? frame->editor()->deleteButtonController() : 0) {
+        RefPtr<Range> updatedRange = frame->editor()->avoidIntersectionWithDeleteButtonController(range);
+        if (!updatedRange)
+            return emptyString();
+
+        deleteButton->disable();
+
+        String result = createMarkupInternal(document, range, updatedRange.get(), nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs);
+
         deleteButton->enable();
+
+        return result;
+    }
 #endif
-    return accumulator.takeResults();
+    return createMarkupInternal(document, range, range, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs);
 }
 
 PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const String& markup, const String& baseURL, FragmentScriptingPermission scriptingPermission)