| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library entered_left_view_test; |
| 6 |
| 7 import 'dart:async'; |
| 8 import 'dart:html'; |
| 9 import 'dart:js' as js; |
| 10 import 'package:unittest/html_individual_config.dart'; |
| 11 import 'package:unittest/unittest.dart'; |
| 12 import '../utils.dart'; |
| 13 |
| 14 var invocations = []; |
| 15 class Foo extends HtmlElement { |
| 16 factory Foo() => null; |
| 17 |
| 18 void created() { |
| 19 invocations.add('created'); |
| 20 } |
| 21 |
| 22 void enteredView() { |
| 23 invocations.add('entered'); |
| 24 } |
| 25 |
| 26 void leftView() { |
| 27 invocations.add('left'); |
| 28 } |
| 29 |
| 30 void attributeChanged() { |
| 31 invocations.add('attribute changed'); |
| 32 } |
| 33 } |
| 34 |
| 35 // Pump custom events polyfill events. |
| 36 void customElementsTakeRecords() { |
| 37 if (js.context.hasProperty('CustomElements')) { |
| 38 js.context['CustomElements'].callMethod('takeRecords'); |
| 39 } |
| 40 } |
| 41 |
| 42 main() { |
| 43 useHtmlIndividualConfiguration(); |
| 44 |
| 45 // Adapted from Blink's |
| 46 // fast/dom/custom/entered-left-document.html test. |
| 47 |
| 48 var docA = document; |
| 49 var docB = document.implementation.createHtmlDocument(''); |
| 50 |
| 51 var nullSanitizer = new NullTreeSanitizer(); |
| 52 |
| 53 var registeredTypes = false; |
| 54 setUp(() { |
| 55 return loadPolyfills().then((_) { |
| 56 if (registeredTypes) { |
| 57 return; |
| 58 } |
| 59 registeredTypes = true; |
| 60 document.register('x-a', Foo); |
| 61 }); |
| 62 }); |
| 63 |
| 64 group('standard_events', () { |
| 65 var a = new Element.tag('x-a'); |
| 66 setUp(() { |
| 67 invocations = []; |
| 68 }); |
| 69 |
| 70 test('Created', () { |
| 71 a = new Element.tag('x-a'); |
| 72 expect(invocations, ['created']); |
| 73 }); |
| 74 |
| 75 test('entered', () { |
| 76 document.body.append(a); |
| 77 customElementsTakeRecords(); |
| 78 expect(invocations, ['entered']); |
| 79 }); |
| 80 |
| 81 test('left', () { |
| 82 a.remove(); |
| 83 customElementsTakeRecords(); |
| 84 expect(invocations, ['left']); |
| 85 }); |
| 86 |
| 87 var div = new DivElement(); |
| 88 test('nesting does not trigger entered', () { |
| 89 div.append(a); |
| 90 customElementsTakeRecords(); |
| 91 expect(invocations, []); |
| 92 }); |
| 93 |
| 94 test('nested entering triggers entered', () { |
| 95 document.body.append(div); |
| 96 customElementsTakeRecords(); |
| 97 expect(invocations, ['entered']); |
| 98 }); |
| 99 |
| 100 test('nested leaving triggers left', () { |
| 101 div.remove(); |
| 102 customElementsTakeRecords(); |
| 103 expect(invocations, ['left']); |
| 104 }); |
| 105 }); |
| 106 |
| 107 group('viewless_document', () { |
| 108 var a = docB.createElement('x-a'); |
| 109 setUp(() { |
| 110 invocations = []; |
| 111 }); |
| 112 |
| 113 test('Created, owned by a document without a view', () { |
| 114 a = docB.createElement('x-a'); |
| 115 expect(a.document, docB, |
| 116 reason:'new instance should be owned by the document the definition ' |
| 117 'was registered with'); |
| 118 expect(invocations, ['created'], |
| 119 reason: 'calling the constructor should invoke the created callback'); |
| 120 }); |
| 121 |
| 122 test('Entered document without a view', () { |
| 123 docB.body.append(a); |
| 124 expect(invocations, [], |
| 125 reason: 'entered callback should not be invoked when entering a ' |
| 126 'document without a view'); |
| 127 }); |
| 128 |
| 129 /* |
| 130 test('Attribute changed in document without a view', () { |
| 131 a.setAttribute('data-foo', 'bar'); |
| 132 expect(invocations, ['attribute changed'], |
| 133 reason: 'changing an attribute should invoke the callback, even in a ' |
| 134 'document without a view'); |
| 135 }); |
| 136 */ |
| 137 test('Entered document with a view', () { |
| 138 document.body.append(a); |
| 139 customElementsTakeRecords(); |
| 140 expect(invocations, ['entered'], |
| 141 reason: 'entered callback should be invoked when entering a document ' |
| 142 'with a view'); |
| 143 }); |
| 144 |
| 145 test('Left document with a view', () { |
| 146 a.remove(); |
| 147 customElementsTakeRecords(); |
| 148 expect(invocations, ['left'], |
| 149 reason: 'left callback should be invoked when leaving a document ' |
| 150 'with a view'); |
| 151 }); |
| 152 |
| 153 test('Created in a document without a view', () { |
| 154 docB.body.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer); |
| 155 Platform.upgradeCustomElements(docB.body); |
| 156 |
| 157 expect(invocations, ['created'], |
| 158 reason: 'only created callback should be invoked when parsing a ' |
| 159 'custom element in a document without a view'); |
| 160 }); |
| 161 }); |
| 162 |
| 163 group('shadow_dom', () { |
| 164 var div; |
| 165 var s; |
| 166 setUp(() { |
| 167 invocations = []; |
| 168 div = new DivElement(); |
| 169 s = div.createShadowRoot(); |
| 170 }); |
| 171 |
| 172 tearDown(() { |
| 173 customElementsTakeRecords(); |
| 174 }); |
| 175 |
| 176 test('Created in Shadow DOM that is not in a document', () { |
| 177 s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer); |
| 178 Platform.upgradeCustomElements(s); |
| 179 |
| 180 expect(invocations, ['created'], |
| 181 reason: 'the entered callback should not be invoked when entering a ' |
| 182 'Shadow DOM subtree not in the document'); |
| 183 }); |
| 184 |
| 185 test('Leaves Shadow DOM that is not in a document', () { |
| 186 s.innerHtml = ''; |
| 187 expect(invocations, [], |
| 188 reason: 'the left callback should not be invoked when leaving a ' |
| 189 'Shadow DOM subtree not in the document'); |
| 190 }); |
| 191 |
| 192 test('Enters a document with a view as a constituent of Shadow DOM', () { |
| 193 s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer); |
| 194 Platform.upgradeCustomElements(s); |
| 195 |
| 196 document.body.append(div); |
| 197 customElementsTakeRecords(); |
| 198 expect(invocations, ['created', 'entered'], |
| 199 reason: 'the entered callback should be invoked when inserted into ' |
| 200 'a document with a view as part of Shadow DOM'); |
| 201 |
| 202 div.remove(); |
| 203 customElementsTakeRecords(); |
| 204 |
| 205 expect(invocations, ['created', 'entered', 'left'], |
| 206 reason: 'the left callback should be invoked when removed from a ' |
| 207 'document with a view as part of Shadow DOM'); |
| 208 }); |
| 209 }); |
| 210 |
| 211 |
| 212 group('disconnected_subtree', () { |
| 213 var div = new DivElement(); |
| 214 |
| 215 setUp(() { |
| 216 invocations = []; |
| 217 }); |
| 218 |
| 219 test('Enters a disconnected subtree of DOM', () { |
| 220 div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer); |
| 221 Platform.upgradeCustomElements(div); |
| 222 |
| 223 expect(invocations, ['created'], |
| 224 reason: 'the entered callback should not be invoked when inserted ' |
| 225 'into a disconnected subtree'); |
| 226 }); |
| 227 |
| 228 test('Leaves a disconnected subtree of DOM', () { |
| 229 div.innerHtml = ''; |
| 230 expect(invocations, [], |
| 231 reason: 'the left callback should not be invoked when removed from a ' |
| 232 'disconnected subtree'); |
| 233 }); |
| 234 |
| 235 test('Enters a document with a view as a constituent of a subtree', () { |
| 236 div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer); |
| 237 Platform.upgradeCustomElements(div); |
| 238 invocations = []; |
| 239 document.body.append(div); |
| 240 customElementsTakeRecords(); |
| 241 expect(invocations, ['entered'], |
| 242 reason: 'the entered callback should be invoked when inserted into a ' |
| 243 'document with a view as part of a subtree'); |
| 244 }); |
| 245 }); |
| 246 } |
| OLD | NEW |