示例#1
0
文件: Editor.cpp 项目: krockot/mojo
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;
}
示例#2
0
文件: Editor.cpp 项目: krockot/mojo
void Editor::replaceSelectionWithFragment(PassRefPtr<DocumentFragment> fragment, bool selectReplacement, bool smartReplace, bool matchStyle)
{
    if (m_frame.selection().isNone() || !m_frame.selection().isContentEditable() || !fragment)
        return;

    ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::PreventNesting;
    if (selectReplacement)
        options |= ReplaceSelectionCommand::SelectReplacement;
    if (smartReplace)
        options |= ReplaceSelectionCommand::SmartReplace;
    if (matchStyle)
        options |= ReplaceSelectionCommand::MatchStyle;
    ASSERT(m_frame.document());
    ReplaceSelectionCommand::create(*m_frame.document(), fragment, options, EditActionPaste)->apply();
    revealSelectionAfterEditingOperation();

    if (m_frame.selection().isInPasswordField() || !spellChecker().isContinuousSpellCheckingEnabled())
        return;
    spellChecker().chunkAndMarkAllMisspellingsAndBadGrammar(m_frame.selection().rootEditableElement());
}
示例#3
0
bool Editor::executeCommand(const String& commandName)
{
    // Specially handling commands that Editor::execCommand does not directly
    // support.
    if (commandName == "DeleteToEndOfParagraph") {
        if (!deleteWithDirection(DirectionForward, ParagraphBoundary, false))
            deleteWithDirection(DirectionForward, CharacterGranularity, false);
        return true;
    }
    if (commandName == "DeleteBackward")
        return command(AtomicString("BackwardDelete")).execute();
    if (commandName == "DeleteForward")
        return command(AtomicString("ForwardDelete")).execute();
    if (commandName == "AdvanceToNextMisspelling") {
        // Wee need to pass false here or else the currently selected word will never be skipped.
        spellChecker().advanceToNextMisspelling(false);
        return true;
    }
    if (commandName == "ToggleSpellPanel") {
        spellChecker().showSpellingGuessPanel();
        return true;
    }
    return command(commandName).execute();
}
示例#4
0
bool Editor::executeCommand(const String& commandName, const String& value)
{
    // moveToBeginningOfDocument and moveToEndfDocument are only handled by WebKit for editable nodes.
    if (!canEdit() && commandName == "moveToBeginningOfDocument")
        return m_frame.eventHandler().bubblingScroll(ScrollUp, ScrollByDocument);

    if (!canEdit() && commandName == "moveToEndOfDocument")
        return m_frame.eventHandler().bubblingScroll(ScrollDown, ScrollByDocument);

    if (commandName == "showGuessPanel") {
        spellChecker().showSpellingGuessPanel();
        return true;
    }

    return command(commandName).execute(value);
}
TEST_F(HTMLTextFormControlElementTest, SpellCheckDoesNotCauseUpdateLayout)
{
    HTMLInputElement* input = toHTMLInputElement(document().getElementById("input"));
    input->focus();
    input->setValue("Hello, input field");
    VisibleSelection oldSelection = document().frame()->selection().selection();

    Position newPosition(input->innerEditorElement()->firstChild(), 3);
    VisibleSelection newSelection(newPosition, TextAffinity::Downstream);
    document().frame()->selection().setSelection(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | FrameSelection::DoNotUpdateAppearance);
    ASSERT_EQ(3, input->selectionStart());

    Persistent<SpellChecker> spellChecker(SpellChecker::create(page().frame()));
    forceLayoutFlag();
    int startCount = layoutCount();
    spellChecker->respondToChangedSelection(oldSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle);
    EXPECT_EQ(startCount, layoutCount());
}
示例#6
0
文件: Editor.cpp 项目: krockot/mojo
void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
{
    spellChecker().respondToChangedSelection(oldSelection, options);
    m_frame.inputMethodController().cancelCompositionIfSelectionIsInvalid();
    notifyComponentsOnChangedSelection(oldSelection, options);
}
示例#7
0
文件: Editor.cpp 项目: krockot/mojo
void Editor::respondToChangedContents(const VisibleSelection& endingSelection)
{
    spellChecker().updateMarkersForWordsAffectedByEditing(true);
    client().respondToChangedContents();
}