15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This file is part of the select element renderer in WebCore.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *               2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderMenuList.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <math.h>
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "HTMLNames.h"
30bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/accessibility/AXMenuList.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/accessibility/AXObjectCache.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSFontSelector.h"
3381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "core/css/resolver/StyleResolver.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeRenderStyle.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLOptGroupElement.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLOptionElement.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLSelectElement.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Chrome.h"
391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/Frame.h"
401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/FrameView.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Page.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderBR.h"
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderScrollbar.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTheme.h"
458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "core/rendering/RenderView.h"
46a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/FontCache.h"
471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntSize.h"
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std;
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderMenuList::RenderMenuList(Element* element)
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    : RenderFlexibleBox(element)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_buttonText(0)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_innerBlock(0)
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_optionsChanged(true)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_optionsWidth(0)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lastActiveIndex(-1)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_popupIsVisible(false)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element->isHTMLElement());
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element->hasTagName(HTMLNames::selectTag));
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderMenuList::~RenderMenuList()
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_popup)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_popup->disconnectClient();
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_popup = 0;
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::createInnerBlock()
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_innerBlock) {
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(firstChild() == m_innerBlock);
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!m_innerBlock->nextSibling());
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Create an anonymous block.
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!firstChild());
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_innerBlock = createAnonymousBlock();
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    adjustInnerStyle();
88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderFlexibleBox::addChild(m_innerBlock);
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::adjustInnerStyle()
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderStyle* innerStyle = m_innerBlock->style();
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    innerStyle->setFlexGrow(1);
95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    innerStyle->setFlexShrink(1);
96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // min-width: 0; is needed for correct shrinking.
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // FIXME: Remove this line when https://bugs.webkit.org/show_bug.cgi?id=111790 is fixed.
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    innerStyle->setMinWidth(Length(0, Fixed));
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Use margin:auto instead of align-items:center to get safe centering, i.e.
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // when the content overflows, treat it the same as align-items: flex-start.
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // But we only do that for the cases where html.css would otherwise use center.
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (style()->alignItems() == AlignCenter) {
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        innerStyle->setMarginTop(Length());
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        innerStyle->setMarginBottom(Length());
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        innerStyle->setAlignSelf(AlignFlexStart);
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
108c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    innerStyle->setPaddingLeft(Length(RenderTheme::theme().popupInternalPaddingLeft(style()), Fixed));
109c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    innerStyle->setPaddingRight(Length(RenderTheme::theme().popupInternalPaddingRight(style()), Fixed));
110c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    innerStyle->setPaddingTop(Length(RenderTheme::theme().popupInternalPaddingTop(style()), Fixed));
111c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    innerStyle->setPaddingBottom(Length(RenderTheme::theme().popupInternalPaddingBottom(style()), Fixed));
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_optionStyle) {
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((m_optionStyle->direction() != innerStyle->direction() || m_optionStyle->unicodeBidi() != innerStyle->unicodeBidi()))
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_innerBlock->setNeedsLayoutAndPrefWidthsRecalc();
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        innerStyle->setTextAlign(style()->isLeftToRightDirection() ? LEFT : RIGHT);
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        innerStyle->setDirection(m_optionStyle->direction());
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        innerStyle->setUnicodeBidi(m_optionStyle->unicodeBidi());
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline HTMLSelectElement* RenderMenuList::selectElement() const
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return toHTMLSelectElement(node());
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::addChild(RenderObject* newChild, RenderObject* beforeChild)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    createInnerBlock();
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_innerBlock->addChild(newChild, beforeChild);
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_innerBlock == firstChild());
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1338abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (AXObjectCache* cache = document().existingAXObjectCache())
134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cache->childrenChanged(this);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::removeChild(RenderObject* oldChild)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (oldChild == m_innerBlock || !m_innerBlock) {
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        RenderFlexibleBox::removeChild(oldChild);
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_innerBlock = 0;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_innerBlock->removeChild(oldChild);
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock::styleDidChange(diff, oldStyle);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_buttonText)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_buttonText->setStyle(style());
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_innerBlock) // RenderBlock handled updating the anonymous block's style.
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        adjustInnerStyle();
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool fontChanged = !oldStyle || oldStyle->font() != style()->font();
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (fontChanged)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updateOptionsWidth();
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::updateOptionsWidth()
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float maxOptionWidth = 0;
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
16402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    int size = listItems.size();
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FontCachePurgePreventer fontCachePurgePreventer;
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int i = 0; i < size; ++i) {
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElement* element = listItems[i];
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!element->hasTagName(optionTag))
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        applyTextTransform(style(), text, ' ');
174c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        if (RenderTheme::theme().popupOptionSupportsTextIndent()) {
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Add in the option's text indent.  We can't calculate percentage values for now.
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            float optionWidth = 0;
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (RenderStyle* optionStyle = element->renderStyle())
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                optionWidth += minimumValueForLength(optionStyle->textIndent(), 0, view());
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!text.isEmpty())
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                optionWidth += style()->font().width(text);
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            maxOptionWidth = max(maxOptionWidth, optionWidth);
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (!text.isEmpty())
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            maxOptionWidth = max(maxOptionWidth, style()->font().width(text));
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int width = static_cast<int>(ceilf(maxOptionWidth));
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_optionsWidth == width)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_optionsWidth = width;
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parent())
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setNeedsLayoutAndPrefWidthsRecalc();
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::updateFromElement()
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_optionsChanged) {
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updateOptionsWidth();
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_optionsChanged = false;
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_popupIsVisible)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_popup->updateFromElement();
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setTextFromOption(selectElement()->selectedIndex());
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::setTextFromOption(int optionIndex)
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLSelectElement* select = selectElement();
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = select->listItems();
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int size = listItems.size();
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int i = select->optionToListIndex(optionIndex);
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String text = emptyString();
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (i >= 0 && i < size) {
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Element* element = listItems[i];
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (element->hasTagName(optionTag)) {
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_optionStyle = element->renderStyle();
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setText(text.stripWhiteSpace());
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    didUpdateActiveOption(optionIndex);
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::setText(const String& s)
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (s.isEmpty()) {
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_buttonText || !m_buttonText->isBR()) {
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_buttonText)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_buttonText->destroy();
2348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            m_buttonText = new RenderBR(&document());
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_buttonText->setStyle(style());
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            addChild(m_buttonText);
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_buttonText && !m_buttonText->isBR())
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_buttonText->setText(s.impl(), true);
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else {
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_buttonText)
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_buttonText->destroy();
2448abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            m_buttonText = new RenderText(&document(), s.impl());
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_buttonText->setStyle(style());
24653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // We need to set the text explicitly though it was specified in the
24753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // constructor because RenderText doesn't refer to the text
24853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // specified in the constructor in a case of re-transforming.
24953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            m_buttonText->setText(s.impl(), true);
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            addChild(m_buttonText);
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        adjustInnerStyle();
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RenderMenuList::text() const
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
258e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return m_buttonText ? m_buttonText->text() : String();
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderMenuList::controlClipRect(const LayoutPoint& additionalOffset) const
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Clip to the intersection of the content box and the content box for the inner box
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This will leave room for the arrows which sit in the inner box padding,
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and if the inner box ever spills out of the outer box, that will get clipped too.
26602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    LayoutRect outerBox(additionalOffset.x() + borderLeft() + paddingLeft(),
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   additionalOffset.y() + borderTop() + paddingTop(),
26802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch                   contentWidth(),
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   contentHeight());
27002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
27102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    LayoutRect innerBox(additionalOffset.x() + m_innerBlock->x() + m_innerBlock->paddingLeft(),
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   additionalOffset.y() + m_innerBlock->y() + m_innerBlock->paddingTop(),
27302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch                   m_innerBlock->contentWidth(),
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   m_innerBlock->contentHeight());
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return intersection(outerBox, innerBox);
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
279926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderMenuList::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
280926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
281c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    maxLogicalWidth = max(m_optionsWidth, RenderTheme::theme().minimumMenuListSize(style())) + m_innerBlock->paddingLeft() + m_innerBlock->paddingRight();
282926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!style()->width().isPercent())
283926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        minLogicalWidth = maxLogicalWidth;
284926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
285926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::computePreferredLogicalWidths()
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_minPreferredLogicalWidth = 0;
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_maxPreferredLogicalWidth = 0;
29002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style()->width().isFixed() && style()->width().value() > 0)
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
299926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style()->maxWidth().isFixed()) {
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit toAdd = borderAndPaddingWidth();
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_minPreferredLogicalWidth += toAdd;
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_maxPreferredLogicalWidth += toAdd;
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
310c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    clearPreferredLogicalWidthsDirty();
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::showPopup()
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_popupIsVisible)
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3188abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (document().page()->chrome().hasOpenedPopup())
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Create m_innerBlock here so it ends up as the first child.
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This is important because otherwise we might try to create m_innerBlock
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // inside the showPopup call and it would fail.
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    createInnerBlock();
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_popup)
3268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        m_popup = document().page()->chrome().createPopupMenu(*document().frame(), this);
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_popupIsVisible = true;
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    FloatQuad quad(localToAbsoluteQuad(FloatQuad(borderBoundingBox())));
33081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    IntSize size = pixelSnappedIntRect(frameRect()).size();
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLSelectElement* select = selectElement();
33293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_popup->show(quad, size, select->optionToListIndex(select->selectedIndex()));
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::hidePopup()
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_popup)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_popup->hide();
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::valueChanged(unsigned listIndex, bool fireOnChange)
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Check to ensure a page navigation has not occurred while
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the popup was up.
3458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& doc = toElement(node())->document();
3468abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (&doc != doc.frame()->document())
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
34802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLSelectElement* select = selectElement();
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    select->optionSelectedByUser(select->listToOptionIndex(listIndex), fireOnChange);
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow)
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    selectElement()->listBoxSelectItem(listIndex, allowMultiplySelections, shift, fireOnChangeNow);
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderMenuList::multiple() const
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return selectElement()->multiple();
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::didSetSelectedIndex(int listIndex)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    didUpdateActiveOption(selectElement()->listToOptionIndex(listIndex));
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::didUpdateActiveOption(int optionIndex)
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3708abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (!AXObjectCache::accessibilityEnabled() || !document().existingAXObjectCache())
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_lastActiveIndex == optionIndex)
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastActiveIndex = optionIndex;
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLSelectElement* select = selectElement();
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int listIndex = select->optionToListIndex(optionIndex);
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (listIndex < 0 || listIndex >= static_cast<int>(select->listItems().size()))
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
38151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (AXMenuList* menuList = toAXMenuList(document().axObjectCache()->get(this)))
38251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        menuList->didUpdateActiveOption(optionIndex);
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RenderMenuList::itemText(unsigned listIndex) const
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLSelectElement* select = selectElement();
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = select->listItems();
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (listIndex >= listItems.size())
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String itemString;
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* element = listItems[listIndex];
394e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (isHTMLOptGroupElement(element))
395e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        itemString = toHTMLOptGroupElement(element)->groupLabelText();
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (element->hasTagName(optionTag))
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        itemString = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    applyTextTransform(style(), itemString, ' ');
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return itemString;
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RenderMenuList::itemLabel(unsigned) const
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return String();
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RenderMenuList::itemIcon(unsigned) const
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return String();
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RenderMenuList::itemAccessibilityText(unsigned listIndex) const
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Allow the accessible name be changed if necessary.
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (listIndex >= listItems.size())
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return listItems[listIndex]->fastGetAttribute(aria_labelAttr);
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
42102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RenderMenuList::itemToolTip(unsigned listIndex) const
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (listIndex >= listItems.size())
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return listItems[listIndex]->title();
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderMenuList::itemIsEnabled(unsigned listIndex) const
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (listIndex >= listItems.size())
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement* element = listItems[listIndex];
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element->hasTagName(optionTag))
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool groupEnabled = true;
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (Element* parentElement = element->parentElement()) {
441e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        if (isHTMLOptGroupElement(parentElement))
44253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            groupEnabled = !parentElement->isDisabledFormControl();
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!groupEnabled)
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
44753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return !element->isDisabledFormControl();
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (listIndex >= listItems.size()) {
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we are making an out of bounds access, then we want to use the style
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // of a different option element (index 0). However, if there isn't an option element
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // before at index 0, we fall back to the menu's style.
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!listIndex)
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return menuStyle();
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Try to retrieve the style of an option element we know exists (index 0).
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        listIndex = 0;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement* element = listItems[listIndex];
464926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
465926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Color itemBackgroundColor;
466926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool itemHasCustomBackgroundColor;
467926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    getItemBackgroundColor(listIndex, itemBackgroundColor, itemHasCustomBackgroundColor);
468926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderStyle* style = element->renderStyle() ? element->renderStyle() : element->computedStyle();
4707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    return style ? PopupMenuStyle(resolveColor(style, CSSPropertyColor), itemBackgroundColor, style->font(), style->visibility() == VISIBLE,
471926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        style->display() == NONE, style->textIndent(), style->direction(), isOverride(style->unicodeBidi()),
472926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        itemHasCustomBackgroundColor ? PopupMenuStyle::CustomBackgroundColor : PopupMenuStyle::DefaultBackgroundColor) : menuStyle();
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
475926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderMenuList::getItemBackgroundColor(unsigned listIndex, Color& itemBackgroundColor, bool& itemHasCustomBackgroundColor) const
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
478926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (listIndex >= listItems.size()) {
4797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        itemBackgroundColor = resolveColor(CSSPropertyBackgroundColor);
480926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        itemHasCustomBackgroundColor = false;
481926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
482926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement* element = listItems[listIndex];
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Color backgroundColor;
4868abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (element->renderStyle())
4877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        backgroundColor = resolveColor(element->renderStyle(), CSSPropertyBackgroundColor);
4888abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    itemHasCustomBackgroundColor = backgroundColor.isValid() && backgroundColor.alpha();
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the item has an opaque background color, return that.
490926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!backgroundColor.hasAlpha()) {
491926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        itemBackgroundColor = backgroundColor;
492926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
493926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Otherwise, the item's background is overlayed on top of the menu background.
4967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    backgroundColor = resolveColor(CSSPropertyBackgroundColor).blend(backgroundColor);
497926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!backgroundColor.hasAlpha()) {
498926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        itemBackgroundColor = backgroundColor;
499926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
500926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the menu background is not opaque, then add an opaque white background behind.
503926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    itemBackgroundColor = Color(Color::white).blend(backgroundColor);
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PopupMenuStyle RenderMenuList::menuStyle() const
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    const RenderObject* o = m_innerBlock ? m_innerBlock : this;
5097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    const RenderStyle* s = o->style();
5107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    return PopupMenuStyle(o->resolveColor(CSSPropertyColor), o->resolveColor(CSSPropertyBackgroundColor), s->font(), s->visibility() == VISIBLE,
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        s->display() == NONE, s->textIndent(), style()->direction(), isOverride(style()->unicodeBidi()));
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HostWindow* RenderMenuList::hostWindow() const
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5168abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    return document().view()->hostWindow();
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<Scrollbar> RenderMenuList::createScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Scrollbar> widget;
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasCustomScrollbarStyle)
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        widget = RenderScrollbar::createCustomScrollbar(scrollableArea, orientation, this->node());
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
5268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        widget = Scrollbar::create(scrollableArea, orientation, controlSize);
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return widget.release();
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderMenuList::clientInsetLeft() const
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderMenuList::clientInsetRight() const
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderMenuList::clientPaddingLeft() const
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return paddingLeft() + m_innerBlock->paddingLeft();
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const int endOfLinePadding = 2;
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderMenuList::clientPaddingRight() const
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style()->appearance() == MenulistPart || style()->appearance() == MenulistButtonPart) {
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // For these appearance values, the theme applies padding to leave room for the
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // drop-down button. But leaving room for the button inside the popup menu itself
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // looks strange, so we return a small default padding to avoid having a large empty
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // space appear on the side of the popup menu.
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return endOfLinePadding;
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the appearance isn't MenulistPart, then the select is styled (non-native), so
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // we want to return the user specified padding.
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return paddingRight() + m_innerBlock->paddingRight();
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderMenuList::listSize() const
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return selectElement()->listItems().size();
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderMenuList::selectedIndex() const
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLSelectElement* select = selectElement();
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return select->optionToListIndex(select->selectedIndex());
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::popupDidHide()
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_popupIsVisible = false;
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderMenuList::itemIsSeparator(unsigned listIndex) const
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return listIndex < listItems.size() && listItems[listIndex]->hasTagName(hrTag);
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderMenuList::itemIsLabel(unsigned listIndex) const
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
586e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return listIndex < listItems.size() && isHTMLOptGroupElement(listItems[listIndex]);
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderMenuList::itemIsSelected(unsigned listIndex) const
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<HTMLElement*>& listItems = selectElement()->listItems();
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (listIndex >= listItems.size())
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement* element = listItems[listIndex];
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected();
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMenuList::setTextFromItem(unsigned listIndex)
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setTextFromOption(selectElement()->listToOptionIndex(listIndex));
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FontSelector* RenderMenuList::fontSelector() const
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
605a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return document().styleEngine()->fontSelector();
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
609