Implement HTMLFormElement#requestAutocomplete and associated events
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Nov 2012 16:08:40 +0000 (16:08 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Nov 2012 16:08:40 +0000 (16:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=100557

Patch by Dan Beam <dbeam@chromium.org> on 2012-11-03
Reviewed by Adam Barth.

Source/WebCore:

Implements an initial version of the proposal for interactive autocomplete outlined in this email:
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html

The goal of this patch is to allow web authors to call formElement.requestAutocomplete(); after subscribing for
autocomplete/autocompleteerror events on formElement. If the form's [autocomplete] attribute is "off" an
error will be dispatched. Otherwise, a request will be issued to the FrameLoaderClient.  At the moment, the
implementation in Chrome (https://codereview.chromium.org/11270018/) will simply dispatch an error until the
UI on Chrome's side is built. Both autocomplete and autocompleteerror events will be dispatched asynchronously
after a small delay to behave consistently in all situations and implementations.

Currently this is behind the feature flag REQUEST_AUTOCOMPLETE, which is disabled.

Test: fast/forms/form-request-autocomplete.html

* dom/EventNames.h:
(WebCore):

Added autocomplete and autocompleteerror events. The autocomplete event is dispatched after a user adds more
information to a form using the future UI. This is not currently dispatched in any implementation (including Chrome)
but will be in the future. The autocompleteerror event is dispatched when the form has [autocomplete="off"] on the
node being asked for an interactive autocomplete. The user agent may also dispatch this event if it doesn't implement
this API but has turned on the feature flag, can't currently show an autocomplete UI (e.g. running headlessly or in
an HTML notification, security concerns, or any other reason it desires).

* html/HTMLAttributeNames.in:

Added onautocomplete and onautocompleteerror attributes so they can be parsed when creating form elements and used
as event listeners. For example:

  <form onautocomplete="/* when autocomplete succeeds */" autocompleteerror="/* when autocomplete fails */">

* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::HTMLFormElement):
(WebCore):

Added m_requestAutocompleteTimer (a timer that's used to dispatch events asynchronously) to the initializer list that
triggers requestAutocompleteTimerFired when it times out.

(WebCore::HTMLFormElement::requestAutocomplete):

Called when HTMLFormElement#requestAutocomplete is called from JS (also see HTMLFormElement.idl) and decides whether
to dispatch an error and exit early (in the case where autocomplete="off") or pass the request on to the
FrameLoaderClient.

(WebCore::HTMLFormElement::finishRequestAutocomplete):

Called when the request for an interactive autocomplete is finished with either a success or error result. This
causes an event to queue and fired after a 0 second delay. Events are owned by HTMLFormElement and reference the
target element (this) until fired.

(WebCore::HTMLFormElement::requestAutocompleteTimerFired):

Called when the event timer runs out to pump the queue of current events. Events are released on dispatch.

(WebCore::HTMLFormElement::parseAttribute):

Encountering onautocomplete or onautocompleteerror attributes while parsing HTMLFormElements now adds event listeners
for autocomplete an autocompleteerror events (respectively) to dispatch the value of the attribute as a script.

* html/HTMLFormElement.h:
(HTMLFormElement):

Added various methods and data members as required by the implementation.

* html/HTMLFormElement.idl:

Added the method requestAutocomplete and associated DOM event handler attributes (onautocomplete/onautocompleteerror)
to HTMLFormElement's public DOM API (unprefixed, as per Ian Hickson's advice). All are require the Conditional
REQUEST_AUTOCOMPLETE to be enabled to be activated.

* loader/EmptyClients.cpp:
(WebCore):
(WebCore::EmptyFrameLoaderClient::didRequestAutocomplete):

Added noop implementation for FrameLoader::didRequestAutocomplete.

* loader/EmptyClients.h:
(EmptyFrameLoaderClient):

Added FrameLoader::didRequestAutocomplete to EmptyFrameLoaderClient interface.

* loader/FrameLoaderClient.h:
(FrameLoaderClient):

Added noop implementation to FrameLoaderClient interface (which is implemented chromium's FrameLoaderLoaderImpl.cpp).

Source/WebKit/chromium:

Implements an initial version of the proposal for interactive autocomplete outlined in this email:
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html

The goal of this patch is to allow web authors to call formElement.requestAutocomplete(); after subscribing for
autocomplete/autocompleteerror events on formElement. If the form's [autocomplete] attribute is "off" an
error will be dispatched. Otherwise, a request will be issued to the FrameLoaderClient.  At the moment, the
implementation in Chrome (https://codereview.chromium.org/11270018/) will simply dispatch an error until the
UI on Chrome's side is built. Both autocomplete and autocompleteerror events will be dispatched asynchronously
after a small delay to behave consistently in all situations and implementations.

Currently this is behind the feature flag REQUEST_AUTOCOMPLETE, which is disabled.

Test: fast/forms/form-request-autocomplete.html

* public/WebAutofillClient.h:
(WebKit):
(WebAutofillClient):
(WebKit::WebAutofillClient::didRequestAutocomplete):

Added WebAutofillClient::didRequestAutocomplete to chrome's public WebKit interface.

* public/WebFormElement.h:

Added an enum that matches HTMLFormElement::AutocompleteResult (and added compile time assert) and a public method
(WebFormElement::finishRequestAutocomplete) to WebFormElement's public interface.

* src/AssertMatchingEnums.cpp:

Added a compile time assert to guarantee the HTMLFormElement::AutocompleteResult enum matches the
WebFormElement::AutocompleteResult enum.

* src/FrameLoaderClientImpl.cpp:
(WebKit):
(WebKit::FrameLoaderClientImpl::didRequestAutocomplete):

Implemented the added FrameLoaderClient::didRequestAutocomplete, which simply passes through to the
WebAutofillClient.

* src/FrameLoaderClientImpl.h:
(FrameLoaderClientImpl):

Implementing FrameLoaderClient::didRequestAutocomplete.

* src/WebFormElement.cpp:
(WebKit::WebFormElement::finishRequestAutocomplete):
(WebKit):

Added WebFormElement::finishRequestAutocomplete to allow chromium's renderer a public API to call to finish the
autocomplete request on a WebFormElement.

LayoutTests:

Adds tests for an initial implementation of the proposal for interactive autocomplete outlined in this email:
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html

The goal of this patch is to allow web authors to call formElement.requestAutocomplete(); after subscribing
for autocomplete/autocompleteerror events on formElement. If the form's [autocomplete] attribute is "off" an
error will be dispatched. Otherwise, a request will be issued to the FrameLoaderClient. At the moment, the
implementation in Chrome (https://codereview.chromium.org/11270018/) will simply dispatch an error until the
UI on Chrome's side is built. Both autocomplete and autocompleteerror events will be dispatched asynchronously
after a small delay to behave consistently in all situations and implementations.

Currently the implementation is behind the feature flag REQUEST_AUTOCOMPLETE, which is disabled, so the test
is expected to fail. This test verifies that currently no client implements this method on HTMLFormElement
(HTMLFormElement#requestAutocomplete) and returns. When the chrome-side lands I'll add a success case in
LayoutTests/platform/chromium/fast/forms/ with the expected successful results.

* fast/forms/form-request-autocomplete-expected.txt: Added.
* fast/forms/form-request-autocomplete.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@133396 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/form-request-autocomplete-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/form-request-autocomplete.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/EventNames.h
Source/WebCore/html/HTMLAttributeNames.in
Source/WebCore/html/HTMLFormElement.cpp
Source/WebCore/html/HTMLFormElement.h
Source/WebCore/html/HTMLFormElement.idl
Source/WebCore/loader/EmptyClients.cpp
Source/WebCore/loader/EmptyClients.h
Source/WebCore/loader/FrameLoaderClient.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebAutofillClient.h
Source/WebKit/chromium/public/WebFormElement.h
Source/WebKit/chromium/src/AssertMatchingEnums.cpp
Source/WebKit/chromium/src/FrameLoaderClientImpl.cpp
Source/WebKit/chromium/src/FrameLoaderClientImpl.h
Source/WebKit/chromium/src/WebFormElement.cpp

index 416c4b26eb6fae2fd7b12c2ebfb688695c38e7e8..5ea38f1700e466e802d5957498235a24f9bfe187 100644 (file)
@@ -1,3 +1,28 @@
+2012-11-03  Dan Beam  <dbeam@chromium.org>
+
+        Implement HTMLFormElement#requestAutocomplete and associated events
+        https://bugs.webkit.org/show_bug.cgi?id=100557
+
+        Reviewed by Adam Barth.
+
+        Adds tests for an initial implementation of the proposal for interactive autocomplete outlined in this email:
+        http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
+
+        The goal of this patch is to allow web authors to call formElement.requestAutocomplete(); after subscribing
+        for autocomplete/autocompleteerror events on formElement. If the form's [autocomplete] attribute is "off" an
+        error will be dispatched. Otherwise, a request will be issued to the FrameLoaderClient. At the moment, the
+        implementation in Chrome (https://codereview.chromium.org/11270018/) will simply dispatch an error until the
+        UI on Chrome's side is built. Both autocomplete and autocompleteerror events will be dispatched asynchronously
+        after a small delay to behave consistently in all situations and implementations.
+
+        Currently the implementation is behind the feature flag REQUEST_AUTOCOMPLETE, which is disabled, so the test
+        is expected to fail. This test verifies that currently no client implements this method on HTMLFormElement
+        (HTMLFormElement#requestAutocomplete) and returns. When the chrome-side lands I'll add a success case in
+        LayoutTests/platform/chromium/fast/forms/ with the expected successful results.
+
+        * fast/forms/form-request-autocomplete-expected.txt: Added.
+        * fast/forms/form-request-autocomplete.html: Added.
+
 2012-11-03  Pavel Feldman  <pfeldman@chromium.org>
 
         Web Inspector: %d, %i, and %f log formatters have same result
diff --git a/LayoutTests/fast/forms/form-request-autocomplete-expected.txt b/LayoutTests/fast/forms/form-request-autocomplete-expected.txt
new file mode 100644 (file)
index 0000000..de6ff13
--- /dev/null
@@ -0,0 +1,9 @@
+Bug 100557: Implement HTMLFormElement#requestAutocomplete and associated events
+
+For this test to pass, you should see all PASSED below.
+
+FAIL no requestAutocomplete function
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/form-request-autocomplete.html b/LayoutTests/fast/forms/form-request-autocomplete.html
new file mode 100644 (file)
index 0000000..ea86e53
--- /dev/null
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+jsTestIsAsync = true;
+
+var numErrors = 0;
+var numErrorsExpected = 0;
+
+function runTests()
+{
+    if (typeof HTMLFormElement.prototype.requestAutocomplete != 'function') {
+        testFailed('no requestAutocomplete function');
+        finishJSTest();
+        return;
+    }
+
+    checkDynamicAttributes();
+    checkParsedAttributes();
+}
+
+function checkForEnumerableProperties(form)
+{
+    var enumerated = false;
+    for (var field in form) {
+        if (/onautocomplete/.test(field))
+            testFailed('enumerable form attribute found on HTMLFormElement: ' + field);
+        enumerated = true;
+    }
+    if (enumerated)
+        testPassed('no enumerable properties on HTMLFormElement');
+    else
+        testFailed('failed to enumerate HTMLFormElement properties');
+}
+
+function checkParsedAttributes()
+{
+    numErrorsExpected += 1;
+
+    var form = document.forms[0];
+    checkForEnumerableProperties(form);
+    form.requestAutocomplete();
+}
+
+function checkDynamicAttributes()
+{
+    numErrorsExpected += 1;
+
+    var form = document.createElement('form');
+    checkForEnumerableProperties(form);
+
+    form.autocomplete = 'off';
+    form.onautocompleteerror = onError;
+    form.requestAutocomplete();
+}
+
+function onError()
+{
+    numErrors += 1;
+    if (numErrors > numErrorsExpected)
+        testFailed('too many error events');
+    else if (numErrors == numErrorsExpected) {
+        testPassed('got expected number of error events (' + numErrorsExpected + ')');
+        finishJSTest();
+    }
+}
+
+window.addEventListener('load', runTests, true);
+</script>
+</head>
+<body>
+<p> Bug <a href="http://bugs.webkit.org/show_bug.cgi?id=100557">100557</a>: Implement HTMLFormElement#requestAutocomplete and associated events </p>
+<p> For this test to pass, you should see all PASSED below. </p>
+<form autocomplete="off" onautocompleteerror="onError();"></form>
+<p id="console"></p>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
index e6e6a4a8cf5a7b8e5c0f737933832c4a5a93c28b..87bcd77ca5329926bceaf9459f19a786020ad84d 100644 (file)
@@ -1,3 +1,96 @@
+2012-11-03  Dan Beam  <dbeam@chromium.org>
+
+        Implement HTMLFormElement#requestAutocomplete and associated events
+        https://bugs.webkit.org/show_bug.cgi?id=100557
+
+        Reviewed by Adam Barth.
+
+        Implements an initial version of the proposal for interactive autocomplete outlined in this email:
+        http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
+
+        The goal of this patch is to allow web authors to call formElement.requestAutocomplete(); after subscribing for
+        autocomplete/autocompleteerror events on formElement. If the form's [autocomplete] attribute is "off" an
+        error will be dispatched. Otherwise, a request will be issued to the FrameLoaderClient.  At the moment, the
+        implementation in Chrome (https://codereview.chromium.org/11270018/) will simply dispatch an error until the
+        UI on Chrome's side is built. Both autocomplete and autocompleteerror events will be dispatched asynchronously
+        after a small delay to behave consistently in all situations and implementations.
+
+        Currently this is behind the feature flag REQUEST_AUTOCOMPLETE, which is disabled.
+
+        Test: fast/forms/form-request-autocomplete.html
+
+        * dom/EventNames.h:
+        (WebCore):
+
+        Added autocomplete and autocompleteerror events. The autocomplete event is dispatched after a user adds more
+        information to a form using the future UI. This is not currently dispatched in any implementation (including Chrome)
+        but will be in the future. The autocompleteerror event is dispatched when the form has [autocomplete="off"] on the
+        node being asked for an interactive autocomplete. The user agent may also dispatch this event if it doesn't implement
+        this API but has turned on the feature flag, can't currently show an autocomplete UI (e.g. running headlessly or in
+        an HTML notification, security concerns, or any other reason it desires).
+
+        * html/HTMLAttributeNames.in:
+
+        Added onautocomplete and onautocompleteerror attributes so they can be parsed when creating form elements and used
+        as event listeners. For example:
+
+          <form onautocomplete="/* when autocomplete succeeds */" autocompleteerror="/* when autocomplete fails */">
+
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::HTMLFormElement):
+        (WebCore):
+
+        Added m_requestAutocompleteTimer (a timer that's used to dispatch events asynchronously) to the initializer list that
+        triggers requestAutocompleteTimerFired when it times out.
+
+        (WebCore::HTMLFormElement::requestAutocomplete):
+
+        Called when HTMLFormElement#requestAutocomplete is called from JS (also see HTMLFormElement.idl) and decides whether
+        to dispatch an error and exit early (in the case where autocomplete="off") or pass the request on to the
+        FrameLoaderClient.
+
+        (WebCore::HTMLFormElement::finishRequestAutocomplete):
+
+        Called when the request for an interactive autocomplete is finished with either a success or error result. This
+        causes an event to queue and fired after a 0 second delay. Events are owned by HTMLFormElement and reference the
+        target element (this) until fired.
+
+        (WebCore::HTMLFormElement::requestAutocompleteTimerFired):
+
+        Called when the event timer runs out to pump the queue of current events. Events are released on dispatch.
+
+        (WebCore::HTMLFormElement::parseAttribute):
+
+        Encountering onautocomplete or onautocompleteerror attributes while parsing HTMLFormElements now adds event listeners
+        for autocomplete an autocompleteerror events (respectively) to dispatch the value of the attribute as a script.
+
+        * html/HTMLFormElement.h:
+        (HTMLFormElement):
+
+        Added various methods and data members as required by the implementation.
+
+        * html/HTMLFormElement.idl:
+
+        Added the method requestAutocomplete and associated DOM event handler attributes (onautocomplete/onautocompleteerror)
+        to HTMLFormElement's public DOM API (unprefixed, as per Ian Hickson's advice). All are require the Conditional
+        REQUEST_AUTOCOMPLETE to be enabled to be activated.
+
+        * loader/EmptyClients.cpp:
+        (WebCore):
+        (WebCore::EmptyFrameLoaderClient::didRequestAutocomplete):
+
+        Added noop implementation for FrameLoader::didRequestAutocomplete.
+
+        * loader/EmptyClients.h:
+        (EmptyFrameLoaderClient):
+
+        Added FrameLoader::didRequestAutocomplete to EmptyFrameLoaderClient interface.
+
+        * loader/FrameLoaderClient.h:
+        (FrameLoaderClient):
+
+        Added noop implementation to FrameLoaderClient interface (which is implemented chromium's FrameLoaderLoaderImpl.cpp).
+
 2012-11-03  Pavel Feldman  <pfeldman@chromium.org>
 
         Web Inspector: %d, %i, and %f log formatters have same result
index 7a0552a4a70da93d420117fd202e9209c3b4721a..09b9ae766fb5db42f702c059119d96071c426efa 100644 (file)
@@ -243,6 +243,9 @@ namespace WebCore {
     \
     macro(webkitdeviceproximity) \
     \
+    macro(autocomplete) \
+    macro(autocompleteerror) \
+    \
 
 // end of DOM_EVENT_NAMES_FOR_EACH
 
index f1b9c59ed002028b58e14a669aae6bfe0ca6c15c..ea8c01512f2ecce860e1c88e69af90355b367685 100644 (file)
@@ -165,6 +165,8 @@ novalidate
 nowrap
 object
 onabort
+onautocomplete
+onautocompleteerror
 onbeforecopy
 onbeforecut
 onbeforeload
index dde5ffa3163bd0cede2cd88457631f80b0935b5e..18ac7092c1c7b4e47640045b03733e49bc7b2de9 100644 (file)
@@ -74,6 +74,9 @@ HTMLFormElement::HTMLFormElement(const QualifiedName& tagName, Document* documen
     , m_shouldSubmit(false)
     , m_isInResetFunction(false)
     , m_wasDemoted(false)
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+    , m_requestAutocompleteTimer(this, &HTMLFormElement::requestAutocompleteTimerFired)
+#endif
 {
     ASSERT(hasTagName(formTag));
 }
@@ -387,6 +390,44 @@ void HTMLFormElement::reset()
     m_isInResetFunction = false;
 }
 
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+void HTMLFormElement::requestAutocomplete()
+{
+    Frame* frame = document()->frame();
+    if (!frame)
+        return;
+
+    if (!shouldAutocomplete()) {
+        finishRequestAutocomplete(AutocompleteResultError);
+        return;
+    }
+
+    StringPairVector controlNamesAndValues;
+    getTextFieldValues(controlNamesAndValues);
+    RefPtr<FormState> formState = FormState::create(this, controlNamesAndValues, document(), SubmittedByJavaScript);
+    frame->loader()->client()->didRequestAutocomplete(formState.release());
+}
+
+void HTMLFormElement::finishRequestAutocomplete(AutocompleteResult result)
+{
+    RefPtr<Event> event(Event::create(result == AutocompleteResultSuccess ? eventNames().autocompleteEvent : eventNames().autocompleteerrorEvent, false, false));
+    event->setTarget(this);
+    m_pendingAutocompleteEvents.append(event.release());
+
+    // Dispatch events later as this API is meant to work asynchronously in all situations and implementations.
+    if (!m_requestAutocompleteTimer.isActive())
+        m_requestAutocompleteTimer.startOneShot(0);
+}
+
+void HTMLFormElement::requestAutocompleteTimerFired(Timer<HTMLFormElement>*)
+{
+    Vector<RefPtr<Event> > pendingEvents;
+    m_pendingAutocompleteEvents.swap(pendingEvents);
+    for (size_t i = 0; i < pendingEvents.size(); ++i)
+        dispatchEvent(pendingEvents[i].release());
+}
+#endif
+
 void HTMLFormElement::parseAttribute(const Attribute& attribute)
 {
     if (attribute.name() == actionAttr)
@@ -408,6 +449,12 @@ void HTMLFormElement::parseAttribute(const Attribute& attribute)
         setAttributeEventListener(eventNames().submitEvent, createAttributeEventListener(this, attribute));
     else if (attribute.name() == onresetAttr)
         setAttributeEventListener(eventNames().resetEvent, createAttributeEventListener(this, attribute));
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+    else if (attribute.name() == onautocompleteAttr)
+        setAttributeEventListener(eventNames().autocompleteEvent, createAttributeEventListener(this, attribute));
+    else if (attribute.name() == onautocompleteerrorAttr)
+        setAttributeEventListener(eventNames().autocompleteerrorEvent, createAttributeEventListener(this, attribute));
+#endif
     else
         HTMLElement::parseAttribute(attribute);
 }
index bf28cca3fb2c6af5857951b62cbf02320e4a96da..a8c2bee454e826011886894e66ff8b74590f0cac 100644 (file)
@@ -99,6 +99,16 @@ public:
 
     bool checkValidity();
 
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+    enum AutocompleteResult { AutocompleteResultSuccess, AutocompleteResultError };
+
+    void requestAutocomplete();
+    void finishRequestAutocomplete(AutocompleteResult);
+
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(autocomplete);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(autocompleteerror);
+#endif
+
     HTMLFormControlElement* elementForAlias(const AtomicString&);
     void addElementAlias(HTMLFormControlElement*, const AtomicString& alias);
 
@@ -162,6 +172,13 @@ private:
     bool m_isInResetFunction;
 
     bool m_wasDemoted;
+
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+    void requestAutocompleteTimerFired(Timer<HTMLFormElement>*);
+
+    Vector<RefPtr<Event> > m_pendingAutocompleteEvents;
+    Timer<HTMLFormElement> m_requestAutocompleteTimer;
+#endif
 };
 
 } // namespace WebCore
index 86a6f74c63fdfd2dae0dfc02fd7cd72f8feb5188..d30de479295654ac7a57f40acba5fe3dd6f87825 100644 (file)
@@ -42,4 +42,8 @@
 #endif
     void reset();
     boolean checkValidity();
+
+    [Conditional=REQUEST_AUTOCOMPLETE] void requestAutocomplete();
+    [NotEnumerable, Conditional=REQUEST_AUTOCOMPLETE] attribute EventListener onautocomplete;
+    [NotEnumerable, Conditional=REQUEST_AUTOCOMPLETE] attribute EventListener onautocompleteerror;
 };
index 37f6b37915f50890e4a7cd2f51cc8fc9a04e1f7a..3898461ad1dc43938c7fcc5c649aba72b43ff9b8 100644 (file)
@@ -194,4 +194,10 @@ PassOwnPtr<ContextMenu> EmptyContextMenuClient::customizeMenu(PassOwnPtr<Context
 #endif
 #endif
 
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+void EmptyFrameLoaderClient::didRequestAutocomplete(PassRefPtr<FormState>)
+{
+}
+#endif
+
 }
index 2828a690e080683a10bdf6fca1642e08e4e91650..67e87a792658bcababd3483d2d543343321790e4 100644 (file)
@@ -384,6 +384,10 @@ public:
 #if ENABLE(WEB_INTENTS)
     virtual void dispatchIntent(PassRefPtr<IntentRequest>) OVERRIDE;
 #endif
+
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+    virtual void didRequestAutocomplete(PassRefPtr<FormState>) OVERRIDE;
+#endif
 };
 
 class EmptyTextCheckerClient : public TextCheckerClient {
index 4f2388af5fbb4c5d65c30bff8884554c7c8b9c0d..b4abf88f359961b89aef876055a497856cf13c5f 100644 (file)
@@ -349,6 +349,10 @@ namespace WebCore {
 #if ENABLE(MEDIA_STREAM)
         virtual void dispatchWillStartUsingPeerConnectionHandler(RTCPeerConnectionHandler*) { }
 #endif
+
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+        virtual void didRequestAutocomplete(PassRefPtr<FormState>) = 0;
+#endif
     };
 
 } // namespace WebCore
index 377db2b6e0488c81e24d637d8530be57d3aaf7fb..9fa6625cbbe53d7c6110ebf232f467cb969a77cc 100644 (file)
@@ -1,3 +1,60 @@
+2012-11-03  Dan Beam  <dbeam@chromium.org>
+
+        Implement HTMLFormElement#requestAutocomplete and associated events
+        https://bugs.webkit.org/show_bug.cgi?id=100557
+
+        Reviewed by Adam Barth.
+
+        Implements an initial version of the proposal for interactive autocomplete outlined in this email:
+        http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
+
+        The goal of this patch is to allow web authors to call formElement.requestAutocomplete(); after subscribing for
+        autocomplete/autocompleteerror events on formElement. If the form's [autocomplete] attribute is "off" an
+        error will be dispatched. Otherwise, a request will be issued to the FrameLoaderClient.  At the moment, the
+        implementation in Chrome (https://codereview.chromium.org/11270018/) will simply dispatch an error until the
+        UI on Chrome's side is built. Both autocomplete and autocompleteerror events will be dispatched asynchronously
+        after a small delay to behave consistently in all situations and implementations.
+
+        Currently this is behind the feature flag REQUEST_AUTOCOMPLETE, which is disabled.
+
+        Test: fast/forms/form-request-autocomplete.html
+
+        * public/WebAutofillClient.h:
+        (WebKit):
+        (WebAutofillClient):
+        (WebKit::WebAutofillClient::didRequestAutocomplete):
+
+        Added WebAutofillClient::didRequestAutocomplete to chrome's public WebKit interface.
+
+        * public/WebFormElement.h:
+
+        Added an enum that matches HTMLFormElement::AutocompleteResult (and added compile time assert) and a public method
+        (WebFormElement::finishRequestAutocomplete) to WebFormElement's public interface.
+
+        * src/AssertMatchingEnums.cpp:
+
+        Added a compile time assert to guarantee the HTMLFormElement::AutocompleteResult enum matches the
+        WebFormElement::AutocompleteResult enum.
+
+        * src/FrameLoaderClientImpl.cpp:
+        (WebKit):
+        (WebKit::FrameLoaderClientImpl::didRequestAutocomplete):
+
+        Implemented the added FrameLoaderClient::didRequestAutocomplete, which simply passes through to the
+        WebAutofillClient.
+
+        * src/FrameLoaderClientImpl.h:
+        (FrameLoaderClientImpl):
+
+        Implementing FrameLoaderClient::didRequestAutocomplete.
+
+        * src/WebFormElement.cpp:
+        (WebKit::WebFormElement::finishRequestAutocomplete):
+        (WebKit):
+
+        Added WebFormElement::finishRequestAutocomplete to allow chromium's renderer a public API to call to finish the
+        autocomplete request on a WebFormElement.
+
 2012-11-02  Anders Carlsson  <andersca@apple.com>
 
         Add a PluginInactive plug-in unavailability reason
index 7b48f57dbe46ea37ef6f4994c513cb2f93d687fc..7424c3fecdba9ffa7286e1b7eef3df8c960bfd5d 100644 (file)
@@ -33,6 +33,8 @@
 
 namespace WebKit {
 
+class WebFormElement;
+class WebFrame;
 class WebInputElement;
 class WebKeyboardEvent;
 class WebNode;
@@ -75,6 +77,9 @@ public:
     // keys to navigate outside the range of possible selections.
     virtual void didClearAutofillSelection(const WebNode&) { }
 
+    // Informs the browser an interactive autocomplete has been requested.
+    virtual void didRequestAutocomplete(WebFrame*, const WebFormElement&) { }
+
     // Instructs the browser to remove the Autocomplete entry specified from
     // its DB.
     virtual void removeAutocompleteSuggestion(const WebString& name,
index 1ef431fa3656f5c278dc2e4d356124d11b767d51..27c99d3a17192f7d0808c87e72ca5da8a63b6c18 100644 (file)
@@ -69,6 +69,9 @@ namespace WebKit {
         WEBKIT_EXPORT void getNamedElements(const WebString&, WebVector<WebNode>&);
         WEBKIT_EXPORT void getFormControlElements(WebVector<WebFormControlElement>&) const;
 
+        enum AutocompleteResult { AutocompleteResultSuccess, AutocompleteResultError };
+        WEBKIT_EXPORT void finishRequestAutocomplete(WebFormElement::AutocompleteResult);
+
 #if WEBKIT_IMPLEMENTATION
         WebFormElement(const WTF::PassRefPtr<WebCore::HTMLFormElement>&);
         WebFormElement& operator=(const WTF::PassRefPtr<WebCore::HTMLFormElement>&);
index 538d9f198525dfa74210ad12c6cd22fb76645a7b..f3e7859eeb9850651dbcfe4184745230ecc4756e 100644 (file)
@@ -48,6 +48,9 @@
 #include "FontSmoothingMode.h"
 #include "GeolocationError.h"
 #include "GeolocationPosition.h"
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+#include "HTMLFormElement.h"
+#endif
 #include "HTMLInputElement.h"
 #include "IDBCursor.h"
 #include "IDBDatabaseException.h"
@@ -86,6 +89,9 @@
 #include "WebFileError.h"
 #include "WebFileInfo.h"
 #include "WebFontDescription.h"
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+#include "WebFormElement.h"
+#endif
 #include "WebGeolocationError.h"
 #include "WebGeolocationPosition.h"
 #include "WebIDBCursor.h"
@@ -633,3 +639,8 @@ COMPILE_ASSERT_MATCHING_ENUM(WebURLResponse::HTTP_1_1, ResourceResponse::HTTP_1_
 COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayer::CORSModeUnspecified, MediaPlayerClient::Unspecified);
 COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayer::CORSModeAnonymous, MediaPlayerClient::Anonymous);
 COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayer::CORSModeUseCredentials, MediaPlayerClient::UseCredentials);
+
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+COMPILE_ASSERT_MATCHING_ENUM(WebFormElement::AutocompleteResultSuccess, HTMLFormElement::AutocompleteResultSuccess);
+COMPILE_ASSERT_MATCHING_ENUM(WebFormElement::AutocompleteResultError, HTMLFormElement::AutocompleteResultError);
+#endif
index 11c726a328a9a1c6078ec1948fb26e45f3104176..7ffe94339ec1c482297a272659e86662a3ed77ac 100644 (file)
@@ -62,6 +62,9 @@
 #endif
 #include "Settings.h"
 #include "SocketStreamHandleInternal.h"
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+#include "WebAutofillClient.h"
+#endif
 #include "WebDOMEvent.h"
 #include "WebDataSourceImpl.h"
 #include "WebDevToolsAgentPrivate.h"
@@ -1651,5 +1654,12 @@ void FrameLoaderClientImpl::dispatchWillStartUsingPeerConnectionHandler(RTCPeerC
 }
 #endif
 
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+void FrameLoaderClientImpl::didRequestAutocomplete(PassRefPtr<FormState> formState)
+{
+    if (m_webFrame->viewImpl() && m_webFrame->viewImpl()->autofillClient())
+        m_webFrame->viewImpl()->autofillClient()->didRequestAutocomplete(m_webFrame, WebFormElement(formState->form()));
+}
+#endif
 
 } // namespace WebKit
index 12a76feee352605b905750a84e6c5fb3bdb1a3bc..6589c37bb79e5641df03a2aedc4bfbd0faa8ae00 100644 (file)
@@ -225,6 +225,10 @@ public:
     virtual void dispatchWillStartUsingPeerConnectionHandler(WebCore::RTCPeerConnectionHandler*) OVERRIDE;
 #endif
 
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+    virtual void didRequestAutocomplete(PassRefPtr<WebCore::FormState>) OVERRIDE;
+#endif
+
 private:
     void makeDocumentView();
 
index cdae6620e8b35e596e5343531a755381e5fe7e4e..f6a9a67f06b33adf7307d440cff8853d32ee24a3 100644 (file)
@@ -102,6 +102,13 @@ void WebFormElement::getFormControlElements(WebVector<WebFormControlElement>& re
     result.assign(tempVector);
 }
 
+void WebFormElement::finishRequestAutocomplete(WebFormElement::AutocompleteResult result)
+{
+#if ENABLE(REQUEST_AUTOCOMPLETE)
+    unwrap<HTMLFormElement>()->finishRequestAutocomplete(static_cast<HTMLFormElement::AutocompleteResult>(result));
+#endif
+}
+
 WebFormElement::WebFormElement(const PassRefPtr<HTMLFormElement>& e)
     : WebElement(e)
 {