| Differences between
and this patch
- a/Source/WebCore/ChangeLog +89 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2016-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
1
2016-10-05  Philippe Normand  <pnormand@igalia.com>
90
2016-10-05  Philippe Normand  <pnormand@igalia.com>
2
91
3
        [GStreamer][OWR] GL rendering support
92
        [GStreamer][OWR] GL rendering support
- a/Source/WebCore/dom/Document.idl +1 lines
Lines 192-197 a/Source/WebCore/dom/Document.idl_sec1
192
    // FIXME: Should these be exposed on Window as well (and therefore moved to GlobalEventHandlers.idl)?
192
    // FIXME: Should these be exposed on Window as well (and therefore moved to GlobalEventHandlers.idl)?
193
    [NotEnumerable] attribute EventHandler onbeforecopy;
193
    [NotEnumerable] attribute EventHandler onbeforecopy;
194
    [NotEnumerable] attribute EventHandler onbeforecut;
194
    [NotEnumerable] attribute EventHandler onbeforecut;
195
    [NotEnumerable] attribute EventHandler onbeforeinput;
195
    [NotEnumerable] attribute EventHandler onbeforepaste;
196
    [NotEnumerable] attribute EventHandler onbeforepaste;
196
    [NotEnumerable] attribute EventHandler oncopy;
197
    [NotEnumerable] attribute EventHandler oncopy;
197
    [NotEnumerable] attribute EventHandler oncut;
198
    [NotEnumerable] attribute EventHandler oncut;
- a/Source/WebCore/dom/Element.idl +1 lines
Lines 145-150 a/Source/WebCore/dom/Element.idl_sec1
145
    // FIXME: Should these be exposed on Window as well (and therefore moved to GlobalEventHandlers.idl)?
145
    // FIXME: Should these be exposed on Window as well (and therefore moved to GlobalEventHandlers.idl)?
146
    [NotEnumerable] attribute EventHandler onbeforecopy;
146
    [NotEnumerable] attribute EventHandler onbeforecopy;
147
    [NotEnumerable] attribute EventHandler onbeforecut;
147
    [NotEnumerable] attribute EventHandler onbeforecut;
148
    [NotEnumerable] attribute EventHandler onbeforeinput;
148
    [NotEnumerable] attribute EventHandler onbeforepaste;
149
    [NotEnumerable] attribute EventHandler onbeforepaste;
149
    [NotEnumerable] attribute EventHandler oncopy;
150
    [NotEnumerable] attribute EventHandler oncopy;
150
    [NotEnumerable] attribute EventHandler oncut;
151
    [NotEnumerable] attribute EventHandler oncut;
- a/Source/WebCore/dom/EventNames.h +1 lines
Lines 60-65 namespace WebCore { a/Source/WebCore/dom/EventNames.h_sec1
60
    macro(autocompleteerror) \
60
    macro(autocompleteerror) \
61
    macro(beforecopy) \
61
    macro(beforecopy) \
62
    macro(beforecut) \
62
    macro(beforecut) \
63
    macro(beforeinput) \
63
    macro(beforeload) \
64
    macro(beforeload) \
64
    macro(beforepaste) \
65
    macro(beforepaste) \
65
    macro(beforeunload) \
66
    macro(beforeunload) \
- a/Source/WebCore/dom/Node.cpp -3 / +2 lines
Lines 2204-2210 bool Node::dispatchBeforeLoadEvent(const String& sourceURL) a/Source/WebCore/dom/Node.cpp_sec1
2204
2204
2205
void Node::dispatchInputEvent(const AtomicString& inputType)
2205
void Node::dispatchInputEvent(const AtomicString& inputType)
2206
{
2206
{
2207
    if (document().settings()->inputEventsEnabled())
2207
    auto* settings = document().settings();
2208
    if (settings && settings->inputEventsEnabled())
2208
        dispatchScopedEvent(InputEvent::create(eventNames().inputEvent, inputType, true, false, document().defaultView(), 0));
2209
        dispatchScopedEvent(InputEvent::create(eventNames().inputEvent, inputType, true, false, document().defaultView(), 0));
2209
    else
2210
    else
2210
        dispatchScopedEvent(Event::create(eventNames().inputEvent, true, false));
2211
        dispatchScopedEvent(Event::create(eventNames().inputEvent, true, false));
Lines 2272-2279 void Node::defaultEventHandler(Event& event) a/Source/WebCore/dom/Node.cpp_sec2
2272
                frame->eventHandler().defaultTouchEventHandler(renderer->node(), &downcast<TouchEvent>(event));
2273
                frame->eventHandler().defaultTouchEventHandler(renderer->node(), &downcast<TouchEvent>(event));
2273
        }
2274
        }
2274
#endif
2275
#endif
2275
    } else if (event.type() == eventNames().webkitEditableContentChangedEvent) {
2276
        dispatchInputEvent(emptyString());
2277
    }
2276
    }
2278
}
2277
}
2279
2278
- a/Source/WebCore/editing/CompositeEditCommand.cpp -4 / +20 lines
Lines 231-236 void EditCommandComposition::unapply() a/Source/WebCore/editing/CompositeEditCommand.cpp_sec1
231
    frame->editor().cancelComposition();
231
    frame->editor().cancelComposition();
232
#endif
232
#endif
233
233
234
    if (!frame->editor().willUnapplyEditing(*this))
235
        return;
236
234
    size_t size = m_commands.size();
237
    size_t size = m_commands.size();
235
    for (size_t i = size; i; --i)
238
    for (size_t i = size; i; --i)
236
        m_commands[i - 1]->doUnapply();
239
        m_commands[i - 1]->doUnapply();
Lines 255-260 void EditCommandComposition::reapply() a/Source/WebCore/editing/CompositeEditCommand.cpp_sec2
255
    // if one is necessary (like for the creation of VisiblePositions).
258
    // if one is necessary (like for the creation of VisiblePositions).
256
    m_document->updateLayoutIgnorePendingStylesheets();
259
    m_document->updateLayoutIgnorePendingStylesheets();
257
260
261
    if (!frame->editor().willReapplyEditing(*this))
262
        return;
263
258
    for (auto& command : m_commands)
264
    for (auto& command : m_commands)
259
        command->doReapply();
265
        command->doReapply();
260
266
Lines 311-316 CompositeEditCommand::~CompositeEditCommand() a/Source/WebCore/editing/CompositeEditCommand.cpp_sec3
311
    ASSERT(isTopLevelCommand() || !m_composition);
317
    ASSERT(isTopLevelCommand() || !m_composition);
312
}
318
}
313
319
320
bool CompositeEditCommand::willApplyCommand()
321
{
322
    return frame().editor().willApplyEditing(*this);
323
}
324
314
void CompositeEditCommand::apply()
325
void CompositeEditCommand::apply()
315
{
326
{
316
    if (!endingSelection().isContentRichlyEditable()) {
327
    if (!endingSelection().isContentRichlyEditable()) {
Lines 337-354 void CompositeEditCommand::apply() a/Source/WebCore/editing/CompositeEditCommand.cpp_sec4
337
    // if one is necessary (like for the creation of VisiblePositions).
348
    // if one is necessary (like for the creation of VisiblePositions).
338
    document().updateLayoutIgnorePendingStylesheets();
349
    document().updateLayoutIgnorePendingStylesheets();
339
350
351
    if (!willApplyCommand())
352
        return;
353
340
    {
354
    {
341
        EventQueueScope eventQueueScope;
355
        EventQueueScope eventQueueScope;
342
        doApply();
356
        doApply();
343
    }
357
    }
344
358
345
    // Only need to call appliedEditing for top-level commands,
359
    didApplyCommand();
346
    // and TypingCommands do it on their own (see TypingCommand::typingAddedToOpenCommand).
347
    if (!isTypingCommand())
348
        frame().editor().appliedEditing(this);
349
    setShouldRetainAutocorrectionIndicator(false);
360
    setShouldRetainAutocorrectionIndicator(false);
350
}
361
}
351
362
363
void CompositeEditCommand::didApplyCommand()
364
{
365
    frame().editor().appliedEditing(this);
366
}
367
352
EditCommandComposition* CompositeEditCommand::ensureComposition()
368
EditCommandComposition* CompositeEditCommand::ensureComposition()
353
{
369
{
354
    CompositeEditCommand* command = this;
370
    CompositeEditCommand* command = this;
- a/Source/WebCore/editing/CompositeEditCommand.h +4 lines
Lines 117-122 public: a/Source/WebCore/editing/CompositeEditCommand.h_sec1
117
protected:
117
protected:
118
    explicit CompositeEditCommand(Document&, EditAction = EditActionUnspecified);
118
    explicit CompositeEditCommand(Document&, EditAction = EditActionUnspecified);
119
119
120
    // If willApplyCommand returns false, we won't proceed with applying the command.
121
    virtual bool willApplyCommand();
122
    virtual void didApplyCommand();
123
120
    //
124
    //
121
    // sugary-sweet convenience functions to help create and apply edit commands in composite commands
125
    // sugary-sweet convenience functions to help create and apply edit commands in composite commands
122
    //
126
    //
- a/Source/WebCore/editing/Editor.cpp -8 / +56 lines
Lines 59-65 a/Source/WebCore/editing/Editor.cpp_sec1
59
#include "HTMLTextAreaElement.h"
59
#include "HTMLTextAreaElement.h"
60
#include "HitTestResult.h"
60
#include "HitTestResult.h"
61
#include "IndentOutdentCommand.h"
61
#include "IndentOutdentCommand.h"
62
#include "InputEvent.h"
62
#include "InsertListCommand.h"
63
#include "InsertListCommand.h"
64
#include "InsertTextCommand.h"
63
#include "KeyboardEvent.h"
65
#include "KeyboardEvent.h"
64
#include "KillRing.h"
66
#include "KillRing.h"
65
#include "Logging.h"
67
#include "Logging.h"
Lines 109-114 a/Source/WebCore/editing/Editor.cpp_sec2
109
111
110
namespace WebCore {
112
namespace WebCore {
111
113
114
static 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
112
class ClearTextCommand : public DeleteSelectionCommand {
126
class ClearTextCommand : public DeleteSelectionCommand {
113
public:
127
public:
114
    ClearTextCommand(Document& document);
128
    ClearTextCommand(Document& document);
Lines 1025-1038 static void notifyTextFromControls(Element* startRoot, Element* endRoot) a/Source/WebCore/editing/Editor.cpp_sec3
1025
        endingTextControl->didEditInnerTextValue();
1039
        endingTextControl->didEditInnerTextValue();
1026
}
1040
}
1027
1041
1028
static void dispatchEditableContentChangedEvents(PassRefPtr<Element> prpStartRoot, PassRefPtr<Element> prpEndRoot)
1042
static bool dispatchBeforeInputEvents(RefPtr<Element> startRoot, RefPtr<Element> endRoot, const AtomicString& inputTypeName)
1029
{
1043
{
1030
    RefPtr<Element> startRoot = prpStartRoot;
1044
    bool continueWithDefaultBehavior = true;
1031
    RefPtr<Element> endRoot = prpEndRoot;
1032
    if (startRoot)
1045
    if (startRoot)
1033
        startRoot->dispatchEvent(Event::create(eventNames().webkitEditableContentChangedEvent, false, false));
1046
        continueWithDefaultBehavior &= dispatchBeforeInputEvent(*startRoot, inputTypeName);
1034
    if (endRoot && endRoot != startRoot)
1047
    if (endRoot && endRoot != startRoot)
1035
        endRoot->dispatchEvent(Event::create(eventNames().webkitEditableContentChangedEvent, false, false));
1048
        continueWithDefaultBehavior &= dispatchBeforeInputEvent(*endRoot, inputTypeName);
1049
    return continueWithDefaultBehavior;
1050
}
1051
1052
static 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
1060
bool 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());
1036
}
1067
}
1037
1068
1038
void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd)
1069
void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd)
Lines 1051-1057 void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd) a/Source/WebCore/editing/Editor.cpp_sec4
1051
    FrameSelection::SetSelectionOptions options = cmd->isDictationCommand() ? FrameSelection::DictationTriggered : 0;
1082
    FrameSelection::SetSelectionOptions options = cmd->isDictationCommand() ? FrameSelection::DictationTriggered : 0;
1052
    
1083
    
1053
    changeSelectionAfterCommand(newSelection, options);
1084
    changeSelectionAfterCommand(newSelection, options);
1054
    dispatchEditableContentChangedEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement());
1085
    dispatchInputEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement(), emptyString());
1055
1086
1056
    updateEditorUINowIfScheduled();
1087
    updateEditorUINowIfScheduled();
1057
    
1088
    
Lines 1074-1079 void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd) a/Source/WebCore/editing/Editor.cpp_sec5
1074
    respondToChangedContents(newSelection);
1105
    respondToChangedContents(newSelection);
1075
}
1106
}
1076
1107
1108
bool Editor::willUnapplyEditing(const EditCommandComposition& composition) const
1109
{
1110
    return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), emptyString());
1111
}
1112
1077
void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd)
1113
void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd)
1078
{
1114
{
1079
    document().updateLayout();
1115
    document().updateLayout();
Lines 1082-1088 void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd) a/Source/WebCore/editing/Editor.cpp_sec6
1082
1118
1083
    VisibleSelection newSelection(cmd->startingSelection());
1119
    VisibleSelection newSelection(cmd->startingSelection());
1084
    changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
1120
    changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
1085
    dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement());
1121
    dispatchInputEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), emptyString());
1086
1122
1087
    updateEditorUINowIfScheduled();
1123
    updateEditorUINowIfScheduled();
1088
1124
Lines 1094-1099 void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd) a/Source/WebCore/editing/Editor.cpp_sec7
1094
    respondToChangedContents(newSelection);
1130
    respondToChangedContents(newSelection);
1095
}
1131
}
1096
1132
1133
bool Editor::willReapplyEditing(const EditCommandComposition& composition) const
1134
{
1135
    return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), emptyString());
1136
}
1137
1097
void Editor::reappliedEditing(PassRefPtr<EditCommandComposition> cmd)
1138
void Editor::reappliedEditing(PassRefPtr<EditCommandComposition> cmd)
1098
{
1139
{
1099
    document().updateLayout();
1140
    document().updateLayout();
Lines 1102-1108 void Editor::reappliedEditing(PassRefPtr<EditCommandComposition> cmd) a/Source/WebCore/editing/Editor.cpp_sec8
1102
1143
1103
    VisibleSelection newSelection(cmd->endingSelection());
1144
    VisibleSelection newSelection(cmd->endingSelection());
1104
    changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
1145
    changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
1105
    dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement());
1146
    dispatchInputEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), emptyString());
1106
    
1147
    
1107
    updateEditorUINowIfScheduled();
1148
    updateEditorUINowIfScheduled();
1108
1149
Lines 3052-3057 void Editor::computeAndSetTypingStyle(EditingStyle& style, EditAction editingAct a/Source/WebCore/editing/Editor.cpp_sec9
3052
        return;
3093
        return;
3053
    }
3094
    }
3054
3095
3096
    auto* element = m_frame.selection().selection().rootEditableElement();
3097
    if (element && !dispatchBeforeInputEvent(*element, emptyString()))
3098
        return;
3099
3055
    // Calculate the current typing style.
3100
    // Calculate the current typing style.
3056
    RefPtr<EditingStyle> typingStyle;
3101
    RefPtr<EditingStyle> typingStyle;
3057
    if (auto existingTypingStyle = m_frame.selection().typingStyle())
3102
    if (auto existingTypingStyle = m_frame.selection().typingStyle())
Lines 3065-3070 void Editor::computeAndSetTypingStyle(EditingStyle& style, EditAction editingAct a/Source/WebCore/editing/Editor.cpp_sec10
3065
    if (!blockStyle->isEmpty())
3110
    if (!blockStyle->isEmpty())
3066
        applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
3111
        applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
3067
3112
3113
    if (element)
3114
        element->dispatchInputEvent(emptyString());
3115
3068
    // Set the remaining style as the typing style.
3116
    // Set the remaining style as the typing style.
3069
    m_frame.selection().setTypingStyle(typingStyle);
3117
    m_frame.selection().setTypingStyle(typingStyle);
3070
}
3118
}
- a/Source/WebCore/editing/Editor.h +5 lines
Lines 198-203 public: a/Source/WebCore/editing/Editor.h_sec1
198
    WEBCORE_EXPORT void applyStyleToSelection(Ref<EditingStyle>&&, EditAction);
198
    WEBCORE_EXPORT void applyStyleToSelection(Ref<EditingStyle>&&, EditAction);
199
    void applyParagraphStyleToSelection(StyleProperties*, EditAction);
199
    void applyParagraphStyleToSelection(StyleProperties*, EditAction);
200
200
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
201
    void appliedEditing(PassRefPtr<CompositeEditCommand>);
206
    void appliedEditing(PassRefPtr<CompositeEditCommand>);
202
    void unappliedEditing(PassRefPtr<EditCommandComposition>);
207
    void unappliedEditing(PassRefPtr<EditCommandComposition>);
203
    void reappliedEditing(PassRefPtr<EditCommandComposition>);
208
    void reappliedEditing(PassRefPtr<EditCommandComposition>);
- a/Source/WebCore/editing/TypingCommand.cpp +47 lines
Lines 262-267 void TypingCommand::postTextStateChangeNotificationForDeletion(const VisibleSele a/Source/WebCore/editing/TypingCommand.cpp_sec1
262
    composition()->setRangeDeletedByUnapply(range);
262
    composition()->setRangeDeletedByUnapply(range);
263
}
263
}
264
264
265
bool 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
265
void TypingCommand::doApply()
275
void TypingCommand::doApply()
266
{
276
{
267
    if (endingSelection().isNoneOrOrphaned())
277
    if (endingSelection().isNoneOrOrphaned())
Lines 298-303 void TypingCommand::doApply() a/Source/WebCore/editing/TypingCommand.cpp_sec2
298
    ASSERT_NOT_REACHED();
308
    ASSERT_NOT_REACHED();
299
}
309
}
300
310
311
void TypingCommand::didApplyCommand()
312
{
313
    // TypingCommands handle applied editing separately (see TypingCommand::typingAddedToOpenCommand).
314
    m_isHandlingInitialTypingCommand = false;
315
}
316
301
void TypingCommand::markMisspellingsAfterTyping(ETypingCommand commandType)
317
void TypingCommand::markMisspellingsAfterTyping(ETypingCommand commandType)
302
{
318
{
303
    Frame& frame = this->frame();
319
    Frame& frame = this->frame();
Lines 352-357 void TypingCommand::markMisspellingsAfterTyping(ETypingCommand commandType) a/Source/WebCore/editing/TypingCommand.cpp_sec3
352
    }
368
    }
353
}
369
}
354
370
371
bool 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
355
void TypingCommand::typingAddedToOpenCommand(ETypingCommand commandTypeForAddedTyping)
381
void TypingCommand::typingAddedToOpenCommand(ETypingCommand commandTypeForAddedTyping)
356
{
382
{
357
    Frame& frame = this->frame();
383
    Frame& frame = this->frame();
Lines 393-398 void TypingCommand::insertTextAndNotifyAccessibility(const String &text, bool se a/Source/WebCore/editing/TypingCommand.cpp_sec4
393
419
394
void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText)
420
void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText)
395
{
421
{
422
    if (!willAddTypingToOpenCommand(InsertText, CharacterGranularity))
423
        return;
424
396
    RefPtr<InsertTextCommand> command = InsertTextCommand::create(document(), text, selectInsertedText,
425
    RefPtr<InsertTextCommand> command = InsertTextCommand::create(document(), text, selectInsertedText,
397
        m_compositionType == TextCompositionNone ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces : InsertTextCommand::RebalanceAllWhitespaces, EditActionTyping);
426
        m_compositionType == TextCompositionNone ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces : InsertTextCommand::RebalanceAllWhitespaces, EditActionTyping);
398
427
Lines 406-411 void TypingCommand::insertLineBreak() a/Source/WebCore/editing/TypingCommand.cpp_sec5
406
    if (!canAppendNewLineFeedToSelection(endingSelection()))
435
    if (!canAppendNewLineFeedToSelection(endingSelection()))
407
        return;
436
        return;
408
437
438
    if (!willAddTypingToOpenCommand(InsertLineBreak, LineGranularity))
439
        return;
440
409
    applyCommandToComposite(InsertLineBreakCommand::create(document()));
441
    applyCommandToComposite(InsertLineBreakCommand::create(document()));
410
    typingAddedToOpenCommand(InsertLineBreak);
442
    typingAddedToOpenCommand(InsertLineBreak);
411
}
443
}
Lines 423-428 void TypingCommand::insertParagraphSeparator() a/Source/WebCore/editing/TypingCommand.cpp_sec6
423
    if (!canAppendNewLineFeedToSelection(endingSelection()))
455
    if (!canAppendNewLineFeedToSelection(endingSelection()))
424
        return;
456
        return;
425
457
458
    if (!willAddTypingToOpenCommand(InsertParagraphSeparator, ParagraphGranularity))
459
        return;
460
426
    applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(), false, false, EditActionTyping));
461
    applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(), false, false, EditActionTyping));
427
    typingAddedToOpenCommand(InsertParagraphSeparator);
462
    typingAddedToOpenCommand(InsertParagraphSeparator);
428
}
463
}
Lines 437-442 void TypingCommand::insertParagraphSeparatorAndNotifyAccessibility() a/Source/WebCore/editing/TypingCommand.cpp_sec7
437
472
438
void TypingCommand::insertParagraphSeparatorInQuotedContent()
473
void TypingCommand::insertParagraphSeparatorInQuotedContent()
439
{
474
{
475
    if (!willAddTypingToOpenCommand(InsertParagraphSeparatorInQuotedContent, ParagraphGranularity))
476
        return;
477
440
    // If the selection starts inside a table, just insert the paragraph separator normally
478
    // If the selection starts inside a table, just insert the paragraph separator normally
441
    // Breaking the blockquote would also break apart the table, which is unecessary when inserting a newline
479
    // Breaking the blockquote would also break apart the table, which is unecessary when inserting a newline
442
    if (enclosingNodeOfType(endingSelection().start(), &isTableStructureNode)) {
480
    if (enclosingNodeOfType(endingSelection().start(), &isTableStructureNode)) {
Lines 479-484 bool TypingCommand::makeEditableRootEmpty() a/Source/WebCore/editing/TypingCommand.cpp_sec8
479
517
480
void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool shouldAddToKillRing)
518
void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool shouldAddToKillRing)
481
{
519
{
520
    if (!willAddTypingToOpenCommand(DeleteKey, granularity))
521
        return;
522
482
    Frame& frame = this->frame();
523
    Frame& frame = this->frame();
483
524
484
    frame.editor().updateMarkersForWordsAffectedByEditing(false);
525
    frame.editor().updateMarkersForWordsAffectedByEditing(false);
Lines 592-597 void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool shouldAdd a/Source/WebCore/editing/TypingCommand.cpp_sec9
592
633
593
void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool shouldAddToKillRing)
634
void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool shouldAddToKillRing)
594
{
635
{
636
    if (!willAddTypingToOpenCommand(ForwardDeleteKey, granularity))
637
        return;
638
595
    Frame& frame = this->frame();
639
    Frame& frame = this->frame();
596
640
597
    frame.editor().updateMarkersForWordsAffectedByEditing(false);
641
    frame.editor().updateMarkersForWordsAffectedByEditing(false);
Lines 690-695 void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool sh a/Source/WebCore/editing/TypingCommand.cpp_sec10
690
734
691
void TypingCommand::deleteSelection(bool smartDelete)
735
void TypingCommand::deleteSelection(bool smartDelete)
692
{
736
{
737
    if (!willAddTypingToOpenCommand(DeleteSelection, CharacterGranularity))
738
        return;
739
693
    CompositeEditCommand::deleteSelection(smartDelete);
740
    CompositeEditCommand::deleteSelection(smartDelete);
694
    typingAddedToOpenCommand(DeleteSelection);
741
    typingAddedToOpenCommand(DeleteSelection);
695
}
742
}
- a/Source/WebCore/editing/TypingCommand.h -7 / +12 lines
Lines 30-36 a/Source/WebCore/editing/TypingCommand.h_sec1
30
30
31
namespace WebCore {
31
namespace WebCore {
32
32
33
class TypingCommand : public TextInsertionBaseCommand {
33
class TypingCommand final : public TextInsertionBaseCommand {
34
public:
34
public:
35
    enum ETypingCommand { 
35
    enum ETypingCommand { 
36
        DeleteSelection,
36
        DeleteSelection,
Lines 104-124 private: a/Source/WebCore/editing/TypingCommand.h_sec2
104
104
105
    static RefPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(Frame&);
105
    static RefPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(Frame&);
106
106
107
    virtual void doApply();
107
    void doApply();
108
    virtual bool isTypingCommand() const;
108
    bool isTypingCommand() const;
109
    virtual bool preservesTypingStyle() const { return m_preservesTypingStyle; }
109
    bool preservesTypingStyle() const { return m_preservesTypingStyle; }
110
    virtual bool shouldRetainAutocorrectionIndicator() const
110
    bool shouldRetainAutocorrectionIndicator() const
111
    {
111
    {
112
        ASSERT(isTopLevelCommand());
112
        ASSERT(isTopLevelCommand());
113
        return m_shouldRetainAutocorrectionIndicator;
113
        return m_shouldRetainAutocorrectionIndicator;
114
    }
114
    }
115
    virtual void setShouldRetainAutocorrectionIndicator(bool retain) { m_shouldRetainAutocorrectionIndicator = retain; }
115
    void setShouldRetainAutocorrectionIndicator(bool retain) { m_shouldRetainAutocorrectionIndicator = retain; }
116
    virtual bool shouldStopCaretBlinking() const { return true; }
116
    bool shouldStopCaretBlinking() const { return true; }
117
    void setShouldPreventSpellChecking(bool prevent) { m_shouldPreventSpellChecking = prevent; }
117
    void setShouldPreventSpellChecking(bool prevent) { m_shouldPreventSpellChecking = prevent; }
118
118
119
    static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
119
    static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
120
120
121
    void updatePreservesTypingStyle(ETypingCommand);
121
    void updatePreservesTypingStyle(ETypingCommand);
122
    bool willAddTypingToOpenCommand(ETypingCommand, TextGranularity);
122
    void markMisspellingsAfterTyping(ETypingCommand);
123
    void markMisspellingsAfterTyping(ETypingCommand);
123
    void typingAddedToOpenCommand(ETypingCommand);
124
    void typingAddedToOpenCommand(ETypingCommand);
124
    bool makeEditableRootEmpty();
125
    bool makeEditableRootEmpty();
Lines 129-139 private: a/Source/WebCore/editing/TypingCommand.h_sec3
129
    void insertParagraphSeparatorInQuotedContentAndNotifyAccessibility();
130
    void insertParagraphSeparatorInQuotedContentAndNotifyAccessibility();
130
    void insertParagraphSeparatorAndNotifyAccessibility();
131
    void insertParagraphSeparatorAndNotifyAccessibility();
131
132
133
    bool willApplyCommand();
134
    void didApplyCommand();
135
132
    ETypingCommand m_commandType;
136
    ETypingCommand m_commandType;
133
    String m_textToInsert;
137
    String m_textToInsert;
134
    bool m_openForMoreTyping;
138
    bool m_openForMoreTyping;
135
    bool m_selectInsertedText;
139
    bool m_selectInsertedText;
136
    bool m_smartDelete;
140
    bool m_smartDelete;
141
    bool m_isHandlingInitialTypingCommand { true };
137
    TextGranularity m_granularity;
142
    TextGranularity m_granularity;
138
    TextCompositionType m_compositionType;
143
    TextCompositionType m_compositionType;
139
    bool m_shouldAddToKillRing;
144
    bool m_shouldAddToKillRing;
- a/Source/WebCore/html/HTMLAttributeNames.in +1 lines
Lines 188-193 onautocomplete a/Source/WebCore/html/HTMLAttributeNames.in_sec1
188
onautocompleteerror
188
onautocompleteerror
189
onbeforecopy
189
onbeforecopy
190
onbeforecut
190
onbeforecut
191
onbeforeinput
191
onbeforeload
192
onbeforeload
192
onbeforepaste
193
onbeforepaste
193
onbeforeunload
194
onbeforeunload
- a/Source/WebCore/html/HTMLElement.cpp +1 lines
Lines 231-236 HTMLElement::EventHandlerNameMap HTMLElement::createEventHandlerNameMap() a/Source/WebCore/html/HTMLElement.cpp_sec1
231
        &onautocompleteerrorAttr,
231
        &onautocompleteerrorAttr,
232
        &onbeforecopyAttr,
232
        &onbeforecopyAttr,
233
        &onbeforecutAttr,
233
        &onbeforecutAttr,
234
        &onbeforeinputAttr,
234
        &onbeforeloadAttr,
235
        &onbeforeloadAttr,
235
        &onbeforepasteAttr,
236
        &onbeforepasteAttr,
236
        &onblurAttr,
237
        &onblurAttr,
- a/LayoutTests/ChangeLog +24 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2016-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
1
2016-10-06  Ryan Haddad  <ryanhaddad@apple.com>
25
2016-10-06  Ryan Haddad  <ryanhaddad@apple.com>
2
26
3
        Skip accessibility/mac/wk1-set-selected-text-marker-range-input-element.html on mac-wk2.
27
        Skip accessibility/mac/wk1-set-selected-text-marker-range-input-element.html on mac-wk2.
- a/LayoutTests/editing/undo/undo-after-event-edited.html -1 / +1 lines
Lines 17-23 var scriptElements = document.getElementsByTagName("script"); a/LayoutTests/editing/undo/undo-after-event-edited.html_sec1
17
scriptElements[0].parentNode.removeChild(scriptElements[0]);
17
scriptElements[0].parentNode.removeChild(scriptElements[0]);
18
var eventHandlerActive = false;
18
var eventHandlerActive = false;
19
19
20
document.addEventListener("webkitEditableContentChanged", function () {
20
document.addEventListener("input", function () {
21
    if (eventHandlerActive)
21
    if (eventHandlerActive)
22
        return;
22
        return;
23
    eventHandlerActive = true;
23
    eventHandlerActive = true;
- a/LayoutTests/fast/events/before-input-events-different-start-end-elements-expected.txt +27 lines
Line 0 a/LayoutTests/fast/events/before-input-events-different-start-end-elements-expected.txt_sec1
1
PASS successfullyParsed is true
2
3
TEST COMPLETE
4
Fired `onbeforeinput` handler!
5
Fired `oninput` handler!
6
Fired `onbeforeinput` handler!
7
Fired `oninput` handler!
8
Fired `onbeforeinput` handler!
9
Fired `oninput` handler!
10
Fired `onbeforeinput` handler!
11
Fired `oninput` handler!
12
Fired `onbeforeinput` handler!
13
Fired `oninput` handler!
14
Fired `onbeforeinput` handler!
15
Fired `oninput` handler!
16
Fired `onbeforeinput` handler!
17
Fired `oninput` handler!
18
Fired `onbeforeinput` handler!
19
Fired `oninput` handler!
20
Fired `onbeforeinput` handler!
21
Fired `oninput` handler!
22
Fired `onbeforeinput` handler!
23
Fired `oninput` handler!
24
Fired `onbeforeinput` handler!
25
Fired `oninput` handler!
26
27
- a/LayoutTests/fast/events/before-input-events-different-start-end-elements.html +43 lines
Line 0 a/LayoutTests/fast/events/before-input-events-different-start-end-elements.html_sec1
1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2
<html>
3
4
<head>
5
    <script src="../../resources/js-test-pre.js"></script>
6
    <script>
7
        function beginTest()
8
        {
9
            if (!window.eventSender || !window.internals || !window.testRunner)
10
                return;
11
12
            internals.settings.setInputEventsEnabled(true);
13
            testRunner.dumpAsText();
14
            document.querySelector("#foo").focus();
15
16
            for (var i = 0; i < 11; i++)
17
                eventSender.keyDown("delete");
18
        }
19
20
        function checkInputEvent(event)
21
        {
22
            debug("Fired `oninput` handler!");
23
        }
24
25
        function checkBeforeInputEvent(event)
26
        {
27
            debug("Fired `onbeforeinput` handler!");
28
        }
29
    </script>
30
</head>
31
32
<body onload=beginTest()>
33
    <div id="foo" contenteditable oninput=checkInputEvent(event) onbeforeinput=checkBeforeInputEvent(event)>
34
        <b>
35
            abc
36
            <i>def</i>
37
            <u>ghi</u>
38
        </b>
39
    </div>
40
    <script src="../../resources/js-test-post.js"></script>
41
</body>
42
43
</html>
- a/LayoutTests/fast/events/before-input-events-prevent-default-expected.txt +5 lines
Line 0 a/LayoutTests/fast/events/before-input-events-prevent-default-expected.txt_sec1
1
PASS successfullyParsed is true
2
3
TEST COMPLETE
4
Fired `onbeforeinput`: preventing default!
5
- a/LayoutTests/fast/events/before-input-events-prevent-default-in-textfield-expected.txt +6 lines
Line 0 a/LayoutTests/fast/events/before-input-events-prevent-default-in-textfield-expected.txt_sec1
1
PASS successfullyParsed is true
2
3
TEST COMPLETE
4
Fired `onbeforeinput`: preventing default!
5
The final value is: abc
6
- a/LayoutTests/fast/events/before-input-events-prevent-default-in-textfield.html +50 lines
Line 0 a/LayoutTests/fast/events/before-input-events-prevent-default-in-textfield.html_sec1
1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2
<html>
3
4
<head>
5
    <script src="../../resources/js-test-pre.js"></script>
6
    <script>
7
        var preventDefaultInputEvents = false;
8
9
        function beginTest()
10
        {
11
            if (!window.eventSender || !window.internals || !window.testRunner)
12
                return;
13
14
            internals.settings.setInputEventsEnabled(true);
15
            testRunner.dumpAsText();
16
            let input = document.querySelector("#foo");
17
            input.focus();
18
19
            eventSender.keyDown("a", []);
20
            eventSender.keyDown("b", []);
21
            eventSender.keyDown("c", []);
22
23
            preventDefaultInputEvents = true;
24
25
            eventSender.keyDown("delete");
26
            debug(`The final value is: ${input.value}`);
27
        }
28
29
        function checkInputEvent(event)
30
        {
31
            if (preventDefaultInputEvents)
32
                debug("FAIL: Did not expect to the `oninput` handler to fire.");
33
        }
34
35
        function checkBeforeInputEvent(event)
36
        {
37
            if (preventDefaultInputEvents) {
38
                debug("Fired `onbeforeinput`: preventing default!");
39
                event.preventDefault();
40
            }
41
        }
42
    </script>
43
</head>
44
45
<body onload=beginTest()>
46
    <input id="foo" contenteditable value="helloworld" oninput=checkInputEvent(event) onbeforeinput=checkBeforeInputEvent(event)></div>
47
    <script src="../../resources/js-test-post.js"></script>
48
</body>
49
50
</html>
- a/LayoutTests/fast/events/before-input-events-prevent-default.html +36 lines
Line 0 a/LayoutTests/fast/events/before-input-events-prevent-default.html_sec1
1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2
<html>
3
4
<head>
5
    <script src="../../resources/js-test-pre.js"></script>
6
    <script>
7
        function beginTest()
8
        {
9
            if (!window.eventSender || !window.internals || !window.testRunner)
10
                return;
11
12
            internals.settings.setInputEventsEnabled(true);
13
            testRunner.dumpAsText();
14
            document.querySelector("#foo").focus();
15
            eventSender.keyDown("a", []);
16
        }
17
18
        function checkInputEvent(event)
19
        {
20
            debug("FAIL: Did not expect to the `oninput` handler to fire.");
21
        }
22
23
        function checkBeforeInputEvent(event)
24
        {
25
            debug("Fired `onbeforeinput`: preventing default!");
26
            event.preventDefault();
27
        }
28
    </script>
29
</head>
30
31
<body onload=beginTest()>
32
    <div id="foo" contenteditable oninput=checkInputEvent(event) onbeforeinput=checkBeforeInputEvent(event)></div>
33
    <script src="../../resources/js-test-post.js"></script>
34
</body>
35
36
</html>
- a/LayoutTests/fast/events/input-events-fired-when-typing-expected.txt +16 lines
Lines 1-12 a/LayoutTests/fast/events/input-events-fired-when-typing-expected.txt_sec1
1
PASS successfullyParsed is true
1
PASS successfullyParsed is true
2
2
3
TEST COMPLETE
3
TEST COMPLETE
4
Fired `onbeforeinput`!
5
PASS event.__lookupGetter__('inputType') is defined.
6
PASS Object.getPrototypeOf(event) is InputEvent.prototype
7
PASS event.target.id is expectedTargetID
8
PASS event.bubbles is true
9
PASS event.cancelable is true
10
PASS event.composed is true
11
Fired `oninput`!
4
PASS event.__lookupGetter__('inputType') is defined.
12
PASS event.__lookupGetter__('inputType') is defined.
5
PASS Object.getPrototypeOf(event) is InputEvent.prototype
13
PASS Object.getPrototypeOf(event) is InputEvent.prototype
6
PASS event.target.id is expectedTargetID
14
PASS event.target.id is expectedTargetID
7
PASS event.bubbles is true
15
PASS event.bubbles is true
8
PASS event.cancelable is false
16
PASS event.cancelable is false
9
PASS event.composed is true
17
PASS event.composed is true
18
Fired `onbeforeinput`!
19
PASS event.__lookupGetter__('inputType') is defined.
20
PASS Object.getPrototypeOf(event) is InputEvent.prototype
21
PASS event.target.id is expectedTargetID
22
PASS event.bubbles is true
23
PASS event.cancelable is true
24
PASS event.composed is true
25
Fired `oninput`!
10
PASS event.__lookupGetter__('inputType') is defined.
26
PASS event.__lookupGetter__('inputType') is defined.
11
PASS Object.getPrototypeOf(event) is InputEvent.prototype
27
PASS Object.getPrototypeOf(event) is InputEvent.prototype
12
PASS event.target.id is expectedTargetID
28
PASS event.target.id is expectedTargetID
- a/LayoutTests/fast/events/input-events-fired-when-typing.html -2 / +14 lines
Lines 33-38 a/LayoutTests/fast/events/input-events-fired-when-typing.html_sec1
33
33
34
        function checkInputEvent(event)
34
        function checkInputEvent(event)
35
        {
35
        {
36
            debug("Fired `oninput`!");
36
            shouldBeDefined("event.__lookupGetter__('inputType')");
37
            shouldBeDefined("event.__lookupGetter__('inputType')");
37
            shouldBe("Object.getPrototypeOf(event)", "InputEvent.prototype");
38
            shouldBe("Object.getPrototypeOf(event)", "InputEvent.prototype");
38
            shouldBe("event.target.id", "expectedTargetID");
39
            shouldBe("event.target.id", "expectedTargetID");
Lines 40-51 a/LayoutTests/fast/events/input-events-fired-when-typing.html_sec2
40
            shouldBe("event.cancelable", "false");
41
            shouldBe("event.cancelable", "false");
41
            shouldBe("event.composed", "true");
42
            shouldBe("event.composed", "true");
42
        }
43
        }
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
        }
43
    </script>
55
    </script>
44
</head>
56
</head>
45
57
46
<body onload=beginTest()>
58
<body onload=beginTest()>
47
    <div id="foo" contenteditable oninput=checkInputEvent(event)></div>
59
    <div id="foo" contenteditable oninput=checkInputEvent(event) onbeforeinput=checkBeforeInputEvent(event)></div>
48
    <input id="bar" oninput=checkInputEvent(event)></input>
60
    <input id="bar" oninput=checkInputEvent(event) onbeforeinput=checkBeforeInputEvent(event)></input>
49
    <script src="../../resources/js-test-post.js"></script>
61
    <script src="../../resources/js-test-post.js"></script>
50
</body>
62
</body>
51
63
- a/LayoutTests/platform/ios-simulator/TestExpectations +2 lines
Lines 1198-1203 fast/events/frame-tab-focus.html [ Failure ] a/LayoutTests/platform/ios-simulator/TestExpectations_sec1
1198
fast/events/ime-composition-events-001.html [ Failure ]
1198
fast/events/ime-composition-events-001.html [ Failure ]
1199
fast/events/inputText-never-fired-on-keydown-cancel.html [ Failure ]
1199
fast/events/inputText-never-fired-on-keydown-cancel.html [ Failure ]
1200
fast/events/input-events-fired-when-typing.html [ Failure ]
1200
fast/events/input-events-fired-when-typing.html [ Failure ]
1201
fast/events/before-input-events-prevent-default.html [ Failure ]
1202
fast/events/before-input-events-prevent-default-in-textfield.html [ Failure ]
1201
fast/events/key-events-in-input-button.html [ Failure ]
1203
fast/events/key-events-in-input-button.html [ Failure ]
1202
fast/events/keydown-1.html [ Failure ]
1204
fast/events/keydown-1.html [ Failure ]
1203
fast/events/keydown-leftright-keys.html [ Failure ]
1205
fast/events/keydown-leftright-keys.html [ Failure ]

Return to Bug 163021