Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Unified Diff: third_party/WebKit/Source/web/WebInputMethodControllerImpl.cpp

Issue 2333813002: Introduce WebInputMethodController to blink (Closed)
Patch Set: Moved ConfirmCompositionBehavior to WebInputMethodController Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/web/WebInputMethodControllerImpl.cpp
diff --git a/third_party/WebKit/Source/web/WebInputMethodControllerImpl.cpp b/third_party/WebKit/Source/web/WebInputMethodControllerImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..550afb969c3204aaa5dc3a8c8bcc6d18234de2e8
--- /dev/null
+++ b/third_party/WebKit/Source/web/WebInputMethodControllerImpl.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2016 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "web/WebInputMethodControllerImpl.h"
+
+#include "core/InputTypeNames.h"
+#include "core/editing/EditingUtilities.h"
+#include "core/editing/Editor.h"
+#include "core/editing/EphemeralRange.h"
+#include "core/editing/FrameSelection.h"
+#include "core/editing/InputMethodController.h"
+#include "core/editing/PlainTextRange.h"
+#include "core/frame/LocalFrame.h"
+#include "core/page/FocusController.h"
+#include "core/page/Page.h"
+#include "platform/UserGestureIndicator.h"
+#include "public/platform/WebString.h"
+#include "public/web/WebPlugin.h"
+#include "public/web/WebRange.h"
+#include "web/CompositionUnderlineVectorBuilder.h"
+#include "web/WebLocalFrameImpl.h"
+#include "web/WebPluginContainerImpl.h"
+
+namespace blink {
+
+WebInputMethodControllerImpl::WebInputMethodControllerImpl(WebLocalFrameImpl* webLocalFrame)
+ : m_webLocalFrame(webLocalFrame)
+ , m_suppressNextKeypressEvent(false)
+{
+}
+
+WebInputMethodControllerImpl::~WebInputMethodControllerImpl()
+{
+}
+
+// static
+WebInputMethodControllerImpl* WebInputMethodControllerImpl::fromFrame(LocalFrame* frame)
+{
+ WebLocalFrameImpl* webLocalFrameImpl = WebLocalFrameImpl::fromFrame(frame);
+ return webLocalFrameImpl ? webLocalFrameImpl->inputMethodController() : nullptr;
+}
+
+DEFINE_TRACE(WebInputMethodControllerImpl)
+{
+ visitor->trace(m_webLocalFrame);
+}
+
+bool WebInputMethodControllerImpl::setComposition(
+ const WebString& text,
+ const WebVector<WebCompositionUnderline>& underlines,
+ int selectionStart,
+ int selectionEnd)
+{
+ if (WebPlugin* plugin = focusedPluginIfInputMethodSupported())
+ return plugin->setComposition(text, underlines, selectionStart, selectionEnd);
+
+ // We should use this |editor| object only to complete the ongoing
+ // composition.
+ if (!frame()->editor().canEdit() && !inputMethodController().hasComposition())
+ return false;
+
+ // We should verify the parent node of this IME composition node are
+ // editable because JavaScript may delete a parent node of the composition
+ // node. In this case, WebKit crashes while deleting texts from the parent
+ // node, which doesn't exist any longer.
+ const EphemeralRange range = inputMethodController().compositionEphemeralRange();
+ if (range.isNotNull()) {
+ Node* node = range.startPosition().computeContainerNode();
+ frame()->document()->updateStyleAndLayoutTree();
+ if (!node || !hasEditableStyle(*node))
+ return false;
+ }
+
+ // A keypress event is canceled. If an ongoing composition exists, then the
+ // keydown event should have arisen from a handled key (e.g., backspace).
+ // In this case we ignore the cancellation and continue; otherwise (no
+ // ongoing composition) we exit and signal success only for attempts to
+ // clear the composition.
+ if (m_suppressNextKeypressEvent && !inputMethodController().hasComposition())
+ return text.isEmpty();
+
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
+
+ // When the range of composition underlines overlap with the range between
+ // selectionStart and selectionEnd, WebKit somehow won't paint the selection
+ // at all (see InlineTextBox::paint() function in InlineTextBox.cpp).
+ // But the selection range actually takes effect.
+ inputMethodController().setComposition(String(text),
+ CompositionUnderlineVectorBuilder(underlines),
+ selectionStart, selectionEnd);
+
+ return text.isEmpty() || inputMethodController().hasComposition();
+}
+
+bool WebInputMethodControllerImpl::finishComposingText(ConfirmCompositionBehavior selectionBehavior)
+{
+ // TODO(ekaramad): Here and in other IME calls we should expect the
+ // call to be made when our frame is focused. This, however, is not the case
+ // all the time. For instance, resetInputMethod call on RenderViewImpl could
+ // be after losing the focus on frame. But since we return the core frame
+ // in WebViewImpl::focusedLocalFrameInWidget(), we will reach here with
+ // |m_webLocalFrame| not focused on page.
+
+ if (WebPlugin* plugin = focusedPluginIfInputMethodSupported())
+ return plugin->finishComposingText(selectionBehavior);
+ return inputMethodController().finishComposingText(selectionBehavior == WebInputMethodController::KeepSelection ? InputMethodController::KeepSelection : InputMethodController::DoNotKeepSelection);
+}
+
+bool WebInputMethodControllerImpl::commitText(const WebString& text, int relativeCaretPosition)
+{
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
+
+ if (WebPlugin* plugin = focusedPluginIfInputMethodSupported())
+ return plugin->commitText(text, relativeCaretPosition);
+
+ // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
+ // needs to be audited. See http://crbug.com/590369 for more details.
+ frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets();
+
+ return inputMethodController().commitText(text, relativeCaretPosition);
+}
+
+LocalFrame* WebInputMethodControllerImpl::frame() const
+{
+ return m_webLocalFrame->frame();
+}
+
+InputMethodController& WebInputMethodControllerImpl::inputMethodController() const
+{
+ return frame()->inputMethodController();
+}
+
+WebPlugin* WebInputMethodControllerImpl::focusedPluginIfInputMethodSupported() const
+{
+ WebPluginContainerImpl* container = WebLocalFrameImpl::currentPluginContainer(frame());
+ if (container && container->supportsInputMethod())
+ return container->plugin();
+ return nullptr;
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698