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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 if (event->isIncrementalInsertion()) | 212 if (event->isIncrementalInsertion()) |
213 return false; | 213 return false; |
214 | 214 |
215 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 215 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
216 // needs to be audited. See http://crbug.com/590369 for more details. | 216 // needs to be audited. See http://crbug.com/590369 for more details. |
217 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 217 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
218 | 218 |
219 if (event->isPaste()) { | 219 if (event->isPaste()) { |
220 if (event->pastingFragment()) { | 220 if (event->pastingFragment()) { |
221 replaceSelectionWithFragment( | 221 replaceSelectionWithFragment( |
222 event->pastingFragment(), false, event->shouldSmartReplace(), | 222 EditCommandSource::kMenuOrKeyBinding, event->pastingFragment(), false, |
223 event->shouldMatchStyle(), InputEvent::InputType::InsertFromPaste); | 223 event->shouldSmartReplace(), event->shouldMatchStyle(), |
| 224 InputEvent::InputType::InsertFromPaste); |
224 } else { | 225 } else { |
225 replaceSelectionWithText(event->data(), false, | 226 replaceSelectionWithText( |
226 event->shouldSmartReplace(), | 227 EditCommandSource::kMenuOrKeyBinding, event->data(), false, |
227 InputEvent::InputType::InsertFromPaste); | 228 event->shouldSmartReplace(), InputEvent::InputType::InsertFromPaste); |
228 } | 229 } |
229 return true; | 230 return true; |
230 } | 231 } |
231 | 232 |
232 String data = event->data(); | 233 String data = event->data(); |
233 if (data == "\n") { | 234 if (data == "\n") { |
234 if (event->isLineBreak()) | 235 if (event->isLineBreak()) |
235 return insertLineBreak(); | 236 return insertLineBreak(); |
236 return insertParagraphSeparator(); | 237 return insertParagraphSeparator(); |
237 } | 238 } |
238 | 239 |
239 return insertTextWithoutSendingTextEvent(data, false, event); | 240 return insertTextWithoutSendingTextEvent(EditCommandSource::kMenuOrKeyBinding, |
| 241 data, false, event); |
240 } | 242 } |
241 | 243 |
242 bool Editor::canEdit() const { | 244 bool Editor::canEdit() const { |
243 return frame().selection().rootEditableElement(); | 245 return frame().selection().rootEditableElement(); |
244 } | 246 } |
245 | 247 |
246 bool Editor::canEditRichly() const { | 248 bool Editor::canEditRichly() const { |
247 return frame().selection().isContentRichlyEditable(); | 249 return frame().selection().isContentRichlyEditable(); |
248 } | 250 } |
249 | 251 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 return smartInsertDeleteEnabled() && | 311 return smartInsertDeleteEnabled() && |
310 frame().selection().granularity() == WordGranularity; | 312 frame().selection().granularity() == WordGranularity; |
311 } | 313 } |
312 | 314 |
313 bool Editor::isSelectTrailingWhitespaceEnabled() const { | 315 bool Editor::isSelectTrailingWhitespaceEnabled() const { |
314 if (Settings* settings = frame().settings()) | 316 if (Settings* settings = frame().settings()) |
315 return settings->selectTrailingWhitespaceEnabled(); | 317 return settings->selectTrailingWhitespaceEnabled(); |
316 return false; | 318 return false; |
317 } | 319 } |
318 | 320 |
319 bool Editor::deleteWithDirection(DeleteDirection direction, | 321 bool Editor::deleteWithDirection(EditCommandSource source, |
| 322 DeleteDirection direction, |
320 TextGranularity granularity, | 323 TextGranularity granularity, |
321 bool killRing, | 324 bool killRing, |
322 bool isTypingAction) { | 325 bool isTypingAction) { |
323 if (!canEdit()) | 326 if (!canEdit()) |
324 return false; | 327 return false; |
325 | 328 |
326 EditingState editingState; | 329 EditingState editingState; |
327 if (frame().selection().isRange()) { | 330 if (frame().selection().isRange()) { |
328 if (isTypingAction) { | 331 if (isTypingAction) { |
329 DCHECK(frame().document()); | 332 DCHECK(frame().document()); |
330 TypingCommand::deleteKeyPressed( | 333 TypingCommand::deleteKeyPressed( |
331 *frame().document(), | 334 *frame().document(), |
332 canSmartCopyOrDelete() ? TypingCommand::SmartDelete : 0, granularity); | 335 canSmartCopyOrDelete() ? TypingCommand::SmartDelete : 0, granularity); |
333 revealSelectionAfterEditingOperation(); | 336 revealSelectionAfterEditingOperation(); |
334 } else { | 337 } else { |
335 if (killRing) | 338 if (killRing) |
336 addToKillRing(selectedRange()); | 339 addToKillRing(selectedRange()); |
337 deleteSelectionWithSmartDelete( | 340 deleteSelectionWithSmartDelete( |
| 341 source, |
338 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, | 342 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, |
339 deletionInputTypeFromTextGranularity(direction, granularity)); | 343 deletionInputTypeFromTextGranularity(direction, granularity)); |
340 // Implicitly calls revealSelectionAfterEditingOperation(). | 344 // Implicitly calls revealSelectionAfterEditingOperation(). |
341 } | 345 } |
342 } else { | 346 } else { |
343 TypingCommand::Options options = 0; | 347 TypingCommand::Options options = 0; |
344 if (canSmartCopyOrDelete()) | 348 if (canSmartCopyOrDelete()) |
345 options |= TypingCommand::SmartDelete; | 349 options |= TypingCommand::SmartDelete; |
346 if (killRing) | 350 if (killRing) |
347 options |= TypingCommand::KillRing; | 351 options |= TypingCommand::KillRing; |
(...skipping 16 matching lines...) Expand all Loading... |
364 | 368 |
365 // FIXME: We should to move this down into deleteKeyPressed. | 369 // FIXME: We should to move this down into deleteKeyPressed. |
366 // clear the "start new kill ring sequence" setting, because it was set to | 370 // clear the "start new kill ring sequence" setting, because it was set to |
367 // true when the selection was updated by deleting the range | 371 // true when the selection was updated by deleting the range |
368 if (killRing) | 372 if (killRing) |
369 setStartNewKillRingSequence(false); | 373 setStartNewKillRingSequence(false); |
370 | 374 |
371 return true; | 375 return true; |
372 } | 376 } |
373 | 377 |
| 378 // TODO(chongz): Pass |EditCommandSource| to |CompositeEditCommand|. |
374 void Editor::deleteSelectionWithSmartDelete( | 379 void Editor::deleteSelectionWithSmartDelete( |
| 380 EditCommandSource, |
375 DeleteMode deleteMode, | 381 DeleteMode deleteMode, |
376 InputEvent::InputType inputType, | 382 InputEvent::InputType inputType, |
377 const Position& referenceMovePosition) { | 383 const Position& referenceMovePosition) { |
378 if (frame().selection().isNone()) | 384 if (frame().selection().isNone()) |
379 return; | 385 return; |
380 | 386 |
381 const bool kMergeBlocksAfterDelete = true; | 387 const bool kMergeBlocksAfterDelete = true; |
382 const bool kExpandForSpecialElements = false; | 388 const bool kExpandForSpecialElements = false; |
383 const bool kSanitizeMarkup = true; | 389 const bool kSanitizeMarkup = true; |
384 DCHECK(frame().document()); | 390 DCHECK(frame().document()); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 // invalidate clipboard here for security | 563 // invalidate clipboard here for security |
558 dataTransfer->setAccessPolicy(DataTransferNumb); | 564 dataTransfer->setAccessPolicy(DataTransferNumb); |
559 | 565 |
560 return !noDefaultProcessing; | 566 return !noDefaultProcessing; |
561 } | 567 } |
562 | 568 |
563 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) { | 569 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) { |
564 return smartInsertDeleteEnabled() && pasteboard->canSmartReplace(); | 570 return smartInsertDeleteEnabled() && pasteboard->canSmartReplace(); |
565 } | 571 } |
566 | 572 |
567 void Editor::replaceSelectionWithFragment(DocumentFragment* fragment, | 573 // TODO(chongz): Pass |EditCommandSource| to |CompositeEditCommand|. |
| 574 void Editor::replaceSelectionWithFragment(EditCommandSource, |
| 575 DocumentFragment* fragment, |
568 bool selectReplacement, | 576 bool selectReplacement, |
569 bool smartReplace, | 577 bool smartReplace, |
570 bool matchStyle, | 578 bool matchStyle, |
571 InputEvent::InputType inputType) { | 579 InputEvent::InputType inputType) { |
572 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 580 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
573 if (frame().selection().isNone() || | 581 if (frame().selection().isNone() || |
574 !frame().selection().isContentEditable() || !fragment) | 582 !frame().selection().isContentEditable() || !fragment) |
575 return; | 583 return; |
576 | 584 |
577 ReplaceSelectionCommand::CommandOptions options = | 585 ReplaceSelectionCommand::CommandOptions options = |
578 ReplaceSelectionCommand::PreventNesting | | 586 ReplaceSelectionCommand::PreventNesting | |
579 ReplaceSelectionCommand::SanitizeFragment; | 587 ReplaceSelectionCommand::SanitizeFragment; |
580 if (selectReplacement) | 588 if (selectReplacement) |
581 options |= ReplaceSelectionCommand::SelectReplacement; | 589 options |= ReplaceSelectionCommand::SelectReplacement; |
582 if (smartReplace) | 590 if (smartReplace) |
583 options |= ReplaceSelectionCommand::SmartReplace; | 591 options |= ReplaceSelectionCommand::SmartReplace; |
584 if (matchStyle) | 592 if (matchStyle) |
585 options |= ReplaceSelectionCommand::MatchStyle; | 593 options |= ReplaceSelectionCommand::MatchStyle; |
586 DCHECK(frame().document()); | 594 DCHECK(frame().document()); |
587 ReplaceSelectionCommand::create(*frame().document(), fragment, options, | 595 ReplaceSelectionCommand::create(*frame().document(), fragment, options, |
588 inputType) | 596 inputType) |
589 ->apply(); | 597 ->apply(); |
590 revealSelectionAfterEditingOperation(); | 598 revealSelectionAfterEditingOperation(); |
591 } | 599 } |
592 | 600 |
593 void Editor::replaceSelectionWithText(const String& text, | 601 void Editor::replaceSelectionWithText(EditCommandSource source, |
| 602 const String& text, |
594 bool selectReplacement, | 603 bool selectReplacement, |
595 bool smartReplace, | 604 bool smartReplace, |
596 InputEvent::InputType inputType) { | 605 InputEvent::InputType inputType) { |
597 replaceSelectionWithFragment(createFragmentFromText(selectedRange(), text), | 606 replaceSelectionWithFragment( |
598 selectReplacement, smartReplace, true, | 607 source, createFragmentFromText(selectedRange(), text), selectReplacement, |
599 inputType); | 608 smartReplace, true, inputType); |
600 } | 609 } |
601 | 610 |
602 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. | 611 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. |
603 void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, | 612 void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, |
604 InsertMode insertMode, | 613 InsertMode insertMode, |
605 DragSourceType dragSourceType) { | 614 DragSourceType dragSourceType) { |
606 ReplaceSelectionCommand::CommandOptions options = | 615 ReplaceSelectionCommand::CommandOptions options = |
607 ReplaceSelectionCommand::SelectReplacement | | 616 ReplaceSelectionCommand::SelectReplacement | |
608 ReplaceSelectionCommand::PreventNesting; | 617 ReplaceSelectionCommand::PreventNesting; |
609 if (insertMode == InsertMode::Smart) | 618 if (insertMode == InsertMode::Smart) |
(...skipping 18 matching lines...) Expand all Loading... |
628 dragSource, InputEvent::InputType::DeleteByDrag, | 637 dragSource, InputEvent::InputType::DeleteByDrag, |
629 nullptr) == DispatchEventResult::NotCanceled; | 638 nullptr) == DispatchEventResult::NotCanceled; |
630 | 639 |
631 // 'beforeinput' event handler may destroy frame, return false to cancel | 640 // 'beforeinput' event handler may destroy frame, return false to cancel |
632 // remaining actions; | 641 // remaining actions; |
633 if (m_frame->document()->frame() != m_frame) | 642 if (m_frame->document()->frame() != m_frame) |
634 return false; | 643 return false; |
635 | 644 |
636 if (shouldDelete && dragSource->isConnected()) { | 645 if (shouldDelete && dragSource->isConnected()) { |
637 deleteSelectionWithSmartDelete( | 646 deleteSelectionWithSmartDelete( |
638 deleteMode, InputEvent::InputType::DeleteByDrag, referenceMovePosition); | 647 EditCommandSource::kMenuOrKeyBinding, deleteMode, |
| 648 InputEvent::InputType::DeleteByDrag, referenceMovePosition); |
639 } | 649 } |
640 | 650 |
641 return true; | 651 return true; |
642 } | 652 } |
643 | 653 |
644 bool Editor::replaceSelectionAfterDraggingWithEvents( | 654 bool Editor::replaceSelectionAfterDraggingWithEvents( |
645 Element* dropTarget, | 655 Element* dropTarget, |
646 DragData* dragData, | 656 DragData* dragData, |
647 DocumentFragment* fragment, | 657 DocumentFragment* fragment, |
648 Range* dropCaretRange, | 658 Range* dropCaretRange, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 if (frame().settings() && frame().settings()->accessibilityEnabled()) { | 702 if (frame().settings() && frame().settings()->accessibilityEnabled()) { |
693 Node* node = endingSelection.start().anchorNode(); | 703 Node* node = endingSelection.start().anchorNode(); |
694 if (AXObjectCache* cache = frame().document()->existingAXObjectCache()) | 704 if (AXObjectCache* cache = frame().document()->existingAXObjectCache()) |
695 cache->handleEditableTextContentChanged(node); | 705 cache->handleEditableTextContentChanged(node); |
696 } | 706 } |
697 | 707 |
698 spellChecker().updateMarkersForWordsAffectedByEditing(true); | 708 spellChecker().updateMarkersForWordsAffectedByEditing(true); |
699 client().respondToChangedContents(); | 709 client().respondToChangedContents(); |
700 } | 710 } |
701 | 711 |
702 void Editor::removeFormattingAndStyle() { | 712 // TODO(chongz): Pass |EditCommandSource| to |CompositeEditCommand|. |
| 713 void Editor::removeFormattingAndStyle(EditCommandSource) { |
703 DCHECK(frame().document()); | 714 DCHECK(frame().document()); |
704 RemoveFormatCommand::create(*frame().document())->apply(); | 715 RemoveFormatCommand::create(*frame().document())->apply(); |
705 } | 716 } |
706 | 717 |
707 void Editor::registerCommandGroup(CompositeEditCommand* commandGroupWrapper) { | 718 void Editor::registerCommandGroup(CompositeEditCommand* commandGroupWrapper) { |
708 DCHECK(commandGroupWrapper->isCommandGroupWrapper()); | 719 DCHECK(commandGroupWrapper->isCommandGroupWrapper()); |
709 m_lastEditCommand = commandGroupWrapper; | 720 m_lastEditCommand = commandGroupWrapper; |
710 } | 721 } |
711 | 722 |
712 void Editor::clearLastEditCommand() { | 723 void Editor::clearLastEditCommand() { |
713 m_lastEditCommand.clear(); | 724 m_lastEditCommand.clear(); |
714 } | 725 } |
715 | 726 |
716 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const { | 727 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const { |
717 Element* target = associatedElementOf(selection.start()); | 728 Element* target = associatedElementOf(selection.start()); |
718 if (!target) | 729 if (!target) |
719 target = frame().document()->body(); | 730 target = frame().document()->body(); |
720 | 731 |
721 return target; | 732 return target; |
722 } | 733 } |
723 | 734 |
724 Element* Editor::findEventTargetFromSelection() const { | 735 Element* Editor::findEventTargetFromSelection() const { |
725 return findEventTargetFrom(frame().selection().selection()); | 736 return findEventTargetFrom(frame().selection().selection()); |
726 } | 737 } |
727 | 738 |
728 void Editor::applyStyle(StylePropertySet* style, | 739 void Editor::applyStyle(EditCommandSource source, |
| 740 StylePropertySet* style, |
729 InputEvent::InputType inputType) { | 741 InputEvent::InputType inputType) { |
730 switch (frame().selection().getSelectionType()) { | 742 switch (frame().selection().getSelectionType()) { |
731 case NoSelection: | 743 case NoSelection: |
732 // do nothing | 744 // do nothing |
733 break; | 745 break; |
734 case CaretSelection: | 746 case CaretSelection: |
735 computeAndSetTypingStyle(style, inputType); | 747 computeAndSetTypingStyle(source, style, inputType); |
736 break; | 748 break; |
737 case RangeSelection: | 749 case RangeSelection: |
738 if (style) { | 750 if (style) { |
739 DCHECK(frame().document()); | 751 DCHECK(frame().document()); |
740 ApplyStyleCommand::create(*frame().document(), | 752 ApplyStyleCommand::create(*frame().document(), |
741 EditingStyle::create(style), inputType) | 753 EditingStyle::create(style), inputType) |
742 ->apply(); | 754 ->apply(); |
743 } | 755 } |
744 break; | 756 break; |
745 } | 757 } |
746 } | 758 } |
747 | 759 |
748 void Editor::applyParagraphStyle(StylePropertySet* style, | 760 // TODO(chongz): Pass |EditCommandSource| to |CompositeEditCommand|. |
| 761 void Editor::applyParagraphStyle(EditCommandSource, |
| 762 StylePropertySet* style, |
749 InputEvent::InputType inputType) { | 763 InputEvent::InputType inputType) { |
750 if (frame().selection().isNone() || !style) | 764 if (frame().selection().isNone() || !style) |
751 return; | 765 return; |
752 DCHECK(frame().document()); | 766 DCHECK(frame().document()); |
753 ApplyStyleCommand::create(*frame().document(), EditingStyle::create(style), | 767 ApplyStyleCommand::create(*frame().document(), EditingStyle::create(style), |
754 inputType, ApplyStyleCommand::ForceBlockProperties) | 768 inputType, ApplyStyleCommand::ForceBlockProperties) |
755 ->apply(); | 769 ->apply(); |
756 } | 770 } |
757 | 771 |
758 void Editor::applyStyleToSelection(StylePropertySet* style, | 772 void Editor::applyStyleToSelection(EditCommandSource source, |
| 773 StylePropertySet* style, |
759 InputEvent::InputType inputType) { | 774 InputEvent::InputType inputType) { |
760 if (!style || style->isEmpty() || !canEditRichly()) | 775 if (!style || style->isEmpty() || !canEditRichly()) |
761 return; | 776 return; |
762 | 777 |
763 applyStyle(style, inputType); | 778 applyStyle(source, style, inputType); |
764 } | 779 } |
765 | 780 |
766 void Editor::applyParagraphStyleToSelection(StylePropertySet* style, | 781 void Editor::applyParagraphStyleToSelection(EditCommandSource source, |
| 782 StylePropertySet* style, |
767 InputEvent::InputType inputType) { | 783 InputEvent::InputType inputType) { |
768 if (!style || style->isEmpty() || !canEditRichly()) | 784 if (!style || style->isEmpty() || !canEditRichly()) |
769 return; | 785 return; |
770 | 786 |
771 applyParagraphStyle(style, inputType); | 787 applyParagraphStyle(source, style, inputType); |
772 } | 788 } |
773 | 789 |
774 bool Editor::selectionStartHasStyle(CSSPropertyID propertyID, | 790 bool Editor::selectionStartHasStyle(CSSPropertyID propertyID, |
775 const String& value) const { | 791 const String& value) const { |
776 EditingStyle* styleToCheck = EditingStyle::create(propertyID, value); | 792 EditingStyle* styleToCheck = EditingStyle::create(propertyID, value); |
777 EditingStyle* styleAtStart = EditingStyle::styleAtSelectionStart( | 793 EditingStyle* styleAtStart = EditingStyle::styleAtSelectionStart( |
778 frame().selection().selection(), propertyID == CSSPropertyBackgroundColor, | 794 frame().selection().selection(), propertyID == CSSPropertyBackgroundColor, |
779 styleToCheck->style()); | 795 styleToCheck->style()); |
780 return styleToCheck->triStateOfStyle(styleAtStart); | 796 return styleToCheck->triStateOfStyle(styleAtStart); |
781 } | 797 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 frame().inputMethodController().clear(); | 963 frame().inputMethodController().clear(); |
948 m_shouldStyleWithCSS = false; | 964 m_shouldStyleWithCSS = false; |
949 m_defaultParagraphSeparator = EditorParagraphSeparatorIsDiv; | 965 m_defaultParagraphSeparator = EditorParagraphSeparatorIsDiv; |
950 m_undoStack->clear(); | 966 m_undoStack->clear(); |
951 } | 967 } |
952 | 968 |
953 bool Editor::insertText(const String& text, KeyboardEvent* triggeringEvent) { | 969 bool Editor::insertText(const String& text, KeyboardEvent* triggeringEvent) { |
954 return frame().eventHandler().handleTextInputEvent(text, triggeringEvent); | 970 return frame().eventHandler().handleTextInputEvent(text, triggeringEvent); |
955 } | 971 } |
956 | 972 |
957 bool Editor::insertTextWithoutSendingTextEvent(const String& text, | 973 bool Editor::insertTextWithoutSendingTextEvent(EditCommandSource source, |
| 974 const String& text, |
958 bool selectInsertedText, | 975 bool selectInsertedText, |
959 TextEvent* triggeringEvent) { | 976 TextEvent* triggeringEvent) { |
960 if (text.isEmpty()) | 977 if (text.isEmpty()) |
961 return false; | 978 return false; |
962 | 979 |
963 const VisibleSelection& selection = selectionForCommand(triggeringEvent); | 980 const VisibleSelection& selection = selectionForCommand(triggeringEvent); |
964 if (!selection.isContentEditable()) | 981 if (!selection.isContentEditable()) |
965 return false; | 982 return false; |
966 | 983 |
967 spellChecker().updateMarkersForWordsAffectedByEditing( | 984 spellChecker().updateMarkersForWordsAffectedByEditing( |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(), | 1069 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(), |
1053 InputEvent::InputType::DeleteByCut, | 1070 InputEvent::InputType::DeleteByCut, |
1054 nullptr, nullptr) != | 1071 nullptr, nullptr) != |
1055 DispatchEventResult::NotCanceled) | 1072 DispatchEventResult::NotCanceled) |
1056 return; | 1073 return; |
1057 // 'beforeinput' event handler may destroy target frame. | 1074 // 'beforeinput' event handler may destroy target frame. |
1058 if (m_frame->document()->frame() != m_frame) | 1075 if (m_frame->document()->frame() != m_frame) |
1059 return; | 1076 return; |
1060 } | 1077 } |
1061 deleteSelectionWithSmartDelete( | 1078 deleteSelectionWithSmartDelete( |
1062 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, | 1079 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, |
1063 InputEvent::InputType::DeleteByCut); | 1080 InputEvent::InputType::DeleteByCut); |
1064 } | 1081 } |
1065 } | 1082 } |
1066 | 1083 |
1067 void Editor::copy() { | 1084 void Editor::copy() { |
1068 if (tryDHTMLCopy()) | 1085 if (tryDHTMLCopy()) |
1069 return; // DHTML did the whole operation | 1086 return; // DHTML did the whole operation |
1070 if (!canCopy()) | 1087 if (!canCopy()) |
1071 return; | 1088 return; |
1072 | 1089 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 | 1146 |
1130 void Editor::pasteAsPlainText(EditCommandSource source) { | 1147 void Editor::pasteAsPlainText(EditCommandSource source) { |
1131 if (tryDHTMLPaste(PlainTextOnly)) | 1148 if (tryDHTMLPaste(PlainTextOnly)) |
1132 return; | 1149 return; |
1133 if (!canPaste()) | 1150 if (!canPaste()) |
1134 return; | 1151 return; |
1135 spellChecker().updateMarkersForWordsAffectedByEditing(false); | 1152 spellChecker().updateMarkersForWordsAffectedByEditing(false); |
1136 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); | 1153 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); |
1137 } | 1154 } |
1138 | 1155 |
1139 void Editor::performDelete() { | 1156 void Editor::performDelete(EditCommandSource source) { |
1140 if (!canDelete()) | 1157 if (!canDelete()) |
1141 return; | 1158 return; |
1142 | 1159 |
1143 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 1160 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
1144 // needs to be audited. See http://crbug.com/590369 for more details. | 1161 // needs to be audited. See http://crbug.com/590369 for more details. |
1145 // |selectedRange| requires clean layout for visible selection normalization. | 1162 // |selectedRange| requires clean layout for visible selection normalization. |
1146 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1163 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
1147 | 1164 |
1148 addToKillRing(selectedRange()); | 1165 addToKillRing(selectedRange()); |
1149 // TODO(chongz): |Editor::performDelete()| has no direction. | 1166 // TODO(chongz): |Editor::performDelete()| has no direction. |
1150 // https://github.com/w3c/editing/issues/130 | 1167 // https://github.com/w3c/editing/issues/130 |
1151 deleteSelectionWithSmartDelete( | 1168 deleteSelectionWithSmartDelete( |
1152 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, | 1169 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, |
1153 InputEvent::InputType::DeleteContentBackward); | 1170 InputEvent::InputType::DeleteContentBackward); |
1154 | 1171 |
1155 // clear the "start new kill ring sequence" setting, because it was set to | 1172 // clear the "start new kill ring sequence" setting, because it was set to |
1156 // true when the selection was updated by deleting the range | 1173 // true when the selection was updated by deleting the range |
1157 setStartNewKillRingSequence(false); | 1174 setStartNewKillRingSequence(false); |
1158 } | 1175 } |
1159 | 1176 |
1160 static void countEditingEvent(ExecutionContext* executionContext, | 1177 static void countEditingEvent(ExecutionContext* executionContext, |
1161 const Event* event, | 1178 const Event* event, |
1162 UseCounter::Feature featureOnInput, | 1179 UseCounter::Feature featureOnInput, |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 void Editor::copyImage(const HitTestResult& result) { | 1246 void Editor::copyImage(const HitTestResult& result) { |
1230 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), | 1247 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), |
1231 result.innerNodeOrImageMapImage(), | 1248 result.innerNodeOrImageMapImage(), |
1232 result.altDisplayString()); | 1249 result.altDisplayString()); |
1233 } | 1250 } |
1234 | 1251 |
1235 bool Editor::canUndo() { | 1252 bool Editor::canUndo() { |
1236 return m_undoStack->canUndo(); | 1253 return m_undoStack->canUndo(); |
1237 } | 1254 } |
1238 | 1255 |
1239 void Editor::undo() { | 1256 // TODO(chongz): Fire 'beforeinput' for user triggered undo. |
| 1257 void Editor::undo(EditCommandSource) { |
1240 m_undoStack->undo(); | 1258 m_undoStack->undo(); |
1241 } | 1259 } |
1242 | 1260 |
1243 bool Editor::canRedo() { | 1261 bool Editor::canRedo() { |
1244 return m_undoStack->canRedo(); | 1262 return m_undoStack->canRedo(); |
1245 } | 1263 } |
1246 | 1264 |
1247 void Editor::redo() { | 1265 // TODO(chongz): Fire 'beforeinput' for user triggered redo. |
| 1266 void Editor::redo(EditCommandSource) { |
1248 m_undoStack->redo(); | 1267 m_undoStack->redo(); |
1249 } | 1268 } |
1250 | 1269 |
1251 void Editor::setBaseWritingDirection(WritingDirection direction) { | 1270 void Editor::setBaseWritingDirection(WritingDirection direction) { |
1252 Element* focusedElement = frame().document()->focusedElement(); | 1271 Element* focusedElement = frame().document()->focusedElement(); |
1253 if (isTextControlElement(focusedElement)) { | 1272 if (isTextControlElement(focusedElement)) { |
1254 if (direction == NaturalWritingDirection) | 1273 if (direction == NaturalWritingDirection) |
1255 return; | 1274 return; |
1256 focusedElement->setAttribute( | 1275 focusedElement->setAttribute( |
1257 dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl"); | 1276 dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl"); |
1258 focusedElement->dispatchInputEvent(); | 1277 focusedElement->dispatchInputEvent(); |
1259 return; | 1278 return; |
1260 } | 1279 } |
1261 | 1280 |
1262 MutableStylePropertySet* style = | 1281 MutableStylePropertySet* style = |
1263 MutableStylePropertySet::create(HTMLQuirksMode); | 1282 MutableStylePropertySet::create(HTMLQuirksMode); |
1264 style->setProperty( | 1283 style->setProperty( |
1265 CSSPropertyDirection, | 1284 CSSPropertyDirection, |
1266 direction == LeftToRightWritingDirection | 1285 direction == LeftToRightWritingDirection |
1267 ? "ltr" | 1286 ? "ltr" |
1268 : direction == RightToLeftWritingDirection ? "rtl" : "inherit", | 1287 : direction == RightToLeftWritingDirection ? "rtl" : "inherit", |
1269 false); | 1288 false); |
1270 applyParagraphStyleToSelection( | 1289 applyParagraphStyleToSelection( |
1271 style, InputEvent::InputType::FormatSetBlockTextDirection); | 1290 EditCommandSource::kMenuOrKeyBinding, style, |
| 1291 InputEvent::InputType::FormatSetBlockTextDirection); |
1272 } | 1292 } |
1273 | 1293 |
1274 void Editor::revealSelectionAfterEditingOperation( | 1294 void Editor::revealSelectionAfterEditingOperation( |
1275 const ScrollAlignment& alignment, | 1295 const ScrollAlignment& alignment, |
1276 RevealExtentOption revealExtentOption) { | 1296 RevealExtentOption revealExtentOption) { |
1277 if (m_preventRevealSelection) | 1297 if (m_preventRevealSelection) |
1278 return; | 1298 return; |
1279 frame().selection().revealSelection(alignment, revealExtentOption); | 1299 frame().selection().revealSelection(alignment, revealExtentOption); |
1280 } | 1300 } |
1281 | 1301 |
1282 void Editor::transpose() { | 1302 void Editor::transpose(EditCommandSource source) { |
1283 if (!canEdit()) | 1303 if (!canEdit()) |
1284 return; | 1304 return; |
1285 | 1305 |
1286 VisibleSelection selection = frame().selection().selection(); | 1306 VisibleSelection selection = frame().selection().selection(); |
1287 if (!selection.isCaret()) | 1307 if (!selection.isCaret()) |
1288 return; | 1308 return; |
1289 | 1309 |
1290 // Make a selection that goes back one character and forward two characters. | 1310 // Make a selection that goes back one character and forward two characters. |
1291 VisiblePosition caret = selection.visibleStart(); | 1311 VisiblePosition caret = selection.visibleStart(); |
1292 VisiblePosition next = | 1312 VisiblePosition next = |
(...skipping 16 matching lines...) Expand all Loading... |
1309 return; | 1329 return; |
1310 String transposed = text.right(1) + text.left(1); | 1330 String transposed = text.right(1) + text.left(1); |
1311 | 1331 |
1312 // Select the two characters. | 1332 // Select the two characters. |
1313 if (newSelection != frame().selection().selection()) | 1333 if (newSelection != frame().selection().selection()) |
1314 frame().selection().setSelection(newSelection); | 1334 frame().selection().setSelection(newSelection); |
1315 | 1335 |
1316 // Insert the transposed characters. | 1336 // Insert the transposed characters. |
1317 // TODO(chongz): Once we add |InsertTranspose| in |InputEvent::InputType|, we | 1337 // TODO(chongz): Once we add |InsertTranspose| in |InputEvent::InputType|, we |
1318 // should use it instead of |InsertFromPaste|. | 1338 // should use it instead of |InsertFromPaste|. |
1319 replaceSelectionWithText(transposed, false, false, | 1339 replaceSelectionWithText(source, transposed, false, false, |
1320 InputEvent::InputType::InsertFromPaste); | 1340 InputEvent::InputType::InsertFromPaste); |
1321 } | 1341 } |
1322 | 1342 |
1323 void Editor::addToKillRing(const EphemeralRange& range) { | 1343 void Editor::addToKillRing(const EphemeralRange& range) { |
1324 if (m_shouldStartNewKillRingSequence) | 1344 if (m_shouldStartNewKillRingSequence) |
1325 killRing().startNewSequence(); | 1345 killRing().startNewSequence(); |
1326 | 1346 |
1327 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 1347 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
1328 String text = plainText(range); | 1348 String text = plainText(range); |
1329 killRing().append(text); | 1349 killRing().append(text); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 std::max(startCaretRect.height(), endCaretRect.height())); | 1410 std::max(startCaretRect.height(), endCaretRect.height())); |
1391 } | 1411 } |
1392 | 1412 |
1393 // start and end aren't on the same line, so go from start to the end of its | 1413 // start and end aren't on the same line, so go from start to the end of its |
1394 // line | 1414 // line |
1395 return IntRect(startCaretRect.x(), startCaretRect.y(), | 1415 return IntRect(startCaretRect.x(), startCaretRect.y(), |
1396 (startCaretRect.width() + extraWidthToEndOfLine).toInt(), | 1416 (startCaretRect.width() + extraWidthToEndOfLine).toInt(), |
1397 startCaretRect.height()); | 1417 startCaretRect.height()); |
1398 } | 1418 } |
1399 | 1419 |
1400 void Editor::computeAndSetTypingStyle(StylePropertySet* style, | 1420 // TODO(chongz): Pass |EditCommandSource| to |CompositeEditCommand|. |
| 1421 void Editor::computeAndSetTypingStyle(EditCommandSource, |
| 1422 StylePropertySet* style, |
1401 InputEvent::InputType inputType) { | 1423 InputEvent::InputType inputType) { |
1402 if (!style || style->isEmpty()) { | 1424 if (!style || style->isEmpty()) { |
1403 frame().selection().clearTypingStyle(); | 1425 frame().selection().clearTypingStyle(); |
1404 return; | 1426 return; |
1405 } | 1427 } |
1406 | 1428 |
1407 // Calculate the current typing style. | 1429 // Calculate the current typing style. |
1408 EditingStyle* typingStyle = nullptr; | 1430 EditingStyle* typingStyle = nullptr; |
1409 if (frame().selection().typingStyle()) { | 1431 if (frame().selection().typingStyle()) { |
1410 typingStyle = frame().selection().typingStyle()->copy(); | 1432 typingStyle = frame().selection().typingStyle()->copy(); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1662 DCHECK(!document.documentElement()); | 1684 DCHECK(!document.documentElement()); |
1663 document.appendChild(root); | 1685 document.appendChild(root); |
1664 | 1686 |
1665 // TODO(tkent): Should we check and move Text node children of <html>? | 1687 // TODO(tkent): Should we check and move Text node children of <html>? |
1666 } | 1688 } |
1667 | 1689 |
1668 void Editor::replaceSelection(const String& text) { | 1690 void Editor::replaceSelection(const String& text) { |
1669 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 1691 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
1670 bool selectReplacement = behavior().shouldSelectReplacement(); | 1692 bool selectReplacement = behavior().shouldSelectReplacement(); |
1671 bool smartReplace = true; | 1693 bool smartReplace = true; |
1672 replaceSelectionWithText(text, selectReplacement, smartReplace, | 1694 replaceSelectionWithText(EditCommandSource::kMenuOrKeyBinding, text, |
| 1695 selectReplacement, smartReplace, |
1673 InputEvent::InputType::InsertReplacementText); | 1696 InputEvent::InputType::InsertReplacementText); |
1674 } | 1697 } |
1675 | 1698 |
| 1699 void Editor::replaceSelectionForSpellChecker(const String& text) { |
| 1700 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
| 1701 const bool kSelectReplacement = false; |
| 1702 const bool kSmartReplace = false; |
| 1703 replaceSelectionWithText(EditCommandSource::kMenuOrKeyBinding, text, |
| 1704 kSelectReplacement, kSmartReplace, |
| 1705 InputEvent::InputType::InsertReplacementText); |
| 1706 } |
| 1707 |
1676 DEFINE_TRACE(Editor) { | 1708 DEFINE_TRACE(Editor) { |
1677 visitor->trace(m_frame); | 1709 visitor->trace(m_frame); |
1678 visitor->trace(m_lastEditCommand); | 1710 visitor->trace(m_lastEditCommand); |
1679 visitor->trace(m_undoStack); | 1711 visitor->trace(m_undoStack); |
1680 visitor->trace(m_mark); | 1712 visitor->trace(m_mark); |
1681 } | 1713 } |
1682 | 1714 |
1683 } // namespace blink | 1715 } // namespace blink |
OLD | NEW |