Handle createShadowSubtree inside of ensureUserAgentShadowRoot
https://bugs.webkit.org/show_bug.cgi?id=108116

Reviewed by Dimitri Glazkov.

Instead of making everyone create the UserAgentShadowRoot manually all
over, centralize it in ensureUserAgentShadowRoot() and add a notification
Element::didAddUserAgentShadowRoot that lets elements fill in the subtree.
This lets us get rid of lots of code duplication.

No new tests, just refactoring.

* dom/Element.cpp:
(WebCore::Element::ensureUserAgentShadowRoot):
* dom/Element.h:
(WebCore::Element::didAddUserAgentShadowRoot):
(Element):
* html/HTMLDetailsElement.cpp:
(WebCore::DetailsSummaryElement::create):
(WebCore::HTMLDetailsElement::create):
(WebCore::HTMLDetailsElement::didAddUserAgentShadowRoot):
* html/HTMLDetailsElement.h:
(HTMLDetailsElement):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::create):
(WebCore::HTMLInputElement::didAddUserAgentShadowRoot):
* html/HTMLInputElement.h:
(HTMLInputElement):
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::willAddAuthorShadowRoot):
(WebCore::HTMLMediaElement::createMediaControls):
* html/HTMLMediaElement.h:
* html/HTMLMeterElement.cpp:
(WebCore::HTMLMeterElement::create):
(WebCore::HTMLMeterElement::didAddUserAgentShadowRoot):
* html/HTMLMeterElement.h:
(HTMLMeterElement):
* html/HTMLProgressElement.cpp:
(WebCore::HTMLProgressElement::create):
(WebCore::HTMLProgressElement::didAddUserAgentShadowRoot):
* html/HTMLProgressElement.h:
* html/HTMLSummaryElement.cpp:
(WebCore::HTMLSummaryElement::create):
(WebCore::HTMLSummaryElement::didAddUserAgentShadowRoot):
* html/HTMLSummaryElement.h:
(HTMLSummaryElement):
* html/HTMLTextAreaElement.cpp:
(WebCore::HTMLTextAreaElement::create):
(WebCore::HTMLTextAreaElement::didAddUserAgentShadowRoot):
* html/HTMLTextAreaElement.h:
* html/shadow/MediaControlElements.cpp:
(WebCore::MediaControlPanelMuteButtonElement::create):
(WebCore::MediaControlVolumeSliderMuteButtonElement::create):
(WebCore::MediaControlPlayButtonElement::create):
(WebCore::MediaControlOverlayPlayButtonElement::create):
(WebCore::MediaControlSeekForwardButtonElement::create):
(WebCore::MediaControlSeekBackButtonElement::create):
(WebCore::MediaControlRewindButtonElement::create):
(WebCore::MediaControlReturnToRealtimeButtonElement::create):
(WebCore::MediaControlToggleClosedCaptionsButtonElement::create):
(WebCore::MediaControlTimelineElement::create):
(WebCore::MediaControlPanelVolumeSliderElement::create):
(WebCore::MediaControlFullscreenVolumeSliderElement::create):
(WebCore::MediaControlFullscreenButtonElement::create):
(WebCore::MediaControlFullscreenVolumeMinButtonElement::create):
(WebCore::MediaControlFullscreenVolumeMaxButtonElement::create):
* html/shadow/MediaControlsBlackBerry.cpp:
(WebCore::MediaControlFullscreenPlayButtonElement::create):
(WebCore::MediaControlFullscreenFullscreenButtonElement::create):
(WebCore::MediaControlFullscreenTimelineElement::create):
(WebCore::MediaControlAudioMuteButtonElement::create):
* svg/SVGTRefElement.cpp:
(WebCore::SVGTRefElement::create):
* svg/SVGTRefElement.h:
(SVGTRefElement):
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::create):
* svg/SVGUseElement.h:
(SVGUseElement):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@141066 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 5149702..23dce8a 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,85 @@
+2013-01-28  Elliott Sprehn  <esprehn@chromium.org>
+
+        Handle createShadowSubtree inside of ensureUserAgentShadowRoot
+        https://bugs.webkit.org/show_bug.cgi?id=108116
+
+        Reviewed by Dimitri Glazkov.
+
+        Instead of making everyone create the UserAgentShadowRoot manually all
+        over, centralize it in ensureUserAgentShadowRoot() and add a notification
+        Element::didAddUserAgentShadowRoot that lets elements fill in the subtree.
+        This lets us get rid of lots of code duplication.
+
+        No new tests, just refactoring.
+
+        * dom/Element.cpp:
+        (WebCore::Element::ensureUserAgentShadowRoot):
+        * dom/Element.h:
+        (WebCore::Element::didAddUserAgentShadowRoot):
+        (Element):
+        * html/HTMLDetailsElement.cpp:
+        (WebCore::DetailsSummaryElement::create):
+        (WebCore::HTMLDetailsElement::create):
+        (WebCore::HTMLDetailsElement::didAddUserAgentShadowRoot):
+        * html/HTMLDetailsElement.h:
+        (HTMLDetailsElement):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::create):
+        (WebCore::HTMLInputElement::didAddUserAgentShadowRoot):
+        * html/HTMLInputElement.h:
+        (HTMLInputElement):
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::willAddAuthorShadowRoot):
+        (WebCore::HTMLMediaElement::createMediaControls):
+        * html/HTMLMediaElement.h:
+        * html/HTMLMeterElement.cpp:
+        (WebCore::HTMLMeterElement::create):
+        (WebCore::HTMLMeterElement::didAddUserAgentShadowRoot):
+        * html/HTMLMeterElement.h:
+        (HTMLMeterElement):
+        * html/HTMLProgressElement.cpp:
+        (WebCore::HTMLProgressElement::create):
+        (WebCore::HTMLProgressElement::didAddUserAgentShadowRoot):
+        * html/HTMLProgressElement.h:
+        * html/HTMLSummaryElement.cpp:
+        (WebCore::HTMLSummaryElement::create):
+        (WebCore::HTMLSummaryElement::didAddUserAgentShadowRoot):
+        * html/HTMLSummaryElement.h:
+        (HTMLSummaryElement):
+        * html/HTMLTextAreaElement.cpp:
+        (WebCore::HTMLTextAreaElement::create):
+        (WebCore::HTMLTextAreaElement::didAddUserAgentShadowRoot):
+        * html/HTMLTextAreaElement.h:
+        * html/shadow/MediaControlElements.cpp:
+        (WebCore::MediaControlPanelMuteButtonElement::create):
+        (WebCore::MediaControlVolumeSliderMuteButtonElement::create):
+        (WebCore::MediaControlPlayButtonElement::create):
+        (WebCore::MediaControlOverlayPlayButtonElement::create):
+        (WebCore::MediaControlSeekForwardButtonElement::create):
+        (WebCore::MediaControlSeekBackButtonElement::create):
+        (WebCore::MediaControlRewindButtonElement::create):
+        (WebCore::MediaControlReturnToRealtimeButtonElement::create):
+        (WebCore::MediaControlToggleClosedCaptionsButtonElement::create):
+        (WebCore::MediaControlTimelineElement::create):
+        (WebCore::MediaControlPanelVolumeSliderElement::create):
+        (WebCore::MediaControlFullscreenVolumeSliderElement::create):
+        (WebCore::MediaControlFullscreenButtonElement::create):
+        (WebCore::MediaControlFullscreenVolumeMinButtonElement::create):
+        (WebCore::MediaControlFullscreenVolumeMaxButtonElement::create):
+        * html/shadow/MediaControlsBlackBerry.cpp:
+        (WebCore::MediaControlFullscreenPlayButtonElement::create):
+        (WebCore::MediaControlFullscreenFullscreenButtonElement::create):
+        (WebCore::MediaControlFullscreenTimelineElement::create):
+        (WebCore::MediaControlAudioMuteButtonElement::create):
+        * svg/SVGTRefElement.cpp:
+        (WebCore::SVGTRefElement::create):
+        * svg/SVGTRefElement.h:
+        (SVGTRefElement):
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::create):
+        * svg/SVGUseElement.h:
+        (SVGUseElement):
+
 2013-01-28   Vineet Chaudhary  <rgf748@motorola.com>
 
         HTMLOutputElement::htmlFor should be readonly
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
index 72f602c..fd924f6 100644
--- a/Source/WebCore/dom/Element.cpp
+++ b/Source/WebCore/dom/Element.cpp
@@ -1492,7 +1492,9 @@
 {
     if (ShadowRoot* shadowRoot = userAgentShadowRoot())
         return shadowRoot;
-    return ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION).get();
+    ShadowRoot* shadowRoot = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION).get();
+    didAddUserAgentShadowRoot(shadowRoot);
+    return shadowRoot;
 }
 
 const AtomicString& Element::shadowPseudoId() const
diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h
index e071222..ef39359 100644
--- a/Source/WebCore/dom/Element.h
+++ b/Source/WebCore/dom/Element.h
@@ -530,6 +530,8 @@
     PassRefPtr<PseudoElement> createPseudoElementIfNeeded(PseudoId);
     void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
 
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) { }
+
     // FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute.
     friend class Attr;
 
diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp
index 05eebab..5c67dbc 100644
--- a/Source/WebCore/html/HTMLDetailsElement.cpp
+++ b/Source/WebCore/html/HTMLDetailsElement.cpp
@@ -83,20 +83,19 @@
 
 PassRefPtr<DetailsSummaryElement> DetailsSummaryElement::create(Document* document)
 {
-    RefPtr<HTMLSummaryElement> defaultSummary = HTMLSummaryElement::create(summaryTag, document);
-    defaultSummary->appendChild(Text::create(document, defaultDetailsSummaryText()), ASSERT_NO_EXCEPTION);
+    RefPtr<HTMLSummaryElement> summary = HTMLSummaryElement::create(summaryTag, document);
+    summary->appendChild(Text::create(document, defaultDetailsSummaryText()), ASSERT_NO_EXCEPTION);
 
-    RefPtr<DetailsSummaryElement> elem = adoptRef(new DetailsSummaryElement(document));
-    elem->appendChild(defaultSummary);
-    return elem.release();
+    RefPtr<DetailsSummaryElement> detailsSummary = adoptRef(new DetailsSummaryElement(document));
+    detailsSummary->appendChild(summary);
+    return detailsSummary.release();
 }
 
 PassRefPtr<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document* document)
 {
-    RefPtr<HTMLDetailsElement> elem = adoptRef(new HTMLDetailsElement(tagName, document));
-    elem->createShadowSubtree();
-
-    return elem.release();
+    RefPtr<HTMLDetailsElement> details = adoptRef(new HTMLDetailsElement(tagName, document));
+    details->ensureUserAgentShadowRoot();
+    return details.release();
 }
 
 HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document* document)
@@ -111,11 +110,8 @@
     return new (arena) RenderBlock(this);
 }
 
-void HTMLDetailsElement::createShadowSubtree()
+void HTMLDetailsElement::didAddUserAgentShadowRoot(ShadowRoot* root)
 {
-    ASSERT(!shadow());
-
-    RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot);
     root->appendChild(DetailsSummaryElement::create(document()), ASSERT_NO_EXCEPTION, true);
     root->appendChild(DetailsContentElement::create(document()), ASSERT_NO_EXCEPTION, true);
 }
diff --git a/Source/WebCore/html/HTMLDetailsElement.h b/Source/WebCore/html/HTMLDetailsElement.h
index 9da9698..864d521 100644
--- a/Source/WebCore/html/HTMLDetailsElement.h
+++ b/Source/WebCore/html/HTMLDetailsElement.h
@@ -39,10 +39,9 @@
     virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
 
-    void createShadowSubtree();
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) OVERRIDE;
 
     bool m_isOpen;
-
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 6aaf994..b1eeb0a 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -138,15 +138,12 @@
 PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
 {
     RefPtr<HTMLInputElement> inputElement = adoptRef(new HTMLInputElement(tagName, document, form, createdByParser));
-    inputElement->createShadowSubtree();
+    inputElement->ensureUserAgentShadowRoot();
     return inputElement.release();
 }
 
-void HTMLInputElement::createShadowSubtree()
+void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot*)
 {
-    ASSERT(!shadow());
-    ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION);
-
     m_inputType->createShadowSubtree();
 }
 
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
index 5b86918..b9daafd 100644
--- a/Source/WebCore/html/HTMLInputElement.h
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -301,8 +301,9 @@
 
 protected:
     HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser);
-    void createShadowSubtree();
+
     virtual void defaultEventHandler(Event*);
+
     // FIXME: Author shadows should be allowed
     // https://bugs.webkit.org/show_bug.cgi?id=92608
     virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
@@ -310,6 +311,8 @@
 private:
     enum AutoCompleteSetting { Uninitialized, On, Off };
 
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) OVERRIDE;
+
     virtual void willChangeForm() OVERRIDE;
     virtual void didChangeForm() OVERRIDE;
     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index 32cfa50..ed5b8eb 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -1980,16 +1980,10 @@
     }
 }
 
-void HTMLMediaElement::createShadowSubtree()
-{
-    ASSERT(!userAgentShadowRoot());
-    ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot);
-}
-
 void HTMLMediaElement::willAddAuthorShadowRoot()
 {
     if (!userAgentShadowRoot())
-        createShadowSubtree();
+        ensureUserAgentShadowRoot();
 }
 
 void HTMLMediaElement::rewind(float timeDelta)
@@ -4306,11 +4300,7 @@
     if (isFullscreen())
         mediaControls->enteredFullscreen();
 
-    if (!shadow())
-        createShadowSubtree();
-
-    ASSERT(userAgentShadowRoot());
-    userAgentShadowRoot()->appendChild(mediaControls, ASSERT_NO_EXCEPTION);
+    ensureUserAgentShadowRoot()->appendChild(mediaControls, ASSERT_NO_EXCEPTION);
 
     if (!controls() || !inDocument())
         mediaControls->hide();
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
index 8144edc..38b0780 100644
--- a/Source/WebCore/html/HTMLMediaElement.h
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -88,7 +88,6 @@
 public:
     MediaPlayer* player() const { return m_player.get(); }
 
-    void createShadowSubtree();
     virtual void willAddAuthorShadowRoot() OVERRIDE;
     virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
 
diff --git a/Source/WebCore/html/HTMLMeterElement.cpp b/Source/WebCore/html/HTMLMeterElement.cpp
index 465d0ff..3918331 100644
--- a/Source/WebCore/html/HTMLMeterElement.cpp
+++ b/Source/WebCore/html/HTMLMeterElement.cpp
@@ -54,7 +54,7 @@
 PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document* document)
 {
     RefPtr<HTMLMeterElement> meter = adoptRef(new HTMLMeterElement(tagName, document));
-    meter->createShadowSubtree();
+    meter->ensureUserAgentShadowRoot();
     return meter;
 }
 
@@ -234,11 +234,9 @@
     return static_cast<RenderMeter*>(renderObject);
 }
 
-void HTMLMeterElement::createShadowSubtree()
+void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot* root)
 {
-    ASSERT(!userAgentShadowRoot());
-           
-    RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION);
+    ASSERT(!m_value);
 
     RefPtr<MeterInnerElement> inner = MeterInnerElement::create(document());
     root->appendChild(inner);
diff --git a/Source/WebCore/html/HTMLMeterElement.h b/Source/WebCore/html/HTMLMeterElement.h
index f58e351..0b81c08 100644
--- a/Source/WebCore/html/HTMLMeterElement.h
+++ b/Source/WebCore/html/HTMLMeterElement.h
@@ -79,7 +79,7 @@
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
 
     void didElementStateChange();
-    void createShadowSubtree();
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) OVERRIDE;
 
     RefPtr<MeterValueElement> m_value;
 };
diff --git a/Source/WebCore/html/HTMLProgressElement.cpp b/Source/WebCore/html/HTMLProgressElement.cpp
index 84b2e89..802f354 100644
--- a/Source/WebCore/html/HTMLProgressElement.cpp
+++ b/Source/WebCore/html/HTMLProgressElement.cpp
@@ -55,8 +55,8 @@
 PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document* document)
 {
     RefPtr<HTMLProgressElement> progress = adoptRef(new HTMLProgressElement(tagName, document));
-    progress->createShadowSubtree();
-    return progress;
+    progress->ensureUserAgentShadowRoot();
+    return progress.release();
 }
 
 RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyle* style)
@@ -157,12 +157,9 @@
     }
 }
 
-void HTMLProgressElement::createShadowSubtree()
+void HTMLProgressElement::didAddUserAgentShadowRoot(ShadowRoot* root)
 {
-    ASSERT(!userAgentShadowRoot());
     ASSERT(!m_value);
-           
-    RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION);
 
     RefPtr<ProgressInnerElement> inner = ProgressInnerElement::create(document());
     root->appendChild(inner);
diff --git a/Source/WebCore/html/HTMLProgressElement.h b/Source/WebCore/html/HTMLProgressElement.h
index 33c96143..df7b772 100644
--- a/Source/WebCore/html/HTMLProgressElement.h
+++ b/Source/WebCore/html/HTMLProgressElement.h
@@ -67,7 +67,7 @@
     virtual void attach();
 
     void didElementStateChange();
-    void createShadowSubtree();
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) OVERRIDE;
 
     ProgressValueElement* m_value;
 };
diff --git a/Source/WebCore/html/HTMLSummaryElement.cpp b/Source/WebCore/html/HTMLSummaryElement.cpp
index 9039b40..800ae1b 100644
--- a/Source/WebCore/html/HTMLSummaryElement.cpp
+++ b/Source/WebCore/html/HTMLSummaryElement.cpp
@@ -55,9 +55,9 @@
 
 PassRefPtr<HTMLSummaryElement> HTMLSummaryElement::create(const QualifiedName& tagName, Document* document)
 {
-    RefPtr<HTMLSummaryElement> result = adoptRef(new HTMLSummaryElement(tagName, document));
-    result->createShadowSubtree();
-    return result;
+    RefPtr<HTMLSummaryElement> summary = adoptRef(new HTMLSummaryElement(tagName, document));
+    summary->ensureUserAgentShadowRoot();
+    return summary.release();
 }
 
 HTMLSummaryElement::HTMLSummaryElement(const QualifiedName& tagName, Document* document)
@@ -76,10 +76,8 @@
     return childContext.isOnEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext);
 }
 
-void HTMLSummaryElement::createShadowSubtree()
+void HTMLSummaryElement::didAddUserAgentShadowRoot(ShadowRoot* root)
 {
-    ASSERT(!shadow());
-    RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot);
     root->appendChild(DetailsMarkerControl::create(document()), ASSERT_NO_EXCEPTION, true);
     root->appendChild(SummaryContentElement::create(document()), ASSERT_NO_EXCEPTION, true);
 }
diff --git a/Source/WebCore/html/HTMLSummaryElement.h b/Source/WebCore/html/HTMLSummaryElement.h
index 2c8a93f..715fe9a 100644
--- a/Source/WebCore/html/HTMLSummaryElement.h
+++ b/Source/WebCore/html/HTMLSummaryElement.h
@@ -40,7 +40,7 @@
     virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
     virtual void defaultEventHandler(Event*);
 
-    void createShadowSubtree();
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) OVERRIDE;
     HTMLDetailsElement* detailsElement() const;
 
     bool supportsFocus() const OVERRIDE;
diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp
index c50c5bc..7618a33 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.cpp
+++ b/Source/WebCore/html/HTMLTextAreaElement.cpp
@@ -98,14 +98,12 @@
 PassRefPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
 {
     RefPtr<HTMLTextAreaElement> textArea = adoptRef(new HTMLTextAreaElement(tagName, document, form));
-    textArea->createShadowSubtree();
+    textArea->ensureUserAgentShadowRoot();
     return textArea.release();
 }
 
-void HTMLTextAreaElement::createShadowSubtree()
+void HTMLTextAreaElement::didAddUserAgentShadowRoot(ShadowRoot* root)
 {
-    ASSERT(!shadow());
-    RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot);
     root->appendChild(TextControlInnerTextElement::create(document()), ASSERT_NO_EXCEPTION);
 }
 
diff --git a/Source/WebCore/html/HTMLTextAreaElement.h b/Source/WebCore/html/HTMLTextAreaElement.h
index e16a695..524e0f0 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.h
+++ b/Source/WebCore/html/HTMLTextAreaElement.h
@@ -65,7 +65,7 @@
 
     enum WrapMethod { NoWrap, SoftWrap, HardWrap };
 
-    void createShadowSubtree();
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) OVERRIDE;
     virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
 
     void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) const;
diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp
index 6f01f6f..a1676ea 100644
--- a/Source/WebCore/html/shadow/MediaControlElements.cpp
+++ b/Source/WebCore/html/shadow/MediaControlElements.cpp
@@ -425,7 +425,7 @@
     ASSERT(controls);
 
     RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(document, controls));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -454,7 +454,7 @@
 PassRefPtr<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(Document* document)
 {
     RefPtr<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -475,7 +475,7 @@
 PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document* document)
 {
     RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -514,7 +514,7 @@
 PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document* document)
 {
     RefPtr<MediaControlOverlayPlayButtonElement> button = adoptRef(new MediaControlOverlayPlayButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -554,7 +554,7 @@
 PassRefPtr<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(Document* document)
 {
     RefPtr<MediaControlSeekForwardButtonElement> button = adoptRef(new MediaControlSeekForwardButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -575,7 +575,7 @@
 PassRefPtr<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(Document* document)
 {
     RefPtr<MediaControlSeekBackButtonElement> button = adoptRef(new MediaControlSeekBackButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -596,7 +596,7 @@
 PassRefPtr<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(Document* document)
 {
     RefPtr<MediaControlRewindButtonElement> button = adoptRef(new MediaControlRewindButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -627,7 +627,7 @@
 PassRefPtr<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(Document* document)
 {
     RefPtr<MediaControlReturnToRealtimeButtonElement> button = adoptRef(new MediaControlReturnToRealtimeButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     button->hide();
     return button.release();
@@ -666,7 +666,7 @@
     ASSERT(controls);
 
     RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document, controls));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     button->hide();
     return button.release();
@@ -954,7 +954,7 @@
     ASSERT(controls);
 
     RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(document, controls));
-    timeline->createShadowSubtree();
+    timeline->ensureUserAgentShadowRoot();
     timeline->setType("range");
     timeline->setAttribute(precisionAttr, "float");
     return timeline.release();
@@ -1026,7 +1026,7 @@
 PassRefPtr<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document* document)
 {
     RefPtr<MediaControlPanelVolumeSliderElement> slider = adoptRef(new MediaControlPanelVolumeSliderElement(document));
-    slider->createShadowSubtree();
+    slider->ensureUserAgentShadowRoot();
     slider->setType("range");
     slider->setAttribute(precisionAttr, "float");
     slider->setAttribute(maxAttr, "1");
@@ -1049,7 +1049,7 @@
 PassRefPtr<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSliderElement::create(Document* document)
 {
     RefPtr<MediaControlFullscreenVolumeSliderElement> slider = adoptRef(new MediaControlFullscreenVolumeSliderElement(document));
-    slider->createShadowSubtree();
+    slider->ensureUserAgentShadowRoot();
     slider->setType("range");
     slider->setAttribute(precisionAttr, "float");
     slider->setAttribute(maxAttr, "1");
@@ -1072,7 +1072,7 @@
 PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document* document)
 {
     RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     button->hide();
     return button.release();
@@ -1121,7 +1121,7 @@
 PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenVolumeMinButtonElement::create(Document* document)
 {
     RefPtr<MediaControlFullscreenVolumeMinButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMinButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -1152,7 +1152,7 @@
 PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenVolumeMaxButtonElement::create(Document* document)
 {
     RefPtr<MediaControlFullscreenVolumeMaxButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMaxButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
diff --git a/Source/WebCore/html/shadow/MediaControlsBlackBerry.cpp b/Source/WebCore/html/shadow/MediaControlsBlackBerry.cpp
index 320f707..eb92657 100644
--- a/Source/WebCore/html/shadow/MediaControlsBlackBerry.cpp
+++ b/Source/WebCore/html/shadow/MediaControlsBlackBerry.cpp
@@ -375,7 +375,7 @@
 PassRefPtr<MediaControlFullscreenPlayButtonElement> MediaControlFullscreenPlayButtonElement::create(Document* document)
 {
     RefPtr<MediaControlFullscreenPlayButtonElement> button = adoptRef(new MediaControlFullscreenPlayButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
@@ -412,7 +412,7 @@
 PassRefPtr<MediaControlFullscreenFullscreenButtonElement> MediaControlFullscreenFullscreenButtonElement::create(Document* document)
 {
     RefPtr<MediaControlFullscreenFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenFullscreenButtonElement(document));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     button->hide();
     return button.release();
@@ -480,7 +480,7 @@
     ASSERT(controls);
 
     RefPtr<MediaControlFullscreenTimelineElement> timeline = adoptRef(new MediaControlFullscreenTimelineElement(document, controls));
-    timeline->createShadowSubtree();
+    timeline->ensureUserAgentShadowRoot();
     timeline->setType("range");
     timeline->setAttribute(precisionAttr, "float");
     return timeline.release();
@@ -584,7 +584,7 @@
     ASSERT(controls);
 
     RefPtr<MediaControlAudioMuteButtonElement> button = adoptRef(new MediaControlAudioMuteButtonElement(document, controls));
-    button->createShadowSubtree();
+    button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
diff --git a/Source/WebCore/svg/SVGTRefElement.cpp b/Source/WebCore/svg/SVGTRefElement.cpp
index a8009a9..6a9d31b 100644
--- a/Source/WebCore/svg/SVGTRefElement.cpp
+++ b/Source/WebCore/svg/SVGTRefElement.cpp
@@ -53,7 +53,7 @@
 PassRefPtr<SVGTRefElement> SVGTRefElement::create(const QualifiedName& tagName, Document* document)
 {
     RefPtr<SVGTRefElement> element = adoptRef(new SVGTRefElement(tagName, document));
-    element->createShadowSubtree();
+    element->ensureUserAgentShadowRoot();
     return element.release();
 }
 
@@ -143,11 +143,6 @@
     m_targetListener->detach();
 }
 
-void SVGTRefElement::createShadowSubtree()
-{
-    ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION);
-}
-
 void SVGTRefElement::updateReferencedText(Element* target)
 {
     String textContent;
diff --git a/Source/WebCore/svg/SVGTRefElement.h b/Source/WebCore/svg/SVGTRefElement.h
index b43b399..7224287 100644
--- a/Source/WebCore/svg/SVGTRefElement.h
+++ b/Source/WebCore/svg/SVGTRefElement.h
@@ -40,8 +40,6 @@
     SVGTRefElement(const QualifiedName&, Document*);
     virtual ~SVGTRefElement();
 
-    void createShadowSubtree();
-
     bool isSupportedAttribute(const QualifiedName&);
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
     virtual void svgAttributeChanged(const QualifiedName&);
diff --git a/Source/WebCore/svg/SVGUseElement.cpp b/Source/WebCore/svg/SVGUseElement.cpp
index 2dbbe41..c6d042d 100644
--- a/Source/WebCore/svg/SVGUseElement.cpp
+++ b/Source/WebCore/svg/SVGUseElement.cpp
@@ -102,7 +102,7 @@
 {
     // Always build a #shadow-root for SVGUseElement.
     RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(tagName, document, wasInsertedByParser));
-    use->createShadowSubtree();
+    use->ensureUserAgentShadowRoot();
     return use.release();
 }
 
@@ -113,12 +113,6 @@
     clearResourceReferences();
 }
 
-void SVGUseElement::createShadowSubtree()
-{
-    ASSERT(!shadow());
-    ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot);
-}
-
 SVGElementInstance* SVGUseElement::instanceRoot()
 {
     // If there is no element instance tree, force immediate SVGElementInstance tree
diff --git a/Source/WebCore/svg/SVGUseElement.h b/Source/WebCore/svg/SVGUseElement.h
index 6bb29ec..b7d0966 100644
--- a/Source/WebCore/svg/SVGUseElement.h
+++ b/Source/WebCore/svg/SVGUseElement.h
@@ -56,8 +56,6 @@
 private:
     SVGUseElement(const QualifiedName&, Document*, bool wasInsertedByParser);
 
-    void createShadowSubtree();
-
     virtual bool isValid() const { return SVGTests::isValid(); }
     virtual bool supportsFocus() const { return true; }