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

Unified Diff: third_party/WebKit/Source/core/editing/InputMethodController.cpp

Issue 2417643002: Move text input mode/info/type into InputMethodController (Closed)
Patch Set: Fix nits Created 4 years, 2 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/core/editing/InputMethodController.cpp
diff --git a/third_party/WebKit/Source/core/editing/InputMethodController.cpp b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
index 0854ba23ba8aaf8dcf222e56bd2b189e959a9d47..3681b8a9ffae6dd4813029d118f21824d72bd981 100644
--- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp
+++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
@@ -26,6 +26,7 @@
#include "core/editing/InputMethodController.h"
+#include "core/InputTypeNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/Text.h"
@@ -35,6 +36,7 @@
#include "core/editing/markers/DocumentMarkerController.h"
#include "core/events/CompositionEvent.h"
#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLTextAreaElement.h"
#include "core/input/EventHandler.h"
#include "core/layout/LayoutObject.h"
@@ -931,6 +933,203 @@ void InputMethodController::deleteSurroundingText(int before, int after) {
setSelectionOffsets(PlainTextRange(selectionStart, selectionEnd));
}
+WebTextInputInfo InputMethodController::textInputInfo() const {
+ WebTextInputInfo info;
+ if (!frame().document())
+ return info;
+
+ if (!frame().selection().isAvailable()) {
+ // plugins/mouse-capture-inside-shadow.html reaches here.
+ return info;
+ }
+ Element* element = frame().selection().rootEditableElement();
+ if (!element)
+ return info;
+
+ info.inputMode = inputModeOfFocusedElement();
+ info.type = textInputType();
+ info.flags = textInputFlags();
+ if (info.type == WebTextInputTypeNone)
+ return info;
+
+ if (!frame().editor().canEdit())
+ return info;
+
+ // TODO(dglazkov): The use of updateStyleAndLayoutIgnorePendingStylesheets
+ // needs to be audited. see http://crbug.com/590369 for more details.
+ frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
+
+ DocumentLifecycle::DisallowTransitionScope disallowTransition(
+ frame().document()->lifecycle());
+
+ // Emits an object replacement character for each replaced element so that
+ // it is exposed to IME and thus could be deleted by IME on android.
+ info.value = plainText(EphemeralRange::rangeOfContents(*element),
+ TextIteratorEmitsObjectReplacementCharacter);
+
+ if (info.value.isEmpty())
+ return info;
+
+ EphemeralRange firstRange =
+ firstEphemeralRangeOf(frame().selection().selection());
+ if (firstRange.isNotNull()) {
+ PlainTextRange plainTextRange(PlainTextRange::create(*element, firstRange));
+ if (plainTextRange.isNotNull()) {
+ info.selectionStart = plainTextRange.start();
+ info.selectionEnd = plainTextRange.end();
+ }
+ }
+
+ EphemeralRange range = compositionEphemeralRange();
+ if (range.isNotNull()) {
+ PlainTextRange plainTextRange(PlainTextRange::create(*element, range));
+ if (plainTextRange.isNotNull()) {
+ info.compositionStart = plainTextRange.start();
+ info.compositionEnd = plainTextRange.end();
+ }
+ }
+
+ return info;
+}
+
+int InputMethodController::textInputFlags() const {
+ Element* element = frame().document()->focusedElement();
+ if (!element)
+ return WebTextInputFlagNone;
+
+ int flags = 0;
+
+ const AtomicString& autocomplete =
+ element->getAttribute(HTMLNames::autocompleteAttr);
+ if (autocomplete == "on")
+ flags |= WebTextInputFlagAutocompleteOn;
+ else if (autocomplete == "off")
+ flags |= WebTextInputFlagAutocompleteOff;
+
+ const AtomicString& autocorrect =
+ element->getAttribute(HTMLNames::autocorrectAttr);
+ if (autocorrect == "on")
+ flags |= WebTextInputFlagAutocorrectOn;
+ else if (autocorrect == "off")
+ flags |= WebTextInputFlagAutocorrectOff;
+
+ SpellcheckAttributeState spellcheck = element->spellcheckAttributeState();
+ if (spellcheck == SpellcheckAttributeTrue)
+ flags |= WebTextInputFlagSpellcheckOn;
+ else if (spellcheck == SpellcheckAttributeFalse)
+ flags |= WebTextInputFlagSpellcheckOff;
+
+ if (isHTMLTextFormControlElement(element)) {
+ HTMLTextFormControlElement* formElement =
+ static_cast<HTMLTextFormControlElement*>(element);
+ if (formElement->supportsAutocapitalize()) {
+ DEFINE_STATIC_LOCAL(const AtomicString, none, ("none"));
+ DEFINE_STATIC_LOCAL(const AtomicString, characters, ("characters"));
+ DEFINE_STATIC_LOCAL(const AtomicString, words, ("words"));
+ DEFINE_STATIC_LOCAL(const AtomicString, sentences, ("sentences"));
+
+ const AtomicString& autocapitalize = formElement->autocapitalize();
+ if (autocapitalize == none)
+ flags |= WebTextInputFlagAutocapitalizeNone;
+ else if (autocapitalize == characters)
+ flags |= WebTextInputFlagAutocapitalizeCharacters;
+ else if (autocapitalize == words)
+ flags |= WebTextInputFlagAutocapitalizeWords;
+ else if (autocapitalize == sentences)
+ flags |= WebTextInputFlagAutocapitalizeSentences;
+ else
+ NOTREACHED();
+ }
+ }
+
+ return flags;
+}
+
+String InputMethodController::inputModeOfFocusedElement() const {
+ if (!RuntimeEnabledFeatures::inputModeAttributeEnabled())
+ return String();
+
+ Element* element = frame().document()->focusedElement();
+ if (!element)
+ return String();
+
+ if (isHTMLInputElement(*element)) {
+ const HTMLInputElement& input = toHTMLInputElement(*element);
+ if (input.supportsInputModeAttribute())
+ return input.fastGetAttribute(HTMLNames::inputmodeAttr).lower();
+ return String();
+ }
+ if (isHTMLTextAreaElement(*element)) {
+ const HTMLTextAreaElement& textarea = toHTMLTextAreaElement(*element);
+ return textarea.fastGetAttribute(HTMLNames::inputmodeAttr).lower();
+ }
+
+ return String();
+}
+
+WebTextInputType InputMethodController::textInputType() const {
+ if (!frame().selection().isAvailable()) {
+ // "mouse-capture-inside-shadow.html" reaches here.
+ return WebTextInputTypeNone;
+ }
+
+ // It's important to preserve the equivalence of textInputInfo().type and
+ // textInputType(), so perform the same rootEditableElement() existence check
+ // here for consistency.
+ if (!frame().selection().selection().rootEditableElement())
+ return WebTextInputTypeNone;
+
+ Document* document = frame().document();
+ if (!document)
+ return WebTextInputTypeNone;
+
+ Element* element = document->focusedElement();
+ if (!element)
+ return WebTextInputTypeNone;
+
+ if (isHTMLInputElement(*element)) {
+ HTMLInputElement& input = toHTMLInputElement(*element);
+ const AtomicString& type = input.type();
+
+ if (input.isDisabledOrReadOnly())
+ return WebTextInputTypeNone;
+
+ if (type == InputTypeNames::password)
+ return WebTextInputTypePassword;
+ if (type == InputTypeNames::search)
+ return WebTextInputTypeSearch;
+ if (type == InputTypeNames::email)
+ return WebTextInputTypeEmail;
+ if (type == InputTypeNames::number)
+ return WebTextInputTypeNumber;
+ if (type == InputTypeNames::tel)
+ return WebTextInputTypeTelephone;
+ if (type == InputTypeNames::url)
+ return WebTextInputTypeURL;
+ if (type == InputTypeNames::text)
+ return WebTextInputTypeText;
+
+ return WebTextInputTypeNone;
+ }
+
+ if (isHTMLTextAreaElement(*element)) {
+ if (toHTMLTextAreaElement(*element).isDisabledOrReadOnly())
+ return WebTextInputTypeNone;
+ return WebTextInputTypeTextArea;
+ }
+
+ if (element->isHTMLElement()) {
+ if (toHTMLElement(element)->isDateTimeFieldElement())
+ return WebTextInputTypeDateTimeField;
+ }
+
+ document->updateStyleAndLayoutTree();
+ if (hasEditableStyle(*element))
+ return WebTextInputTypeContentEditable;
+
+ return WebTextInputTypeNone;
+}
+
DEFINE_TRACE(InputMethodController) {
visitor->trace(m_frame);
visitor->trace(m_compositionRange);

Powered by Google App Engine
This is Rietveld 408576698