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> selectedIndexAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLSelectElement.selectedIndex._get"); HTMLSelectElement* imp = V8HTMLSelectElement::toNative(info.Holder()); if (!R_check(imp)) return v8::Handle<v8::Value>(v8::Undefined()); return v8::Integer::New(imp->selectedIndex()); }
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); }
JSValue jsHTMLSelectElementSelectedIndex(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->selectedIndex()); return result; }
bool RenderThemeAndroid::paintTextArea(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect) { if (!obj->isListBox()) return true; paintCombo(obj, info, rect); RenderStyle* style = obj->style(); if (style) style->setColor(Color::transparent); Node* node = obj->node(); if (!node || !node->hasTagName(HTMLNames::selectTag)) return true; HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node); // The first item may be visible. Make sure it does not draw. // If it has a style, it overrides the RenderListBox's style, so we // need to make sure both are set to transparent. node = select->item(0); if (node) { RenderObject* renderer = node->renderer(); if (renderer) { RenderStyle* renderStyle = renderer->style(); if (renderStyle) renderStyle->setColor(Color::transparent); } } // Find the first selected option, and draw its text. // FIXME: In a later change, if there is more than one item selected, // draw a string that says "X items" like iPhone Safari does int index = select->selectedIndex(); node = select->item(index); if (!node || !node->hasTagName(HTMLNames::optionTag)) return true; HTMLOptionElement* option = static_cast<HTMLOptionElement*>(node); String label = option->textIndentedToRespectGroupLabel(); SkRect r(rect); SkPaint paint; paint.setAntiAlias(true); paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); // Values for text size and positioning determined by trial and error paint.setTextSize(r.height() - SkIntToScalar(6)); SkCanvas* canvas = getCanvasFromInfo(info); int saveCount = canvas->save(); r.fRight -= SkIntToScalar(RenderSkinCombo::extraWidth()); canvas->clipRect(r); canvas->drawText(label.characters(), label.length() << 1, r.fLeft + SkIntToScalar(5), r.fBottom - SkIntToScalar(5), paint); canvas->restoreToCount(saveCount); return true; }
int AXMenuListPopup::getSelectedIndex() const { if (!m_parent) return -1; Node* parentNode = m_parent->node(); if (!isHTMLSelectElement(parentNode)) return -1; HTMLSelectElement* htmlSelectElement = toHTMLSelectElement(parentNode); return htmlSelectElement->selectedIndex(); }
TEST_F(ExternalPopupMenuTest, DidAcceptIndicesClearSelect) { registerMockedURLLoad("select.html"); loadFrame("select.html"); HTMLSelectElement* select = toHTMLSelectElement(mainFrame()->frame()->document()->getElementById("select")); LayoutMenuList* menuList = toLayoutMenuList(select->layoutObject()); ASSERT_TRUE(menuList); select->showPopup(); ASSERT_TRUE(select->popupIsVisible()); WebExternalPopupMenuClient* client = static_cast<ExternalPopupMenu*>(select->popup()); WebVector<int> indices; client->didAcceptIndices(indices); EXPECT_FALSE(select->popupIsVisible()); EXPECT_EQ(-1, select->selectedIndex()); }
TEST_F(ExternalPopupMenuTest, DidAcceptIndex) { registerMockedURLLoad("select.html"); loadFrame("select.html"); HTMLSelectElement* select = toHTMLSelectElement(mainFrame()->frame()->document()->getElementById("select")); LayoutMenuList* menuList = toLayoutMenuList(select->layoutObject()); ASSERT_TRUE(menuList); select->showPopup(); ASSERT_TRUE(select->popupIsVisible()); WebExternalPopupMenuClient* client = static_cast<ExternalPopupMenu*>(select->popup()); client->didAcceptIndex(2); EXPECT_FALSE(select->popupIsVisible()); ASSERT_STREQ("2", menuList->text().utf8().data()); EXPECT_EQ(2, select->selectedIndex()); }
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(*document()->frame(), this); m_popupIsVisible = true; FloatQuad quad(localToAbsoluteQuad(FloatQuad(borderBoundingBox()))); IntSize size = pixelSnappedIntRect(frameRect()).size(); HTMLSelectElement* select = selectElement(); m_popup->show(quad, size, select->optionToListIndex(select->selectedIndex())); }
void ExternalPopupMenu::getPopupMenuInfo(WebPopupMenuInfo& info, HTMLSelectElement& ownerElement) { const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = ownerElement.listItems(); size_t itemCount = listItems.size(); size_t count = 0; Vector<WebMenuItemInfo> items(itemCount); for (size_t i = 0; i < itemCount; ++i) { if (ownerElement.itemIsDisplayNone(*listItems[i])) continue; Element& itemElement = *listItems[i]; WebMenuItemInfo& popupItem = items[count++]; popupItem.label = ownerElement.itemText(itemElement); popupItem.toolTip = itemElement.title(); popupItem.checked = false; if (isHTMLHRElement(itemElement)) { popupItem.type = WebMenuItemInfo::Separator; } else if (isHTMLOptGroupElement(itemElement)) { popupItem.type = WebMenuItemInfo::Group; } else { popupItem.type = WebMenuItemInfo::Option; popupItem.checked = toHTMLOptionElement(itemElement).selected(); } popupItem.enabled = !itemElement.isDisabledFormControl(); const ComputedStyle& style = *ownerElement.itemComputedStyle(itemElement); popupItem.textDirection = toWebTextDirection(style.direction()); popupItem.hasTextDirectionOverride = isOverride(style.unicodeBidi()); } const ComputedStyle& menuStyle = ownerElement.computedStyle() ? *ownerElement.computedStyle() : *ownerElement.ensureComputedStyle(); info.itemHeight = menuStyle.font().fontMetrics().height(); info.itemFontSize = static_cast<int>(menuStyle.font().fontDescription().computedSize()); info.selectedIndex = toExternalPopupMenuItemIndex(ownerElement.optionToListIndex(ownerElement.selectedIndex()), ownerElement); info.rightAligned = menuStyle.direction() == RTL; info.allowMultipleSelection = ownerElement.multiple(); if (count < itemCount) items.shrink(count); info.items = items; }
void RenderMenuList::showPopup() { if (m_popupIsVisible) 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 = PopupMenu::create(this); HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node()); 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 = absoluteBoundingBoxRect(); absBounds.setLocation(roundedIntPoint(absTopLeft)); m_popup->show(absBounds, document()->view(), select->optionToListIndex(select->selectedIndex())); }
int RenderMenuList::selectedIndex() const { HTMLSelectElement* select = selectElement(); return select->optionToListIndex(select->selectedIndex()); }
int RenderMenuList::selectedIndex() const { HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node()); return select->optionToListIndex(select->selectedIndex()); }