static v8::Handle<v8::Value> valueAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.value._get"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(info.Holder()); if (!R_check(imp)) return v8::Handle<v8::Value>(v8::Undefined()); return v8String(imp->value()); }
v8::Handle<v8::Value> V8HTMLSelectElement::namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.NamedPropertyGetter"); HTMLSelectElement* select = V8HTMLSelectElement::toNative(info.Holder()); v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name); if (!value.IsEmpty()) return value; // Search local callback properties next to find IDL defined properties. if (info.Holder()->HasRealNamedCallbackProperty(name)) return notHandledByInterceptor(); PassRefPtr<HTMLOptionsCollection> collection = select->options(); Vector<RefPtr<Node> > items; collection->namedItems(v8StringToAtomicWebCoreString(name), items); if (!items.size()) return notHandledByInterceptor(); if (items.size() == 1) return toV8(items.at(0).release()); NodeList* list = new V8NamedNodesCollection(items); return toV8(list); }
TEST_F(HTMLSelectElementTest, LastSelectableOption) { { document().documentElement()->setInnerHTML("<select></select>", ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); HTMLSelectElement* select = toHTMLSelectElement(document().body()->firstChild()); EXPECT_EQ(nullptr, select->lastSelectableOption()); } { document().documentElement()->setInnerHTML("<select><option id=o1></option><option id=o2></option></select>", ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); HTMLSelectElement* select = toHTMLSelectElement(document().body()->firstChild()); EXPECT_EQ("o2", select->lastSelectableOption()->fastGetAttribute(HTMLNames::idAttr)); } { document().documentElement()->setInnerHTML("<select><option id=o1></option><option id=o2 disabled></option></select>", ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); HTMLSelectElement* select = toHTMLSelectElement(document().body()->firstChild()); EXPECT_EQ("o1", select->lastSelectableOption()->fastGetAttribute(HTMLNames::idAttr)); } { document().documentElement()->setInnerHTML("<select><option id=o1></option><option id=o2 style='display:none'></option></select>", ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); HTMLSelectElement* select = toHTMLSelectElement(document().body()->firstChild()); EXPECT_EQ("o1", select->lastSelectableOption()->fastGetAttribute(HTMLNames::idAttr)); } { document().documentElement()->setInnerHTML("<select><optgroup><option id=o1></option><option id=o2></option></optgroup></select>", ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); HTMLSelectElement* select = toHTMLSelectElement(document().body()->firstChild()); EXPECT_EQ("o2", select->lastSelectableOption()->fastGetAttribute(HTMLNames::idAttr)); } }
static v8::Handle<v8::Value> namedItemCallback(const v8::Arguments& args) { INC_STATS("DOM.HTMLSelectElement.namedItem"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(args.Holder()); STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, name, args[0]); return toV8(imp->namedItem(name)); }
bool HTMLOptionElement::spatialNavigationFocused() const { HTMLSelectElement* select = ownerSelectElement(); if (!select || !select->focused()) return false; return select->spatialNavigationFocusedOption() == this; }
void AXMenuListPopup::addChildren() { ASSERT(!isDetached()); if (!m_parent) return; Node* parentNode = m_parent->node(); if (!isHTMLSelectElement(parentNode)) return; HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(parentNode); m_haveChildren = true; if (m_activeIndex == -1) m_activeIndex = getSelectedIndex(); const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = htmlSelectElement->listItems(); unsigned length = listItems.size(); for (unsigned i = 0; i < length; i++) { AXMenuListOption* option = menuListOptionAXObject(listItems[i]); if (option) { option->setParent(this); m_children.append(option); } } }
bool AXListBoxOption::isSelectedOptionActive() const { HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode(); if (!listBoxParentNode) return false; return listBoxParentNode->activeSelectionEnd() == getNode(); }
static AccessibilityObject* optionFromSelection(AtkSelection* selection, gint index) { // i is the ith selection as opposed to the ith child. AccessibilityObject* coreSelection = core(selection); if (!coreSelection || !coreSelection->isAccessibilityRenderObject() || index < 0) return 0; AccessibilityObject::AccessibilityChildrenVector selectedItems; if (coreSelection->isListBox()) coreSelection->selectedChildren(selectedItems); else if (coreSelection->isMenuList()) { RenderObject* renderer = coreSelection->renderer(); if (!renderer) return 0; HTMLSelectElement* selectNode = toHTMLSelectElement(renderer->node()); int selectedIndex = selectNode->selectedIndex(); const Vector<HTMLElement*> listItems = selectNode->listItems(); if (selectedIndex < 0 || selectedIndex >= static_cast<int>(listItems.size())) return 0; return optionFromList(selection, selectedIndex); } if (index < static_cast<gint>(selectedItems.size())) return selectedItems.at(index).get(); return 0; }
static AccessibilityObject* optionFromSelection(AtkSelection* selection, gint index) { // i is the ith selection as opposed to the ith child. AccessibilityObject* coreSelection = core(selection); if (!coreSelection || !coreSelection->isAccessibilityRenderObject() || index < 0) return nullptr; int selectedIndex = index; if (coreSelection->isMenuList()) { RenderObject* renderer = coreSelection->renderer(); if (!renderer) return nullptr; HTMLSelectElement* selectNode = downcast<HTMLSelectElement>(renderer->node()); if (!selectNode) return nullptr; selectedIndex = selectNode->selectedIndex(); const auto& listItems = selectNode->listItems(); if (selectedIndex < 0 || selectedIndex >= static_cast<int>(listItems.size())) return nullptr; } return optionFromList(selection, selectedIndex); }
void LayoutListBox::stopAutoscroll() { HTMLSelectElement* select = selectElement(); if (select->isDisabledFormControl()) return; select->handleMouseRelease(); }
void RenderListBox::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset) { if (!isSpatialNavigationEnabled(frame())) return RenderBlock::addFocusRingRects(rects, additionalOffset); HTMLSelectElement* select = toHTMLSelectElement(node()); // Focus the last selected item. int selectedItem = select->activeSelectionEndListIndex(); if (selectedItem >= 0) { rects.append(itemBoundingBoxRect(additionalOffset, selectedItem)); return; } // No selected items, find the first non-disabled item. int size = numItems(); const Vector<HTMLElement*>& listItems = select->listItems(); for (int i = 0; i < size; ++i) { HTMLElement* element = listItems[i]; if (element->hasTagName(optionTag) && !toHTMLOptionElement(element)->disabled()) { rects.append(itemBoundingBoxRect(additionalOffset, i)); return; } } }
void HTMLOptGroupElement::accessKeyAction(bool) { HTMLSelectElement* select = ownerSelectElement(); // send to the parent to bring focus to the list box if (select && !select->focused()) select->accessKeyAction(false); }
TEST_F(ExternalPopupMenuTest, PopupAccountsForVisualViewportOffset) { registerMockedURLLoad("select_mid_screen.html"); loadFrame("select_mid_screen.html"); webView()->resize(WebSize(100, 100)); webView()->updateAllLifecyclePhases(); HTMLSelectElement* select = toHTMLSelectElement(mainFrame()->frame()->document()->getElementById("select")); LayoutMenuList* menuList = toLayoutMenuList(select->layoutObject()); ASSERT_TRUE(menuList); VisualViewport& visualViewport = webView()->page()->frameHost().visualViewport(); IntRect rectInDocument = menuList->absoluteBoundingBoxRect(); webView()->setPageScaleFactor(2); IntPoint scrollDelta(20, 30); visualViewport.move(scrollDelta); select->showPopup(); EXPECT_EQ(rectInDocument.x() - scrollDelta.x(), client().shownBounds().x); EXPECT_EQ(rectInDocument.y() - scrollDelta.y(), client().shownBounds().y); }
void RenderMenuList::showPopup() { if (m_popupIsVisible) return; if (document()->page()->chrome()->hasOpenedPopup()) return; // Create m_innerBlock here so it ends up as the first child. // This is important because otherwise we might try to create m_innerBlock // inside the showPopup call and it would fail. createInnerBlock(); if (!m_popup) m_popup = document()->page()->chrome()->createPopupMenu(this); m_popupIsVisible = true; // Compute the top left taking transforms into account, but use // the actual width of the element to size the popup. FloatPoint absTopLeft = localToAbsolute(FloatPoint(), false, true); IntRect absBounds = absoluteBoundingBoxRectIgnoringTransforms(); int scale = document()->page()->settings()->defaultDeviceScaleFactor(); if (scale && scale != 1) absBounds.scale(scale); absBounds.setLocation(roundedIntPoint(absTopLeft)); HTMLSelectElement* select = toHTMLSelectElement(node()); m_popup->show(absBounds, document()->view(), select->optionToListIndex(select->selectedIndex())); }
static v8::Handle<v8::Value> autofocusAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.autofocus._get"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(info.Holder()); if (!R_check(imp)) return v8::Handle<v8::Value>(v8::Undefined()); return v8Boolean(imp->hasAttribute(WebCore::HTMLNames::autofocusAttr)); }
static v8::Handle<v8::Value> lengthAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.length._get"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(info.Holder()); if (!R_check(imp)) return v8::Handle<v8::Value>(v8::Undefined()); return v8::Integer::NewFromUnsigned(imp->length()); }
void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { HTMLSelectElement* select = ownerSelectElement(); if (select) select->childrenChanged(changedByParser); HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); }
void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, int listIndex) { HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node()); const Vector<HTMLElement*>& listItems = select->listItems(); HTMLElement* element = listItems[listIndex]; String itemText; if (element->hasTagName(optionTag)) itemText = static_cast<HTMLOptionElement*>(element)->optionText(); else if (element->hasTagName(optgroupTag)) itemText = static_cast<HTMLOptGroupElement*>(element)->groupLabelText(); // Determine where the item text should be placed IntRect r = itemBoundingBoxRect(tx, ty, listIndex); r.move(optionsSpacingHorizontal, style()->font().ascent()); RenderStyle* itemStyle = element->renderStyle(); if (!itemStyle) itemStyle = style(); Color textColor = element->renderStyle() ? element->renderStyle()->color() : style()->color(); if (element->hasTagName(optionTag) && static_cast<HTMLOptionElement*>(element)->selected()) { if (document()->frame()->isActive() && document()->focusedNode() == node()) textColor = theme()->activeListBoxSelectionForegroundColor(); // Honor the foreground color for disabled items else if (!element->disabled()) textColor = theme()->inactiveListBoxSelectionForegroundColor(); } paintInfo.context->setFillColor(textColor); Font itemFont = style()->font(); if (element->hasTagName(optgroupTag)) { FontDescription d = itemFont.fontDescription(); d.setBold(true); itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing()); itemFont.update(); } paintInfo.context->setFont(itemFont); unsigned length = itemText.length(); const UChar* string = itemText.characters(); TextStyle textStyle(0, 0, 0, false, true); RenderBlock::CharacterBuffer characterBuffer; if (itemStyle->direction() == RTL && itemStyle->unicodeBidi() == Override) textStyle.setRTL(true); else if ((itemStyle->direction() == RTL || itemStyle->unicodeBidi() != Override) && !itemStyle->visuallyOrdered()) { // If necessary, reorder characters by running the string through the bidi algorithm characterBuffer.append(string, length); RenderBlock::bidiReorderCharacters(document(), itemStyle, characterBuffer); string = characterBuffer.data(); } TextRun textRun(string, length); // Draw the item text if (itemStyle->visibility() != HIDDEN) paintInfo.context->drawText(textRun, r.location(), textStyle); }
TEST_F(HTMLSelectElementTest, SetRecalcListItemsByOptgroupRemoval) { document().documentElement()->setInnerHTML("<select><optgroup><option>sub1</option><option>sub2</option></optgroup></select>", ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); HTMLSelectElement* select = toHTMLSelectElement(document().body()->firstChild()); select->setInnerHTML("", ASSERT_NO_EXCEPTION); // PASS if setInnerHTML didn't have a check failure. }
AccessibilityObject* AccessibilityListBoxOption::parentObject() const { HTMLSelectElement* parentNode = listBoxOptionParentNode(); if (!parentNode) return 0; return m_optionElement->document()->axObjectCache()->getOrCreate(parentNode->renderer()); }
static void autofocusAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.autofocus._set"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(info.Holder()); bool v = value->BooleanValue(); imp->setBooleanAttribute(WebCore::HTMLNames::autofocusAttr, v); return; }
static void multipleAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.multiple._set"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(info.Holder()); bool v = value->BooleanValue(); imp->setMultiple(v); return; }
static v8::Handle<v8::Value> setCustomValidityCallback(const v8::Arguments& args) { INC_STATS("DOM.HTMLSelectElement.setCustomValidity"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(args.Holder()); STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, error, args[0]); imp->setCustomValidity(error); return v8::Handle<v8::Value>(); }
void setJSHTMLSelectElementLength(ExecState* exec, JSObject* thisObject, JSValue value) { JSHTMLSelectElement* castedThis = static_cast<JSHTMLSelectElement*>(thisObject); HTMLSelectElement* imp = static_cast<HTMLSelectElement*>(castedThis->impl()); ExceptionCode ec = 0; imp->setLength(value.toUInt32(exec), ec); setDOMException(exec, ec); }
static void selectedIndexAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.selectedIndex._set"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(info.Holder()); int v = toInt32(value); imp->setSelectedIndex(v); return; }
JSValue jsHTMLSelectElementSize(ExecState* exec, JSValue slotBase, const Identifier&) { JSHTMLSelectElement* castedThis = static_cast<JSHTMLSelectElement*>(asObject(slotBase)); UNUSED_PARAM(exec); HTMLSelectElement* imp = static_cast<HTMLSelectElement*>(castedThis->impl()); JSValue result = jsNumber(imp->size()); return result; }
bool AccessibilityListBoxOption::isSelectedOptionActive() const { HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode(); if (!listBoxParentNode) return false; return listBoxParentNode->activeSelectionEndListIndex() == listBoxOptionIndex(); }
static void valueAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.value._set"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(info.Holder()); V8Parameter<WithNullCheck> v = value; imp->setValue(v); return; }
JSValue jsHTMLSelectElementRequired(ExecState* exec, JSValue slotBase, const Identifier&) { JSHTMLSelectElement* castedThis = static_cast<JSHTMLSelectElement*>(asObject(slotBase)); UNUSED_PARAM(exec); HTMLSelectElement* imp = static_cast<HTMLSelectElement*>(castedThis->impl()); JSValue result = jsBoolean(imp->hasAttribute(WebCore::HTMLNames::requiredAttr)); return result; }
JSValue jsHTMLSelectElementLabels(ExecState* exec, JSValue slotBase, const Identifier&) { JSHTMLSelectElement* castedThis = static_cast<JSHTMLSelectElement*>(asObject(slotBase)); UNUSED_PARAM(exec); HTMLSelectElement* imp = static_cast<HTMLSelectElement*>(castedThis->impl()); JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->labels())); return result; }