OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 5 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
6 * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. |
7 * Copyright (C) 2010 Google Inc. All rights reserved. | 7 * Copyright (C) 2010 Google Inc. All rights reserved. |
8 * Copyright (C) 2011 Motorola Mobility, Inc. All rights reserved. | 8 * Copyright (C) 2011 Motorola Mobility, Inc. All rights reserved. |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "core/layout/LayoutTheme.h" | 42 #include "core/layout/LayoutTheme.h" |
43 #include "wtf/Vector.h" | 43 #include "wtf/Vector.h" |
44 #include "wtf/text/StringBuilder.h" | 44 #include "wtf/text/StringBuilder.h" |
45 | 45 |
46 namespace blink { | 46 namespace blink { |
47 | 47 |
48 using namespace HTMLNames; | 48 using namespace HTMLNames; |
49 | 49 |
50 HTMLOptionElement::HTMLOptionElement(Document& document) | 50 HTMLOptionElement::HTMLOptionElement(Document& document) |
51 : HTMLElement(optionTag, document), m_isSelected(false) { | 51 : HTMLElement(optionTag, document), m_isSelected(false) { |
52 setHasCustomStyleCallbacks(); | |
53 } | 52 } |
54 | 53 |
55 // An explicit empty destructor should be in HTMLOptionElement.cpp, because | 54 // An explicit empty destructor should be in HTMLOptionElement.cpp, because |
56 // if an implicit destructor is used or an empty destructor is defined in | 55 // if an implicit destructor is used or an empty destructor is defined in |
57 // HTMLOptionElement.h, when including HTMLOptionElement.h, | 56 // HTMLOptionElement.h, when including HTMLOptionElement.h, |
58 // msvc tries to expand the destructor and causes | 57 // msvc tries to expand the destructor and causes |
59 // a compile error because of lack of ComputedStyle definition. | 58 // a compile error because of lack of ComputedStyle definition. |
60 HTMLOptionElement::~HTMLOptionElement() {} | 59 HTMLOptionElement::~HTMLOptionElement() {} |
61 | 60 |
62 HTMLOptionElement* HTMLOptionElement::create(Document& document) { | 61 HTMLOptionElement* HTMLOptionElement::create(Document& document) { |
(...skipping 20 matching lines...) Expand all Loading... |
83 element->setValue(value); | 82 element->setValue(value); |
84 if (defaultSelected) | 83 if (defaultSelected) |
85 element->setAttribute(selectedAttr, emptyAtom); | 84 element->setAttribute(selectedAttr, emptyAtom); |
86 element->setSelected(selected); | 85 element->setSelected(selected); |
87 | 86 |
88 return element; | 87 return element; |
89 } | 88 } |
90 | 89 |
91 void HTMLOptionElement::attachLayoutTree(const AttachContext& context) { | 90 void HTMLOptionElement::attachLayoutTree(const AttachContext& context) { |
92 AttachContext optionContext(context); | 91 AttachContext optionContext(context); |
93 if (context.resolvedStyle) { | 92 RefPtr<ComputedStyle> resolvedStyle; |
94 DCHECK(!m_style || m_style == context.resolvedStyle); | 93 if (!context.resolvedStyle && parentComputedStyle()) { |
95 m_style = context.resolvedStyle; | 94 if (HTMLSelectElement* select = ownerSelectElement()) |
96 } else if (parentComputedStyle()) { | 95 select->updateListOnLayoutObject(); |
97 updateNonComputedStyle(); | 96 resolvedStyle = originalStyleForLayoutObject(); |
98 optionContext.resolvedStyle = m_style.get(); | 97 optionContext.resolvedStyle = resolvedStyle.get(); |
99 } | 98 } |
100 HTMLElement::attachLayoutTree(optionContext); | 99 HTMLElement::attachLayoutTree(optionContext); |
101 } | 100 } |
102 | 101 |
103 void HTMLOptionElement::detachLayoutTree(const AttachContext& context) { | 102 void HTMLOptionElement::detachLayoutTree(const AttachContext& context) { |
104 m_style.clear(); | |
105 HTMLElement::detachLayoutTree(context); | 103 HTMLElement::detachLayoutTree(context); |
106 } | 104 } |
107 | 105 |
108 bool HTMLOptionElement::supportsFocus() const { | 106 bool HTMLOptionElement::supportsFocus() const { |
109 HTMLSelectElement* select = ownerSelectElement(); | 107 HTMLSelectElement* select = ownerSelectElement(); |
110 if (select && select->usesMenuList()) | 108 if (select && select->usesMenuList()) |
111 return false; | 109 return false; |
112 return HTMLElement::supportsFocus(); | 110 return HTMLElement::supportsFocus(); |
113 } | 111 } |
114 | 112 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 return label; | 321 return label; |
324 return collectOptionInnerText() | 322 return collectOptionInnerText() |
325 .stripWhiteSpace(isHTMLSpace<UChar>) | 323 .stripWhiteSpace(isHTMLSpace<UChar>) |
326 .simplifyWhiteSpace(isHTMLSpace<UChar>); | 324 .simplifyWhiteSpace(isHTMLSpace<UChar>); |
327 } | 325 } |
328 | 326 |
329 void HTMLOptionElement::setLabel(const AtomicString& label) { | 327 void HTMLOptionElement::setLabel(const AtomicString& label) { |
330 setAttribute(labelAttr, label); | 328 setAttribute(labelAttr, label); |
331 } | 329 } |
332 | 330 |
333 void HTMLOptionElement::updateNonComputedStyle() { | |
334 m_style = originalStyleForLayoutObject(); | |
335 if (HTMLSelectElement* select = ownerSelectElement()) | |
336 select->updateListOnLayoutObject(); | |
337 } | |
338 | |
339 ComputedStyle* HTMLOptionElement::nonLayoutObjectComputedStyle() const { | |
340 return m_style.get(); | |
341 } | |
342 | |
343 PassRefPtr<ComputedStyle> HTMLOptionElement::customStyleForLayoutObject() { | |
344 updateNonComputedStyle(); | |
345 return m_style; | |
346 } | |
347 | |
348 String HTMLOptionElement::textIndentedToRespectGroupLabel() const { | 331 String HTMLOptionElement::textIndentedToRespectGroupLabel() const { |
349 ContainerNode* parent = parentNode(); | 332 ContainerNode* parent = parentNode(); |
350 if (parent && isHTMLOptGroupElement(*parent)) | 333 if (parent && isHTMLOptGroupElement(*parent)) |
351 return " " + displayLabel(); | 334 return " " + displayLabel(); |
352 return displayLabel(); | 335 return displayLabel(); |
353 } | 336 } |
354 | 337 |
355 bool HTMLOptionElement::ownElementDisabled() const { | 338 bool HTMLOptionElement::ownElementDisabled() const { |
356 return fastHasAttribute(disabledAttr); | 339 return fastHasAttribute(disabledAttr); |
357 } | 340 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 } | 407 } |
425 | 408 |
426 bool HTMLOptionElement::spatialNavigationFocused() const { | 409 bool HTMLOptionElement::spatialNavigationFocused() const { |
427 HTMLSelectElement* select = ownerSelectElement(); | 410 HTMLSelectElement* select = ownerSelectElement(); |
428 if (!select || !select->isFocused()) | 411 if (!select || !select->isFocused()) |
429 return false; | 412 return false; |
430 return select->spatialNavigationFocusedOption() == this; | 413 return select->spatialNavigationFocusedOption() == this; |
431 } | 414 } |
432 | 415 |
433 bool HTMLOptionElement::isDisplayNone() const { | 416 bool HTMLOptionElement::isDisplayNone() const { |
434 // If m_style is not set, then the node is still unattached. | 417 // If the style is not set, then the node is still unattached. |
435 // We have to wait till it gets attached to read the display property. | 418 // We have to wait till it gets attached to read the display property. |
436 if (!m_style) | 419 const ComputedStyle* style = nonLayoutObjectComputedStyle(); |
| 420 if (!style) |
437 return false; | 421 return false; |
438 | 422 |
439 if (m_style->display() != EDisplay::None) { | 423 if (style->display() != EDisplay::None) { |
440 // We need to check the parent's display property. Parent's | 424 // We need to check the parent's display property. Parent's |
441 // display:none doesn't override children's display properties in | 425 // display:none doesn't override children's display properties in |
442 // ComputedStyle. | 426 // ComputedStyle. |
443 Element* parent = parentElement(); | 427 Element* parent = parentElement(); |
444 DCHECK(parent); | 428 DCHECK(parent); |
445 if (isHTMLOptGroupElement(*parent)) { | 429 if (isHTMLOptGroupElement(*parent)) { |
446 const ComputedStyle* parentStyle = parent->computedStyle() | 430 const ComputedStyle* parentStyle = parent->computedStyle() |
447 ? parent->computedStyle() | 431 ? parent->computedStyle() |
448 : parent->ensureComputedStyle(); | 432 : parent->ensureComputedStyle(); |
449 return !parentStyle || parentStyle->display() == EDisplay::None; | 433 return !parentStyle || parentStyle->display() == EDisplay::None; |
450 } | 434 } |
451 } | 435 } |
452 return m_style->display() == EDisplay::None; | 436 return style->display() == EDisplay::None; |
453 } | 437 } |
454 | 438 |
455 String HTMLOptionElement::innerText() { | 439 String HTMLOptionElement::innerText() { |
456 // A workaround for crbug.com/424578. We add ShadowRoot to an OPTION, but | 440 // A workaround for crbug.com/424578. We add ShadowRoot to an OPTION, but |
457 // innerText behavior for Shadow DOM is unclear. We just return the same | 441 // innerText behavior for Shadow DOM is unclear. We just return the same |
458 // string before adding ShadowRoot. | 442 // string before adding ShadowRoot. |
459 return textContent(); | 443 return textContent(); |
460 } | 444 } |
461 | 445 |
462 } // namespace blink | 446 } // namespace blink |
OLD | NEW |