Source/WebCore/ChangeLog

112016-10-07 Wenson Hsieh <wenson_hsieh@apple.com>
22
 3 Support InputEvent.inputType for the new InputEvent spec
 4 https://bugs.webkit.org/show_bug.cgi?id=163025
 5 <rdar://problem/28658092>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Adds support for the inputType attribute of InputEvent. To do this, we introduce a helper to
 10 map EditActions to inputType names, and also split out ambiguous EditActions (such as
 11 EditActionTyping) into more specific subtypes (such as EditActionTypingDeleteBackward,
 12 EditActionTypingInsertParagraph, etc.), each of which corresponds to an inputType.
 13
 14 In places where we create CompositeEditCommands, we now pass in these specific EditActions
 15 where appropriate, and when dispatching `beforeinput` and `input` events, we ask the
 16 CompositeEditCommand for its input type name, which it derives from its editingAction.
 17
 18 Lastly, adds an Internals test helper that layout tests may use to directly invoke commands on
 19 the current document's Editor.
 20
 21 Tests: fast/events/before-input-prevent-biu.html
 22 fast/events/before-input-prevent-cut.html
 23 fast/events/before-input-prevent-paste.html
 24 fast/events/before-input-prevent-undo.html
 25
 26 * dom/Node.cpp:
 27 (WebCore::Node::dispatchBeforeInputEvent):
 28 (WebCore::Node::dispatchInputEvent):
 29 * editing/CompositeEditCommand.cpp:
 30 (WebCore::CompositeEditCommand::apply):
 31 (WebCore::CompositeEditCommand::inputEventTypeName):
 32
 33 Allows a CompositeEditCommand to specify the inputType its corresponding `beforeinput` and `input` events
 34 should have.
 35
 36 * editing/CompositeEditCommand.h:
 37 (WebCore::CompositeEditCommand::shouldStopCaretBlinking): Deleted.
 38 * editing/EditAction.h:
 39 * editing/EditCommand.cpp:
 40 (WebCore::inputTypeNameForEditingAction):
 41 * editing/EditCommand.h:
 42 * editing/Editor.cpp:
 43 (WebCore::Editor::willApplyEditing):
 44 (WebCore::Editor::appliedEditing):
 45 (WebCore::Editor::willUnapplyEditing):
 46 (WebCore::Editor::unappliedEditing):
 47 (WebCore::Editor::willReapplyEditing):
 48 (WebCore::Editor::reappliedEditing):
 49 (WebCore::Editor::computeAndSetTypingStyle):
 50 * editing/InsertListCommand.cpp:
 51 (WebCore::InsertListCommand::editingAction):
 52 * editing/InsertListCommand.h:
 53 (WebCore::InsertListCommand::preservesTypingStyle): Deleted.
 54 (WebCore::InsertListCommand::editingAction): Deleted.
 55 * editing/ReplaceRangeWithTextCommand.cpp:
 56 (WebCore::ReplaceRangeWithTextCommand::ReplaceRangeWithTextCommand):
 57 * editing/SpellingCorrectionCommand.cpp:
 58 (WebCore::SpellingCorrectionCommand::SpellingCorrectionCommand):
 59 * editing/TypingCommand.cpp:
 60 (WebCore::editActionForTypingCommand):
 61 (WebCore::TypingCommand::TypingCommand):
 62 (WebCore::TypingCommand::inputEventTypeName):
 63
 64 The editingAction() of a TypingCommand is the first editing action the TypingCommand was initialized using.
 65 Since subsequent typing commands update the last open typing command, we override inputEventTypeName here to
 66 use the last updated editing action rather than the default (initial) editing action.
 67
 68 (WebCore::TypingCommand::willAddTypingToOpenCommand):
 69 (WebCore::TypingCommand::insertTextRunWithoutNewlines):
 70 (WebCore::TypingCommand::insertParagraphSeparator):
 71 * editing/TypingCommand.h:
 72 * testing/Internals.cpp:
 73 (WebCore::Internals::executeEditingCommand):
 74
 75 Adds a new hook that allows layout tests to execute arbitrary editing commands. This effectively ignores user
 76 gesture restrictions on operations like cut and paste.
 77
 78 * testing/Internals.h:
 79 * testing/Internals.idl:
 80
 812016-10-07 Wenson Hsieh <wenson_hsieh@apple.com>
 82
383 Support onbeforeinput event handling for the new InputEvent spec
484 https://bugs.webkit.org/show_bug.cgi?id=163021
585 <rdar://problem/28658073>

Source/WebKit/mac/ChangeLog

 12016-10-07 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 Support InputEvent.inputType for the new InputEvent spec
 4 https://bugs.webkit.org/show_bug.cgi?id=163025
 5 <rdar://problem/28658092>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Accounts for some changes to the EditAction enum in nameForEditAction. See WebCore ChangeLog
 10 entry for more details.
 11
 12 * WebCoreSupport/WebEditorClient.mm:
 13 (undoNameForEditAction):
 14
1152016-10-07 Simon Fraser <simon.fraser@apple.com>
216
317 [WK1 Mac] Fix repaints of fixed-background elements in layer-backed WebViews

Source/WebKit/win/ChangeLog

 12016-10-07 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 Support InputEvent.inputType for the new InputEvent spec
 4 https://bugs.webkit.org/show_bug.cgi?id=163025
 5 <rdar://problem/28658092>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Accounts for some changes to the EditAction enum in nameForEditAction. See WebCore ChangeLog
 10 entry for more details.
 11
 12 * WebCoreSupport/WebEditorClient.cpp:
 13 (undoNameForEditAction):
 14
1152016-10-04 Brent Fulgham <bfulgham@apple.com>
216
317 [Win][Direct2D] Connect WebCore/WebKit Drawing

Source/WebKit2/ChangeLog

 12016-10-07 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 Support InputEvent.inputType for the new InputEvent spec
 4 https://bugs.webkit.org/show_bug.cgi?id=163025
 5 <rdar://problem/28658092>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Accounts for some changes to the EditAction enum in nameForEditAction. Some former edit
 10 actions, such as EditActionTyping, have been split out into its more specific subtypes,
 11 so we preserve shipping behavior by treating all of the new subtypes the same way as the
 12 original type.
 13
 14 * UIProcess/WebEditCommandProxy.cpp:
 15 (WebKit::WebEditCommandProxy::nameForEditAction):
 16
1172016-10-07 Anders Carlsson <andersca@apple.com>
218
319 Get rid of API::Session and WKSessionRef

Source/WebCore/editing/CompositeEditCommand.cpp

@@void CompositeEditCommand::apply()
326326{
327327 if (!endingSelection().isContentRichlyEditable()) {
328328 switch (editingAction()) {
329  case EditActionTyping:
 329 case EditActionTypingDeleteSelection:
 330 case EditActionTypingDeleteBackward:
 331 case EditActionTypingDeleteForward:
 332 case EditActionTypingDeleteWordBackward:
 333 case EditActionTypingDeleteWordForward:
 334 case EditActionTypingDeleteLineBackward:
 335 case EditActionTypingDeleteLineForward:
 336 case EditActionTypingInsertText:
 337 case EditActionTypingInsertLineBreak:
 338 case EditActionTypingInsertParagraph:
330339 case EditActionPaste:
331340 case EditActionDrag:
332341 case EditActionSetWritingDirection:
333342 case EditActionCut:
334343 case EditActionUnspecified:
335344 case EditActionInsert:
 345 case EditActionInsertReplacement:
336346 case EditActionDelete:
337347 case EditActionDictation:
338348 break;

@@void CompositeEditCommand::setShouldRetainAutocorrectionIndicator(bool)
399409{
400410}
401411
 412AtomicString CompositeEditCommand::inputEventTypeName() const
 413{
 414 return inputTypeNameForEditingAction(editingAction());
 415}
 416
402417//
403418// sugary-sweet convenience functions to help create and apply edit commands in composite commands
404419//

Source/WebCore/editing/CompositeEditCommand.h

@@public:
113113 virtual bool shouldRetainAutocorrectionIndicator() const;
114114 virtual void setShouldRetainAutocorrectionIndicator(bool);
115115 virtual bool shouldStopCaretBlinking() const { return false; }
 116 virtual AtomicString inputEventTypeName() const;
116117
117118protected:
118119 explicit CompositeEditCommand(Document&, EditAction = EditActionUnspecified);

Source/WebCore/editing/EditAction.h

@@namespace WebCore {
3030 typedef enum {
3131 EditActionUnspecified,
3232 EditActionInsert,
 33 EditActionInsertReplacement,
3334 EditActionSetColor,
3435 EditActionSetBackgroundColor,
3536 EditActionTurnOffKerning,

@@namespace WebCore {
6364 EditActionPaste,
6465 EditActionPasteFont,
6566 EditActionPasteRuler,
66  EditActionTyping,
 67 EditActionTypingDeleteSelection,
 68 EditActionTypingDeleteBackward,
 69 EditActionTypingDeleteForward,
 70 EditActionTypingDeleteWordBackward,
 71 EditActionTypingDeleteWordForward,
 72 EditActionTypingDeleteLineBackward,
 73 EditActionTypingDeleteLineForward,
 74 EditActionTypingInsertText,
 75 EditActionTypingInsertLineBreak,
 76 EditActionTypingInsertParagraph,
6777 EditActionCreateLink,
6878 EditActionUnlink,
6979 EditActionFormatBlock,
70  EditActionInsertList,
 80 EditActionInsertOrderedList,
 81 EditActionInsertUnorderedList,
7182 EditActionIndent,
7283 EditActionOutdent
7384 } EditAction;

Source/WebCore/editing/EditCommand.cpp

3838
3939namespace WebCore {
4040
 41AtomicString inputTypeNameForEditingAction(EditAction action)
 42{
 43 switch (action) {
 44 case EditActionJustify:
 45 case EditActionAlignLeft:
 46 return "formatJustifyLeft";
 47 case EditActionAlignRight:
 48 return "formatJustifyRight";
 49 case EditActionCenter:
 50 return "formatJustifyCenter";
 51 case EditActionSubscript:
 52 return "formatSubscript";
 53 case EditActionSuperscript:
 54 return "formatSuperscript";
 55 case EditActionUnderline:
 56 return "formatUnderline";
 57 case EditActionDrag:
 58 return "deleteByDrag";
 59 case EditActionCut:
 60 return "deleteByCut";
 61 case EditActionBold:
 62 return "formatBold";
 63 case EditActionItalics:
 64 return "formatItalic";
 65 case EditActionPaste:
 66 return "insertFromPaste";
 67 case EditActionDelete:
 68 case EditActionTypingDeleteSelection:
 69 return "deleteContent";
 70 case EditActionTypingDeleteBackward:
 71 return "deleteContentBackward";
 72 case EditActionTypingDeleteForward:
 73 return "deleteContentForward";
 74 case EditActionTypingDeleteWordBackward:
 75 return "deleteWordBackward";
 76 case EditActionTypingDeleteWordForward:
 77 return "deleteWordForward";
 78 case EditActionTypingDeleteLineBackward:
 79 return "deleteHardLineBackward";
 80 case EditActionTypingDeleteLineForward:
 81 return "deleteHardLineForward";
 82 case EditActionInsert:
 83 case EditActionTypingInsertText:
 84 return "insertText";
 85 case EditActionInsertReplacement:
 86 return "insertReplacementText";
 87 case EditActionTypingInsertLineBreak:
 88 return "insertLineBreak";
 89 case EditActionTypingInsertParagraph:
 90 return "insertParagraph";
 91 case EditActionInsertOrderedList:
 92 return "insertOrderedList";
 93 case EditActionInsertUnorderedList:
 94 return "insertUnorderedList";
 95 case EditActionIndent:
 96 return "formatIndent";
 97 case EditActionOutdent:
 98 return "formatOutdent";
 99 default:
 100 return emptyString();
 101 }
 102}
 103
41104EditCommand::EditCommand(Document& document, EditAction editingAction)
42105 : m_document(document)
43106 , m_editingAction(editingAction)

Source/WebCore/editing/EditCommand.h

@@class Document;
4141class Element;
4242class Frame;
4343
 44AtomicString inputTypeNameForEditingAction(EditAction);
 45
4446class EditCommand : public RefCounted<EditCommand> {
4547public:
4648 virtual ~EditCommand();
4749
4850 void setParent(CompositeEditCommand*);
4951
50  EditAction editingAction() const;
 52 virtual EditAction editingAction() const;
5153
5254 const VisibleSelection& startingSelection() const { return m_startingSelection; }
5355 const VisibleSelection& endingSelection() const { return m_endingSelection; }

Source/WebCore/editing/Editor.cpp

@@bool Editor::willApplyEditing(CompositeEditCommand& command) const
10631063 if (!composition)
10641064 return true;
10651065
1066  return dispatchBeforeInputEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement(), emptyString());
 1066 return dispatchBeforeInputEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement(), command.inputEventTypeName());
10671067}
10681068
10691069void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd)

@@void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd)
10821082 FrameSelection::SetSelectionOptions options = cmd->isDictationCommand() ? FrameSelection::DictationTriggered : 0;
10831083
10841084 changeSelectionAfterCommand(newSelection, options);
1085  dispatchInputEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement(), emptyString());
 1085 dispatchInputEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement(), cmd->inputEventTypeName());
10861086
10871087 updateEditorUINowIfScheduled();
10881088

@@void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd)
11071107
11081108bool Editor::willUnapplyEditing(const EditCommandComposition& composition) const
11091109{
1110  return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), emptyString());
 1110 return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), "historyUndo");
11111111}
11121112
11131113void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd)

@@void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd)
11181118
11191119 VisibleSelection newSelection(cmd->startingSelection());
11201120 changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
1121  dispatchInputEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), emptyString());
 1121 dispatchInputEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), "historyUndo");
11221122
11231123 updateEditorUINowIfScheduled();
11241124

@@void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd)
11321132
11331133bool Editor::willReapplyEditing(const EditCommandComposition& composition) const
11341134{
1135  return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), emptyString());
 1135 return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), "historyRedo");
11361136}
11371137
11381138void Editor::reappliedEditing(PassRefPtr<EditCommandComposition> cmd)

@@void Editor::reappliedEditing(PassRefPtr<EditCommandComposition> cmd)
11431143
11441144 VisibleSelection newSelection(cmd->endingSelection());
11451145 changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
1146  dispatchInputEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), emptyString());
 1146 dispatchInputEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), "historyRedo");
11471147
11481148 updateEditorUINowIfScheduled();
11491149

@@void Editor::computeAndSetTypingStyle(EditingStyle& style, EditAction editingAct
30933093 return;
30943094 }
30953095
 3096 AtomicString inputTypeName = inputTypeNameForEditingAction(editingAction);
30963097 auto* element = m_frame.selection().selection().rootEditableElement();
3097  if (element && !dispatchBeforeInputEvent(*element, emptyString()))
 3098 if (element && !dispatchBeforeInputEvent(*element, inputTypeName))
30983099 return;
30993100
31003101 // Calculate the current typing style.

@@void Editor::computeAndSetTypingStyle(EditingStyle& style, EditAction editingAct
31113112 applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
31123113
31133114 if (element)
3114  element->dispatchInputEvent(emptyString());
 3115 element->dispatchInputEvent(inputTypeName);
31153116
31163117 // Set the remaining style as the typing style.
31173118 m_frame.selection().setTypingStyle(typingStyle);

Source/WebCore/editing/InsertListCommand.cpp

@@void InsertListCommand::doApply()
193193 doApplyForSingleParagraph(false, listTag, endingSelection().firstRange().get());
194194}
195195
 196EditAction InsertListCommand::editingAction() const
 197{
 198 return m_type == OrderedList ? EditActionInsertOrderedList : EditActionInsertUnorderedList;
 199}
 200
196201void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const HTMLQualifiedName& listTag, Range* currentSelection)
197202{
198203 // FIXME: This will produce unexpected results for a selection that starts just before a

Source/WebCore/editing/InsertListCommand.h

@@namespace WebCore {
3333class HTMLElement;
3434class HTMLQualifiedName;
3535
36 class InsertListCommand : public CompositeEditCommand {
 36class InsertListCommand final : public CompositeEditCommand {
3737public:
3838 enum Type { OrderedList, UnorderedList };
3939

@@public:
4444
4545 static RefPtr<HTMLElement> insertList(Document&, Type);
4646
47  virtual bool preservesTypingStyle() const { return true; }
 47 bool preservesTypingStyle() const { return true; }
4848
4949private:
5050 InsertListCommand(Document&, Type);
5151
52  virtual void doApply();
53  virtual EditAction editingAction() const { return EditActionInsertList; }
 52 void doApply();
 53 EditAction editingAction() const;
5454
5555 HTMLElement* fixOrphanedListChild(Node*);
5656 bool selectionHasListOfType(const VisibleSelection& selection, const QualifiedName&);

Source/WebCore/editing/ReplaceRangeWithTextCommand.cpp

3939namespace WebCore {
4040
4141ReplaceRangeWithTextCommand::ReplaceRangeWithTextCommand(RefPtr<Range> rangeToBeReplaced, const String& text)
42  : CompositeEditCommand(rangeToBeReplaced->startContainer().document())
 42 : CompositeEditCommand(rangeToBeReplaced->startContainer().document(), EditActionInsertReplacement)
4343 , m_rangeToBeReplaced(rangeToBeReplaced)
4444 , m_text(text)
4545{

Source/WebCore/editing/SpellingCorrectionCommand.cpp

@@private:
8282#endif
8383
8484SpellingCorrectionCommand::SpellingCorrectionCommand(PassRefPtr<Range> rangeToBeCorrected, const String& correction)
85  : CompositeEditCommand(rangeToBeCorrected->startContainer().document())
 85 : CompositeEditCommand(rangeToBeCorrected->startContainer().document(), EditActionInsertReplacement)
8686 , m_rangeToBeCorrected(rangeToBeCorrected)
8787 , m_selectionToBeCorrected(*m_rangeToBeCorrected)
8888 , m_correction(correction)

Source/WebCore/editing/TypingCommand.cpp

@@private:
7676 const String& m_text;
7777};
7878
 79static inline EditAction editActionForTypingCommand(TypingCommand::ETypingCommand command, TextGranularity granularity)
 80{
 81 switch (command) {
 82 case TypingCommand::DeleteSelection:
 83 return EditActionTypingDeleteSelection;
 84 case TypingCommand::DeleteKey: {
 85 if (granularity == WordGranularity)
 86 return EditActionTypingDeleteWordBackward;
 87 if (granularity == LineBoundary)
 88 return EditActionTypingDeleteLineBackward;
 89 return EditActionTypingDeleteBackward;
 90 }
 91 case TypingCommand::ForwardDeleteKey:
 92 if (granularity == WordGranularity)
 93 return EditActionTypingDeleteWordForward;
 94 if (granularity == LineBoundary)
 95 return EditActionTypingDeleteLineForward;
 96 return EditActionTypingDeleteForward;
 97 case TypingCommand::InsertText:
 98 return EditActionTypingInsertText;
 99 case TypingCommand::InsertLineBreak:
 100 return EditActionTypingInsertLineBreak;
 101 case TypingCommand::InsertParagraphSeparator:
 102 case TypingCommand::InsertParagraphSeparatorInQuotedContent:
 103 return EditActionTypingInsertParagraph;
 104 default:
 105 return EditActionUnspecified;
 106 }
 107}
 108
79109TypingCommand::TypingCommand(Document& document, ETypingCommand commandType, const String &textToInsert, Options options, TextGranularity granularity, TextCompositionType compositionType)
80  : TextInsertionBaseCommand(document, EditActionTyping)
 110 : TextInsertionBaseCommand(document, editActionForTypingCommand(commandType, granularity))
81111 , m_commandType(commandType)
82112 , m_textToInsert(textToInsert)
83113 , m_openForMoreTyping(true)

@@TypingCommand::TypingCommand(Document& document, ETypingCommand commandType, con
90120 , m_shouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator)
91121 , m_shouldPreventSpellChecking(options & PreventSpellChecking)
92122{
 123 m_currentTypingEditAction = editingAction();
93124 updatePreservesTypingStyle(m_commandType);
94125}
95126

@@void TypingCommand::doApply()
308339 ASSERT_NOT_REACHED();
309340}
310341
 342AtomicString TypingCommand::inputEventTypeName() const
 343{
 344 return inputTypeNameForEditingAction(m_currentTypingEditAction);
 345}
 346
311347void TypingCommand::didApplyCommand()
312348{
313349 // TypingCommands handle applied editing separately (see TypingCommand::typingAddedToOpenCommand).

@@void TypingCommand::markMisspellingsAfterTyping(ETypingCommand commandType)
368404 }
369405}
370406
371 bool TypingCommand::willAddTypingToOpenCommand(ETypingCommand, TextGranularity)
 407bool TypingCommand::willAddTypingToOpenCommand(ETypingCommand commandType, TextGranularity granularity)
372408{
373409 if (m_isHandlingInitialTypingCommand)
374410 return true;
375411
376412 // FIXME: Use the newly added typing command and granularity to ensure that an InputEvent with the
377413 // correct inputType is dispatched.
 414 m_currentTypingEditAction = editActionForTypingCommand(commandType, granularity);
378415 return frame().editor().willApplyEditing(*this);
379416}
380417

@@void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool select
423460 return;
424461
425462 RefPtr<InsertTextCommand> command = InsertTextCommand::create(document(), text, selectInsertedText,
426  m_compositionType == TextCompositionNone ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces : InsertTextCommand::RebalanceAllWhitespaces, EditActionTyping);
 463 m_compositionType == TextCompositionNone ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces : InsertTextCommand::RebalanceAllWhitespaces, EditActionTypingInsertText);
427464
428465 applyCommandToComposite(command, endingSelection());
429466

@@void TypingCommand::insertParagraphSeparator()
458495 if (!willAddTypingToOpenCommand(InsertParagraphSeparator, ParagraphGranularity))
459496 return;
460497
461  applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(), false, false, EditActionTyping));
 498 applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(), false, false, EditActionTypingInsertParagraph));
462499 typingAddedToOpenCommand(InsertParagraphSeparator);
463500}
464501

Source/WebCore/editing/TypingCommand.h

@@private:
116116 bool shouldStopCaretBlinking() const { return true; }
117117 void setShouldPreventSpellChecking(bool prevent) { m_shouldPreventSpellChecking = prevent; }
118118
 119 AtomicString inputEventTypeName() const;
 120
119121 static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
120122
121123 void updatePreservesTypingStyle(ETypingCommand);

@@private:
134136 void didApplyCommand();
135137
136138 ETypingCommand m_commandType;
 139 EditAction m_currentTypingEditAction;
137140 String m_textToInsert;
138141 bool m_openForMoreTyping;
139142 bool m_selectInsertedText;

Source/WebCore/testing/Internals.cpp

@@void Internals::setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection use
33733373 page->setUserInterfaceLayoutDirection(userInterfaceLayoutDirection == UserInterfaceLayoutDirection::LTR ? WebCore::UserInterfaceLayoutDirection::LTR : WebCore::UserInterfaceLayoutDirection::RTL);
33743374}
33753375
 3376void Internals::executeEditingCommand(const String& commandName) const
 3377{
 3378 if (auto* document = contextDocument()) {
 3379 if (Frame* frame = document->frame())
 3380 frame->editor().command(commandName).execute();
 3381 }
 3382}
 3383
33763384} // namespace WebCore

Source/WebCore/testing/Internals.h

@@public:
495495 enum class UserInterfaceLayoutDirection { LTR, RTL };
496496 void setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection);
497497
 498 void executeEditingCommand(const String& commandName) const;
 499
498500private:
499501 explicit Internals(Document&);
500502 Document* contextDocument() const;

Source/WebCore/testing/Internals.idl

@@enum UserInterfaceLayoutDirection {
466466 GCObservation observeGC(any observed);
467467
468468 void setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection userInterfaceLayoutDirection);
 469
 470 void executeEditingCommand(DOMString commandName);
469471};

Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm

@@static NSString* undoNameForEditAction(EditAction editAction)
563563 switch (editAction) {
564564 case EditActionUnspecified: return nil;
565565 case EditActionInsert: return nil;
 566 case EditActionInsertReplacement: return nil;
566567 case EditActionSetColor: return UI_STRING_KEY_INTERNAL("Set Color", "Set Color (Undo action name)", "Undo action name");
567568 case EditActionSetBackgroundColor: return UI_STRING_KEY_INTERNAL("Set Background Color", "Set Background Color (Undo action name)", "Undo action name");
568569 case EditActionTurnOffKerning: return UI_STRING_KEY_INTERNAL("Turn Off Kerning", "Turn Off Kerning (Undo action name)", "Undo action name");

@@static NSString* undoNameForEditAction(EditAction editAction)
592593 case EditActionPaste: return UI_STRING_KEY_INTERNAL("Paste", "Paste (Undo action name)", "Undo action name");
593594 case EditActionPasteFont: return UI_STRING_KEY_INTERNAL("Paste Font", "Paste Font (Undo action name)", "Undo action name");
594595 case EditActionPasteRuler: return UI_STRING_KEY_INTERNAL("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name");
595  case EditActionTyping: return UI_STRING_KEY_INTERNAL("Typing", "Typing (Undo action name)", "Undo action name");
 596 case EditActionTypingDeleteSelection:
 597 case EditActionTypingDeleteBackward:
 598 case EditActionTypingDeleteForward:
 599 case EditActionTypingDeleteWordBackward:
 600 case EditActionTypingDeleteWordForward:
 601 case EditActionTypingDeleteLineBackward:
 602 case EditActionTypingDeleteLineForward:
 603 case EditActionTypingInsertText:
 604 case EditActionTypingInsertLineBreak:
 605 case EditActionTypingInsertParagraph:
 606 return UI_STRING_KEY_INTERNAL("Typing", "Typing (Undo action name)", "Undo action name");
596607 case EditActionCreateLink: return UI_STRING_KEY_INTERNAL("Create Link", "Create Link (Undo action name)", "Undo action name");
597608 case EditActionUnlink: return UI_STRING_KEY_INTERNAL("Unlink", "Unlink (Undo action name)", "Undo action name");
598  case EditActionInsertList: return UI_STRING_KEY_INTERNAL("Insert List", "Insert List (Undo action name)", "Undo action name");
 609 case EditActionInsertOrderedList:
 610 case EditActionInsertUnorderedList:
 611 return UI_STRING_KEY_INTERNAL("Insert List", "Insert List (Undo action name)", "Undo action name");
599612 case EditActionFormatBlock: return UI_STRING_KEY_INTERNAL("Formatting", "Format Block (Undo action name)", "Undo action name");
600613 case EditActionIndent: return UI_STRING_KEY_INTERNAL("Indent", "Indent (Undo action name)", "Undo action name");
601614 case EditActionOutdent: return UI_STRING_KEY_INTERNAL("Outdent", "Outdent (Undo action name)", "Undo action name");

Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp

@@ULONG WebEditorUndoCommand::Release()
563563static String undoNameForEditAction(EditAction editAction)
564564{
565565 switch (editAction) {
566  case EditActionUnspecified: return String();
 566 case EditActionUnspecified:
 567 case EditActionInsertReplacement:
 568 return String();
567569 case EditActionSetColor: return WEB_UI_STRING_KEY("Set Color", "Set Color (Undo action name)", "Undo action name");
568570 case EditActionSetBackgroundColor: return WEB_UI_STRING_KEY("Set Background Color", "Set Background Color (Undo action name)", "Undo action name");
569571 case EditActionTurnOffKerning: return WEB_UI_STRING_KEY("Turn Off Kerning", "Turn Off Kerning (Undo action name)", "Undo action name");

@@static String undoNameForEditAction(EditAction editAction)
595597 case EditActionPaste: return WEB_UI_STRING_KEY("Paste", "Paste (Undo action name)", "Undo action name");
596598 case EditActionPasteFont: return WEB_UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name");
597599 case EditActionPasteRuler: return WEB_UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name");
598  case EditActionTyping: return WEB_UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name");
 600 case EditActionTypingDeleteSelection:
 601 case EditActionTypingDeleteBackward:
 602 case EditActionTypingDeleteForward:
 603 case EditActionTypingDeleteWordBackward:
 604 case EditActionTypingDeleteWordForward:
 605 case EditActionTypingDeleteLineBackward:
 606 case EditActionTypingDeleteLineForward:
 607 case EditActionTypingInsertText:
 608 case EditActionTypingInsertLineBreak:
 609 case EditActionTypingInsertParagraph:
 610 return WEB_UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name");
599611 case EditActionCreateLink: return WEB_UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name");
600612 case EditActionUnlink: return WEB_UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name");
601  case EditActionInsertList: return WEB_UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name");
 613 case EditActionInsertUnorderedList:
 614 case EditActionInsertOrderedList:
 615 return WEB_UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name");
602616 case EditActionFormatBlock: return WEB_UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name");
603617 case EditActionIndent: return WEB_UI_STRING_KEY("Indent", "Indent (Undo action name)", "Undo action name");
604618 case EditActionOutdent: return WEB_UI_STRING_KEY("Outdent", "Outdent (Undo action name)", "Undo action name");

Source/WebKit2/UIProcess/WebEditCommandProxy.cpp

@@String WebEditCommandProxy::nameForEditAction(EditAction editAction)
7676 return String();
7777 case EditActionInsert:
7878 return String();
 79 case EditActionInsertReplacement:
 80 return String();
7981 case EditActionSetColor:
8082 return WEB_UI_STRING_KEY("Set Color", "Set Color (Undo action name)", "Undo action name");
8183 case EditActionSetBackgroundColor:

@@String WebEditCommandProxy::nameForEditAction(EditAction editAction)
142144 return WEB_UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name");
143145 case EditActionPasteRuler:
144146 return WEB_UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name");
145  case EditActionTyping:
 147 case EditActionTypingDeleteSelection:
 148 case EditActionTypingDeleteBackward:
 149 case EditActionTypingDeleteForward:
 150 case EditActionTypingDeleteWordBackward:
 151 case EditActionTypingDeleteWordForward:
 152 case EditActionTypingDeleteLineBackward:
 153 case EditActionTypingDeleteLineForward:
 154 case EditActionTypingInsertText:
 155 case EditActionTypingInsertLineBreak:
 156 case EditActionTypingInsertParagraph:
146157 return WEB_UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name");
147158 case EditActionCreateLink:
148159 return WEB_UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name");
149160 case EditActionUnlink:
150161 return WEB_UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name");
151  case EditActionInsertList:
 162 case EditActionInsertUnorderedList:
 163 case EditActionInsertOrderedList:
152164 return WEB_UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name");
153165 case EditActionFormatBlock:
154166 return WEB_UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name");

LayoutTests/ChangeLog

112016-10-07 Wenson Hsieh <wenson_hsieh@apple.com>
22
 3 Support InputEvent.inputType for the new InputEvent spec
 4 https://bugs.webkit.org/show_bug.cgi?id=163025
 5 <rdar://problem/28658092>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Adds new layout tests to check that various actions, such as cutting, pasting and undoing can
 10 be prevented via the InputEvent fired in a `beforechange` handler.
 11
 12 * fast/events/before-input-prevent-biu-expected.txt: Added.
 13 * fast/events/before-input-prevent-biu.html: Added.
 14 * fast/events/before-input-prevent-cut-expected.txt: Added.
 15 * fast/events/before-input-prevent-cut.html: Added.
 16 * fast/events/before-input-prevent-paste-expected.txt: Added.
 17 * fast/events/before-input-prevent-paste.html: Added.
 18 * fast/events/before-input-prevent-undo-expected.txt: Added.
 19 * fast/events/before-input-prevent-undo.html: Added.
 20 * platform/ios-simulator/TestExpectations:
 21
 222016-10-07 Wenson Hsieh <wenson_hsieh@apple.com>
 23
324 Unreviewed, mark a test as failing on iOS simulator
425
526 This was intended to be a part of r206944.

LayoutTests/fast/events/before-input-prevent-biu-expected.txt

 1PASS successfullyParsed is true
 2
 3TEST COMPLETE
 4PASS firstChild.tagName is undefined.
 5PASS firstChild.textContent is 'abc'
 6PASS secondChild.tagName is 'I'
 7PASS secondChild.textContent is 'def'
 8PASS secondChild.children[0].tagName is 'U'
 9abcdef

LayoutTests/fast/events/before-input-prevent-biu.html

 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 let editable = document.querySelector("#foo");
 10 editable.focus();
 11
 12 if (!window.eventSender || !window.internals || !window.testRunner)
 13 return;
 14
 15 internals.settings.setInputEventsEnabled(true);
 16 testRunner.dumpAsText();
 17
 18 eventSender.keyDown("a", []);
 19 eventSender.keyDown("b", []);
 20 eventSender.keyDown("c", []);
 21
 22 internals.executeEditingCommand("ToggleBold");
 23 internals.executeEditingCommand("ToggleItalic");
 24 internals.executeEditingCommand("ToggleUnderline");
 25
 26 eventSender.keyDown("d", []);
 27 eventSender.keyDown("e", []);
 28 eventSender.keyDown("f", []);
 29
 30 window.firstChild = editable.childNodes[0];
 31 window.secondChild = editable.childNodes[1];
 32 shouldBeUndefined("firstChild.tagName");
 33 shouldBe("firstChild.textContent", "'abc'");
 34 shouldBe("secondChild.tagName", "'I'");
 35 shouldBe("secondChild.textContent", "'def'");
 36 shouldBe("secondChild.children[0].tagName", "'U'");
 37 }
 38
 39 function handleBeforeInput(event)
 40 {
 41 if (event.inputType === "formatBold")
 42 event.preventDefault();
 43 }
 44 </script>
 45</head>
 46
 47<body onload=beginTest()>
 48 <div id="foo" contenteditable onbeforeinput=handleBeforeInput(event)></div>
 49 <script src="../../resources/js-test-post.js"></script>
 50</body>
 51
 52</html>

LayoutTests/fast/events/before-input-prevent-cut-expected.txt

 1PASS successfullyParsed is true
 2
 3TEST COMPLETE
 4Initial value: "helloworld"
 5After the prevented cut: "helloworld"
 6After the actual cut: ""
 7

LayoutTests/fast/events/before-input-prevent-cut.html

 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 preventCut = true;
 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 document.querySelector("input").focus();
 17 }
 18
 19 function handleBeforeInput(event)
 20 {
 21 if (preventCut)
 22 event.preventDefault();
 23 }
 24
 25 function handleFocus()
 26 {
 27 let input = document.querySelector("input");
 28 input.select();
 29 if (!window.internals)
 30 return;
 31
 32 debug(`Initial value: "${input.value}"`);
 33
 34 internals.executeEditingCommand("Cut");
 35 debug(`After the prevented cut: "${input.value}"`);
 36
 37 preventCut = false;
 38 internals.executeEditingCommand("Cut");
 39 debug(`After the actual cut: "${input.value}"`);
 40 }
 41 </script>
 42</head>
 43
 44<body onload=beginTest()>
 45 <input onfocus=handleFocus() value="helloworld" onbeforeinput=handleBeforeInput(event)></div>
 46 <script src="../../resources/js-test-post.js"></script>
 47</body>
 48
 49</html>

LayoutTests/fast/events/before-input-prevent-paste-expected.txt

 1PASS successfullyParsed is true
 2
 3TEST COMPLETE
 4Initial value: "helloworld"
 5After the cut: ""
 6After the prevented paste: ""
 7After the actual paste: "helloworld"
 8

LayoutTests/fast/events/before-input-prevent-paste.html

 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 preventPaste = true;
 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 document.querySelector("input").focus();
 17 }
 18
 19 function handleBeforeInput(event)
 20 {
 21 if (preventPaste && event.inputType !== "deleteByCut")
 22 event.preventDefault();
 23 }
 24
 25 function handleFocus()
 26 {
 27 let input = document.querySelector("input");
 28 input.select();
 29 if (!window.internals)
 30 return;
 31
 32 debug(`Initial value: "${input.value}"`);
 33
 34 internals.executeEditingCommand("Cut");
 35 debug(`After the cut: "${input.value}"`);
 36
 37 internals.executeEditingCommand("Paste");
 38 debug(`After the prevented paste: "${input.value}"`);
 39
 40 preventPaste = false;
 41 internals.executeEditingCommand("Paste");
 42 debug(`After the actual paste: "${input.value}"`);
 43 }
 44 </script>
 45</head>
 46
 47<body onload=beginTest()>
 48 <input onfocus=handleFocus() value="helloworld" onbeforeinput=handleBeforeInput(event)></div>
 49 <script src="../../resources/js-test-post.js"></script>
 50</body>
 51
 52</html>

LayoutTests/fast/events/before-input-prevent-undo-expected.txt

 1PASS successfullyParsed is true
 2
 3TEST COMPLETE
 4Initial value:
 5PASS editable.value is 'abc'
 6After the prevented undo:
 7PASS editable.value is 'abc'
 8

LayoutTests/fast/events/before-input-prevent-undo.html

 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 window.editable = document.querySelector("#foo");
 10 editable.focus();
 11
 12 if (!window.eventSender || !window.internals || !window.testRunner)
 13 return;
 14
 15 testRunner.dumpAsText();
 16 internals.settings.setInputEventsEnabled(true);
 17
 18 eventSender.keyDown("a", []);
 19 eventSender.keyDown("b", []);
 20 eventSender.keyDown("c", []);
 21
 22 debug("Initial value:");
 23 shouldBe("editable.value", "'abc'");
 24
 25 internals.executeEditingCommand("Undo");
 26 debug("After the prevented undo:");
 27 shouldBe("editable.value", "'abc'");
 28 }
 29
 30 function handleBeforeInput(event)
 31 {
 32 if (event.inputType === "historyUndo")
 33 event.preventDefault();
 34 }
 35 </script>
 36</head>
 37
 38<body onload=beginTest()>
 39 <input id="foo" onbeforeinput=handleBeforeInput(event)></input>
 40 <script src="../../resources/js-test-post.js"></script>
 41</body>
 42
 43</html>

LayoutTests/platform/ios-simulator/TestExpectations

@@fast/events/input-events-fired-when-typing.html [ Failure ]
12011201fast/events/before-input-events-prevent-default.html [ Failure ]
12021202fast/events/before-input-events-prevent-default-in-textfield.html [ Failure ]
12031203fast/events/before-input-events-different-start-end-elements.html [ Failure ]
 1204fast/events/before-input-prevent-biu.html [ Failure ]
 1205fast/events/before-input-prevent-cut.html [ Failure ]
 1206fast/events/before-input-prevent-paste.html [ Failure ]
 1207fast/events/before-input-prevent-undo.html [ Failure ]
12041208fast/events/key-events-in-input-button.html [ Failure ]
12051209fast/events/keydown-1.html [ Failure ]
12061210fast/events/keydown-leftright-keys.html [ Failure ]