Diff
Modified: trunk/LayoutTests/ChangeLog (106612 => 106613)
--- trunk/LayoutTests/ChangeLog 2012-02-03 02:40:49 UTC (rev 106612)
+++ trunk/LayoutTests/ChangeLog 2012-02-03 02:47:04 UTC (rev 106613)
@@ -1,3 +1,20 @@
+2012-02-02 Shinya Kawanaka <[email protected]>
+
+ StyleRecalc should occur when shadow root exists and light children are changed.
+ https://bugs.webkit.org/show_bug.cgi?id=76262
+
+ Reviewed by Hajime Morita.
+
+ Tests for dynamic content fallback.
+ Also, unnecessary RenderText objects in previous test expectations were removed.
+
+ * fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt: Added.
+ * fast/dom/shadow/shadow-contents-fallback-dynamic.html: Added.
+ * platform/chromium-win/fast/html/details-remove-child-2-expected.txt:
+ * platform/gtk/fast/html/details-remove-child-2-expected.txt:
+ * platform/mac/fast/html/details-remove-child-2-expected.txt:
+ * platform/qt/fast/html/details-remove-child-2-expected.txt:
+
2012-02-02 Raymond Toy <[email protected]>
noteGrainOn needs more tests
Added: trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt (0 => 106613)
--- trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt 2012-02-03 02:47:04 UTC (rev 106613)
@@ -0,0 +1,26 @@
+testAppendFallback
+PASS
+testAppendFallbackDeep
+PASS
+testRemoveFallback
+PASS
+testRemoveFallbackDeep
+PASS
+testRemove1
+PASS
+testRemove2
+PASS
+testRemove3
+PASS
+testReplaceFallback
+PASS
+testFallbackContentChanged
+PASS
+testComplexAppend
+PASS
+testComplexRemove
+PASS
+testComplexReplace
+PASS
+TEST COMPLETED
+
Added: trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic.html (0 => 106613)
--- trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic.html (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic.html 2012-02-03 02:47:04 UTC (rev 106613)
@@ -0,0 +1,401 @@
+ <!DOCTYPE html>
+<html>
+<head>
+<style>
+/* relative positioning ensures underlying RenderLayer */
+.container {
+ position: relative;
+}
+
+.span {
+ display: boxed-inline;
+ margin: 2px;
+ border: solid;
+}
+</style>
+<script>
+function log(message) {
+ document.getElementById('console').innerHTML += (message + "\n");
+}
+
+function removeAllChildren(elem) {
+ while (elem.firstChild)
+ elem.removeChild(elem.firstChild);
+}
+
+function cleanUp() {
+ removeAllChildren(document.getElementById('actual-container'));
+ removeAllChildren(document.getElementById('expect-container'));
+}
+
+function removeContainerLines(text) {
+ var lines = text.split('\n');
+ lines.splice(0, 2);
+ return lines.join('\n');
+}
+
+function check() {
+ var refContainerRenderTree = internals.elementRenderTreeAsText(document.getElementById('expect-container'));
+ var refRenderTree = removeContainerLines(refContainerRenderTree);
+
+ var targetContainerRenderTree = internals.elementRenderTreeAsText(document.getElementById('actual-container'));
+ var targetRenderTree = removeContainerLines(targetContainerRenderTree);
+
+ if (targetRenderTree == refRenderTree)
+ log("PASS");
+ else {
+ log("FAIL");
+ log("Expected: ");
+ log(refRenderTree);
+ log("Actual: ");
+ log(targetRenderTree);
+ }
+}
+
+function createSpanWithText(text) {
+ var span = document.createElement('span');
+ span.appendChild(document.createTextNode(text));
+ return span;
+}
+
+function appendShadow(target, select) {
+ var root = internals.ensureShadowRoot(target);
+
+ var content = internals.createContentElement(document);
+ content.setAttribute('select', select);
+ content.appendChild(createSpanWithText("FALLBACK"));
+
+ root.appendChild(document.createTextNode("{SHADOW: "));
+ root.appendChild(content);
+ root.appendChild(document.createTextNode("}"));
+}
+
+function appendShadowDeep(target, select) {
+ var root = internals.ensureShadowRoot(target);
+
+ var child = document.createElement("span");
+ {
+ var content = internals.createContentElement(document);
+ content.setAttribute('select', select);
+ content.appendChild(createSpanWithText("FALLBACK"));
+
+ child.appendChild(document.createTextNode("{INNER: "));
+ child.appendChild(content);
+ child.appendChild(document.createTextNode("}"));
+ }
+
+ root.appendChild(document.createTextNode("{SHADOW: "));
+ root.appendChild(child);
+ root.appendChild(document.createTextNode("}"));
+}
+
+function testAppendFallback(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span>content</span>";
+
+ appendShadow(target, "#append");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.innerHTML = "<span id='append'>appended</span>";
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>appended</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testAppendFallbackDeep(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span>content</span>";
+
+ appendShadowDeep(target, "#append-deep");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.innerHTML = "<span id='append-deep'>appended</span>";
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>{INNER: <span>appended</span>}</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testRemoveFallback(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span id='remove'>content</span>";
+
+ appendShadow(target, "#remove");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.innerHTML = "<span>content</span>"
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>FALLBACK</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testRemoveFallbackDeep(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span id='remove-deep'>content</span>";
+
+ appendShadowDeep(target, "#remove-deep");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.innerHTML = "<span>content</span>"
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>{INNER: <span>FALLBACK</span>}</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testRemove1(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span id='remove1-1'>content 1</span><span id='remove1-2'>content 2</span>";
+ appendShadow(target, "span");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.removeChild(document.getElementById('remove1-1'));
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>content 2</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testRemove2(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span id='testremove2-1'>content 1</span><span id='testremove2-2'>content 2</span>";
+ appendShadow(target, "span");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.removeChild(document.getElementById('testremove2-2'));
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>content 1</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testRemove3(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span id='testremove3-1'>content 1</span><span id='testremove3-2'>content 2</span>";
+ appendShadow(target, "span");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.removeChild(document.getElementById('testremove3-1'));
+ target.removeChild(document.getElementById('testremove3-2'));
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>FALLBACK</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testReplaceFallback(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span id='to-replace'>content</span>";
+
+ appendShadow(target, "#to-replace");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.innerHTML = "<span id='to-replace'>replaced</span>";
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>replaced</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testFallbackContentChanged(callIfDone) {
+ var target = document.createElement('div');
+ target.innerHTML = "<span>content</span>";
+
+ appendShadow(target, "#non-element");
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, callIfDone) {
+ return function() {
+ target.appendChild(createSpanWithText('appended content'));
+ document.getElementById('expect-container').innerHTML = "<div>{SHADOW: <span>FALLBACK</span>}</div>";
+ callIfDone();
+ };
+ })(target, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testComplexAppend(callIfDone) {
+ var target = document.createElement('div');
+ appendShadow(target, '#complex-1');
+
+ var selectContent = document.createElement('span');
+ selectContent.setAttribute('id', 'complex-1');
+ appendShadow(selectContent, 'span');
+
+ target.appendChild(document.createTextNode('[WONT SELECTED]'));
+ target.appendChild(selectContent);
+ target.appendChild(document.createTextNode('[WONT SELECTED]'));
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, selectContent, callIfDone) {
+ return function() {
+ selectContent.appendChild(createSpanWithText('SELECTED'));
+ document.getElementById('expect-container').innerHTML =
+ "<div>{SHADOW: <span>{SHADOW: <span>SELECTED</span>}</span>}</div>";
+ callIfDone();
+ };
+ })(target, selectContent, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testComplexRemove(callIfDone) {
+ var target = document.createElement('div');
+ appendShadow(target, '#complex-2');
+
+ var selectContent = document.createElement('span');
+ selectContent.setAttribute('id', 'complex-2');
+ {
+ selectContent.appendChild(createSpanWithText('SELECTED'));
+ }
+ appendShadow(selectContent, 'span');
+
+ target.appendChild(document.createTextNode('[WONT SELECTED]'));
+ target.appendChild(selectContent);
+ target.appendChild(document.createTextNode('[WONT SELECTED]'));
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, selectContent, callIfDone) {
+ return function() {
+ removeAllChildren(selectContent);
+ document.getElementById('expect-container').innerHTML =
+ "<div>{SHADOW: <span>{SHADOW: <span>FALLBACK</span>}</span>}</div>";
+ callIfDone();
+ };
+ })(target, selectContent, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+function testComplexReplace(callIfDone) {
+ var target = document.createElement('div');
+ appendShadow(target, '#complex-3');
+
+ var selectContent = document.createElement('span');
+ selectContent.setAttribute('id', 'complex-3');
+ {
+ }
+ appendShadow(selectContent, 'span');
+
+ target.appendChild(document.createTextNode('[WONT SELECTED]'));
+ target.appendChild(selectContent);
+ target.appendChild(document.createTextNode('[WONT SELECTED]'));
+
+ document.getElementById('actual-container').appendChild(target);
+
+ var f = (function(target, selectContent, callIfDone) {
+ return function() {
+ removeAllChildren(selectContent);
+ selectContent.appendChild(createSpanWithText('REPLACED'));
+ document.getElementById('expect-container').innerHTML =
+ "<div>{SHADOW: <span>{SHADOW: <span>REPLACED</span>}</span>}</div>";
+ callIfDone();
+ };
+ })(target, selectContent, callIfDone);
+
+ setTimeout(f, 0);
+}
+
+var testFuncs = [
+ testAppendFallback,
+ testAppendFallbackDeep,
+ testRemoveFallback,
+ testRemoveFallbackDeep,
+ testRemove1,
+ testRemove2,
+ testRemove3,
+ testReplaceFallback,
+ testFallbackContentChanged,
+ testComplexAppend,
+ testComplexRemove,
+ testComplexReplace,
+
+];
+
+function doTestIfLeft() {
+ var test = testFuncs.shift();
+ if (test == null)
+ return doneTest();
+
+ var callIfDone = function() {
+ setTimeout(function() {
+ check();
+ cleanUp();
+ doTestIfLeft();
+ }, 0);
+ };
+
+ log(test.name);
+ test(callIfDone);
+}
+
+function doneTest() {
+ log("TEST COMPLETED");
+ layoutTestController.notifyDone();
+}
+
+function doTest() {
+ if (window.layoutTestController) {
+ layoutTestController.waitUntilDone();
+ layoutTestController.dumpAsText();
+ }
+
+ cleanUp();
+ doTestIfLeft();
+}
+</script>
+</head>
+<body _onload_="doTest()">
+
+<div id="actual-container" class="container"></div>
+<div id="expect-container" class="container"></div>
+<pre id="console"></pre>
+
+</body>
+</html>
Modified: trunk/LayoutTests/platform/chromium-win/fast/html/details-remove-child-2-expected.txt (106612 => 106613)
--- trunk/LayoutTests/platform/chromium-win/fast/html/details-remove-child-2-expected.txt 2012-02-03 02:40:49 UTC (rev 106612)
+++ trunk/LayoutTests/platform/chromium-win/fast/html/details-remove-child-2-expected.txt 2012-02-03 02:47:04 UTC (rev 106613)
@@ -9,6 +9,5 @@
RenderText {#text} at (16,0) size 54x19
text run at (16,0) width 54: "summary"
RenderBlock (anonymous) at (0,20) size 784x20
- RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 150x19
text run at (0,0) width 150: "should have no bold test."
Modified: trunk/LayoutTests/platform/gtk/fast/html/details-remove-child-2-expected.txt (106612 => 106613)
--- trunk/LayoutTests/platform/gtk/fast/html/details-remove-child-2-expected.txt 2012-02-03 02:40:49 UTC (rev 106612)
+++ trunk/LayoutTests/platform/gtk/fast/html/details-remove-child-2-expected.txt 2012-02-03 02:47:04 UTC (rev 106613)
@@ -9,6 +9,5 @@
RenderText {#text} at (16,0) size 60x17
text run at (16,0) width 60: "summary"
RenderBlock (anonymous) at (0,18) size 784x18
- RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 160x17
text run at (0,0) width 160: "should have no bold test."
Modified: trunk/LayoutTests/platform/mac/fast/html/details-remove-child-2-expected.txt (106612 => 106613)
--- trunk/LayoutTests/platform/mac/fast/html/details-remove-child-2-expected.txt 2012-02-03 02:40:49 UTC (rev 106612)
+++ trunk/LayoutTests/platform/mac/fast/html/details-remove-child-2-expected.txt 2012-02-03 02:47:04 UTC (rev 106613)
@@ -9,6 +9,5 @@
RenderText {#text} at (16,0) size 58x18
text run at (16,0) width 58: "summary"
RenderBlock (anonymous) at (0,18) size 784x18
- RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 157x18
text run at (0,0) width 157: "should have no bold test."
Modified: trunk/LayoutTests/platform/qt/fast/html/details-remove-child-2-expected.txt (106612 => 106613)
--- trunk/LayoutTests/platform/qt/fast/html/details-remove-child-2-expected.txt 2012-02-03 02:40:49 UTC (rev 106612)
+++ trunk/LayoutTests/platform/qt/fast/html/details-remove-child-2-expected.txt 2012-02-03 02:47:04 UTC (rev 106613)
@@ -9,6 +9,5 @@
RenderText {#text} at (16,0) size 65x21
text run at (16,0) width 65: "summary"
RenderBlock (anonymous) at (0,21) size 784x21
- RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 177x21
text run at (0,0) width 177: "should have no bold test."
Modified: trunk/Source/WebCore/ChangeLog (106612 => 106613)
--- trunk/Source/WebCore/ChangeLog 2012-02-03 02:40:49 UTC (rev 106612)
+++ trunk/Source/WebCore/ChangeLog 2012-02-03 02:47:04 UTC (rev 106613)
@@ -1,3 +1,18 @@
+2012-02-02 Shinya Kawanaka <[email protected]>
+
+ StyleRecalc should occur when shadow root exists and light children are changed.
+ https://bugs.webkit.org/show_bug.cgi?id=76262
+
+ Reviewed by Hajime Morita.
+
+ When light children is changed, the element included in HTMLContentElement may also be changed.
+ So we have to recalculate inclusion of content element again.
+
+ Test: fast/dom/shadow/shadow-contents-fallback-dynamic.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::childrenChanged):
+
2012-02-02 Ami Fischman <[email protected]>
Avoid crashing renderer when GPU process dies by not caching textures between video frames.
Modified: trunk/Source/WebCore/dom/Element.cpp (106612 => 106613)
--- trunk/Source/WebCore/dom/Element.cpp 2012-02-03 02:40:49 UTC (rev 106612)
+++ trunk/Source/WebCore/dom/Element.cpp 2012-02-03 02:47:04 UTC (rev 106613)
@@ -1359,6 +1359,11 @@
checkForEmptyStyleChange(this, renderStyle());
else
checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
+
+ if (hasRareData()) {
+ if (ShadowRoot* root = shadowRoot())
+ root->hostChildrenChanged();
+ }
}
void Element::beginParsingChildren()
Modified: trunk/Source/WebCore/dom/ShadowRoot.cpp (106612 => 106613)
--- trunk/Source/WebCore/dom/ShadowRoot.cpp 2012-02-03 02:40:49 UTC (rev 106612)
+++ trunk/Source/WebCore/dom/ShadowRoot.cpp 2012-02-03 02:47:04 UTC (rev 106613)
@@ -142,8 +142,9 @@
{
if (!hasContentElement())
return;
+
// This results in forced detaching/attaching of the shadow render tree. See ShadowRoot::recalcStyle().
- setNeedsStyleRecalc();
+ setNeedsReattachHostChildrenAndShadow();
}
bool ShadowRoot::isInclusionSelectorActive() const