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

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

Issue 14096013: Implement select element list box with shadow DOM. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@shadowselect
Patch Set: Created 7 years, 8 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/WebCore/html/HTMLOptionElement.cpp
diff --git a/Source/WebCore/html/HTMLOptionElement.cpp b/Source/WebCore/html/HTMLOptionElement.cpp
index ac0bb7ff1422d2562de922317d6eba4ddfac1f8f..6836ef0db301ce16e6a24e404d6140ded7ed00d8 100644
--- a/Source/WebCore/html/HTMLOptionElement.cpp
+++ b/Source/WebCore/html/HTMLOptionElement.cpp
@@ -34,12 +34,11 @@
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "HTMLSelectElement.h"
-#include "NodeRenderStyle.h"
-#include "NodeRenderingContext.h"
#include "NodeTraversal.h"
#include "RenderMenuList.h"
#include "RenderTheme.h"
#include "ScriptElement.h"
+#include "ShadowRoot.h"
#include "StyleResolver.h"
#include "Text.h"
#include <wtf/StdLibExtras.h>
@@ -62,18 +61,20 @@ HTMLOptionElement::HTMLOptionElement(const QualifiedName& tagName, Document* doc
PassRefPtr<HTMLOptionElement> HTMLOptionElement::create(Document* document)
{
- return adoptRef(new HTMLOptionElement(optionTag, document));
+ return HTMLOptionElement::create(optionTag, document);
}
PassRefPtr<HTMLOptionElement> HTMLOptionElement::create(const QualifiedName& tagName, Document* document)
{
- return adoptRef(new HTMLOptionElement(tagName, document));
+ RefPtr<HTMLOptionElement> option = adoptRef(new HTMLOptionElement(tagName, document));
+ option->ensureUserAgentShadowRoot();
yosin_UTC9 2013/05/01 01:38:21 Can we postpone creating shadow root until this op
+ return option.release();
}
PassRefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document* document, const String& data, const String& value,
bool defaultSelected, bool selected, ExceptionCode& ec)
{
- RefPtr<HTMLOptionElement> element = adoptRef(new HTMLOptionElement(optionTag, document));
+ RefPtr<HTMLOptionElement> element = HTMLOptionElement::create(optionTag, document);
RefPtr<Text> text = Text::create(document, data.isNull() ? "" : data);
@@ -91,22 +92,6 @@ PassRefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document
return element.release();
}
-void HTMLOptionElement::attach()
-{
- HTMLElement::attach();
- // If after attaching nothing called styleForRenderer() on this node we
- // manually cache the value. This happens if our parent doesn't have a
- // renderer like <optgroup> or if it doesn't allow children like <select>.
- if (!m_style && parentNode()->renderStyle())
- updateNonRenderStyle();
-}
-
-void HTMLOptionElement::detach()
-{
- m_style.clear();
- HTMLElement::detach();
-}
-
bool HTMLOptionElement::supportsFocus() const
{
return HTMLElement::supportsFocus();
@@ -216,6 +201,8 @@ void HTMLOptionElement::parseAttribute(const QualifiedName& name, const AtomicSt
// that we need to do more than just set m_isSelected to select in that
// case; we'd need to do the other work from the setSelected function.
m_isSelected = !value.isNull();
+ } else if (name == labelAttr) {
+ updateLabel();
} else
HTMLElement::parseAttribute(name, value);
}
@@ -272,6 +259,7 @@ void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange
#endif
if (HTMLSelectElement* select = ownerSelectElement())
select->optionElementChildrenChanged();
+ updateLabel();
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
@@ -311,34 +299,6 @@ void HTMLOptionElement::setLabel(const String& label)
setAttribute(labelAttr, label);
}
-void HTMLOptionElement::updateNonRenderStyle()
-{
- m_style = document()->styleResolver()->styleForElement(this);
-}
-
-RenderStyle* HTMLOptionElement::nonRendererStyle() const
-{
- return m_style.get();
-}
-
-PassRefPtr<RenderStyle> HTMLOptionElement::customStyleForRenderer()
-{
- // styleForRenderer is called whenever a new style should be associated
- // with an Element so now is a good time to update our cached style.
- updateNonRenderStyle();
- return m_style;
-}
-
-void HTMLOptionElement::didRecalcStyle(StyleChange)
-{
- // FIXME: This is nasty, we ask our owner select to repaint even if the new
- // style is exactly the same.
- if (HTMLSelectElement* select = ownerSelectElement()) {
- if (RenderObject* renderer = select->renderer())
- renderer->repaint();
- }
-}
-
String HTMLOptionElement::textIndentedToRespectGroupLabel() const
{
ContainerNode* parent = parentNode();
@@ -390,6 +350,30 @@ String HTMLOptionElement::collectOptionInnerText() const
return text.toString();
}
+void HTMLOptionElement::updateLabel()
+{
+ Text* const textNode = toText(userAgentShadowRoot()->firstChild());
+ if (textNode)
+ textNode->replaceWholeText(text(), ASSERT_NO_EXCEPTION);
+ else
+ userAgentShadowRoot()->appendChild(Text::create(document(), text()), ASSERT_NO_EXCEPTION);
+}
+
+PassRefPtr<RenderStyle> HTMLOptionElement::customStyleForRenderer()
+{
+ RefPtr<RenderStyle> originalStyle = document()->styleResolver()->styleForElement(this);
+ RefPtr<RenderStyle> style = RenderStyle::clone(originalStyle.get());
+
+ HTMLSelectElement* selectElement = ownerSelectElement();
+ if (selectElement) {
+ const Vector<HTMLElement*>& items = selectElement->listItems();
+ if (items[items.size() - 1] == this)
yosin_UTC9 2013/05/01 01:38:21 nit: We should check item.size() > 0.
+ style->setPaddingBottom(Length(0, Fixed));
+ }
+
+ return style.release();
+}
+
#ifndef NDEBUG
HTMLOptionElement* toHTMLOptionElement(Node* node)

Powered by Google App Engine
This is Rietveld 408576698