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

Unified Diff: Source/WebCore/html/HTMLOptGroupElement.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/HTMLOptGroupElement.cpp
diff --git a/Source/WebCore/html/HTMLOptGroupElement.cpp b/Source/WebCore/html/HTMLOptGroupElement.cpp
index 11614432d1115f7d9b352092e9ed8103d441b31e..4d66cfba0224c09da6e6c33940ecc3236d9e799d 100644
--- a/Source/WebCore/html/HTMLOptGroupElement.cpp
+++ b/Source/WebCore/html/HTMLOptGroupElement.cpp
@@ -26,18 +26,60 @@
#include "HTMLOptGroupElement.h"
#include "Document.h"
+#include "HTMLContentElement.h"
+#include "HTMLDivElement.h"
#include "HTMLNames.h"
#include "HTMLSelectElement.h"
#include "RenderMenuList.h"
#include "NodeRenderStyle.h"
#include "NodeRenderingContext.h"
#include "StyleResolver.h"
+#include "Text.h"
#include <wtf/StdLibExtras.h>
+#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
using namespace HTMLNames;
+class GroupLabelElement : public HTMLDivElement {
+public:
+ static PassRefPtr<GroupLabelElement> create(Document*);
+
+private:
+ GroupLabelElement(Document* document)
+ : HTMLDivElement(HTMLNames::divTag, document)
+ {
+ setHasCustomStyleCallbacks();
+ }
+ virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
+};
+
+PassRefPtr<GroupLabelElement> GroupLabelElement::create(Document* document)
+{
+ return adoptRef(new GroupLabelElement(document));
+}
+
+PassRefPtr<RenderStyle> GroupLabelElement::customStyleForRenderer()
+{
+ RefPtr<RenderStyle> originalStyle = document()->styleResolver()->styleForElement(this);
+ RefPtr<RenderStyle> style = RenderStyle::clone(originalStyle.get());
+
+ style->setPaddingRight(Length(2, Fixed));
+ style->setPaddingLeft(Length(2, Fixed));
+
+ int paddingBottom = 1;
+ HTMLSelectElement* selectElement = toHTMLOptGroupElement(shadowHost())->ownerSelectElement();
+ if (selectElement) {
+ const Vector<HTMLElement*>& items = selectElement->listItems();
+ if (items[items.size() - 1] == this)
+ paddingBottom = 0;
+ }
+ style->setPaddingBottom(Length(paddingBottom, Fixed));
+
+ return style.release();
+}
+
inline HTMLOptGroupElement::HTMLOptGroupElement(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
{
@@ -48,7 +90,9 @@ inline HTMLOptGroupElement::HTMLOptGroupElement(const QualifiedName& tagName, Do
PassRefPtr<HTMLOptGroupElement> HTMLOptGroupElement::create(const QualifiedName& tagName, Document* document)
{
- return adoptRef(new HTMLOptGroupElement(tagName, document));
+ RefPtr<HTMLOptGroupElement> optGroup = adoptRef(new HTMLOptGroupElement(tagName, document));
+ optGroup->ensureUserAgentShadowRoot();
+ return optGroup.release();
}
bool HTMLOptGroupElement::isDisabledFormControl() const
@@ -86,6 +130,8 @@ void HTMLOptGroupElement::parseAttribute(const QualifiedName& name, const Atomic
if (name == disabledAttr)
didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
+ else if (name == labelAttr)
+ updateGroupLabel();
}
void HTMLOptGroupElement::recalcSelectOptions()
@@ -97,40 +143,6 @@ void HTMLOptGroupElement::recalcSelectOptions()
toHTMLSelectElement(select)->setRecalcListItems();
}
-void HTMLOptGroupElement::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 HTMLOptGroupElement::detach()
-{
- m_style.clear();
- HTMLElement::detach();
-}
-
-void HTMLOptGroupElement::updateNonRenderStyle()
-{
- m_style = document()->styleResolver()->styleForElement(this);
-}
-
-RenderStyle* HTMLOptGroupElement::nonRendererStyle() const
-{
- return m_style.get();
-}
-
-PassRefPtr<RenderStyle> HTMLOptGroupElement::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;
-}
-
String HTMLOptGroupElement::groupLabelText() const
{
String itemText = document()->displayStringModifiedByEncoding(getAttribute(labelAttr));
@@ -163,4 +175,37 @@ void HTMLOptGroupElement::accessKeyAction(bool)
select->accessKeyAction(false);
}
+void HTMLOptGroupElement::didAddUserAgentShadowRoot(ShadowRoot* root)
+{
+ RefPtr<GroupLabelElement> groupLabelElement = GroupLabelElement::create(document());
+ groupLabelElement->appendChild(Text::create(document(), "TEST"), ASSERT_NO_EXCEPTION);
+ root->appendChild(groupLabelElement);
+ m_groupLabelElement = groupLabelElement.get();
+
+ RefPtr<HTMLContentElement> content = HTMLContentElement::create(document());
+ content->setAttribute(selectAttr, "option");
+ root->appendChild(content);
+
+ updateGroupLabel();
+}
+
+void HTMLOptGroupElement::updateGroupLabel()
+{
+ DEFINE_STATIC_LOCAL(String, nonBreakingSpaceString, (&noBreakSpace, 1));
+ String labelText = groupLabelText();
+ if (labelText.isEmpty())
+ labelText = nonBreakingSpaceString;
+ Text* const textNode = toText(userAgentShadowRoot()->firstChild()->firstChild());
+ ASSERT(textNode);
+ if (!textNode)
+ return;
+ textNode->replaceWholeText(labelText, ASSERT_NO_EXCEPTION);
+}
+
+HTMLOptGroupElement* toHTMLOptGroupElement(Node* node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || node->hasTagName(optgroupTag));
+ return static_cast<HTMLOptGroupElement*>(node);
+}
+
} // namespace

Powered by Google App Engine
This is Rietveld 408576698