| <!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(); |
| 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(); |
| 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); |
| } |
| |
| function testContentInContent(callIfDone) { |
| document.getElementById('expect-container').innerHTML = |
| "<div>{SHADOW: <content><span>CONTENT 2 FALLBACK</span></content>}</div>"; |
| |
| var target = document.createElement('div'); |
| target.appendChild(createSpanWithText('S1')); |
| target.appendChild(createSpanWithText('S2')); |
| |
| var root = internals.ensureShadowRoot(target); |
| var content1 = internals.createContentElement(); |
| content1.setAttribute('select', 'div'); |
| |
| root.appendChild(document.createTextNode("{SHADOW: ")); |
| root.appendChild(content1); |
| root.appendChild(document.createTextNode("}")); |
| |
| document.getElementById('actual-container').appendChild(target); |
| |
| var f = (function(target, content1, callIfDone) { |
| return function() { |
| var content2 = internals.createContentElement(); |
| content2.setAttribute('select', 'span'); |
| content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK')); |
| content1.appendChild(content2); |
| callIfDone(); |
| }; |
| })(target, content1, callIfDone); |
| |
| setTimeout(f, 0); |
| } |
| |
| function testContentInContentFallback(callIfDone) { |
| document.getElementById('expect-container').innerHTML = |
| "<div>{SHADOW: <content><span>CONTENT 2 FALLBACK</span></content>}</div>"; |
| |
| var target = document.createElement('div'); |
| target.appendChild(createSpanWithText('S1')); |
| target.appendChild(createSpanWithText('S2')); |
| |
| var root = internals.ensureShadowRoot(target); |
| var content1 = internals.createContentElement(); |
| content1.setAttribute('select', 'div'); |
| |
| root.appendChild(document.createTextNode("{SHADOW: ")); |
| root.appendChild(content1); |
| root.appendChild(document.createTextNode("}")); |
| |
| document.getElementById('actual-container').appendChild(target); |
| |
| var f = (function(target, content1, callIfDone) { |
| return function() { |
| var content2 = internals.createContentElement(); |
| content2.setAttribute('select', 'div'); |
| content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK')); |
| content1.appendChild(content2); |
| callIfDone(); |
| }; |
| })(target, content1, callIfDone); |
| |
| setTimeout(f, 0); |
| } |
| |
| function testContentInContentFallbackDirect(callIfDone) { |
| document.getElementById('expect-container').innerHTML = |
| "<div><content><span>CONTENT 2 FALLBACK</span></content></div>"; |
| |
| var target = document.createElement('div'); |
| target.appendChild(createSpanWithText('S1')); |
| target.appendChild(createSpanWithText('S2')); |
| |
| var root = internals.ensureShadowRoot(target); |
| var content1 = internals.createContentElement(); |
| content1.setAttribute('select', 'div'); |
| root.appendChild(content1); |
| |
| document.getElementById('actual-container').appendChild(target); |
| |
| var f = (function(target, content1, callIfDone) { |
| return function() { |
| var content2 = internals.createContentElement(); |
| content2.setAttribute('select', 'div'); |
| content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK')); |
| content1.appendChild(content2); |
| callIfDone(); |
| }; |
| })(target, content1, callIfDone); |
| |
| setTimeout(f, 0); |
| } |
| |
| var testFuncs = [ |
| testAppendFallback, |
| testAppendFallbackDeep, |
| testRemoveFallback, |
| testRemoveFallbackDeep, |
| testRemove1, |
| testRemove2, |
| testRemove3, |
| testReplaceFallback, |
| testFallbackContentChanged, |
| testComplexAppend, |
| testComplexRemove, |
| testComplexReplace, |
| testContentInContent, |
| testContentInContentFallback, |
| testContentInContentFallbackDirect |
| ]; |
| |
| 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"); |
| testRunner.notifyDone(); |
| } |
| |
| function doTest() { |
| if (window.testRunner) { |
| testRunner.waitUntilDone(); |
| testRunner.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> |