Changeset 136111 in webkit
- Timestamp:
- Nov 29, 2012, 1:15:57 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 14 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt (modified) (2 diffs)
-
LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events.html (modified) (1 diff)
-
Source/WebCore/CMakeLists.txt (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/GNUmakefile.list.am (modified) (1 diff)
-
Source/WebCore/Target.pri (modified) (2 diffs)
-
Source/WebCore/WebCore.gypi (modified) (1 diff)
-
Source/WebCore/WebCore.vcproj/WebCore.vcproj (modified) (1 diff)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (5 diffs)
-
Source/WebCore/html/HTMLSelectElement.cpp (modified) (2 diffs)
-
Source/WebCore/html/HTMLSelectElement.h (modified) (4 diffs)
-
Source/WebCore/html/TypeAhead.cpp (added)
-
Source/WebCore/html/TypeAhead.h (added)
-
Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp (modified) (3 diffs)
-
Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r136110 r136111 1 2012-11-29 Keishi Hattori <keishi@webkit.org> 2 3 Better type ahead for DateTimeSymbolicFieldElement 4 https://bugs.webkit.org/show_bug.cgi?id=103031 5 6 Reviewed by Kent Tamura. 7 8 * fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt: 9 * fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events.html: Added tests for typeahead. 10 1 11 2012-11-29 Kent Tamura <tkent@chromium.org> 2 12 -
trunk/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events-expected.txt
r131898 r136111 16 16 FAIL input.value should be 0012-09. Was 0112-09. 17 17 == Left/Right keys == 18 FAIL input.value should be 0005-06. Was 0005-09. 18 PASS input.value is "0005-06" 19 19 PASS document.activeElement.id is "input" 20 20 == Up/Down keys == … … 50 50 PASS input.value is "0001-12" 51 51 PASS input.value is "0002-12" 52 == Typeahead cycle first character == 53 PASS input.value is "2012-01" 54 PASS input.value is "2012-06" 55 PASS input.value is "2012-07" 56 PASS input.value is "2012-01" 57 PASS input.value is "2012-01" 58 == Typeahead prefix match == 59 PASS input.value is "2012-03" 60 PASS input.value is "2012-03" 61 PASS input.value is "2012-05" 62 PASS input.value is "2012-05" 63 == Typeahead index match == 64 PASS input.value is "2012-01" 65 PASS input.value is "2012-12" 66 PASS input.value is "2012-12" 67 == Typeahead should search from current selection == 68 PASS input.value is "2012-06" 52 69 == RTL Left/Right keys == 53 70 PASS input.value is "2012-10" -
trunk/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-keyboard-events.html
r131898 r136111 172 172 shouldBeEqualToString('input.value', '0002-12'); 173 173 174 beginTest('Typeahead cycle first character', '2012-09'); 175 keyDown('j'); // -> [Jan] 2012 176 shouldBeEqualToString('input.value', '2012-01'); 177 keyDown('j'); // -> [Jun] 2012 178 shouldBeEqualToString('input.value', '2012-06'); 179 keyDown('j'); // -> [Jul] 2012 180 shouldBeEqualToString('input.value', '2012-07'); 181 keyDown('j'); // -> [Jan] 2012 182 shouldBeEqualToString('input.value', '2012-01'); 183 keyDown('x'); // -> [Jan] 2012 184 shouldBeEqualToString('input.value', '2012-01'); 185 186 beginTest('Typeahead prefix match', '2012-09'); 187 keyDown('m'); // -> [Mar] 2012 188 shouldBeEqualToString('input.value', '2012-03'); 189 keyDown('a'); // -> [Mar] 2012 190 shouldBeEqualToString('input.value', '2012-03'); 191 keyDown('y'); // -> [May] 2012 192 shouldBeEqualToString('input.value', '2012-05'); 193 keyDown('x'); // -> [May] 2012 194 shouldBeEqualToString('input.value', '2012-05'); 195 196 beginTest('Typeahead index match', '2012-09'); 197 keyDown('1'); // -> [Jan] 2012 198 shouldBeEqualToString('input.value', '2012-01'); 199 keyDown('2'); // -> [Dec] 2012 200 shouldBeEqualToString('input.value', '2012-12'); 201 keyDown('x'); // -> [Dec] 2012 202 shouldBeEqualToString('input.value', '2012-12'); 203 204 beginTest('Typeahead should search from current selection', '2012-01'); 205 keyDown('j'); // -> [Jun] 2012 206 shouldBeEqualToString('input.value', '2012-06'); 207 174 208 // The tests in the following block fail on platforms without the 175 209 // lang-attribute-aware-form-control-UI feature. -
trunk/Source/WebCore/CMakeLists.txt
r136063 r136111 1468 1468 html/TimeInputType.cpp 1469 1469 html/TimeRanges.cpp 1470 html/TypeAhead.cpp 1470 1471 html/URLInputType.cpp 1471 1472 html/ValidationMessage.cpp -
trunk/Source/WebCore/ChangeLog
r136107 r136111 1 2012-11-29 Keishi Hattori <keishi@webkit.org> 2 3 Better type ahead for DateTimeSymbolicFieldElement 4 https://bugs.webkit.org/show_bug.cgi?id=103031 5 6 Reviewed by Kent Tamura. 7 8 This cuts out the type ahead code that will be used by HTMLSelectElement 9 and DateTimeSymbolicFieldElement into a TypeAhead class. This will 10 improve DateTimeSymbolicFieldElement type ahead which was first 11 character match only, by adding cycling, prefix match and index number 12 match. 13 14 Added tests to month-multiple-fields-keyboard-events.html. 15 16 * GNUmakefile.list.am: Added TypeAhead.{h,cpp} 17 * Target.pri: Ditto. 18 * WebCore.gypi: Ditto. 19 * WebCore.vcproj/WebCore.vcproj: Ditto. 20 * WebCore.xcodeproj/project.pbxproj: Ditto. 21 * CMakeLists.txt: Ditto. 22 * html/HTMLSelectElement.cpp: 23 (WebCore): 24 (WebCore::HTMLSelectElement::HTMLSelectElement): 25 (WebCore::HTMLSelectElement::indexOfSelectedOption): Returns index of current selection. 26 (WebCore::HTMLSelectElement::optionCount): Returns total number of options. 27 (WebCore::HTMLSelectElement::optionAtIndex): Returns option at index. 28 (WebCore::HTMLSelectElement::typeAheadFind): Use TypeAhead. 29 * html/HTMLSelectElement.h: 30 (HTMLSelectElement): 31 * html/TypeAhead.cpp: Added. 32 (WebCore): 33 (WebCore::TypeAhead::TypeAhead): 34 (WebCore::stripLeadingWhiteSpace): Moved from HTMLSelectElement.cpp. 35 (WebCore::TypeAhead::handleEvent): Returns index for match. 36 * html/TypeAhead.h: Added. 37 (WebCore): 38 (TypeAheadDataSource): Provide the data about the options that TypeAhead should match against. 39 (TypeAhead): 40 * html/shadow/DateTimeSymbolicFieldElement.cpp: 41 (WebCore::DateTimeSymbolicFieldElement::DateTimeSymbolicFieldElement): 42 (WebCore::DateTimeSymbolicFieldElement::handleKeyboardEvent): 43 (WebCore::DateTimeSymbolicFieldElement::indexOfSelectedOption): 44 (WebCore): 45 (WebCore::DateTimeSymbolicFieldElement::optionCount): 46 (WebCore::DateTimeSymbolicFieldElement::optionAtIndex): 47 * html/shadow/DateTimeSymbolicFieldElement.h: 48 (DateTimeSymbolicFieldElement): 49 1 50 2012-11-29 Andrei Bucur <abucur@adobe.com> 2 51 -
trunk/Source/WebCore/GNUmakefile.list.am
r136063 r136111 3626 3626 Source/WebCore/html/track/WebVTTTokenizer.h \ 3627 3627 Source/WebCore/html/track/WebVTTTokenizer.cpp \ 3628 Source/WebCore/html/TypeAhead.cpp \ 3629 Source/WebCore/html/TypeAhead.h \ 3628 3630 Source/WebCore/html/URLInputType.cpp \ 3629 3631 Source/WebCore/html/URLInputType.h \ -
trunk/Source/WebCore/Target.pri
r135952 r136111 691 691 html/TextInputType.cpp \ 692 692 html/TimeInputType.cpp \ 693 html/TypeAhead.cpp \ 693 694 html/URLInputType.cpp \ 694 695 html/ValidationMessage.cpp \ … … 1845 1846 html/TextDocument.h \ 1846 1847 html/TimeRanges.h \ 1848 html/TypeAhead.h \ 1847 1849 html/ValidityState.h \ 1848 1850 html/parser/CSSPreloadScanner.h \ -
trunk/Source/WebCore/WebCore.gypi
r136063 r136111 4266 4266 'html/WeekInputType.cpp', 4267 4267 'html/WeekInputType.h', 4268 'html/TypeAhead.cpp', 4269 'html/TypeAhead.h', 4268 4270 'html/canvas/CanvasContextAttributes.cpp', 4269 4271 'html/canvas/CanvasContextAttributes.h', -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r135952 r136111 63990 63990 > 63991 63991 </File> 63992 <File 63993 RelativePath="..\html\TypeAhead.cpp" 63994 > 63995 </File> 63996 <File 63997 RelativePath="..\html\TypeAhead.h" 63998 > 63999 </File> 63992 64000 <File 63993 64001 RelativePath="..\html\URLInputType.cpp" -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r135952 r136111 5832 5832 C348612315FDE21E007A1CC9 /* InputTypeNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C348612115FDE21E007A1CC9 /* InputTypeNames.cpp */; }; 5833 5833 C348612415FDE21E007A1CC9 /* InputTypeNames.h in Headers */ = {isa = PBXBuildFile; fileRef = C348612215FDE21E007A1CC9 /* InputTypeNames.h */; }; 5834 C375D7FD16639519006184AB /* TypeAhead.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C375D7FB16639519006184AB /* TypeAhead.cpp */; }; 5835 C375D7FE16639519006184AB /* TypeAhead.h in Headers */ = {isa = PBXBuildFile; fileRef = C375D7FC16639519006184AB /* TypeAhead.h */; }; 5834 5836 C37CDEBD149EF2030042090D /* ColorChooserClient.h in Headers */ = {isa = PBXBuildFile; fileRef = C37CDEBC149EF2030042090D /* ColorChooserClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5835 5837 C3CF17A415B0063F00276D39 /* IdTargetObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3CF17A015B0063F00276D39 /* IdTargetObserver.cpp */; }; … … 13240 13242 C348612115FDE21E007A1CC9 /* InputTypeNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputTypeNames.cpp; sourceTree = "<group>"; }; 13241 13243 C348612215FDE21E007A1CC9 /* InputTypeNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputTypeNames.h; sourceTree = "<group>"; }; 13244 C375D7FB16639519006184AB /* TypeAhead.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeAhead.cpp; sourceTree = "<group>"; }; 13245 C375D7FC16639519006184AB /* TypeAhead.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeAhead.h; sourceTree = "<group>"; }; 13242 13246 C37CDEBC149EF2030042090D /* ColorChooserClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorChooserClient.h; sourceTree = "<group>"; }; 13243 13247 C3CF17A015B0063F00276D39 /* IdTargetObserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IdTargetObserver.cpp; sourceTree = "<group>"; }; … … 17893 17897 E446139E0CD6331000FADA75 /* TimeRanges.h */, 17894 17898 E446139F0CD6331000FADA75 /* TimeRanges.idl */, 17899 C375D7FB16639519006184AB /* TypeAhead.cpp */, 17900 C375D7FC16639519006184AB /* TypeAhead.h */, 17895 17901 F55B3DA91251F12D003EF269 /* URLInputType.cpp */, 17896 17902 F55B3DAA1251F12D003EF269 /* URLInputType.h */, … … 25837 25843 31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */, 25838 25844 15B8B7C91652C5220036EF55 /* JSWebKitCSSMixFunctionValue.h in Headers */, 25845 C375D7FE16639519006184AB /* TypeAhead.h in Headers */, 25839 25846 ); 25840 25847 runOnlyForDeploymentPostprocessing = 0; … … 28940 28947 15B8B7C81652C5220036EF55 /* JSWebKitCSSMixFunctionValue.cpp in Sources */, 28941 28948 86BA766E166427A8005BE5D1 /* FrameLoadRequest.cpp in Sources */, 28949 C375D7FD16639519006184AB /* TypeAhead.cpp in Sources */, 28942 28950 ); 28943 28951 runOnlyForDeploymentPostprocessing = 0; -
trunk/Source/WebCore/html/HTMLSelectElement.cpp
r135690 r136111 65 65 static const unsigned maxSelectItems = 10000; 66 66 67 static const DOMTimeStamp typeAheadTimeout = 1000;68 69 67 HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) 70 68 : HTMLFormControlElementWithState(tagName, document, form) 71 , m_ lastCharTime(0)69 , m_typeAhead(this) 72 70 , m_size(0) 73 71 , m_lastOnChangeIndex(-1) 74 72 , m_activeSelectionAnchorIndex(-1) 75 73 , m_activeSelectionEndIndex(-1) 76 , m_repeatingChar(0)77 74 , m_isProcessingUserDrivenChange(false) 78 75 , m_multiple(false) … … 1475 1472 } 1476 1473 1477 static String stripLeadingWhiteSpace(const String& string) 1478 { 1479 int length = string.length(); 1480 1481 int i; 1482 for (i = 0; i < length; ++i) { 1483 if (string[i] != noBreakSpace && (string[i] <= 0x7F ? !isASCIISpace(string[i]) : (direction(string[i]) != WhiteSpaceNeutral))) 1484 break; 1485 } 1486 1487 return string.substring(i, length - i); 1474 int HTMLSelectElement::indexOfSelectedOption() const 1475 { 1476 return optionToListIndex(selectedIndex()); 1477 } 1478 1479 int HTMLSelectElement::optionCount() const 1480 { 1481 return listItems().size(); 1482 } 1483 1484 String HTMLSelectElement::optionAtIndex(int index) const 1485 { 1486 const Vector<HTMLElement*>& items = listItems(); 1487 1488 HTMLElement* element = items[index]; 1489 if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->disabled()) 1490 return String(); 1491 return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); 1488 1492 } 1489 1493 1490 1494 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) 1491 1495 { 1492 if (event->timeStamp() < m_lastCharTime) 1493 return; 1494 1495 DOMTimeStamp delta = event->timeStamp() - m_lastCharTime; 1496 m_lastCharTime = event->timeStamp(); 1497 1498 UChar c = event->charCode(); 1499 1500 String prefix; 1501 int searchStartOffset = 1; 1502 if (delta > typeAheadTimeout) { 1503 prefix = String(&c, 1); 1504 m_typedString = prefix; 1505 m_repeatingChar = c; 1506 } else { 1507 m_typedString.append(c); 1508 1509 if (c == m_repeatingChar) { 1510 // The user is likely trying to cycle through all the items starting 1511 // with this character, so just search on the character. 1512 prefix = String(&c, 1); 1513 } else { 1514 m_repeatingChar = 0; 1515 prefix = m_typedString; 1516 searchStartOffset = 0; 1517 } 1518 } 1519 1520 const Vector<HTMLElement*>& items = listItems(); 1521 int itemCount = items.size(); 1522 if (itemCount < 1) 1523 return; 1524 1525 int selected = selectedIndex(); 1526 int index = optionToListIndex(selected >= 0 ? selected : 0) + searchStartOffset; 1496 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar); 1527 1497 if (index < 0) 1528 1498 return; 1529 index %= itemCount; 1530 1531 // Compute a case-folded copy of the prefix string before beginning the search for 1532 // a matching element. This code uses foldCase to work around the fact that 1533 // String::startWith does not fold non-ASCII characters. This code can be changed 1534 // to use startWith once that is fixed. 1535 String prefixWithCaseFolded(prefix.foldCase()); 1536 for (int i = 0; i < itemCount; ++i, index = (index + 1) % itemCount) { 1537 HTMLElement* element = items[index]; 1538 if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->disabled()) 1539 continue; 1540 1541 // Fold the option string and check if its prefix is equal to the folded prefix. 1542 String text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); 1543 if (stripLeadingWhiteSpace(text).foldCase().startsWith(prefixWithCaseFolded)) { 1544 selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchChangeEvent | UserDriven); 1545 if (!usesMenuList()) 1546 listBoxOnChange(); 1547 1548 setOptionsChangedOnRenderer(); 1549 setNeedsStyleRecalc(); 1550 return; 1551 } 1552 } 1499 selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchChangeEvent | UserDriven); 1500 if (!usesMenuList()) 1501 listBoxOnChange(); 1553 1502 } 1554 1503 -
trunk/Source/WebCore/html/HTMLSelectElement.h
r135069 r136111 30 30 #include "HTMLFormControlElementWithState.h" 31 31 #include "HTMLOptionsCollection.h" 32 #include "TypeAhead.h" 32 33 #include <wtf/Vector.h> 33 34 … … 36 37 class HTMLOptionElement; 37 38 38 class HTMLSelectElement : public HTMLFormControlElementWithState {39 class HTMLSelectElement : public HTMLFormControlElementWithState, public TypeAheadDataSource { 39 40 public: 40 41 static PassRefPtr<HTMLSelectElement> create(const QualifiedName&, Document*, HTMLFormElement*); … … 104 105 // For use in the implementation of HTMLOptionElement. 105 106 void optionSelectionStateChanged(HTMLOptionElement*, bool optionIsSelected); 106 107 107 108 protected: 108 109 HTMLSelectElement(const QualifiedName&, Document*, HTMLFormElement*); … … 182 183 virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; } 183 184 185 // TypeAheadDataSource functions. 186 virtual int indexOfSelectedOption() const OVERRIDE; 187 virtual int optionCount() const OVERRIDE; 188 virtual String optionAtIndex(int index) const OVERRIDE; 189 184 190 // m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and HTMLHRElement objects. 185 191 mutable Vector<HTMLElement*> m_listItems; 186 192 Vector<bool> m_lastOnChangeSelection; 187 193 Vector<bool> m_cachedStateForActiveSelection; 188 DOMTimeStamp m_lastCharTime; 189 String m_typedString; 194 TypeAhead m_typeAhead; 190 195 int m_size; 191 196 int m_lastOnChangeIndex; 192 197 int m_activeSelectionAnchorIndex; 193 198 int m_activeSelectionEndIndex; 194 UChar m_repeatingChar;195 199 bool m_isProcessingUserDrivenChange; 196 200 bool m_multiple; -
trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp
r134239 r136111 56 56 , m_visibleEmptyValue(makeVisibleEmptyValue(symbols)) 57 57 , m_selectedIndex(-1) 58 , m_typeAhead(this) 58 59 { 59 60 ASSERT(!symbols.isEmpty()); … … 83 84 84 85 keyboardEvent->setDefaultHandled(); 85 for (unsigned index = 0; index < m_symbols.size(); ++index) { 86 if (!m_symbols[index].isEmpty() && WTF::Unicode::toLower(m_symbols[index][0]) == charCode) { 87 setValueAsInteger(index, DispatchEvent); 88 return; 89 } 90 } 86 87 int index = m_typeAhead.handleEvent(keyboardEvent, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar | TypeAhead::MatchIndex); 88 if (index < 0) 89 return; 90 setValueAsInteger(index, DispatchEvent); 91 91 } 92 92 … … 151 151 } 152 152 153 int DateTimeSymbolicFieldElement::indexOfSelectedOption() const 154 { 155 return m_selectedIndex; 156 } 157 158 int DateTimeSymbolicFieldElement::optionCount() const 159 { 160 return m_symbols.size(); 161 } 162 163 String DateTimeSymbolicFieldElement::optionAtIndex(int index) const 164 { 165 return m_symbols[index]; 166 } 167 153 168 } // namespace WebCore 154 169 -
trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h
r134239 r136111 29 29 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI) 30 30 #include "DateTimeFieldElement.h" 31 #include "TypeAhead.h" 31 32 32 33 namespace WebCore { … … 34 35 // DateTimeSymbolicFieldElement represents non-numeric field of data time 35 36 // format, such as: AM/PM, and month. 36 class DateTimeSymbolicFieldElement : public DateTimeFieldElement {37 class DateTimeSymbolicFieldElement : public DateTimeFieldElement, public TypeAheadDataSource { 37 38 WTF_MAKE_NONCOPYABLE(DateTimeSymbolicFieldElement); 38 39 … … 60 61 virtual String visibleValue() const OVERRIDE FINAL; 61 62 63 // TypeAheadDataSource functions. 64 virtual int indexOfSelectedOption() const OVERRIDE; 65 virtual int optionCount() const OVERRIDE; 66 virtual String optionAtIndex(int index) const OVERRIDE; 67 62 68 const Vector<String> m_symbols; 63 69 … … 66 72 const AtomicString m_visibleEmptyValue; 67 73 int m_selectedIndex; 74 TypeAhead m_typeAhead; 68 75 }; 69 76
Note:
See TracChangeset
for help on using the changeset viewer.