| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library custom_elements_test; | 5 library custom_elements_test; |
| 6 import '../../pkg/unittest/lib/unittest.dart'; | 6 import '../../pkg/unittest/lib/unittest.dart'; |
| 7 import '../../pkg/unittest/lib/html_individual_config.dart'; | 7 import '../../pkg/unittest/lib/html_individual_config.dart'; |
| 8 import 'dart:html'; | 8 import 'dart:html'; |
| 9 | 9 |
| 10 class CustomType extends HtmlElement { | 10 class CustomMixin { |
| 11 var mixinMethodCalled; |
| 12 |
| 13 void mixinMethod() { |
| 14 mixinMethodCalled = true; |
| 15 } |
| 16 } |
| 17 |
| 18 class CustomType extends HtmlElement with CustomMixin{ |
| 11 factory CustomType() => null; | 19 factory CustomType() => null; |
| 12 bool onCreatedCalled; // = false; | 20 bool onCreatedCalled; // = false; |
| 13 void onCreated() { | 21 void onCreated() { |
| 14 onCreatedCalled = true; | 22 onCreatedCalled = true; |
| 15 customCreatedCount++; | 23 customCreatedCount++; |
| 16 } | 24 } |
| 25 |
| 26 void invokeMixinMethod() { |
| 27 mixinMethod(); |
| 28 } |
| 17 } | 29 } |
| 18 | 30 |
| 19 int customCreatedCount = 0; | 31 int customCreatedCount = 0; |
| 20 | 32 |
| 33 int nextTagId = 0; |
| 34 String get nextTag => 'x-type${nextTagId++}'; |
| 35 |
| 21 class NotAnElement {} | 36 class NotAnElement {} |
| 22 | 37 |
| 23 main() { | 38 main() { |
| 24 useHtmlIndividualConfiguration(); | 39 useHtmlIndividualConfiguration(); |
| 25 | 40 |
| 26 group('register', () { | 41 group('register', () { |
| 27 test('register', () { | 42 test('register', () { |
| 28 document.register('x-type1', CustomType); | 43 var tag = nextTag; |
| 44 document.register(tag, CustomType); |
| 29 | 45 |
| 30 var element = new Element.tag('x-type1'); | 46 var element = new Element.tag(tag); |
| 31 expect(element, isNotNull); | 47 expect(element, isNotNull); |
| 32 expect(element is CustomType, isTrue); | 48 expect(element is CustomType, isTrue); |
| 33 expect(element.onCreatedCalled, isTrue); | 49 expect(element.onCreatedCalled, isTrue); |
| 34 }); | 50 }); |
| 35 | 51 |
| 36 test('register twice', () { | 52 test('register twice', () { |
| 37 document.register('x-type2', CustomType); | 53 var tag = nextTag; |
| 54 document.register(tag, CustomType); |
| 38 expect(() { | 55 expect(() { |
| 39 document.register('x-type2', CustomType); | 56 document.register(tag, CustomType); |
| 40 }, throws, reason: 'Cannot register a tag more than once.'); | 57 }, throws, reason: 'Cannot register a tag more than once.'); |
| 41 | 58 |
| 42 document.register('x-type3', CustomType); | 59 var newTag = nextTag; |
| 60 document.register(newTag, CustomType); |
| 43 | 61 |
| 44 var element = new Element.tag('x-type3'); | 62 var element = new Element.tag(newTag); |
| 45 expect(element, isNotNull); | 63 expect(element, isNotNull); |
| 46 expect(element is CustomType, isTrue); | 64 expect(element is CustomType, isTrue); |
| 47 }); | 65 }); |
| 48 | 66 |
| 49 test('register null', () { | 67 test('register null', () { |
| 50 expect(() { | 68 expect(() { |
| 51 document.register('x-type4', null); | 69 document.register(nextTag, null); |
| 52 }, throws, reason: 'Cannot register a null type.'); | 70 }, throws, reason: 'Cannot register a null type.'); |
| 53 }); | 71 }); |
| 54 | 72 |
| 55 test('register native', () { | 73 test('register native', () { |
| 56 expect(() { | 74 expect(() { |
| 57 document.register('x-type5', BodyElement); | 75 document.register(nextTag, BodyElement); |
| 58 }, throws, reason: 'Cannot register a native element.'); | 76 }, throws, reason: 'Cannot register a native element.'); |
| 59 }); | 77 }); |
| 60 | 78 |
| 61 test('register non-element', () { | 79 test('register non-element', () { |
| 62 expect(() { | 80 expect(() { |
| 63 document.register('x-type6', NotAnElement); | 81 document.register(nextTag, NotAnElement); |
| 64 }, throws, reason: 'Cannot register a non-element.'); | 82 }, throws, reason: 'Cannot register a non-element.'); |
| 65 }); | 83 }); |
| 66 }); | 84 }); |
| 67 | 85 |
| 68 group('preregister', () { | 86 group('preregister', () { |
| 69 // TODO(vsm): Modify this test once we agree on the proper semantics. | 87 // TODO(vsm): Modify this test once we agree on the proper semantics. |
| 70 test('pre-registration construction', () { | 88 test('pre-registration construction', () { |
| 71 var dom = new Element.html('<div><x-type7></x-type7></div>'); | 89 var tag = nextTag; |
| 90 var dom = new Element.html('<div><$tag></$tag></div>'); |
| 72 var preElement = dom.children[0]; | 91 var preElement = dom.children[0]; |
| 73 expect(preElement, isNotNull); | 92 expect(preElement, isNotNull); |
| 74 expect(preElement is UnknownElement, isTrue); | 93 expect(preElement is UnknownElement, isTrue); |
| 75 var firedOnPre = false; | 94 var firedOnPre = false; |
| 76 preElement.onFocus.listen((_) { | 95 preElement.onFocus.listen((_) { |
| 77 firedOnPre = true; | 96 firedOnPre = true; |
| 78 }); | 97 }); |
| 79 | 98 |
| 80 document.register('x-type7', CustomType); | 99 document.register(tag, CustomType); |
| 81 | 100 |
| 82 var postElement = dom.children[0]; | 101 var postElement = dom.children[0]; |
| 83 expect(postElement, isNotNull); | 102 expect(postElement, isNotNull); |
| 84 expect(postElement is CustomType, isTrue); | 103 expect(postElement is CustomType, isTrue); |
| 85 expect(postElement.onCreatedCalled, isTrue); | 104 expect(postElement.onCreatedCalled, isTrue); |
| 86 | 105 |
| 87 // Element from first query remains an UnknownElement. | 106 // Element from first query remains an UnknownElement. |
| 88 expect(preElement is UnknownElement, isTrue); | 107 expect(preElement is UnknownElement, isTrue); |
| 89 expect(preElement.parent, isNull); | 108 expect(preElement.parent, isNull); |
| 90 expect(dom.children.length, 1); | 109 expect(dom.children.length, 1); |
| 91 | 110 |
| 92 var firedOnPost = false; | 111 var firedOnPost = false; |
| 93 postElement.onFocus.listen((_) { | 112 postElement.onFocus.listen((_) { |
| 94 firedOnPost = true; | 113 firedOnPost = true; |
| 95 }); | 114 }); |
| 96 // Event handlers should not persist to new element. | 115 // Event handlers should not persist to new element. |
| 97 postElement.dispatchEvent(new Event('focus')); | 116 postElement.dispatchEvent(new Event('focus')); |
| 98 expect(firedOnPre, isFalse); | 117 expect(firedOnPre, isFalse); |
| 99 expect(firedOnPost, isTrue); | 118 expect(firedOnPost, isTrue); |
| 100 }); | 119 }); |
| 101 }); | 120 }); |
| 102 | 121 |
| 103 group('innerHtml', () { | 122 group('innerHtml', () { |
| 104 test('query', () { | 123 test('query', () { |
| 105 document.register('x-type8', CustomType); | 124 var tag = nextTag; |
| 125 document.register(tag, CustomType); |
| 106 var element = new DivElement(); | 126 var element = new DivElement(); |
| 107 element.innerHtml = '<x-type8></x-type8>'; | 127 element.innerHtml = '<$tag></$tag>'; |
| 108 document.body.nodes.add(element); | 128 document.body.nodes.add(element); |
| 109 var queried = query('x-type8'); | 129 var queried = query(tag); |
| 110 | 130 |
| 111 expect(queried, isNotNull); | 131 expect(queried, isNotNull); |
| 112 expect(queried is CustomType, isTrue); | 132 expect(queried is CustomType, isTrue); |
| 113 expect(queried.onCreatedCalled, isTrue); | 133 expect(queried.onCreatedCalled, isTrue); |
| 114 }); | 134 }); |
| 115 | 135 |
| 116 test('query id', () { | 136 test('query id', () { |
| 117 document.register('x-type9', CustomType); | 137 var tag = nextTag; |
| 138 document.register(tag, CustomType); |
| 118 var element = new DivElement(); | 139 var element = new DivElement(); |
| 119 element.innerHtml = '<x-type9 id="someid"></x-type9>'; | 140 element.innerHtml = '<$tag id="someid"></$tag>'; |
| 120 document.body.nodes.add(element); | 141 document.body.nodes.add(element); |
| 121 var queried = query('#someid'); | 142 var queried = query('#someid'); |
| 122 | 143 |
| 123 expect(queried, isNotNull); | 144 expect(queried, isNotNull); |
| 124 expect(queried is CustomType, isTrue); | 145 expect(queried is CustomType, isTrue); |
| 125 expect(queried.id, "someid"); | 146 expect(queried.id, "someid"); |
| 126 }); | 147 }); |
| 127 }); | 148 }); |
| 128 | 149 |
| 129 group('lifecycle', () { | 150 group('lifecycle', () { |
| 130 test('onCreated', () { | 151 test('onCreated', () { |
| 131 int oldCount = customCreatedCount; | 152 int oldCount = customCreatedCount; |
| 132 | 153 var tag = nextTag; |
| 133 document.register('x-type10', CustomType); | 154 document.register(tag, CustomType); |
| 134 var element = new DivElement(); | 155 var element = new DivElement(); |
| 135 element.innerHtml = '<x-type10></x-type10>'; | 156 element.innerHtml = '<$tag></$tag>'; |
| 136 document.body.nodes.add(element); | 157 document.body.nodes.add(element); |
| 137 expect(customCreatedCount, oldCount + 1); | 158 expect(customCreatedCount, oldCount + 1); |
| 138 }); | 159 }); |
| 139 }); | 160 }); |
| 161 |
| 162 group('mixins', () { |
| 163 test('can invoke mixin methods', () { |
| 164 var tag = nextTag; |
| 165 document.register(tag, CustomType); |
| 166 |
| 167 var element = new Element.tag(tag); |
| 168 element.invokeMixinMethod(); |
| 169 expect(element.mixinMethodCalled, isTrue); |
| 170 }); |
| 171 }); |
| 140 } | 172 } |
| OLD | NEW |