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