| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of the select element renderer in WebCore. | 2 * This file is part of the select element renderer in WebCore. |
| 3 * | 3 * |
| 4 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | 4 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
| 5 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. | 5 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. |
| 6 * 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 6 * 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 void RenderMenuList::trace(Visitor* visitor) | 79 void RenderMenuList::trace(Visitor* visitor) |
| 80 { | 80 { |
| 81 visitor->trace(m_buttonText); | 81 visitor->trace(m_buttonText); |
| 82 visitor->trace(m_innerBlock); | 82 visitor->trace(m_innerBlock); |
| 83 visitor->trace(m_popup); | 83 visitor->trace(m_popup); |
| 84 RenderFlexibleBox::trace(visitor); | 84 RenderFlexibleBox::trace(visitor); |
| 85 } | 85 } |
| 86 | 86 |
| 87 // FIXME: Instead of this hack we should add a ShadowRoot to <select> with no in
sertion point | 87 // FIXME: Instead of this hack we should add a ShadowRoot to <select> with no in
sertion point |
| 88 // to prevent children from rendering. | 88 // to prevent children from rendering. |
| 89 bool RenderMenuList::isChildAllowed(RenderObject* object, RenderStyle*) const | 89 bool RenderMenuList::isChildAllowed(RenderObject* object, const RenderStyle*) co
nst |
| 90 { | 90 { |
| 91 return object->isAnonymous() && !object->isRenderFullScreen(); | 91 return object->isAnonymous() && !object->isRenderFullScreen(); |
| 92 } | 92 } |
| 93 | 93 |
| 94 void RenderMenuList::createInnerBlock() | 94 void RenderMenuList::createInnerBlock() |
| 95 { | 95 { |
| 96 if (m_innerBlock) { | 96 if (m_innerBlock) { |
| 97 ASSERT(firstChild() == m_innerBlock); | 97 ASSERT(firstChild() == m_innerBlock); |
| 98 ASSERT(!m_innerBlock->nextSibling()); | 98 ASSERT(!m_innerBlock->nextSibling()); |
| 99 return; | 99 return; |
| 100 } | 100 } |
| 101 | 101 |
| 102 // Create an anonymous block. | 102 // Create an anonymous block. |
| 103 ASSERT(!firstChild()); | 103 ASSERT(!firstChild()); |
| 104 m_innerBlock = createAnonymousBlock(); | 104 m_innerBlock = createAnonymousBlock(); |
| 105 adjustInnerStyle(); | 105 adjustInnerStyle(); |
| 106 RenderFlexibleBox::addChild(m_innerBlock); | 106 RenderFlexibleBox::addChild(m_innerBlock); |
| 107 } | 107 } |
| 108 | 108 |
| 109 void RenderMenuList::adjustInnerStyle() | 109 void RenderMenuList::adjustInnerStyle() |
| 110 { | 110 { |
| 111 RenderStyle* innerStyle = m_innerBlock->style(); | 111 RenderStyle* innerStyle = m_innerBlock->deprecatedMutableStyle(); |
| 112 innerStyle->setFlexGrow(1); | 112 innerStyle->setFlexGrow(1); |
| 113 innerStyle->setFlexShrink(1); | 113 innerStyle->setFlexShrink(1); |
| 114 // Use margin:auto instead of align-items:center to get safe centering, i.e. | 114 // Use margin:auto instead of align-items:center to get safe centering, i.e. |
| 115 // when the content overflows, treat it the same as align-items: flex-start. | 115 // when the content overflows, treat it the same as align-items: flex-start. |
| 116 // But we only do that for the cases where html.css would otherwise use cent
er. | 116 // But we only do that for the cases where html.css would otherwise use cent
er. |
| 117 if (style()->alignItems() == ItemPositionCenter) { | 117 if (style()->alignItems() == ItemPositionCenter) { |
| 118 innerStyle->setMarginTop(Length()); | 118 innerStyle->setMarginTop(Length()); |
| 119 innerStyle->setMarginBottom(Length()); | 119 innerStyle->setMarginBottom(Length()); |
| 120 innerStyle->setAlignSelf(ItemPositionFlexStart); | 120 innerStyle->setAlignSelf(ItemPositionFlexStart); |
| 121 } | 121 } |
| 122 | 122 |
| 123 innerStyle->setPaddingLeft(Length(LayoutTheme::theme().popupInternalPaddingL
eft(style()), Fixed)); | 123 innerStyle->setPaddingLeft(Length(LayoutTheme::theme().popupInternalPaddingL
eft(deprecatedMutableStyle()), Fixed)); |
| 124 innerStyle->setPaddingRight(Length(LayoutTheme::theme().popupInternalPadding
Right(style()), Fixed)); | 124 innerStyle->setPaddingRight(Length(LayoutTheme::theme().popupInternalPadding
Right(deprecatedMutableStyle()), Fixed)); |
| 125 innerStyle->setPaddingTop(Length(LayoutTheme::theme().popupInternalPaddingTo
p(style()), Fixed)); | 125 innerStyle->setPaddingTop(Length(LayoutTheme::theme().popupInternalPaddingTo
p(deprecatedMutableStyle()), Fixed)); |
| 126 innerStyle->setPaddingBottom(Length(LayoutTheme::theme().popupInternalPaddin
gBottom(style()), Fixed)); | 126 innerStyle->setPaddingBottom(Length(LayoutTheme::theme().popupInternalPaddin
gBottom(deprecatedMutableStyle()), Fixed)); |
| 127 | 127 |
| 128 if (m_optionStyle) { | 128 if (m_optionStyle) { |
| 129 if ((m_optionStyle->direction() != innerStyle->direction() || m_optionSt
yle->unicodeBidi() != innerStyle->unicodeBidi())) | 129 if ((m_optionStyle->direction() != innerStyle->direction() || m_optionSt
yle->unicodeBidi() != innerStyle->unicodeBidi())) |
| 130 m_innerBlock->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidat
ion(); | 130 m_innerBlock->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidat
ion(); |
| 131 innerStyle->setTextAlign(style()->isLeftToRightDirection() ? LEFT : RIGH
T); | 131 innerStyle->setTextAlign(style()->isLeftToRightDirection() ? LEFT : RIGH
T); |
| 132 innerStyle->setDirection(m_optionStyle->direction()); | 132 innerStyle->setDirection(m_optionStyle->direction()); |
| 133 innerStyle->setUnicodeBidi(m_optionStyle->unicodeBidi()); | 133 innerStyle->setUnicodeBidi(m_optionStyle->unicodeBidi()); |
| 134 } | 134 } |
| 135 } | 135 } |
| 136 | 136 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 156 m_innerBlock = nullptr; | 156 m_innerBlock = nullptr; |
| 157 } else | 157 } else |
| 158 m_innerBlock->removeChild(oldChild); | 158 m_innerBlock->removeChild(oldChild); |
| 159 } | 159 } |
| 160 | 160 |
| 161 void RenderMenuList::styleDidChange(StyleDifference diff, const RenderStyle* old
Style) | 161 void RenderMenuList::styleDidChange(StyleDifference diff, const RenderStyle* old
Style) |
| 162 { | 162 { |
| 163 RenderBlock::styleDidChange(diff, oldStyle); | 163 RenderBlock::styleDidChange(diff, oldStyle); |
| 164 | 164 |
| 165 if (m_buttonText) | 165 if (m_buttonText) |
| 166 m_buttonText->setStyle(style()); | 166 m_buttonText->setStyle(deprecatedMutableStyle()); |
| 167 if (m_innerBlock) // RenderBlock handled updating the anonymous block's styl
e. | 167 if (m_innerBlock) // RenderBlock handled updating the anonymous block's styl
e. |
| 168 adjustInnerStyle(); | 168 adjustInnerStyle(); |
| 169 | 169 |
| 170 bool fontChanged = !oldStyle || oldStyle->font() != style()->font(); | 170 bool fontChanged = !oldStyle || oldStyle->font() != style()->font(); |
| 171 if (fontChanged) | 171 if (fontChanged) |
| 172 updateOptionsWidth(); | 172 updateOptionsWidth(); |
| 173 } | 173 } |
| 174 | 174 |
| 175 void RenderMenuList::updateOptionsWidth() | 175 void RenderMenuList::updateOptionsWidth() |
| 176 { | 176 { |
| 177 float maxOptionWidth = 0; | 177 float maxOptionWidth = 0; |
| 178 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = select
Element()->listItems(); | 178 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = select
Element()->listItems(); |
| 179 int size = listItems.size(); | 179 int size = listItems.size(); |
| 180 | 180 |
| 181 for (int i = 0; i < size; ++i) { | 181 for (int i = 0; i < size; ++i) { |
| 182 HTMLElement* element = listItems[i]; | 182 HTMLElement* element = listItems[i]; |
| 183 if (!isHTMLOptionElement(*element)) | 183 if (!isHTMLOptionElement(*element)) |
| 184 continue; | 184 continue; |
| 185 | 185 |
| 186 String text = toHTMLOptionElement(element)->textIndentedToRespectGroupLa
bel(); | 186 String text = toHTMLOptionElement(element)->textIndentedToRespectGroupLa
bel(); |
| 187 applyTextTransform(style(), text, ' '); | 187 applyTextTransform(style(), text, ' '); |
| 188 if (LayoutTheme::theme().popupOptionSupportsTextIndent()) { | 188 if (LayoutTheme::theme().popupOptionSupportsTextIndent()) { |
| 189 // Add in the option's text indent. We can't calculate percentage v
alues for now. | 189 // Add in the option's text indent. We can't calculate percentage v
alues for now. |
| 190 float optionWidth = 0; | 190 float optionWidth = 0; |
| 191 if (RenderStyle* optionStyle = element->renderStyle()) | 191 if (const RenderStyle* optionStyle = element->renderStyle()) |
| 192 optionWidth += minimumValueForLength(optionStyle->textIndent(),
0); | 192 optionWidth += minimumValueForLength(optionStyle->textIndent(),
0); |
| 193 if (!text.isEmpty()) | 193 if (!text.isEmpty()) |
| 194 optionWidth += style()->font().width(text); | 194 optionWidth += style()->font().width(text); |
| 195 maxOptionWidth = std::max(maxOptionWidth, optionWidth); | 195 maxOptionWidth = std::max(maxOptionWidth, optionWidth); |
| 196 } else if (!text.isEmpty()) { | 196 } else if (!text.isEmpty()) { |
| 197 maxOptionWidth = std::max(maxOptionWidth, style()->font().width(text
)); | 197 maxOptionWidth = std::max(maxOptionWidth, style()->font().width(text
)); |
| 198 } | 198 } |
| 199 } | 199 } |
| 200 | 200 |
| 201 int width = static_cast<int>(ceilf(maxOptionWidth)); | 201 int width = static_cast<int>(ceilf(maxOptionWidth)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 firstSelectedIndex = i; | 245 firstSelectedIndex = i; |
| 246 } | 246 } |
| 247 } | 247 } |
| 248 | 248 |
| 249 if (selectedCount == 1) { | 249 if (selectedCount == 1) { |
| 250 ASSERT(0 <= firstSelectedIndex); | 250 ASSERT(0 <= firstSelectedIndex); |
| 251 ASSERT(firstSelectedIndex < size); | 251 ASSERT(firstSelectedIndex < size); |
| 252 HTMLOptionElement* selectedOptionElement = toHTMLOptionElement(listI
tems[firstSelectedIndex]); | 252 HTMLOptionElement* selectedOptionElement = toHTMLOptionElement(listI
tems[firstSelectedIndex]); |
| 253 ASSERT(selectedOptionElement->selected()); | 253 ASSERT(selectedOptionElement->selected()); |
| 254 text = selectedOptionElement->textIndentedToRespectGroupLabel(); | 254 text = selectedOptionElement->textIndentedToRespectGroupLabel(); |
| 255 m_optionStyle = selectedOptionElement->renderStyle(); | 255 m_optionStyle = selectedOptionElement->mutableRenderStyle(); |
| 256 } else { | 256 } else { |
| 257 Locale& locale = select->locale(); | 257 Locale& locale = select->locale(); |
| 258 String localizedNumberString = locale.convertToLocalizedNumber(Strin
g::number(selectedCount)); | 258 String localizedNumberString = locale.convertToLocalizedNumber(Strin
g::number(selectedCount)); |
| 259 text = locale.queryString(WebLocalizedString::SelectMenuListText, lo
calizedNumberString); | 259 text = locale.queryString(WebLocalizedString::SelectMenuListText, lo
calizedNumberString); |
| 260 ASSERT(!m_optionStyle); | 260 ASSERT(!m_optionStyle); |
| 261 } | 261 } |
| 262 } else { | 262 } else { |
| 263 const int i = select->optionToListIndex(optionIndex); | 263 const int i = select->optionToListIndex(optionIndex); |
| 264 if (i >= 0 && i < size) { | 264 if (i >= 0 && i < size) { |
| 265 Element* element = listItems[i]; | 265 Element* element = listItems[i]; |
| 266 if (isHTMLOptionElement(*element)) { | 266 if (isHTMLOptionElement(*element)) { |
| 267 text = toHTMLOptionElement(element)->textIndentedToRespectGroupL
abel(); | 267 text = toHTMLOptionElement(element)->textIndentedToRespectGroupL
abel(); |
| 268 m_optionStyle = element->renderStyle(); | 268 m_optionStyle = element->mutableRenderStyle(); |
| 269 } | 269 } |
| 270 } | 270 } |
| 271 } | 271 } |
| 272 | 272 |
| 273 setText(text.stripWhiteSpace()); | 273 setText(text.stripWhiteSpace()); |
| 274 | 274 |
| 275 didUpdateActiveOption(optionIndex); | 275 didUpdateActiveOption(optionIndex); |
| 276 } | 276 } |
| 277 | 277 |
| 278 void RenderMenuList::setText(const String& s) | 278 void RenderMenuList::setText(const String& s) |
| 279 { | 279 { |
| 280 if (s.isEmpty()) { | 280 if (s.isEmpty()) { |
| 281 if (!m_buttonText || !m_buttonText->isBR()) { | 281 if (!m_buttonText || !m_buttonText->isBR()) { |
| 282 // FIXME: We should not modify the structure of the render tree | 282 // FIXME: We should not modify the structure of the render tree |
| 283 // during layout. crbug.com/370462 | 283 // during layout. crbug.com/370462 |
| 284 DeprecatedDisableModifyRenderTreeStructureAsserts disabler; | 284 DeprecatedDisableModifyRenderTreeStructureAsserts disabler; |
| 285 if (m_buttonText) | 285 if (m_buttonText) |
| 286 m_buttonText->destroy(); | 286 m_buttonText->destroy(); |
| 287 m_buttonText = new RenderBR(&document()); | 287 m_buttonText = new RenderBR(&document()); |
| 288 m_buttonText->setStyle(style()); | 288 m_buttonText->setStyle(deprecatedMutableStyle()); |
| 289 addChild(m_buttonText); | 289 addChild(m_buttonText); |
| 290 } | 290 } |
| 291 } else { | 291 } else { |
| 292 if (m_buttonText && !m_buttonText->isBR()) | 292 if (m_buttonText && !m_buttonText->isBR()) |
| 293 m_buttonText->setText(s.impl(), true); | 293 m_buttonText->setText(s.impl(), true); |
| 294 else { | 294 else { |
| 295 // FIXME: We should not modify the structure of the render tree | 295 // FIXME: We should not modify the structure of the render tree |
| 296 // during layout. crbug.com/370462 | 296 // during layout. crbug.com/370462 |
| 297 DeprecatedDisableModifyRenderTreeStructureAsserts disabler; | 297 DeprecatedDisableModifyRenderTreeStructureAsserts disabler; |
| 298 if (m_buttonText) | 298 if (m_buttonText) |
| 299 m_buttonText->destroy(); | 299 m_buttonText->destroy(); |
| 300 m_buttonText = new RenderText(&document(), s.impl()); | 300 m_buttonText = new RenderText(&document(), s.impl()); |
| 301 m_buttonText->setStyle(style()); | 301 m_buttonText->setStyle(deprecatedMutableStyle()); |
| 302 // We need to set the text explicitly though it was specified in the | 302 // We need to set the text explicitly though it was specified in the |
| 303 // constructor because RenderText doesn't refer to the text | 303 // constructor because RenderText doesn't refer to the text |
| 304 // specified in the constructor in a case of re-transforming. | 304 // specified in the constructor in a case of re-transforming. |
| 305 m_buttonText->setText(s.impl(), true); | 305 m_buttonText->setText(s.impl(), true); |
| 306 addChild(m_buttonText); | 306 addChild(m_buttonText); |
| 307 } | 307 } |
| 308 adjustInnerStyle(); | 308 adjustInnerStyle(); |
| 309 } | 309 } |
| 310 } | 310 } |
| 311 | 311 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 | 474 |
| 475 // Try to retrieve the style of an option element we know exists (index
0). | 475 // Try to retrieve the style of an option element we know exists (index
0). |
| 476 listIndex = 0; | 476 listIndex = 0; |
| 477 } | 477 } |
| 478 HTMLElement* element = listItems[listIndex]; | 478 HTMLElement* element = listItems[listIndex]; |
| 479 | 479 |
| 480 Color itemBackgroundColor; | 480 Color itemBackgroundColor; |
| 481 bool itemHasCustomBackgroundColor; | 481 bool itemHasCustomBackgroundColor; |
| 482 getItemBackgroundColor(listIndex, itemBackgroundColor, itemHasCustomBackgrou
ndColor); | 482 getItemBackgroundColor(listIndex, itemBackgroundColor, itemHasCustomBackgrou
ndColor); |
| 483 | 483 |
| 484 RenderStyle* style = element->renderStyle() ? element->renderStyle() : eleme
nt->computedStyle(); | 484 const RenderStyle* style = element->renderStyle() ? element->renderStyle() :
element->computedStyle(); |
| 485 return style ? PopupMenuStyle(resolveColor(style, CSSPropertyColor), itemBac
kgroundColor, style->font(), style->visibility() == VISIBLE, | 485 return style ? PopupMenuStyle(resolveColor(style, CSSPropertyColor), itemBac
kgroundColor, style->font(), style->visibility() == VISIBLE, |
| 486 isHTMLOptionElement(*element) ? toHTMLOptionElement(*element).isDisplayN
one() : style->display() == NONE, | 486 isHTMLOptionElement(*element) ? toHTMLOptionElement(*element).isDisplayN
one() : style->display() == NONE, |
| 487 style->textIndent(), style->direction(), isOverride(style->unicodeBidi()
), | 487 style->textIndent(), style->direction(), isOverride(style->unicodeBidi()
), |
| 488 itemHasCustomBackgroundColor ? PopupMenuStyle::CustomBackgroundColor : P
opupMenuStyle::DefaultBackgroundColor) : menuStyle(); | 488 itemHasCustomBackgroundColor ? PopupMenuStyle::CustomBackgroundColor : P
opupMenuStyle::DefaultBackgroundColor) : menuStyle(); |
| 489 } | 489 } |
| 490 | 490 |
| 491 void RenderMenuList::getItemBackgroundColor(unsigned listIndex, Color& itemBackg
roundColor, bool& itemHasCustomBackgroundColor) const | 491 void RenderMenuList::getItemBackgroundColor(unsigned listIndex, Color& itemBackg
roundColor, bool& itemHasCustomBackgroundColor) const |
| 492 { | 492 { |
| 493 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = select
Element()->listItems(); | 493 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = select
Element()->listItems(); |
| 494 if (listIndex >= listItems.size()) { | 494 if (listIndex >= listItems.size()) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 HTMLElement* element = listItems[listIndex]; | 584 HTMLElement* element = listItems[listIndex]; |
| 585 return isHTMLOptionElement(*element) && toHTMLOptionElement(*element).select
ed(); | 585 return isHTMLOptionElement(*element) && toHTMLOptionElement(*element).select
ed(); |
| 586 } | 586 } |
| 587 | 587 |
| 588 void RenderMenuList::setTextFromItem(unsigned listIndex) | 588 void RenderMenuList::setTextFromItem(unsigned listIndex) |
| 589 { | 589 { |
| 590 setTextFromOption(selectElement()->listToOptionIndex(listIndex)); | 590 setTextFromOption(selectElement()->listToOptionIndex(listIndex)); |
| 591 } | 591 } |
| 592 | 592 |
| 593 } // namespace blink | 593 } // namespace blink |
| OLD | NEW |