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 c64c0dc3716cc6c401fb5c2ca4eb8f8214422b33..a4783a0ad07de2a673b857963e54467c1ddf3998 100644 |
--- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
+++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp |
@@ -30,6 +30,7 @@ |
#include "core/InputTypeNames.h" |
#include "core/dom/Document.h" |
#include "core/dom/Element.h" |
+#include "core/dom/ElementTraversal.h" |
#include "core/dom/Text.h" |
#include "core/editing/EditingUtilities.h" |
#include "core/editing/Editor.h" |
@@ -39,12 +40,15 @@ |
#include "core/editing/state_machines/ForwardCodePointStateMachine.h" |
#include "core/events/CompositionEvent.h" |
#include "core/frame/LocalFrame.h" |
+#include "core/html/HTMLFormElement.h" |
#include "core/html/HTMLInputElement.h" |
#include "core/html/HTMLTextAreaElement.h" |
#include "core/input/EventHandler.h" |
#include "core/layout/LayoutObject.h" |
#include "core/layout/LayoutTheme.h" |
#include "core/page/ChromeClient.h" |
+#include "core/page/FocusController.h" |
+#include "core/page/Page.h" |
namespace blink { |
@@ -1109,9 +1113,75 @@ int InputMethodController::textInputFlags() const { |
} |
} |
+ if (isListeningToKeyboardEvents(element)) |
+ flags |= WebTextInputFlagListeningToKeyboardEvents; |
+ |
+ if (nextFocusableElementInForm(element, WebFocusTypeForward)) |
+ flags |= WebTextInputFlagHaveNextFocusableElement; |
+ |
+ if (nextFocusableElementInForm(element, WebFocusTypeBackward)) |
+ flags |= WebTextInputFlagHavePreviousFocusableElement; |
+ |
return flags; |
} |
+bool InputMethodController::isListeningToKeyboardEvents( |
+ Element* element) const { |
+ if (!element->isFormControlElement() && |
+ !toHTMLElement(element)->isContentEditableForBinding()) |
+ return false; |
+ for (Node* node = element; node; node = node->parentNode()) { |
+ if (node->hasEventListeners(EventTypeNames::keydown) || |
+ node->hasEventListeners(EventTypeNames::keypress) || |
+ node->hasEventListeners(EventTypeNames::keyup)) |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+Element* InputMethodController::nextFocusableElementInForm( |
+ Element* element, |
+ WebFocusType focusType) const { |
+ if (!element->isFormControlElement() && |
+ !toHTMLElement(element)->isContentEditableForBinding()) |
+ return nullptr; |
+ |
+ HTMLFormElement* formOwner = nullptr; |
+ if (toHTMLElement(element)->isContentEditableForBinding()) |
+ formOwner = Traversal<HTMLFormElement>::firstAncestor(*element); |
+ else |
+ formOwner = toHTMLFormControlElement(element)->formOwner(); |
+ |
+ if (!formOwner) |
+ return nullptr; |
+ |
+ Element* nextElement = element; |
+ for (nextElement = document().page()->focusController().findFocusableElement( |
+ focusType, *nextElement); |
+ nextElement; |
+ nextElement = document().page()->focusController().findFocusableElement( |
+ focusType, *nextElement)) { |
+ if (toHTMLElement(nextElement)->isContentEditableForBinding() && |
+ nextElement->isDescendantOf(formOwner)) |
+ return nextElement; |
+ if (!nextElement->isFormControlElement()) |
+ continue; |
+ HTMLFormControlElement* formElement = toHTMLFormControlElement(nextElement); |
+ if (formElement->formOwner() != formOwner) |
+ continue; |
+ // Skip disabled or readonly editable elements. |
+ if (formElement->isDisabledOrReadOnly()) |
+ continue; |
+ LayoutObject* layout = nextElement->layoutObject(); |
+ if (layout && layout->isTextControl()) { |
+ // TODO(ajith.v) Extend it for Select element, Radio button and Check |
+ // boxes |
+ return nextElement; |
+ } |
+ } |
+ return nullptr; |
+} |
+ |
WebTextInputMode InputMethodController::inputModeOfFocusedElement() const { |
if (!RuntimeEnabledFeatures::inputModeAttributeEnabled()) |
return kWebTextInputModeDefault; |