diff options
Diffstat (limited to 'Source/WebCore/html/HTMLSelectElement.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLSelectElement.cpp | 91 |
1 files changed, 20 insertions, 71 deletions
diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp index 23ac57af4..f41ee0d07 100644 --- a/Source/WebCore/html/HTMLSelectElement.cpp +++ b/Source/WebCore/html/HTMLSelectElement.cpp @@ -64,16 +64,13 @@ using namespace HTMLNames; // Upper limit agreed upon with representatives of Opera and Mozilla. static const unsigned maxSelectItems = 10000; -static const DOMTimeStamp typeAheadTimeout = 1000; - HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) : HTMLFormControlElementWithState(tagName, document, form) - , m_lastCharTime(0) + , m_typeAhead(this) , m_size(0) , m_lastOnChangeIndex(-1) , m_activeSelectionAnchorIndex(-1) , m_activeSelectionEndIndex(-1) - , m_repeatingChar(0) , m_isProcessingUserDrivenChange(false) , m_multiple(false) , m_activeSelectionState(false) @@ -1474,82 +1471,34 @@ int HTMLSelectElement::lastSelectedListIndex() const return -1; } -static String stripLeadingWhiteSpace(const String& string) +int HTMLSelectElement::indexOfSelectedOption() const { - int length = string.length(); - - int i; - for (i = 0; i < length; ++i) { - if (string[i] != noBreakSpace && (string[i] <= 0x7F ? !isASCIISpace(string[i]) : (direction(string[i]) != WhiteSpaceNeutral))) - break; - } - - return string.substring(i, length - i); + return optionToListIndex(selectedIndex()); } -void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) +int HTMLSelectElement::optionCount() const { - if (event->timeStamp() < m_lastCharTime) - return; - - DOMTimeStamp delta = event->timeStamp() - m_lastCharTime; - m_lastCharTime = event->timeStamp(); - - UChar c = event->charCode(); - - String prefix; - int searchStartOffset = 1; - if (delta > typeAheadTimeout) { - prefix = String(&c, 1); - m_typedString = prefix; - m_repeatingChar = c; - } else { - m_typedString.append(c); - - if (c == m_repeatingChar) { - // The user is likely trying to cycle through all the items starting - // with this character, so just search on the character. - prefix = String(&c, 1); - } else { - m_repeatingChar = 0; - prefix = m_typedString; - searchStartOffset = 0; - } - } + return listItems().size(); +} +String HTMLSelectElement::optionAtIndex(int index) const +{ const Vector<HTMLElement*>& items = listItems(); - int itemCount = items.size(); - if (itemCount < 1) - return; + + HTMLElement* element = items[index]; + if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->disabled()) + return String(); + return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); +} - int selected = selectedIndex(); - int index = optionToListIndex(selected >= 0 ? selected : 0) + searchStartOffset; +void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) +{ + int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar); if (index < 0) return; - index %= itemCount; - - // Compute a case-folded copy of the prefix string before beginning the search for - // a matching element. This code uses foldCase to work around the fact that - // String::startWith does not fold non-ASCII characters. This code can be changed - // to use startWith once that is fixed. - String prefixWithCaseFolded(prefix.foldCase()); - for (int i = 0; i < itemCount; ++i, index = (index + 1) % itemCount) { - HTMLElement* element = items[index]; - if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->disabled()) - continue; - - // Fold the option string and check if its prefix is equal to the folded prefix. - String text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); - if (stripLeadingWhiteSpace(text).foldCase().startsWith(prefixWithCaseFolded)) { - selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchChangeEvent | UserDriven); - if (!usesMenuList()) - listBoxOnChange(); - - setOptionsChangedOnRenderer(); - setNeedsStyleRecalc(); - return; - } - } + selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchChangeEvent | UserDriven); + if (!usesMenuList()) + listBoxOnChange(); } Node::InsertionNotificationRequest HTMLSelectElement::insertedInto(ContainerNode* insertionPoint) |