Changeset 206944 in webkit


Ignore:
Timestamp:
Oct 7, 2016 4:47:18 PM (8 years ago)
Author:
Wenson Hsieh
Message:

Support onbeforeinput event handling for the new InputEvent spec
https://bugs.webkit.org/show_bug.cgi?id=163021
<rdar://problem/28658073>

Reviewed by Darin Adler.

Source/WebCore:

Adds support for parsing the onbeforeinput attribute, and for sending default-preventable
beforeinput InputEvents to the page. To do this, we introduce two new virtual methods:
willApplyCommand and didApplyCommand on the CompositeEditCommand that are called before and
after CompositeEditCommand::doApply, respectively. willApplyCommand indicates whether or not
the composite editor command should proceed with applying the command.

Tweaks existing layout tests and adds new tests.

Tests: fast/events/before-input-events-different-start-end-elements.html

fast/events/before-input-events-prevent-default-in-textfield.html
fast/events/before-input-events-prevent-default.html

  • dom/Document.idl:
  • dom/Element.idl:
  • dom/EventNames.h:
  • dom/Node.cpp:

(WebCore::Node::dispatchInputEvent):
(WebCore::Node::defaultEventHandler):

Currently, we fire input events in Node in response to dispatching a webkitEditableContentChangedEvent. After
some discussion, Ryosuke and I believe that it will be ok to instead directly dispatch the input event where we
would normally dispatch a webkitEditableContentChangedEvent.

  • editing/CompositeEditCommand.cpp:

(WebCore::EditCommandComposition::unapply):
(WebCore::EditCommandComposition::reapply):

Added calls to Editor::willUnapplyEditing and Editor::willReapplyEditing.

(WebCore::CompositeEditCommand::willApplyCommand):
(WebCore::CompositeEditCommand::apply):
(WebCore::CompositeEditCommand::didApplyCommand):

Added new virtual functions, willApplyCommand and didApplyCommand, that surround a call to
CompositeEditCommand::doApply. By default, they call willApplyEditing and appliedEditing on the editor, but may
be overridden in special cases, such as in TypingCommand, where we invoke appliedEditing after adding a new
typing command to the last open command.

If willApplyCommand returns false, CompositeEditCommand::apply will bail and not proceed with the command.

  • editing/CompositeEditCommand.h:
  • editing/Editor.cpp:

(WebCore::dispatchBeforeInputEvent):
(WebCore::dispatchBeforeInputEvents):
(WebCore::dispatchInputEvents):
(WebCore::Editor::willApplyEditing):
(WebCore::Editor::appliedEditing):
(WebCore::Editor::willUnapplyEditing):
(WebCore::Editor::unappliedEditing):
(WebCore::Editor::willReapplyEditing):
(WebCore::Editor::reappliedEditing):
(WebCore::Editor::computeAndSetTypingStyle):
(WebCore::dispatchEditableContentChangedEvents): Deleted.

  • editing/Editor.h:
  • editing/TypingCommand.cpp:

(WebCore::TypingCommand::willApplyCommand):
(WebCore::TypingCommand::didApplyCommand):
(WebCore::TypingCommand::willAddTypingToOpenCommand):
(WebCore::TypingCommand::insertTextRunWithoutNewlines):
(WebCore::TypingCommand::insertLineBreak):
(WebCore::TypingCommand::insertParagraphSeparator):
(WebCore::TypingCommand::insertParagraphSeparatorInQuotedContent):
(WebCore::TypingCommand::deleteKeyPressed):
(WebCore::TypingCommand::forwardDeleteKeyPressed):
(WebCore::TypingCommand::deleteSelection):

These now invoke willAddTypingToOpenCommand before proceeding with creating the command and applying it. The
flow is now:

  • willAddTypingToOpenCommand
  • create and apply a new command
  • typingAddedToOpenCommand
  • editing/TypingCommand.h:

(WebCore::TypingCommand::preservesTypingStyle): Deleted.
(WebCore::TypingCommand::shouldRetainAutocorrectionIndicator): Deleted.
(WebCore::TypingCommand::setShouldRetainAutocorrectionIndicator): Deleted.
(WebCore::TypingCommand::shouldStopCaretBlinking): Deleted.

  • html/HTMLAttributeNames.in:
  • html/HTMLElement.cpp:

(WebCore::HTMLElement::createEventHandlerNameMap):

LayoutTests:

Tweak an existing test to hook into the 'input' event instead of 'webkitEditableContentChanged', as well as
tests added in r206843 to verify that onbeforeinput handlers are invoked with InputEvents. Also introduces
new unit tests verifying that calling preventDefault on InputEvents fired by onbeforeinput correctly prevent
text from being inserted or deleted.

  • editing/undo/undo-after-event-edited.html:
  • fast/events/before-input-events-different-start-end-elements-expected.txt: Added.
  • fast/events/before-input-events-different-start-end-elements.html: Added.
  • fast/events/before-input-events-prevent-default-expected.txt: Added.
  • fast/events/before-input-events-prevent-default-in-textfield-expected.txt: Added.
  • fast/events/before-input-events-prevent-default-in-textfield.html: Added.
  • fast/events/before-input-events-prevent-default.html: Added.
  • fast/events/input-events-fired-when-typing-expected.txt:
  • fast/events/input-events-fired-when-typing.html:
  • platform/ios-simulator/TestExpectations:
Location:
trunk
Files:
6 added
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r206943 r206944  
     12016-10-07  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Support onbeforeinput event handling for the new InputEvent spec
     4        https://bugs.webkit.org/show_bug.cgi?id=163021
     5        <rdar://problem/28658073>
     6
     7        Reviewed by Darin Adler.
     8
     9        Tweak an existing test to hook into the 'input' event instead of 'webkitEditableContentChanged', as well as
     10        tests added in r206843 to verify that `onbeforeinput` handlers are invoked with InputEvents. Also introduces
     11        new unit tests verifying that calling preventDefault on InputEvents fired by `onbeforeinput` correctly prevent
     12        text from being inserted or deleted.
     13
     14        * editing/undo/undo-after-event-edited.html:
     15        * fast/events/before-input-events-different-start-end-elements-expected.txt: Added.
     16        * fast/events/before-input-events-different-start-end-elements.html: Added.
     17        * fast/events/before-input-events-prevent-default-expected.txt: Added.
     18        * fast/events/before-input-events-prevent-default-in-textfield-expected.txt: Added.
     19        * fast/events/before-input-events-prevent-default-in-textfield.html: Added.
     20        * fast/events/before-input-events-prevent-default.html: Added.
     21        * fast/events/input-events-fired-when-typing-expected.txt:
     22        * fast/events/input-events-fired-when-typing.html:
     23        * platform/ios-simulator/TestExpectations:
     24
    1252016-10-07  Nan Wang  <n_wang@apple.com>
    226
  • trunk/LayoutTests/editing/undo/undo-after-event-edited.html

    r163560 r206944  
    1818var eventHandlerActive = false;
    1919
    20 document.addEventListener("webkitEditableContentChanged", function () {
     20document.addEventListener("input", function () {
    2121    if (eventHandlerActive)
    2222        return;
  • trunk/LayoutTests/fast/events/input-events-fired-when-typing-expected.txt

    r206843 r206944  
    22
    33TEST COMPLETE
     4Fired `onbeforeinput`!
     5PASS event.__lookupGetter__('inputType') is defined.
     6PASS Object.getPrototypeOf(event) is InputEvent.prototype
     7PASS event.target.id is expectedTargetID
     8PASS event.bubbles is true
     9PASS event.cancelable is true
     10PASS event.composed is true
     11Fired `oninput`!
    412PASS event.__lookupGetter__('inputType') is defined.
    513PASS Object.getPrototypeOf(event) is InputEvent.prototype
     
    816PASS event.cancelable is false
    917PASS event.composed is true
     18Fired `onbeforeinput`!
     19PASS event.__lookupGetter__('inputType') is defined.
     20PASS Object.getPrototypeOf(event) is InputEvent.prototype
     21PASS event.target.id is expectedTargetID
     22PASS event.bubbles is true
     23PASS event.cancelable is true
     24PASS event.composed is true
     25Fired `oninput`!
    1026PASS event.__lookupGetter__('inputType') is defined.
    1127PASS Object.getPrototypeOf(event) is InputEvent.prototype
  • trunk/LayoutTests/fast/events/input-events-fired-when-typing.html

    r206843 r206944  
    3434        function checkInputEvent(event)
    3535        {
     36            debug("Fired `oninput`!");
    3637            shouldBeDefined("event.__lookupGetter__('inputType')");
    3738            shouldBe("Object.getPrototypeOf(event)", "InputEvent.prototype");
     
    4142            shouldBe("event.composed", "true");
    4243        }
     44
     45        function checkBeforeInputEvent(event)
     46        {
     47            debug("Fired `onbeforeinput`!");
     48            shouldBeDefined("event.__lookupGetter__('inputType')");
     49            shouldBe("Object.getPrototypeOf(event)", "InputEvent.prototype");
     50            shouldBe("event.target.id", "expectedTargetID");
     51            shouldBe("event.bubbles", "true");
     52            shouldBe("event.cancelable", "true");
     53            shouldBe("event.composed", "true");
     54        }
    4355    </script>
    4456</head>
    4557
    4658<body onload=beginTest()>
    47     <div id="foo" contenteditable oninput=checkInputEvent(event)></div>
    48     <input id="bar" oninput=checkInputEvent(event)></input>
     59    <div id="foo" contenteditable oninput=checkInputEvent(event) onbeforeinput=checkBeforeInputEvent(event)></div>
     60    <input id="bar" oninput=checkInputEvent(event) onbeforeinput=checkBeforeInputEvent(event)></input>
    4961    <script src="../../resources/js-test-post.js"></script>
    5062</body>
  • trunk/LayoutTests/platform/ios-simulator/TestExpectations

    r206896 r206944  
    11991199fast/events/inputText-never-fired-on-keydown-cancel.html [ Failure ]
    12001200fast/events/input-events-fired-when-typing.html [ Failure ]
     1201fast/events/before-input-events-prevent-default.html [ Failure ]
     1202fast/events/before-input-events-prevent-default-in-textfield.html [ Failure ]
    12011203fast/events/key-events-in-input-button.html [ Failure ]
    12021204fast/events/keydown-1.html [ Failure ]
  • trunk/Source/WebCore/ChangeLog

    r206943 r206944  
     12016-10-07  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Support onbeforeinput event handling for the new InputEvent spec
     4        https://bugs.webkit.org/show_bug.cgi?id=163021
     5        <rdar://problem/28658073>
     6
     7        Reviewed by Darin Adler.
     8
     9        Adds support for parsing the onbeforeinput attribute, and for sending default-preventable
     10        `beforeinput` InputEvents to the page. To do this, we introduce two new virtual methods:
     11        willApplyCommand and didApplyCommand on the CompositeEditCommand that are called before and
     12        after CompositeEditCommand::doApply, respectively. willApplyCommand indicates whether or not
     13        the composite editor command should proceed with applying the command.
     14
     15        Tweaks existing layout tests and adds new tests.
     16
     17        Tests: fast/events/before-input-events-different-start-end-elements.html
     18               fast/events/before-input-events-prevent-default-in-textfield.html
     19               fast/events/before-input-events-prevent-default.html
     20
     21        * dom/Document.idl:
     22        * dom/Element.idl:
     23        * dom/EventNames.h:
     24        * dom/Node.cpp:
     25        (WebCore::Node::dispatchInputEvent):
     26        (WebCore::Node::defaultEventHandler):
     27
     28        Currently, we fire input events in Node in response to dispatching a webkitEditableContentChangedEvent. After
     29        some discussion, Ryosuke and I believe that it will be ok to instead directly dispatch the input event where we
     30        would normally dispatch a webkitEditableContentChangedEvent.
     31
     32        * editing/CompositeEditCommand.cpp:
     33        (WebCore::EditCommandComposition::unapply):
     34        (WebCore::EditCommandComposition::reapply):
     35
     36        Added calls to Editor::willUnapplyEditing and Editor::willReapplyEditing.
     37
     38        (WebCore::CompositeEditCommand::willApplyCommand):
     39        (WebCore::CompositeEditCommand::apply):
     40        (WebCore::CompositeEditCommand::didApplyCommand):
     41
     42        Added new virtual functions, willApplyCommand and didApplyCommand, that surround a call to
     43        CompositeEditCommand::doApply. By default, they call willApplyEditing and appliedEditing on the editor, but may
     44        be overridden in special cases, such as in TypingCommand, where we invoke appliedEditing after adding a new
     45        typing command to the last open command.
     46
     47        If willApplyCommand returns false, CompositeEditCommand::apply will bail and not proceed with the command.
     48
     49        * editing/CompositeEditCommand.h:
     50        * editing/Editor.cpp:
     51        (WebCore::dispatchBeforeInputEvent):
     52        (WebCore::dispatchBeforeInputEvents):
     53        (WebCore::dispatchInputEvents):
     54        (WebCore::Editor::willApplyEditing):
     55        (WebCore::Editor::appliedEditing):
     56        (WebCore::Editor::willUnapplyEditing):
     57        (WebCore::Editor::unappliedEditing):
     58        (WebCore::Editor::willReapplyEditing):
     59        (WebCore::Editor::reappliedEditing):
     60        (WebCore::Editor::computeAndSetTypingStyle):
     61        (WebCore::dispatchEditableContentChangedEvents): Deleted.
     62        * editing/Editor.h:
     63        * editing/TypingCommand.cpp:
     64        (WebCore::TypingCommand::willApplyCommand):
     65        (WebCore::TypingCommand::didApplyCommand):
     66        (WebCore::TypingCommand::willAddTypingToOpenCommand):
     67        (WebCore::TypingCommand::insertTextRunWithoutNewlines):
     68        (WebCore::TypingCommand::insertLineBreak):
     69        (WebCore::TypingCommand::insertParagraphSeparator):
     70        (WebCore::TypingCommand::insertParagraphSeparatorInQuotedContent):
     71        (WebCore::TypingCommand::deleteKeyPressed):
     72        (WebCore::TypingCommand::forwardDeleteKeyPressed):
     73        (WebCore::TypingCommand::deleteSelection):
     74
     75        These now invoke willAddTypingToOpenCommand before proceeding with creating the command and applying it. The
     76        flow is now:
     77            - willAddTypingToOpenCommand
     78            - create and apply a new command
     79            - typingAddedToOpenCommand
     80
     81        * editing/TypingCommand.h:
     82        (WebCore::TypingCommand::preservesTypingStyle): Deleted.
     83        (WebCore::TypingCommand::shouldRetainAutocorrectionIndicator): Deleted.
     84        (WebCore::TypingCommand::setShouldRetainAutocorrectionIndicator): Deleted.
     85        (WebCore::TypingCommand::shouldStopCaretBlinking): Deleted.
     86        * html/HTMLAttributeNames.in:
     87        * html/HTMLElement.cpp:
     88        (WebCore::HTMLElement::createEventHandlerNameMap):
     89
    1902016-10-07  Nan Wang  <n_wang@apple.com>
    291
  • trunk/Source/WebCore/dom/Document.idl

    r206795 r206944  
    193193    [NotEnumerable] attribute EventHandler onbeforecopy;
    194194    [NotEnumerable] attribute EventHandler onbeforecut;
     195    [NotEnumerable] attribute EventHandler onbeforeinput;
    195196    [NotEnumerable] attribute EventHandler onbeforepaste;
    196197    [NotEnumerable] attribute EventHandler oncopy;
  • trunk/Source/WebCore/dom/Element.idl

    r206877 r206944  
    146146    [NotEnumerable] attribute EventHandler onbeforecopy;
    147147    [NotEnumerable] attribute EventHandler onbeforecut;
     148    [NotEnumerable] attribute EventHandler onbeforeinput;
    148149    [NotEnumerable] attribute EventHandler onbeforepaste;
    149150    [NotEnumerable] attribute EventHandler oncopy;
  • trunk/Source/WebCore/dom/EventNames.h

    r202298 r206944  
    6161    macro(beforecopy) \
    6262    macro(beforecut) \
     63    macro(beforeinput) \
    6364    macro(beforeload) \
    6465    macro(beforepaste) \
  • trunk/Source/WebCore/dom/Node.cpp

    r206843 r206944  
    22052205void Node::dispatchInputEvent(const AtomicString& inputType)
    22062206{
    2207     if (document().settings()->inputEventsEnabled())
     2207    auto* settings = document().settings();
     2208    if (settings && settings->inputEventsEnabled())
    22082209        dispatchScopedEvent(InputEvent::create(eventNames().inputEvent, inputType, true, false, document().defaultView(), 0));
    22092210    else
     
    22732274        }
    22742275#endif
    2275     } else if (event.type() == eventNames().webkitEditableContentChangedEvent) {
    2276         dispatchInputEvent(emptyString());
    22772276    }
    22782277}
  • trunk/Source/WebCore/editing/CompositeEditCommand.cpp

    r203660 r206944  
    232232#endif
    233233
     234    if (!frame->editor().willUnapplyEditing(*this))
     235        return;
     236
    234237    size_t size = m_commands.size();
    235238    for (size_t i = size; i; --i)
     
    256259    m_document->updateLayoutIgnorePendingStylesheets();
    257260
     261    if (!frame->editor().willReapplyEditing(*this))
     262        return;
     263
    258264    for (auto& command : m_commands)
    259265        command->doReapply();
     
    310316{
    311317    ASSERT(isTopLevelCommand() || !m_composition);
     318}
     319
     320bool CompositeEditCommand::willApplyCommand()
     321{
     322    return frame().editor().willApplyEditing(*this);
    312323}
    313324
     
    338349    document().updateLayoutIgnorePendingStylesheets();
    339350
     351    if (!willApplyCommand())
     352        return;
     353
    340354    {
    341355        EventQueueScope eventQueueScope;
     
    343357    }
    344358
    345     // Only need to call appliedEditing for top-level commands,
    346     // and TypingCommands do it on their own (see TypingCommand::typingAddedToOpenCommand).
    347     if (!isTypingCommand())
    348         frame().editor().appliedEditing(this);
     359    didApplyCommand();
    349360    setShouldRetainAutocorrectionIndicator(false);
     361}
     362
     363void CompositeEditCommand::didApplyCommand()
     364{
     365    frame().editor().appliedEditing(this);
    350366}
    351367
  • trunk/Source/WebCore/editing/CompositeEditCommand.h

    r200876 r206944  
    117117protected:
    118118    explicit CompositeEditCommand(Document&, EditAction = EditActionUnspecified);
     119
     120    // If willApplyCommand returns false, we won't proceed with applying the command.
     121    virtual bool willApplyCommand();
     122    virtual void didApplyCommand();
    119123
    120124    //
  • trunk/Source/WebCore/editing/Editor.cpp

    r206843 r206944  
    6060#include "HitTestResult.h"
    6161#include "IndentOutdentCommand.h"
     62#include "InputEvent.h"
    6263#include "InsertListCommand.h"
     64#include "InsertTextCommand.h"
    6365#include "KeyboardEvent.h"
    6466#include "KillRing.h"
     
    110112namespace WebCore {
    111113
     114static bool dispatchBeforeInputEvent(Element& element, const AtomicString& inputType)
     115{
     116    auto* settings = element.document().settings();
     117    if (!settings || !settings->inputEventsEnabled())
     118        return true;
     119
     120    auto event = InputEvent::create(eventNames().beforeinputEvent, inputType, true, true, element.document().defaultView(), 0);
     121    element.dispatchScopedEvent(event);
     122
     123    return !event->defaultPrevented();
     124}
     125
    112126class ClearTextCommand : public DeleteSelectionCommand {
    113127public:
     
    10261040}
    10271041
    1028 static void dispatchEditableContentChangedEvents(PassRefPtr<Element> prpStartRoot, PassRefPtr<Element> prpEndRoot)
    1029 {
    1030     RefPtr<Element> startRoot = prpStartRoot;
    1031     RefPtr<Element> endRoot = prpEndRoot;
     1042static bool dispatchBeforeInputEvents(RefPtr<Element> startRoot, RefPtr<Element> endRoot, const AtomicString& inputTypeName)
     1043{
     1044    bool continueWithDefaultBehavior = true;
    10321045    if (startRoot)
    1033         startRoot->dispatchEvent(Event::create(eventNames().webkitEditableContentChangedEvent, false, false));
     1046        continueWithDefaultBehavior &= dispatchBeforeInputEvent(*startRoot, inputTypeName);
    10341047    if (endRoot && endRoot != startRoot)
    1035         endRoot->dispatchEvent(Event::create(eventNames().webkitEditableContentChangedEvent, false, false));
     1048        continueWithDefaultBehavior &= dispatchBeforeInputEvent(*endRoot, inputTypeName);
     1049    return continueWithDefaultBehavior;
     1050}
     1051
     1052static void dispatchInputEvents(RefPtr<Element> startRoot, RefPtr<Element> endRoot, const AtomicString& inputTypeName)
     1053{
     1054    if (startRoot)
     1055        startRoot->dispatchInputEvent(inputTypeName);
     1056    if (endRoot && endRoot != startRoot)
     1057        endRoot->dispatchInputEvent(inputTypeName);
     1058}
     1059
     1060bool Editor::willApplyEditing(CompositeEditCommand& command) const
     1061{
     1062    auto* composition = command.composition();
     1063    if (!composition)
     1064        return true;
     1065
     1066    return dispatchBeforeInputEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement(), emptyString());
    10361067}
    10371068
     
    10521083   
    10531084    changeSelectionAfterCommand(newSelection, options);
    1054     dispatchEditableContentChangedEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement());
     1085    dispatchInputEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement(), emptyString());
    10551086
    10561087    updateEditorUINowIfScheduled();
     
    10751106}
    10761107
     1108bool Editor::willUnapplyEditing(const EditCommandComposition& composition) const
     1109{
     1110    return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), emptyString());
     1111}
     1112
    10771113void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd)
    10781114{
     
    10831119    VisibleSelection newSelection(cmd->startingSelection());
    10841120    changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
    1085     dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement());
     1121    dispatchInputEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), emptyString());
    10861122
    10871123    updateEditorUINowIfScheduled();
     
    10951131}
    10961132
     1133bool Editor::willReapplyEditing(const EditCommandComposition& composition) const
     1134{
     1135    return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), emptyString());
     1136}
     1137
    10971138void Editor::reappliedEditing(PassRefPtr<EditCommandComposition> cmd)
    10981139{
     
    11031144    VisibleSelection newSelection(cmd->endingSelection());
    11041145    changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
    1105     dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement());
     1146    dispatchInputEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), emptyString());
    11061147   
    11071148    updateEditorUINowIfScheduled();
     
    30533094    }
    30543095
     3096    auto* element = m_frame.selection().selection().rootEditableElement();
     3097    if (element && !dispatchBeforeInputEvent(*element, emptyString()))
     3098        return;
     3099
    30553100    // Calculate the current typing style.
    30563101    RefPtr<EditingStyle> typingStyle;
     
    30653110    if (!blockStyle->isEmpty())
    30663111        applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
     3112
     3113    if (element)
     3114        element->dispatchInputEvent(emptyString());
    30673115
    30683116    // Set the remaining style as the typing style.
  • trunk/Source/WebCore/editing/Editor.h

    r206629 r206944  
    199199    void applyParagraphStyleToSelection(StyleProperties*, EditAction);
    200200
     201    // Returns whether or not we should proceed with editing.
     202    bool willApplyEditing(CompositeEditCommand&) const;
     203    bool willUnapplyEditing(const EditCommandComposition&) const;
     204    bool willReapplyEditing(const EditCommandComposition&) const;
     205
    201206    void appliedEditing(PassRefPtr<CompositeEditCommand>);
    202207    void unappliedEditing(PassRefPtr<EditCommandComposition>);
  • trunk/Source/WebCore/editing/TypingCommand.cpp

    r205092 r206944  
    263263}
    264264
     265bool TypingCommand::willApplyCommand()
     266{
     267    if (!m_isHandlingInitialTypingCommand) {
     268        // The TypingCommand will handle the willApplyCommand logic separately in TypingCommand::willAddTypingToOpenCommand.
     269        return true;
     270    }
     271
     272    return CompositeEditCommand::willApplyCommand();
     273}
     274
    265275void TypingCommand::doApply()
    266276{
     
    297307
    298308    ASSERT_NOT_REACHED();
     309}
     310
     311void TypingCommand::didApplyCommand()
     312{
     313    // TypingCommands handle applied editing separately (see TypingCommand::typingAddedToOpenCommand).
     314    m_isHandlingInitialTypingCommand = false;
    299315}
    300316
     
    353369}
    354370
     371bool TypingCommand::willAddTypingToOpenCommand(ETypingCommand, TextGranularity)
     372{
     373    if (m_isHandlingInitialTypingCommand)
     374        return true;
     375
     376    // FIXME: Use the newly added typing command and granularity to ensure that an InputEvent with the
     377    // correct inputType is dispatched.
     378    return frame().editor().willApplyEditing(*this);
     379}
     380
    355381void TypingCommand::typingAddedToOpenCommand(ETypingCommand commandTypeForAddedTyping)
    356382{
     
    394420void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText)
    395421{
     422    if (!willAddTypingToOpenCommand(InsertText, CharacterGranularity))
     423        return;
     424
    396425    RefPtr<InsertTextCommand> command = InsertTextCommand::create(document(), text, selectInsertedText,
    397426        m_compositionType == TextCompositionNone ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces : InsertTextCommand::RebalanceAllWhitespaces, EditActionTyping);
     
    405434{
    406435    if (!canAppendNewLineFeedToSelection(endingSelection()))
     436        return;
     437
     438    if (!willAddTypingToOpenCommand(InsertLineBreak, LineGranularity))
    407439        return;
    408440
     
    424456        return;
    425457
     458    if (!willAddTypingToOpenCommand(InsertParagraphSeparator, ParagraphGranularity))
     459        return;
     460
    426461    applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(), false, false, EditActionTyping));
    427462    typingAddedToOpenCommand(InsertParagraphSeparator);
     
    438473void TypingCommand::insertParagraphSeparatorInQuotedContent()
    439474{
     475    if (!willAddTypingToOpenCommand(InsertParagraphSeparatorInQuotedContent, ParagraphGranularity))
     476        return;
     477
    440478    // If the selection starts inside a table, just insert the paragraph separator normally
    441479    // Breaking the blockquote would also break apart the table, which is unecessary when inserting a newline
     
    480518void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool shouldAddToKillRing)
    481519{
     520    if (!willAddTypingToOpenCommand(DeleteKey, granularity))
     521        return;
     522
    482523    Frame& frame = this->frame();
    483524
     
    593634void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool shouldAddToKillRing)
    594635{
     636    if (!willAddTypingToOpenCommand(ForwardDeleteKey, granularity))
     637        return;
     638
    595639    Frame& frame = this->frame();
    596640
     
    691735void TypingCommand::deleteSelection(bool smartDelete)
    692736{
     737    if (!willAddTypingToOpenCommand(DeleteSelection, CharacterGranularity))
     738        return;
     739
    693740    CompositeEditCommand::deleteSelection(smartDelete);
    694741    typingAddedToOpenCommand(DeleteSelection);
  • trunk/Source/WebCore/editing/TypingCommand.h

    r203250 r206944  
    3131namespace WebCore {
    3232
    33 class TypingCommand : public TextInsertionBaseCommand {
     33class TypingCommand final : public TextInsertionBaseCommand {
    3434public:
    3535    enum ETypingCommand {
     
    105105    static RefPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(Frame&);
    106106
    107     virtual void doApply();
    108     virtual bool isTypingCommand() const;
    109     virtual bool preservesTypingStyle() const { return m_preservesTypingStyle; }
    110     virtual bool shouldRetainAutocorrectionIndicator() const
     107    void doApply();
     108    bool isTypingCommand() const;
     109    bool preservesTypingStyle() const { return m_preservesTypingStyle; }
     110    bool shouldRetainAutocorrectionIndicator() const
    111111    {
    112112        ASSERT(isTopLevelCommand());
    113113        return m_shouldRetainAutocorrectionIndicator;
    114114    }
    115     virtual void setShouldRetainAutocorrectionIndicator(bool retain) { m_shouldRetainAutocorrectionIndicator = retain; }
    116     virtual bool shouldStopCaretBlinking() const { return true; }
     115    void setShouldRetainAutocorrectionIndicator(bool retain) { m_shouldRetainAutocorrectionIndicator = retain; }
     116    bool shouldStopCaretBlinking() const { return true; }
    117117    void setShouldPreventSpellChecking(bool prevent) { m_shouldPreventSpellChecking = prevent; }
    118118
     
    120120
    121121    void updatePreservesTypingStyle(ETypingCommand);
     122    bool willAddTypingToOpenCommand(ETypingCommand, TextGranularity);
    122123    void markMisspellingsAfterTyping(ETypingCommand);
    123124    void typingAddedToOpenCommand(ETypingCommand);
     
    130131    void insertParagraphSeparatorAndNotifyAccessibility();
    131132
     133    bool willApplyCommand();
     134    void didApplyCommand();
     135
    132136    ETypingCommand m_commandType;
    133137    String m_textToInsert;
     
    135139    bool m_selectInsertedText;
    136140    bool m_smartDelete;
     141    bool m_isHandlingInitialTypingCommand { true };
    137142    TextGranularity m_granularity;
    138143    TextCompositionType m_compositionType;
  • trunk/Source/WebCore/html/HTMLAttributeNames.in

    r205524 r206944  
    189189onbeforecopy
    190190onbeforecut
     191onbeforeinput
    191192onbeforeload
    192193onbeforepaste
  • trunk/Source/WebCore/html/HTMLElement.cpp

    r205663 r206944  
    232232        &onbeforecopyAttr,
    233233        &onbeforecutAttr,
     234        &onbeforeinputAttr,
    234235        &onbeforeloadAttr,
    235236        &onbeforepasteAttr,
Note: See TracChangeset for help on using the changeset viewer.