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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 if (event->isDrop()) | 207 if (event->isDrop()) |
| 208 return false; | 208 return false; |
| 209 | 209 |
| 210 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 210 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 211 // needs to be audited. See http://crbug.com/590369 for more details. | 211 // needs to be audited. See http://crbug.com/590369 for more details. |
| 212 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 212 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 213 | 213 |
| 214 if (event->isPaste()) { | 214 if (event->isPaste()) { |
| 215 if (event->pastingFragment()) { | 215 if (event->pastingFragment()) { |
| 216 replaceSelectionWithFragment( | 216 replaceSelectionWithFragment( |
| 217 event->pastingFragment(), false, event->shouldSmartReplace(), | 217 CommandSource::MenuOrKeyBinding, event->pastingFragment(), false, |
| 218 event->shouldMatchStyle(), InputEvent::InputType::InsertFromPaste); | 218 event->shouldSmartReplace(), event->shouldMatchStyle(), |
| 219 InputEvent::InputType::InsertFromPaste); | |
| 219 } else { | 220 } else { |
| 220 replaceSelectionWithText(event->data(), false, | 221 replaceSelectionWithText(CommandSource::MenuOrKeyBinding, event->data(), |
| 221 event->shouldSmartReplace(), | 222 false, event->shouldSmartReplace(), |
| 222 InputEvent::InputType::InsertFromPaste); | 223 InputEvent::InputType::InsertFromPaste); |
| 223 } | 224 } |
| 224 return true; | 225 return true; |
| 225 } | 226 } |
| 226 | 227 |
| 227 String data = event->data(); | 228 String data = event->data(); |
| 228 if (data == "\n") { | 229 if (data == "\n") { |
| 229 if (event->isLineBreak()) | 230 if (event->isLineBreak()) |
| 230 return insertLineBreak(); | 231 return insertLineBreak(); |
| 231 return insertParagraphSeparator(); | 232 return insertParagraphSeparator(); |
| 232 } | 233 } |
| 233 | 234 |
| 234 return insertTextWithoutSendingTextEvent(data, false, event); | 235 return insertTextWithoutSendingTextEvent(CommandSource::MenuOrKeyBinding, |
| 236 data, false, event); | |
| 235 } | 237 } |
| 236 | 238 |
| 237 bool Editor::canEdit() const { | 239 bool Editor::canEdit() const { |
| 238 return frame().selection().rootEditableElement(); | 240 return frame().selection().rootEditableElement(); |
| 239 } | 241 } |
| 240 | 242 |
| 241 bool Editor::canEditRichly() const { | 243 bool Editor::canEditRichly() const { |
| 242 return frame().selection().isContentRichlyEditable(); | 244 return frame().selection().isContentRichlyEditable(); |
| 243 } | 245 } |
| 244 | 246 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 return smartInsertDeleteEnabled() && | 306 return smartInsertDeleteEnabled() && |
| 305 frame().selection().granularity() == WordGranularity; | 307 frame().selection().granularity() == WordGranularity; |
| 306 } | 308 } |
| 307 | 309 |
| 308 bool Editor::isSelectTrailingWhitespaceEnabled() const { | 310 bool Editor::isSelectTrailingWhitespaceEnabled() const { |
| 309 if (Settings* settings = frame().settings()) | 311 if (Settings* settings = frame().settings()) |
| 310 return settings->selectTrailingWhitespaceEnabled(); | 312 return settings->selectTrailingWhitespaceEnabled(); |
| 311 return false; | 313 return false; |
| 312 } | 314 } |
| 313 | 315 |
| 314 bool Editor::deleteWithDirection(DeleteDirection direction, | 316 bool Editor::deleteWithDirection(CommandSource source, |
| 317 DeleteDirection direction, | |
| 315 TextGranularity granularity, | 318 TextGranularity granularity, |
| 316 bool killRing, | 319 bool killRing, |
| 317 bool isTypingAction) { | 320 bool isTypingAction) { |
| 318 if (!canEdit()) | 321 if (!canEdit()) |
| 319 return false; | 322 return false; |
| 320 | 323 |
| 321 EditingState editingState; | 324 EditingState editingState; |
| 322 if (frame().selection().isRange()) { | 325 if (frame().selection().isRange()) { |
| 323 if (isTypingAction) { | 326 if (isTypingAction) { |
| 324 DCHECK(frame().document()); | 327 DCHECK(frame().document()); |
| 325 TypingCommand::deleteKeyPressed( | 328 TypingCommand::deleteKeyPressed( |
| 326 *frame().document(), | 329 *frame().document(), source, |
| 327 canSmartCopyOrDelete() ? TypingCommand::SmartDelete : 0, granularity); | 330 canSmartCopyOrDelete() ? TypingCommand::SmartDelete : 0, granularity); |
| 328 revealSelectionAfterEditingOperation(); | 331 revealSelectionAfterEditingOperation(); |
| 329 } else { | 332 } else { |
| 330 if (killRing) | 333 if (killRing) |
| 331 addToKillRing(selectedRange()); | 334 addToKillRing(selectedRange()); |
| 332 deleteSelectionWithSmartDelete( | 335 deleteSelectionWithSmartDelete( |
| 336 source, | |
| 333 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, | 337 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, |
| 334 deletionInputTypeFromTextGranularity(direction, granularity)); | 338 deletionInputTypeFromTextGranularity(direction, granularity)); |
| 335 // Implicitly calls revealSelectionAfterEditingOperation(). | 339 // Implicitly calls revealSelectionAfterEditingOperation(). |
| 336 } | 340 } |
| 337 } else { | 341 } else { |
| 338 TypingCommand::Options options = 0; | 342 TypingCommand::Options options = 0; |
| 339 if (canSmartCopyOrDelete()) | 343 if (canSmartCopyOrDelete()) |
| 340 options |= TypingCommand::SmartDelete; | 344 options |= TypingCommand::SmartDelete; |
| 341 if (killRing) | 345 if (killRing) |
| 342 options |= TypingCommand::KillRing; | 346 options |= TypingCommand::KillRing; |
| 343 switch (direction) { | 347 switch (direction) { |
| 344 case DeleteDirection::Forward: | 348 case DeleteDirection::Forward: |
| 345 DCHECK(frame().document()); | 349 DCHECK(frame().document()); |
| 346 TypingCommand::forwardDeleteKeyPressed( | 350 TypingCommand::forwardDeleteKeyPressed( |
| 347 *frame().document(), &editingState, options, granularity); | 351 *frame().document(), source, &editingState, options, granularity); |
| 348 if (editingState.isAborted()) | 352 if (editingState.isAborted()) |
| 349 return false; | 353 return false; |
| 350 break; | 354 break; |
| 351 case DeleteDirection::Backward: | 355 case DeleteDirection::Backward: |
| 352 DCHECK(frame().document()); | 356 DCHECK(frame().document()); |
| 353 TypingCommand::deleteKeyPressed(*frame().document(), options, | 357 TypingCommand::deleteKeyPressed(*frame().document(), source, options, |
| 354 granularity); | 358 granularity); |
| 355 break; | 359 break; |
| 356 } | 360 } |
| 357 revealSelectionAfterEditingOperation(); | 361 revealSelectionAfterEditingOperation(); |
| 358 } | 362 } |
| 359 | 363 |
| 360 // FIXME: We should to move this down into deleteKeyPressed. | 364 // FIXME: We should to move this down into deleteKeyPressed. |
| 361 // clear the "start new kill ring sequence" setting, because it was set to | 365 // clear the "start new kill ring sequence" setting, because it was set to |
| 362 // true when the selection was updated by deleting the range | 366 // true when the selection was updated by deleting the range |
| 363 if (killRing) | 367 if (killRing) |
| 364 setStartNewKillRingSequence(false); | 368 setStartNewKillRingSequence(false); |
| 365 | 369 |
| 366 return true; | 370 return true; |
| 367 } | 371 } |
| 368 | 372 |
| 369 void Editor::deleteSelectionWithSmartDelete( | 373 void Editor::deleteSelectionWithSmartDelete( |
| 374 CommandSource source, | |
| 370 DeleteMode deleteMode, | 375 DeleteMode deleteMode, |
| 371 InputEvent::InputType inputType, | 376 InputEvent::InputType inputType, |
| 372 const Position& referenceMovePosition) { | 377 const Position& referenceMovePosition) { |
| 373 if (frame().selection().isNone()) | 378 if (frame().selection().isNone()) |
| 374 return; | 379 return; |
| 375 | 380 |
| 376 const bool kMergeBlocksAfterDelete = true; | 381 const bool kMergeBlocksAfterDelete = true; |
| 377 const bool kExpandForSpecialElements = false; | 382 const bool kExpandForSpecialElements = false; |
| 378 const bool kSanitizeMarkup = true; | 383 const bool kSanitizeMarkup = true; |
| 379 DCHECK(frame().document()); | 384 DCHECK(frame().document()); |
| 380 DeleteSelectionCommand::create( | 385 DeleteSelectionCommand::create( |
| 381 *frame().document(), deleteMode == DeleteMode::Smart, | 386 *frame().document(), source, deleteMode == DeleteMode::Smart, |
| 382 kMergeBlocksAfterDelete, kExpandForSpecialElements, kSanitizeMarkup, | 387 kMergeBlocksAfterDelete, kExpandForSpecialElements, kSanitizeMarkup, |
| 383 inputType, referenceMovePosition) | 388 inputType, referenceMovePosition) |
| 384 ->apply(); | 389 ->apply(); |
| 385 } | 390 } |
| 386 | 391 |
| 387 void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace) { | 392 void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace) { |
| 388 Element* target = findEventTargetFromSelection(); | 393 Element* target = findEventTargetFromSelection(); |
| 389 if (!target) | 394 if (!target) |
| 390 return; | 395 return; |
| 391 target->dispatchEvent(TextEvent::createForPlainTextPaste( | 396 target->dispatchEvent(TextEvent::createForPlainTextPaste( |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 // invalidate clipboard here for security | 556 // invalidate clipboard here for security |
| 552 dataTransfer->setAccessPolicy(DataTransferNumb); | 557 dataTransfer->setAccessPolicy(DataTransferNumb); |
| 553 | 558 |
| 554 return !noDefaultProcessing; | 559 return !noDefaultProcessing; |
| 555 } | 560 } |
| 556 | 561 |
| 557 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) { | 562 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) { |
| 558 return smartInsertDeleteEnabled() && pasteboard->canSmartReplace(); | 563 return smartInsertDeleteEnabled() && pasteboard->canSmartReplace(); |
| 559 } | 564 } |
| 560 | 565 |
| 561 void Editor::replaceSelectionWithFragment(DocumentFragment* fragment, | 566 void Editor::replaceSelectionWithFragment(CommandSource source, |
| 567 DocumentFragment* fragment, | |
| 562 bool selectReplacement, | 568 bool selectReplacement, |
| 563 bool smartReplace, | 569 bool smartReplace, |
| 564 bool matchStyle, | 570 bool matchStyle, |
| 565 InputEvent::InputType inputType) { | 571 InputEvent::InputType inputType) { |
| 566 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 572 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
| 567 if (frame().selection().isNone() || | 573 if (frame().selection().isNone() || |
| 568 !frame().selection().isContentEditable() || !fragment) | 574 !frame().selection().isContentEditable() || !fragment) |
| 569 return; | 575 return; |
| 570 | 576 |
| 571 ReplaceSelectionCommand::CommandOptions options = | 577 ReplaceSelectionCommand::CommandOptions options = |
| 572 ReplaceSelectionCommand::PreventNesting | | 578 ReplaceSelectionCommand::PreventNesting | |
| 573 ReplaceSelectionCommand::SanitizeFragment; | 579 ReplaceSelectionCommand::SanitizeFragment; |
| 574 if (selectReplacement) | 580 if (selectReplacement) |
| 575 options |= ReplaceSelectionCommand::SelectReplacement; | 581 options |= ReplaceSelectionCommand::SelectReplacement; |
| 576 if (smartReplace) | 582 if (smartReplace) |
| 577 options |= ReplaceSelectionCommand::SmartReplace; | 583 options |= ReplaceSelectionCommand::SmartReplace; |
| 578 if (matchStyle) | 584 if (matchStyle) |
| 579 options |= ReplaceSelectionCommand::MatchStyle; | 585 options |= ReplaceSelectionCommand::MatchStyle; |
| 580 DCHECK(frame().document()); | 586 DCHECK(frame().document()); |
| 581 ReplaceSelectionCommand::create(*frame().document(), fragment, options, | 587 ReplaceSelectionCommand::create(*frame().document(), source, fragment, |
| 582 inputType) | 588 options, inputType) |
| 583 ->apply(); | 589 ->apply(); |
| 584 revealSelectionAfterEditingOperation(); | 590 revealSelectionAfterEditingOperation(); |
| 585 } | 591 } |
| 586 | 592 |
| 587 void Editor::replaceSelectionWithText(const String& text, | 593 void Editor::replaceSelectionWithText(CommandSource source, |
| 594 const String& text, | |
| 588 bool selectReplacement, | 595 bool selectReplacement, |
| 589 bool smartReplace, | 596 bool smartReplace, |
| 590 InputEvent::InputType inputType) { | 597 InputEvent::InputType inputType) { |
| 591 replaceSelectionWithFragment(createFragmentFromText(selectedRange(), text), | 598 replaceSelectionWithFragment( |
| 592 selectReplacement, smartReplace, true, | 599 source, createFragmentFromText(selectedRange(), text), selectReplacement, |
| 593 inputType); | 600 smartReplace, true, inputType); |
| 594 } | 601 } |
| 595 | 602 |
| 596 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. | 603 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. |
| 597 void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, | 604 void Editor::replaceSelectionAfterDragging(DocumentFragment* fragment, |
| 598 InsertMode insertMode, | 605 InsertMode insertMode, |
| 599 DragSourceType dragSourceType) { | 606 DragSourceType dragSourceType) { |
| 600 ReplaceSelectionCommand::CommandOptions options = | 607 ReplaceSelectionCommand::CommandOptions options = |
| 601 ReplaceSelectionCommand::SelectReplacement | | 608 ReplaceSelectionCommand::SelectReplacement | |
| 602 ReplaceSelectionCommand::PreventNesting; | 609 ReplaceSelectionCommand::PreventNesting; |
| 603 if (insertMode == InsertMode::Smart) | 610 if (insertMode == InsertMode::Smart) |
| 604 options |= ReplaceSelectionCommand::SmartReplace; | 611 options |= ReplaceSelectionCommand::SmartReplace; |
| 605 if (dragSourceType == DragSourceType::PlainTextSource) | 612 if (dragSourceType == DragSourceType::PlainTextSource) |
| 606 options |= ReplaceSelectionCommand::MatchStyle; | 613 options |= ReplaceSelectionCommand::MatchStyle; |
| 607 DCHECK(frame().document()); | 614 DCHECK(frame().document()); |
| 608 ReplaceSelectionCommand::create(*frame().document(), fragment, options, | 615 ReplaceSelectionCommand::create( |
| 609 InputEvent::InputType::InsertFromDrop) | 616 *frame().document(), CommandSource::MenuOrKeyBinding, fragment, options, |
| 617 InputEvent::InputType::InsertFromDrop) | |
| 610 ->apply(); | 618 ->apply(); |
| 611 } | 619 } |
| 612 | 620 |
| 613 bool Editor::deleteSelectionAfterDraggingWithEvents( | 621 bool Editor::deleteSelectionAfterDraggingWithEvents( |
| 614 Element* dragSource, | 622 Element* dragSource, |
| 615 DeleteMode deleteMode, | 623 DeleteMode deleteMode, |
| 616 const Position& referenceMovePosition) { | 624 const Position& referenceMovePosition) { |
| 617 if (!dragSource || !dragSource->isConnected()) | 625 if (!dragSource || !dragSource->isConnected()) |
| 618 return true; | 626 return true; |
| 619 | 627 |
| 620 // Dispatch 'beforeinput'. | 628 // Dispatch 'beforeinput'. |
| 621 const bool shouldDelete = dispatchBeforeInputEditorCommand( | 629 const bool shouldDelete = dispatchBeforeInputEditorCommand( |
| 622 dragSource, InputEvent::InputType::DeleteByDrag, | 630 dragSource, InputEvent::InputType::DeleteByDrag, |
| 623 nullptr) == DispatchEventResult::NotCanceled; | 631 nullptr) == DispatchEventResult::NotCanceled; |
| 624 | 632 |
| 625 // 'beforeinput' event handler may destroy frame, return false to cancel | 633 // 'beforeinput' event handler may destroy frame, return false to cancel |
| 626 // remaining actions; | 634 // remaining actions; |
| 627 if (m_frame->document()->frame() != m_frame) | 635 if (m_frame->document()->frame() != m_frame) |
| 628 return false; | 636 return false; |
| 629 | 637 |
| 630 if (shouldDelete && dragSource->isConnected()) { | 638 if (shouldDelete && dragSource->isConnected()) { |
| 631 deleteSelectionWithSmartDelete( | 639 deleteSelectionWithSmartDelete(CommandSource::MenuOrKeyBinding, deleteMode, |
| 632 deleteMode, InputEvent::InputType::DeleteByDrag, referenceMovePosition); | 640 InputEvent::InputType::DeleteByDrag, |
| 641 referenceMovePosition); | |
| 633 } | 642 } |
| 634 | 643 |
| 635 return true; | 644 return true; |
| 636 } | 645 } |
| 637 | 646 |
| 638 bool Editor::replaceSelectionAfterDraggingWithEvents( | 647 bool Editor::replaceSelectionAfterDraggingWithEvents( |
| 639 Element* dropTarget, | 648 Element* dropTarget, |
| 640 DragData* dragData, | 649 DragData* dragData, |
| 641 DocumentFragment* fragment, | 650 DocumentFragment* fragment, |
| 642 Range* dropCaretRange, | 651 Range* dropCaretRange, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 686 if (frame().settings() && frame().settings()->accessibilityEnabled()) { | 695 if (frame().settings() && frame().settings()->accessibilityEnabled()) { |
| 687 Node* node = endingSelection.start().anchorNode(); | 696 Node* node = endingSelection.start().anchorNode(); |
| 688 if (AXObjectCache* cache = frame().document()->existingAXObjectCache()) | 697 if (AXObjectCache* cache = frame().document()->existingAXObjectCache()) |
| 689 cache->handleEditableTextContentChanged(node); | 698 cache->handleEditableTextContentChanged(node); |
| 690 } | 699 } |
| 691 | 700 |
| 692 spellChecker().updateMarkersForWordsAffectedByEditing(true); | 701 spellChecker().updateMarkersForWordsAffectedByEditing(true); |
| 693 client().respondToChangedContents(); | 702 client().respondToChangedContents(); |
| 694 } | 703 } |
| 695 | 704 |
| 696 void Editor::removeFormattingAndStyle() { | 705 void Editor::removeFormattingAndStyle(CommandSource source) { |
| 697 DCHECK(frame().document()); | 706 DCHECK(frame().document()); |
| 698 RemoveFormatCommand::create(*frame().document())->apply(); | 707 RemoveFormatCommand::create(*frame().document(), source)->apply(); |
| 699 } | 708 } |
| 700 | 709 |
| 701 void Editor::registerCommandGroup(CompositeEditCommand* commandGroupWrapper) { | 710 void Editor::registerCommandGroup(CompositeEditCommand* commandGroupWrapper) { |
| 702 DCHECK(commandGroupWrapper->isCommandGroupWrapper()); | 711 DCHECK(commandGroupWrapper->isCommandGroupWrapper()); |
| 703 m_lastEditCommand = commandGroupWrapper; | 712 m_lastEditCommand = commandGroupWrapper; |
| 704 } | 713 } |
| 705 | 714 |
| 706 void Editor::clearLastEditCommand() { | 715 void Editor::clearLastEditCommand() { |
| 707 m_lastEditCommand.clear(); | 716 m_lastEditCommand.clear(); |
| 708 } | 717 } |
| 709 | 718 |
| 710 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const { | 719 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const { |
| 711 Element* target = associatedElementOf(selection.start()); | 720 Element* target = associatedElementOf(selection.start()); |
| 712 if (!target) | 721 if (!target) |
| 713 target = frame().document()->body(); | 722 target = frame().document()->body(); |
| 714 | 723 |
| 715 return target; | 724 return target; |
| 716 } | 725 } |
| 717 | 726 |
| 718 Element* Editor::findEventTargetFromSelection() const { | 727 Element* Editor::findEventTargetFromSelection() const { |
| 719 return findEventTargetFrom(frame().selection().selection()); | 728 return findEventTargetFrom(frame().selection().selection()); |
| 720 } | 729 } |
| 721 | 730 |
| 722 void Editor::applyStyle(StylePropertySet* style, | 731 void Editor::applyStyle(CommandSource source, |
| 732 StylePropertySet* style, | |
| 723 InputEvent::InputType inputType) { | 733 InputEvent::InputType inputType) { |
| 724 switch (frame().selection().getSelectionType()) { | 734 switch (frame().selection().getSelectionType()) { |
| 725 case NoSelection: | 735 case NoSelection: |
| 726 // do nothing | 736 // do nothing |
| 727 break; | 737 break; |
| 728 case CaretSelection: | 738 case CaretSelection: |
| 729 computeAndSetTypingStyle(style, inputType); | 739 computeAndSetTypingStyle(source, style, inputType); |
| 730 break; | 740 break; |
| 731 case RangeSelection: | 741 case RangeSelection: |
| 732 if (style) { | 742 if (style) { |
| 733 DCHECK(frame().document()); | 743 DCHECK(frame().document()); |
| 734 ApplyStyleCommand::create(*frame().document(), | 744 ApplyStyleCommand::create(*frame().document(), source, |
| 735 EditingStyle::create(style), inputType) | 745 EditingStyle::create(style), inputType) |
| 736 ->apply(); | 746 ->apply(); |
| 737 } | 747 } |
| 738 break; | 748 break; |
| 739 } | 749 } |
| 740 } | 750 } |
| 741 | 751 |
| 742 void Editor::applyParagraphStyle(StylePropertySet* style, | 752 void Editor::applyParagraphStyle(CommandSource source, |
| 753 StylePropertySet* style, | |
| 743 InputEvent::InputType inputType) { | 754 InputEvent::InputType inputType) { |
| 744 if (frame().selection().isNone() || !style) | 755 if (frame().selection().isNone() || !style) |
| 745 return; | 756 return; |
| 746 DCHECK(frame().document()); | 757 DCHECK(frame().document()); |
| 747 ApplyStyleCommand::create(*frame().document(), EditingStyle::create(style), | 758 ApplyStyleCommand::create(*frame().document(), source, |
| 748 inputType, ApplyStyleCommand::ForceBlockProperties) | 759 EditingStyle::create(style), inputType, |
| 760 ApplyStyleCommand::ForceBlockProperties) | |
| 749 ->apply(); | 761 ->apply(); |
| 750 } | 762 } |
| 751 | 763 |
| 752 void Editor::applyStyleToSelection(StylePropertySet* style, | 764 void Editor::applyStyleToSelection(CommandSource source, |
| 765 StylePropertySet* style, | |
| 753 InputEvent::InputType inputType) { | 766 InputEvent::InputType inputType) { |
| 754 if (!style || style->isEmpty() || !canEditRichly()) | 767 if (!style || style->isEmpty() || !canEditRichly()) |
| 755 return; | 768 return; |
| 756 | 769 |
| 757 applyStyle(style, inputType); | 770 applyStyle(source, style, inputType); |
| 758 } | 771 } |
| 759 | 772 |
| 760 void Editor::applyParagraphStyleToSelection(StylePropertySet* style, | 773 void Editor::applyParagraphStyleToSelection(CommandSource source, |
| 774 StylePropertySet* style, | |
| 761 InputEvent::InputType inputType) { | 775 InputEvent::InputType inputType) { |
| 762 if (!style || style->isEmpty() || !canEditRichly()) | 776 if (!style || style->isEmpty() || !canEditRichly()) |
| 763 return; | 777 return; |
| 764 | 778 |
| 765 applyParagraphStyle(style, inputType); | 779 applyParagraphStyle(source, style, inputType); |
| 766 } | 780 } |
| 767 | 781 |
| 768 bool Editor::selectionStartHasStyle(CSSPropertyID propertyID, | 782 bool Editor::selectionStartHasStyle(CSSPropertyID propertyID, |
| 769 const String& value) const { | 783 const String& value) const { |
| 770 EditingStyle* styleToCheck = EditingStyle::create(propertyID, value); | 784 EditingStyle* styleToCheck = EditingStyle::create(propertyID, value); |
| 771 EditingStyle* styleAtStart = EditingStyle::styleAtSelectionStart( | 785 EditingStyle* styleAtStart = EditingStyle::styleAtSelectionStart( |
| 772 frame().selection().selection(), propertyID == CSSPropertyBackgroundColor, | 786 frame().selection().selection(), propertyID == CSSPropertyBackgroundColor, |
| 773 styleToCheck->style()); | 787 styleToCheck->style()); |
| 774 return styleToCheck->triStateOfStyle(styleAtStart); | 788 return styleToCheck->triStateOfStyle(styleAtStart); |
| 775 } | 789 } |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 941 frame().inputMethodController().clear(); | 955 frame().inputMethodController().clear(); |
| 942 m_shouldStyleWithCSS = false; | 956 m_shouldStyleWithCSS = false; |
| 943 m_defaultParagraphSeparator = EditorParagraphSeparatorIsDiv; | 957 m_defaultParagraphSeparator = EditorParagraphSeparatorIsDiv; |
| 944 m_undoStack->clear(); | 958 m_undoStack->clear(); |
| 945 } | 959 } |
| 946 | 960 |
| 947 bool Editor::insertText(const String& text, KeyboardEvent* triggeringEvent) { | 961 bool Editor::insertText(const String& text, KeyboardEvent* triggeringEvent) { |
| 948 return frame().eventHandler().handleTextInputEvent(text, triggeringEvent); | 962 return frame().eventHandler().handleTextInputEvent(text, triggeringEvent); |
| 949 } | 963 } |
| 950 | 964 |
| 951 bool Editor::insertTextWithoutSendingTextEvent(const String& text, | 965 bool Editor::insertTextWithoutSendingTextEvent(CommandSource source, |
| 966 const String& text, | |
| 952 bool selectInsertedText, | 967 bool selectInsertedText, |
| 953 TextEvent* triggeringEvent) { | 968 TextEvent* triggeringEvent) { |
| 954 if (text.isEmpty()) | 969 if (text.isEmpty()) |
| 955 return false; | 970 return false; |
| 956 | 971 |
| 957 const VisibleSelection& selection = selectionForCommand(triggeringEvent); | 972 const VisibleSelection& selection = selectionForCommand(triggeringEvent); |
| 958 if (!selection.isContentEditable()) | 973 if (!selection.isContentEditable()) |
| 959 return false; | 974 return false; |
| 960 | 975 |
| 961 spellChecker().updateMarkersForWordsAffectedByEditing( | 976 spellChecker().updateMarkersForWordsAffectedByEditing( |
| 962 isSpaceOrNewline(text[0])); | 977 isSpaceOrNewline(text[0])); |
| 963 | 978 |
| 964 // Insert the text | 979 // Insert the text |
| 965 TypingCommand::insertText( | 980 TypingCommand::insertText( |
| 966 *selection.start().document(), text, selection, | 981 *selection.start().document(), source, text, selection, |
| 967 selectInsertedText ? TypingCommand::SelectInsertedText : 0, | 982 selectInsertedText ? TypingCommand::SelectInsertedText : 0, |
| 968 triggeringEvent && triggeringEvent->isComposition() | 983 triggeringEvent && triggeringEvent->isComposition() |
| 969 ? TypingCommand::TextCompositionConfirm | 984 ? TypingCommand::TextCompositionConfirm |
| 970 : TypingCommand::TextCompositionNone); | 985 : TypingCommand::TextCompositionNone); |
| 971 | 986 |
| 972 // Reveal the current selection | 987 // Reveal the current selection |
| 973 if (LocalFrame* editedFrame = selection.start().document()->frame()) { | 988 if (LocalFrame* editedFrame = selection.start().document()->frame()) { |
| 974 if (Page* page = editedFrame->page()) { | 989 if (Page* page = editedFrame->page()) { |
| 975 LocalFrame* focusedOrMainFrame = | 990 LocalFrame* focusedOrMainFrame = |
| 976 toLocalFrame(page->focusController().focusedOrMainFrame()); | 991 toLocalFrame(page->focusController().focusedOrMainFrame()); |
| 992 if (!focusedOrMainFrame->selection().isAvailable()) | |
|
Xiaocheng
2016/12/14 04:19:50
Seems irrelevant to this patch.
chongz
2016/12/15 00:53:32
Will remove.
| |
| 993 return true; | |
| 977 focusedOrMainFrame->selection().revealSelection( | 994 focusedOrMainFrame->selection().revealSelection( |
| 978 ScrollAlignment::alignCenterIfNeeded); | 995 ScrollAlignment::alignCenterIfNeeded); |
| 979 } | 996 } |
| 980 } | 997 } |
| 981 | 998 |
| 982 return true; | 999 return true; |
| 983 } | 1000 } |
| 984 | 1001 |
| 985 bool Editor::insertLineBreak() { | 1002 bool Editor::insertLineBreak() { |
| 986 if (!canEdit()) | 1003 if (!canEdit()) |
| 987 return false; | 1004 return false; |
| 988 | 1005 |
| 989 VisiblePosition caret = frame().selection().selection().visibleStart(); | 1006 VisiblePosition caret = frame().selection().selection().visibleStart(); |
| 990 bool alignToEdge = isEndOfEditableOrNonEditableContent(caret); | 1007 bool alignToEdge = isEndOfEditableOrNonEditableContent(caret); |
| 991 DCHECK(frame().document()); | 1008 DCHECK(frame().document()); |
| 992 if (!TypingCommand::insertLineBreak(*frame().document())) | 1009 if (!TypingCommand::insertLineBreak(*frame().document(), |
| 1010 CommandSource::MenuOrKeyBinding)) | |
| 993 return false; | 1011 return false; |
| 994 revealSelectionAfterEditingOperation( | 1012 revealSelectionAfterEditingOperation( |
| 995 alignToEdge ? ScrollAlignment::alignToEdgeIfNeeded | 1013 alignToEdge ? ScrollAlignment::alignToEdgeIfNeeded |
| 996 : ScrollAlignment::alignCenterIfNeeded); | 1014 : ScrollAlignment::alignCenterIfNeeded); |
| 997 | 1015 |
| 998 return true; | 1016 return true; |
| 999 } | 1017 } |
| 1000 | 1018 |
| 1001 bool Editor::insertParagraphSeparator() { | 1019 bool Editor::insertParagraphSeparator() { |
| 1002 if (!canEdit()) | 1020 if (!canEdit()) |
| 1003 return false; | 1021 return false; |
| 1004 | 1022 |
| 1005 if (!canEditRichly()) | 1023 if (!canEditRichly()) |
| 1006 return insertLineBreak(); | 1024 return insertLineBreak(); |
| 1007 | 1025 |
| 1008 VisiblePosition caret = frame().selection().selection().visibleStart(); | 1026 VisiblePosition caret = frame().selection().selection().visibleStart(); |
| 1009 bool alignToEdge = isEndOfEditableOrNonEditableContent(caret); | 1027 bool alignToEdge = isEndOfEditableOrNonEditableContent(caret); |
| 1010 DCHECK(frame().document()); | 1028 DCHECK(frame().document()); |
| 1011 EditingState editingState; | 1029 EditingState editingState; |
| 1012 if (!TypingCommand::insertParagraphSeparator(*frame().document())) | 1030 if (!TypingCommand::insertParagraphSeparator(*frame().document(), |
| 1031 CommandSource::MenuOrKeyBinding)) | |
| 1013 return false; | 1032 return false; |
| 1014 revealSelectionAfterEditingOperation( | 1033 revealSelectionAfterEditingOperation( |
| 1015 alignToEdge ? ScrollAlignment::alignToEdgeIfNeeded | 1034 alignToEdge ? ScrollAlignment::alignToEdgeIfNeeded |
| 1016 : ScrollAlignment::alignCenterIfNeeded); | 1035 : ScrollAlignment::alignCenterIfNeeded); |
| 1017 | 1036 |
| 1018 return true; | 1037 return true; |
| 1019 } | 1038 } |
| 1020 | 1039 |
| 1021 void Editor::cut(EditorCommandSource source) { | 1040 void Editor::cut(CommandSource source) { |
| 1022 if (tryDHTMLCut()) | 1041 if (tryDHTMLCut()) |
| 1023 return; // DHTML did the whole operation | 1042 return; // DHTML did the whole operation |
| 1024 if (!canCut()) | 1043 if (!canCut()) |
| 1025 return; | 1044 return; |
| 1026 | 1045 |
| 1027 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 1046 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 1028 // needs to be audited. See http://crbug.com/590369 for more details. | 1047 // needs to be audited. See http://crbug.com/590369 for more details. |
| 1029 // |tryDHTMLCut| dispatches cut event, which may make layout dirty, but we | 1048 // |tryDHTMLCut| dispatches cut event, which may make layout dirty, but we |
| 1030 // need clean layout to obtain the selected content. | 1049 // need clean layout to obtain the selected content. |
| 1031 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1050 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 1032 | 1051 |
| 1033 // TODO(yosin) We should use early return style here. | 1052 // TODO(yosin) We should use early return style here. |
| 1034 if (canDeleteRange(selectedRange())) { | 1053 if (canDeleteRange(selectedRange())) { |
| 1035 spellChecker().updateMarkersForWordsAffectedByEditing(true); | 1054 spellChecker().updateMarkersForWordsAffectedByEditing(true); |
| 1036 if (enclosingTextControl(frame().selection().start())) { | 1055 if (enclosingTextControl(frame().selection().start())) { |
| 1037 String plainText = frame().selectedTextForClipboard(); | 1056 String plainText = frame().selectedTextForClipboard(); |
| 1038 Pasteboard::generalPasteboard()->writePlainText( | 1057 Pasteboard::generalPasteboard()->writePlainText( |
| 1039 plainText, canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace | 1058 plainText, canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace |
| 1040 : Pasteboard::CannotSmartReplace); | 1059 : Pasteboard::CannotSmartReplace); |
| 1041 } else { | 1060 } else { |
| 1042 writeSelectionToPasteboard(); | 1061 writeSelectionToPasteboard(); |
| 1043 } | 1062 } |
| 1044 | 1063 |
| 1045 if (source == CommandFromMenuOrKeyBinding) { | 1064 if (source == CommandSource::MenuOrKeyBinding) { |
| 1046 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(), | 1065 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(), |
| 1047 InputEvent::InputType::DeleteByCut, | 1066 InputEvent::InputType::DeleteByCut, |
| 1048 nullptr, nullptr) != | 1067 nullptr, nullptr) != |
| 1049 DispatchEventResult::NotCanceled) | 1068 DispatchEventResult::NotCanceled) |
| 1050 return; | 1069 return; |
| 1051 // 'beforeinput' event handler may destroy target frame. | 1070 // 'beforeinput' event handler may destroy target frame. |
| 1052 if (m_frame->document()->frame() != m_frame) | 1071 if (m_frame->document()->frame() != m_frame) |
| 1053 return; | 1072 return; |
| 1054 } | 1073 } |
| 1055 deleteSelectionWithSmartDelete( | 1074 deleteSelectionWithSmartDelete( |
| 1056 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, | 1075 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, |
| 1057 InputEvent::InputType::DeleteByCut); | 1076 InputEvent::InputType::DeleteByCut); |
| 1058 } | 1077 } |
| 1059 } | 1078 } |
| 1060 | 1079 |
| 1061 void Editor::copy() { | 1080 void Editor::copy() { |
| 1062 if (tryDHTMLCopy()) | 1081 if (tryDHTMLCopy()) |
| 1063 return; // DHTML did the whole operation | 1082 return; // DHTML did the whole operation |
| 1064 if (!canCopy()) | 1083 if (!canCopy()) |
| 1065 return; | 1084 return; |
| 1066 | 1085 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1079 Document* document = frame().document(); | 1098 Document* document = frame().document(); |
| 1080 if (HTMLImageElement* imageElement = | 1099 if (HTMLImageElement* imageElement = |
| 1081 imageElementFromImageDocument(document)) | 1100 imageElementFromImageDocument(document)) |
| 1082 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), imageElement, | 1101 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), imageElement, |
| 1083 document->title()); | 1102 document->title()); |
| 1084 else | 1103 else |
| 1085 writeSelectionToPasteboard(); | 1104 writeSelectionToPasteboard(); |
| 1086 } | 1105 } |
| 1087 } | 1106 } |
| 1088 | 1107 |
| 1089 void Editor::paste(EditorCommandSource source) { | 1108 void Editor::paste(CommandSource source) { |
| 1090 DCHECK(frame().document()); | 1109 DCHECK(frame().document()); |
| 1091 if (tryDHTMLPaste(AllMimeTypes)) | 1110 if (tryDHTMLPaste(AllMimeTypes)) |
| 1092 return; // DHTML did the whole operation | 1111 return; // DHTML did the whole operation |
| 1093 if (!canPaste()) | 1112 if (!canPaste()) |
| 1094 return; | 1113 return; |
| 1095 spellChecker().updateMarkersForWordsAffectedByEditing(false); | 1114 spellChecker().updateMarkersForWordsAffectedByEditing(false); |
| 1096 ResourceFetcher* loader = frame().document()->fetcher(); | 1115 ResourceFetcher* loader = frame().document()->fetcher(); |
| 1097 ResourceCacheValidationSuppressor validationSuppressor(loader); | 1116 ResourceCacheValidationSuppressor validationSuppressor(loader); |
| 1098 | 1117 |
| 1099 PasteMode pasteMode = frame().selection().isContentRichlyEditable() | 1118 PasteMode pasteMode = frame().selection().isContentRichlyEditable() |
| 1100 ? AllMimeTypes | 1119 ? AllMimeTypes |
| 1101 : PlainTextOnly; | 1120 : PlainTextOnly; |
| 1102 | 1121 |
| 1103 if (source == CommandFromMenuOrKeyBinding) { | 1122 if (source == CommandSource::MenuOrKeyBinding) { |
| 1104 DataTransfer* dataTransfer = | 1123 DataTransfer* dataTransfer = |
| 1105 DataTransfer::create(DataTransfer::CopyAndPaste, DataTransferReadable, | 1124 DataTransfer::create(DataTransfer::CopyAndPaste, DataTransferReadable, |
| 1106 DataObject::createFromPasteboard(pasteMode)); | 1125 DataObject::createFromPasteboard(pasteMode)); |
| 1107 | 1126 |
| 1108 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(), | 1127 if (dispatchBeforeInputDataTransfer(findEventTargetFromSelection(), |
| 1109 InputEvent::InputType::InsertFromPaste, | 1128 InputEvent::InputType::InsertFromPaste, |
| 1110 dataTransfer, nullptr) != | 1129 dataTransfer, nullptr) != |
| 1111 DispatchEventResult::NotCanceled) | 1130 DispatchEventResult::NotCanceled) |
| 1112 return; | 1131 return; |
| 1113 // 'beforeinput' event handler may destroy target frame. | 1132 // 'beforeinput' event handler may destroy target frame. |
| 1114 if (m_frame->document()->frame() != m_frame) | 1133 if (m_frame->document()->frame() != m_frame) |
| 1115 return; | 1134 return; |
| 1116 } | 1135 } |
| 1117 | 1136 |
| 1118 if (pasteMode == AllMimeTypes) | 1137 if (pasteMode == AllMimeTypes) |
| 1119 pasteWithPasteboard(Pasteboard::generalPasteboard()); | 1138 pasteWithPasteboard(Pasteboard::generalPasteboard()); |
| 1120 else | 1139 else |
| 1121 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); | 1140 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); |
| 1122 } | 1141 } |
| 1123 | 1142 |
| 1124 void Editor::pasteAsPlainText(EditorCommandSource source) { | 1143 void Editor::pasteAsPlainText(CommandSource source) { |
| 1125 if (tryDHTMLPaste(PlainTextOnly)) | 1144 if (tryDHTMLPaste(PlainTextOnly)) |
| 1126 return; | 1145 return; |
| 1127 if (!canPaste()) | 1146 if (!canPaste()) |
| 1128 return; | 1147 return; |
| 1129 spellChecker().updateMarkersForWordsAffectedByEditing(false); | 1148 spellChecker().updateMarkersForWordsAffectedByEditing(false); |
| 1130 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); | 1149 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); |
| 1131 } | 1150 } |
| 1132 | 1151 |
| 1133 void Editor::performDelete() { | 1152 void Editor::performDelete(CommandSource source) { |
| 1134 if (!canDelete()) | 1153 if (!canDelete()) |
| 1135 return; | 1154 return; |
| 1136 | 1155 |
| 1137 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 1156 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 1138 // 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. |
| 1139 // |selectedRange| requires clean layout for visible selection normalization. | 1158 // |selectedRange| requires clean layout for visible selection normalization. |
| 1140 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1159 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 1141 | 1160 |
| 1142 addToKillRing(selectedRange()); | 1161 addToKillRing(selectedRange()); |
| 1143 // TODO(chongz): |Editor::performDelete()| has no direction. | 1162 // TODO(chongz): |Editor::performDelete()| has no direction. |
| 1144 // https://github.com/w3c/editing/issues/130 | 1163 // https://github.com/w3c/editing/issues/130 |
| 1145 deleteSelectionWithSmartDelete( | 1164 deleteSelectionWithSmartDelete( |
| 1146 canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, | 1165 source, canSmartCopyOrDelete() ? DeleteMode::Smart : DeleteMode::Simple, |
| 1147 InputEvent::InputType::DeleteContentBackward); | 1166 InputEvent::InputType::DeleteContentBackward); |
| 1148 | 1167 |
| 1149 // 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 |
| 1150 // true when the selection was updated by deleting the range | 1169 // true when the selection was updated by deleting the range |
| 1151 setStartNewKillRingSequence(false); | 1170 setStartNewKillRingSequence(false); |
| 1152 } | 1171 } |
| 1153 | 1172 |
| 1154 static void countEditingEvent(ExecutionContext* executionContext, | 1173 static void countEditingEvent(ExecutionContext* executionContext, |
| 1155 const Event* event, | 1174 const Event* event, |
| 1156 UseCounter::Feature featureOnInput, | 1175 UseCounter::Feature featureOnInput, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1223 void Editor::copyImage(const HitTestResult& result) { | 1242 void Editor::copyImage(const HitTestResult& result) { |
| 1224 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), | 1243 writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), |
| 1225 result.innerNodeOrImageMapImage(), | 1244 result.innerNodeOrImageMapImage(), |
| 1226 result.altDisplayString()); | 1245 result.altDisplayString()); |
| 1227 } | 1246 } |
| 1228 | 1247 |
| 1229 bool Editor::canUndo() { | 1248 bool Editor::canUndo() { |
| 1230 return m_undoStack->canUndo(); | 1249 return m_undoStack->canUndo(); |
| 1231 } | 1250 } |
| 1232 | 1251 |
| 1233 void Editor::undo() { | 1252 void Editor::undo(CommandSource) { |
| 1234 m_undoStack->undo(); | 1253 m_undoStack->undo(); |
| 1235 } | 1254 } |
| 1236 | 1255 |
| 1237 bool Editor::canRedo() { | 1256 bool Editor::canRedo() { |
| 1238 return m_undoStack->canRedo(); | 1257 return m_undoStack->canRedo(); |
| 1239 } | 1258 } |
| 1240 | 1259 |
| 1241 void Editor::redo() { | 1260 void Editor::redo(CommandSource) { |
| 1242 m_undoStack->redo(); | 1261 m_undoStack->redo(); |
| 1243 } | 1262 } |
| 1244 | 1263 |
| 1245 void Editor::setBaseWritingDirection(WritingDirection direction) { | 1264 void Editor::setBaseWritingDirection(WritingDirection direction) { |
| 1246 Element* focusedElement = frame().document()->focusedElement(); | 1265 Element* focusedElement = frame().document()->focusedElement(); |
| 1247 if (isTextControlElement(focusedElement)) { | 1266 if (isTextControlElement(focusedElement)) { |
| 1248 if (direction == NaturalWritingDirection) | 1267 if (direction == NaturalWritingDirection) |
| 1249 return; | 1268 return; |
| 1250 focusedElement->setAttribute( | 1269 focusedElement->setAttribute( |
| 1251 dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl"); | 1270 dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl"); |
| 1252 focusedElement->dispatchInputEvent(); | 1271 focusedElement->dispatchInputEvent(); |
| 1253 return; | 1272 return; |
| 1254 } | 1273 } |
| 1255 | 1274 |
| 1256 MutableStylePropertySet* style = | 1275 MutableStylePropertySet* style = |
| 1257 MutableStylePropertySet::create(HTMLQuirksMode); | 1276 MutableStylePropertySet::create(HTMLQuirksMode); |
| 1258 style->setProperty( | 1277 style->setProperty( |
| 1259 CSSPropertyDirection, | 1278 CSSPropertyDirection, |
| 1260 direction == LeftToRightWritingDirection | 1279 direction == LeftToRightWritingDirection |
| 1261 ? "ltr" | 1280 ? "ltr" |
| 1262 : direction == RightToLeftWritingDirection ? "rtl" : "inherit", | 1281 : direction == RightToLeftWritingDirection ? "rtl" : "inherit", |
| 1263 false); | 1282 false); |
| 1264 applyParagraphStyleToSelection( | 1283 applyParagraphStyleToSelection( |
| 1265 style, InputEvent::InputType::FormatSetBlockTextDirection); | 1284 CommandSource::MenuOrKeyBinding, style, |
| 1285 InputEvent::InputType::FormatSetBlockTextDirection); | |
| 1266 } | 1286 } |
| 1267 | 1287 |
| 1268 void Editor::revealSelectionAfterEditingOperation( | 1288 void Editor::revealSelectionAfterEditingOperation( |
| 1269 const ScrollAlignment& alignment, | 1289 const ScrollAlignment& alignment, |
| 1270 RevealExtentOption revealExtentOption) { | 1290 RevealExtentOption revealExtentOption) { |
| 1271 if (m_preventRevealSelection) | 1291 if (m_preventRevealSelection || !m_frame->selection().isAvailable()) |
|
Xiaocheng
2016/12/14 04:19:50
Seems irrelevant to this patch.
chongz
2016/12/15 00:53:32
Will remove.
| |
| 1272 return; | 1292 return; |
| 1273 frame().selection().revealSelection(alignment, revealExtentOption); | 1293 frame().selection().revealSelection(alignment, revealExtentOption); |
| 1274 } | 1294 } |
| 1275 | 1295 |
| 1276 void Editor::transpose() { | 1296 void Editor::transpose(CommandSource source) { |
| 1277 if (!canEdit()) | 1297 if (!canEdit()) |
| 1278 return; | 1298 return; |
| 1279 | 1299 |
| 1280 VisibleSelection selection = frame().selection().selection(); | 1300 VisibleSelection selection = frame().selection().selection(); |
| 1281 if (!selection.isCaret()) | 1301 if (!selection.isCaret()) |
| 1282 return; | 1302 return; |
| 1283 | 1303 |
| 1284 // 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. |
| 1285 VisiblePosition caret = selection.visibleStart(); | 1305 VisiblePosition caret = selection.visibleStart(); |
| 1286 VisiblePosition next = | 1306 VisiblePosition next = |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1303 return; | 1323 return; |
| 1304 String transposed = text.right(1) + text.left(1); | 1324 String transposed = text.right(1) + text.left(1); |
| 1305 | 1325 |
| 1306 // Select the two characters. | 1326 // Select the two characters. |
| 1307 if (newSelection != frame().selection().selection()) | 1327 if (newSelection != frame().selection().selection()) |
| 1308 frame().selection().setSelection(newSelection); | 1328 frame().selection().setSelection(newSelection); |
| 1309 | 1329 |
| 1310 // Insert the transposed characters. | 1330 // Insert the transposed characters. |
| 1311 // TODO(chongz): Once we add |InsertTranspose| in |InputEvent::InputType|, we | 1331 // TODO(chongz): Once we add |InsertTranspose| in |InputEvent::InputType|, we |
| 1312 // should use it instead of |InsertFromPaste|. | 1332 // should use it instead of |InsertFromPaste|. |
| 1313 replaceSelectionWithText(transposed, false, false, | 1333 replaceSelectionWithText(source, transposed, false, false, |
| 1314 InputEvent::InputType::InsertFromPaste); | 1334 InputEvent::InputType::InsertFromPaste); |
| 1315 } | 1335 } |
| 1316 | 1336 |
| 1317 void Editor::addToKillRing(const EphemeralRange& range) { | 1337 void Editor::addToKillRing(const EphemeralRange& range) { |
| 1318 if (m_shouldStartNewKillRingSequence) | 1338 if (m_shouldStartNewKillRingSequence) |
| 1319 killRing().startNewSequence(); | 1339 killRing().startNewSequence(); |
| 1320 | 1340 |
| 1321 DCHECK(!frame().document()->needsLayoutTreeUpdate()); | 1341 DCHECK(!frame().document()->needsLayoutTreeUpdate()); |
| 1322 String text = plainText(range); | 1342 String text = plainText(range); |
| 1323 killRing().append(text); | 1343 killRing().append(text); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1384 std::max(startCaretRect.height(), endCaretRect.height())); | 1404 std::max(startCaretRect.height(), endCaretRect.height())); |
| 1385 } | 1405 } |
| 1386 | 1406 |
| 1387 // 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 |
| 1388 // line | 1408 // line |
| 1389 return IntRect(startCaretRect.x(), startCaretRect.y(), | 1409 return IntRect(startCaretRect.x(), startCaretRect.y(), |
| 1390 (startCaretRect.width() + extraWidthToEndOfLine).toInt(), | 1410 (startCaretRect.width() + extraWidthToEndOfLine).toInt(), |
| 1391 startCaretRect.height()); | 1411 startCaretRect.height()); |
| 1392 } | 1412 } |
| 1393 | 1413 |
| 1394 void Editor::computeAndSetTypingStyle(StylePropertySet* style, | 1414 void Editor::computeAndSetTypingStyle(CommandSource source, |
| 1415 StylePropertySet* style, | |
| 1395 InputEvent::InputType inputType) { | 1416 InputEvent::InputType inputType) { |
| 1396 if (!style || style->isEmpty()) { | 1417 if (!style || style->isEmpty()) { |
| 1397 frame().selection().clearTypingStyle(); | 1418 frame().selection().clearTypingStyle(); |
| 1398 return; | 1419 return; |
| 1399 } | 1420 } |
| 1400 | 1421 |
| 1401 // Calculate the current typing style. | 1422 // Calculate the current typing style. |
| 1402 EditingStyle* typingStyle = nullptr; | 1423 EditingStyle* typingStyle = nullptr; |
| 1403 if (frame().selection().typingStyle()) { | 1424 if (frame().selection().typingStyle()) { |
| 1404 typingStyle = frame().selection().typingStyle()->copy(); | 1425 typingStyle = frame().selection().typingStyle()->copy(); |
| 1405 typingStyle->overrideWithStyle(style); | 1426 typingStyle->overrideWithStyle(style); |
| 1406 } else { | 1427 } else { |
| 1407 typingStyle = EditingStyle::create(style); | 1428 typingStyle = EditingStyle::create(style); |
| 1408 } | 1429 } |
| 1409 | 1430 |
| 1410 typingStyle->prepareToApplyAt( | 1431 typingStyle->prepareToApplyAt( |
| 1411 frame().selection().selection().visibleStart().deepEquivalent(), | 1432 frame().selection().selection().visibleStart().deepEquivalent(), |
| 1412 EditingStyle::PreserveWritingDirection); | 1433 EditingStyle::PreserveWritingDirection); |
| 1413 | 1434 |
| 1414 // Handle block styles, substracting these from the typing style. | 1435 // Handle block styles, substracting these from the typing style. |
| 1415 EditingStyle* blockStyle = typingStyle->extractAndRemoveBlockProperties(); | 1436 EditingStyle* blockStyle = typingStyle->extractAndRemoveBlockProperties(); |
| 1416 if (!blockStyle->isEmpty()) { | 1437 if (!blockStyle->isEmpty()) { |
| 1417 DCHECK(frame().document()); | 1438 DCHECK(frame().document()); |
| 1418 ApplyStyleCommand::create(*frame().document(), blockStyle, inputType) | 1439 ApplyStyleCommand::create(*frame().document(), source, blockStyle, |
| 1440 inputType) | |
| 1419 ->apply(); | 1441 ->apply(); |
| 1420 } | 1442 } |
| 1421 | 1443 |
| 1422 // Set the remaining style as the typing style. | 1444 // Set the remaining style as the typing style. |
| 1423 frame().selection().setTypingStyle(typingStyle); | 1445 if (frame().selection().isAvailable()) |
|
Xiaocheng
2016/12/14 04:19:50
Seems irrelevant to this patch.
chongz
2016/12/15 00:53:32
Will remove.
| |
| 1446 frame().selection().setTypingStyle(typingStyle); | |
| 1424 } | 1447 } |
| 1425 | 1448 |
| 1426 bool Editor::findString(const String& target, FindOptions options) { | 1449 bool Editor::findString(const String& target, FindOptions options) { |
| 1427 VisibleSelection selection = frame().selection().selection(); | 1450 VisibleSelection selection = frame().selection().selection(); |
| 1428 | 1451 |
| 1429 // TODO(yosin) We should make |findRangeOfString()| to return | 1452 // TODO(yosin) We should make |findRangeOfString()| to return |
| 1430 // |EphemeralRange| rather than|Range| object. | 1453 // |EphemeralRange| rather than|Range| object. |
| 1431 Range* resultRange = findRangeOfString( | 1454 Range* resultRange = findRangeOfString( |
| 1432 target, EphemeralRange(selection.start(), selection.end()), | 1455 target, EphemeralRange(selection.start(), selection.end()), |
| 1433 static_cast<FindOptions>(options | FindAPICall)); | 1456 static_cast<FindOptions>(options | FindAPICall)); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1660 } | 1683 } |
| 1661 | 1684 |
| 1662 DEFINE_TRACE(Editor) { | 1685 DEFINE_TRACE(Editor) { |
| 1663 visitor->trace(m_frame); | 1686 visitor->trace(m_frame); |
| 1664 visitor->trace(m_lastEditCommand); | 1687 visitor->trace(m_lastEditCommand); |
| 1665 visitor->trace(m_undoStack); | 1688 visitor->trace(m_undoStack); |
| 1666 visitor->trace(m_mark); | 1689 visitor->trace(m_mark); |
| 1667 } | 1690 } |
| 1668 | 1691 |
| 1669 } // namespace blink | 1692 } // namespace blink |
| OLD | NEW |