Node.appendChild(null) / replaceChild(null, null) / removeChild(null) / insertBefore...
[WebKit-https.git] / LayoutTests / fast / dom / move-nodes-across-documents.html
1 <!DocType HTML>
2 <script>
3 if (window.testRunner)
4     testRunner.dumpAsText();
5
6 var iframe, iframeDoc;
7
8 function log(msg)
9 {
10     document.getElementById('logger').innerHTML += msg + '\n';
11 }
12
13 var i = 0;
14
15 function runTest(test, opt_expectedErrorName)
16 {
17     var errorName;
18     try {
19         test();
20     } catch(error) {
21         errorName = error.name;
22     } finally {
23         i++;
24         var hasExpectedErrorName = opt_expectedErrorName;
25         if (hasExpectedErrorName && navigator.userAgent.indexOf('Firefox') != -1)
26             opt_expectedErrorName = 'NS_ERROR_DOM_' + opt_expectedErrorName;
27
28         if (!errorName && !opt_expectedErrorName || opt_expectedErrorName == errorName)
29             log(i + '. PASS');
30         else
31             log(i + '. FAIL: expected ' + opt_expectedErrorName + ' got ' + (errorName || 'no error'));
32     }
33 }
34
35 function elementInCurrentDocument(html)
36 {
37     var node = document.createElement('div');
38     node.innerHTML = html || 'lorem ipsum';
39     document.body.appendChild(node);
40     return node;
41 }
42
43 function rangeInIframe()
44 {
45     var range = iframeDoc.createRange();
46     range.setStart(iframeDoc.body, 0);
47     range.setEnd(iframeDoc.body, 1);
48     return range;
49 }
50
51 function rangeInCurrentDocument()
52 {
53     var range = document.createRange();
54     range.setStart(document.body, 0);
55     range.setEnd(document.body, 1);
56     return range;
57 }
58
59 function run()
60 {
61     iframe = document.querySelector('iframe');
62     iframeDoc = iframe.contentDocument;
63
64     runTest(function() {
65         iframeDoc.body.appendChild(document.createElement('div'));
66         iframeDoc.body.appendChild(elementInCurrentDocument('appendChild'));
67     });
68
69     runTest(function() {
70         var dummy = document.createElement('span');
71         iframeDoc.body.appendChild(dummy);
72         iframeDoc.body.replaceChild(document.createElement('div'), dummy);
73
74         var dummy = document.createElement('span');
75         iframeDoc.body.appendChild(dummy);
76         iframeDoc.body.replaceChild(elementInCurrentDocument('replaceChild'), dummy);
77     });
78     runTest(function() {
79         iframeDoc.body.insertBefore(document.createElement('div'), iframeDoc.body.firstChild);
80         iframeDoc.body.insertBefore(elementInCurrentDocument('insertBefore'), iframeDoc.body.firstChild);
81     });
82     runTest(function() {
83         rangeInIframe().insertNode(document.createElement('div'));
84         rangeInIframe().insertNode(elementInCurrentDocument('insertNode'));
85     });
86     runTest(function() {
87         rangeInIframe().surroundContents(document.createElement('div'));
88         rangeInIframe().surroundContents(elementInCurrentDocument('surroundContents'));
89     });
90
91     runTest(function() {
92         iframeDoc.body.appendChild(document.createElement('div'));
93         var element = elementInCurrentDocument('insertBefore');
94         // Make sure we don't crash if the element is moved back to the original document during the insertBefore call.
95         var mutationHandler = function() {
96             document.body.removeEventListener('DOMSubtreeModified', mutationHandler, true);
97             document.body.appendChild(element);
98             // Access something on the element to see if it's in a valid state.
99             element.offsetLeft;
100         };
101         document.body.addEventListener('DOMSubtreeModified', mutationHandler, true);
102         try {
103             iframeDoc.body.insertBefore(element);
104         } catch (e) {
105           throw e;
106         } finally {
107           // Clear the event handler to avoid affecting the following tests.
108         }
109     });
110     
111     runTest(function() {
112         iframeDoc.body.appendChild(document.createElement('div'));
113         var element = elementInCurrentDocument('appendChild');
114         // Make sure we don't crash if the element is moved back to the original document during the insertBefore call.
115         var mutationHandler = function() {
116             document.body.removeEventListener('DOMSubtreeModified', mutationHandler, true);
117             document.body.appendChild(element);
118             // Access something on the element to see if it's in a valid state.
119             element.offsetLeft;
120         };
121         document.body.addEventListener('DOMSubtreeModified', mutationHandler, true);
122         try {
123             iframeDoc.body.appendChild(element);
124         } catch (e) {
125           throw e;
126         } finally {
127           // Clear the event handler to avoid affecting the following tests.
128         }
129     });
130
131     runTest(function() {
132         iframeDoc.body.appendChild(document.createElement('div'));
133         var element = elementInCurrentDocument('replaceChild');
134         // Make sure we don't crash if the element is moved back to the original document during the insertBefore call.
135         var mutationHandler = function() {
136             document.body.removeEventListener('DOMSubtreeModified', mutationHandler, true);
137             document.body.appendChild(element);
138             // Access something on the element to see if it's in a valid state.
139             element.offsetLeft;
140         };
141         document.body.addEventListener('DOMSubtreeModified', mutationHandler, true);
142         try {
143             iframeDoc.body.replaceChild(element, iframeDoc.body.firstChild);
144         } catch (e) {
145           throw e;
146         } finally {
147           // Clear the event handler to avoid affecting the following tests.
148         }
149     });
150
151     runTest(function() {
152         var attribute = document.createAttribute('asdf');
153         iframeDoc.body.attributes.setNamedItem(attribute);
154     });
155     runTest(function() {
156         var attribute = document.createAttribute('asdf');
157         document.body.attributes.setNamedItem(attribute);
158         iframeDoc.body.attributes.setNamedItem(attribute);
159     }, 'InUseAttributeError');
160
161     runTest(function() {
162         var doctype = document.implementation.createDocumentType(
163             'html',
164             '-//W3C//DTD XHTML 1.0 Strict//EN',
165             'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
166         );
167         iframeDoc.implementation.createDocument('', 'html', doctype); 
168     });
169     runTest(function() {
170         iframeDoc.implementation.createDocument('', 'html', document.doctype); 
171     });
172     runTest(function() {
173         rangeInIframe().compareBoundaryPoints(Range.END_TO_END, rangeInCurrentDocument());
174     }, 'WrongDocumentError');
175     runTest(function() {
176         rangeInIframe().comparePoint(elementInCurrentDocument('comparePoint'), 0);
177     }, 'WrongDocumentError');
178
179     runTest(function() {
180         iframeDoc.appendChild(document.doctype);
181         console.log(document.doctype);
182     }, 'TypeError');
183
184     // When setting a boundary of the range in a different
185     // document, the call should succeed and the range should be collapsed.
186     runTest(function() {
187         rangeInIframe().setStart(elementInCurrentDocument('setStart'), 0);
188     });
189     runTest(function() {
190         rangeInIframe().setEnd(elementInCurrentDocument('setEnd'), 0);
191     });
192     runTest(function() {
193         rangeInIframe().setStartBefore(elementInCurrentDocument('setStartBefore'), 0);
194     });
195     runTest(function() {
196         rangeInIframe().setStartAfter(elementInCurrentDocument('setStartAfter'), 0);
197     });
198     runTest(function() {
199         rangeInIframe().setEndBefore(elementInCurrentDocument('setEndBefore'), 0);
200     });
201     runTest(function() {
202         rangeInIframe().setEndAfter(elementInCurrentDocument('setEndAfter'), 0);
203     });
204     runTest(function() {
205         rangeInIframe().isPointInRange(elementInCurrentDocument('isPointInRange'), 0);
206     });
207
208 }
209 </script> 
210 <pre id='logger'></pre>
211 <iframe onload='run()'></iframe>