| Index: Source/core/layout/LayoutMenuList.cpp
|
| diff --git a/Source/core/layout/LayoutMenuList.cpp b/Source/core/layout/LayoutMenuList.cpp
|
| index ecdf569b379c261542a9c756af33eef5b3c57a84..b0af499bb1d366df030f466b3737207cd1daa60f 100644
|
| --- a/Source/core/layout/LayoutMenuList.cpp
|
| +++ b/Source/core/layout/LayoutMenuList.cpp
|
| @@ -56,9 +56,11 @@ LayoutMenuList::LayoutMenuList(Element* element)
|
| , m_buttonText(nullptr)
|
| , m_innerBlock(nullptr)
|
| , m_optionsChanged(true)
|
| + , m_isEmpty(false)
|
| + , m_hasUpdatedActiveOption(false)
|
| + , m_popupIsVisible(false)
|
| , m_optionsWidth(0)
|
| , m_lastActiveIndex(-1)
|
| - , m_popupIsVisible(false)
|
| , m_indexToSelectOnCancel(-1)
|
| {
|
| ASSERT(isHTMLSelectElement(element));
|
| @@ -95,6 +97,14 @@ void LayoutMenuList::createInnerBlock()
|
| // Create an anonymous block.
|
| ASSERT(!firstChild());
|
| m_innerBlock = createAnonymousBlock();
|
| +
|
| + m_buttonText = new LayoutText(&document(), StringImpl::empty());
|
| + // We need to set the text explicitly though it was specified in the
|
| + // constructor because LayoutText doesn't refer to the text
|
| + // specified in the constructor in a case of re-transforming.
|
| + m_buttonText->setStyle(mutableStyle());
|
| + m_innerBlock->addChild(m_buttonText);
|
| +
|
| adjustInnerStyle();
|
| LayoutFlexibleBox::addChild(m_innerBlock);
|
| }
|
| @@ -136,7 +146,6 @@ inline HTMLSelectElement* LayoutMenuList::selectElement() const
|
|
|
| void LayoutMenuList::addChild(LayoutObject* newChild, LayoutObject* beforeChild)
|
| {
|
| - createInnerBlock();
|
| m_innerBlock->addChild(newChild, beforeChild);
|
| ASSERT(m_innerBlock == firstChild());
|
|
|
| @@ -158,10 +167,11 @@ void LayoutMenuList::styleDidChange(StyleDifference diff, const ComputedStyle* o
|
| {
|
| LayoutBlock::styleDidChange(diff, oldStyle);
|
|
|
| - if (m_buttonText)
|
| - m_buttonText->setStyle(mutableStyle());
|
| - if (m_innerBlock) // LayoutBlock handled updating the anonymous block's style.
|
| - adjustInnerStyle();
|
| + if (!m_innerBlock)
|
| + createInnerBlock();
|
| +
|
| + m_buttonText->setStyle(mutableStyle());
|
| + adjustInnerStyle();
|
|
|
| bool fontChanged = !oldStyle || oldStyle->font() != style()->font();
|
| if (fontChanged)
|
| @@ -287,40 +297,23 @@ void LayoutMenuList::setTextFromOption(int optionIndex)
|
| void LayoutMenuList::setText(const String& s)
|
| {
|
| if (s.isEmpty()) {
|
| - if (!m_buttonText || !m_buttonText->isBR()) {
|
| - // FIXME: We should not modify the structure of the layout tree
|
| - // during layout. crbug.com/370462
|
| - DeprecatedDisableModifyLayoutTreeStructureAsserts disabler;
|
| - if (m_buttonText)
|
| - m_buttonText->destroy();
|
| - m_buttonText = new LayoutBR(&document());
|
| - m_buttonText->setStyle(mutableStyle());
|
| - addChild(m_buttonText);
|
| - }
|
| + // FIXME: This is a hack. We need the select to have the same baseline positioning as
|
| + // any surrounding text. Wihtout any content, we align the bottom of the select to the bottom
|
| + // of the text. With content (In this case the faked " ") we correctly align the middle of
|
| + // the select to the middle of the text. It should be possible to remove this, just set
|
| + // s.impl() into the text and have things align correctly ... crbug.com/485982
|
| + m_isEmpty = true;
|
| + m_buttonText->setText(StringImpl::create(" ", 1), true);
|
| } else {
|
| - if (m_buttonText && !m_buttonText->isBR()) {
|
| - m_buttonText->setText(s.impl(), true);
|
| - } else {
|
| - // FIXME: We should not modify the structure of the layout tree
|
| - // during layout. crbug.com/370462
|
| - DeprecatedDisableModifyLayoutTreeStructureAsserts disabler;
|
| - if (m_buttonText)
|
| - m_buttonText->destroy();
|
| - m_buttonText = new LayoutText(&document(), s.impl());
|
| - m_buttonText->setStyle(mutableStyle());
|
| - // We need to set the text explicitly though it was specified in the
|
| - // constructor because LayoutText doesn't refer to the text
|
| - // specified in the constructor in a case of re-transforming.
|
| - m_buttonText->setText(s.impl(), true);
|
| - addChild(m_buttonText);
|
| - }
|
| - adjustInnerStyle();
|
| + m_isEmpty = false;
|
| + m_buttonText->setText(s.impl(), true);
|
| }
|
| + adjustInnerStyle();
|
| }
|
|
|
| String LayoutMenuList::text() const
|
| {
|
| - return m_buttonText ? m_buttonText->text() : String();
|
| + return m_buttonText && !m_isEmpty ? m_buttonText->text() : String();
|
| }
|
|
|
| LayoutRect LayoutMenuList::controlClipRect(const LayoutPoint& additionalOffset) const
|
| @@ -353,10 +346,6 @@ void LayoutMenuList::showPopup()
|
| if (document().frameHost()->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().frameHost()->chrome().createPopupMenu(*document().frame(), this);
|
| m_popupIsVisible = true;
|
| @@ -367,7 +356,6 @@ void LayoutMenuList::showPopup()
|
| m_popup->show(quad, size, select->optionToListIndex(select->selectedIndex()));
|
| if (AXObjectCache* cache = document().existingAXObjectCache())
|
| cache->didShowMenuListPopup(this);
|
| -
|
| }
|
|
|
| void LayoutMenuList::hidePopup()
|
| @@ -435,6 +423,14 @@ void LayoutMenuList::didUpdateActiveOption(int optionIndex)
|
| int listIndex = select->optionToListIndex(optionIndex);
|
| if (listIndex < 0 || listIndex >= static_cast<int>(select->listItems().size()))
|
| return;
|
| +
|
| + // We skip sending accessiblity notifications for the very first option, otherwise
|
| + // we get extra focus and select events that are undesired.
|
| + if (!m_hasUpdatedActiveOption) {
|
| + m_hasUpdatedActiveOption = true;
|
| + return;
|
| + }
|
| +
|
| document().existingAXObjectCache()->handleUpdateActiveMenuOption(this, optionIndex);
|
| }
|
|
|
|
|