- Revision
- 206404
- Author
- [email protected]
- Date
- 2016-09-26 16:51:17 -0700 (Mon, 26 Sep 2016)
Log Message
Setter on style element's textContent or cssText doesn't trigger style recalc
https://bugs.webkit.org/show_bug.cgi?id=160331
<rdar://problem/27609715>
Reviewed by Ryosuke Niwa and Daniel Bates.
Source/WebCore:
We would not notify the parent when text node content changed in a shadow tree.
Test: fast/shadow-dom/shadow-style-text-mutation.html
* dom/AuthorStyleSheets.cpp:
(WebCore::AuthorStyleSheets::updateActiveStyleSheets):
Invalidate shadow root children instead of the root itself when doing full invalidation.
The invalidity bits have no meaning for non-element, non-texts.
* dom/CharacterData.cpp:
(WebCore::CharacterData::parserAppendData):
(WebCore::CharacterData::setDataAndUpdate):
(WebCore::CharacterData::notifyParentAfterChange):
Add a helper and call it also in shadow trees.
(WebCore::CharacterData::dispatchModifiedEvent):
* dom/CharacterData.h:
LayoutTests:
* fast/shadow-dom/shadow-style-text-mutation-expected.html: Added.
* fast/shadow-dom/shadow-style-text-mutation.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (206403 => 206404)
--- trunk/LayoutTests/ChangeLog 2016-09-26 23:45:21 UTC (rev 206403)
+++ trunk/LayoutTests/ChangeLog 2016-09-26 23:51:17 UTC (rev 206404)
@@ -1,5 +1,16 @@
2016-09-26 Antti Koivisto <[email protected]>
+ Setter on style element's textContent or cssText doesn't trigger style recalc
+ https://bugs.webkit.org/show_bug.cgi?id=160331
+ <rdar://problem/27609715>
+
+ Reviewed by Ryosuke Niwa and Daniel Bates.
+
+ * fast/shadow-dom/shadow-style-text-mutation-expected.html: Added.
+ * fast/shadow-dom/shadow-style-text-mutation.html: Added.
+
+2016-09-26 Antti Koivisto <[email protected]>
+
Input elements don't work inside shadow tree
https://bugs.webkit.org/show_bug.cgi?id=160427
Added: trunk/LayoutTests/fast/shadow-dom/shadow-style-text-mutation-expected.html (0 => 206404)
--- trunk/LayoutTests/fast/shadow-dom/shadow-style-text-mutation-expected.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/shadow-style-text-mutation-expected.html 2016-09-26 23:51:17 UTC (rev 206404)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <div style="width: 100px; height: 100px; background: green;"></div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/shadow-style-text-mutation.html (0 => 206404)
--- trunk/LayoutTests/fast/shadow-dom/shadow-style-text-mutation.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/shadow-style-text-mutation.html 2016-09-26 23:51:17 UTC (rev 206404)
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.test {
+ width: 100px;
+ height: 25px;
+ background: red;
+}
+#host4 { background: green };
+</style>
+</head>
+<body>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host1" class="test"></div>
+<div id="host2" class="test"></div>
+<div id="host3" class="test"></div>
+<div id="host4" class="test"></div>
+<script>
+{
+ var host = document.getElementById('host1');
+ var shadow = host.attachShadow({mode: 'closed'});
+ shadow.innerHTML = `
+ <div style="height:100%"></div>
+ `;
+ document.body.offsetWidth;
+ var style = document.createElement("style");
+ style.textContent = "div { background: green; }";
+ shadow.appendChild(style);
+}
+{
+ var host = document.getElementById('host2');
+ var shadow = host.attachShadow({mode: 'closed'});
+ shadow.innerHTML = `
+ <style></style>
+ <div style="height:100%"></div>
+ `;
+ document.body.offsetWidth;
+ shadow.querySelector('style').textContent = "div { background: green; }";
+}
+{
+ var host = document.getElementById('host3');
+ var shadow = host.attachShadow({mode: 'closed'});
+ shadow.innerHTML = `
+ <style>div { background: red; }</style>
+ <div style="height:100%"></div>
+ `;
+ document.body.offsetWidth;
+ shadow.querySelector('style').textContent = "div { background: green; }";
+}
+{
+ var host = document.getElementById('host4');
+ var shadow = host.attachShadow({mode: 'closed'});
+ shadow.innerHTML = `
+ <style>div { background: red; }</style>
+ <div style="height:100%"></div>
+ `;
+ document.body.offsetWidth;
+ shadow.querySelector('style').textContent = "";
+}
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (206403 => 206404)
--- trunk/Source/WebCore/ChangeLog 2016-09-26 23:45:21 UTC (rev 206403)
+++ trunk/Source/WebCore/ChangeLog 2016-09-26 23:51:17 UTC (rev 206404)
@@ -1,5 +1,33 @@
2016-09-26 Antti Koivisto <[email protected]>
+ Setter on style element's textContent or cssText doesn't trigger style recalc
+ https://bugs.webkit.org/show_bug.cgi?id=160331
+ <rdar://problem/27609715>
+
+ Reviewed by Ryosuke Niwa and Daniel Bates.
+
+ We would not notify the parent when text node content changed in a shadow tree.
+
+ Test: fast/shadow-dom/shadow-style-text-mutation.html
+
+ * dom/AuthorStyleSheets.cpp:
+ (WebCore::AuthorStyleSheets::updateActiveStyleSheets):
+
+ Invalidate shadow root children instead of the root itself when doing full invalidation.
+ The invalidity bits have no meaning for non-element, non-texts.
+
+ * dom/CharacterData.cpp:
+ (WebCore::CharacterData::parserAppendData):
+ (WebCore::CharacterData::setDataAndUpdate):
+ (WebCore::CharacterData::notifyParentAfterChange):
+
+ Add a helper and call it also in shadow trees.
+
+ (WebCore::CharacterData::dispatchModifiedEvent):
+ * dom/CharacterData.h:
+
+2016-09-26 Antti Koivisto <[email protected]>
+
Input elements don't work inside shadow tree
https://bugs.webkit.org/show_bug.cgi?id=160427
Modified: trunk/Source/WebCore/dom/AuthorStyleSheets.cpp (206403 => 206404)
--- trunk/Source/WebCore/dom/AuthorStyleSheets.cpp 2016-09-26 23:45:21 UTC (rev 206403)
+++ trunk/Source/WebCore/dom/AuthorStyleSheets.cpp 2016-09-26 23:51:17 UTC (rev 206404)
@@ -30,6 +30,7 @@
#include "CSSStyleSheet.h"
#include "Element.h"
+#include "ElementChildIterator.h"
#include "ExtensionStyleSheets.h"
#include "HTMLIFrameElement.h"
#include "HTMLLinkElement.h"
@@ -336,9 +337,10 @@
}
if (requiresFullStyleRecalc) {
- if (m_shadowRoot)
- m_shadowRoot->setNeedsStyleRecalc();
- else
+ if (m_shadowRoot) {
+ for (auto& shadowChild : childrenOfType<Element>(*m_shadowRoot))
+ shadowChild.setNeedsStyleRecalc();
+ } else
m_document.scheduleForcedStyleRecalc();
}
}
Modified: trunk/Source/WebCore/dom/CharacterData.cpp (206403 => 206404)
--- trunk/Source/WebCore/dom/CharacterData.cpp 2016-09-26 23:45:21 UTC (rev 206403)
+++ trunk/Source/WebCore/dom/CharacterData.cpp 2016-09-26 23:51:17 UTC (rev 206404)
@@ -103,18 +103,7 @@
if (is<Text>(*this) && parentNode())
downcast<Text>(*this).updateRendererAfterContentChange(oldLength, 0);
- document().incDOMTreeVersion();
- // We don't call dispatchModifiedEvent here because we don't want the
- // parser to dispatch DOM mutation events.
- if (parentNode()) {
- ContainerNode::ChildChange change = {
- ContainerNode::TextChanged,
- ElementTraversal::previousSibling(*this),
- ElementTraversal::nextSibling(*this),
- ContainerNode::ChildChangeSourceParser
- };
- parentNode()->childrenChanged(change);
- }
+ notifyParentAfterChange(ContainerNode::ChildChangeSourceParser);
return characterLengthLimit;
}
@@ -208,10 +197,27 @@
if (document().frame())
document().frame()->selection().textWasReplaced(this, offsetOfReplacedData, oldLength, newLength);
- document().incDOMTreeVersion();
+ notifyParentAfterChange(ContainerNode::ChildChangeSourceAPI);
+
dispatchModifiedEvent(oldData);
}
+void CharacterData::notifyParentAfterChange(ContainerNode::ChildChangeSource source)
+{
+ document().incDOMTreeVersion();
+
+ if (!parentNode())
+ return;
+
+ ContainerNode::ChildChange change = {
+ ContainerNode::TextChanged,
+ ElementTraversal::previousSibling(*this),
+ ElementTraversal::nextSibling(*this),
+ source
+ };
+ parentNode()->childrenChanged(change);
+}
+
void CharacterData::dispatchModifiedEvent(const String& oldData)
{
if (std::unique_ptr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this))
@@ -218,15 +224,6 @@
mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(*this, oldData));
if (!isInShadowTree()) {
- if (parentNode()) {
- ContainerNode::ChildChange change = {
- ContainerNode::TextChanged,
- ElementTraversal::previousSibling(*this),
- ElementTraversal::nextSibling(*this),
- ContainerNode::ChildChangeSourceAPI
- };
- parentNode()->childrenChanged(change);
- }
if (document().hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
dispatchScopedEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, nullptr, oldData, m_data));
dispatchSubtreeModifiedEvent();
Modified: trunk/Source/WebCore/dom/CharacterData.h (206403 => 206404)
--- trunk/Source/WebCore/dom/CharacterData.h 2016-09-26 23:45:21 UTC (rev 206403)
+++ trunk/Source/WebCore/dom/CharacterData.h 2016-09-26 23:51:17 UTC (rev 206404)
@@ -22,7 +22,7 @@
#pragma once
-#include "Node.h"
+#include "ContainerNode.h"
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -69,6 +69,7 @@
bool offsetInCharacters() const final;
void setDataAndUpdate(const String&, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength);
void checkCharDataOperation(unsigned offset, ExceptionCode&);
+ void notifyParentAfterChange(ContainerNode::ChildChangeSource);
String m_data;
};