RESOLVED FIXED 31718
Framework to show form validation message for invalid controls
https://bugs.webkit.org/show_bug.cgi?id=31718
Summary Framework to show form validation message for invalid controls
Kent Tamura
Reported 2009-11-20 04:16:24 PST
- Adds methods to show/hide validation messages to ChromeClient - A form control calls them if it has focus and it is invalid.
Attachments
Proposed patch (6.50 KB, patch)
2010-02-04 08:11 PST, Kent Tamura
no flags
Screenshot of this implementation on Safari/Windows (15.99 KB, image/png)
2010-03-25 17:23 PDT, Kent Tamura
no flags
Proposed patch (rev.2) (52.59 KB, patch)
2010-03-25 17:54 PDT, Kent Tamura
no flags
Proposed patch (rev.3) (52.64 KB, patch)
2010-04-01 04:50 PDT, Kent Tamura
no flags
Proposed patch (rev.4) (52.94 KB, patch)
2010-04-01 09:07 PDT, Kent Tamura
no flags
Patch (rev.5; remove Windows impl.) (57.74 KB, patch)
2010-06-09 08:44 PDT, Kent Tamura
no flags
Patch (rev.6; build fix) (57.71 KB, patch)
2010-06-09 09:14 PDT, Kent Tamura
no flags
Patch (rev.7; build fix 2) (58.17 KB, patch)
2010-06-09 10:08 PDT, Kent Tamura
no flags
Patch (rev.8; build fix 3) (58.19 KB, patch)
2010-06-09 17:19 PDT, Kent Tamura
no flags
Patch (rev.9) (58.89 KB, patch)
2010-06-10 08:52 PDT, Kent Tamura
no flags
Patch rev.10 (34.12 KB, patch)
2010-10-13 02:54 PDT, Kent Tamura
no flags
Patch rev.11 (rebased) (34.13 KB, patch)
2010-10-13 03:32 PDT, Kent Tamura
no flags
Patch 12 (rebased and simplified) (34.50 KB, patch)
2010-10-25 03:41 PDT, Kent Tamura
no flags
Patch 13 (more simplification. No Chrome changes) (22.00 KB, patch)
2010-10-28 01:22 PDT, Kent Tamura
no flags
Kent Tamura
Comment 1 2010-02-04 08:11:22 PST
Created attachment 48145 [details] Proposed patch
Darin Adler
Comment 2 2010-02-04 11:31:17 PST
Comment on attachment 48145 [details] Proposed patch > + void mayShowValidationMessage(); > + void mayHideValidationMessage(); A single update function would be better than these two. > + // A validation message for this element is shown. > + bool m_validationMessageShown : 1; For boolean data members we normally use a name that fits the sentence "form control element <xxx>". But I think what you may need here is a copy of the message that was last sent to the client, rather than just a boolean. > + virtual void showFormValidationMessage(const Node*, const IntRect&, FrameView*, const String&) { }; > + virtual void hideFormValidationMessage(const Node*) { }; Should be HTMLFormControlElement* instead of Node*. Also no good reason to use const Node* since these objects are in a tree and const pointers are not all that useful. No semicolons after "{ }". I don’t understand the value of the IntRect and FrameView arguments. What rectangle? What guarantees that a form element is rectangular, given that it can be transformed arbitrarily? Why can’t the caller get things like the rectangle and view from the form control element using the usual APIs instead of having them explicitly passed? Maybe this is best for the current usage in Chromium but I don’t think it’s quite right. I would leave all that complexity out of the chrome client hookup. Further, if you pass a rectangle and frame view, then who is responsible for calling with a new rectangle if the page changes? It's clearly wrong to send a rectangle for one moment in time without providing for tracking over time, and it's not useful to supply the FrameView since it can easily be derived. If the validation interface is going to be shown overlaying the web page, I’d like to see more support for it in WebKit itself. It’s unpleasant to have to redo this feature for each platform separately. It’s good to have flexibility but ideally we would share as much common code as necessary. I’m not sure it makes sense to have separate hide/show calls for this -- this should instead just be a single set function. All the logic would end up simpler and we can use either a null or empty string to mean "hide". Is the client guaranteed to receive a call for a form element if it’s removed from the document? What about when a document moves out of the view or back into the view during navigation? I think that sending the call at destructor time is clearly bad, because these are reference-counted times and the timing of the call to the destructor is unpredictable. More thought needs to go into this aspect of the design. How can we test this? Can you hook this up to DumpRenderTree? I don’t think we should land the ChromeClient level alone without the upper level hookup that allows testing. What prevents the same validation message from being repeatedly sent to the client? There's a lot to think about here.
Kent Tamura
Comment 3 2010-02-08 23:34:12 PST
(In reply to comment #2) > (From update of attachment 48145 [details]) > > + void mayShowValidationMessage(); > > + void mayHideValidationMessage(); > > A single update function would be better than these two. ok, I'll merge them into updateValidationMessage(const String&). > > + // A validation message for this element is shown. > > + bool m_validationMessageShown : 1; > > For boolean data members we normally use a name that fits the sentence "form > control element <xxx>". > > But I think what you may need here is a copy of the message that was last sent > to the client, rather than just a boolean. > > > + virtual void showFormValidationMessage(const Node*, const IntRect&, FrameView*, const String&) { }; > > + virtual void hideFormValidationMessage(const Node*) { }; > > Should be HTMLFormControlElement* instead of Node*. Also no good reason to use > const Node* since these objects are in a tree and const pointers are not all > that useful. > > No semicolons after "{ }". > > I don’t understand the value of the IntRect and FrameView arguments. What > rectangle? What guarantees that a form element is rectangular, given that it > can be transformed arbitrarily? Why can’t the caller get things like the > rectangle and view from the form control element using the usual APIs instead > of having them explicitly passed? Maybe this is best for the current usage in > Chromium but I don’t think it’s quite right. I would leave all that complexity > out of the chrome client hookup. Ah, I didn't take care of transformation. You're right. We shouldn't provide a rectangle here. > > Further, if you pass a rectangle and frame view, then who is responsible for > calling with a new rectangle if the page changes? It's clearly wrong to send a > rectangle for one moment in time without providing for tracking over time, and > it's not useful to supply the FrameView since it can easily be derived. > > If the validation interface is going to be shown overlaying the web page, I’d > like to see more support for it in WebKit itself. It’s unpleasant to have to > redo this feature for each platform separately. It’s good to have flexibility > but ideally we would share as much common code as necessary. I see. However I don't have any idea how to support. I thought validation messages were similar to tooltips or history completions. They don't have common support code. > > I’m not sure it makes sense to have separate hide/show calls for this -- this > should instead just be a single set function. All the logic would end up > simpler and we can use either a null or empty string to mean "hide". > > Is the client guaranteed to receive a call for a form element if it’s removed > from the document? What about when a document moves out of the view or back > into the view during navigation? I think that sending the call at destructor > time is clearly bad, because these are reference-counted times and the timing > of the call to the destructor is unpredictable. More thought needs to go into > this aspect of the design. I assumed ChromeClient implementations were responsible for them. That is to say, the implementations may hide validation messages even if hideFormValidationMessage() is not called. > How can we test this? Can you hook this up to DumpRenderTree? I don’t think we > should land the ChromeClient level alone without the upper level hookup that > allows testing. Hmm, how about introducing layoutTestController.visibleValidationMessage(element) ? > What prevents the same validation message from being repeatedly sent to the > client? It never happens because of the code in HTMLFormControlElement.cpp. If HTMLFormControlElement has a visible message string as you advised, we can double-check it. BTW, I suppose a validation message is shown as "Balloon Tooltip" in Windows, and couldn't find such UI control for Mac. Do you have any idea on Mac UI? http://msdn.microsoft.com/en-us/library/bb760252(VS.85).aspx I'll update the patch later (a few days or more).
Darin Adler
Comment 4 2010-02-09 10:40:27 PST
(In reply to comment #3) > > Further, if you pass a rectangle and frame view, then who is responsible for > > calling with a new rectangle if the page changes? It's clearly wrong to send a > > rectangle for one moment in time without providing for tracking over time, and > > it's not useful to supply the FrameView since it can easily be derived. > > > > If the validation interface is going to be shown overlaying the web page, I’d > > like to see more support for it in WebKit itself. It’s unpleasant to have to > > redo this feature for each platform separately. It’s good to have flexibility > > but ideally we would share as much common code as necessary. > > I see. However I don't have any idea how to support. > I thought validation messages were similar to tooltips or history completions. > They don't have common support code. Tooltips are indeed updated as elements move on the page. I’m not sure about completion, but I believe they also update. Neither has an API that involves passing a rectangle to the ChromeClient, so I don’t think these are similar enough. Imagine a page where there is a zip code field that appears only if the country is U.S. You enter some invalid data below and then the user changes the country to non-U.S.. So the invalid field moves up on the page and the rectangle that was passed to the ChromeClient is now invalid. How would you suggest this work? > > I’m not sure it makes sense to have separate hide/show calls for this -- this > > should instead just be a single set function. All the logic would end up > > simpler and we can use either a null or empty string to mean "hide". > > > > Is the client guaranteed to receive a call for a form element if it’s removed > > from the document? What about when a document moves out of the view or back > > into the view during navigation? I think that sending the call at destructor > > time is clearly bad, because these are reference-counted times and the timing > > of the call to the destructor is unpredictable. More thought needs to go into > > this aspect of the design. > > I assumed ChromeClient implementations were responsible for them. That is to > say, the implementations may hide validation messages even if > hideFormValidationMessage() is not called. I think we want most of the logic to be in the engine. The more code that client applications need, the more we’ll have bugs and an unequal playing field between clients. We want WebKit to be as easy to use as possible. The policy comes from the client, but as much of the sensible behavior as possible should be built into WebKit. Specifically, simple cases like elements going away should not require extra explicit code in every client. > > How can we test this? Can you hook this up to DumpRenderTree? I don’t think we > > should land the ChromeClient level alone without the upper level hookup that > > allows testing. > > Hmm, how about introducing > layoutTestController.visibleValidationMessage(element) ? > BTW, I suppose a validation message is shown as "Balloon Tooltip" in Windows, > and couldn't find such UI control for Mac. Do you have any idea on Mac UI? The very notion of a one size fits all “validation failed” UI seems a bit quaint and naive to me. But I suggest looking for interface in Mac OS X UI that implement this type of thing. Take a Mac and poke around at the system until you can find something. I believe there is an example like this when you install Mac OS X and set up your initial account name and password. Tap some other Mac OS X experts to find some examples and then we can make an informed decision.
Kent Tamura
Comment 5 2010-02-18 08:32:05 PST
I had some investigation. * Tooltips for title= attributes ChromeClient::setTooltip() doesn't pass location information. It just shows the specified string as a tooltip, and disappears a few seconds later. A tooltip appears at the mouse pointer position initially, and never moves. * History completion popup in Chromium A history completion popup appears on the focused element, and doesn't move even if the focused element moves. It is implemented at outside of WebCore. * When should we hide a validation message? Node::detach(). We should not show validation messages for a node with no renderer node. * Keep track of the target element position To hook layout() or paint() seems costly. I think polling the position periodically is better.
Kent Tamura
Comment 6 2010-02-25 07:51:55 PST
The new patch is ready. I'll upload it after Bug#34924 is landed.
Kent Tamura
Comment 7 2010-03-25 17:23:45 PDT
Created attachment 51697 [details] Screenshot of this implementation on Safari/Windows
Kent Tamura
Comment 8 2010-03-25 17:54:10 PDT
Created attachment 51702 [details] Proposed patch (rev.2)
Kent Tamura
Comment 9 2010-03-25 22:27:50 PDT
(In reply to comment #8) > Created an attachment (id=51702) [details] > Proposed patch (rev.2) Notable differences from the first patch are: - Introduce layoutTestController.visibleValidationMessageForElementById() - WebCore::Chrome manages timing of showing / hiding validation messages A message is hidden 5 seconds later, etc. - Has a Windows implementation No Mac implementation. It would be another patch.
Sam Weinig
Comment 10 2010-03-28 19:15:05 PDT
Comment on attachment 51702 [details] Proposed patch (rev.2) > + // Returns the top-left, top-right, bottom-left, bottom-right corner > + // locations with transformations. This returns an empty vector if the > + // element has no renderer. > + // Suppose that 'points' is a result of getTransformedCorners(), you can > + // access each of corners with symbolic indexes: > + // points[TopLeftCorner] > + // points[TopRightCorner] > + // points[BottomLeftCorner] > + // points[bottomRightCorner] > + virtual Vector<FloatPoint> getTransformedCorners() const; > + enum { // Indexes for the result of getTransformedCorners(). > + TopLeftCorner = 0, > + TopRightCorner, > + BottomLeftCorner, > + BottomRightCorner > + }; Why doesn't this just a FloatQuad?
Sam Weinig
Comment 11 2010-03-28 19:20:51 PDT
Why doesn't this just *use* a FloatQuad?
Kent Tamura
Comment 12 2010-03-28 19:26:21 PDT
(In reply to comment #11) > Why doesn't this just *use* a FloatQuad? Oh, I haven't known FloatQuad. We should use it. I'll update the patch.
Kent Tamura
Comment 13 2010-04-01 04:50:56 PDT
Created attachment 52284 [details] Proposed patch (rev.3)
Kent Tamura
Comment 14 2010-04-01 04:52:54 PDT
(In reply to comment #13) > Created an attachment (id=52284) [details] > Proposed patch (rev.3) - Use FloatQuad - Replace unnecessary PassRefPtr<HTMLFormControlElement> with HTMLFormControlElement*
Kent Tamura
Comment 15 2010-04-01 09:07:54 PDT
Created attachment 52302 [details] Proposed patch (rev.4)
Kent Tamura
Comment 16 2010-04-01 09:08:48 PDT
(In reply to comment #15) > Created an attachment (id=52302) [details] > Proposed patch (rev.4) This improved comments and ChangeLog.
Kent Tamura
Comment 17 2010-05-03 09:03:25 PDT
The latest patch makes some conflicts with the current WebKit source. I'll resolve them when I update the patch or I commit it.
Kent Tamura
Comment 18 2010-05-24 09:41:04 PDT
Could anyone review the patch please? If the patch is too large, I'll split it into some pieces.
Kent Tamura
Comment 19 2010-06-09 08:44:17 PDT
Created attachment 58248 [details] Patch (rev.5; remove Windows impl.)
Early Warning System Bot
Comment 20 2010-06-09 08:51:27 PDT
Eric Seidel (no email)
Comment 21 2010-06-09 08:52:30 PDT
WebKit Review Bot
Comment 22 2010-06-09 08:56:42 PDT
WebKit Review Bot
Comment 23 2010-06-09 09:05:38 PDT
Kent Tamura
Comment 24 2010-06-09 09:14:36 PDT
Created attachment 58252 [details] Patch (rev.6; build fix)
Early Warning System Bot
Comment 25 2010-06-09 09:26:18 PDT
WebKit Review Bot
Comment 26 2010-06-09 10:02:07 PDT
Kent Tamura
Comment 27 2010-06-09 10:08:38 PDT
Created attachment 58254 [details] Patch (rev.7; build fix 2)
Kent Tamura
Comment 28 2010-06-09 10:20:07 PDT
I removed Windows balloon implementation and ContainerNode::getTransformedCorners() from the patch to minimize the size.
WebKit Review Bot
Comment 29 2010-06-09 11:42:41 PDT
Kent Tamura
Comment 30 2010-06-09 17:19:47 PDT
Created attachment 58312 [details] Patch (rev.8; build fix 3)
Kent Tamura
Comment 31 2010-06-10 08:52:15 PDT
Created attachment 58375 [details] Patch (rev.9)
Kent Tamura
Comment 32 2010-07-22 20:57:25 PDT
Reviewers, could you review the patch please?
Kent Tamura
Comment 33 2010-09-21 18:02:27 PDT
FYI: Mozilla completed the implementation of this feature for Firefox. https://bugzilla.mozilla.org/show_bug.cgi?id=561636
Adam Barth
Comment 34 2010-10-10 11:21:10 PDT
Comment on attachment 58375 [details] Patch (rev.9) View in context: https://bugs.webkit.org/attachment.cgi?id=58375&action=review r- for crash. > WebCore/html/HTMLFormControlElement.cpp:360 > + page->chrome()->updateFormValidationMessage(this, message); Doesn't this crash if page is null?
Kent Tamura
Comment 35 2010-10-13 02:52:26 PDT
Thank you for reviewing an ancient patch. (In reply to comment #34) > > WebCore/html/HTMLFormControlElement.cpp:360 > > + page->chrome()->updateFormValidationMessage(this, message); > > Doesn't this crash if page is null? It can crash though I don't know when page() returns NULL. I'll update the patch.
Kent Tamura
Comment 36 2010-10-13 02:54:48 PDT
Created attachment 70593 [details] Patch rev.10 Fix null-dereference of page()
Kent Tamura
Comment 37 2010-10-13 02:57:13 PDT
(In reply to comment #36) > Created an attachment (id=70593) [details] > Patch rev.10 > > Fix null-dereference of page() I removed the ChromeClient change which the prior patches had because I'm going to implement the message bubble with shadow DOM.
Kent Tamura
Comment 38 2010-10-13 03:32:54 PDT
Created attachment 70595 [details] Patch rev.11 (rebased)
Kent Tamura
Comment 39 2010-10-25 03:41:46 PDT
Created attachment 71726 [details] Patch 12 (rebased and simplified)
Dimitri Glazkov (Google)
Comment 40 2010-10-26 14:04:52 PDT
(In reply to comment #39) > Created an attachment (id=71726) [details] > Patch 12 (rebased and simplified) Story for stepping into the middle of the story here. I thought you mentioned using shadow DOM in one of the previous comments, but this patch still uses the same page->chrome->foo machinery as the others. Also, why does Chrome.cpp code is doing so much work? Shouldn't it be basically just a shim to shuttle information between browser and renderer?
Kent Tamura
Comment 41 2010-10-27 03:34:20 PDT
(In reply to comment #40) > (In reply to comment #39) > > Created an attachment (id=71726) [details] [details] > > Patch 12 (rebased and simplified) > > Story for stepping into the middle of the story here. I thought you mentioned using shadow DOM in one of the previous comments, but this patch still uses the same page->chrome->foo machinery as the others. > > Also, why does Chrome.cpp code is doing so much work? Shouldn't it be basically just a shim to shuttle information between browser and renderer? The original intention was 1) Showing a validation message by a native way. It means Chromium needs IPC messagings. 2) Showing just one validation message in one page even if the page consists of multiple frames As you know, 1 is invalid for now because I have a shadow DOM implementation. As for 2, I have changed my mind :-) Showing multiple validation messages for multiple forms would be acceptable. It happens only if a page has multiple forms and a user tries to submit them in short time. We can simplify the patch. Simpler is better.
Kent Tamura
Comment 42 2010-10-28 01:22:48 PDT
Created attachment 72157 [details] Patch 13 (more simplification. No Chrome changes)
Dimitri Glazkov (Google)
Comment 43 2010-11-03 21:00:46 PDT
Comment on attachment 72157 [details] Patch 13 (more simplification. No Chrome changes) View in context: https://bugs.webkit.org/attachment.cgi?id=72157&action=review ok. > WebCore/html/ValidationMessage.cpp:55 > + if (m_message.isEmpty()) { } // FIXME: Construct validation message UI. Probably should just remove this, leaving just a FIXME.
Dimitri Glazkov (Google)
Comment 44 2010-11-03 21:23:02 PDT
Comment on attachment 72157 [details] Patch 13 (more simplification. No Chrome changes) View in context: https://bugs.webkit.org/attachment.cgi?id=72157&action=review > WebCore/html/ValidationMessage.cpp:45 > + hideMessage(); Cancel timer here?
Kent Tamura
Comment 45 2010-11-03 23:41:15 PDT
Comment on attachment 72157 [details] Patch 13 (more simplification. No Chrome changes) View in context: https://bugs.webkit.org/attachment.cgi?id=72157&action=review Thank you for reviewing!!! >> WebCore/html/ValidationMessage.cpp:45 >> + hideMessage(); > > Cancel timer here? We don't need to cancel explicitly. It is canceled by m_timer destruction. >> WebCore/html/ValidationMessage.cpp:55 >> + if (m_message.isEmpty()) { } // FIXME: Construct validation message UI. > > Probably should just remove this, leaving just a FIXME. ok.
Kent Tamura
Comment 46 2010-11-04 00:02:39 PDT
Note You need to log in before you can comment on or make changes to this bug.