RESOLVED FIXED Bug 29004
[HTML5][Forms] simple implementation of date&time types of INPUT element
https://bugs.webkit.org/show_bug.cgi?id=29004
Summary [HTML5][Forms] simple implementation of date&time types of INPUT element
Kent Tamura
Reported 2009-09-07 01:49:03 PDT
Like bug#28966 for type=color, implement the following types as a text field and add support for type checking. - date - datetime - datetime-local - month - time - week
Attachments
Proposed patch (60.00 KB, patch)
2009-09-07 02:06 PDT, Kent Tamura
tkent: review-
Patch part 1: recognize date&time types as text fields (16.89 KB, patch)
2009-09-10 05:14 PDT, Kent Tamura
eric: review-
Patch part2: ISO 8601 parser (20.21 KB, patch)
2009-09-10 05:15 PDT, Kent Tamura
eric: review-
Patch part 3: support for ValidityState.typeMismatch and layout tests (34.69 KB, patch)
2009-09-10 05:16 PDT, Kent Tamura
no flags
39344: Patch part 3: support for ValidityState.typeMismatch and layout tests (rev.2) (34.71 KB, patch)
2009-09-13 18:50 PDT, Kent Tamura
no flags
Patch part 3: ValidityState.typeMismatch and layout tests (rev.3) (38.14 KB, patch)
2009-09-21 09:53 PDT, Kent Tamura
tkent: commit-queue-
Patch part 1: recognize date&time types as text fields (rev.2) (28.12 KB, patch)
2009-09-23 19:43 PDT, Kent Tamura
no flags
Patch part 1: recognize date&time types as text fields (rev.3) (28.13 KB, patch)
2009-09-27 18:54 PDT, Kent Tamura
no flags
Patch part 2: ISO 8601 parser (rev.2) (34.51 KB, patch)
2009-09-28 00:36 PDT, Kent Tamura
no flags
Patch part 3: ValidityState.typeMismatch and layout tests (rev.4) (39.91 KB, patch)
2009-09-28 01:20 PDT, Kent Tamura
tkent: commit-queue-
Patch part 1: recognize date&time types as text fields (rev.4) (28.62 KB, patch)
2009-10-01 18:18 PDT, Kent Tamura
eric: review-
Patch part 2: ISO 8601 parser (rev.3) (34.49 KB, patch)
2009-10-13 19:34 PDT, Kent Tamura
tkent: review-
tkent: commit-queue-
Patch part 3: ValidityState.typeMismatch and layout tests (rev.5) (39.80 KB, patch)
2009-10-13 19:38 PDT, Kent Tamura
tkent: review-
tkent: commit-queue-
Patch part 1: recognize date&time types as text fields (rev.5) (28.52 KB, patch)
2009-10-19 21:13 PDT, Kent Tamura
eric: review-
Patch part 2: ISO 8601 parser (rev.4) (26.98 KB, patch)
2009-11-09 01:36 PST, Kent Tamura
no flags
Patch part 3: ValidityState.typeMismatch and layout tests (rev.6) (39.28 KB, patch)
2009-11-09 01:38 PST, Kent Tamura
tkent: commit-queue-
Patch part 1: recognize date&time types as text fields (rev.6) (27.05 KB, patch)
2009-11-10 19:54 PST, Kent Tamura
no flags
Recognize date&time types as text fields (rev.7) (29.64 KB, patch)
2009-11-11 02:10 PST, Kent Tamura
darin: review-
Recognize date&time types as text fields (rev.8) (29.77 KB, patch)
2009-11-13 17:30 PST, Kent Tamura
no flags
Kent Tamura
Comment 1 2009-09-07 02:06:24 PDT
Created attachment 39136 [details] Proposed patch
Eric Seidel (no email)
Comment 2 2009-09-08 09:32:52 PDT
Comment on attachment 39136 [details] Proposed patch This is a big patch to review. :( Do you know about CaseInsentiveHash? Might be the right thing to use instead of: 336 else if (equalIgnoringCase(t, "date")) 337 newType = DATE;
Kent Tamura
Comment 3 2009-09-08 17:40:27 PDT
(In reply to comment #2) > This is a big patch to review. :( Do you know about CaseInsentiveHash? Might > be the right thing to use instead of: I haven't known it. Thanks. Maybe I should move DateTime class to separated .h and .cpp. The class is going to have more methods in the near future.
Kent Tamura
Comment 4 2009-09-10 03:25:16 PDT
(In reply to comment #2) I'll split the patch into 3. Part 1: Implement date&time types as text fields without type validation Part 2: ISO 8601 parser Part 3: ValidityState.typeCheck for date&time types, and tests
Kent Tamura
Comment 5 2009-09-10 05:14:58 PDT
Created attachment 39342 [details] Patch part 1: recognize date&time types as text fields
Kent Tamura
Comment 6 2009-09-10 05:15:57 PDT
Created attachment 39343 [details] Patch part2: ISO 8601 parser
Kent Tamura
Comment 7 2009-09-10 05:16:59 PDT
Created attachment 39344 [details] Patch part 3: support for ValidityState.typeMismatch and layout tests
Kent Tamura
Comment 8 2009-09-13 18:50:34 PDT
Created attachment 39532 [details] 39344: Patch part 3: support for ValidityState.typeMismatch and layout tests (rev.2) Resolved a patch conflict by r48318
Kent Tamura
Comment 9 2009-09-21 09:53:50 PDT
Created attachment 39857 [details] Patch part 3: ValidityState.typeMismatch and layout tests (rev.3) resources/ -> script-tests/
Eric Seidel (no email)
Comment 10 2009-09-21 10:50:30 PDT
Comment on attachment 39342 [details] Patch part 1: recognize date&time types as text fields Explicit String construction isn't needed: String("button") the compiler will find String(char*) anyway. Why two lookups? 333 if (!t.isNull() && typeMap->contains(t)) // contains() with a null string makes crash. 334 newType = typeMap->get(t); just do one get instead of two lookups. Lets make a hash for these too: @@ const AtomicString& HTMLInputElement::formControlType() const Then you don't have a zillion DEFINE_STATIC_LOCAL calls, because the Hash can be TYPE -> AtomicString (That doesn't have to be part of this patch, but if you're in there cleaning stuff up, you should consider it. I think it will be much less code. Heck, it could even be a Vector instead of a Hash if you like.) Default is bad with switches over enums: default: 1048 return false; it's breaks the compiler's ability to tell you when you're missing cases. In this function 1028 bool HTMLInputElement::isTextField() const it seems we don't even want a switch. We just want a single if, or? Or at least we want an explicit list of the false cases if you're going to use a switch.
Eric Seidel (no email)
Comment 11 2009-09-21 10:52:39 PDT
Comment on attachment 39343 [details] Patch part2: ISO 8601 parser You wrote the parser by yourself I assume? It's no code from any other license? Also, we need tests for this parser. I think we should consider splitting it off into its own file which DateMath can use. ISO8601DateParser or some other nicer name? r- for the lack of tests.
Eric Seidel (no email)
Comment 12 2009-09-21 10:54:26 PDT
Comment on attachment 39857 [details] Patch part 3: ValidityState.typeMismatch and layout tests (rev.3) OK, here are the tests. or at least some tests. So my r- above was perhaps premature. I guess I'll still leave it r- awaiting your response to the other questions raised. I've not looked at your parser close enough to see if I had security or performance concerns, but I can look again.
Eric Seidel (no email)
Comment 13 2009-09-23 10:46:52 PDT
Comment on attachment 39857 [details] Patch part 3: ValidityState.typeMismatch and layout tests (rev.3) I think I would have used two separate methods: shoudlBeInvalid shoudlBeValid instead of check true/false. But it looks fine as is.
Kent Tamura
Comment 14 2009-09-23 19:43:26 PDT
Created attachment 40036 [details] Patch part 1: recognize date&time types as text fields (rev.2) > Explicit String construction isn't needed: > String("button") Fixed. > Why two lookups? Fixed. > Lets make a hash for these too: > @@ const AtomicString& HTMLInputElement::formControlType() const Done. I used Vector. > Default is bad with switches over enums: > default: Removed the default label and expanded the rest of types.
Kent Tamura
Comment 15 2009-09-24 02:21:32 PDT
(In reply to comment #11) > (From update of attachment 39343 [details]) > You wrote the parser by yourself I assume? It's no code from any other > license? Yes, it's my code written for WebKit. > I think we should consider splitting it off into its own file which DateMath > can use. ISO8601DateParser or some other nicer name? Do you think the new file should be in JavaScriptCore/wtf/ ? I assume so. The parser might be used by JSON.parse(), not only html/HTMLInputElement.cpp
Eric Seidel (no email)
Comment 16 2009-09-24 14:11:04 PDT
(In reply to comment #15) > Do you think the new file should be in JavaScriptCore/wtf/ ? > I assume so. The parser might be used by JSON.parse(), not only > html/HTMLInputElement.cpp I'm OK w/ either location.
Kent Tamura
Comment 17 2009-09-27 18:54:32 PDT
Created attachment 40211 [details] Patch part 1: recognize date&time types as text fields (rev.3) Resolved a conflict with today's WebKit source.
Kent Tamura
Comment 18 2009-09-28 00:36:48 PDT
Created attachment 40219 [details] Patch part 2: ISO 8601 parser (rev.2) - Move ISO 8601 parser code to wtf/ISODateParser.{cpp.h} This patch doesn't depend on Part 1. Part 1 and Part2 can be committed independently.
Kent Tamura
Comment 19 2009-09-28 01:20:50 PDT
Created attachment 40221 [details] Patch part 3: ValidityState.typeMismatch and layout tests (rev.4) Update for the Part 2 change. This patch depends on both of Part 1 and 2.
Kent Tamura
Comment 20 2009-09-28 01:39:04 PDT
(In reply to comment #19) > Created an attachment (id=40221) [details] > Patch part 1: recognize date&time types as text fields (rev.4) The attachment title was wrong. I corrected it to: Patch part 3: ValidityState.typeMismatch and layout tests (rev.4)
Kent Tamura
Comment 21 2009-10-01 18:18:02 PDT
Created attachment 40488 [details] Patch part 1: recognize date&time types as text fields (rev.4) Resolved a build failure with new "switch (inputType())" introduced by r48959.
Kent Tamura
Comment 22 2009-10-13 19:34:35 PDT
Created attachment 41146 [details] Patch part 2: ISO 8601 parser (rev.3) - Resolved conflict with r49365 on project.pbxproj
Kent Tamura
Comment 23 2009-10-13 19:38:08 PDT
Created attachment 41147 [details] Patch part 3: ValidityState.typeMismatch and layout tests (rev.5) - Resolved conflict with r49508.
Eric Seidel (no email)
Comment 24 2009-10-19 14:52:49 PDT
Comment on attachment 40488 [details] Patch part 1: recognize date&time types as text fields (rev.4) 366 // get() with unregistered names returns HTMLInputElement::TEXT. Wild. // get() with a null string makes crash. // get() with a null string causes a crash. would be better. I would probably have written: 75 if (!t.isNull()) // get() with a null string makes crash. 376 newType = typeMap->get(t); 357377 else 358378 newType = TEXT; as: if (typeMap.contains(t)) newType = typeMap.get(); else newType = TEXT; Then you don't need any fancy emptyValue either. You could do: 448 static const Vector<AtomicString>* createFormControlTypes() as just an accessor and use a static Vector<AtomicString> w/o a pointer if you like. It's OK as is, but: 452 (*types)[HTMLInputElement::BUTTON] = "button"; is slightly harder to read wiht a pointer. I think at this point, I wouldn't bother changing it though. 43 TEXT = 0, // TEXT must be 0 because it's the default type. is not needed if you change the way the hash lookup works, no? 68 static const int MAX_INPUT_TYPES = DATETIMELOCAL + 1; Could be easier as a LAST_INPUT_TYPE a the end of the enum, no? This looks great, but I think we shoudl go one more round. Thanks again!
Eric Seidel (no email)
Comment 25 2009-10-19 15:15:54 PDT
Comment on attachment 39857 [details] Patch part 3: ValidityState.typeMismatch and layout tests (rev.3) Clearing r+ on this obsolete patch.
Kent Tamura
Comment 26 2009-10-19 21:13:34 PDT
Created attachment 41478 [details] Patch part 1: recognize date&time types as text fields (rev.5)
Kent Tamura
Comment 27 2009-10-19 21:19:57 PDT
(In reply to comment #24) > // get() with a null string causes a crash. > would be better. Done. > I would probably have written: > 75 if (!t.isNull()) // get() with a null string makes crash. > 376 newType = typeMap->get(t); > 357377 else > 358378 newType = TEXT; > > as: > > if (typeMap.contains(t)) > newType = typeMap.get(); > else > newType = TEXT; > > Then you don't need any fancy emptyValue either. Right. We don't need to assume TEXT=0 if we use contains(). I changed to contains(), but we still need t.isNull() because contains() with a null string also crashes. > You could do: > 448 static const Vector<AtomicString>* createFormControlTypes() I changed the type to HashMap<InputType, AtomicString>. As for Vector<>, we need to ensure the minimum value of InputType is 0, need to know the maximum value of InputType, InputType values must not have gaps. > 43 TEXT = 0, // TEXT must be 0 because it's the default type. > 68 static const int MAX_INPUT_TYPES = DATETIMELOCAL + 1; Removed them by the Vector -> HashMap change above.
Kent Tamura
Comment 28 2009-11-08 22:42:58 PST
Comment on attachment 41146 [details] Patch part 2: ISO 8601 parser (rev.3) Recent changes to DateMath.* critically broke this patch.
Kent Tamura
Comment 29 2009-11-09 01:36:20 PST
Created attachment 42740 [details] Patch part 2: ISO 8601 parser (rev.4) Move the code from JavaScritpCore/wtf to WebCore/html because GregorianDateTime became a JSC-specific class.
Kent Tamura
Comment 30 2009-11-09 01:38:03 PST
Created attachment 42741 [details] Patch part 3: ValidityState.typeMismatch and layout tests (rev.6) Sync with the updated part 2.
Eric Seidel (no email)
Comment 31 2009-11-10 10:22:34 PST
Comment on attachment 41478 [details] Patch part 1: recognize date&time types as text fields (rev.5) It seems your test case only needs to test the casing once. once it's confirmed that button and BUTTON both map to BUTTON, you don't really need to check CHECKBOX, COLOR, EMail, etc. Just the lowercase versions should be enough and might make the test less confusing. Cleanup of these mthods could have been done as a separate first patch, but this is OK too. I suspect the dom spec says nothing about the implementation, but it does say that input.type has to be lowercase, right? Would be more clear to say something like: // input.type must return a lower case value according to DOM3. I dont understand this comment: // We don't use formControlTypes->get(inputType()) because this function 542 // tries to return a reference to a temporary AtomicString object in that 543 // case. This comment isn't clear: 509 // Needs to be lowercase according to DOM spec Excellent cleanup! 794 if (inputType() == HIDDEN) 795 return false; 796 return HTMLFormControlElementWithState::rendererIsNeeded(style); This patch looks fine. The comments could/should be adjusted before landing. I'm torn. I would like to r+ this, but I would also like to understand the formControlTypes->get(inputType()) issue before I do. I guess we should go one more round. Ping me as soon as you post a new patch or respond to the formControlTypes->get(inputType()) issue and I'll be happy to r+ this.
Eric Seidel (no email)
Comment 32 2009-11-10 10:25:12 PST
Comment on attachment 42740 [details] Patch part 2: ISO 8601 parser (rev.4) This patch desperately needs c++ unit test support. So sad that we don't have any in WebKit.
Kent Tamura
Comment 33 2009-11-10 19:54:43 PST
Created attachment 42918 [details] Patch part 1: recognize date&time types as text fields (rev.6) (In reply to comment #31) > It seems your test case only needs to test the casing once. once it's > confirmed that button and BUTTON both map to BUTTON, you don't really need to > check CHECKBOX, COLOR, EMail, etc. Just the lowercase versions should be > enough and might make the test less confusing. Done. > I suspect the dom spec says nothing about the implementation, but it does say > that input.type has to be lowercase, right? Would be more clear to say > something like: > // input.type must return a lower case value according to DOM3. Done. > I dont understand this comment: > // We don't use formControlTypes->get(inputType()) because this function > 542 // tries to return a reference to a temporary AtomicString object in > that > 543 // case. I updated that comment. I hope it get clearer. If we write "return formControlTypes->get(inputType());", gcc in Xcode warns it: WebKit/WebCore/html/HTMLInputElement.cpp:547: warning: returning reference to temporary > This comment isn't clear: > 509 // Needs to be lowercase according to DOM spec Improved.
Kent Tamura
Comment 34 2009-11-11 02:10:59 PST
Created attachment 42942 [details] Recognize date&time types as text fields (rev.7) * Sort case labels as per levin's advice
Kent Tamura
Comment 35 2009-11-11 02:51:43 PST
Part 2 and 3 patches were moved to Bug#31340 and Bug#31342.
David Levin
Comment 36 2009-11-11 19:33:50 PST
I'm working on reviewing this.
David Levin
Comment 37 2009-11-11 19:35:14 PST
Whoops.I'm not reviewing this patch at present. The changelog of the issue I'm reviewing mentions the wrong bug :( (I'll add that to my comments.)
Darin Adler
Comment 38 2009-11-13 09:39:27 PST
Comment on attachment 42942 [details] Recognize date&time types as text fields (rev.7) > + // get() or contains() with a null string causes a crash. > + if (!t.isNull() && typeMap->contains(t)) > + newType = typeMap->get(t); > else > newType = TEXT; It's not a good idiom for performance to do a contains followed by a separate get. Those are two completely separate hash table lookups. There are two alternatives: 1) Just call get without first checking contains. The result will be the default value, 0, which is TEXT. 2) Use find instead of contains/get. I think "causes a crash" is also not the perfect way to explain the issue. Callers are not allowed to call get or contains with a null string. It's not guaranteed to cause a crash, though! I also think the comment is a little strange because there are tons of call sites for this and I don't think we want to add a comment like this at every one. > + // The values in the map must be lowercased because they will be the > + // return values of input.type and it must be lowercase according to DOM Level 2. > + types->add(HTMLInputElement::BUTTON, "button"); > + types->add(HTMLInputElement::CHECKBOX, "checkbox"); > + types->add(HTMLInputElement::COLOR, "color"); > + types->add(HTMLInputElement::DATE, "date"); > + types->add(HTMLInputElement::DATETIME, "datetime"); > + types->add(HTMLInputElement::DATETIMELOCAL, "datetime-local"); > + types->add(HTMLInputElement::EMAIL, "email"); > + types->add(HTMLInputElement::FILE, "file"); > + types->add(HTMLInputElement::HIDDEN, "hidden"); > + types->add(HTMLInputElement::IMAGE, "image"); > + types->add(HTMLInputElement::ISINDEX, emptyAtom); > + types->add(HTMLInputElement::MONTH, "month"); > + types->add(HTMLInputElement::NUMBER, "number"); > + types->add(HTMLInputElement::PASSWORD, "password"); > + types->add(HTMLInputElement::RADIO, "radio"); > + types->add(HTMLInputElement::RANGE, "range"); > + types->add(HTMLInputElement::RESET, "reset"); > + types->add(HTMLInputElement::SEARCH, "search"); > + types->add(HTMLInputElement::SUBMIT, "submit"); > + types->add(HTMLInputElement::TELEPHONE, "tel"); > + types->add(HTMLInputElement::TEXT, "text"); > + types->add(HTMLInputElement::TIME, "time"); > + types->add(HTMLInputElement::URL, "url"); > + types->add(HTMLInputElement::WEEK, "week"); These values are enum values, consecutive integers. This should be done with an array, not a HashMap. > + static const FormControlMap* formControlTypes = createFormControlTypes(); > + ASSERT(formControlTypes->contains(inputType())); > + // Don't do "return formControlTypes->get(inputType())" here. > + // In that case, compilers generate code like: > + // AtomicString str = formControlTypes->get(inputType()); > + // return &str; > + return formControlTypes->find(inputType())->second; I don’t really like the comment above but it will be gone if you switch to an array anyway. > bool HTMLInputElement::rendererIsNeeded(RenderStyle *style) > { > - switch (inputType()) { > - case BUTTON: > - case CHECKBOX: > - case COLOR: > - case EMAIL: > - case FILE: > - case IMAGE: > - case ISINDEX: > - case NUMBER: > - case PASSWORD: > - case RADIO: > - case RANGE: > - case RESET: > - case SEARCH: > - case SUBMIT: > - case TELEPHONE: > - case TEXT: > - case URL: > - return HTMLFormControlElementWithState::rendererIsNeeded(style); > - case HIDDEN: > - return false; > - } > - ASSERT(false); > - return false; > + if (inputType() == HIDDEN) > + return false; > + return HTMLFormControlElementWithState::rendererIsNeeded(style); This change is fine assuming that no future type will be like "hidden". I guess that's a reasonable assumption. The patch otherwise seems OK.
Kent Tamura
Comment 39 2009-11-13 17:30:04 PST
Created attachment 43216 [details] Recognize date&time types as text fields (rev.8) Thank you for reviewing! (In reply to comment #38) > > + if (!t.isNull() && typeMap->contains(t)) > > + newType = typeMap->get(t); > > else > > newType = TEXT; > > It's not a good idiom for performance to do a contains followed by a separate > get. Those are two completely separate hash table lookups. There are two > alternatives: > > 1) Just call get without first checking contains. The result will be the > default value, 0, which is TEXT Done. > I also think the comment is a little strange because there are tons of call > sites for this and I don't think we want to add a comment like this at every > one. Removed the comment. > > + types->add(HTMLInputElement::URL, "url"); > > + types->add(HTMLInputElement::WEEK, "week"); > > These values are enum values, consecutive integers. This should be done with an > array, not a HashMap. Changed it to AtomicString[].
WebKit Commit Bot
Comment 40 2009-11-13 18:13:47 PST
Comment on attachment 43216 [details] Recognize date&time types as text fields (rev.8) Rejecting patch 43216 from commit-queue. Failed to run "['WebKitTools/Scripts/run-webkit-tests', '--no-launch-safari', '--quiet', '--exit-after-n-failures=1']" exit_code: 1 Running build-dumprendertree Running tests from /Users/eseidel/Projects/CommitQueue/LayoutTests Testing 11624 test cases. http/tests/xmlhttprequest/abort-crash.html -> crashed Exiting early after 1 failures. 9148 tests run. 346.71s total testing time 9147 test cases (99%) succeeded 1 test case (<1%) crashed 5 test cases (<1%) had stderr output
Eric Seidel (no email)
Comment 41 2009-11-13 18:20:31 PST
Comment on attachment 43216 [details] Recognize date&time types as text fields (rev.8) I may just need to turn off the commit-queue until bug 31461 is solved. :(
Kent Tamura
Comment 42 2009-11-13 20:16:17 PST
Comment on attachment 43216 [details] Recognize date&time types as text fields (rev.8) Rejecting patch 43216 from commit-queue. Failed to run "['/Users/tkent/WebKit/WebKitTools/Scripts/svn-apply', '--reviewer', 'Darin Adler']" exit_code: 255 Last 500 characters of output: ++++--------- WebCore/html/HTMLInputElement.h | 16 +- 7 files changed, 403 insertions(+), 184 deletions(-) create mode 100644 LayoutTests/fast/forms/input-type-change3-expected.txt create mode 100644 LayoutTests/fast/forms/input-type-change3.html create mode 100644 LayoutTests/fast/forms/script-tests/input-type-change3.js ------------------------------------------------------------------- Died at /Users/tkent/WebKit/WebKitTools/Scripts/svn-apply line 339, <> line 953.
Kent Tamura
Comment 43 2009-11-13 21:13:25 PST
Comment on attachment 43216 [details] Recognize date&time types as text fields (rev.8) Rejecting patch 43216 from commit-queue. Failed to run "['/Users/tkent/WebKit/WebKitTools/Scripts/svn-apply', '--reviewer', 'Darin Adler']" exit_code: 255 Last 500 characters of output: ++++--------- WebCore/html/HTMLInputElement.h | 16 +- 7 files changed, 403 insertions(+), 184 deletions(-) create mode 100644 LayoutTests/fast/forms/input-type-change3-expected.txt create mode 100644 LayoutTests/fast/forms/input-type-change3.html create mode 100644 LayoutTests/fast/forms/script-tests/input-type-change3.js ------------------------------------------------------------------- Died at /Users/tkent/WebKit/WebKitTools/Scripts/svn-apply line 339, <> line 953.
Kent Tamura
Comment 44 2009-11-14 07:22:57 PST
Comment on attachment 43216 [details] Recognize date&time types as text fields (rev.8) Manually committed as r50996.
Note You need to log in before you can comment on or make changes to this bug.