summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/editor_client_impl.cc30
-rw-r--r--webkit/glue/editor_client_impl.h19
-rw-r--r--webkit/glue/webview_impl.cc26
-rw-r--r--webkit/glue/webview_impl.h3
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_;