AuthorShadowDOM for progress element
https://bugs.webkit.org/show_bug.cgi?id=91969

Reviewed by Hajime Morita.

Source/WebCore:

We add support for AuthorShadowDOM for progress element.

According to the Shadow DOM spec, a progress element should behave like having a UserAgentShadowRoot and
an element in UserAgentShadowRoot draws a real 'progress' bar. In this patch, we change the inner structure
of a progress element so that we can distribute an element having RenderProgress to AuthorShadowDOM.

Before this patch, a progress element has the following inner structure.

    <progress>--UserAgentShadowRoot -- -- -- -- -- -- -- -- -- -- AuthorShadowRoot
                       |
                       +-- ProgressBarElement
                       |
                       +-- ProgressValueElement

After this patch, a progress element will have the following inner structure.

    <progress>--UserAgentShadowRoot -- -- -- -- -- -- -- -- -- -- AuthorShadowRoot
                       |
                       +-- ProgressInnerElement
                                   |
                                   +-- ProgressBarElement
                                   |
                                   +-- ProgressValueElement

Tests: fast/dom/shadow/shadowdom-for-progress-dynamic.html
       fast/dom/shadow/shadowdom-for-progress-multiple.html
       fast/dom/shadow/shadowdom-for-progress-with-style.html
       fast/dom/shadow/shadowdom-for-progress-without-appearance.html
       fast/dom/shadow/shadowdom-for-progress-without-shadow-element.html
       fast/dom/shadow/shadowdom-for-progress.html

* css/html.css:
(progress::-webkit-progress-inner-element):
* html/HTMLProgressElement.cpp:
(WebCore::HTMLProgressElement::HTMLProgressElement):
(WebCore::HTMLProgressElement::createRenderer):
(WebCore::HTMLProgressElement::renderProgress): Returns RenderProgress gotten from UserAgentShadowDOM.
(WebCore):
(WebCore::HTMLProgressElement::willAddAuthorShadowRoot):
(WebCore::HTMLProgressElement::didElementStateChange):
(WebCore::HTMLProgressElement::createShadowSubtree): Creates a new Shadow DOM structure.
* html/HTMLProgressElement.h:
(WebCore):
(WebCore::HTMLProgressElement::hasAuthorShadowRoot):
(HTMLProgressElement):
(WebCore::isHTMLProgressElement):
(WebCore::toHTMLProgressElement):
* html/shadow/ProgressShadowElement.cpp:
(WebCore::ProgressShadowElement::ProgressShadowElement):
(WebCore::ProgressShadowElement::progressElement):
(WebCore::ProgressInnerElement::ProgressInnerElement): We introduce a new element having RenderProgress
so that we can distribute an element having RenderProgress to AuthorShadowDOM.
(WebCore):
(WebCore::ProgressInnerElement::create):
(WebCore::ProgressInnerElement::shadowPseudoId):
(WebCore::ProgressInnerElement::createRenderer):
(WebCore::ProgressInnerElement::rendererIsNeeded):
* html/shadow/ProgressShadowElement.h:
(ProgressShadowElement):
(WebCore):
(ProgressInnerElement):
* rendering/RenderProgress.cpp:
(WebCore::RenderProgress::RenderProgress):
(WebCore::RenderProgress::progressElement):
* rendering/RenderProgress.h:
(RenderProgress):

LayoutTests:

Contains the following tests:
  (1) progress element with AuthorShadowDOM
  (2) progress element with multiple AuthorShadowDOM with a shadow element
  (3) progress element with multiple AuthorShadowDOM without a shadow element
  (4) progress element with AuthorShadowDOM with dynamic value update
  (5) progress element with AuthorShadowDOM with style
  (6) progress element with AuthorShadowDOM with -webkit-appearance: none

* fast/dom/HTMLProgressElement/progress-clone-expected.txt:
* fast/dom/HTMLProgressElement/progress-clone.html:
* fast/dom/HTMLProgressElement/progress-element-markup-expected.txt:
* fast/dom/shadow/resources/replaced-element-styles.css: Added.
(.progress-like):
(.progress-inner-element-like):
* fast/dom/shadow/shadowdom-for-progress-dynamic-expected.html: Added.
* fast/dom/shadow/shadowdom-for-progress-dynamic.html: Added.
* fast/dom/shadow/shadowdom-for-progress-expected.html: Added.
* fast/dom/shadow/shadowdom-for-progress-multiple-expected.html: Added.
* fast/dom/shadow/shadowdom-for-progress-multiple.html: Added.
* fast/dom/shadow/shadowdom-for-progress-with-style-expected.html: Added.
* fast/dom/shadow/shadowdom-for-progress-with-style.html: Added.
* fast/dom/shadow/shadowdom-for-progress-without-appearance-expected.html: Added.
* fast/dom/shadow/shadowdom-for-progress-without-appearance.html: Added.
* fast/dom/shadow/shadowdom-for-progress-without-shadow-element-expected.html: Added.
* fast/dom/shadow/shadowdom-for-progress-without-shadow-element.html: Added.
* fast/dom/shadow/shadowdom-for-progress.html: Added.
* platform/chromium-win/fast/dom/HTMLProgressElement/indeterminate-progress-001-expected.txt:
* platform/chromium-win/fast/dom/HTMLProgressElement/progress-bar-value-pseudo-element-expected.txt:
* platform/chromium-win/fast/dom/HTMLProgressElement/progress-writing-mode-expected.txt:
* platform/mac/TestExpectations:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@124754 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/html/HTMLProgressElement.cpp b/Source/WebCore/html/HTMLProgressElement.cpp
index 742b09f..48b5b88 100644
--- a/Source/WebCore/html/HTMLProgressElement.cpp
+++ b/Source/WebCore/html/HTMLProgressElement.cpp
@@ -43,6 +43,7 @@
 
 HTMLProgressElement::HTMLProgressElement(const QualifiedName& tagName, Document* document)
     : LabelableElement(tagName, document)
+    , m_hasAuthorShadowRoot(false)
 {
     ASSERT(hasTagName(progressTag));
 }
@@ -58,8 +59,11 @@
     return progress;
 }
 
-RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyle*)
+RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyle* style)
 {
+    if (!style->hasAppearance() || hasAuthorShadowRoot())
+        return RenderObject::createObject(this, style);
+
     return new (arena) RenderProgress(this);
 }
 
@@ -68,6 +72,21 @@
     return childContext.isOnUpperEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext);
 }
 
+RenderProgress* HTMLProgressElement::renderProgress() const
+{
+    if (renderer() && renderer()->isProgress())
+        return static_cast<RenderProgress*>(renderer());
+
+    RenderObject* renderObject = userAgentShadowRoot()->firstChild()->renderer();
+    ASSERT(!renderObject || renderObject->isProgress());
+    return static_cast<RenderProgress*>(renderObject);
+}
+
+void HTMLProgressElement::willAddAuthorShadowRoot()
+{
+    m_hasAuthorShadowRoot = true;
+}
+
 bool HTMLProgressElement::supportsFocus() const
 {
     return Node::supportsFocus() && !disabled();
@@ -134,10 +153,9 @@
 void HTMLProgressElement::didElementStateChange()
 {
     m_value->setWidthPercentage(position() * 100);
-    if (renderer() && renderer()->isProgress()) {
-        RenderProgress* render = toRenderProgress(renderer());
+    if (RenderProgress* render = renderProgress()) {
         bool wasDeterminate = render->isDeterminate();
-        renderer()->updateFromElement();
+        render->updateFromElement();
         if (wasDeterminate != isDeterminate())
             setNeedsStyleRecalc();
     }
@@ -145,14 +163,18 @@
 
 void HTMLProgressElement::createShadowSubtree()
 {
-    ASSERT(!shadow());
+    ASSERT(!userAgentShadowRoot());
+           
+    RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION);
+
+    RefPtr<ProgressInnerElement> inner = ProgressInnerElement::create(document());
+    root->appendChild(inner);
 
     RefPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
     m_value = ProgressValueElement::create(document());
     bar->appendChild(m_value, ASSERT_NO_EXCEPTION);
 
-    RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION);
-    root->appendChild(bar, ASSERT_NO_EXCEPTION);
+    inner->appendChild(bar, ASSERT_NO_EXCEPTION);
 }
 
 } // namespace