bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectInsertedText, TextEvent* triggeringEvent) { if (text.isEmpty()) return false; VisibleSelection selection = selectionForCommand(triggeringEvent); if (!selection.isContentEditable()) return false; spellChecker().updateMarkersForWordsAffectedByEditing(isSpaceOrNewline(text[0])); // Get the selection to use for the event that triggered this insertText. // If the event handler changed the selection, we may want to use a different selection // that is contained in the event target. selection = selectionForCommand(triggeringEvent); if (selection.isContentEditable()) { if (Node* selectionStart = selection.start().deprecatedNode()) { RefPtr<Document> document(selectionStart->document()); // Insert the text TypingCommand::Options options = 0; if (selectInsertedText) options |= TypingCommand::SelectInsertedText; TypingCommand::insertText(*document.get(), text, selection, options, triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompositionConfirm : TypingCommand::TextCompositionNone); // Reveal the current selection if (LocalFrame* editedFrame = document->frame()) { if (Page* page = editedFrame->page()) page->focusController().focusedOrMainFrame()->selection().revealSelection(ScrollAlignment::alignCenterIfNeeded); } } } return true; }
void SpellChecker::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options) { bool closeTyping = options & FrameSelection::CloseTyping; bool isContinuousSpellCheckingEnabled = this->isContinuousSpellCheckingEnabled(); bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && isGrammarCheckingEnabled(); if (isContinuousSpellCheckingEnabled) { VisibleSelection newAdjacentWords; VisibleSelection newSelectedSentence; const VisibleSelection newSelection = m_frame.selection().selection(); VisiblePosition newStart(newSelection.visibleStart()); newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary)); if (isContinuousGrammarCheckingEnabled) newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart)); // Don't check spelling and grammar if the change of selection is triggered by spelling correction itself. bool shouldCheckSpellingAndGrammar = !(options & FrameSelection::SpellCorrectionTriggered); // When typing we check spelling elsewhere, so don't redo it here. // If this is a change in selection resulting from a delete operation, // oldSelection may no longer be in the document. // FIXME(http://crbug.com/382809): if oldSelection is on a textarea // element, we cause synchronous layout. if (shouldCheckSpellingAndGrammar && closeTyping && !isSelectionInTextField(oldSelection) && (isSelectionInTextArea(oldSelection) || oldSelection.isContentEditable()) && oldSelection.start().inDocument()) { spellCheckOldSelection(oldSelection, newAdjacentWords); } // FIXME(http://crbug.com/382809): // shouldEraseMarkersAfterChangeSelection is true, we cause synchronous // layout. if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)) { if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange()) m_frame.document()->markers().removeMarkers(wordRange.get(), DocumentMarker::Spelling); } if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeGrammar)) { if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange()) m_frame.document()->markers().removeMarkers(sentenceRange.get(), DocumentMarker::Grammar); } } // When continuous spell checking is off, existing markers disappear after the selection changes. if (!isContinuousSpellCheckingEnabled) m_frame.document()->markers().removeMarkers(DocumentMarker::Spelling); if (!isContinuousGrammarCheckingEnabled) m_frame.document()->markers().removeMarkers(DocumentMarker::Grammar); }