Chromium Code Reviews| Index: Source/core/html/HTMLOptionElement.cpp |
| diff --git a/Source/core/html/HTMLOptionElement.cpp b/Source/core/html/HTMLOptionElement.cpp |
| index 79239f43d70034107d2d61f13d3d2e29703a3344..4814944c6edc9f56468ab48ace6aad63fb1356ca 100644 |
| --- a/Source/core/html/HTMLOptionElement.cpp |
| +++ b/Source/core/html/HTMLOptionElement.cpp |
| @@ -34,7 +34,9 @@ |
| #include "core/dom/NodeTraversal.h" |
| #include "core/dom/ScriptLoader.h" |
| #include "core/dom/Text.h" |
| +#include "core/dom/shadow/ShadowRoot.h" |
| #include "core/html/HTMLDataListElement.h" |
| +#include "core/html/HTMLOptGroupElement.h" |
| #include "core/html/HTMLSelectElement.h" |
| #include "core/html/parser/HTMLParserIdioms.h" |
| #include "core/rendering/RenderTheme.h" |
| @@ -97,8 +99,11 @@ void HTMLOptionElement::detach(const AttachContext& context) |
| bool HTMLOptionElement::rendererIsFocusable() const |
| { |
| - // Option elements do not have a renderer so we check the renderStyle instead. |
| - return renderStyle() && renderStyle()->display() != NONE; |
| + HTMLSelectElement* selectElement = ownerSelectElement(); |
| + if (!selectElement || selectElement->usesMenuList()) { |
| + return !isDisplayNone(); |
| + } |
| + return HTMLElement::rendererIsFocusable(); |
| } |
| String HTMLOptionElement::text() const |
| @@ -188,6 +193,8 @@ void HTMLOptionElement::parseAttribute(const QualifiedName& name, const AtomicSt |
| } else if (name == selectedAttr) { |
| if (bool willBeSelected = !value.isNull()) |
| setSelected(willBeSelected); |
| + } else if (name == labelAttr) { |
| + updateLabel(); |
| } else |
| HTMLElement::parseAttribute(name, value); |
| } |
| @@ -251,6 +258,7 @@ void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange |
| dataList->optionElementChildrenChanged(); |
| else if (HTMLSelectElement* select = ownerSelectElement()) |
| select->optionElementChildrenChanged(); |
| + updateLabel(); |
| HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); |
| } |
| @@ -277,6 +285,12 @@ void HTMLOptionElement::setLabel(const AtomicString& label) |
| setAttribute(labelAttr, label); |
| } |
| +bool HTMLOptionElement::rendererIsNeeded(const RenderStyle&) |
| +{ |
| + HTMLSelectElement* select = ownerSelectElement(); |
| + return select && !select->usesMenuList() && !isDisplayNone(); |
| +} |
| + |
| void HTMLOptionElement::updateNonRenderStyle() |
| { |
| bool oldDisplayNoneStatus = isDisplayNone(); |
| @@ -329,6 +343,7 @@ bool HTMLOptionElement::isDisabledFormControl() const |
| Node::InsertionNotificationRequest HTMLOptionElement::insertedInto(ContainerNode* insertionPoint) |
| { |
| + HTMLElement::insertedInto(insertionPoint); |
| if (HTMLSelectElement* select = ownerSelectElement()) { |
| select->setRecalcListItems(); |
| // Do not call selected() since calling updateListItemSelectedStates() |
| @@ -339,8 +354,29 @@ Node::InsertionNotificationRequest HTMLOptionElement::insertedInto(ContainerNode |
| select->optionSelectionStateChanged(this, true); |
| select->scrollToSelection(); |
| } |
| + return insertionPoint->inDocument() ? InsertionShouldCallDidNotifySubtreeInsertions : InsertionDone; |
|
keishi
2014/06/22 11:59:55
We can't call ensureUserAgentShadow inside inserte
|
| +} |
| - return HTMLElement::insertedInto(insertionPoint); |
| +void HTMLOptionElement::didNotifySubtreeInsertionsToDocument() |
| +{ |
| + updateView(); |
| +} |
| + |
| +void HTMLOptionElement::updateView() |
| +{ |
| + HTMLSelectElement* select = ownerSelectElement(); |
| + if (select && !select->usesMenuList()) |
|
keishi
2014/06/22 11:59:55
Only create shadow root when shown in a listbox.
|
| + ensureUserAgentShadowRoot(); |
| + else if (userAgentShadowRoot()) |
| + userAgentShadowRoot()->detach(); |
| +} |
| + |
| +void HTMLOptionElement::removedFrom(ContainerNode* insertionPoint) |
| +{ |
| + HTMLSelectElement* select = Traversal<HTMLSelectElement>::firstAncestorOrSelf(*insertionPoint); |
| + if (select) |
| + return select->optionRemoved(this); |
| + HTMLElement::removedFrom(insertionPoint); |
| } |
| String HTMLOptionElement::collectOptionInnerText() const |
| @@ -378,4 +414,16 @@ bool HTMLOptionElement::isDisplayNone() const |
| return style && style->display() == NONE; |
| } |
| +void HTMLOptionElement::updateLabel() |
| +{ |
| + ShadowRoot* root = userAgentShadowRoot(); |
| + if (!root) |
| + return; |
| + Text* const textNode = toText(root->firstChild()); |
| + if (textNode) |
| + textNode->replaceWholeText(textIndentedToRespectGroupLabel()); |
| + else |
| + root->appendChild(Text::create(document(), textIndentedToRespectGroupLabel()), ASSERT_NO_EXCEPTION); |
| +} |
| + |
| } // namespace WebCore |