diff options
Diffstat (limited to 'WebCore/html/HTMLSelectElement.cpp')
-rw-r--r-- | WebCore/html/HTMLSelectElement.cpp | 75 |
1 files changed, 51 insertions, 24 deletions
diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp index 115e473..44e7fe4 100644 --- a/WebCore/html/HTMLSelectElement.cpp +++ b/WebCore/html/HTMLSelectElement.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "HTMLSelectElement.h" +#include "AXObjectCache.h" #include "CSSPropertyNames.h" #include "CSSStyleSelector.h" #include "CharacterNames.h" @@ -57,7 +58,6 @@ using namespace Unicode; namespace WebCore { -using namespace EventNames; using namespace HTMLNames; static const DOMTimeStamp typeAheadTimeout = 1000; @@ -301,17 +301,17 @@ void HTMLSelectElement::restoreState(const String& state) setChanged(); } -bool HTMLSelectElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec) +bool HTMLSelectElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach) { - bool result = HTMLFormControlElementWithState::insertBefore(newChild, refChild, ec); + bool result = HTMLFormControlElementWithState::insertBefore(newChild, refChild, ec, shouldLazyAttach); if (result) setRecalcListItems(); return result; } -bool HTMLSelectElement::replaceChild(PassRefPtr<Node> newChild, Node *oldChild, ExceptionCode& ec) +bool HTMLSelectElement::replaceChild(PassRefPtr<Node> newChild, Node *oldChild, ExceptionCode& ec, bool shouldLazyAttach) { - bool result = HTMLFormControlElementWithState::replaceChild(newChild, oldChild, ec); + bool result = HTMLFormControlElementWithState::replaceChild(newChild, oldChild, ec, shouldLazyAttach); if (result) setRecalcListItems(); return result; @@ -325,9 +325,9 @@ bool HTMLSelectElement::removeChild(Node* oldChild, ExceptionCode& ec) return result; } -bool HTMLSelectElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec) +bool HTMLSelectElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach) { - bool result = HTMLFormControlElementWithState::appendChild(newChild, ec); + bool result = HTMLFormControlElementWithState::appendChild(newChild, ec, shouldLazyAttach); if (result) setRecalcListItems(); return result; @@ -373,11 +373,11 @@ void HTMLSelectElement::parseMappedAttribute(MappedAttribute *attr) // Don't map 'align' attribute. This matches what Firefox, Opera and IE do. // See http://bugs.webkit.org/show_bug.cgi?id=12072 } else if (attr->name() == onfocusAttr) { - setHTMLEventListener(focusEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr); } else if (attr->name() == onblurAttr) { - setHTMLEventListener(blurEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr); } else if (attr->name() == onchangeAttr) { - setHTMLEventListener(changeEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().changeEvent, attr); } else HTMLFormControlElementWithState::parseMappedAttribute(attr); } @@ -491,7 +491,7 @@ int HTMLSelectElement::listToOptionIndex(int listIndex) const PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options() { - return new HTMLOptionsCollection(this); + return HTMLOptionsCollection::create(this); } void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const @@ -529,10 +529,13 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const m_recalcListItems = false; } -void HTMLSelectElement::childrenChanged(bool changedByParser) +void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { setRecalcListItems(); - HTMLFormControlElementWithState::childrenChanged(changedByParser); + HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + + if (AXObjectCache::accessibilityEnabled() && renderer()) + renderer()->document()->axObjectCache()->childrenChanged(renderer()); } void HTMLSelectElement::setRecalcListItems() @@ -605,7 +608,7 @@ void HTMLSelectElement::defaultEventHandler(Event* evt) if (evt->defaultHandled()) return; - if (evt->type() == keypressEvent && evt->isKeyboardEvent()) { + if (evt->type() == eventNames().keypressEvent && evt->isKeyboardEvent()) { KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(evt); if (!keyboardEvent->ctrlKey() && !keyboardEvent->altKey() && !keyboardEvent->metaKey() && @@ -623,7 +626,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt) { RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer()); - if (evt->type() == keydownEvent) { + if (evt->type() == eventNames().keydownEvent) { if (!renderer() || !evt->isKeyboardEvent()) return; String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier(); @@ -648,7 +651,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt) int size = listItems().size(); for (listIndex += 1; listIndex >= 0 && listIndex < size && (listItems()[listIndex]->disabled() || !listItems()[listIndex]->hasTagName(optionTag)); - ++listIndex); + ++listIndex) { } if (listIndex >= 0 && listIndex < size) setSelectedIndex(listToOptionIndex(listIndex)); @@ -657,7 +660,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt) int size = listItems().size(); for (listIndex -= 1; listIndex >= 0 && listIndex < size && (listItems()[listIndex]->disabled() || !listItems()[listIndex]->hasTagName(optionTag)); - --listIndex); + --listIndex) { } if (listIndex >= 0 && listIndex < size) setSelectedIndex(listToOptionIndex(listIndex)); @@ -670,7 +673,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt) // Use key press event here since sending simulated mouse events // on key down blocks the proper sending of the key press event. - if (evt->type() == keypressEvent) { + if (evt->type() == eventNames().keypressEvent) { if (!renderer() || !evt->isKeyboardEvent()) return; int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode(); @@ -702,7 +705,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt) evt->setDefaultHandled(); } - if (evt->type() == mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) { + if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) { focus(); if (menuList->popupIsVisible()) menuList->hidePopup(); @@ -718,7 +721,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt) void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt) { - if (evt->type() == mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) { + if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) { focus(); MouseEvent* mEvt = static_cast<MouseEvent*>(evt); @@ -778,10 +781,10 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt) evt->setDefaultHandled(); } - } else if (evt->type() == mouseupEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer()) + } else if (evt->type() == eventNames().mouseupEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer()) // This makes sure we fire onChange for a single click. For drag selection, onChange will fire when the autoscroll timer stops. listBoxOnChange(); - else if (evt->type() == keydownEvent) { + else if (evt->type() == eventNames().keydownEvent) { if (!evt->isKeyboardEvent()) return; String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier(); @@ -822,7 +825,7 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt) listBoxOnChange(); evt->setDefaultHandled(); } - } else if (evt->type() == keypressEvent) { + } else if (evt->type() == eventNames().keypressEvent) { if (!evt->isKeyboardEvent()) return; int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode(); @@ -981,13 +984,17 @@ void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) if (itemCount < 1) return; - int index = (optionToListIndex(selectedIndex()) + searchStartOffset) % itemCount; + int selected = selectedIndex(); + int index = (optionToListIndex(selected >= 0 ? selected : 0) + searchStartOffset) % itemCount; + ASSERT(index >= 0); for (int i = 0; i < itemCount; i++, index = (index + 1) % itemCount) { if (!items[index]->hasTagName(optionTag) || items[index]->disabled()) continue; if (stripLeadingWhiteSpace(static_cast<HTMLOptionElement*>(items[index])->optionText()).startsWith(prefix, false)) { setSelectedIndex(listToOptionIndex(index)); + if(!usesMenuList()) + listBoxOnChange(); setChanged(); return; } @@ -1024,6 +1031,26 @@ void HTMLSelectElement::accessKeyAction(bool sendToAnyElement) dispatchSimulatedClick(0, sendToAnyElement); } +void HTMLSelectElement::accessKeySetSelectedIndex(int index) +{ + // first bring into focus the list box + if (!focused()) + accessKeyAction(false); + + // if this index is already selected, unselect. otherwise update the selected index + Node* listNode = item(index); + if (listNode && listNode->hasTagName(optionTag)) { + HTMLOptionElement* listElement = static_cast<HTMLOptionElement*>(listNode); + if (listElement->selected()) + listElement->setSelectedState(false); + else + setSelectedIndex(index, false, true); + } + + listBoxOnChange(); + scrollToSelection(); +} + void HTMLSelectElement::setMultiple(bool multiple) { setAttribute(multipleAttr, multiple ? "" : 0); |