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));
}
Пример #5
0
bool HTMLOptionElement::spatialNavigationFocused() const
{
    HTMLSelectElement* select = ownerSelectElement();
    if (!select || !select->focused())
        return false;
    return select->spatialNavigationFocusedOption() == this;
}
Пример #6
0
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);
        }
    }
}
Пример #7
0
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);
}
Пример #10
0
void LayoutListBox::stopAutoscroll()
{
    HTMLSelectElement* select = selectElement();
    if (select->isDisabledFormControl())
        return;
    select->handleMouseRelease();
}
Пример #11
0
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;
        }
    }
}
Пример #12
0
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);
}
Пример #14
0
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);
}
Пример #18
0
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>();
}
Пример #24
0
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;
}
Пример #26
0
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;
}
Пример #29
0
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;
}
Пример #30
0
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;
}