summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html/HTMLSelectElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/HTMLSelectElement.cpp')
-rw-r--r--Source/WebCore/html/HTMLSelectElement.cpp91
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)