// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library custom_elements_test; import 'dart:async'; import 'dart:html'; import 'package:unittest/html_individual_config.dart'; import 'package:unittest/unittest.dart'; import 'utils.dart'; class CustomMixin { var mixinMethodCalled; void mixinMethod() { mixinMethodCalled = true; } } class CustomType extends HtmlElement with CustomMixin{ bool createdCalled = false; factory CustomType() => null; CustomType.created(): super.created() { createdCalled = true; customCreatedCount++; } void invokeMixinMethod() { mixinMethod(); } } int customCreatedCount = 0; int nextTagId = 0; String get nextTag => 'x-type${nextTagId++}'; class NotAnElement {} main() { useHtmlIndividualConfiguration(); setUp(() => customElementsReady); group('register', () { test('register', () { var tag = nextTag; document.registerElement(tag, CustomType); var element = new Element.tag(tag); expect(element, isNotNull); expect(element is CustomType, isTrue); expect(element.createdCalled, isTrue); }); test('register twice', () { var tag = nextTag; document.registerElement(tag, CustomType); expect(() { document.registerElement(tag, CustomType); }, throws, reason: 'Cannot register a tag more than once.'); var newTag = nextTag; document.registerElement(newTag, CustomType); var element = new Element.tag(newTag); expect(element, isNotNull); expect(element is CustomType, isTrue); }); test('register null', () { expect(() { document.registerElement(nextTag, null); }, throws, reason: 'Cannot register a null type.'); }); test('register native', () { expect(() { document.registerElement(nextTag, BodyElement); }, throws, reason: 'Cannot register a native element.'); }); test('register non-element', () { expect(() { document.registerElement(nextTag, NotAnElement); }, throws, reason: 'Cannot register a non-element.'); }); }); // TODO(vsm): Modify this test once we agree on the proper semantics. /* group('preregister', () { test('pre-registration construction', () { var tag = nextTag; var dom = new Element.html('
<$tag>
'); var preElement = dom.children[0]; expect(preElement, isNotNull); expect(preElement is HtmlElement, isTrue); expect(preElement is CustomType, isFalse); var firedOnPre = false; preElement.onFocus.listen((_) { firedOnPre = true; }); document.registerElement(tag, CustomType); upgradeCustomElements(dom); var postElement = dom.children[0]; expect(postElement, isNotNull); expect(postElement is CustomType, isTrue); expect(postElement.createdCalled, isTrue); // Element from first query remains an UnknownElement. expect(preElement is HtmlElement, isTrue); expect(preElement.parent, dom); expect(dom.children.length, 1); var firedOnPost = false; postElement.onFocus.listen((_) { firedOnPost = true; }); // Event handlers persist on old and new element. postElement.dispatchEvent(new Event('focus')); expect(firedOnPre, isTrue); expect(firedOnPost, isTrue); }); });*/ group('innerHtml', () { test('query', () { var tag = nextTag; document.registerElement(tag, CustomType); var element = new DivElement(); element.setInnerHtml('<$tag>', treeSanitizer: new NullTreeSanitizer()); upgradeCustomElements(element); document.body.nodes.add(element); var queried = query(tag); expect(queried, isNotNull); expect(queried is CustomType, isTrue); expect(queried.createdCalled, isTrue); }); test('query id', () { var tag = nextTag; document.registerElement(tag, CustomType); var element = new DivElement(); element.setInnerHtml('<$tag id="someid">', treeSanitizer: new NullTreeSanitizer()); upgradeCustomElements(element); document.body.nodes.add(element); var queried = query('#someid'); expect(queried, isNotNull); expect(queried is CustomType, isTrue); expect(queried.id, "someid"); }); }); group('lifecycle', () { test('created', () { int oldCount = customCreatedCount; var tag = nextTag; document.registerElement(tag, CustomType); var element = new DivElement(); element.setInnerHtml('<$tag>', treeSanitizer: new NullTreeSanitizer()); upgradeCustomElements(element); document.body.nodes.add(element); expect(customCreatedCount, oldCount + 1); }); }); group('mixins', () { test('can invoke mixin methods', () { var tag = nextTag; document.registerElement(tag, CustomType); var element = new Element.tag(tag); element.invokeMixinMethod(); expect(element.mixinMethodCalled, isTrue); }); }); }