DeleteButtonController::enable and disable should be called via a RAII object
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Feb 2013 19:59:41 +0000 (19:59 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Feb 2013 19:59:41 +0000 (19:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109550

Reviewed by Enrica Casucci.

Added DeleteButtonControllerDisableScope, a friend class of DeleteButtonController,
and made DeleteButtonController::enable/disable private.

* dom/ContainerNode.cpp:
* editing/CompositeEditCommand.cpp:
(WebCore::EditCommandComposition::unapply):
(WebCore::EditCommandComposition::reapply):
(WebCore::CompositeEditCommand::apply):
* editing/DeleteButtonController.h:
(WebCore):
(DeleteButtonController):
(DeleteButtonControllerDisableScope):
(WebCore::DeleteButtonControllerDisableScope::DeleteButtonControllerDisableScope):
(WebCore::DeleteButtonControllerDisableScope::~DeleteButtonControllerDisableScope):
* editing/markup.cpp:
(WebCore::createMarkup):
(WebCore::createFragmentFromNodes):

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

Source/WebCore/ChangeLog
Source/WebCore/editing/CompositeEditCommand.cpp
Source/WebCore/editing/DeleteButtonController.h
Source/WebCore/editing/markup.cpp

index 5c44a6c01ebaefe6a03b84a8567239e292eb3b71..5e2d285065a804e562b9e4c2b9d820ab849353f8 100644 (file)
@@ -1,3 +1,28 @@
+2013-02-13  Ryosuke Niwa  <rniwa@webkit.org>
+
+        DeleteButtonController::enable and disable should be called via a RAII object
+        https://bugs.webkit.org/show_bug.cgi?id=109550
+
+        Reviewed by Enrica Casucci.
+
+        Added DeleteButtonControllerDisableScope, a friend class of DeleteButtonController,
+        and made DeleteButtonController::enable/disable private.
+
+        * dom/ContainerNode.cpp:
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::EditCommandComposition::unapply):
+        (WebCore::EditCommandComposition::reapply):
+        (WebCore::CompositeEditCommand::apply):
+        * editing/DeleteButtonController.h:
+        (WebCore):
+        (DeleteButtonController):
+        (DeleteButtonControllerDisableScope):
+        (WebCore::DeleteButtonControllerDisableScope::DeleteButtonControllerDisableScope):
+        (WebCore::DeleteButtonControllerDisableScope::~DeleteButtonControllerDisableScope):
+        * editing/markup.cpp:
+        (WebCore::createMarkup):
+        (WebCore::createFragmentFromNodes):
+
 2013-02-15  Max Vujovic  <mvujovic@adobe.com>
 
         Add code from other branch.
index 2be60541233684fc4b1a6de2430c40618a096b15..d7016a6e387ced0bfefe52e4c1a38a545d8cc28a 100644 (file)
@@ -103,16 +103,16 @@ void EditCommandComposition::unapply()
     // if one is necessary (like for the creation of VisiblePositions).
     m_document->updateLayoutIgnorePendingStylesheets();
 
+    {
 #if ENABLE(DELETION_UI)
-    DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController();
-    deleteButtonController->disable();
-#endif
-    size_t size = m_commands.size();
-    for (size_t i = size; i != 0; --i)
-        m_commands[i - 1]->doUnapply();
-#if ENABLE(DELETION_UI)
-    deleteButtonController->enable();
+        DeleteButtonControllerDisableScope deleteButtonControllerDisableScope(frame.get());
 #endif
+
+        size_t size = m_commands.size();
+        for (size_t i = size; i; --i)
+            m_commands[i - 1]->doUnapply();
+    }
+
     frame->editor()->unappliedEditing(this);
 }
 
@@ -126,17 +126,15 @@ void EditCommandComposition::reapply()
     // Low level operations, like RemoveNodeCommand, don't require a layout because the high level operations that use them perform one
     // if one is necessary (like for the creation of VisiblePositions).
     m_document->updateLayoutIgnorePendingStylesheets();
-    
-#if ENABLE(DELETION_UI)
-    DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController();
-    deleteButtonController->disable();
-#endif
-    size_t size = m_commands.size();
-    for (size_t i = 0; i != size; ++i)
-        m_commands[i]->doReapply();
+
+    {
 #if ENABLE(DELETION_UI)
-    deleteButtonController->enable();
+        DeleteButtonControllerDisableScope deleteButtonControllerDisableScope(frame.get());
 #endif
+        size_t size = m_commands.size();
+        for (size_t i = 0; i != size; ++i)
+            m_commands[i]->doReapply();
+    }
     
     frame->editor()->reappliedEditing(this);
 }
@@ -211,13 +209,9 @@ void CompositeEditCommand::apply()
     {
         EventQueueScope scope;
 #if ENABLE(DELETION_UI)
-        DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController();
-        deleteButtonController->disable();
+        DeleteButtonControllerDisableScope deleteButtonControllerDisableScope(frame);
 #endif
         doApply();
-#if ENABLE(DELETION_UI)
-        deleteButtonController->enable();
-#endif
     }
 
     // Only need to call appliedEditing for top-level commands,
index 68508bfd794edd02d255ac5f0be84b4151d955c9..96c4f0ca060afb2dedb7f82b51ca70b6f26660fc 100644 (file)
 #define DeleteButtonController_h
 
 #include "DeleteButton.h"
+#include "Frame.h"
 
 namespace WebCore {
 
+#if ENABLE(DELETION_UI)
+
 class DeleteButton;
-class Frame;
 class HTMLElement;
 class RenderObject;
 class VisibleSelection;
@@ -50,15 +52,16 @@ public:
     void show(HTMLElement*);
     void hide();
 
-    void enable();
-    void disable();
-
     void deleteTarget();
 
 private:
     static const char* const buttonElementIdentifier;
     static const char* const outlineElementIdentifier;
     static const char* const containerElementIdentifier;
+    
+    void enable();
+    void disable();
+    friend class DeleteButtonControllerDisableScope;
 
     void createDeletionUI();
     bool enabled() const { return (!m_disableStack); }
@@ -73,6 +76,27 @@ private:
     unsigned m_disableStack;
 };
 
+class DeleteButtonControllerDisableScope {
+public:
+    DeleteButtonControllerDisableScope(Frame* frame)
+        : m_frame(frame)
+    {
+        if (frame)
+            frame->editor()->deleteButtonController()->disable();
+    }
+
+    ~DeleteButtonControllerDisableScope()
+    {
+        if (m_frame)
+            m_frame->editor()->deleteButtonController()->enable();
+    }
+
+private:
+    RefPtr<Frame> m_frame;
+};
+
+#endif
+
 } // namespace WebCore
 
 #endif
index ce4c73ce625c70f067a033b7d2fe3de0c64beaf7..93265c7dd93d26355e75755659da04c06ba759b1 100644 (file)
@@ -639,25 +639,23 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
     if (!document)
         return emptyString();
 
+    const Range* updatedRange = range;
+
+#if ENABLE(DELETION_UI)
     // 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)
     Frame* frame = document->frame();
-    if (DeleteButtonController* deleteButton = frame ? frame->editor()->deleteButtonController() : 0) {
-        RefPtr<Range> updatedRange = frame->editor()->avoidIntersectionWithDeleteButtonController(range);
+    DeleteButtonControllerDisableScope deleteButtonControllerDisableScope(frame);
+
+    if (frame) {
+        RefPtr<Range> updatedRangeRef = frame->editor()->avoidIntersectionWithDeleteButtonController(range);
+        updatedRange = updatedRangeRef.get();
         if (!updatedRange)
             return emptyString();
-
-        deleteButton->disable();
-
-        String result = createMarkupInternal(document, range, updatedRange.get(), nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs);
-
-        deleteButton->enable();
-
-        return result;
     }
 #endif
-    return createMarkupInternal(document, range, range, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs);
+
+    return createMarkupInternal(document, range, updatedRange, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs);
 }
 
 PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const String& markup, const String& baseURL, FragmentScriptingPermission scriptingPermission)
@@ -909,9 +907,9 @@ PassRefPtr<DocumentFragment> createFragmentFromNodes(Document *document, const V
 
 #if ENABLE(DELETION_UI)
     // disable the delete button so it's elements are not serialized into the markup
-    if (document->frame())
-        document->frame()->editor()->deleteButtonController()->disable();
+    DeleteButtonControllerDisableScope(document->frame());
 #endif
+
     RefPtr<DocumentFragment> fragment = document->createDocumentFragment();
 
     size_t size = nodes.size();
@@ -921,10 +919,6 @@ PassRefPtr<DocumentFragment> createFragmentFromNodes(Document *document, const V
         fragment->appendChild(element.release(), ASSERT_NO_EXCEPTION);
     }
 
-#if ENABLE(DELETION_UI)
-    if (document->frame())
-        document->frame()->editor()->deleteButtonController()->enable();
-#endif
     return fragment.release();
 }