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 416c4b2..5ea38f1 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 e6e6a4a..87bcd77 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 7a0552a..09b9ae7 100644 (file)
@@ -243,6 +243,9 @@ namespace WebCore {
     \
     macro(webkitdeviceproximity) \
     \
+    macro(autocomplete) \
+    macro(autocompleteerror) \
+    \
 
 // end of DOM_EVENT_NAMES_FOR_EACH
 
index f1b9c59..ea8c015 100644 (file)
@@ -165,6 +165,8 @@ novalidate
 nowrap
 object
 onabort
+onautocomplete
+onautocompleteerror
 onbeforecopy
 onbeforecut
 onbeforeload
index dde5ffa..18ac709 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 bf28cca..a8c2bee 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 86a6f74..d30de47 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 37f6b37..3898461 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 2828a69..67e87a7 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 4f2388a..b4abf88 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 377db2b..9fa6625 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 7b48f57..7424c3f 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 1ef431f..27c99d3 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 538d9f1..f3e7859 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 11c726a..7ffe943 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 12a76fe..6589c37 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 cdae662..f6a9a67 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)
 {