createContextualFragment.html (7633B)
1 <!doctype html> 2 <title>createContextualFragment() tests</title> 3 <div id=log></div> 4 <script src=/resources/testharness.js></script> 5 <script src=/resources/testharnessreport.js></script> 6 <script> 7 // We are not testing XML documents here, because apparently it's not clear 8 // what we want to happen there. We also aren't testing the HTML parser in any 9 // depth, just some basic sanity checks. 10 11 // Exception-throwing 12 test(function() { 13 var range = document.createRange(); 14 range.detach(); 15 range.createContextualFragment(""); 16 }, "Must not throw INVALID_STATE_ERR for a detached node."); 17 18 test(function() { 19 var range = document.createRange(); 20 assert_throws_js(TypeError, function() { 21 range.createContextualFragment(); 22 }); 23 }, "Must throw TypeError when calling without arguments"); 24 25 test(function() { 26 // Simple test 27 var range = document.createRange(); 28 range.selectNodeContents(document.body); 29 30 var fragment = "<p CLaSs=testclass> Hi! <p>Hi!"; 31 var expected = document.createDocumentFragment(); 32 var tmpNode = document.createElement("p"); 33 tmpNode.setAttribute("class", "testclass"); 34 tmpNode.appendChild(document.createTextNode(" Hi! ")); 35 expected.appendChild(tmpNode); 36 37 tmpNode = document.createElement("p"); 38 tmpNode.appendChild(document.createTextNode("Hi!")); 39 expected.appendChild(tmpNode); 40 41 var result = range.createContextualFragment(fragment); 42 assert_true(expected.isEqualNode(result), 43 "Unexpected result (collapsed Range)"); 44 45 // Token test that the end node makes no difference 46 range.setEnd(document.body.getElementsByTagName("script")[0], 0); 47 result = range.createContextualFragment(fragment); 48 assert_true(expected.isEqualNode(result), 49 "Unexpected result (Range ends in <script>)"); 50 }, "Simple test with paragraphs"); 51 52 test(function() { 53 // This test based on https://bugzilla.mozilla.org/show_bug.cgi?id=585819, 54 // from a real-world compat bug 55 var range = document.createRange(); 56 range.selectNodeContents(document.documentElement); 57 var fragment = "<span>Hello world</span>"; 58 var expected = document.createDocumentFragment(); 59 var tmpNode = document.createElement("span"); 60 tmpNode.appendChild(document.createTextNode("Hello world")); 61 expected.appendChild(tmpNode); 62 63 var result = range.createContextualFragment(fragment); 64 assert_true(expected.isEqualNode(result), 65 "Unexpected result (collapsed Range)"); 66 67 // Another token test that the end node makes no difference 68 range.setEnd(document.head, 0); 69 result = range.createContextualFragment(fragment); 70 assert_true(expected.isEqualNode(result), 71 "Unexpected result (Range ends in <head>)"); 72 }, "Don't auto-create <body> when applied to <html>"); 73 74 // Scripts should be run if inserted (that's what the "Unmark all scripts 75 // . . ." line means, I'm told) 76 var passed = false; 77 test(function() { 78 assert_false(passed, "Sanity check"); 79 var range = document.createRange(); 80 range.selectNodeContents(document.documentElement); 81 var fragment = range.createContextualFragment("<script>passed = true</s" + "cript>"); 82 assert_false(passed, "Fragment created but not yet added to document, should not have run"); 83 document.body.appendChild(fragment); 84 assert_true(passed, "Fragment created and added to document, should run"); 85 }, "<script>s should be run when appended to the document (but not before)"); 86 87 // Historical bugs in browsers; see https://github.com/whatwg/html/issues/2222 88 89 [ 90 // Void 91 "area", 92 "base", 93 "basefont", 94 "bgsound", 95 "br", 96 "col", 97 "embed", 98 "frame", 99 "hr", 100 "img", 101 "input", 102 "keygen", 103 "link", 104 "meta", 105 "param", 106 "source", 107 "track", 108 "wbr", 109 110 // Historical 111 "menuitem", 112 "image" 113 ].forEach(name => { 114 test(() => { 115 const range = document.createRange(); 116 const contextNode = document.createElement(name); 117 const selectedNode = document.createElement("div"); 118 contextNode.appendChild(selectedNode); 119 range.selectNode(selectedNode); 120 121 range.createContextualFragment("some text"); 122 }, `createContextualFragment should work even when the context is <${name}>`); 123 }); 124 125 126 // Now that we've established basic sanity, let's do equivalence tests. Those 127 // are easier to write anyway. 128 function testEquivalence(element1, fragment1, element2, fragment2) { 129 var range1 = element1.ownerDocument.createRange(); 130 range1.selectNodeContents(element1); 131 var range2 = element2.ownerDocument.createRange(); 132 range2.selectNodeContents(element2); 133 134 var result1 = range1.createContextualFragment(fragment1); 135 var result2 = range2.createContextualFragment(fragment2); 136 137 assert_true(result1.isEqualNode(result2), "Results are supposed to be equivalent"); 138 139 // Throw in partial ownerDocument tests on the side, since the algorithm 140 // does specify that and we don't want to completely not test it. 141 if (result1.firstChild != null) { 142 assert_equals(result1.firstChild.ownerDocument, element1.ownerDocument, 143 "ownerDocument must be set to that of the reference node"); 144 } 145 if (result2.firstChild != null) { 146 assert_equals(result2.firstChild.ownerDocument, element2.ownerDocument, 147 "ownerDocument must be set to that of the reference node"); 148 } 149 } 150 151 var doc_fragment = document.createDocumentFragment(); 152 var comment = document.createComment("~o~"); 153 doc_fragment.appendChild(comment); 154 155 var tests = [ 156 ["<html> and <body> must work the same, 1", document.documentElement, "<span>Hello world</span>", document.body, "<span>Hello world</span>"], 157 ["<html> and <body> must work the same, 2", document.documentElement, "<body><p>Hello world", document.body, "<body><p>Hello world"], 158 ["Implicit <body> creation", document.documentElement, "<body><p>", document.documentElement, "<p>"], 159 ["Namespace generally shouldn't matter", 160 document.createElementNS("http://fake-namespace", "div"), "<body><p><span>Foo", 161 document.createElement("div"), "<body><p><span>Foo"], 162 ["<html> in a different namespace shouldn't be special", 163 document.createElementNS("http://fake-namespace", "html"), "<body><p>", 164 document.createElement("div"), "<body><p>"], 165 ["SVG namespace shouldn't be special", 166 document.createElementNS("http://www.w3.org/2000/svg", "div"), "<body><p>", 167 document.createElement("div"), "<body><p>"], 168 ["null should be stringified", document.createElement("span"), null, document.createElement("span"), "null"], 169 ["undefined should be stringified", document.createElement("span"), undefined, document.createElement("span"), "undefined"], 170 ["Text nodes shouldn't be special", 171 document.createTextNode("?"), "<body><p>", 172 document.createElement("div"), "<body><p>"], 173 ["Non-Element parent should not be special", 174 comment, "<body><p>", 175 document.createElement("div"), "<body><p>"] 176 ]; 177 178 generate_tests(testEquivalence, tests); 179 </script>