Ejemplo n.º 1
0
bool InputMethodController::finishComposition(const String& text, FinishCompositionMode mode)
{
    if (!hasComposition())
        return false;

    ASSERT(mode == ConfirmComposition || mode == CancelComposition);

    Editor::RevealSelectionScope revealSelectionScope(&editor());

    if (mode == CancelComposition)
        ASSERT(text == emptyString());
    else
        selectComposition();

    if (m_frame.selection().isNone())
        return false;

    // Dispatch a compositionend event to the focused node.
    // We should send this event before sending a TextEvent as written in Section 6.2.2 and 6.2.3 of
    // the DOM Event specification.
    if (Element* target = m_frame.document()->focusedElement()) {
        unsigned baseOffset = m_frame.selection().base().downstream().deprecatedEditingOffset();
        Vector<CompositionUnderline> underlines;
        for (size_t i = 0; i < m_customCompositionUnderlines.size(); ++i) {
            CompositionUnderline underline = m_customCompositionUnderlines[i];
            underline.startOffset -= baseOffset;
            underline.endOffset -= baseOffset;
            underlines.append(underline);
        }
        RefPtrWillBeRawPtr<CompositionEvent> event = CompositionEvent::create(EventTypeNames::compositionend, m_frame.domWindow(), text, underlines);
        target->dispatchEvent(event, IGNORE_EXCEPTION);
    }

    // If text is empty, then delete the old composition here. If text is non-empty, InsertTextCommand::input
    // will delete the old composition with an optimized replace operation.
    if (text.isEmpty() && mode != CancelComposition) {
        ASSERT(m_frame.document());
        TypingCommand::deleteSelection(*m_frame.document(), 0);
    }

    m_compositionNode = nullptr;
    m_customCompositionUnderlines.clear();

    insertTextForConfirmedComposition(text);

    if (mode == CancelComposition) {
        // An open typing command that disagrees about current selection would cause issues with typing later on.
        TypingCommand::closeTyping(&m_frame);
    }

    return true;
}
bool InputMethodController::finishComposition(const String& text, FinishCompositionMode mode)
{
    if (!hasComposition())
        return false;

    ASSERT(mode == ConfirmComposition || mode == CancelComposition);

    Editor::RevealSelectionScope revealSelectionScope(&editor());

    bool dirty = m_isDirty || plainText(compositionEphemeralRange()) != text;

    if (mode == CancelComposition) {
        ASSERT(text == emptyString());
    } else if (dirty) {
        selectComposition();
    }

    if (frame().selection().isNone())
        return false;

    // Dispatch a compositionend event to the focused node.
    // We should send this event before sending a TextEvent as written in Section 6.2.2 and 6.2.3 of
    // the DOM Event specification.
    if (Element* target = frame().document()->focusedElement()) {
        RefPtrWillBeRawPtr<CompositionEvent> event = CompositionEvent::create(EventTypeNames::compositionend, frame().domWindow(), text);
        target->dispatchEvent(event);
    }

    // If text is empty, then delete the old composition here. If text is non-empty, InsertTextCommand::input
    // will delete the old composition with an optimized replace operation.
    if (text.isEmpty() && mode != CancelComposition && dirty) {
        ASSERT(frame().document());
        TypingCommand::deleteSelection(*frame().document(), 0);
    }

    clear();

    if (dirty)
        insertTextForConfirmedComposition(text);

    if (mode == CancelComposition) {
        // An open typing command that disagrees about current selection would cause issues with typing later on.
        TypingCommand::closeTyping(m_frame);
    }

    return true;
}
Ejemplo n.º 3
0
void InputMethodController::cancelComposition()
{
    if (!hasComposition())
        return;

    Editor::RevealSelectionScope revealSelectionScope(&editor());

    if (frame().selection().isNone())
        return;

    dispatchCompositionEndEvent(frame(), emptyString());
    clear();
    insertTextForConfirmedComposition(emptyString());

    // An open typing command that disagrees about current selection would cause
    // issues with typing later on.
    TypingCommand::closeTyping(m_frame);
}
void InputMethodController::finishComposition(const String& text, FinishCompositionMode mode)
{
    ASSERT(mode == ConfirmComposition || mode == CancelComposition);
    UserTypingGestureIndicator typingGestureIndicator(m_frame);

    Editor::RevealSelectionScope revealSelectionScope(&editor());

    if (mode == CancelComposition)
        ASSERT(text == emptyString());
    else
        selectComposition();

    if (m_frame->selection().isNone())
        return;

    // Dispatch a compositionend event to the focused node.
    // We should send this event before sending a TextEvent as written in Section 6.2.2 and 6.2.3 of
    // the DOM Event specification.
    if (Element* target = m_frame->document()->focusedElement()) {
        RefPtr<CompositionEvent> event = CompositionEvent::create(eventNames().compositionendEvent, m_frame->domWindow(), text);
        target->dispatchEvent(event, IGNORE_EXCEPTION);
    }

    // If text is empty, then delete the old composition here. If text is non-empty, InsertTextCommand::input
    // will delete the old composition with an optimized replace operation.
    if (text.isEmpty() && mode != CancelComposition) {
        ASSERT(m_frame->document());
        TypingCommand::deleteSelection(*m_frame->document(), 0);
    }

    m_compositionNode = 0;
    m_customCompositionUnderlines.clear();

    insertTextForConfirmedComposition(text);

    if (mode == CancelComposition) {
        // An open typing command that disagrees about current selection would cause issues with typing later on.
        TypingCommand::closeTyping(m_frame);
    }
}
bool InputMethodController::confirmComposition(const String& text, ConfirmCompositionBehavior confirmBehavior)
{
    if (!hasComposition())
        return false;

    Optional<Editor::RevealSelectionScope> revealSelectionScope;
    if (confirmBehavior == KeepSelection)
        revealSelectionScope.emplace(&editor());

    // If the composition was set from existing text and didn't change, then
    // there's nothing to do here (and we should avoid doing anything as that
    // may clobber multi-node styled text).
    if (!m_isDirty && composingText() == text) {
        clear();
        return true;
    }

    // Select the text that will be deleted or replaced.
    selectComposition();

    if (frame().selection().isNone())
        return false;

    dispatchCompositionEndEvent(frame(), text);

    if (!frame().document())
        return false;

    // If text is empty, then delete the old composition here. If text is
    // non-empty, InsertTextCommand::input will delete the old composition with
    // an optimized replace operation.
    if (text.isEmpty())
        TypingCommand::deleteSelection(*frame().document(), 0);

    clear();

    insertTextForConfirmedComposition(text);

    return true;
}