Chromium Code Reviews| 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 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 876 static void dispatchEditableContentChangedEvents(Element* startRoot, | 876 static void dispatchEditableContentChangedEvents(Element* startRoot, |
| 877 Element* endRoot) { | 877 Element* endRoot) { |
| 878 if (startRoot) | 878 if (startRoot) |
| 879 startRoot->dispatchEvent( | 879 startRoot->dispatchEvent( |
| 880 Event::create(EventTypeNames::webkitEditableContentChanged)); | 880 Event::create(EventTypeNames::webkitEditableContentChanged)); |
| 881 if (endRoot && endRoot != startRoot) | 881 if (endRoot && endRoot != startRoot) |
| 882 endRoot->dispatchEvent( | 882 endRoot->dispatchEvent( |
| 883 Event::create(EventTypeNames::webkitEditableContentChanged)); | 883 Event::create(EventTypeNames::webkitEditableContentChanged)); |
| 884 } | 884 } |
| 885 | 885 |
| 886 static VisibleSelection correctedVisibleSelection( | 886 static SelectionInDOMTree correctedSelectionAfterCommand( |
| 887 const VisibleSelection& passedSelection) { | 887 const VisibleSelection& passedSelection, |
|
yoichio
2017/03/21 06:41:57
Could you use SelectionINDOMTree& passedSelection
Xiaocheng
2017/03/21 20:53:39
It doesn't seem to introduce any benefit, since Ed
yoichio
2017/03/22 01:48:57
Yes, no benefit from a view of semantics.
However,
Xiaocheng
2017/03/22 02:12:44
Sorry, I just realized that we can't change it in
| |
| 888 Document* document) { | |
| 888 if (!passedSelection.base().isConnected() || | 889 if (!passedSelection.base().isConnected() || |
| 889 !passedSelection.extent().isConnected()) | 890 !passedSelection.extent().isConnected() || |
| 890 return VisibleSelection(); | 891 passedSelection.base().document() != document || |
| 891 DCHECK(!passedSelection.base().document()->needsLayoutTreeUpdate()); | 892 passedSelection.base().document() != passedSelection.extent().document()) |
| 892 return createVisibleSelection(passedSelection.asSelection()); | 893 return SelectionInDOMTree(); |
| 894 return passedSelection.asSelection(); | |
| 893 } | 895 } |
| 894 | 896 |
| 895 void Editor::appliedEditing(CompositeEditCommand* cmd) { | 897 void Editor::appliedEditing(CompositeEditCommand* cmd) { |
| 896 DCHECK(!cmd->isCommandGroupWrapper()); | 898 DCHECK(!cmd->isCommandGroupWrapper()); |
| 897 EventQueueScope scope; | 899 EventQueueScope scope; |
| 898 | 900 |
| 899 // Request spell checking before any further DOM change. | 901 // Request spell checking before any further DOM change. |
| 900 spellChecker().markMisspellingsAfterApplyingCommand(*cmd); | 902 spellChecker().markMisspellingsAfterApplyingCommand(*cmd); |
| 901 | 903 |
| 902 UndoStep* undoStep = cmd->undoStep(); | 904 UndoStep* undoStep = cmd->undoStep(); |
| 903 DCHECK(undoStep); | 905 DCHECK(undoStep); |
| 904 dispatchEditableContentChangedEvents(undoStep->startingRootEditableElement(), | 906 dispatchEditableContentChangedEvents(undoStep->startingRootEditableElement(), |
| 905 undoStep->endingRootEditableElement()); | 907 undoStep->endingRootEditableElement()); |
| 906 // TODO(chongz): Filter empty InputType after spec is finalized. | 908 // TODO(chongz): Filter empty InputType after spec is finalized. |
| 907 dispatchInputEventEditableContentChanged( | 909 dispatchInputEventEditableContentChanged( |
| 908 undoStep->startingRootEditableElement(), | 910 undoStep->startingRootEditableElement(), |
| 909 undoStep->endingRootEditableElement(), cmd->inputType(), | 911 undoStep->endingRootEditableElement(), cmd->inputType(), |
| 910 cmd->textDataForInputEvent(), isComposingFromCommand(cmd)); | 912 cmd->textDataForInputEvent(), isComposingFromCommand(cmd)); |
| 911 | 913 |
| 912 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 914 const SelectionInDOMTree& newSelection = correctedSelectionAfterCommand( |
| 913 // needs to be audited. See http://crbug.com/590369 for more details. | 915 cmd->endingSelection(), frame().document()); |
| 914 // The clean layout is consumed by |mostBackwardCaretPosition|, called through | |
| 915 // |changeSelectionAfterCommand|. In the long term, we should postpone visible | |
| 916 // selection canonicalization so that selection update does not need layout. | |
| 917 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 918 | |
| 919 const VisibleSelection& newSelection = | |
| 920 correctedVisibleSelection(cmd->endingSelection()); | |
| 921 | 916 |
| 922 // Don't clear the typing style with this selection change. We do those things | 917 // Don't clear the typing style with this selection change. We do those things |
| 923 // elsewhere if necessary. | 918 // elsewhere if necessary. |
| 924 changeSelectionAfterCommand(newSelection.asSelection(), 0); | 919 changeSelectionAfterCommand(newSelection, 0); |
| 925 | 920 |
| 926 if (!cmd->preservesTypingStyle()) | 921 if (!cmd->preservesTypingStyle()) |
| 927 clearTypingStyle(); | 922 clearTypingStyle(); |
| 928 | 923 |
| 929 // Command will be equal to last edit command only in the case of typing | 924 // Command will be equal to last edit command only in the case of typing |
| 930 if (m_lastEditCommand.get() == cmd) { | 925 if (m_lastEditCommand.get() == cmd) { |
| 931 DCHECK(cmd->isTypingCommand()); | 926 DCHECK(cmd->isTypingCommand()); |
| 932 } else if (m_lastEditCommand && m_lastEditCommand->isDragAndDropCommand() && | 927 } else if (m_lastEditCommand && m_lastEditCommand->isDragAndDropCommand() && |
| 933 (cmd->inputType() == InputEvent::InputType::DeleteByDrag || | 928 (cmd->inputType() == InputEvent::InputType::DeleteByDrag || |
| 934 cmd->inputType() == InputEvent::InputType::InsertFromDrop)) { | 929 cmd->inputType() == InputEvent::InputType::InsertFromDrop)) { |
| 935 // Only register undo entry when combined with other commands. | 930 // Only register undo entry when combined with other commands. |
| 936 if (!m_lastEditCommand->undoStep()) | 931 if (!m_lastEditCommand->undoStep()) |
| 937 m_undoStack->registerUndoStep(m_lastEditCommand->ensureUndoStep()); | 932 m_undoStack->registerUndoStep(m_lastEditCommand->ensureUndoStep()); |
| 938 m_lastEditCommand->appendCommandToUndoStep(cmd); | 933 m_lastEditCommand->appendCommandToUndoStep(cmd); |
| 939 } else { | 934 } else { |
| 940 // Only register a new undo command if the command passed in is | 935 // Only register a new undo command if the command passed in is |
| 941 // different from the last command | 936 // different from the last command |
| 942 m_lastEditCommand = cmd; | 937 m_lastEditCommand = cmd; |
| 943 m_undoStack->registerUndoStep(m_lastEditCommand->ensureUndoStep()); | 938 m_undoStack->registerUndoStep(m_lastEditCommand->ensureUndoStep()); |
| 944 } | 939 } |
| 945 | 940 |
| 946 respondToChangedContents(newSelection.start()); | 941 respondToChangedContents(newSelection.base()); |
| 947 } | 942 } |
| 948 | 943 |
| 949 void Editor::unappliedEditing(UndoStep* cmd) { | 944 void Editor::unappliedEditing(UndoStep* cmd) { |
| 950 EventQueueScope scope; | 945 EventQueueScope scope; |
| 951 | 946 |
| 952 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), | 947 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), |
| 953 cmd->endingRootEditableElement()); | 948 cmd->endingRootEditableElement()); |
| 954 dispatchInputEventEditableContentChanged( | 949 dispatchInputEventEditableContentChanged( |
| 955 cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), | 950 cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), |
| 956 InputEvent::InputType::HistoryUndo, nullAtom, | 951 InputEvent::InputType::HistoryUndo, nullAtom, |
| 957 InputEvent::EventIsComposing::NotComposing); | 952 InputEvent::EventIsComposing::NotComposing); |
| 958 | 953 |
| 959 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 954 const SelectionInDOMTree& newSelection = correctedSelectionAfterCommand( |
| 960 // needs to be audited. See http://crbug.com/590369 for more details. | 955 cmd->startingSelection(), frame().document()); |
| 961 // In the long term, we should stop editing commands from storing | |
| 962 // VisibleSelections as starting and ending selections. | |
| 963 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 964 | |
| 965 const VisibleSelection& newSelection = | |
| 966 correctedVisibleSelection(cmd->startingSelection()); | |
| 967 DCHECK(newSelection.isValidFor(*frame().document())) << newSelection; | |
| 968 changeSelectionAfterCommand( | 956 changeSelectionAfterCommand( |
| 969 newSelection.asSelection(), | 957 newSelection, |
| 970 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); | 958 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); |
| 971 | 959 |
| 972 m_lastEditCommand = nullptr; | 960 m_lastEditCommand = nullptr; |
| 973 m_undoStack->registerRedoStep(cmd); | 961 m_undoStack->registerRedoStep(cmd); |
| 974 respondToChangedContents(newSelection.start()); | 962 respondToChangedContents(newSelection.base()); |
| 975 } | 963 } |
| 976 | 964 |
| 977 void Editor::reappliedEditing(UndoStep* cmd) { | 965 void Editor::reappliedEditing(UndoStep* cmd) { |
| 978 EventQueueScope scope; | 966 EventQueueScope scope; |
| 979 | 967 |
| 980 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), | 968 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), |
| 981 cmd->endingRootEditableElement()); | 969 cmd->endingRootEditableElement()); |
| 982 dispatchInputEventEditableContentChanged( | 970 dispatchInputEventEditableContentChanged( |
| 983 cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), | 971 cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), |
| 984 InputEvent::InputType::HistoryRedo, nullAtom, | 972 InputEvent::InputType::HistoryRedo, nullAtom, |
| 985 InputEvent::EventIsComposing::NotComposing); | 973 InputEvent::EventIsComposing::NotComposing); |
| 986 | 974 |
| 987 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 975 const SelectionInDOMTree& newSelection = correctedSelectionAfterCommand( |
| 988 // needs to be audited. See http://crbug.com/590369 for more details. | 976 cmd->endingSelection(), frame().document()); |
| 989 // In the long term, we should stop editing commands from storing | |
| 990 // VisibleSelections as starting and ending selections. | |
| 991 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 992 const VisibleSelection& newSelection = | |
| 993 correctedVisibleSelection(cmd->endingSelection()); | |
| 994 DCHECK(newSelection.isValidFor(*frame().document())) << newSelection; | |
| 995 changeSelectionAfterCommand( | 977 changeSelectionAfterCommand( |
| 996 newSelection.asSelection(), | 978 newSelection, |
| 997 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); | 979 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); |
| 998 | 980 |
| 999 m_lastEditCommand = nullptr; | 981 m_lastEditCommand = nullptr; |
| 1000 m_undoStack->registerUndoStep(cmd); | 982 m_undoStack->registerUndoStep(cmd); |
| 1001 respondToChangedContents(newSelection.start()); | 983 respondToChangedContents(newSelection.base()); |
| 1002 } | 984 } |
| 1003 | 985 |
| 1004 Editor* Editor::create(LocalFrame& frame) { | 986 Editor* Editor::create(LocalFrame& frame) { |
| 1005 return new Editor(frame); | 987 return new Editor(frame); |
| 1006 } | 988 } |
| 1007 | 989 |
| 1008 Editor::Editor(LocalFrame& frame) | 990 Editor::Editor(LocalFrame& frame) |
| 1009 : m_frame(&frame), | 991 : m_frame(&frame), |
| 1010 m_undoStack(UndoStack::create()), | 992 m_undoStack(UndoStack::create()), |
| 1011 m_preventRevealSelection(0), | 993 m_preventRevealSelection(0), |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1795 | 1777 |
| 1796 DEFINE_TRACE(Editor) { | 1778 DEFINE_TRACE(Editor) { |
| 1797 visitor->trace(m_frame); | 1779 visitor->trace(m_frame); |
| 1798 visitor->trace(m_lastEditCommand); | 1780 visitor->trace(m_lastEditCommand); |
| 1799 visitor->trace(m_undoStack); | 1781 visitor->trace(m_undoStack); |
| 1800 visitor->trace(m_mark); | 1782 visitor->trace(m_mark); |
| 1801 visitor->trace(m_typingStyle); | 1783 visitor->trace(m_typingStyle); |
| 1802 } | 1784 } |
| 1803 | 1785 |
| 1804 } // namespace blink | 1786 } // namespace blink |
| OLD | NEW |