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