| 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
|
|
|