diff options
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/glue/editor_client_impl.cc | 30 | ||||
-rw-r--r-- | webkit/glue/editor_client_impl.h | 19 | ||||
-rw-r--r-- | webkit/glue/webview_impl.cc | 26 | ||||
-rw-r--r-- | webkit/glue/webview_impl.h | 3 |
4 files changed, 73 insertions, 5 deletions
diff --git a/webkit/glue/editor_client_impl.cc b/webkit/glue/editor_client_impl.cc index 4daa74d..3d4e96f 100644 --- a/webkit/glue/editor_client_impl.cc +++ b/webkit/glue/editor_client_impl.cc @@ -575,7 +575,7 @@ const char* EditorClientImpl::interpretKeyEvent( } bool EditorClientImpl::handleEditingKeyboardEvent( - WebCore::KeyboardEvent* evt) { + WebCore::KeyboardEvent* evt) { const WebCore::PlatformKeyboardEvent* keyEvent = evt->keyEvent(); // do not treat this as text input if it's a system key event if (!keyEvent || keyEvent->isSystemKey()) @@ -627,6 +627,12 @@ bool EditorClientImpl::handleEditingKeyboardEvent( // void EditorClientImpl::handleKeyboardEvent(WebCore::KeyboardEvent* evt) { + if (evt->keyCode() == WebCore::VKEY_DOWN || + evt->keyCode() == WebCore::VKEY_UP) { + DCHECK(evt->target()->toNode()); + ShowAutofillForNode(evt->target()->toNode()); + } + if (handleEditingKeyboardEvent(evt)) evt->setDefaultHandled(); } @@ -651,13 +657,27 @@ void EditorClientImpl::textFieldDidEndEditing(WebCore::Element*) { void EditorClientImpl::textDidChangeInTextField(WebCore::Element* element) { DCHECK(element->hasLocalName(WebCore::HTMLNames::inputTag)); + Autofill(static_cast<WebCore::HTMLInputElement*>(element), false); +} + +void EditorClientImpl::ShowAutofillForNode(WebCore::Node* node) { + if (node->nodeType() == WebCore::Node::ELEMENT_NODE) { + WebCore::Element* element = static_cast<WebCore::Element*>(node); + if (element->hasLocalName(WebCore::HTMLNames::inputTag)) { + WebCore::HTMLInputElement* input_element = + static_cast<WebCore::HTMLInputElement*>(element); + if (input_element->value().isEmpty()) + Autofill(input_element, true); + } + } +} +void EditorClientImpl::Autofill(WebCore::HTMLInputElement* input_element, + bool autofill_on_empty_value) { // Cancel any pending DoAutofill calls. autofill_factory_.RevokeAll(); // Let's try to trigger autofill for that field, if applicable. - WebCore::HTMLInputElement* input_element = - static_cast<WebCore::HTMLInputElement*>(element); if (!input_element->isEnabled() || !input_element->isTextField() || input_element->isPasswordField() || !input_element->autoComplete()) { return; @@ -679,10 +699,12 @@ void EditorClientImpl::textDidChangeInTextField(WebCore::Element* element) { FROM_HERE, autofill_factory_.NewRunnableMethod(&EditorClientImpl::DoAutofill, input_element, + autofill_on_empty_value, backspace_pressed_)); } void EditorClientImpl::DoAutofill(WebCore::HTMLInputElement* input_element, + bool autofill_on_empty_value, bool backspace) { std::wstring value = webkit_glue::StringToStdWString(input_element->value()); @@ -690,7 +712,7 @@ void EditorClientImpl::DoAutofill(WebCore::HTMLInputElement* input_element, bool caret_at_end = input_element->selectionStart() == input_element->selectionEnd() && input_element->selectionEnd() == static_cast<int>(value.length()); - if (value.empty() || !caret_at_end) { + if ((!autofill_on_empty_value && value.empty()) || !caret_at_end) { web_view_->HideAutoCompletePopup(); return; } diff --git a/webkit/glue/editor_client_impl.h b/webkit/glue/editor_client_impl.h index 3870923..daef0fb 100644 --- a/webkit/glue/editor_client_impl.h +++ b/webkit/glue/editor_client_impl.h @@ -119,11 +119,28 @@ class EditorClientImpl : public WebCore::EditorClient { virtual std::wstring Describe(WebCore::EAffinity affinity); virtual std::wstring Describe(WebCore::CSSStyleDeclaration* style); + // Shows the autofill popup for |node| if it is an HTMLInputElement and it is + // empty. This is called when you press the up or down arrow in a text field + // or when clicking an already focused text-field. + virtual void ShowAutofillForNode(WebCore::Node* node); + private: void ModifySelection(WebCore::Frame* frame, WebCore::KeyboardEvent* event); - void DoAutofill(WebCore::HTMLInputElement* input_element, bool backspace); + // Popups an autofill menu for |input_element| is applicable. + // |autofill_on_empty_value| indicates whether the autofill should be shown + // when the text-field is empty. + void Autofill(WebCore::HTMLInputElement* input_element, + bool autofill_on_empty_value); + + // This method is invoked later by Autofill() as when Autofill() is invoked + // (from one of the EditorClient callback) the carret position is not + // reflecting the last text change yet and we need it to decide whether or not + // to show the autofill popup. + void DoAutofill(WebCore::HTMLInputElement* input_element, + bool autofill_on_empty_value, + bool backspace); protected: WebViewImpl* web_view_; diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc index d4d19fb..8a1aee6 100644 --- a/webkit/glue/webview_impl.cc +++ b/webkit/glue/webview_impl.cc @@ -364,8 +364,22 @@ void WebViewImpl::MouseDown(const WebMouseEvent& event) { return; last_mouse_down_point_ = gfx::Point(event.x, event.y); + // We need to remember who has focus, as if the user left-clicks an already + // focused text-field, we may want to show the auto-fill popup. + RefPtr<Node> focused_node; + if (event.button == WebMouseEvent::BUTTON_LEFT) + focused_node = GetFocusedNode(); + main_frame()->frame()->eventHandler()->handleMousePressEvent( MakePlatformMouseEvent(main_frame()->frameview(), event)); + + if (focused_node.get() && focused_node == GetFocusedNode()) { + // Already focused node was clicked, ShowAutofillForNode will determine + // whether to show the autofill (typically, if the node is a text-field and + // is empty). + static_cast<EditorClientImpl*>(page_->editorClient())-> + ShowAutofillForNode(focused_node.get()); + } } void WebViewImpl::MouseContextMenu(const WebMouseEvent& event) { @@ -1617,3 +1631,15 @@ void WebViewImpl::HideAutoCompletePopup() { autocomplete_popup_client_.clear(); } } + +Node* WebViewImpl::GetFocusedNode() { + Frame* frame = page_->focusController()->focusedFrame(); + if (!frame) + return NULL; + + Document* document = frame->document(); + if (!document) + return NULL; + + return document->focusedNode(); +} diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h index 5c0a554..1f03477 100644 --- a/webkit/glue/webview_impl.h +++ b/webkit/glue/webview_impl.h @@ -255,6 +255,9 @@ class WebViewImpl : public WebView { // This is invoked after the download is completed (or fails). void DeleteImageResourceFetcher(ImageResourceFetcher* fetcher); + // Returns the currently focused Node or NULL if no node has focus. + WebCore::Node* GetFocusedNode(); + // ImageResourceFetchers schedule via DownloadImage. std::set<ImageResourceFetcher*> image_fetchers_; |