Separate undo step into insert text and delete text
authorSangYong Park <sy302.park@samsung.com>
Thu, 14 Mar 2013 02:12:49 +0000 (11:12 +0900)
committerSangYong Park <sy302.park@samsung.com>
Tue, 26 Mar 2013 08:24:48 +0000 (17:24 +0900)
[Title] Separate undo step into insert text and delete text
[Issue#] P130301-2220
[Problem]
[Cause]
[Solution]

Change-Id: I293da579f96503d23e9cffa3ff0a0e597e531e85

Source/WebCore/editing/TypingCommand.cpp [changed mode: 0644->0755]
Source/WebCore/editing/TypingCommand.h [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 1c0aa78..88f9e81
 #include "htmlediting.h"
 #include "visible_units.h"
 
+#if ENABLE(TIZEN_ISF_PORT)
+#include "CharacterData.h"
+#endif
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -87,6 +91,9 @@ TypingCommand::TypingCommand(Document *document, ETypingCommand commandType, con
     , m_openedByBackwardDelete(false)
     , m_shouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator)
     , m_shouldPreventSpellChecking(options & PreventSpellChecking)
+#if ENABLE(TIZEN_ISF_PORT)
+    , m_isInsertText(false)
+#endif
 {
     updatePreservesTypingStyle(m_commandType);
 }
@@ -114,7 +121,12 @@ void TypingCommand::deleteKeyPressed(Document *document, Options options, TextGr
 {
     ASSERT(document);
     if (granularity == CharacterGranularity) {
+#if ENABLE(TIZEN_ISF_PORT)
+        RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame());
+        if (lastTypingCommand && !lastTypingCommand->m_isInsertText) {
+#else
         if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+#endif
             updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), document->frame());
             lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
             lastTypingCommand->deleteKeyPressed(granularity, options & KillRing);
@@ -166,6 +178,31 @@ void TypingCommand::insertText(Document* document, const String& text, Options o
     insertText(document, text, frame->selection()->selection(), options, composition);
 }
 
+#if ENABLE(TIZEN_ISF_PORT)
+unsigned selectionCount(const VisibleSelection& selection)
+{
+    if (!selection.isRange())
+        return 0;
+
+    RefPtr<Range> range = selection.firstRange();
+    Node* startContainer = range->startContainer();
+    Node* endContainer = range->endContainer();
+    Node* pastLast = range->pastLastNode();
+    unsigned count = 0;
+
+    for (Node* node = range->firstNode(); node != pastLast; node = node->traverseNextNode()) {
+        if (node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE) {
+            int length = static_cast<CharacterData*>(node)->length();
+            int start = (node == startContainer) ? std::min(std::max(0, range->startOffset()), length) : 0;
+            int end = (node == endContainer) ? std::min(std::max(start, range->endOffset()), length) : length;
+            count += static_cast<unsigned>(end - start);
+        }
+    }
+
+    return count;
+}
+#endif
+
 // FIXME: We shouldn't need to take selectionForInsertion. It should be identical to FrameSelection's current selection.
 void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, Options options, TextCompositionType compositionType)
 {
@@ -181,7 +218,13 @@ void TypingCommand::insertText(Document* document, const String& text, const Vis
     // Set the starting and ending selection appropriately if we are using a selection
     // that is different from the current selection.  In the future, we should change EditCommand
     // to deal with custom selections in a general way that can be used by all of the commands.
+#if ENABLE(TIZEN_ISF_PORT)
+    RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame.get());
+    unsigned deleteCount = selectionCount(selectionForInsertion);
+    if (lastTypingCommand && (lastTypingCommand->m_isInsertText ? text.length() >= deleteCount : text.length() <= deleteCount)) {
+#else
     if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame.get())) {
+#endif
         if (lastTypingCommand->endingSelection() != selectionForInsertion) {
             lastTypingCommand->setStartingSelection(selectionForInsertion);
             lastTypingCommand->setEndingSelection(selectionForInsertion);
@@ -196,6 +239,9 @@ void TypingCommand::insertText(Document* document, const String& text, const Vis
 
     RefPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, options, compositionType);
     applyTextInsertionCommand(frame.get(), cmd, selectionForInsertion, currentSelection);
+#if ENABLE(TIZEN_ISF_PORT)
+    cmd->m_isInsertText = (text.length() >= deleteCount);
+#endif
 }
 
 void TypingCommand::insertLineBreak(Document *document, Options options)
old mode 100644 (file)
new mode 100755 (executable)
index 950eec8..7c5c567
@@ -134,6 +134,10 @@ private:
 
     bool m_shouldRetainAutocorrectionIndicator;
     bool m_shouldPreventSpellChecking;
+
+#if ENABLE(TIZEN_ISF_PORT)
+    bool m_isInsertText;
+#endif
 };
 
 } // namespace WebCore