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 |