| 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 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 static void DispatchEditableContentChangedEvents(Element* start_root, | 909 static void DispatchEditableContentChangedEvents(Element* start_root, |
| 910 Element* end_root) { | 910 Element* end_root) { |
| 911 if (start_root) | 911 if (start_root) |
| 912 start_root->DispatchEvent( | 912 start_root->DispatchEvent( |
| 913 Event::Create(EventTypeNames::webkitEditableContentChanged)); | 913 Event::Create(EventTypeNames::webkitEditableContentChanged)); |
| 914 if (end_root && end_root != start_root) | 914 if (end_root && end_root != start_root) |
| 915 end_root->DispatchEvent( | 915 end_root->DispatchEvent( |
| 916 Event::Create(EventTypeNames::webkitEditableContentChanged)); | 916 Event::Create(EventTypeNames::webkitEditableContentChanged)); |
| 917 } | 917 } |
| 918 | 918 |
| 919 static VisibleSelection CorrectedVisibleSelection( | 919 static SelectionInDOMTree CorrectedSelectionAfterCommand( |
| 920 const VisibleSelection& passed_selection) { | 920 const VisibleSelection& passed_selection, |
| 921 Document* document) { |
| 921 if (!passed_selection.Base().IsConnected() || | 922 if (!passed_selection.Base().IsConnected() || |
| 922 !passed_selection.Extent().IsConnected()) | 923 !passed_selection.Extent().IsConnected() || |
| 923 return VisibleSelection(); | 924 passed_selection.Base().GetDocument() != document || |
| 924 DCHECK(!passed_selection.Base().GetDocument()->NeedsLayoutTreeUpdate()); | 925 passed_selection.Base().GetDocument() != |
| 925 return CreateVisibleSelection(passed_selection.AsSelection()); | 926 passed_selection.Extent().GetDocument()) |
| 927 return SelectionInDOMTree(); |
| 928 return passed_selection.AsSelection(); |
| 926 } | 929 } |
| 927 | 930 |
| 928 void Editor::AppliedEditing(CompositeEditCommand* cmd) { | 931 void Editor::AppliedEditing(CompositeEditCommand* cmd) { |
| 929 DCHECK(!cmd->IsCommandGroupWrapper()); | 932 DCHECK(!cmd->IsCommandGroupWrapper()); |
| 930 EventQueueScope scope; | 933 EventQueueScope scope; |
| 931 | 934 |
| 932 // Request spell checking before any further DOM change. | 935 // Request spell checking before any further DOM change. |
| 933 GetSpellChecker().MarkMisspellingsAfterApplyingCommand(*cmd); | 936 GetSpellChecker().MarkMisspellingsAfterApplyingCommand(*cmd); |
| 934 | 937 |
| 935 UndoStep* undo_step = cmd->GetUndoStep(); | 938 UndoStep* undo_step = cmd->GetUndoStep(); |
| 936 DCHECK(undo_step); | 939 DCHECK(undo_step); |
| 937 DispatchEditableContentChangedEvents(undo_step->StartingRootEditableElement(), | 940 DispatchEditableContentChangedEvents(undo_step->StartingRootEditableElement(), |
| 938 undo_step->EndingRootEditableElement()); | 941 undo_step->EndingRootEditableElement()); |
| 939 // TODO(chongz): Filter empty InputType after spec is finalized. | 942 // TODO(chongz): Filter empty InputType after spec is finalized. |
| 940 DispatchInputEventEditableContentChanged( | 943 DispatchInputEventEditableContentChanged( |
| 941 undo_step->StartingRootEditableElement(), | 944 undo_step->StartingRootEditableElement(), |
| 942 undo_step->EndingRootEditableElement(), cmd->GetInputType(), | 945 undo_step->EndingRootEditableElement(), cmd->GetInputType(), |
| 943 cmd->TextDataForInputEvent(), IsComposingFromCommand(cmd)); | 946 cmd->TextDataForInputEvent(), IsComposingFromCommand(cmd)); |
| 944 | 947 |
| 945 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 948 const SelectionInDOMTree& new_selection = CorrectedSelectionAfterCommand( |
| 946 // needs to be audited. See http://crbug.com/590369 for more details. | 949 cmd->EndingSelection(), GetFrame().GetDocument()); |
| 947 // The clean layout is consumed by |mostBackwardCaretPosition|, called through | |
| 948 // |changeSelectionAfterCommand|. In the long term, we should postpone visible | |
| 949 // selection canonicalization so that selection update does not need layout. | |
| 950 GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); | |
| 951 | |
| 952 const VisibleSelection& new_selection = | |
| 953 CorrectedVisibleSelection(cmd->EndingSelection()); | |
| 954 | 950 |
| 955 // Don't clear the typing style with this selection change. We do those things | 951 // Don't clear the typing style with this selection change. We do those things |
| 956 // elsewhere if necessary. | 952 // elsewhere if necessary. |
| 957 ChangeSelectionAfterCommand(new_selection.AsSelection(), 0); | 953 ChangeSelectionAfterCommand(new_selection, 0); |
| 958 | 954 |
| 959 if (!cmd->PreservesTypingStyle()) | 955 if (!cmd->PreservesTypingStyle()) |
| 960 ClearTypingStyle(); | 956 ClearTypingStyle(); |
| 961 | 957 |
| 962 // Command will be equal to last edit command only in the case of typing | 958 // Command will be equal to last edit command only in the case of typing |
| 963 if (last_edit_command_.Get() == cmd) { | 959 if (last_edit_command_.Get() == cmd) { |
| 964 DCHECK(cmd->IsTypingCommand()); | 960 DCHECK(cmd->IsTypingCommand()); |
| 965 } else if (last_edit_command_ && last_edit_command_->IsDragAndDropCommand() && | 961 } else if (last_edit_command_ && last_edit_command_->IsDragAndDropCommand() && |
| 966 (cmd->GetInputType() == InputEvent::InputType::kDeleteByDrag || | 962 (cmd->GetInputType() == InputEvent::InputType::kDeleteByDrag || |
| 967 cmd->GetInputType() == InputEvent::InputType::kInsertFromDrop)) { | 963 cmd->GetInputType() == InputEvent::InputType::kInsertFromDrop)) { |
| 968 // Only register undo entry when combined with other commands. | 964 // Only register undo entry when combined with other commands. |
| 969 if (!last_edit_command_->GetUndoStep()) | 965 if (!last_edit_command_->GetUndoStep()) |
| 970 undo_stack_->RegisterUndoStep(last_edit_command_->EnsureUndoStep()); | 966 undo_stack_->RegisterUndoStep(last_edit_command_->EnsureUndoStep()); |
| 971 last_edit_command_->AppendCommandToUndoStep(cmd); | 967 last_edit_command_->AppendCommandToUndoStep(cmd); |
| 972 } else { | 968 } else { |
| 973 // Only register a new undo command if the command passed in is | 969 // Only register a new undo command if the command passed in is |
| 974 // different from the last command | 970 // different from the last command |
| 975 last_edit_command_ = cmd; | 971 last_edit_command_ = cmd; |
| 976 undo_stack_->RegisterUndoStep(last_edit_command_->EnsureUndoStep()); | 972 undo_stack_->RegisterUndoStep(last_edit_command_->EnsureUndoStep()); |
| 977 } | 973 } |
| 978 | 974 |
| 979 RespondToChangedContents(new_selection.Start()); | 975 RespondToChangedContents(new_selection.Base()); |
| 980 } | 976 } |
| 981 | 977 |
| 982 void Editor::UnappliedEditing(UndoStep* cmd) { | 978 void Editor::UnappliedEditing(UndoStep* cmd) { |
| 983 EventQueueScope scope; | 979 EventQueueScope scope; |
| 984 | 980 |
| 985 DispatchEditableContentChangedEvents(cmd->StartingRootEditableElement(), | 981 DispatchEditableContentChangedEvents(cmd->StartingRootEditableElement(), |
| 986 cmd->EndingRootEditableElement()); | 982 cmd->EndingRootEditableElement()); |
| 987 DispatchInputEventEditableContentChanged( | 983 DispatchInputEventEditableContentChanged( |
| 988 cmd->StartingRootEditableElement(), cmd->EndingRootEditableElement(), | 984 cmd->StartingRootEditableElement(), cmd->EndingRootEditableElement(), |
| 989 InputEvent::InputType::kHistoryUndo, g_null_atom, | 985 InputEvent::InputType::kHistoryUndo, g_null_atom, |
| 990 InputEvent::EventIsComposing::kNotComposing); | 986 InputEvent::EventIsComposing::kNotComposing); |
| 991 | 987 |
| 992 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 988 const SelectionInDOMTree& new_selection = CorrectedSelectionAfterCommand( |
| 993 // needs to be audited. See http://crbug.com/590369 for more details. | 989 cmd->StartingSelection(), GetFrame().GetDocument()); |
| 994 // In the long term, we should stop editing commands from storing | |
| 995 // VisibleSelections as starting and ending selections. | |
| 996 GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); | |
| 997 | |
| 998 const VisibleSelection& new_selection = | |
| 999 CorrectedVisibleSelection(cmd->StartingSelection()); | |
| 1000 DCHECK(new_selection.IsValidFor(*GetFrame().GetDocument())) << new_selection; | |
| 1001 ChangeSelectionAfterCommand( | 990 ChangeSelectionAfterCommand( |
| 1002 new_selection.AsSelection(), | 991 new_selection, |
| 1003 FrameSelection::kCloseTyping | FrameSelection::kClearTypingStyle); | 992 FrameSelection::kCloseTyping | FrameSelection::kClearTypingStyle); |
| 1004 | 993 |
| 1005 last_edit_command_ = nullptr; | 994 last_edit_command_ = nullptr; |
| 1006 undo_stack_->RegisterRedoStep(cmd); | 995 undo_stack_->RegisterRedoStep(cmd); |
| 1007 RespondToChangedContents(new_selection.Start()); | 996 RespondToChangedContents(new_selection.Base()); |
| 1008 } | 997 } |
| 1009 | 998 |
| 1010 void Editor::ReappliedEditing(UndoStep* cmd) { | 999 void Editor::ReappliedEditing(UndoStep* cmd) { |
| 1011 EventQueueScope scope; | 1000 EventQueueScope scope; |
| 1012 | 1001 |
| 1013 DispatchEditableContentChangedEvents(cmd->StartingRootEditableElement(), | 1002 DispatchEditableContentChangedEvents(cmd->StartingRootEditableElement(), |
| 1014 cmd->EndingRootEditableElement()); | 1003 cmd->EndingRootEditableElement()); |
| 1015 DispatchInputEventEditableContentChanged( | 1004 DispatchInputEventEditableContentChanged( |
| 1016 cmd->StartingRootEditableElement(), cmd->EndingRootEditableElement(), | 1005 cmd->StartingRootEditableElement(), cmd->EndingRootEditableElement(), |
| 1017 InputEvent::InputType::kHistoryRedo, g_null_atom, | 1006 InputEvent::InputType::kHistoryRedo, g_null_atom, |
| 1018 InputEvent::EventIsComposing::kNotComposing); | 1007 InputEvent::EventIsComposing::kNotComposing); |
| 1019 | 1008 |
| 1020 // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets | 1009 const SelectionInDOMTree& new_selection = CorrectedSelectionAfterCommand( |
| 1021 // needs to be audited. See http://crbug.com/590369 for more details. | 1010 cmd->EndingSelection(), GetFrame().GetDocument()); |
| 1022 // In the long term, we should stop editing commands from storing | |
| 1023 // VisibleSelections as starting and ending selections. | |
| 1024 GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); | |
| 1025 const VisibleSelection& new_selection = | |
| 1026 CorrectedVisibleSelection(cmd->EndingSelection()); | |
| 1027 DCHECK(new_selection.IsValidFor(*GetFrame().GetDocument())) << new_selection; | |
| 1028 ChangeSelectionAfterCommand( | 1011 ChangeSelectionAfterCommand( |
| 1029 new_selection.AsSelection(), | 1012 new_selection, |
| 1030 FrameSelection::kCloseTyping | FrameSelection::kClearTypingStyle); | 1013 FrameSelection::kCloseTyping | FrameSelection::kClearTypingStyle); |
| 1031 | 1014 |
| 1032 last_edit_command_ = nullptr; | 1015 last_edit_command_ = nullptr; |
| 1033 undo_stack_->RegisterUndoStep(cmd); | 1016 undo_stack_->RegisterUndoStep(cmd); |
| 1034 RespondToChangedContents(new_selection.Start()); | 1017 RespondToChangedContents(new_selection.Base()); |
| 1035 } | 1018 } |
| 1036 | 1019 |
| 1037 Editor* Editor::Create(LocalFrame& frame) { | 1020 Editor* Editor::Create(LocalFrame& frame) { |
| 1038 return new Editor(frame); | 1021 return new Editor(frame); |
| 1039 } | 1022 } |
| 1040 | 1023 |
| 1041 Editor::Editor(LocalFrame& frame) | 1024 Editor::Editor(LocalFrame& frame) |
| 1042 : frame_(&frame), | 1025 : frame_(&frame), |
| 1043 undo_stack_(UndoStack::Create()), | 1026 undo_stack_(UndoStack::Create()), |
| 1044 prevent_reveal_selection_(0), | 1027 prevent_reveal_selection_(0), |
| (...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1837 | 1820 |
| 1838 DEFINE_TRACE(Editor) { | 1821 DEFINE_TRACE(Editor) { |
| 1839 visitor->Trace(frame_); | 1822 visitor->Trace(frame_); |
| 1840 visitor->Trace(last_edit_command_); | 1823 visitor->Trace(last_edit_command_); |
| 1841 visitor->Trace(undo_stack_); | 1824 visitor->Trace(undo_stack_); |
| 1842 visitor->Trace(mark_); | 1825 visitor->Trace(mark_); |
| 1843 visitor->Trace(typing_style_); | 1826 visitor->Trace(typing_style_); |
| 1844 } | 1827 } |
| 1845 | 1828 |
| 1846 } // namespace blink | 1829 } // namespace blink |
| OLD | NEW |