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 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 static void dispatchEditableContentChangedEvents(Element* startRoot, | 859 static void dispatchEditableContentChangedEvents(Element* startRoot, |
| 860 Element* endRoot) { | 860 Element* endRoot) { |
| 861 if (startRoot) | 861 if (startRoot) |
| 862 startRoot->dispatchEvent( | 862 startRoot->dispatchEvent( |
| 863 Event::create(EventTypeNames::webkitEditableContentChanged)); | 863 Event::create(EventTypeNames::webkitEditableContentChanged)); |
| 864 if (endRoot && endRoot != startRoot) | 864 if (endRoot && endRoot != startRoot) |
| 865 endRoot->dispatchEvent( | 865 endRoot->dispatchEvent( |
| 866 Event::create(EventTypeNames::webkitEditableContentChanged)); | 866 Event::create(EventTypeNames::webkitEditableContentChanged)); |
| 867 } | 867 } |
| 868 | 868 |
| 869 static VisibleSelection correctedVisibleSelection( | |
|
yosin_UTC9
2017/03/01 01:20:39
It seems you need to rebase. Patch[1] did this cha
Xiaocheng
2017/03/01 01:41:23
No need to rebase.
This patch removes this functi
yosin_UTC9
2017/03/01 01:44:01
Oops. I see.
| |
| 870 const VisibleSelection& passedSelection) { | |
| 871 if (!passedSelection.base().isConnected() || | |
| 872 !passedSelection.extent().isConnected()) | |
| 873 return VisibleSelection(); | |
| 874 DCHECK(!passedSelection.base().document()->needsLayoutTreeUpdate()); | |
| 875 return createVisibleSelection(passedSelection.asSelection()); | |
| 876 } | |
| 877 | |
| 869 void Editor::appliedEditing(CompositeEditCommand* cmd) { | 878 void Editor::appliedEditing(CompositeEditCommand* cmd) { |
| 870 DCHECK(!cmd->isCommandGroupWrapper()); | 879 DCHECK(!cmd->isCommandGroupWrapper()); |
| 871 EventQueueScope scope; | 880 EventQueueScope scope; |
| 872 | 881 |
| 873 // Request spell checking before any further DOM change. | 882 // Request spell checking before any further DOM change. |
| 874 spellChecker().markMisspellingsAfterApplyingCommand(*cmd); | 883 spellChecker().markMisspellingsAfterApplyingCommand(*cmd); |
| 875 | 884 |
| 876 UndoStep* undoStep = cmd->undoStep(); | 885 UndoStep* undoStep = cmd->undoStep(); |
| 877 DCHECK(undoStep); | 886 DCHECK(undoStep); |
| 878 dispatchEditableContentChangedEvents(undoStep->startingRootEditableElement(), | 887 dispatchEditableContentChangedEvents(undoStep->startingRootEditableElement(), |
| 879 undoStep->endingRootEditableElement()); | 888 undoStep->endingRootEditableElement()); |
| 880 // TODO(chongz): Filter empty InputType after spec is finalized. | 889 // TODO(chongz): Filter empty InputType after spec is finalized. |
| 881 dispatchInputEventEditableContentChanged( | 890 dispatchInputEventEditableContentChanged( |
| 882 undoStep->startingRootEditableElement(), | 891 undoStep->startingRootEditableElement(), |
| 883 undoStep->endingRootEditableElement(), cmd->inputType(), | 892 undoStep->endingRootEditableElement(), cmd->inputType(), |
| 884 cmd->textDataForInputEvent(), isComposingFromCommand(cmd)); | 893 cmd->textDataForInputEvent(), isComposingFromCommand(cmd)); |
| 885 | 894 |
| 886 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 895 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 887 // needs to be audited. See http://crbug.com/590369 for more details. | 896 // needs to be audited. See http://crbug.com/590369 for more details. |
| 888 // The clean layout is consumed by |mostBackwardCaretPosition|, called through | 897 // The clean layout is consumed by |mostBackwardCaretPosition|, called through |
| 889 // |changeSelectionAfterCommand|. In the long term, we should postpone visible | 898 // |changeSelectionAfterCommand|. In the long term, we should postpone visible |
| 890 // selection canonicalization so that selection update does not need layout. | 899 // selection canonicalization so that selection update does not need layout. |
| 891 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 900 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 892 | 901 |
| 893 VisibleSelection newSelection(cmd->endingSelection()); | 902 const VisibleSelection& newSelection = |
| 903 correctedVisibleSelection(cmd->endingSelection()); | |
| 894 | 904 |
| 895 // Don't clear the typing style with this selection change. We do those things | 905 // Don't clear the typing style with this selection change. We do those things |
| 896 // elsewhere if necessary. | 906 // elsewhere if necessary. |
| 897 changeSelectionAfterCommand(newSelection, 0); | 907 changeSelectionAfterCommand(newSelection.asSelection(), 0); |
| 898 | 908 |
| 899 if (!cmd->preservesTypingStyle()) | 909 if (!cmd->preservesTypingStyle()) |
| 900 clearTypingStyle(); | 910 clearTypingStyle(); |
| 901 | 911 |
| 902 // Command will be equal to last edit command only in the case of typing | 912 // Command will be equal to last edit command only in the case of typing |
| 903 if (m_lastEditCommand.get() == cmd) { | 913 if (m_lastEditCommand.get() == cmd) { |
| 904 DCHECK(cmd->isTypingCommand()); | 914 DCHECK(cmd->isTypingCommand()); |
| 905 } else if (m_lastEditCommand && m_lastEditCommand->isDragAndDropCommand() && | 915 } else if (m_lastEditCommand && m_lastEditCommand->isDragAndDropCommand() && |
| 906 (cmd->inputType() == InputEvent::InputType::DeleteByDrag || | 916 (cmd->inputType() == InputEvent::InputType::DeleteByDrag || |
| 907 cmd->inputType() == InputEvent::InputType::InsertFromDrop)) { | 917 cmd->inputType() == InputEvent::InputType::InsertFromDrop)) { |
| 908 // Only register undo entry when combined with other commands. | 918 // Only register undo entry when combined with other commands. |
| 909 if (!m_lastEditCommand->undoStep()) | 919 if (!m_lastEditCommand->undoStep()) |
| 910 m_undoStack->registerUndoStep(m_lastEditCommand->ensureUndoStep()); | 920 m_undoStack->registerUndoStep(m_lastEditCommand->ensureUndoStep()); |
| 911 m_lastEditCommand->appendCommandToUndoStep(cmd); | 921 m_lastEditCommand->appendCommandToUndoStep(cmd); |
| 912 } else { | 922 } else { |
| 913 // Only register a new undo command if the command passed in is | 923 // Only register a new undo command if the command passed in is |
| 914 // different from the last command | 924 // different from the last command |
| 915 m_lastEditCommand = cmd; | 925 m_lastEditCommand = cmd; |
| 916 m_undoStack->registerUndoStep(m_lastEditCommand->ensureUndoStep()); | 926 m_undoStack->registerUndoStep(m_lastEditCommand->ensureUndoStep()); |
| 917 } | 927 } |
| 918 | 928 |
| 919 respondToChangedContents(newSelection.start()); | 929 respondToChangedContents(newSelection.start()); |
| 920 } | 930 } |
| 921 | 931 |
| 922 static VisibleSelection correctedVisibleSelection( | |
| 923 const VisibleSelection& passedSelection) { | |
| 924 if (!passedSelection.base().isConnected() || | |
| 925 !passedSelection.extent().isConnected()) | |
| 926 return VisibleSelection(); | |
| 927 DCHECK(!passedSelection.base().document()->needsLayoutTreeUpdate()); | |
| 928 return createVisibleSelection(passedSelection.asSelection()); | |
| 929 } | |
| 930 | |
| 931 void Editor::unappliedEditing(UndoStep* cmd) { | 932 void Editor::unappliedEditing(UndoStep* cmd) { |
| 932 EventQueueScope scope; | 933 EventQueueScope scope; |
| 933 | 934 |
| 934 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), | 935 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), |
| 935 cmd->endingRootEditableElement()); | 936 cmd->endingRootEditableElement()); |
| 936 dispatchInputEventEditableContentChanged( | 937 dispatchInputEventEditableContentChanged( |
| 937 cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), | 938 cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), |
| 938 InputEvent::InputType::HistoryUndo, nullAtom, | 939 InputEvent::InputType::HistoryUndo, nullAtom, |
| 939 InputEvent::EventIsComposing::NotComposing); | 940 InputEvent::EventIsComposing::NotComposing); |
| 940 | 941 |
| 941 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 942 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 942 // needs to be audited. See http://crbug.com/590369 for more details. | 943 // needs to be audited. See http://crbug.com/590369 for more details. |
| 943 // In the long term, we should stop editing commands from storing | 944 // In the long term, we should stop editing commands from storing |
| 944 // VisibleSelections as starting and ending selections. | 945 // VisibleSelections as starting and ending selections. |
| 945 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 946 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 946 | 947 |
| 947 const VisibleSelection& newSelection = | 948 const VisibleSelection& newSelection = |
| 948 correctedVisibleSelection(cmd->startingSelection()); | 949 correctedVisibleSelection(cmd->startingSelection()); |
| 949 DCHECK(newSelection.isValidFor(*frame().document())) << newSelection; | 950 DCHECK(newSelection.isValidFor(*frame().document())) << newSelection; |
| 950 if (!newSelection.isNone()) { | 951 changeSelectionAfterCommand( |
| 951 changeSelectionAfterCommand( | 952 newSelection.asSelection(), |
| 952 newSelection, | 953 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); |
| 953 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); | |
| 954 } | |
| 955 | 954 |
| 956 m_lastEditCommand = nullptr; | 955 m_lastEditCommand = nullptr; |
| 957 m_undoStack->registerRedoStep(cmd); | 956 m_undoStack->registerRedoStep(cmd); |
| 958 respondToChangedContents(newSelection.start()); | 957 respondToChangedContents(newSelection.start()); |
| 959 } | 958 } |
| 960 | 959 |
| 961 void Editor::reappliedEditing(UndoStep* cmd) { | 960 void Editor::reappliedEditing(UndoStep* cmd) { |
| 962 EventQueueScope scope; | 961 EventQueueScope scope; |
| 963 | 962 |
| 964 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), | 963 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), |
| 965 cmd->endingRootEditableElement()); | 964 cmd->endingRootEditableElement()); |
| 966 dispatchInputEventEditableContentChanged( | 965 dispatchInputEventEditableContentChanged( |
| 967 cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), | 966 cmd->startingRootEditableElement(), cmd->endingRootEditableElement(), |
| 968 InputEvent::InputType::HistoryRedo, nullAtom, | 967 InputEvent::InputType::HistoryRedo, nullAtom, |
| 969 InputEvent::EventIsComposing::NotComposing); | 968 InputEvent::EventIsComposing::NotComposing); |
| 970 | 969 |
| 971 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 970 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 972 // needs to be audited. See http://crbug.com/590369 for more details. | 971 // needs to be audited. See http://crbug.com/590369 for more details. |
| 973 // In the long term, we should stop editing commands from storing | 972 // In the long term, we should stop editing commands from storing |
| 974 // VisibleSelections as starting and ending selections. | 973 // VisibleSelections as starting and ending selections. |
| 975 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 974 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 976 const VisibleSelection& newSelection = | 975 const VisibleSelection& newSelection = |
| 977 correctedVisibleSelection(cmd->endingSelection()); | 976 correctedVisibleSelection(cmd->endingSelection()); |
| 978 DCHECK(newSelection.isValidFor(*frame().document())) << newSelection; | 977 DCHECK(newSelection.isValidFor(*frame().document())) << newSelection; |
| 979 if (!newSelection.isNone()) { | 978 changeSelectionAfterCommand( |
| 980 changeSelectionAfterCommand( | 979 newSelection.asSelection(), |
| 981 newSelection, | 980 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); |
| 982 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); | |
| 983 } | |
| 984 | 981 |
| 985 m_lastEditCommand = nullptr; | 982 m_lastEditCommand = nullptr; |
| 986 m_undoStack->registerUndoStep(cmd); | 983 m_undoStack->registerUndoStep(cmd); |
| 987 respondToChangedContents(newSelection.start()); | 984 respondToChangedContents(newSelection.start()); |
| 988 } | 985 } |
| 989 | 986 |
| 990 Editor* Editor::create(LocalFrame& frame) { | 987 Editor* Editor::create(LocalFrame& frame) { |
| 991 return new Editor(frame); | 988 return new Editor(frame); |
| 992 } | 989 } |
| 993 | 990 |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1405 if (m_shouldStartNewKillRingSequence) | 1402 if (m_shouldStartNewKillRingSequence) |
| 1406 killRing().startNewSequence(); | 1403 killRing().startNewSequence(); |
| 1407 | 1404 |
| 1408 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 1405 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
| 1409 String text = plainText(range); | 1406 String text = plainText(range); |
| 1410 killRing().append(text); | 1407 killRing().append(text); |
| 1411 m_shouldStartNewKillRingSequence = false; | 1408 m_shouldStartNewKillRingSequence = false; |
| 1412 } | 1409 } |
| 1413 | 1410 |
| 1414 void Editor::changeSelectionAfterCommand( | 1411 void Editor::changeSelectionAfterCommand( |
| 1415 const VisibleSelection& newSelection, | 1412 const SelectionInDOMTree& newSelection, |
| 1416 FrameSelection::SetSelectionOptions options) { | 1413 FrameSelection::SetSelectionOptions options) { |
| 1417 // If the new selection is orphaned, then don't update the selection. | 1414 if (newSelection.isNone()) |
| 1418 if (newSelection.start().isOrphan() || newSelection.end().isOrphan()) | |
| 1419 return; | 1415 return; |
| 1420 | 1416 |
| 1421 // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain | 1417 // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain |
| 1422 // Ranges for selections that are no longer valid | 1418 // Ranges for selections that are no longer valid |
| 1423 bool selectionDidNotChangeDOMPosition = | 1419 bool selectionDidNotChangeDOMPosition = |
| 1424 newSelection == | 1420 newSelection == frame().selection().selectionInDOMTree(); |
| 1425 frame().selection().computeVisibleSelectionInDOMTreeDeprecated(); | |
| 1426 frame().selection().setSelection(newSelection, options); | 1421 frame().selection().setSelection(newSelection, options); |
| 1427 | 1422 |
| 1428 // Some editing operations change the selection visually without affecting its | 1423 // Some editing operations change the selection visually without affecting its |
| 1429 // position within the DOM. For example when you press return in the following | 1424 // position within the DOM. For example when you press return in the following |
| 1430 // (the caret is marked by ^): | 1425 // (the caret is marked by ^): |
| 1431 // <div contentEditable="true"><div>^Hello</div></div> | 1426 // <div contentEditable="true"><div>^Hello</div></div> |
| 1432 // WebCore inserts <div><br></div> *before* the current block, which correctly | 1427 // WebCore inserts <div><br></div> *before* the current block, which correctly |
| 1433 // moves the paragraph down but which doesn't change the caret's DOM position | 1428 // moves the paragraph down but which doesn't change the caret's DOM position |
| 1434 // (["hello", 0]). In these situations the above FrameSelection::setSelection | 1429 // (["hello", 0]). In these situations the above FrameSelection::setSelection |
| 1435 // call does not call EditorClient::respondToChangedSelection(), which, on the | 1430 // call does not call EditorClient::respondToChangedSelection(), which, on the |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1763 | 1758 |
| 1764 DEFINE_TRACE(Editor) { | 1759 DEFINE_TRACE(Editor) { |
| 1765 visitor->trace(m_frame); | 1760 visitor->trace(m_frame); |
| 1766 visitor->trace(m_lastEditCommand); | 1761 visitor->trace(m_lastEditCommand); |
| 1767 visitor->trace(m_undoStack); | 1762 visitor->trace(m_undoStack); |
| 1768 visitor->trace(m_mark); | 1763 visitor->trace(m_mark); |
| 1769 visitor->trace(m_typingStyle); | 1764 visitor->trace(m_typingStyle); |
| 1770 } | 1765 } |
| 1771 | 1766 |
| 1772 } // namespace blink | 1767 } // namespace blink |
| OLD | NEW |