| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 VisibleSelection Editor::selectionForCommand(Event* event) | 114 VisibleSelection Editor::selectionForCommand(Event* event) |
| 115 { | 115 { |
| 116 VisibleSelection selection = frame().selection().selection(); | 116 VisibleSelection selection = frame().selection().selection(); |
| 117 if (!event) | 117 if (!event) |
| 118 return selection; | 118 return selection; |
| 119 // If the target is a text control, and the current selection is outside of
its shadow tree, | 119 // If the target is a text control, and the current selection is outside of
its shadow tree, |
| 120 // then use the saved selection for that text control. | 120 // then use the saved selection for that text control. |
| 121 HTMLTextFormControlElement* textFormControlOfSelectionStart = enclosingTextF
ormControl(selection.start()); | 121 HTMLTextFormControlElement* textFormControlOfSelectionStart = enclosingTextF
ormControl(selection.start()); |
| 122 HTMLTextFormControlElement* textFromControlOfTarget = isHTMLTextFormControlE
lement(*event->target()->toNode()) ? toHTMLTextFormControlElement(event->target(
)->toNode()) : 0; | 122 HTMLTextFormControlElement* textFromControlOfTarget = isHTMLTextFormControlE
lement(*event->target()->toNode()) ? toHTMLTextFormControlElement(event->target(
)->toNode()) : 0; |
| 123 if (textFromControlOfTarget && (selection.start().isNull() || textFromContro
lOfTarget != textFormControlOfSelectionStart)) { | 123 if (textFromControlOfTarget && (selection.start().isNull() || textFromContro
lOfTarget != textFormControlOfSelectionStart)) { |
| 124 if (RefPtrWillBeRawPtr<Range> range = textFromControlOfTarget->selection
()) | 124 if (RawPtr<Range> range = textFromControlOfTarget->selection()) |
| 125 return VisibleSelection(EphemeralRange(range.get()), TextAffinity::D
ownstream, selection.isDirectional()); | 125 return VisibleSelection(EphemeralRange(range.get()), TextAffinity::D
ownstream, selection.isDirectional()); |
| 126 } | 126 } |
| 127 return selection; | 127 return selection; |
| 128 } | 128 } |
| 129 | 129 |
| 130 // Function considers Mac editing behavior a fallback when Page or Settings is n
ot available. | 130 // Function considers Mac editing behavior a fallback when Page or Settings is n
ot available. |
| 131 EditingBehavior Editor::behavior() const | 131 EditingBehavior Editor::behavior() const |
| 132 { | 132 { |
| 133 if (!frame().settings()) | 133 if (!frame().settings()) |
| 134 return EditingBehavior(EditingMacBehavior); | 134 return EditingBehavior(EditingMacBehavior); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 } | 342 } |
| 343 | 343 |
| 344 void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace) | 344 void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace) |
| 345 { | 345 { |
| 346 Element* target = findEventTargetFromSelection(); | 346 Element* target = findEventTargetFromSelection(); |
| 347 if (!target) | 347 if (!target) |
| 348 return; | 348 return; |
| 349 target->dispatchEvent(TextEvent::createForPlainTextPaste(frame().domWindow()
, pastingText, smartReplace)); | 349 target->dispatchEvent(TextEvent::createForPlainTextPaste(frame().domWindow()
, pastingText, smartReplace)); |
| 350 } | 350 } |
| 351 | 351 |
| 352 void Editor::pasteAsFragment(PassRefPtrWillBeRawPtr<DocumentFragment> pastingFra
gment, bool smartReplace, bool matchStyle) | 352 void Editor::pasteAsFragment(RawPtr<DocumentFragment> pastingFragment, bool smar
tReplace, bool matchStyle) |
| 353 { | 353 { |
| 354 Element* target = findEventTargetFromSelection(); | 354 Element* target = findEventTargetFromSelection(); |
| 355 if (!target) | 355 if (!target) |
| 356 return; | 356 return; |
| 357 target->dispatchEvent(TextEvent::createForFragmentPaste(frame().domWindow(),
pastingFragment, smartReplace, matchStyle)); | 357 target->dispatchEvent(TextEvent::createForFragmentPaste(frame().domWindow(),
pastingFragment, smartReplace, matchStyle)); |
| 358 } | 358 } |
| 359 | 359 |
| 360 bool Editor::tryDHTMLCopy() | 360 bool Editor::tryDHTMLCopy() |
| 361 { | 361 { |
| 362 if (frame().selection().isInPasswordField()) | 362 if (frame().selection().isInPasswordField()) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 379 } | 379 } |
| 380 | 380 |
| 381 void Editor::pasteAsPlainTextWithPasteboard(Pasteboard* pasteboard) | 381 void Editor::pasteAsPlainTextWithPasteboard(Pasteboard* pasteboard) |
| 382 { | 382 { |
| 383 String text = pasteboard->plainText(); | 383 String text = pasteboard->plainText(); |
| 384 pasteAsPlainText(text, canSmartReplaceWithPasteboard(pasteboard)); | 384 pasteAsPlainText(text, canSmartReplaceWithPasteboard(pasteboard)); |
| 385 } | 385 } |
| 386 | 386 |
| 387 void Editor::pasteWithPasteboard(Pasteboard* pasteboard) | 387 void Editor::pasteWithPasteboard(Pasteboard* pasteboard) |
| 388 { | 388 { |
| 389 RefPtrWillBeRawPtr<DocumentFragment> fragment = nullptr; | 389 RawPtr<DocumentFragment> fragment = nullptr; |
| 390 bool chosePlainText = false; | 390 bool chosePlainText = false; |
| 391 | 391 |
| 392 if (pasteboard->isHTMLAvailable()) { | 392 if (pasteboard->isHTMLAvailable()) { |
| 393 unsigned fragmentStart = 0; | 393 unsigned fragmentStart = 0; |
| 394 unsigned fragmentEnd = 0; | 394 unsigned fragmentEnd = 0; |
| 395 KURL url; | 395 KURL url; |
| 396 String markup = pasteboard->readHTML(url, fragmentStart, fragmentEnd); | 396 String markup = pasteboard->readHTML(url, fragmentStart, fragmentEnd); |
| 397 if (!markup.isEmpty()) { | 397 if (!markup.isEmpty()) { |
| 398 ASSERT(frame().document()); | 398 ASSERT(frame().document()); |
| 399 fragment = createFragmentFromMarkupWithContext(*frame().document(),
markup, fragmentStart, fragmentEnd, url, DisallowScriptingAndPluginContent); | 399 fragment = createFragmentFromMarkupWithContext(*frame().document(),
markup, fragmentStart, fragmentEnd, url, DisallowScriptingAndPluginContent); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 if (!target) | 474 if (!target) |
| 475 return true; | 475 return true; |
| 476 | 476 |
| 477 DataTransfer* dataTransfer = DataTransfer::create( | 477 DataTransfer* dataTransfer = DataTransfer::create( |
| 478 DataTransfer::CopyAndPaste, | 478 DataTransfer::CopyAndPaste, |
| 479 policy, | 479 policy, |
| 480 policy == DataTransferWritable | 480 policy == DataTransferWritable |
| 481 ? DataObject::create() | 481 ? DataObject::create() |
| 482 : DataObject::createFromPasteboard(pasteMode)); | 482 : DataObject::createFromPasteboard(pasteMode)); |
| 483 | 483 |
| 484 RefPtrWillBeRawPtr<Event> evt = ClipboardEvent::create(eventType, true, true
, dataTransfer); | 484 RawPtr<Event> evt = ClipboardEvent::create(eventType, true, true, dataTransf
er); |
| 485 target->dispatchEvent(evt); | 485 target->dispatchEvent(evt); |
| 486 bool noDefaultProcessing = evt->defaultPrevented(); | 486 bool noDefaultProcessing = evt->defaultPrevented(); |
| 487 if (noDefaultProcessing && policy == DataTransferWritable) | 487 if (noDefaultProcessing && policy == DataTransferWritable) |
| 488 Pasteboard::generalPasteboard()->writeDataObject(dataTransfer->dataObjec
t()); | 488 Pasteboard::generalPasteboard()->writeDataObject(dataTransfer->dataObjec
t()); |
| 489 | 489 |
| 490 // invalidate clipboard here for security | 490 // invalidate clipboard here for security |
| 491 dataTransfer->setAccessPolicy(DataTransferNumb); | 491 dataTransfer->setAccessPolicy(DataTransferNumb); |
| 492 | 492 |
| 493 return !noDefaultProcessing; | 493 return !noDefaultProcessing; |
| 494 } | 494 } |
| 495 | 495 |
| 496 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) | 496 bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) |
| 497 { | 497 { |
| 498 return smartInsertDeleteEnabled() && pasteboard->canSmartReplace(); | 498 return smartInsertDeleteEnabled() && pasteboard->canSmartReplace(); |
| 499 } | 499 } |
| 500 | 500 |
| 501 void Editor::replaceSelectionWithFragment(PassRefPtrWillBeRawPtr<DocumentFragmen
t> fragment, bool selectReplacement, bool smartReplace, bool matchStyle) | 501 void Editor::replaceSelectionWithFragment(RawPtr<DocumentFragment> fragment, boo
l selectReplacement, bool smartReplace, bool matchStyle) |
| 502 { | 502 { |
| 503 if (frame().selection().isNone() || !frame().selection().isContentEditable()
|| !fragment) | 503 if (frame().selection().isNone() || !frame().selection().isContentEditable()
|| !fragment) |
| 504 return; | 504 return; |
| 505 | 505 |
| 506 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::P
reventNesting | ReplaceSelectionCommand::SanitizeFragment; | 506 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::P
reventNesting | ReplaceSelectionCommand::SanitizeFragment; |
| 507 if (selectReplacement) | 507 if (selectReplacement) |
| 508 options |= ReplaceSelectionCommand::SelectReplacement; | 508 options |= ReplaceSelectionCommand::SelectReplacement; |
| 509 if (smartReplace) | 509 if (smartReplace) |
| 510 options |= ReplaceSelectionCommand::SmartReplace; | 510 options |= ReplaceSelectionCommand::SmartReplace; |
| 511 if (matchStyle) | 511 if (matchStyle) |
| 512 options |= ReplaceSelectionCommand::MatchStyle; | 512 options |= ReplaceSelectionCommand::MatchStyle; |
| 513 ASSERT(frame().document()); | 513 ASSERT(frame().document()); |
| 514 ReplaceSelectionCommand::create(*frame().document(), fragment, options, Edit
ActionPaste)->apply(); | 514 ReplaceSelectionCommand::create(*frame().document(), fragment, options, Edit
ActionPaste)->apply(); |
| 515 revealSelectionAfterEditingOperation(); | 515 revealSelectionAfterEditingOperation(); |
| 516 } | 516 } |
| 517 | 517 |
| 518 void Editor::replaceSelectionWithText(const String& text, bool selectReplacement
, bool smartReplace) | 518 void Editor::replaceSelectionWithText(const String& text, bool selectReplacement
, bool smartReplace) |
| 519 { | 519 { |
| 520 replaceSelectionWithFragment(createFragmentFromText(selectedRange(), text),
selectReplacement, smartReplace, true); | 520 replaceSelectionWithFragment(createFragmentFromText(selectedRange(), text),
selectReplacement, smartReplace, true); |
| 521 } | 521 } |
| 522 | 522 |
| 523 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. | 523 // TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. |
| 524 void Editor::replaceSelectionAfterDragging(PassRefPtrWillBeRawPtr<DocumentFragme
nt> fragment, bool smartReplace, bool plainText) | 524 void Editor::replaceSelectionAfterDragging(RawPtr<DocumentFragment> fragment, bo
ol smartReplace, bool plainText) |
| 525 { | 525 { |
| 526 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S
electReplacement | ReplaceSelectionCommand::PreventNesting; | 526 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S
electReplacement | ReplaceSelectionCommand::PreventNesting; |
| 527 if (smartReplace) | 527 if (smartReplace) |
| 528 options |= ReplaceSelectionCommand::SmartReplace; | 528 options |= ReplaceSelectionCommand::SmartReplace; |
| 529 if (plainText) | 529 if (plainText) |
| 530 options |= ReplaceSelectionCommand::MatchStyle; | 530 options |= ReplaceSelectionCommand::MatchStyle; |
| 531 ASSERT(frame().document()); | 531 ASSERT(frame().document()); |
| 532 ReplaceSelectionCommand::create(*frame().document(), fragment, options, Edit
ActionDrag)->apply(); | 532 ReplaceSelectionCommand::create(*frame().document(), fragment, options, Edit
ActionDrag)->apply(); |
| 533 } | 533 } |
| 534 | 534 |
| 535 void Editor::moveSelectionAfterDragging(PassRefPtrWillBeRawPtr<DocumentFragment>
fragment, const Position& pos, bool smartInsert, bool smartDelete) | 535 void Editor::moveSelectionAfterDragging(RawPtr<DocumentFragment> fragment, const
Position& pos, bool smartInsert, bool smartDelete) |
| 536 { | 536 { |
| 537 MoveSelectionCommand::create(fragment, pos, smartInsert, smartDelete)->apply
(); | 537 MoveSelectionCommand::create(fragment, pos, smartInsert, smartDelete)->apply
(); |
| 538 } | 538 } |
| 539 | 539 |
| 540 EphemeralRange Editor::selectedRange() | 540 EphemeralRange Editor::selectedRange() |
| 541 { | 541 { |
| 542 return frame().selection().selection().toNormalizedEphemeralRange(); | 542 return frame().selection().selection().toNormalizedEphemeralRange(); |
| 543 } | 543 } |
| 544 | 544 |
| 545 bool Editor::shouldDeleteRange(const EphemeralRange& range) const | 545 bool Editor::shouldDeleteRange(const EphemeralRange& range) const |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 EditingStyle::styleAtSelectionStart(frame().selection().selection(), pro
pertyID == CSSPropertyBackgroundColor).get()); | 641 EditingStyle::styleAtSelectionStart(frame().selection().selection(), pro
pertyID == CSSPropertyBackgroundColor).get()); |
| 642 } | 642 } |
| 643 | 643 |
| 644 TriState Editor::selectionHasStyle(CSSPropertyID propertyID, const String& value
) const | 644 TriState Editor::selectionHasStyle(CSSPropertyID propertyID, const String& value
) const |
| 645 { | 645 { |
| 646 return EditingStyle::create(propertyID, value)->triStateOfStyle(frame().sele
ction().selection()); | 646 return EditingStyle::create(propertyID, value)->triStateOfStyle(frame().sele
ction().selection()); |
| 647 } | 647 } |
| 648 | 648 |
| 649 String Editor::selectionStartCSSPropertyValue(CSSPropertyID propertyID) | 649 String Editor::selectionStartCSSPropertyValue(CSSPropertyID propertyID) |
| 650 { | 650 { |
| 651 RefPtrWillBeRawPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelec
tionStart(frame().selection().selection(), | 651 RawPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelectionStart(fr
ame().selection().selection(), |
| 652 propertyID == CSSPropertyBackgroundColor); | 652 propertyID == CSSPropertyBackgroundColor); |
| 653 if (!selectionStyle || !selectionStyle->style()) | 653 if (!selectionStyle || !selectionStyle->style()) |
| 654 return String(); | 654 return String(); |
| 655 | 655 |
| 656 if (propertyID == CSSPropertyFontSize) | 656 if (propertyID == CSSPropertyFontSize) |
| 657 return String::number(selectionStyle->legacyFontSize(frame().document())
); | 657 return String::number(selectionStyle->legacyFontSize(frame().document())
); |
| 658 return selectionStyle->style()->getPropertyValue(propertyID); | 658 return selectionStyle->style()->getPropertyValue(propertyID); |
| 659 } | 659 } |
| 660 | 660 |
| 661 static void dispatchEditableContentChangedEvents(PassRefPtrWillBeRawPtr<Element>
startRoot, PassRefPtrWillBeRawPtr<Element> endRoot) | 661 static void dispatchEditableContentChangedEvents(RawPtr<Element> startRoot, RawP
tr<Element> endRoot) |
| 662 { | 662 { |
| 663 if (startRoot) | 663 if (startRoot) |
| 664 startRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableCon
tentChanged)); | 664 startRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableCon
tentChanged)); |
| 665 if (endRoot && endRoot != startRoot) | 665 if (endRoot && endRoot != startRoot) |
| 666 endRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableConte
ntChanged)); | 666 endRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableConte
ntChanged)); |
| 667 } | 667 } |
| 668 | 668 |
| 669 void Editor::requestSpellcheckingAfterApplyingCommand(CompositeEditCommand* cmd) | 669 void Editor::requestSpellcheckingAfterApplyingCommand(CompositeEditCommand* cmd) |
| 670 { | 670 { |
| 671 // Note: Request spell checking for and only for |ReplaceSelectionCommand|s | 671 // Note: Request spell checking for and only for |ReplaceSelectionCommand|s |
| 672 // created in |Editor::replaceSelectionWithFragment()|. | 672 // created in |Editor::replaceSelectionWithFragment()|. |
| 673 // TODO(xiaochengh): May also need to do this after dragging crbug.com/29804
6. | 673 // TODO(xiaochengh): May also need to do this after dragging crbug.com/29804
6. |
| 674 if (cmd->editingAction() != EditActionPaste) | 674 if (cmd->editingAction() != EditActionPaste) |
| 675 return; | 675 return; |
| 676 if (frame().selection().isInPasswordField() || !spellChecker().isContinuousS
pellCheckingEnabled()) | 676 if (frame().selection().isInPasswordField() || !spellChecker().isContinuousS
pellCheckingEnabled()) |
| 677 return; | 677 return; |
| 678 ASSERT(cmd->isReplaceSelectionCommand()); | 678 ASSERT(cmd->isReplaceSelectionCommand()); |
| 679 const EphemeralRange& insertedRange = toReplaceSelectionCommand(cmd)->insert
edRange(); | 679 const EphemeralRange& insertedRange = toReplaceSelectionCommand(cmd)->insert
edRange(); |
| 680 if (insertedRange.isNull()) | 680 if (insertedRange.isNull()) |
| 681 return; | 681 return; |
| 682 spellChecker().chunkAndMarkAllMisspellingsAndBadGrammar(cmd->endingSelection
().rootEditableElement(), insertedRange); | 682 spellChecker().chunkAndMarkAllMisspellingsAndBadGrammar(cmd->endingSelection
().rootEditableElement(), insertedRange); |
| 683 } | 683 } |
| 684 | 684 |
| 685 void Editor::appliedEditing(PassRefPtrWillBeRawPtr<CompositeEditCommand> cmd) | 685 void Editor::appliedEditing(RawPtr<CompositeEditCommand> cmd) |
| 686 { | 686 { |
| 687 EventQueueScope scope; | 687 EventQueueScope scope; |
| 688 frame().document()->updateLayout(); | 688 frame().document()->updateLayout(); |
| 689 | 689 |
| 690 // Request spell checking after pasting before any further DOM change. | 690 // Request spell checking after pasting before any further DOM change. |
| 691 requestSpellcheckingAfterApplyingCommand(cmd.get()); | 691 requestSpellcheckingAfterApplyingCommand(cmd.get()); |
| 692 | 692 |
| 693 EditCommandComposition* composition = cmd->composition(); | 693 EditCommandComposition* composition = cmd->composition(); |
| 694 ASSERT(composition); | 694 ASSERT(composition); |
| 695 dispatchEditableContentChangedEvents(composition->startingRootEditableElemen
t(), composition->endingRootEditableElement()); | 695 dispatchEditableContentChangedEvents(composition->startingRootEditableElemen
t(), composition->endingRootEditableElement()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 708 // Only register a new undo command if the command passed in is | 708 // Only register a new undo command if the command passed in is |
| 709 // different from the last command | 709 // different from the last command |
| 710 m_lastEditCommand = cmd; | 710 m_lastEditCommand = cmd; |
| 711 if (UndoStack* undoStack = this->undoStack()) | 711 if (UndoStack* undoStack = this->undoStack()) |
| 712 undoStack->registerUndoStep(m_lastEditCommand->ensureComposition()); | 712 undoStack->registerUndoStep(m_lastEditCommand->ensureComposition()); |
| 713 } | 713 } |
| 714 | 714 |
| 715 respondToChangedContents(newSelection); | 715 respondToChangedContents(newSelection); |
| 716 } | 716 } |
| 717 | 717 |
| 718 void Editor::unappliedEditing(PassRefPtrWillBeRawPtr<EditCommandComposition> cmd
) | 718 void Editor::unappliedEditing(RawPtr<EditCommandComposition> cmd) |
| 719 { | 719 { |
| 720 EventQueueScope scope; | 720 EventQueueScope scope; |
| 721 frame().document()->updateLayout(); | 721 frame().document()->updateLayout(); |
| 722 | 722 |
| 723 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd
->endingRootEditableElement()); | 723 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd
->endingRootEditableElement()); |
| 724 | 724 |
| 725 VisibleSelection newSelection(cmd->startingSelection()); | 725 VisibleSelection newSelection(cmd->startingSelection()); |
| 726 newSelection.validatePositionsIfNeeded(); | 726 newSelection.validatePositionsIfNeeded(); |
| 727 if (newSelection.start().document() == frame().document() && newSelection.en
d().document() == frame().document()) | 727 if (newSelection.start().document() == frame().document() && newSelection.en
d().document() == frame().document()) |
| 728 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping |
FrameSelection::ClearTypingStyle); | 728 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping |
FrameSelection::ClearTypingStyle); |
| 729 | 729 |
| 730 m_lastEditCommand = nullptr; | 730 m_lastEditCommand = nullptr; |
| 731 if (UndoStack* undoStack = this->undoStack()) | 731 if (UndoStack* undoStack = this->undoStack()) |
| 732 undoStack->registerRedoStep(cmd); | 732 undoStack->registerRedoStep(cmd); |
| 733 respondToChangedContents(newSelection); | 733 respondToChangedContents(newSelection); |
| 734 } | 734 } |
| 735 | 735 |
| 736 void Editor::reappliedEditing(PassRefPtrWillBeRawPtr<EditCommandComposition> cmd
) | 736 void Editor::reappliedEditing(RawPtr<EditCommandComposition> cmd) |
| 737 { | 737 { |
| 738 EventQueueScope scope; | 738 EventQueueScope scope; |
| 739 frame().document()->updateLayout(); | 739 frame().document()->updateLayout(); |
| 740 | 740 |
| 741 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd
->endingRootEditableElement()); | 741 dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd
->endingRootEditableElement()); |
| 742 | 742 |
| 743 VisibleSelection newSelection(cmd->endingSelection()); | 743 VisibleSelection newSelection(cmd->endingSelection()); |
| 744 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | Fram
eSelection::ClearTypingStyle); | 744 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | Fram
eSelection::ClearTypingStyle); |
| 745 | 745 |
| 746 m_lastEditCommand = nullptr; | 746 m_lastEditCommand = nullptr; |
| 747 if (UndoStack* undoStack = this->undoStack()) | 747 if (UndoStack* undoStack = this->undoStack()) |
| 748 undoStack->registerUndoStep(cmd); | 748 undoStack->registerUndoStep(cmd); |
| 749 respondToChangedContents(newSelection); | 749 respondToChangedContents(newSelection); |
| 750 } | 750 } |
| 751 | 751 |
| 752 PassOwnPtrWillBeRawPtr<Editor> Editor::create(LocalFrame& frame) | 752 RawPtr<Editor> Editor::create(LocalFrame& frame) |
| 753 { | 753 { |
| 754 return adoptPtrWillBeNoop(new Editor(frame)); | 754 return (new Editor(frame)); |
| 755 } | 755 } |
| 756 | 756 |
| 757 Editor::Editor(LocalFrame& frame) | 757 Editor::Editor(LocalFrame& frame) |
| 758 : m_frame(&frame) | 758 : m_frame(&frame) |
| 759 , m_preventRevealSelection(0) | 759 , m_preventRevealSelection(0) |
| 760 , m_shouldStartNewKillRingSequence(false) | 760 , m_shouldStartNewKillRingSequence(false) |
| 761 // This is off by default, since most editors want this behavior (this match
es IE but not FF). | 761 // This is off by default, since most editors want this behavior (this match
es IE but not FF). |
| 762 , m_shouldStyleWithCSS(false) | 762 , m_shouldStyleWithCSS(false) |
| 763 , m_killRing(adoptPtr(new KillRing)) | 763 , m_killRing(adoptPtr(new KillRing)) |
| 764 , m_areMarkedTextMatchesHighlighted(false) | 764 , m_areMarkedTextMatchesHighlighted(false) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 793 return false; | 793 return false; |
| 794 | 794 |
| 795 spellChecker().updateMarkersForWordsAffectedByEditing(isSpaceOrNewline(text[
0])); | 795 spellChecker().updateMarkersForWordsAffectedByEditing(isSpaceOrNewline(text[
0])); |
| 796 | 796 |
| 797 // Get the selection to use for the event that triggered this insertText. | 797 // Get the selection to use for the event that triggered this insertText. |
| 798 // If the event handler changed the selection, we may want to use a differen
t selection | 798 // If the event handler changed the selection, we may want to use a differen
t selection |
| 799 // that is contained in the event target. | 799 // that is contained in the event target. |
| 800 selection = selectionForCommand(triggeringEvent); | 800 selection = selectionForCommand(triggeringEvent); |
| 801 if (selection.isContentEditable()) { | 801 if (selection.isContentEditable()) { |
| 802 if (Node* selectionStart = selection.start().anchorNode()) { | 802 if (Node* selectionStart = selection.start().anchorNode()) { |
| 803 RefPtrWillBeRawPtr<Document> document(selectionStart->document()); | 803 RawPtr<Document> document(selectionStart->document()); |
| 804 | 804 |
| 805 // Insert the text | 805 // Insert the text |
| 806 TypingCommand::Options options = 0; | 806 TypingCommand::Options options = 0; |
| 807 if (selectInsertedText) | 807 if (selectInsertedText) |
| 808 options |= TypingCommand::SelectInsertedText; | 808 options |= TypingCommand::SelectInsertedText; |
| 809 TypingCommand::insertText(*document.get(), text, selection, options,
triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompos
itionConfirm : TypingCommand::TextCompositionNone); | 809 TypingCommand::insertText(*document.get(), text, selection, options,
triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompos
itionConfirm : TypingCommand::TextCompositionNone); |
| 810 | 810 |
| 811 // Reveal the current selection | 811 // Reveal the current selection |
| 812 if (LocalFrame* editedFrame = document->frame()) { | 812 if (LocalFrame* editedFrame = document->frame()) { |
| 813 if (Page* page = editedFrame->page()) | 813 if (Page* page = editedFrame->page()) |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 Element* focusedElement = frame().document()->focusedElement(); | 1027 Element* focusedElement = frame().document()->focusedElement(); |
| 1028 if (isHTMLTextFormControlElement(focusedElement)) { | 1028 if (isHTMLTextFormControlElement(focusedElement)) { |
| 1029 if (direction == NaturalWritingDirection) | 1029 if (direction == NaturalWritingDirection) |
| 1030 return; | 1030 return; |
| 1031 focusedElement->setAttribute(dirAttr, direction == LeftToRightWritingDir
ection ? "ltr" : "rtl"); | 1031 focusedElement->setAttribute(dirAttr, direction == LeftToRightWritingDir
ection ? "ltr" : "rtl"); |
| 1032 focusedElement->dispatchInputEvent(); | 1032 focusedElement->dispatchInputEvent(); |
| 1033 frame().document()->updateLayoutTreeIfNeeded(); | 1033 frame().document()->updateLayoutTreeIfNeeded(); |
| 1034 return; | 1034 return; |
| 1035 } | 1035 } |
| 1036 | 1036 |
| 1037 RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet:
:create(HTMLQuirksMode); | 1037 RawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create(HTML
QuirksMode); |
| 1038 style->setProperty(CSSPropertyDirection, direction == LeftToRightWritingDire
ction ? "ltr" : direction == RightToLeftWritingDirection ? "rtl" : "inherit", fa
lse); | 1038 style->setProperty(CSSPropertyDirection, direction == LeftToRightWritingDire
ction ? "ltr" : direction == RightToLeftWritingDirection ? "rtl" : "inherit", fa
lse); |
| 1039 applyParagraphStyleToSelection(style.get(), EditActionSetWritingDirection); | 1039 applyParagraphStyleToSelection(style.get(), EditActionSetWritingDirection); |
| 1040 } | 1040 } |
| 1041 | 1041 |
| 1042 void Editor::revealSelectionAfterEditingOperation(const ScrollAlignment& alignme
nt, RevealExtentOption revealExtentOption) | 1042 void Editor::revealSelectionAfterEditingOperation(const ScrollAlignment& alignme
nt, RevealExtentOption revealExtentOption) |
| 1043 { | 1043 { |
| 1044 if (m_preventRevealSelection) | 1044 if (m_preventRevealSelection) |
| 1045 return; | 1045 return; |
| 1046 | 1046 |
| 1047 frame().selection().revealSelection(alignment, revealExtentOption); | 1047 frame().selection().revealSelection(alignment, revealExtentOption); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 void Editor::computeAndSetTypingStyle(StylePropertySet* style, EditAction editin
gAction) | 1152 void Editor::computeAndSetTypingStyle(StylePropertySet* style, EditAction editin
gAction) |
| 1153 { | 1153 { |
| 1154 if (!style || style->isEmpty()) { | 1154 if (!style || style->isEmpty()) { |
| 1155 frame().selection().clearTypingStyle(); | 1155 frame().selection().clearTypingStyle(); |
| 1156 return; | 1156 return; |
| 1157 } | 1157 } |
| 1158 | 1158 |
| 1159 // Calculate the current typing style. | 1159 // Calculate the current typing style. |
| 1160 RefPtrWillBeRawPtr<EditingStyle> typingStyle = nullptr; | 1160 RawPtr<EditingStyle> typingStyle = nullptr; |
| 1161 if (frame().selection().typingStyle()) { | 1161 if (frame().selection().typingStyle()) { |
| 1162 typingStyle = frame().selection().typingStyle()->copy(); | 1162 typingStyle = frame().selection().typingStyle()->copy(); |
| 1163 typingStyle->overrideWithStyle(style); | 1163 typingStyle->overrideWithStyle(style); |
| 1164 } else { | 1164 } else { |
| 1165 typingStyle = EditingStyle::create(style); | 1165 typingStyle = EditingStyle::create(style); |
| 1166 } | 1166 } |
| 1167 | 1167 |
| 1168 typingStyle->prepareToApplyAt(frame().selection().selection().visibleStart()
.deepEquivalent(), EditingStyle::PreserveWritingDirection); | 1168 typingStyle->prepareToApplyAt(frame().selection().selection().visibleStart()
.deepEquivalent(), EditingStyle::PreserveWritingDirection); |
| 1169 | 1169 |
| 1170 // Handle block styles, substracting these from the typing style. | 1170 // Handle block styles, substracting these from the typing style. |
| 1171 RefPtrWillBeRawPtr<EditingStyle> blockStyle = typingStyle->extractAndRemoveB
lockProperties(); | 1171 RawPtr<EditingStyle> blockStyle = typingStyle->extractAndRemoveBlockProperti
es(); |
| 1172 if (!blockStyle->isEmpty()) { | 1172 if (!blockStyle->isEmpty()) { |
| 1173 ASSERT(frame().document()); | 1173 ASSERT(frame().document()); |
| 1174 ApplyStyleCommand::create(*frame().document(), blockStyle.get(), editing
Action)->apply(); | 1174 ApplyStyleCommand::create(*frame().document(), blockStyle.get(), editing
Action)->apply(); |
| 1175 } | 1175 } |
| 1176 | 1176 |
| 1177 // Set the remaining style as the typing style. | 1177 // Set the remaining style as the typing style. |
| 1178 frame().selection().setTypingStyle(typingStyle); | 1178 frame().selection().setTypingStyle(typingStyle); |
| 1179 } | 1179 } |
| 1180 | 1180 |
| 1181 bool Editor::findString(const String& target, FindOptions options) | 1181 bool Editor::findString(const String& target, FindOptions options) |
| 1182 { | 1182 { |
| 1183 VisibleSelection selection = frame().selection().selection(); | 1183 VisibleSelection selection = frame().selection().selection(); |
| 1184 | 1184 |
| 1185 // TODO(yosin) We should make |findRangeOfString()| to return | 1185 // TODO(yosin) We should make |findRangeOfString()| to return |
| 1186 // |EphemeralRange| rather than|Range| object. | 1186 // |EphemeralRange| rather than|Range| object. |
| 1187 RefPtrWillBeRawPtr<Range> resultRange = findRangeOfString(target, EphemeralR
ange(selection.start(), selection.end()), static_cast<FindOptions>(options | Fin
dAPICall)); | 1187 RawPtr<Range> resultRange = findRangeOfString(target, EphemeralRange(selecti
on.start(), selection.end()), static_cast<FindOptions>(options | FindAPICall)); |
| 1188 | 1188 |
| 1189 if (!resultRange) | 1189 if (!resultRange) |
| 1190 return false; | 1190 return false; |
| 1191 | 1191 |
| 1192 frame().selection().setSelection(VisibleSelection(EphemeralRange(resultRange
.get()))); | 1192 frame().selection().setSelection(VisibleSelection(EphemeralRange(resultRange
.get()))); |
| 1193 frame().selection().revealSelection(); | 1193 frame().selection().revealSelection(); |
| 1194 return true; | 1194 return true; |
| 1195 } | 1195 } |
| 1196 | 1196 |
| 1197 template <typename Strategy> | 1197 template <typename Strategy> |
| 1198 static PassRefPtrWillBeRawPtr<Range> findStringAndScrollToVisibleAlgorithm(Edito
r& editor, const String& target, const EphemeralRangeTemplate<Strategy>& previou
sMatch, FindOptions options) | 1198 static RawPtr<Range> findStringAndScrollToVisibleAlgorithm(Editor& editor, const
String& target, const EphemeralRangeTemplate<Strategy>& previousMatch, FindOpti
ons options) |
| 1199 { | 1199 { |
| 1200 RefPtrWillBeRawPtr<Range> nextMatch = editor.findRangeOfString(target, previ
ousMatch, options); | 1200 RawPtr<Range> nextMatch = editor.findRangeOfString(target, previousMatch, op
tions); |
| 1201 if (!nextMatch) | 1201 if (!nextMatch) |
| 1202 return nullptr; | 1202 return nullptr; |
| 1203 | 1203 |
| 1204 nextMatch->firstNode()->layoutObject()->scrollRectToVisible(LayoutRect(nextM
atch->boundingBox()), | 1204 nextMatch->firstNode()->layoutObject()->scrollRectToVisible(LayoutRect(nextM
atch->boundingBox()), |
| 1205 ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeed
ed, UserScroll); | 1205 ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeed
ed, UserScroll); |
| 1206 | 1206 |
| 1207 return nextMatch.release(); | 1207 return nextMatch.release(); |
| 1208 } | 1208 } |
| 1209 | 1209 |
| 1210 PassRefPtrWillBeRawPtr<Range> Editor::findStringAndScrollToVisible(const String&
target, Range* range, FindOptions options) | 1210 RawPtr<Range> Editor::findStringAndScrollToVisible(const String& target, Range*
range, FindOptions options) |
| 1211 { | 1211 { |
| 1212 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) | 1212 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
| 1213 return findStringAndScrollToVisibleAlgorithm<EditingInFlatTreeStrategy>(
*this, target, EphemeralRangeInFlatTree(range), options); | 1213 return findStringAndScrollToVisibleAlgorithm<EditingInFlatTreeStrategy>(
*this, target, EphemeralRangeInFlatTree(range), options); |
| 1214 return findStringAndScrollToVisibleAlgorithm<EditingStrategy>(*this, target,
EphemeralRange(range), options); | 1214 return findStringAndScrollToVisibleAlgorithm<EditingStrategy>(*this, target,
EphemeralRange(range), options); |
| 1215 } | 1215 } |
| 1216 | 1216 |
| 1217 // TODO(yosin) We should return |EphemeralRange| rather than |Range|. We use | 1217 // TODO(yosin) We should return |EphemeralRange| rather than |Range|. We use |
| 1218 // |Range| object for checking whether start and end position crossing shadow | 1218 // |Range| object for checking whether start and end position crossing shadow |
| 1219 // boundaries, however we can do it without |Range| object. | 1219 // boundaries, however we can do it without |Range| object. |
| 1220 template <typename Strategy> | 1220 template <typename Strategy> |
| 1221 static PassRefPtrWillBeRawPtr<Range> findStringBetweenPositions(const String& ta
rget, const EphemeralRangeTemplate<Strategy>& referenceRange, FindOptions option
s) | 1221 static RawPtr<Range> findStringBetweenPositions(const String& target, const Ephe
meralRangeTemplate<Strategy>& referenceRange, FindOptions options) |
| 1222 { | 1222 { |
| 1223 EphemeralRangeTemplate<Strategy> searchRange(referenceRange); | 1223 EphemeralRangeTemplate<Strategy> searchRange(referenceRange); |
| 1224 | 1224 |
| 1225 bool forward = !(options & Backwards); | 1225 bool forward = !(options & Backwards); |
| 1226 | 1226 |
| 1227 while (true) { | 1227 while (true) { |
| 1228 EphemeralRangeTemplate<Strategy> resultRange = findPlainText(searchRange
, target, options); | 1228 EphemeralRangeTemplate<Strategy> resultRange = findPlainText(searchRange
, target, options); |
| 1229 if (resultRange.isCollapsed()) | 1229 if (resultRange.isCollapsed()) |
| 1230 return nullptr; | 1230 return nullptr; |
| 1231 | 1231 |
| 1232 RefPtrWillBeRawPtr<Range> rangeObject = Range::create(resultRange.docume
nt(), toPositionInDOMTree(resultRange.startPosition()), toPositionInDOMTree(resu
ltRange.endPosition())); | 1232 RawPtr<Range> rangeObject = Range::create(resultRange.document(), toPosi
tionInDOMTree(resultRange.startPosition()), toPositionInDOMTree(resultRange.endP
osition())); |
| 1233 if (!rangeObject->collapsed()) | 1233 if (!rangeObject->collapsed()) |
| 1234 return rangeObject.release(); | 1234 return rangeObject.release(); |
| 1235 | 1235 |
| 1236 // Found text spans over multiple TreeScopes. Since it's impossible to | 1236 // Found text spans over multiple TreeScopes. Since it's impossible to |
| 1237 // return such section as a Range, we skip this match and seek for the | 1237 // return such section as a Range, we skip this match and seek for the |
| 1238 // next occurrence. | 1238 // next occurrence. |
| 1239 // TODO(yosin) Handle this case. | 1239 // TODO(yosin) Handle this case. |
| 1240 if (forward) { | 1240 if (forward) { |
| 1241 // TODO(yosin) We should use |PositionMoveType::Character| | 1241 // TODO(yosin) We should use |PositionMoveType::Character| |
| 1242 // for |nextPositionOf()|. | 1242 // for |nextPositionOf()|. |
| 1243 searchRange = EphemeralRangeTemplate<Strategy>(nextPositionOf(result
Range.startPosition(), PositionMoveType::CodePoint), searchRange.endPosition()); | 1243 searchRange = EphemeralRangeTemplate<Strategy>(nextPositionOf(result
Range.startPosition(), PositionMoveType::CodePoint), searchRange.endPosition()); |
| 1244 } else { | 1244 } else { |
| 1245 // TODO(yosin) We should use |PositionMoveType::Character| | 1245 // TODO(yosin) We should use |PositionMoveType::Character| |
| 1246 // for |previousPositionOf()|. | 1246 // for |previousPositionOf()|. |
| 1247 searchRange = EphemeralRangeTemplate<Strategy>(searchRange.startPosi
tion(), previousPositionOf(resultRange.endPosition(), PositionMoveType::CodePoin
t)); | 1247 searchRange = EphemeralRangeTemplate<Strategy>(searchRange.startPosi
tion(), previousPositionOf(resultRange.endPosition(), PositionMoveType::CodePoin
t)); |
| 1248 } | 1248 } |
| 1249 } | 1249 } |
| 1250 | 1250 |
| 1251 ASSERT_NOT_REACHED(); | 1251 ASSERT_NOT_REACHED(); |
| 1252 return nullptr; | 1252 return nullptr; |
| 1253 } | 1253 } |
| 1254 | 1254 |
| 1255 template <typename Strategy> | 1255 template <typename Strategy> |
| 1256 static PassRefPtrWillBeRawPtr<Range> findRangeOfStringAlgorithm(Document& docume
nt, const String& target, const EphemeralRangeTemplate<Strategy>& referenceRange
, FindOptions options) | 1256 static RawPtr<Range> findRangeOfStringAlgorithm(Document& document, const String
& target, const EphemeralRangeTemplate<Strategy>& referenceRange, FindOptions op
tions) |
| 1257 { | 1257 { |
| 1258 if (target.isEmpty()) | 1258 if (target.isEmpty()) |
| 1259 return nullptr; | 1259 return nullptr; |
| 1260 | 1260 |
| 1261 // Start from an edge of the reference range. Which edge is used depends on | 1261 // Start from an edge of the reference range. Which edge is used depends on |
| 1262 // whether we're searching forward or backward, and whether startInSelection | 1262 // whether we're searching forward or backward, and whether startInSelection |
| 1263 // is set. | 1263 // is set. |
| 1264 EphemeralRangeTemplate<Strategy> documentRange = EphemeralRangeTemplate<Stra
tegy>::rangeOfContents(document); | 1264 EphemeralRangeTemplate<Strategy> documentRange = EphemeralRangeTemplate<Stra
tegy>::rangeOfContents(document); |
| 1265 EphemeralRangeTemplate<Strategy> searchRange(documentRange); | 1265 EphemeralRangeTemplate<Strategy> searchRange(documentRange); |
| 1266 | 1266 |
| 1267 bool forward = !(options & Backwards); | 1267 bool forward = !(options & Backwards); |
| 1268 bool startInReferenceRange = false; | 1268 bool startInReferenceRange = false; |
| 1269 if (referenceRange.isNotNull()) { | 1269 if (referenceRange.isNotNull()) { |
| 1270 startInReferenceRange = options & StartInSelection; | 1270 startInReferenceRange = options & StartInSelection; |
| 1271 if (forward && startInReferenceRange) | 1271 if (forward && startInReferenceRange) |
| 1272 searchRange = EphemeralRangeTemplate<Strategy>(referenceRange.startP
osition(), documentRange.endPosition()); | 1272 searchRange = EphemeralRangeTemplate<Strategy>(referenceRange.startP
osition(), documentRange.endPosition()); |
| 1273 else if (forward) | 1273 else if (forward) |
| 1274 searchRange = EphemeralRangeTemplate<Strategy>(referenceRange.endPos
ition(), documentRange.endPosition()); | 1274 searchRange = EphemeralRangeTemplate<Strategy>(referenceRange.endPos
ition(), documentRange.endPosition()); |
| 1275 else if (startInReferenceRange) | 1275 else if (startInReferenceRange) |
| 1276 searchRange = EphemeralRangeTemplate<Strategy>(documentRange.startPo
sition(), referenceRange.endPosition()); | 1276 searchRange = EphemeralRangeTemplate<Strategy>(documentRange.startPo
sition(), referenceRange.endPosition()); |
| 1277 else | 1277 else |
| 1278 searchRange = EphemeralRangeTemplate<Strategy>(documentRange.startPo
sition(), referenceRange.startPosition()); | 1278 searchRange = EphemeralRangeTemplate<Strategy>(documentRange.startPo
sition(), referenceRange.startPosition()); |
| 1279 } | 1279 } |
| 1280 | 1280 |
| 1281 RefPtrWillBeRawPtr<Range> resultRange = findStringBetweenPositions(target, s
earchRange, options); | 1281 RawPtr<Range> resultRange = findStringBetweenPositions(target, searchRange,
options); |
| 1282 | 1282 |
| 1283 // If we started in the reference range and the found range exactly matches | 1283 // If we started in the reference range and the found range exactly matches |
| 1284 // the reference range, find again. Build a selection with the found range | 1284 // the reference range, find again. Build a selection with the found range |
| 1285 // to remove collapsed whitespace. Compare ranges instead of selection | 1285 // to remove collapsed whitespace. Compare ranges instead of selection |
| 1286 // objects to ignore the way that the current selection was made. | 1286 // objects to ignore the way that the current selection was made. |
| 1287 if (resultRange && startInReferenceRange && normalizeRange(EphemeralRangeTem
plate<Strategy>(resultRange.get())) == referenceRange) { | 1287 if (resultRange && startInReferenceRange && normalizeRange(EphemeralRangeTem
plate<Strategy>(resultRange.get())) == referenceRange) { |
| 1288 if (forward) | 1288 if (forward) |
| 1289 searchRange = EphemeralRangeTemplate<Strategy>(fromPositionInDOMTree
<Strategy>(resultRange->endPosition()), searchRange.endPosition()); | 1289 searchRange = EphemeralRangeTemplate<Strategy>(fromPositionInDOMTree
<Strategy>(resultRange->endPosition()), searchRange.endPosition()); |
| 1290 else | 1290 else |
| 1291 searchRange = EphemeralRangeTemplate<Strategy>(searchRange.startPosi
tion(), fromPositionInDOMTree<Strategy>(resultRange->startPosition())); | 1291 searchRange = EphemeralRangeTemplate<Strategy>(searchRange.startPosi
tion(), fromPositionInDOMTree<Strategy>(resultRange->startPosition())); |
| 1292 resultRange = findStringBetweenPositions(target, searchRange, options); | 1292 resultRange = findStringBetweenPositions(target, searchRange, options); |
| 1293 } | 1293 } |
| 1294 | 1294 |
| 1295 if (!resultRange && options & WrapAround) | 1295 if (!resultRange && options & WrapAround) |
| 1296 return findStringBetweenPositions(target, documentRange, options); | 1296 return findStringBetweenPositions(target, documentRange, options); |
| 1297 | 1297 |
| 1298 return resultRange.release(); | 1298 return resultRange.release(); |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 PassRefPtrWillBeRawPtr<Range> Editor::findRangeOfString(const String& target, co
nst EphemeralRange& reference, FindOptions options) | 1301 RawPtr<Range> Editor::findRangeOfString(const String& target, const EphemeralRan
ge& reference, FindOptions options) |
| 1302 { | 1302 { |
| 1303 return findRangeOfStringAlgorithm<EditingStrategy>(*frame().document(), targ
et, reference, options); | 1303 return findRangeOfStringAlgorithm<EditingStrategy>(*frame().document(), targ
et, reference, options); |
| 1304 } | 1304 } |
| 1305 | 1305 |
| 1306 PassRefPtrWillBeRawPtr<Range> Editor::findRangeOfString(const String& target, co
nst EphemeralRangeInFlatTree& reference, FindOptions options) | 1306 RawPtr<Range> Editor::findRangeOfString(const String& target, const EphemeralRan
geInFlatTree& reference, FindOptions options) |
| 1307 { | 1307 { |
| 1308 return findRangeOfStringAlgorithm<EditingInFlatTreeStrategy>(*frame().docume
nt(), target, reference, options); | 1308 return findRangeOfStringAlgorithm<EditingInFlatTreeStrategy>(*frame().docume
nt(), target, reference, options); |
| 1309 } | 1309 } |
| 1310 | 1310 |
| 1311 void Editor::setMarkedTextMatchesAreHighlighted(bool flag) | 1311 void Editor::setMarkedTextMatchesAreHighlighted(bool flag) |
| 1312 { | 1312 { |
| 1313 if (flag == m_areMarkedTextMatchesHighlighted) | 1313 if (flag == m_areMarkedTextMatchesHighlighted) |
| 1314 return; | 1314 return; |
| 1315 | 1315 |
| 1316 m_areMarkedTextMatchesHighlighted = flag; | 1316 m_areMarkedTextMatchesHighlighted = flag; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1335 frame().selection().setShouldShowBlockCursor(m_overwriteModeEnabled); | 1335 frame().selection().setShouldShowBlockCursor(m_overwriteModeEnabled); |
| 1336 } | 1336 } |
| 1337 | 1337 |
| 1338 void Editor::tidyUpHTMLStructure(Document& document) | 1338 void Editor::tidyUpHTMLStructure(Document& document) |
| 1339 { | 1339 { |
| 1340 // hasEditableStyle() needs up-to-date ComputedStyle. | 1340 // hasEditableStyle() needs up-to-date ComputedStyle. |
| 1341 document.updateLayoutTreeIfNeeded(); | 1341 document.updateLayoutTreeIfNeeded(); |
| 1342 bool needsValidStructure = document.hasEditableStyle() || (document.document
Element() && document.documentElement()->hasEditableStyle()); | 1342 bool needsValidStructure = document.hasEditableStyle() || (document.document
Element() && document.documentElement()->hasEditableStyle()); |
| 1343 if (!needsValidStructure) | 1343 if (!needsValidStructure) |
| 1344 return; | 1344 return; |
| 1345 RefPtrWillBeRawPtr<Element> existingHead = nullptr; | 1345 RawPtr<Element> existingHead = nullptr; |
| 1346 RefPtrWillBeRawPtr<Element> existingBody = nullptr; | 1346 RawPtr<Element> existingBody = nullptr; |
| 1347 Element* currentRoot = document.documentElement(); | 1347 Element* currentRoot = document.documentElement(); |
| 1348 if (currentRoot) { | 1348 if (currentRoot) { |
| 1349 if (isHTMLHtmlElement(currentRoot)) | 1349 if (isHTMLHtmlElement(currentRoot)) |
| 1350 return; | 1350 return; |
| 1351 if (isHTMLHeadElement(currentRoot)) | 1351 if (isHTMLHeadElement(currentRoot)) |
| 1352 existingHead = currentRoot; | 1352 existingHead = currentRoot; |
| 1353 else if (isHTMLBodyElement(currentRoot)) | 1353 else if (isHTMLBodyElement(currentRoot)) |
| 1354 existingBody = currentRoot; | 1354 existingBody = currentRoot; |
| 1355 else if (isHTMLFrameSetElement(currentRoot)) | 1355 else if (isHTMLFrameSetElement(currentRoot)) |
| 1356 existingBody = currentRoot; | 1356 existingBody = currentRoot; |
| 1357 } | 1357 } |
| 1358 // We ensure only "the root is <html>." | 1358 // We ensure only "the root is <html>." |
| 1359 // documentElement as rootEditableElement is problematic. So we move | 1359 // documentElement as rootEditableElement is problematic. So we move |
| 1360 // non-<html> root elements under <body>, and the <body> works as | 1360 // non-<html> root elements under <body>, and the <body> works as |
| 1361 // rootEditableElement. | 1361 // rootEditableElement. |
| 1362 document.addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMe
ssageLevel, "document.execCommand() doesn't work with an invalid HTML structure.
It is corrected automatically.")); | 1362 document.addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMe
ssageLevel, "document.execCommand() doesn't work with an invalid HTML structure.
It is corrected automatically.")); |
| 1363 | 1363 |
| 1364 RefPtrWillBeRawPtr<Element> root = HTMLHtmlElement::create(document); | 1364 RawPtr<Element> root = HTMLHtmlElement::create(document); |
| 1365 if (existingHead) | 1365 if (existingHead) |
| 1366 root->appendChild(existingHead.release()); | 1366 root->appendChild(existingHead.release()); |
| 1367 RefPtrWillBeRawPtr<Element> body = nullptr; | 1367 RawPtr<Element> body = nullptr; |
| 1368 if (existingBody) | 1368 if (existingBody) |
| 1369 body = existingBody.release(); | 1369 body = existingBody.release(); |
| 1370 else | 1370 else |
| 1371 body = HTMLBodyElement::create(document); | 1371 body = HTMLBodyElement::create(document); |
| 1372 if (document.documentElement()) | 1372 if (document.documentElement()) |
| 1373 body->appendChild(document.documentElement()); | 1373 body->appendChild(document.documentElement()); |
| 1374 root->appendChild(body.release()); | 1374 root->appendChild(body.release()); |
| 1375 ASSERT(!document.documentElement()); | 1375 ASSERT(!document.documentElement()); |
| 1376 document.appendChild(root.release()); | 1376 document.appendChild(root.release()); |
| 1377 | 1377 |
| 1378 // TODO(tkent): Should we check and move Text node children of <html>? | 1378 // TODO(tkent): Should we check and move Text node children of <html>? |
| 1379 } | 1379 } |
| 1380 | 1380 |
| 1381 DEFINE_TRACE(Editor) | 1381 DEFINE_TRACE(Editor) |
| 1382 { | 1382 { |
| 1383 visitor->trace(m_frame); | 1383 visitor->trace(m_frame); |
| 1384 visitor->trace(m_lastEditCommand); | 1384 visitor->trace(m_lastEditCommand); |
| 1385 visitor->trace(m_mark); | 1385 visitor->trace(m_mark); |
| 1386 } | 1386 } |
| 1387 | 1387 |
| 1388 } // namespace blink | 1388 } // namespace blink |
| OLD | NEW |