Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(723)

Unified Diff: Source/core/html/HTMLOptionElement.cpp

Issue 347773002: Implement select listbox using shadow DOM (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698