2011-04-07  Dominic Cooney  <dominicc@google.com>

        Reviewed by Dimitri Glazkov.

        Let shadow DOM have a list of nodes at the top level of a shadow.
        https://bugs.webkit.org/show_bug.cgi?id=57813

        * fast/dom/HTMLKeygenElement/keygen-expected.txt: shadow DOM changed
        * fast/dom/HTMLKeygenElement/keygen.html: added assertion on shadow
2011-04-07  Dominic Cooney  <dominicc@google.com>

        Reviewed by Dimitri Glazkov.

        Let shadow DOM have a list of nodes at the top level of a shadow.
        https://bugs.webkit.org/show_bug.cgi?id=57813

        Adds ShadowRoot, a list of nodes, to be a parent for top-level
        shadow children. Forwards rendering through the root and into the
        host's renderer.

        Covered by existing tests of elements that use this style of shadow.

        * Android.mk: add ShadowRoot.h/cpp
        * CMakeLists.txt:
        * GNUmakefile.am:
        * WebCore.exp.in:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::initForStyleResolve): proxy style to host
        * dom/ContainerNode.cpp: parent nodes that are shadow roots are alive
        (WebCore::ContainerNode::insertBefore):
        (WebCore::ContainerNode::replaceChild):
        (WebCore::ContainerNode::removeChild):
        (WebCore::ContainerNode::appendChild):
        * dom/DocumentFragment.cpp:
        (WebCore::DocumentFragment::DocumentFragment):
        * dom/DocumentFragment.h:
        * dom/Element.cpp:
        (WebCore::Element::recalcStyle): look through ShadowRoots for host's style
        (WebCore::Element::shadowRoot): should be const
        (WebCore::Element::ensureShadowRoot): simpler than setShadowRoot
        * dom/Element.h:
        * dom/ElementRareData.h:
        * dom/Node.cpp:
        (WebCore::Node::parentNodeForRenderingAndStyle): indirection so
          ShadowRoot can forward to the host's renderer
        (WebCore::Node::createRendererAndStyle):
        (WebCore::Node::createRendererIfNeeded):
        * dom/Node.h:
        (WebCore::Node::isShadowBoundary): temporary, to differentiate
          old- and new-style, until all roots are ShadowRoot instances
        * dom/ShadowRoot.cpp: Added.
        (WebCore::ShadowRoot::ShadowRoot):
        (WebCore::ShadowRoot::recalcStyle): forward recalc to children
        * dom/ShadowRoot.h: Added.
        (WebCore::ShadowRoot::isShadowBoundary):
        (WebCore::ShadowRoot::create):
        * html/HTMLKeygenElement.cpp: use ensureShadowRoot
        (WebCore::HTMLKeygenElement::HTMLKeygenElement):
        (WebCore::HTMLKeygenElement::parseMappedAttribute):
        (WebCore::HTMLKeygenElement::appendFormData):
        (WebCore::HTMLKeygenElement::reset):
        (WebCore::HTMLKeygenElement::shadowSelect):
        * html/HTMLKeygenElement.h:
        * html/HTMLMeterElement.cpp: use ensureShadowRoot
        (WebCore::HTMLMeterElement::createShadowSubtree):
        * html/HTMLProgressElement.cpp: use ensureShadowRoot
        (WebCore::HTMLProgressElement::createShadowSubtree):
        * html/InputType.cpp: use ensureShadowRoot
        (WebCore::InputType::destroyShadowSubtree):
        * html/RangeInputType.cpp: use ensureShadowRoot
        (WebCore::RangeInputType::handleMouseDownEvent):
        (WebCore::RangeInputType::createShadowSubtree):
        (WebCore::RangeInputType::valueChanged):
        (WebCore::RangeInputType::shadowSliderThumb):
        * html/RangeInputType.h:
        * html/ValidationMessage.cpp: use ensureShadowRoot
        (WebCore::ValidationMessage::buildBubbleTree):
        (WebCore::ValidationMessage::deleteBubbleTree):
        * html/shadow/SliderThumbElement.cpp:
        (WebCore::SliderThumbElement::setPositionFromPoint):
        (WebCore::SliderThumbElement::hostInput):
        * html/shadow/SliderThumbElement.h:
        * rendering/MediaControlElements.cpp: use ensureShadowRoot
        (WebCore::MediaControlInputElement::attach):
        (WebCore::MediaControlInputElement::updateStyle):
        * rendering/RenderSlider.cpp: use ensureShadowRoot
        (WebCore::RenderSlider::thumbRect):
        (WebCore::RenderSlider::layout):
        (WebCore::RenderSlider::shadowSliderThumb):
        (WebCore::RenderSlider::inDragMode):
        * rendering/RenderSlider.h:
2011-04-07  Dominic Cooney  <dominicc@google.com>

        Reviewed by Dimitri Glazkov.

        Let shadow DOM have a list of nodes at the top level of a shadow.
        https://bugs.webkit.org/show_bug.cgi?id=57813

        * src/WebElement.cpp:
        (WebKit::WebElement::shadowRoot): shadow roots are ContainerNodes now

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@83256 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/html/HTMLKeygenElement.cpp b/Source/WebCore/html/HTMLKeygenElement.cpp
index b90335e..29c9deb 100644
--- a/Source/WebCore/html/HTMLKeygenElement.cpp
+++ b/Source/WebCore/html/HTMLKeygenElement.cpp
@@ -32,6 +32,7 @@
 #include "HTMLSelectElement.h"
 #include "HTMLOptionElement.h"
 #include "SSLKeyGenerator.h"
+#include "ShadowRoot.h"
 #include "Text.h"
 #include <wtf/StdLibExtras.h>
 
@@ -67,15 +68,18 @@
     ASSERT(hasTagName(keygenTag));
 
     // Create a select element with one option element for each key size.
-    RefPtr<HTMLSelectElement> select = KeygenSelectElement::create(document);
     Vector<String> keys;
     getSupportedKeySizes(keys);
+
+    RefPtr<HTMLSelectElement> select = KeygenSelectElement::create(document);
+    ExceptionCode ec = 0;
     for (size_t i = 0; i < keys.size(); ++i) {
         RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document, this->form());
-        select->parserAddChild(option);
-        option->parserAddChild(Text::create(document, keys[i]));
+        select->appendChild(option, ec);
+        option->appendChild(Text::create(document, keys[i]), ec);
     }
-    setShadowRoot(select);
+
+    ensureShadowRoot()->appendChild(select, ec);
 }
 
 PassRefPtr<HTMLKeygenElement> HTMLKeygenElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
@@ -87,7 +91,7 @@
 {
     // Reflect disabled attribute on the shadow select element
     if (attr->name() == disabledAttr)
-        selectShadow()->setAttribute(attr->name(), attr->value());
+        shadowSelect()->setAttribute(attr->name(), attr->value());
 
     if (attr->name() == challengeAttr)
         m_challenge = attr->value();
@@ -102,7 +106,7 @@
     // Only RSA is supported at this time.
     if (!m_keyType.isNull() && !equalIgnoringCase(m_keyType, "rsa"))
         return false;
-    String value = signedPublicKeyAndChallengeString(selectShadow()->selectedIndex(), m_challenge, document()->baseURL());
+    String value = signedPublicKeyAndChallengeString(shadowSelect()->selectedIndex(), m_challenge, document()->baseURL());
     if (value.isNull())
         return false;
     encoded_values.appendData(name(), value.utf8());
@@ -117,12 +121,14 @@
 
 void HTMLKeygenElement::reset()
 {
-    static_cast<HTMLFormControlElement*>(selectShadow())->reset();
+    static_cast<HTMLFormControlElement*>(shadowSelect())->reset();
 }
 
-HTMLSelectElement* HTMLKeygenElement::selectShadow()
+HTMLSelectElement* HTMLKeygenElement::shadowSelect() const
 {
-    return static_cast<HTMLSelectElement*>(shadowRoot());
+    Node* shadow = shadowRoot();
+    ASSERT(shadow);
+    return shadow ? static_cast<HTMLSelectElement*>(shadow->firstChild()) : 0;
 }
 
 } // namespace