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 |