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 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 CommandSource::MenuOrKeyBinding, 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(event->data(), false, |
| 226 event->shouldSmartReplace(), | 227 event->shouldSmartReplace(), |
| 227 InputEvent::InputType::InsertFromPaste); | 228 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(CommandSource::MenuOrKeyBinding, |
| 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(CommandSource 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 17 matching lines...) Expand all Loading... | |
| 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 |
| 374 void Editor::deleteSelectionWithSmartDelete( | 378 void Editor::deleteSelectionWithSmartDelete( |
| 379 CommandSource, | |
|
Xiaocheng
2016/12/15 03:27:50
Please add a TODO about future plan so that other
chongz
2016/12/16 00:45:22
Done.
| |
| 375 DeleteMode deleteMode, | 380 DeleteMode deleteMode, |
| 376 InputEvent::InputType inputType, | 381 InputEvent::InputType inputType, |
| 377 const Position& referenceMovePosition) { | 382 const Position& referenceMovePosition) { |
| 378 if (frame().selection().isNone()) | 383 if (frame().selection().isNone()) |
| 379 return; | 384 return; |
| 380 | 385 |
| 381 const bool kMergeBlocksAfterDelete = true; | 386 const bool kMergeBlocksAfterDelete = true; |
| 382 const bool kExpandForSpecialElements = false; | 387 const bool kExpandForSpecialElements = false; |
| 383 const bool kSanitizeMarkup = true; | 388 const bool kSanitizeMarkup = true; |
| 384 DCHECK(frame().document()); | 389 DCHECK(frame().document()); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 // invalidate clipboard here for security | 562 // invalidate clipboard here for security |
| 558 dataTransfer->setAccessPolicy(DataTransferNumb); | 563 dataTransfer->setAccessPolicy(DataTransferNumb); |
| 559 | 564 |
| 560 return !noDefaultProcessing; | 565 return !noDefaultProcessing; |
| 561 } | 566 } |
| 562 | 567 |
| 563 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) { | 568 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) { |
| 564 return smartInsertDeleteEnabled() && pasteboard->canSmartReplace(); | 569 return smartInsertDeleteEnabled() && pasteboard->canSmartReplace(); |
| 565 } | 570 } |
| 566 | 571 |
| 567 void Editor::replaceSelectionWithFragment(DocumentFragment* fragment, | 572 void Editor::replaceSelectionWithFragment(CommandSource, |
|
Xiaocheng
2016/12/15 03:27:50
Please add a TODO about future plan so that other
chongz
2016/12/16 00:45:22
Done.
| |
| 573 DocumentFragment* fragment, | |
| 568 bool selectReplacement, | 574 bool selectReplacement, |
| 569 bool smartReplace, | 575 bool smartReplace, |
| 570 bool matchStyle, | 576 bool matchStyle, |
| 571 InputEvent::InputType inputType) { | 577 InputEvent::InputType inputType) { |
| 572 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 578 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
| 573 if (frame().selection().isNone() || | 579 if (frame().selection().isNone() || |
| 574 !frame().selection().isContentEditable() || !fragment) | 580 !frame().selection().isContentEditable() || !fragment) |
| 575 return; | 581 return; |
| 576 | 582 |
| 577 ReplaceSelectionCommand::CommandOptions options = | 583 ReplaceSelectionCommand::CommandOptions options = |
| 578 ReplaceSelectionCommand::PreventNesting | | 584 ReplaceSelectionCommand::PreventNesting | |
| 579 ReplaceSelectionCommand::SanitizeFragment; | 585 ReplaceSelectionCommand::SanitizeFragment; |
| 580 if (selectReplacement) | 586 if (selectReplacement) |
| 581 options |= ReplaceSelectionCommand::SelectReplacement; | 587 options |= ReplaceSelectionCommand::SelectReplacement; |
| 582 if (smartReplace) | 588 if (smartReplace) |
| 583 options |= ReplaceSelectionCommand::SmartReplace; | 589 options |= ReplaceSelectionCommand::SmartReplace; |
| 584 if (matchStyle) | 590 if (matchStyle) |
| 585 options |= ReplaceSelectionCommand::MatchStyle; | 591 options |= ReplaceSelectionCommand::MatchStyle; |
| 586 DCHECK(frame().document()); | 592 DCHECK(frame().document()); |
| 587 ReplaceSelectionCommand::create(*frame().document(), fragment, options, | 593 ReplaceSelectionCommand::create(*frame().document(), fragment, options, |
| 588 inputType) | 594 inputType) |
| 589 ->apply(); | 595 ->apply(); |
| 590 revealSelectionAfterEditingOperation(); | 596 revealSelectionAfterEditingOperation(); |
| 591 } | 597 } |
| 592 | 598 |
| 593 void Editor::replaceSelectionWithText(const String& text, | 599 void Editor::replaceSelectionWithText(const String& text, |
| 594 bool selectReplacement, | 600 bool selectReplacement, |
| 595 bool smartReplace, | 601 bool smartReplace, |
| 596 InputEvent::InputType inputType) { | 602 InputEvent::InputType inputType, |
| 597 replaceSelectionWithFragment(createFragmentFromText(selectedRange(), text), | 603 CommandSource source) { |
| 598 selectReplacement, smartReplace, true, | 604 replaceSelectionWithFragment( |
| 599 inputType); | 605 source, createFragmentFromText(selectedRange(), text), selectReplacement, |
| 606 smartReplace, true, inputType); | |
| 600 } | 607 } |
| 601 | 608 |
| 602 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. | 609 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. |
| 603 void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, | 610 void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, |
| 604 InsertMode insertMode, | 611 InsertMode insertMode, |
| 605 DragSourceType dragSourceType) { | 612 DragSourceType dragSourceType) { |
| 606 ReplaceSelectionCommand::CommandOptions options = | 613 ReplaceSelectionCommand::CommandOptions options = |
| 607 ReplaceSelectionCommand::SelectReplacement | | 614 ReplaceSelectionCommand::SelectReplacement | |
| 608 ReplaceSelectionCommand::PreventNesting; | 615 ReplaceSelectionCommand::PreventNesting; |
| 609 if (insertMode == InsertMode::Smart) | 616 if (insertMode == InsertMode::Smart) |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 627 const bool shouldDelete = dispatchBeforeInputEditorCommand( | 634 const bool shouldDelete = dispatchBeforeInputEditorCommand( |
| 628 dragSource, InputEvent::InputType::DeleteByDrag, | 635 dragSource, InputEvent::InputType::DeleteByDrag, |
| 629 nullptr) == DispatchEventResult::NotCanceled; | 636 nullptr) == DispatchEventResult::NotCanceled; |
| 630 | 637 |
| 631 // 'beforeinput' event handler may destroy frame, return false to cancel | 638 // 'beforeinput' event handler may destroy frame, return false to cancel |
| 632 // remaining actions; | 639 // remaining actions; |
| 633 if (m_frame->document()->frame() != m_frame) | 640 if (m_frame->document()->frame() != m_frame) |
| 634 return false; | 641 return false; |
| 635 | 642 |
| 636 if (shouldDelete && dragSource->isConnected()) { | 643 if (shouldDelete && dragSource->isConnected()) { |
| 637 deleteSelectionWithSmartDelete( | 644 deleteSelectionWithSmartDelete(CommandSource::MenuOrKeyBinding, deleteMode, |
| 638 deleteMode, InputEvent::InputType::DeleteByDrag, referenceMovePosition); | 645 InputEvent::InputType::DeleteByDrag, |
| 646 referenceMovePosition); | |
| 639 } | 647 } |
| 640 | 648 |
| 641 return true; | 649 return true; |
| 642 } | 650 } |
| 643 | 651 |
| 644 bool Editor::replaceSelectionAfterDraggingWithEvents( | 652 bool Editor::replaceSelectionAfterDraggingWithEvents( |
| 645 Element* dropTarget, | 653 Element* dropTarget, |
| 646 DragData* dragData, | 654 DragData* dragData, |
| 647 DocumentFragment* fragment, | 655 DocumentFragment* fragment, |
| 648 Range* dropCaretRange, | 656 Range* dropCaretRange, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 692 if (frame().settings() && frame().settings()->accessibilityEnabled()) { | 700 if (frame().settings() && frame().settings()->accessibilityEnabled()) { |
| 693 Node* node = endingSelection.start().anchorNode(); | 701 Node* node = endingSelection.start().anchorNode(); |
| 694 if (AXObjectCache* cache = frame().document()->existingAXObjectCache()) | 702 if (AXObjectCache* cache = frame().document()->existingAXObjectCache()) |
| 695 cache->handleEditableTextContentChanged(node); | 703 cache->handleEditableTextContentChanged(node); |
| 696 } | 704 } |
| 697 | 705 |
| 698 spellChecker().updateMarkersForWordsAffectedByEditing(true); | 706 spellChecker().updateMarkersForWordsAffectedByEditing(true); |
| 699 client().respondToChangedContents(); | 707 client().respondToChangedContents(); |
| 700 } | 708 } |
| 701 | 709 |
| 702 void Editor::removeFormattingAndStyle() { | 710 void Editor::removeFormattingAndStyle(CommandSource) { |
|
Xiaocheng
2016/12/15 03:27:50
Please add a TODO about future plan so that other
chongz
2016/12/16 00:45:22
Done.
| |
| 703 DCHECK(frame().document()); | 711 DCHECK(frame().document()); |
| 704 RemoveFormatCommand::create(*frame().document())->apply(); | 712 RemoveFormatCommand::create(*frame().document())->apply(); |
| 705 } | 713 } |
| 706 | 714 |
| 707 void Editor::registerCommandGroup(CompositeEditCommand* commandGroupWrapper) { | 715 void Editor::registerCommandGroup(CompositeEditCommand* commandGroupWrapper) { |
| 708 DCHECK(commandGroupWrapper->isCommandGroupWrapper()); | 716 DCHECK(commandGroupWrapper->isCommandGroupWrapper()); |
| 709 m_lastEditCommand = commandGroupWrapper; | 717 m_lastEditCommand = commandGroupWrapper; |
| 710 } | 718 } |
| 711 | 719 |
| 712 void Editor::clearLastEditCommand() { | 720 void Editor::clearLastEditCommand() { |
| 713 m_lastEditCommand.clear(); | 721 m_lastEditCommand.clear(); |
| 714 } | 722 } |
| 715 | 723 |
| 716 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const { | 724 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const { |
| 717 Element* target = associatedElementOf(selection.start()); | 725 Element* target = associatedElementOf(selection.start()); |
| 718 if (!target) | 726 if (!target) |
| 719 target = frame().document()->body(); | 727 target = frame().document()->body(); |
| 720 | 728 |
| 721 return target; | 729 return target; |
| 722 } | 730 } |
| 723 | 731 |
| 724 Element* Editor::findEventTargetFromSelection() const { | 732 Element* Editor::findEventTargetFromSelection() const { |
| 725 return findEventTargetFrom(frame().selection().selection()); | 733 return findEventTargetFrom(frame().selection().selection()); |
| 726 } | 734 } |
| 727 | 735 |
| 728 void Editor::applyStyle(StylePropertySet* style, | 736 void Editor::applyStyle(CommandSource source, |
| 737 StylePropertySet* style, | |
| 729 InputEvent::InputType inputType) { | 738 InputEvent::InputType inputType) { |
| 730 switch (frame().selection().getSelectionType()) { | 739 switch (frame().selection().getSelectionType()) { |
| 731 case NoSelection: | 740 case NoSelection: |
| 732 // do nothing | 741 // do nothing |
| 733 break; | 742 break; |
| 734 case CaretSelection: | 743 case CaretSelection: |
| 735 computeAndSetTypingStyle(style, inputType); | 744 computeAndSetTypingStyle(source, style, inputType); |
| 736 break; | 745 break; |
| 737 case RangeSelection: | 746 case RangeSelection: |
| 738 if (style) { | 747 if (style) { |
| 739 DCHECK(frame().document()); | 748 DCHECK(frame().document()); |
| 740 ApplyStyleCommand::create(*frame().document(), | 749 ApplyStyleCommand::create(*frame().document(), |
| 741 EditingStyle::create(style), inputType) | 750 EditingStyle::create(style), inputType) |
| 742 ->apply(); | 751 ->apply(); |
| 743 } | 752 } |
| 744 break; | 753 break; |
| 745 } | 754 } |
| 746 } | 755 } |
| 747 | 756 |
| 748 void Editor::applyParagraphStyle(StylePropertySet* style, | 757 void Editor::applyParagraphStyle(CommandSource, |
|
Xiaocheng
2016/12/15 03:27:50
Please add a TODO about future plan so that other
chongz
2016/12/16 00:45:22
Done.
| |
| 758 StylePropertySet* style, | |
| 749 InputEvent::InputType inputType) { | 759 InputEvent::InputType inputType) { |
| 750 if (frame().selection().isNone() || !style) | 760 if (frame().selection().isNone() || !style) |
| 751 return; | 761 return; |
| 752 DCHECK(frame().document()); | 762 DCHECK(frame().document()); |
| 753 ApplyStyleCommand::create(*frame().document(), EditingStyle::create(style), | 763 ApplyStyleCommand::create(*frame().document(), EditingStyle::create(style), |
| 754 inputType, ApplyStyleCommand::ForceBlockProperties) | 764 inputType, ApplyStyleCommand::ForceBlockProperties) |
| 755 ->apply(); | 765 ->apply(); |
| 756 } | 766 } |
| 757 | 767 |
| 758 void Editor::applyStyleToSelection(StylePropertySet* style, | 768 void Editor::applyStyleToSelection(CommandSource source, |
| 769 StylePropertySet* style, | |
| 759 InputEvent::InputType inputType) { | 770 InputEvent::InputType inputType) { |
| 760 if (!style || style->isEmpty() || !canEditRichly()) | 771 if (!style || style->isEmpty() || !canEditRichly()) |
| 761 return; | 772 return; |
| 762 | 773 |
| 763 applyStyle(style, inputType); | 774 applyStyle(source, style, inputType); |
| 764 } | 775 } |
| 765 | 776 |
| 766 void Editor::applyParagraphStyleToSelection(StylePropertySet* style, | 777 void Editor::applyParagraphStyleToSelection(CommandSource source, |
| 778 StylePropertySet* style, | |
| 767 InputEvent::InputType inputType) { | 779 InputEvent::InputType inputType) { |
| 768 if (!style || style->isEmpty() || !canEditRichly()) | 780 if (!style || style->isEmpty() || !canEditRichly()) |
| 769 return; | 781 return; |
| 770 | 782 |
| 771 applyParagraphStyle(style, inputType); | 783 applyParagraphStyle(source, style, inputType); |
| 772 } | 784 } |
| 773 | 785 |
| 774 bool Editor::selectionStartHasStyle(CSSPropertyID propertyID, | 786 bool Editor::selectionStartHasStyle(CSSPropertyID propertyID, |
| 775 const String& value) const { | 787 const String& value) const { |
| 776 EditingStyle* styleToCheck = EditingStyle::create(propertyID, value); | 788 EditingStyle* styleToCheck = EditingStyle::create(propertyID, value); |
| 777 EditingStyle* styleAtStart = EditingStyle::styleAtSelectionStart( | 789 EditingStyle* styleAtStart = EditingStyle::styleAtSelectionStart( |
| 778 frame().selection().selection(), propertyID == CSSPropertyBackgroundColor, | 790 frame().selection().selection(), propertyID == CSSPropertyBackgroundColor, |
| 779 styleToCheck->style()); | 791 styleToCheck->style()); |
| 780 return styleToCheck->triStateOfStyle(styleAtStart); | 792 return styleToCheck->triStateOfStyle(styleAtStart); |
| 781 } | 793 } |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 947 frame().inputMethodController().clear(); | 959 frame().inputMethodController().clear(); |
| 948 m_shouldStyleWithCSS = false; | 960 m_shouldStyleWithCSS = false; |
| 949 m_defaultParagraphSeparator = EditorParagraphSeparatorIsDiv; | 961 m_defaultParagraphSeparator = EditorParagraphSeparatorIsDiv; |
| 950 m_undoStack->clear(); | 962 m_undoStack->clear(); |
| 951 } | 963 } |
| 952 | 964 |
| 953 bool Editor::insertText(const String& text, KeyboardEvent* triggeringEvent) { | 965 bool Editor::insertText(const String& text, KeyboardEvent* triggeringEvent) { |
| 954 return frame().eventHandler().handleTextInputEvent(text, triggeringEvent); | 966 return frame().eventHandler().handleTextInputEvent(text, triggeringEvent); |
| 955 } | 967 } |
| 956 | 968 |
| 957 bool Editor::insertTextWithoutSendingTextEvent(const String& text, | 969 bool Editor::insertTextWithoutSendingTextEvent(CommandSource source, |
| 970 const String& text, | |
| 958 bool selectInsertedText, | 971 bool selectInsertedText, |
| 959 TextEvent* triggeringEvent) { | 972 TextEvent* triggeringEvent) { |
| 960 if (text.isEmpty()) | 973 if (text.isEmpty()) |
| 961 return false; | 974 return false; |
| 962 | 975 |
| 963 const VisibleSelection& selection = selectionForCommand(triggeringEvent); | 976 const VisibleSelection& selection = selectionForCommand(triggeringEvent); |
| 964 if (!selection.isContentEditable()) | 977 if (!selection.isContentEditable()) |
| 965 return false; | 978 return false; |
| 966 | 979 |
| 967 spellChecker().updateMarkersForWordsAffectedByEditing( | 980 spellChecker().updateMarkersForWordsAffectedByEditing( |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1052 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(), | 1065 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(), |
| 1053 InputEvent::InputType::DeleteByCut, | 1066 InputEvent::InputType::DeleteByCut, |
| 1054 nullptr, nullptr) != | 1067 nullptr, nullptr) != |
| 1055 DispatchEventResult::NotCanceled) | 1068 DispatchEventResult::NotCanceled) |
| 1056 return; | 1069 return; |
| 1057 // 'beforeinput' event handler may destroy target frame. | 1070 // 'beforeinput' event handler may destroy target frame. |
| 1058 if (m_frame->document()->frame() != m_frame) | 1071 if (m_frame->document()->frame() != m_frame) |
| 1059 return; | 1072 return; |
| 1060 } | 1073 } |
| 1061 deleteSelectionWithSmartDelete( | 1074 deleteSelectionWithSmartDelete( |
| 1062 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, | 1075 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, |
| 1063 InputEvent::InputType::DeleteByCut); | 1076 InputEvent::InputType::DeleteByCut); |
| 1064 } | 1077 } |
| 1065 } | 1078 } |
| 1066 | 1079 |
| 1067 void Editor::copy() { | 1080 void Editor::copy() { |
| 1068 if (tryDHTMLCopy()) | 1081 if (tryDHTMLCopy()) |
| 1069 return; // DHTML did the whole operation | 1082 return; // DHTML did the whole operation |
| 1070 if (!canCopy()) | 1083 if (!canCopy()) |
| 1071 return; | 1084 return; |
| 1072 | 1085 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1129 | 1142 |
| 1130 void Editor::pasteAsPlainText(CommandSource source) { | 1143 void Editor::pasteAsPlainText(CommandSource source) { |
| 1131 if (tryDHTMLPaste(PlainTextOnly)) | 1144 if (tryDHTMLPaste(PlainTextOnly)) |
| 1132 return; | 1145 return; |
| 1133 if (!canPaste()) | 1146 if (!canPaste()) |
| 1134 return; | 1147 return; |
| 1135 spellChecker().updateMarkersForWordsAffectedByEditing(false); | 1148 spellChecker().updateMarkersForWordsAffectedByEditing(false); |
| 1136 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); | 1149 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); |
| 1137 } | 1150 } |
| 1138 | 1151 |
| 1139 void Editor::performDelete() { | 1152 void Editor::performDelete(CommandSource source) { |
| 1140 if (!canDelete()) | 1153 if (!canDelete()) |
| 1141 return; | 1154 return; |
| 1142 | 1155 |
| 1143 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 1156 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 1144 // needs to be audited. See http://crbug.com/590369 for more details. | 1157 // needs to be audited. See http://crbug.com/590369 for more details. |
| 1145 // |selectedRange| requires clean layout for visible selection normalization. | 1158 // |selectedRange| requires clean layout for visible selection normalization. |
| 1146 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1159 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 1147 | 1160 |
| 1148 addToKillRing(selectedRange()); | 1161 addToKillRing(selectedRange()); |
| 1149 // TODO(chongz): |Editor::performDelete()| has no direction. | 1162 // TODO(chongz): |Editor::performDelete()| has no direction. |
| 1150 // https://github.com/w3c/editing/issues/130 | 1163 // https://github.com/w3c/editing/issues/130 |
| 1151 deleteSelectionWithSmartDelete( | 1164 deleteSelectionWithSmartDelete( |
| 1152 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, | 1165 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, |
| 1153 InputEvent::InputType::DeleteContentBackward); | 1166 InputEvent::InputType::DeleteContentBackward); |
| 1154 | 1167 |
| 1155 // clear the "start new kill ring sequence" setting, because it was set to | 1168 // clear the "start new kill ring sequence" setting, because it was set to |
| 1156 // true when the selection was updated by deleting the range | 1169 // true when the selection was updated by deleting the range |
| 1157 setStartNewKillRingSequence(false); | 1170 setStartNewKillRingSequence(false); |
| 1158 } | 1171 } |
| 1159 | 1172 |
| 1160 static void countEditingEvent(ExecutionContext* executionContext, | 1173 static void countEditingEvent(ExecutionContext* executionContext, |
| 1161 const Event* event, | 1174 const Event* event, |
| 1162 UseCounter::Feature featureOnInput, | 1175 UseCounter::Feature featureOnInput, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1229 void Editor::copyImage(const HitTestResult& result) { | 1242 void Editor::copyImage(const HitTestResult& result) { |
| 1230 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), | 1243 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), |
| 1231 result.innerNodeOrImageMapImage(), | 1244 result.innerNodeOrImageMapImage(), |
| 1232 result.altDisplayString()); | 1245 result.altDisplayString()); |
| 1233 } | 1246 } |
| 1234 | 1247 |
| 1235 bool Editor::canUndo() { | 1248 bool Editor::canUndo() { |
| 1236 return m_undoStack->canUndo(); | 1249 return m_undoStack->canUndo(); |
| 1237 } | 1250 } |
| 1238 | 1251 |
| 1239 void Editor::undo() { | 1252 void Editor::undo(CommandSource) { |
|
Xiaocheng
2016/12/15 03:27:50
How are we going to use CommandSource here?
chongz
2016/12/16 00:45:22
We are going to fire a 'beforeinput' for user trig
| |
| 1240 m_undoStack->undo(); | 1253 m_undoStack->undo(); |
| 1241 } | 1254 } |
| 1242 | 1255 |
| 1243 bool Editor::canRedo() { | 1256 bool Editor::canRedo() { |
| 1244 return m_undoStack->canRedo(); | 1257 return m_undoStack->canRedo(); |
| 1245 } | 1258 } |
| 1246 | 1259 |
| 1247 void Editor::redo() { | 1260 void Editor::redo(CommandSource) { |
|
Xiaocheng
2016/12/15 03:27:50
Same question as undo.
chongz
2016/12/16 00:45:22
Same as above.
| |
| 1248 m_undoStack->redo(); | 1261 m_undoStack->redo(); |
| 1249 } | 1262 } |
| 1250 | 1263 |
| 1251 void Editor::setBaseWritingDirection(WritingDirection direction) { | 1264 void Editor::setBaseWritingDirection(WritingDirection direction) { |
| 1252 Element* focusedElement = frame().document()->focusedElement(); | 1265 Element* focusedElement = frame().document()->focusedElement(); |
| 1253 if (isTextControlElement(focusedElement)) { | 1266 if (isTextControlElement(focusedElement)) { |
| 1254 if (direction == NaturalWritingDirection) | 1267 if (direction == NaturalWritingDirection) |
| 1255 return; | 1268 return; |
| 1256 focusedElement->setAttribute( | 1269 focusedElement->setAttribute( |
| 1257 dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl"); | 1270 dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl"); |
| 1258 focusedElement->dispatchInputEvent(); | 1271 focusedElement->dispatchInputEvent(); |
| 1259 return; | 1272 return; |
| 1260 } | 1273 } |
| 1261 | 1274 |
| 1262 MutableStylePropertySet* style = | 1275 MutableStylePropertySet* style = |
| 1263 MutableStylePropertySet::create(HTMLQuirksMode); | 1276 MutableStylePropertySet::create(HTMLQuirksMode); |
| 1264 style->setProperty( | 1277 style->setProperty( |
| 1265 CSSPropertyDirection, | 1278 CSSPropertyDirection, |
| 1266 direction == LeftToRightWritingDirection | 1279 direction == LeftToRightWritingDirection |
| 1267 ? "ltr" | 1280 ? "ltr" |
| 1268 : direction == RightToLeftWritingDirection ? "rtl" : "inherit", | 1281 : direction == RightToLeftWritingDirection ? "rtl" : "inherit", |
| 1269 false); | 1282 false); |
| 1270 applyParagraphStyleToSelection( | 1283 applyParagraphStyleToSelection( |
| 1271 style, InputEvent::InputType::FormatSetBlockTextDirection); | 1284 CommandSource::MenuOrKeyBinding, style, |
| 1285 InputEvent::InputType::FormatSetBlockTextDirection); | |
| 1272 } | 1286 } |
| 1273 | 1287 |
| 1274 void Editor::revealSelectionAfterEditingOperation( | 1288 void Editor::revealSelectionAfterEditingOperation( |
| 1275 const ScrollAlignment& alignment, | 1289 const ScrollAlignment& alignment, |
| 1276 RevealExtentOption revealExtentOption) { | 1290 RevealExtentOption revealExtentOption) { |
| 1277 if (m_preventRevealSelection) | 1291 if (m_preventRevealSelection) |
| 1278 return; | 1292 return; |
| 1279 frame().selection().revealSelection(alignment, revealExtentOption); | 1293 frame().selection().revealSelection(alignment, revealExtentOption); |
| 1280 } | 1294 } |
| 1281 | 1295 |
| 1282 void Editor::transpose() { | 1296 void Editor::transpose(CommandSource source) { |
| 1283 if (!canEdit()) | 1297 if (!canEdit()) |
| 1284 return; | 1298 return; |
| 1285 | 1299 |
| 1286 VisibleSelection selection = frame().selection().selection(); | 1300 VisibleSelection selection = frame().selection().selection(); |
| 1287 if (!selection.isCaret()) | 1301 if (!selection.isCaret()) |
| 1288 return; | 1302 return; |
| 1289 | 1303 |
| 1290 // Make a selection that goes back one character and forward two characters. | 1304 // Make a selection that goes back one character and forward two characters. |
| 1291 VisiblePosition caret = selection.visibleStart(); | 1305 VisiblePosition caret = selection.visibleStart(); |
| 1292 VisiblePosition next = | 1306 VisiblePosition next = |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1310 String transposed = text.right(1) + text.left(1); | 1324 String transposed = text.right(1) + text.left(1); |
| 1311 | 1325 |
| 1312 // Select the two characters. | 1326 // Select the two characters. |
| 1313 if (newSelection != frame().selection().selection()) | 1327 if (newSelection != frame().selection().selection()) |
| 1314 frame().selection().setSelection(newSelection); | 1328 frame().selection().setSelection(newSelection); |
| 1315 | 1329 |
| 1316 // Insert the transposed characters. | 1330 // Insert the transposed characters. |
| 1317 // TODO(chongz): Once we add |InsertTranspose| in |InputEvent::InputType|, we | 1331 // TODO(chongz): Once we add |InsertTranspose| in |InputEvent::InputType|, we |
| 1318 // should use it instead of |InsertFromPaste|. | 1332 // should use it instead of |InsertFromPaste|. |
| 1319 replaceSelectionWithText(transposed, false, false, | 1333 replaceSelectionWithText(transposed, false, false, |
| 1320 InputEvent::InputType::InsertFromPaste); | 1334 InputEvent::InputType::InsertFromPaste, source); |
| 1321 } | 1335 } |
| 1322 | 1336 |
| 1323 void Editor::addToKillRing(const EphemeralRange& range) { | 1337 void Editor::addToKillRing(const EphemeralRange& range) { |
| 1324 if (m_shouldStartNewKillRingSequence) | 1338 if (m_shouldStartNewKillRingSequence) |
| 1325 killRing().startNewSequence(); | 1339 killRing().startNewSequence(); |
| 1326 | 1340 |
| 1327 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 1341 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
| 1328 String text = plainText(range); | 1342 String text = plainText(range); |
| 1329 killRing().append(text); | 1343 killRing().append(text); |
| 1330 m_shouldStartNewKillRingSequence = false; | 1344 m_shouldStartNewKillRingSequence = false; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1390 std::max(startCaretRect.height(), endCaretRect.height())); | 1404 std::max(startCaretRect.height(), endCaretRect.height())); |
| 1391 } | 1405 } |
| 1392 | 1406 |
| 1393 // start and end aren't on the same line, so go from start to the end of its | 1407 // start and end aren't on the same line, so go from start to the end of its |
| 1394 // line | 1408 // line |
| 1395 return IntRect(startCaretRect.x(), startCaretRect.y(), | 1409 return IntRect(startCaretRect.x(), startCaretRect.y(), |
| 1396 (startCaretRect.width() + extraWidthToEndOfLine).toInt(), | 1410 (startCaretRect.width() + extraWidthToEndOfLine).toInt(), |
| 1397 startCaretRect.height()); | 1411 startCaretRect.height()); |
| 1398 } | 1412 } |
| 1399 | 1413 |
| 1400 void Editor::computeAndSetTypingStyle(StylePropertySet* style, | 1414 void Editor::computeAndSetTypingStyle(CommandSource, |
|
Xiaocheng
2016/12/15 03:27:50
Please add a TODO about future plan so that other
chongz
2016/12/16 00:45:22
Done.
| |
| 1415 StylePropertySet* style, | |
| 1401 InputEvent::InputType inputType) { | 1416 InputEvent::InputType inputType) { |
| 1402 if (!style || style->isEmpty()) { | 1417 if (!style || style->isEmpty()) { |
| 1403 frame().selection().clearTypingStyle(); | 1418 frame().selection().clearTypingStyle(); |
| 1404 return; | 1419 return; |
| 1405 } | 1420 } |
| 1406 | 1421 |
| 1407 // Calculate the current typing style. | 1422 // Calculate the current typing style. |
| 1408 EditingStyle* typingStyle = nullptr; | 1423 EditingStyle* typingStyle = nullptr; |
| 1409 if (frame().selection().typingStyle()) { | 1424 if (frame().selection().typingStyle()) { |
| 1410 typingStyle = frame().selection().typingStyle()->copy(); | 1425 typingStyle = frame().selection().typingStyle()->copy(); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1666 } | 1681 } |
| 1667 | 1682 |
| 1668 DEFINE_TRACE(Editor) { | 1683 DEFINE_TRACE(Editor) { |
| 1669 visitor->trace(m_frame); | 1684 visitor->trace(m_frame); |
| 1670 visitor->trace(m_lastEditCommand); | 1685 visitor->trace(m_lastEditCommand); |
| 1671 visitor->trace(m_undoStack); | 1686 visitor->trace(m_undoStack); |
| 1672 visitor->trace(m_mark); | 1687 visitor->trace(m_mark); |
| 1673 } | 1688 } |
| 1674 | 1689 |
| 1675 } // namespace blink | 1690 } // namespace blink |
| OLD | NEW |