Changeset 64963 in webkit


Ignore:
Timestamp:
Aug 8, 2010 10:26:47 PM (14 years ago)
Author:
morrita@google.com
Message:

2010-08-04 MORITA Hajime <morrita@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@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@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:]):
Location:
trunk
Files:
3 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r64962 r64963  
     12010-08-04  MORITA Hajime  <morrita@google.com>
     2
     3        Reviewed by Tony Chang.
     4
     5        Pasting should fire textInput event.
     6        https://bugs.webkit.org/show_bug.cgi?id=42958
     7
     8        * editing/pasteboard/paste-text-events-expected.txt: Added.
     9        * editing/pasteboard/paste-text-events.html: Added.
     10        * editing/pasteboard/script-tests/paste-text-events.js: Added.
     11
    1122010-08-05  MORITA Hajime  <morrita@google.com>
    213
  • trunk/WebCore/ChangeLog

    r64958 r64963  
     12010-08-05  MORITA Hajime  <morrita@google.com>
     2
     3        Reviewed by Tony Chang.
     4
     5        Pasting should fire textInput event.
     6        https://bugs.webkit.org/show_bug.cgi?id=42958
     7
     8        - Extended TextEvents to hold paste-specific parameters
     9        - Did fire TextEvents at where we originally did immediate pastes.
     10        - Factored out TextEvent handling from EventHandler::defaultTextInputEventHandler()
     11          to Editor::handleTextEvent() because it's solely done by the editor.
     12        - move actual pasting logic to Editor::handleTextEvent()
     13
     14        Test: editing/pasteboard/paste-text-events.html
     15
     16        * WebCore.exp.in:
     17        * dom/TextEvent.cpp:
     18        (WebCore::TextEvent::create):
     19        (WebCore::TextEvent::createForPlainTextPaste):
     20        (WebCore::TextEvent::createForFragmentPaste):
     21        (WebCore::TextEvent::TextEvent):
     22        * dom/TextEvent.h:
     23        (WebCore::TextEvent::isPaste):
     24        (WebCore::TextEvent::shouldSmartReplace):
     25        (WebCore::TextEvent::shouldMatchStyle):
     26        (WebCore::TextEvent::pastingFragment):
     27        * editing/Editor.cpp:
     28        (WebCore::Editor::handleTextEvent):
     29        (WebCore::Editor::pasteAsPlainText):
     30        (WebCore::Editor::pasteAsFragment):
     31        (WebCore::Editor::pasteAsPlainTextWithPasteboard):
     32        (WebCore::Editor::pasteWithPasteboard):
     33        (WebCore::Editor::dispatchCPPEvent):
     34        (WebCore::Editor::findEventTargetFromSelection):
     35        * editing/Editor.h:
     36        * page/EventHandler.cpp:
     37        (WebCore::EventHandler::defaultTextInputEventHandler):
     38
    1392010-08-08  Kevin Ollivier  <kevino@theolliviers.com>
    240
  • trunk/WebCore/WebCore.exp.in

    r64845 r64963  
    613613__ZN7WebCore6Editor13tryDHTMLPasteEv
    614614__ZN7WebCore6Editor14setCompositionERKNS_6StringERKN3WTF6VectorINS_20CompositionUnderlineELm0EEEjj
     615__ZN7WebCore6Editor15pasteAsFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbb
    615616__ZN7WebCore6Editor16pasteAsPlainTextEv
    616617__ZN7WebCore6Editor17insertOrderedListEv
  • trunk/WebCore/dom/TextEvent.cpp

    r38094 r64963  
    3232namespace WebCore {
    3333
     34PassRefPtr<TextEvent> TextEvent::create()
     35{
     36    return adoptRef(new TextEvent);
     37}
     38
     39PassRefPtr<TextEvent> TextEvent::create(PassRefPtr<AbstractView> view, const String& data)
     40{
     41    return adoptRef(new TextEvent(view, data));
     42}
     43
     44PassRefPtr<TextEvent> TextEvent::createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace)
     45{
     46    return adoptRef(new TextEvent(view, data, 0, true, shouldSmartReplace));
     47}
     48
     49PassRefPtr<TextEvent> TextEvent::createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle)
     50{
     51    return adoptRef(new TextEvent(view, "", data, true, shouldSmartReplace, shouldMatchStyle));
     52}
     53
    3454TextEvent::TextEvent()
    3555    : m_isLineBreak(false)
    3656    , m_isBackTab(false)
     57    , m_isPaste(false)
     58    , m_shouldSmartReplace(false)
     59    , m_shouldMatchStyle(false)
    3760{
    3861}
    3962
    40 TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data)
     63TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data, PassRefPtr<DocumentFragment> pastingFragment,
     64                     bool isPaste, bool shouldSmartReplace, bool shouldMatchStyle)
    4165    : UIEvent(eventNames().textInputEvent, true, true, view, 0)
    4266    , m_data(data)
    4367    , m_isLineBreak(false)
    4468    , m_isBackTab(false)
     69    , m_pastingFragment(pastingFragment)
     70    , m_isPaste(isPaste)
     71    , m_shouldSmartReplace(shouldSmartReplace)
     72    , m_shouldMatchStyle(shouldMatchStyle)
    4573{
    4674}
  • trunk/WebCore/dom/TextEvent.h

    r34536 r64963  
    2828#define TextEvent_h
    2929
     30#include "DocumentFragment.h"
    3031#include "UIEvent.h"
    3132
     
    3435    class TextEvent : public UIEvent {
    3536    public:
    36         static PassRefPtr<TextEvent> create()
    37         {
    38             return adoptRef(new TextEvent);
    39         }
    40         static PassRefPtr<TextEvent> create(PassRefPtr<AbstractView> view, const String& data)
    41         {
    42             return adoptRef(new TextEvent(view, data));
    43         }
     37        static PassRefPtr<TextEvent> create();
     38        static PassRefPtr<TextEvent> create(PassRefPtr<AbstractView> view, const String& data);
     39        static PassRefPtr<TextEvent> createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace);
     40        static PassRefPtr<TextEvent> createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle);
     41
    4442        virtual ~TextEvent();
    4543   
     
    5856        void setIsBackTab(bool isBackTab) { m_isBackTab = isBackTab; }
    5957
     58        bool isPaste() const { return m_isPaste; }
     59        bool shouldSmartReplace() const { return m_shouldSmartReplace; }
     60        bool shouldMatchStyle() const { return m_shouldMatchStyle; }
     61        DocumentFragment* pastingFragment() const { return m_pastingFragment.get(); }
     62
    6063    private:
    6164        TextEvent();
    62         TextEvent(PassRefPtr<AbstractView>, const String& data);
     65        TextEvent(PassRefPtr<AbstractView>, const String& data, PassRefPtr<DocumentFragment> = 0,
     66                  bool isPaste = false, bool shouldSmartReplace = false, bool shouldMatchStyle = false);
    6367
    6468        String m_data;
    6569        bool m_isLineBreak;
    6670        bool m_isBackTab;
     71
     72        RefPtr<DocumentFragment> m_pastingFragment;
     73        bool m_isPaste; // FIXME: Should use inputMode after it be available: http://webkit.org/b/42805
     74        bool m_shouldSmartReplace;
     75        bool m_shouldMatchStyle;
    6776    };
    6877
  • trunk/WebCore/editing/Editor.cpp

    r64152 r64963  
    6767#include "Sound.h"
    6868#include "Text.h"
     69#include "TextEvent.h"
    6970#include "TextIterator.h"
    7071#include "TypingCommand.h"
     
    126127    if (EditorClient* c = client())
    127128        c->handleInputMethodKeydown(event);
     129}
     130
     131bool Editor::handleTextEvent(TextEvent* event)
     132{
     133    if (event->isPaste()) {
     134        if (event->pastingFragment())
     135            replaceSelectionWithFragment(event->pastingFragment(), false, event->shouldSmartReplace(), event->shouldMatchStyle());
     136        else
     137            replaceSelectionWithText(event->data(), false, event->shouldSmartReplace());
     138        return true;
     139    }
     140
     141    String data = event->data();
     142    if (data == "\n") {
     143        if (event->isLineBreak())
     144            return insertLineBreak();
     145        return insertParagraphSeparator();
     146    }
     147
     148    return insertTextWithoutSendingTextEvent(data, false, event);
    128149}
    129150
     
    283304}
    284305
     306void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace)
     307{
     308    Node* target = findEventTargetFromSelection();
     309    if (!target)
     310        return;
     311    ExceptionCode ec = 0;
     312    target->dispatchEvent(TextEvent::createForPlainTextPaste(m_frame->domWindow(), pastingText, smartReplace), ec);
     313}
     314
     315void Editor::pasteAsFragment(PassRefPtr<DocumentFragment> pastingFragment, bool smartReplace, bool matchStyle)
     316{
     317    Node* target = findEventTargetFromSelection();
     318    if (!target)
     319        return;
     320    ExceptionCode ec = 0;
     321    target->dispatchEvent(TextEvent::createForFragmentPaste(m_frame->domWindow(), pastingFragment, smartReplace, matchStyle), ec);
     322}
     323
    285324void Editor::pasteAsPlainTextWithPasteboard(Pasteboard* pasteboard)
    286325{
    287326    String text = pasteboard->plainText(m_frame);
    288327    if (client() && client()->shouldInsertText(text, selectedRange().get(), EditorInsertActionPasted))
    289         replaceSelectionWithText(text, false, canSmartReplaceWithPasteboard(pasteboard));
     328        pasteAsPlainText(text, canSmartReplaceWithPasteboard(pasteboard));
    290329}
    291330
     
    296335    RefPtr<DocumentFragment> fragment = pasteboard->documentFragment(m_frame, range, allowPlainText, chosePlainText);
    297336    if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted))
    298         replaceSelectionWithFragment(fragment, false, canSmartReplaceWithPasteboard(pasteboard), chosePlainText);
     337        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(pasteboard), chosePlainText);
    299338}
    300339
     
    707746bool Editor::dispatchCPPEvent(const AtomicString &eventType, ClipboardAccessPolicy policy)
    708747{
     748    Node* target = findEventTargetFromSelection();
     749    if (!target)
     750        return true;
     751   
     752    RefPtr<Clipboard> clipboard = newGeneralClipboard(policy, m_frame);
     753
     754    ExceptionCode ec = 0;
     755    RefPtr<Event> evt = ClipboardEvent::create(eventType, true, true, clipboard);
     756    target->dispatchEvent(evt, ec);
     757    bool noDefaultProcessing = evt->defaultPrevented();
     758
     759    // invalidate clipboard here for security
     760    clipboard->setAccessPolicy(ClipboardNumb);
     761   
     762    return !noDefaultProcessing;
     763}
     764
     765Node* Editor::findEventTargetFromSelection() const
     766{
    709767    Node* target = m_frame->selection()->start().element();
    710768    if (!target)
    711769        target = m_frame->document()->body();
    712770    if (!target)
    713         return true;
    714     target = target->shadowAncestorNode();
    715    
    716     RefPtr<Clipboard> clipboard = newGeneralClipboard(policy, m_frame);
    717 
    718     ExceptionCode ec = 0;
    719     RefPtr<Event> evt = ClipboardEvent::create(eventType, true, true, clipboard);
    720     target->dispatchEvent(evt, ec);
    721     bool noDefaultProcessing = evt->defaultPrevented();
    722 
    723     // invalidate clipboard here for security
    724     clipboard->setAccessPolicy(ClipboardNumb);
    725    
    726     return !noDefaultProcessing;
     771        return 0;
     772    return target->shadowAncestorNode();
    727773}
    728774
  • trunk/WebCore/editing/Editor.h

    r64152 r64963  
    5050class SimpleFontData;
    5151class Text;
     52class TextEvent;
    5253
    5354struct CompositionUnderline {
     
    7879    void handleKeyboardEvent(KeyboardEvent*);
    7980    void handleInputMethodKeydown(KeyboardEvent*);
     81    bool handleTextEvent(TextEvent*);
    8082
    8183    bool canEdit() const;
     
    294296   
    295297    void addToKillRing(Range*, bool prepend);
     298
     299    void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
     300    void pasteAsPlainText(const String&, bool smartReplace);
     301
    296302private:
    297303    Frame* m_frame;
     
    327333   
    328334    void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle);
     335    Node* findEventTargetFromSelection() const;
    329336};
    330337
  • trunk/WebCore/page/EventHandler.cpp

    r64272 r64963  
    26752675void EventHandler::defaultTextInputEventHandler(TextEvent* event)
    26762676{
    2677     String data = event->data();
    2678     if (data == "\n") {
    2679         if (event->isLineBreak()) {
    2680             if (m_frame->editor()->insertLineBreak())
    2681                 event->setDefaultHandled();
    2682         } else {
    2683             if (m_frame->editor()->insertParagraphSeparator())
    2684                 event->setDefaultHandled();
    2685         }
    2686     } else {
    2687         if (m_frame->editor()->insertTextWithoutSendingTextEvent(data, false, event))
    2688             event->setDefaultHandled();
    2689     }
     2677    if (m_frame->editor()->handleTextEvent(event))
     2678        event->setDefaultHandled();
    26902679}
    26912680
  • trunk/WebKit/mac/ChangeLog

    r64868 r64963  
     12010-08-04  MORITA Hajime  <morrita@google.com>
     2
     3        Reviewed by Tony Chang.
     4
     5        Pasting should fire textInput event.
     6        https://bugs.webkit.org/show_bug.cgi?id=42958
     7
     8        On paste, invoke Editor instead of direct command invocation,
     9        which allows dispatching events before actual paste.
     10
     11        * WebView/WebHTMLView.mm:
     12        (-[WebHTMLView _pasteWithPasteboard:allowPlainText:]):
     13
    1142010-08-06  Yongjun Zhang  <yongjun_zhang@apple.com>
    215
  • trunk/WebKit/mac/WebView/WebHTMLView.mm

    r64409 r64963  
    850850
    851851    DOMRange *range = [self _selectedRange];
     852    Frame* coreFrame = core([self _frame]);
    852853   
    853854#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    854855    DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText];
    855856    if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:range givenAction:WebViewInsertActionPasted])
    856         [[self _frame] _replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO];
     857        coreFrame->editor()->pasteAsFragment(core(fragment), [self _canSmartReplaceWithPasteboard:pasteboard], false);
    857858#else
    858859    // Mail is ignoring the frament passed to the delegate and creates a new one.
     
    862863            DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText];
    863864            if (fragment)
    864                 [[self _frame] _replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO];
     865                coreFrame->editor()->pasteAsFragment(core(fragment), [self _canSmartReplaceWithPasteboard:pasteboard], false);
    865866        }       
    866867    } else {
    867868        DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText];
    868869        if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:range givenAction:WebViewInsertActionPasted])
    869             [[self _frame] _replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO];
     870            coreFrame->editor()->pasteAsFragment(core(fragment), [self _canSmartReplaceWithPasteboard:pasteboard], false);
    870871    }
    871872#endif
Note: See TracChangeset for help on using the changeset viewer.