[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

morrita at google.com morrita at google.com
Wed Dec 22 11:49:49 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit ba223ed4f78179e5fd57959dad1e64150d3e746b
Author: morrita at google.com <morrita at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Aug 9 05:26:47 2010 +0000

    2010-08-04  MORITA Hajime  <morrita at google.com>
    
            Reviewed by Tony Chang.
    
            Pasting should fire textInput event.
            https://bugs.webkit.org/show_bug.cgi?id=42958
    
            * editing/pasteboard/paste-text-events-expected.txt: Added.
            * editing/pasteboard/paste-text-events.html: Added.
            * editing/pasteboard/script-tests/paste-text-events.js: Added.
    2010-08-05  MORITA Hajime  <morrita at google.com>
    
            Reviewed by Tony Chang.
    
            Pasting should fire textInput event.
            https://bugs.webkit.org/show_bug.cgi?id=42958
    
            - Extended TextEvents to hold paste-specific parameters
            - Did fire TextEvents at where we originally did immediate pastes.
            - Factored out TextEvent handling from EventHandler::defaultTextInputEventHandler()
              to Editor::handleTextEvent() because it's solely done by the editor.
            - move actual pasting logic to Editor::handleTextEvent()
    
            Test: editing/pasteboard/paste-text-events.html
    
            * WebCore.exp.in:
            * dom/TextEvent.cpp:
            (WebCore::TextEvent::create):
            (WebCore::TextEvent::createForPlainTextPaste):
            (WebCore::TextEvent::createForFragmentPaste):
            (WebCore::TextEvent::TextEvent):
            * dom/TextEvent.h:
            (WebCore::TextEvent::isPaste):
            (WebCore::TextEvent::shouldSmartReplace):
            (WebCore::TextEvent::shouldMatchStyle):
            (WebCore::TextEvent::pastingFragment):
            * editing/Editor.cpp:
            (WebCore::Editor::handleTextEvent):
            (WebCore::Editor::pasteAsPlainText):
            (WebCore::Editor::pasteAsFragment):
            (WebCore::Editor::pasteAsPlainTextWithPasteboard):
            (WebCore::Editor::pasteWithPasteboard):
            (WebCore::Editor::dispatchCPPEvent):
            (WebCore::Editor::findEventTargetFromSelection):
            * editing/Editor.h:
            * page/EventHandler.cpp:
            (WebCore::EventHandler::defaultTextInputEventHandler):
    2010-08-04  MORITA Hajime  <morrita at google.com>
    
            Reviewed by Tony Chang.
    
            Pasting should fire textInput event.
            https://bugs.webkit.org/show_bug.cgi?id=42958
    
            On paste, invoke Editor instead of direct command invocation,
            which allows dispatching events before actual paste.
    
            * WebView/WebHTMLView.mm:
            (-[WebHTMLView _pasteWithPasteboard:allowPlainText:]):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64963 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 1431668..bdab453 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2010-08-04  MORITA Hajime  <morrita at google.com>
+
+        Reviewed by Tony Chang.
+
+        Pasting should fire textInput event.
+        https://bugs.webkit.org/show_bug.cgi?id=42958
+
+        * editing/pasteboard/paste-text-events-expected.txt: Added.
+        * editing/pasteboard/paste-text-events.html: Added.
+        * editing/pasteboard/script-tests/paste-text-events.js: Added.
+
 2010-08-05  MORITA Hajime  <morrita at google.com>
 
         Reviewed by Tony Chang.
diff --git a/LayoutTests/editing/pasteboard/paste-text-events-expected.txt b/LayoutTests/editing/pasteboard/paste-text-events-expected.txt
new file mode 100644
index 0000000..c81e8e2
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/paste-text-events-expected.txt
@@ -0,0 +1,35 @@
+This tests that Paste commands fires textInput events.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS event.data is 'PlainHello'
+PASS testTargetTextarea.value is 'PlainHello'
+PASS event.data is 'PlainHello'
+PASS testTargetInput.value is 'PlainHello'
+PASS event.data is ''
+PASS testTargetEditable.innerHTML is 'PlainHello'
+PASS event.data is 'RichHello'
+PASS testTargetTextarea.value is 'RichHello'
+PASS event.data is 'RichHello'
+PASS testTargetInput.value is 'RichHello'
+PASS event.data is ''
+PASS testTargetEditable.innerHTML is '<b>Rich</b>Hello'
+PASS textInputCount is proceedingTestCases.length
+PASS event.data is 'PlainHello'
+PASS testTargetTextarea.value is ''
+PASS event.data is 'PlainHello'
+PASS testTargetInput.value is ''
+PASS event.data is ''
+PASS testTargetEditable.innerHTML is ''
+PASS event.data is 'RichHello'
+PASS testTargetTextarea.value is ''
+PASS event.data is 'RichHello'
+PASS testTargetInput.value is ''
+PASS event.data is ''
+PASS testTargetEditable.innerHTML is ''
+PASS textInputCount is cancelingTestCases.length
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/pasteboard/paste-text-events.html b/LayoutTests/editing/pasteboard/paste-text-events.html
new file mode 100644
index 0000000..93a50ad
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/paste-text-events.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/paste-text-events.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/script-tests/paste-text-events.js b/LayoutTests/editing/pasteboard/script-tests/paste-text-events.js
new file mode 100644
index 0000000..e733fa3
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/script-tests/paste-text-events.js
@@ -0,0 +1,145 @@
+description('This tests that Paste commands fires textInput events.');
+
+function toStringLiteral(str)
+{
+   return "'" + str + "'";
+}
+
+var willCancelTextInput = false;
+var textInputCount = 0;
+var expectedTextEventData = "";
+
+function pastingTextInputHandler(evt)
+{
+    shouldBe("event.data", toStringLiteral(expectedTextEventData));
+    textInputCount++;
+    if (willCancelTextInput)
+        evt.preventDefault();
+}
+
+var testSourceRoot = document.createElement("div");
+document.body.appendChild(testSourceRoot);
+
+var testTargetRoot = document.createElement("div");
+testTargetRoot.innerHTML += "<input type='text' id='targetInput' value=''>";
+testTargetRoot.innerHTML += "<div id='targetEditable' contentEditable>";
+testTargetRoot.innerHTML += "<textarea id='targetTextarea' ></textarea>";
+document.body.appendChild(testTargetRoot);
+
+testTargetEditable = document.getElementById("targetEditable");
+testTargetEditable.addEventListener("textInput", pastingTextInputHandler);
+testTargetInput = document.getElementById("targetInput");
+testTargetInput.addEventListener("textInput", pastingTextInputHandler);
+testTargetTextarea = document.getElementById("targetTextarea");
+testTargetTextarea.addEventListener("textInput", pastingTextInputHandler);
+
+var selection = window.getSelection();
+
+function copyPlainText()
+{
+    testSourceRoot.innerHTML = "<input type='text' value='PlainHello' id='src' />";
+    var input = document.getElementById("src");
+    input.focus();
+
+    selection.modify("extend", "forward", "line");
+    document.execCommand("Copy");
+}
+
+function copyRichText()
+{
+    testSourceRoot.innerHTML = "<div id='src' contentEditable><b>Rich</b>Hello</div>";
+    var editable = document.getElementById("src");
+    selection.setBaseAndExtent(editable, 0, editable, 0);
+    selection.modify("extend", "forward", "line");
+    document.execCommand("Copy");
+}
+
+function pasteToTargetEditable()
+{
+    var editable = testTargetEditable;
+    editable.innerHTML = "";
+    selection.setBaseAndExtent(editable, 0, editable, 0);
+    document.execCommand("Paste");
+
+}
+
+function targetEditableShouldHave(value)
+{
+    shouldBe("testTargetEditable.innerHTML", toStringLiteral(value));
+}
+
+function pasteToTargetInput()
+{
+    var input = testTargetInput;
+    input.value = "";
+    input.focus();
+    document.execCommand("Paste");
+}
+
+function targetInputShouldHave(value)
+{
+    shouldBe("testTargetInput.value", toStringLiteral(value));
+}
+
+function pasteToTargetTextarea()
+{
+    var textarea = testTargetTextarea;
+    textarea.value = "";
+    textarea.focus();
+    document.execCommand("Paste");
+}
+
+function targetTextareaShouldHave(value)
+{
+    shouldBe("testTargetTextarea.value", toStringLiteral(value));
+}
+
+var proceedingTestCases = [
+    [copyPlainText, pasteToTargetTextarea, targetTextareaShouldHave, "PlainHello", "PlainHello"],
+    [copyPlainText, pasteToTargetInput, targetInputShouldHave, "PlainHello", "PlainHello"],
+    [copyPlainText, pasteToTargetEditable, targetEditableShouldHave, "PlainHello", ""],
+    [copyRichText, pasteToTargetTextarea, targetTextareaShouldHave, "RichHello", "RichHello"],
+    [copyRichText, pasteToTargetInput, targetInputShouldHave, "RichHello", "RichHello"],
+    [copyRichText, pasteToTargetEditable, targetEditableShouldHave, "<b>Rich</b>Hello", ""],
+];
+
+var cancelingTestCases = [
+    [copyPlainText, pasteToTargetTextarea, targetTextareaShouldHave, "", "PlainHello"],
+    [copyPlainText, pasteToTargetInput, targetInputShouldHave, "", "PlainHello"],
+    [copyPlainText, pasteToTargetEditable, targetEditableShouldHave, "", ""],
+    [copyRichText, pasteToTargetTextarea, targetTextareaShouldHave, "", "RichHello"],
+    [copyRichText, pasteToTargetInput, targetInputShouldHave, "", "RichHello"],
+    [copyRichText, pasteToTargetEditable, targetEditableShouldHave, "", ""],
+];
+
+function runSingleTest(caseData)
+{
+    var copy = caseData[0];
+    var paste = caseData[1];
+    var verifyFunction = caseData[2];
+    var verifyParameter = caseData[3];
+
+    expectedTextEventData = caseData[4];
+
+    copy();
+    paste();
+    verifyFunction(verifyParameter);
+}
+
+textInputCount = 0;
+willCancelTextInput = false;
+for (var i = 0; i < proceedingTestCases.length; ++i)
+    runSingleTest(proceedingTestCases[i]);
+shouldBe("textInputCount", "proceedingTestCases.length");
+
+textInputCount = 0;
+willCancelTextInput = true;
+for (var i = 0; i < cancelingTestCases.length; ++i)
+    runSingleTest(cancelingTestCases[i]);
+shouldBe("textInputCount", "cancelingTestCases.length");
+
+// Hides dataset to make dump clean.
+testTargetRoot.style.display = "none";
+testSourceRoot.style.display = "none";
+
+var successfullyParsed = true;
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 704bdc8..d08711c 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,41 @@
+2010-08-05  MORITA Hajime  <morrita at google.com>
+
+        Reviewed by Tony Chang.
+
+        Pasting should fire textInput event.
+        https://bugs.webkit.org/show_bug.cgi?id=42958
+
+        - Extended TextEvents to hold paste-specific parameters
+        - Did fire TextEvents at where we originally did immediate pastes.
+        - Factored out TextEvent handling from EventHandler::defaultTextInputEventHandler()
+          to Editor::handleTextEvent() because it's solely done by the editor.
+        - move actual pasting logic to Editor::handleTextEvent() 
+
+        Test: editing/pasteboard/paste-text-events.html
+
+        * WebCore.exp.in:
+        * dom/TextEvent.cpp:
+        (WebCore::TextEvent::create):
+        (WebCore::TextEvent::createForPlainTextPaste):
+        (WebCore::TextEvent::createForFragmentPaste):
+        (WebCore::TextEvent::TextEvent):
+        * dom/TextEvent.h:
+        (WebCore::TextEvent::isPaste):
+        (WebCore::TextEvent::shouldSmartReplace):
+        (WebCore::TextEvent::shouldMatchStyle):
+        (WebCore::TextEvent::pastingFragment):
+        * editing/Editor.cpp:
+        (WebCore::Editor::handleTextEvent):
+        (WebCore::Editor::pasteAsPlainText):
+        (WebCore::Editor::pasteAsFragment):
+        (WebCore::Editor::pasteAsPlainTextWithPasteboard):
+        (WebCore::Editor::pasteWithPasteboard):
+        (WebCore::Editor::dispatchCPPEvent):
+        (WebCore::Editor::findEventTargetFromSelection):
+        * editing/Editor.h:
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::defaultTextInputEventHandler):
+
 2010-08-08  Kevin Ollivier  <kevino at theolliviers.com>
 
         [wx] Build fix, add member needed to compile Mac-specific font code.
diff --git a/WebCore/WebCore.exp.in b/WebCore/WebCore.exp.in
index a96b190..0ba2cfd 100644
--- a/WebCore/WebCore.exp.in
+++ b/WebCore/WebCore.exp.in
@@ -612,6 +612,7 @@ __ZN7WebCore6Editor13performDeleteEv
 __ZN7WebCore6Editor13rangeForPointERKNS_8IntPointE
 __ZN7WebCore6Editor13tryDHTMLPasteEv
 __ZN7WebCore6Editor14setCompositionERKNS_6StringERKN3WTF6VectorINS_20CompositionUnderlineELm0EEEjj
+__ZN7WebCore6Editor15pasteAsFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbb
 __ZN7WebCore6Editor16pasteAsPlainTextEv
 __ZN7WebCore6Editor17insertOrderedListEv
 __ZN7WebCore6Editor18confirmCompositionERKNS_6StringE
diff --git a/WebCore/dom/TextEvent.cpp b/WebCore/dom/TextEvent.cpp
index d282c13..5dc39e3 100644
--- a/WebCore/dom/TextEvent.cpp
+++ b/WebCore/dom/TextEvent.cpp
@@ -31,17 +31,45 @@
 
 namespace WebCore {
 
+PassRefPtr<TextEvent> TextEvent::create()
+{
+    return adoptRef(new TextEvent);
+}
+
+PassRefPtr<TextEvent> TextEvent::create(PassRefPtr<AbstractView> view, const String& data)
+{
+    return adoptRef(new TextEvent(view, data));
+}
+
+PassRefPtr<TextEvent> TextEvent::createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace)
+{
+    return adoptRef(new TextEvent(view, data, 0, true, shouldSmartReplace));
+}
+
+PassRefPtr<TextEvent> TextEvent::createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle)
+{
+    return adoptRef(new TextEvent(view, "", data, true, shouldSmartReplace, shouldMatchStyle));
+}
+
 TextEvent::TextEvent()
     : m_isLineBreak(false)
     , m_isBackTab(false)
+    , m_isPaste(false)
+    , m_shouldSmartReplace(false)
+    , m_shouldMatchStyle(false)
 {
 }
 
-TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data)
+TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data, PassRefPtr<DocumentFragment> pastingFragment,
+                     bool isPaste, bool shouldSmartReplace, bool shouldMatchStyle)
     : UIEvent(eventNames().textInputEvent, true, true, view, 0)
     , m_data(data)
     , m_isLineBreak(false)
     , m_isBackTab(false)
+    , m_pastingFragment(pastingFragment)
+    , m_isPaste(isPaste)
+    , m_shouldSmartReplace(shouldSmartReplace)
+    , m_shouldMatchStyle(shouldMatchStyle)
 {
 }
 
diff --git a/WebCore/dom/TextEvent.h b/WebCore/dom/TextEvent.h
index 9f93fdb..2e2eb95 100644
--- a/WebCore/dom/TextEvent.h
+++ b/WebCore/dom/TextEvent.h
@@ -27,20 +27,18 @@
 #ifndef TextEvent_h
 #define TextEvent_h
 
+#include "DocumentFragment.h"
 #include "UIEvent.h"
 
 namespace WebCore {
 
     class TextEvent : public UIEvent {
     public:
-        static PassRefPtr<TextEvent> create()
-        {
-            return adoptRef(new TextEvent);
-        }
-        static PassRefPtr<TextEvent> create(PassRefPtr<AbstractView> view, const String& data)
-        {
-            return adoptRef(new TextEvent(view, data));
-        }
+        static PassRefPtr<TextEvent> create();
+        static PassRefPtr<TextEvent> create(PassRefPtr<AbstractView> view, const String& data);
+        static PassRefPtr<TextEvent> createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace);
+        static PassRefPtr<TextEvent> createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle);
+
         virtual ~TextEvent();
     
         void initTextEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, const String& data);
@@ -57,13 +55,24 @@ namespace WebCore {
         bool isBackTab() const { return m_isBackTab; }
         void setIsBackTab(bool isBackTab) { m_isBackTab = isBackTab; }
 
+        bool isPaste() const { return m_isPaste; }
+        bool shouldSmartReplace() const { return m_shouldSmartReplace; }
+        bool shouldMatchStyle() const { return m_shouldMatchStyle; }
+        DocumentFragment* pastingFragment() const { return m_pastingFragment.get(); }
+
     private:
         TextEvent();
-        TextEvent(PassRefPtr<AbstractView>, const String& data);
+        TextEvent(PassRefPtr<AbstractView>, const String& data, PassRefPtr<DocumentFragment> = 0,
+                  bool isPaste = false, bool shouldSmartReplace = false, bool shouldMatchStyle = false);
 
         String m_data;
         bool m_isLineBreak;
         bool m_isBackTab;
+
+        RefPtr<DocumentFragment> m_pastingFragment;
+        bool m_isPaste; // FIXME: Should use inputMode after it be available: http://webkit.org/b/42805
+        bool m_shouldSmartReplace;
+        bool m_shouldMatchStyle;
     };
 
 } // namespace WebCore
diff --git a/WebCore/editing/Editor.cpp b/WebCore/editing/Editor.cpp
index 44d8d5f..9c5b312 100644
--- a/WebCore/editing/Editor.cpp
+++ b/WebCore/editing/Editor.cpp
@@ -66,6 +66,7 @@
 #include "Settings.h"
 #include "Sound.h"
 #include "Text.h"
+#include "TextEvent.h"
 #include "TextIterator.h"
 #include "TypingCommand.h"
 #include "UserTypingGestureIndicator.h"
@@ -127,6 +128,26 @@ void Editor::handleInputMethodKeydown(KeyboardEvent* event)
         c->handleInputMethodKeydown(event);
 }
 
+bool Editor::handleTextEvent(TextEvent* event)
+{
+    if (event->isPaste()) {
+        if (event->pastingFragment())
+            replaceSelectionWithFragment(event->pastingFragment(), false, event->shouldSmartReplace(), event->shouldMatchStyle());
+        else 
+            replaceSelectionWithText(event->data(), false, event->shouldSmartReplace());
+        return true;
+    }
+
+    String data = event->data();
+    if (data == "\n") {
+        if (event->isLineBreak())
+            return insertLineBreak();
+        return insertParagraphSeparator();
+    }
+
+    return insertTextWithoutSendingTextEvent(data, false, event);
+}
+
 bool Editor::canEdit() const
 {
     return m_frame->selection()->isContentEditable();
@@ -282,11 +303,29 @@ void Editor::deleteSelectionWithSmartDelete(bool smartDelete)
     applyCommand(DeleteSelectionCommand::create(m_frame->document(), smartDelete));
 }
 
+void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace)
+{
+    Node* target = findEventTargetFromSelection();
+    if (!target)
+        return;
+    ExceptionCode ec = 0;
+    target->dispatchEvent(TextEvent::createForPlainTextPaste(m_frame->domWindow(), pastingText, smartReplace), ec);
+}
+
+void Editor::pasteAsFragment(PassRefPtr<DocumentFragment> pastingFragment, bool smartReplace, bool matchStyle)
+{
+    Node* target = findEventTargetFromSelection();
+    if (!target)
+        return;
+    ExceptionCode ec = 0;
+    target->dispatchEvent(TextEvent::createForFragmentPaste(m_frame->domWindow(), pastingFragment, smartReplace, matchStyle), ec);
+}
+
 void Editor::pasteAsPlainTextWithPasteboard(Pasteboard* pasteboard)
 {
     String text = pasteboard->plainText(m_frame);
     if (client() && client()->shouldInsertText(text, selectedRange().get(), EditorInsertActionPasted))
-        replaceSelectionWithText(text, false, canSmartReplaceWithPasteboard(pasteboard));
+        pasteAsPlainText(text, canSmartReplaceWithPasteboard(pasteboard));
 }
 
 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText)
@@ -295,7 +334,7 @@ void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText)
     bool chosePlainText;
     RefPtr<DocumentFragment> fragment = pasteboard->documentFragment(m_frame, range, allowPlainText, chosePlainText);
     if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted))
-        replaceSelectionWithFragment(fragment, false, canSmartReplaceWithPasteboard(pasteboard), chosePlainText);
+        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(pasteboard), chosePlainText);
 }
 
 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard)
@@ -706,12 +745,9 @@ void Editor::clearLastEditCommand()
 // the event handler NOT setting the return value to false
 bool Editor::dispatchCPPEvent(const AtomicString &eventType, ClipboardAccessPolicy policy)
 {
-    Node* target = m_frame->selection()->start().element();
-    if (!target)
-        target = m_frame->document()->body();
+    Node* target = findEventTargetFromSelection();
     if (!target)
         return true;
-    target = target->shadowAncestorNode();
     
     RefPtr<Clipboard> clipboard = newGeneralClipboard(policy, m_frame);
 
@@ -726,6 +762,16 @@ bool Editor::dispatchCPPEvent(const AtomicString &eventType, ClipboardAccessPoli
     return !noDefaultProcessing;
 }
 
+Node* Editor::findEventTargetFromSelection() const
+{
+    Node* target = m_frame->selection()->start().element();
+    if (!target)
+        target = m_frame->document()->body();
+    if (!target)
+        return 0;
+    return target->shadowAncestorNode();
+}
+
 void Editor::applyStyle(CSSStyleDeclaration* style, EditAction editingAction)
 {
     switch (m_frame->selection()->selectionType()) {
diff --git a/WebCore/editing/Editor.h b/WebCore/editing/Editor.h
index db249e7..13e6df5 100644
--- a/WebCore/editing/Editor.h
+++ b/WebCore/editing/Editor.h
@@ -49,6 +49,7 @@ class KillRing;
 class Pasteboard;
 class SimpleFontData;
 class Text;
+class TextEvent;
 
 struct CompositionUnderline {
     CompositionUnderline() 
@@ -77,6 +78,7 @@ public:
 
     void handleKeyboardEvent(KeyboardEvent*);
     void handleInputMethodKeydown(KeyboardEvent*);
+    bool handleTextEvent(TextEvent*);
 
     bool canEdit() const;
     bool canEditRichly() const;
@@ -293,6 +295,10 @@ public:
     PassRefPtr<Range> nextVisibleRange(Range*, const String&, bool forward, bool caseFlag, bool wrapFlag);
     
     void addToKillRing(Range*, bool prepend);
+
+    void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
+    void pasteAsPlainText(const String&, bool smartReplace);
+
 private:
     Frame* m_frame;
     OwnPtr<DeleteButtonController> m_deleteButtonController;
@@ -326,6 +332,7 @@ private:
     PassRefPtr<Range> lastVisibleRange(const String&, bool caseFlag);
     
     void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle);
+    Node* findEventTargetFromSelection() const;
 };
 
 inline void Editor::setStartNewKillRingSequence(bool flag)
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index e10a3a1..8a16181 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -2674,19 +2674,8 @@ bool EventHandler::tabsToLinks(KeyboardEvent* event) const
 
 void EventHandler::defaultTextInputEventHandler(TextEvent* event)
 {
-    String data = event->data();
-    if (data == "\n") {
-        if (event->isLineBreak()) {
-            if (m_frame->editor()->insertLineBreak())
-                event->setDefaultHandled();
-        } else {
-            if (m_frame->editor()->insertParagraphSeparator())
-                event->setDefaultHandled();
-        }
-    } else {
-        if (m_frame->editor()->insertTextWithoutSendingTextEvent(data, false, event))
-            event->setDefaultHandled();
-    }
+    if (m_frame->editor()->handleTextEvent(event))
+        event->setDefaultHandled();
 }
 
 #if PLATFORM(QT) || PLATFORM(MAC)
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index e08d188..d9c721e 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,16 @@
+2010-08-04  MORITA Hajime  <morrita at google.com>
+
+        Reviewed by Tony Chang.
+
+        Pasting should fire textInput event.
+        https://bugs.webkit.org/show_bug.cgi?id=42958
+
+        On paste, invoke Editor instead of direct command invocation,
+        which allows dispatching events before actual paste.
+
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView _pasteWithPasteboard:allowPlainText:]):
+
 2010-08-06  Yongjun Zhang  <yongjun_zhang at apple.com>
 
         Reviewed by Eric Seidel.
diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm
index 58ce124..0e559b4 100644
--- a/WebKit/mac/WebView/WebHTMLView.mm
+++ b/WebKit/mac/WebView/WebHTMLView.mm
@@ -849,11 +849,12 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
     [webView _setInsertionPasteboard:pasteboard];
 
     DOMRange *range = [self _selectedRange];
+    Frame* coreFrame = core([self _frame]);
     
 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
     DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText];
     if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:range givenAction:WebViewInsertActionPasted])
-        [[self _frame] _replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO];
+        coreFrame->editor()->pasteAsFragment(core(fragment), [self _canSmartReplaceWithPasteboard:pasteboard], false);
 #else
     // Mail is ignoring the frament passed to the delegate and creates a new one.
     // We want to avoid creating the fragment twice.
@@ -861,12 +862,12 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
         if ([self _shouldInsertFragment:nil replacingDOMRange:range givenAction:WebViewInsertActionPasted]) {
             DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText];
             if (fragment)
-                [[self _frame] _replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO];
+                coreFrame->editor()->pasteAsFragment(core(fragment), [self _canSmartReplaceWithPasteboard:pasteboard], false);
         }        
     } else {
         DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText];
         if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:range givenAction:WebViewInsertActionPasted])
-            [[self _frame] _replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO];
+            coreFrame->editor()->pasteAsFragment(core(fragment), [self _canSmartReplaceWithPasteboard:pasteboard], false);
     }
 #endif
     [webView _setInsertionPasteboard:nil];

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list