| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 #include "platform/weborigin/KURL.h" | 89 #include "platform/weborigin/KURL.h" |
| 90 #include "wtf/PtrUtil.h" | 90 #include "wtf/PtrUtil.h" |
| 91 #include "wtf/text/CharacterNames.h" | 91 #include "wtf/text/CharacterNames.h" |
| 92 | 92 |
| 93 namespace blink { | 93 namespace blink { |
| 94 | 94 |
| 95 using namespace HTMLNames; | 95 using namespace HTMLNames; |
| 96 using namespace WTF; | 96 using namespace WTF; |
| 97 using namespace Unicode; | 97 using namespace Unicode; |
| 98 | 98 |
| 99 namespace { |
| 100 |
| 101 void dispatchInputEvent(Element* target, InputEvent::InputType inputType, const
String& data, InputEvent::EventIsComposing isComposing) |
| 102 { |
| 103 if (!RuntimeEnabledFeatures::inputEventEnabled()) |
| 104 return; |
| 105 if (!target) |
| 106 return; |
| 107 // TODO(chongz): Pass appreciate |ranges| after it's defined on spec. |
| 108 // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype |
| 109 InputEvent* inputEvent = InputEvent::createInput(inputType, data, isComposin
g, nullptr); |
| 110 target->dispatchScopedEvent(inputEvent); |
| 111 } |
| 112 |
| 113 void dispatchInputEventEditableContentChanged(Element* startRoot, Element* endRo
ot, InputEvent::InputType inputType, const String& data, InputEvent::EventIsComp
osing isComposing) |
| 114 { |
| 115 if (startRoot) |
| 116 dispatchInputEvent(startRoot, inputType, data, isComposing); |
| 117 if (endRoot && endRoot != startRoot) |
| 118 dispatchInputEvent(endRoot, inputType, data, isComposing); |
| 119 } |
| 120 |
| 121 InputEvent::InputType inputTypeFromCommand(const CompositeEditCommand* command) |
| 122 { |
| 123 if (command->isTypingCommand()) { |
| 124 const TypingCommand* typingCommand = toTypingCommand(command); |
| 125 // TODO(chongz): Separate command types into more detailed InputType. |
| 126 switch (typingCommand->commandTypeOfOpenCommand()) { |
| 127 case TypingCommand::DeleteSelection: |
| 128 case TypingCommand::DeleteKey: |
| 129 case TypingCommand::ForwardDeleteKey: |
| 130 return InputEvent::InputType::DeleteContent; |
| 131 case TypingCommand::InsertText: |
| 132 case TypingCommand::InsertLineBreak: |
| 133 case TypingCommand::InsertParagraphSeparator: |
| 134 case TypingCommand::InsertParagraphSeparatorInQuotedContent: |
| 135 return InputEvent::InputType::InsertText; |
| 136 default: |
| 137 return InputEvent::InputType::None; |
| 138 } |
| 139 } |
| 140 |
| 141 // TODO(chongz): Handle other edit actions. |
| 142 return InputEvent::InputType::None; |
| 143 } |
| 144 |
| 145 InputEvent::EventIsComposing isComposingFromCommand(const CompositeEditCommand*
command) |
| 146 { |
| 147 if (command->isTypingCommand() && toTypingCommand(command)->compositionType(
) != TypingCommand::TextCompositionNone) |
| 148 return InputEvent::EventIsComposing::IsComposing; |
| 149 return InputEvent::EventIsComposing::NotComposing; |
| 150 } |
| 151 |
| 152 } // anonymous namespace |
| 153 |
| 99 Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor) | 154 Editor::RevealSelectionScope::RevealSelectionScope(Editor* editor) |
| 100 : m_editor(editor) | 155 : m_editor(editor) |
| 101 { | 156 { |
| 102 ++m_editor->m_preventRevealSelection; | 157 ++m_editor->m_preventRevealSelection; |
| 103 } | 158 } |
| 104 | 159 |
| 105 Editor::RevealSelectionScope::~RevealSelectionScope() | 160 Editor::RevealSelectionScope::~RevealSelectionScope() |
| 106 { | 161 { |
| 107 DCHECK(m_editor->m_preventRevealSelection); | 162 DCHECK(m_editor->m_preventRevealSelection); |
| 108 --m_editor->m_preventRevealSelection; | 163 --m_editor->m_preventRevealSelection; |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 { | 750 { |
| 696 EventQueueScope scope; | 751 EventQueueScope scope; |
| 697 frame().document()->updateStyleAndLayout(); | 752 frame().document()->updateStyleAndLayout(); |
| 698 | 753 |
| 699 // Request spell checking after pasting before any further DOM change. | 754 // Request spell checking after pasting before any further DOM change. |
| 700 requestSpellcheckingAfterApplyingCommand(cmd); | 755 requestSpellcheckingAfterApplyingCommand(cmd); |
| 701 | 756 |
| 702 EditCommandComposition* composition = cmd->composition(); | 757 EditCommandComposition* composition = cmd->composition(); |
| 703 DCHECK(composition); | 758 DCHECK(composition); |
| 704 dispatchEditableContentChangedEvents(composition->startingRootEditableElemen
t(), composition->endingRootEditableElement()); | 759 dispatchEditableContentChangedEvents(composition->startingRootEditableElemen
t(), composition->endingRootEditableElement()); |
| 760 // TODO(chongz): Filter empty InputType after spec is finalized. |
| 761 // TODO(chongz): Fill in |data| field. |
| 762 dispatchInputEventEditableContentChanged(composition->startingRootEditableEl
ement(), composition->endingRootEditableElement(), inputTypeFromCommand(cmd), em
ptyString(), isComposingFromCommand(cmd)); |
| 705 VisibleSelection newSelection(cmd->endingSelection()); | 763 VisibleSelection newSelection(cmd->endingSelection()); |
| 706 | 764 |
| 707 // Don't clear the typing style with this selection change. We do those thin
gs elsewhere if necessary. | 765 // Don't clear the typing style with this selection change. We do those thin
gs elsewhere if necessary. |
| 708 changeSelectionAfterCommand(newSelection, 0); | 766 changeSelectionAfterCommand(newSelection, 0); |
| 709 | 767 |
| 710 if (!cmd->preservesTypingStyle()) | 768 if (!cmd->preservesTypingStyle()) |
| 711 frame().selection().clearTypingStyle(); | 769 frame().selection().clearTypingStyle(); |
| 712 | 770 |
| 713 // Command will be equal to last edit command only in the case of typing | 771 // Command will be equal to last edit command only in the case of typing |
| 714 if (m_lastEditCommand.get() == cmd) { | 772 if (m_lastEditCommand.get() == cmd) { |
| 715 DCHECK(cmd->isTypingCommand()); | 773 DCHECK(cmd->isTypingCommand()); |
| 716 } else { | 774 } else { |
| 717 // Only register a new undo command if the command passed in is | 775 // Only register a new undo command if the command passed in is |
| 718 // different from the last command | 776 // different from the last command |
| 719 m_lastEditCommand = cmd; | 777 m_lastEditCommand = cmd; |
| 720 if (UndoStack* undoStack = this->undoStack()) | 778 if (UndoStack* undoStack = this->undoStack()) |
| 721 undoStack->registerUndoStep(m_lastEditCommand->ensureComposition()); | 779 undoStack->registerUndoStep(m_lastEditCommand->ensureComposition()); |
| 722 } | 780 } |
| 723 | 781 |
| 724 respondToChangedContents(newSelection); | 782 respondToChangedContents(newSelection); |
| 725 } | 783 } |
| 726 | 784 |
| 727 void Editor::unappliedEditing(EditCommandComposition* cmd) | 785 void Editor::unappliedEditing(EditCommandComposition* cmd) |
| 728 { | 786 { |
| 729 EventQueueScope scope; | 787 EventQueueScope scope; |
| 730 frame().document()->updateStyleAndLayout(); | 788 frame().document()->updateStyleAndLayout(); |
| 731 | 789 |
| 732 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd
->endingRootEditableElement()); | 790 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd
->endingRootEditableElement()); |
| 791 dispatchInputEventEditableContentChanged(cmd->startingRootEditableElement(),
cmd->endingRootEditableElement(), InputEvent::InputType::Undo, emptyString(), I
nputEvent::EventIsComposing::NotComposing); |
| 733 | 792 |
| 734 VisibleSelection newSelection(cmd->startingSelection()); | 793 VisibleSelection newSelection(cmd->startingSelection()); |
| 735 newSelection.validatePositionsIfNeeded(); | 794 newSelection.validatePositionsIfNeeded(); |
| 736 if (newSelection.start().document() == frame().document() && newSelection.en
d().document() == frame().document()) | 795 if (newSelection.start().document() == frame().document() && newSelection.en
d().document() == frame().document()) |
| 737 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping |
FrameSelection::ClearTypingStyle); | 796 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping |
FrameSelection::ClearTypingStyle); |
| 738 | 797 |
| 739 m_lastEditCommand = nullptr; | 798 m_lastEditCommand = nullptr; |
| 740 if (UndoStack* undoStack = this->undoStack()) | 799 if (UndoStack* undoStack = this->undoStack()) |
| 741 undoStack->registerRedoStep(cmd); | 800 undoStack->registerRedoStep(cmd); |
| 742 respondToChangedContents(newSelection); | 801 respondToChangedContents(newSelection); |
| 743 } | 802 } |
| 744 | 803 |
| 745 void Editor::reappliedEditing(EditCommandComposition* cmd) | 804 void Editor::reappliedEditing(EditCommandComposition* cmd) |
| 746 { | 805 { |
| 747 EventQueueScope scope; | 806 EventQueueScope scope; |
| 748 frame().document()->updateStyleAndLayout(); | 807 frame().document()->updateStyleAndLayout(); |
| 749 | 808 |
| 750 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd
->endingRootEditableElement()); | 809 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd
->endingRootEditableElement()); |
| 810 dispatchInputEventEditableContentChanged(cmd->startingRootEditableElement(),
cmd->endingRootEditableElement(), InputEvent::InputType::Redo, emptyString(), I
nputEvent::EventIsComposing::NotComposing); |
| 751 | 811 |
| 752 VisibleSelection newSelection(cmd->endingSelection()); | 812 VisibleSelection newSelection(cmd->endingSelection()); |
| 753 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | Fram
eSelection::ClearTypingStyle); | 813 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | Fram
eSelection::ClearTypingStyle); |
| 754 | 814 |
| 755 m_lastEditCommand = nullptr; | 815 m_lastEditCommand = nullptr; |
| 756 if (UndoStack* undoStack = this->undoStack()) | 816 if (UndoStack* undoStack = this->undoStack()) |
| 757 undoStack->registerUndoStep(cmd); | 817 undoStack->registerUndoStep(cmd); |
| 758 respondToChangedContents(newSelection); | 818 respondToChangedContents(newSelection); |
| 759 } | 819 } |
| 760 | 820 |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1370 } | 1430 } |
| 1371 | 1431 |
| 1372 DEFINE_TRACE(Editor) | 1432 DEFINE_TRACE(Editor) |
| 1373 { | 1433 { |
| 1374 visitor->trace(m_frame); | 1434 visitor->trace(m_frame); |
| 1375 visitor->trace(m_lastEditCommand); | 1435 visitor->trace(m_lastEditCommand); |
| 1376 visitor->trace(m_mark); | 1436 visitor->trace(m_mark); |
| 1377 } | 1437 } |
| 1378 | 1438 |
| 1379 } // namespace blink | 1439 } // namespace blink |
| OLD | NEW |