Index: test/codegen/lib/html/custom/document_register_type_extensions_test.dart |
diff --git a/test/codegen/lib/html/custom/document_register_type_extensions_test.dart b/test/codegen/lib/html/custom/document_register_type_extensions_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..67957b123230ca673e558d2a1b72d5505992a8ee |
--- /dev/null |
+++ b/test/codegen/lib/html/custom/document_register_type_extensions_test.dart |
@@ -0,0 +1,317 @@ |
+// 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 document_register_type_extensions_test; |
+import 'package:unittest/unittest.dart'; |
+import 'package:unittest/html_individual_config.dart'; |
+import 'dart:html'; |
+import '../utils.dart'; |
+ |
+class Foo extends HtmlElement { |
+ static const tag = 'x-foo'; |
+ static final List outerHtmlStrings = [ |
+ '<x-foo></x-foo>', |
+ '<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-foo></x-foo>']; |
+ factory Foo() => new Element.tag(tag); |
+ Foo.created() : super.created(); |
+} |
+ |
+class Bar extends InputElement { |
+ static const tag = 'x-bar'; |
+ static const outerHtmlString = '<input is="x-bar">'; |
+ factory Bar() => new Element.tag('input', tag); |
+ Bar.created() : super.created(); |
+} |
+ |
+class Baz extends Foo { |
+ static const tag = 'x-baz'; |
+ static final List outerHtmlStrings = [ |
+ '<x-baz></x-baz>', |
+ '<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-baz></x-baz>']; |
+ factory Baz() => new Element.tag(tag); |
+ Baz.created() : super.created(); |
+} |
+ |
+class Qux extends Bar { |
+ static const tag = 'x-qux'; |
+ factory Qux() => new Element.tag('input', tag); |
+ Qux.created() : super.created(); |
+} |
+ |
+class FooBad extends DivElement { |
+ static const tag = 'x-foo'; |
+ factory FooBad() => new Element.tag('div', tag); |
+ FooBad.created() : super.created(); |
+} |
+ |
+class MyCanvas extends CanvasElement { |
+ static const tag = 'my-canvas'; |
+ factory MyCanvas() => new Element.tag('canvas', tag); |
+ |
+ MyCanvas.created() : super.created(); |
+ |
+ void fillAsRed() { |
+ width = 100; |
+ height = 100; |
+ |
+ var context = this.getContext('2d'); |
+ context.fillStyle = 'red'; |
+ context.fillRect(0, 0, width, height); |
+ context.fill(); |
+ |
+ var data = context.getImageData(0, 0, 1, 1).data; |
+ expect(data, [255, 0, 0, 255]); |
+ } |
+} |
+ |
+class CustomDiv extends DivElement { |
+ CustomDiv.created() : super.created(); |
+} |
+ |
+class CustomCustomDiv extends CustomDiv { |
+ static const tag = 'custom-custom'; |
+ CustomCustomDiv.created() : super.created(); |
+} |
+ |
+main() { |
+ useHtmlIndividualConfiguration(); |
+ |
+ // Adapted from Blink's fast/dom/custom/document-register-type-extension test. |
+ |
+ var testForm = new FormElement()..id = 'testForm'; |
+ document.body.append(testForm); |
+ |
+ var isFormControl = (element) { |
+ testForm.append(element); |
+ return element.form == testForm; |
+ }; |
+ |
+ var registeredTypes = false; |
+ void registerTypes() { |
+ if (registeredTypes) { |
+ return; |
+ } |
+ registeredTypes = true; |
+ document.registerElement(Foo.tag, Foo); |
+ document.registerElement(Bar.tag, Bar, extendsTag: 'input'); |
+ document.registerElement(Baz.tag, Baz); |
+ document.registerElement(Qux.tag, Qux, extendsTag: 'input'); |
+ document.registerElement(MyCanvas.tag, MyCanvas, extendsTag: 'canvas'); |
+ document.registerElement(CustomCustomDiv.tag, CustomCustomDiv, extendsTag: 'div'); |
+ } |
+ |
+ setUp(() => customElementsReady); |
+ |
+ group('registration', () { |
+ setUp(registerTypes); |
+ |
+ test('cannot register twice', () { |
+ expect(() => document.registerElement(FooBad.tag, Foo, extendsTag: 'div'), |
+ throws); |
+ }); |
+ |
+ test('cannot register for non-matching tag', () { |
+ expect(() { |
+ document.registerElement('x-input-div', Bar, extendsTag: 'div'); |
+ }, throws); |
+ }); |
+ |
+ test('cannot register type extension for custom tag', () { |
+ expect(() { |
+ document.registerElement('x-custom-tag', CustomCustomDiv); |
+ }, throws); |
+ }); |
+ }); |
+ |
+ group('construction', () { |
+ setUp(registerTypes); |
+ |
+ group('constructors', () { |
+ |
+ test('custom tag', () { |
+ var fooNewed = new Foo(); |
+ expect(fooNewed.outerHtml, anyOf(Foo.outerHtmlStrings)); |
+ expect(fooNewed is Foo, isTrue); |
+ expect(fooNewed is HtmlElement, isTrue); |
+ expect(fooNewed is UnknownElement, isFalse); |
+ }); |
+ |
+ test('type extension', () { |
+ var barNewed = new Bar(); |
+ expect(barNewed.outerHtml, Bar.outerHtmlString); |
+ expect(barNewed is Bar, isTrue); |
+ expect(barNewed is InputElement, isTrue); |
+ expect(isFormControl(barNewed), isTrue); |
+ }); |
+ |
+ test('custom tag deriving from custom tag', () { |
+ var bazNewed = new Baz(); |
+ expect(bazNewed.outerHtml, anyOf(Baz.outerHtmlStrings)); |
+ expect(bazNewed is Baz, isTrue); |
+ expect(bazNewed is HtmlElement, isTrue); |
+ expect(bazNewed is UnknownElement, isFalse); |
+ }); |
+ |
+ test('type extension deriving from custom tag', () { |
+ var quxNewed = new Qux(); |
+ var quxOuterHtml = '<input is="x-qux">'; |
+ expect(quxNewed.outerHtml, quxOuterHtml); |
+ expect(quxNewed is Qux, isTrue); |
+ expect(quxNewed is InputElement, isTrue); |
+ expect(isFormControl(quxNewed), isTrue); |
+ }); |
+ }); |
+ |
+ group('single-parameter createElement', () { |
+ test('custom tag', () { |
+ var fooCreated = new Element.tag('x-foo'); |
+ expect(fooCreated.outerHtml, anyOf(Foo.outerHtmlStrings)); |
+ expect(fooCreated is Foo, isTrue); |
+ }); |
+ |
+ test('does not upgrade type extension', () { |
+ var barCreated = new Element.tag('x-bar'); |
+ expect(barCreated is Bar, isFalse); |
+ expect(barCreated.outerHtml, "<x-bar></x-bar>"); |
+ expect(barCreated is UnknownElement, isFalse); |
+ expect(barCreated is HtmlElement, isTrue); |
+ }); |
+ |
+ test('custom tag deriving from custom tag', () { |
+ var bazCreated = new Element.tag('x-baz'); |
+ expect(bazCreated.outerHtml, anyOf(Baz.outerHtmlStrings)); |
+ expect(bazCreated is Baz, isTrue); |
+ expect(bazCreated is UnknownElement, isFalse); |
+ }); |
+ |
+ test('type extension deriving from custom tag', () { |
+ var quxCreated = new Element.tag('x-qux'); |
+ expect(quxCreated.outerHtml, "<x-qux></x-qux>"); |
+ expect(quxCreated is Qux, isFalse); |
+ expect(quxCreated is UnknownElement, isFalse); |
+ expect(quxCreated is HtmlElement, isTrue); |
+ }); |
+ }); |
+ |
+ group('createElement with type extension', () { |
+ test('does not upgrade extension of custom tag', () { |
+ var divFooCreated = new Element.tag("div", Foo.tag); |
+ expect(divFooCreated.outerHtml, '<div is="x-foo"></div>'); |
+ expect(divFooCreated is Foo, isFalse); |
+ expect(divFooCreated is DivElement, isTrue); |
+ }); |
+ |
+ test('upgrades valid extension', () { |
+ var inputBarCreated = new Element.tag("input", Bar.tag); |
+ expect(inputBarCreated.outerHtml, Bar.outerHtmlString); |
+ expect(inputBarCreated is Bar, isTrue); |
+ expect(inputBarCreated is UnknownElement, isFalse); |
+ expect(isFormControl(inputBarCreated), isTrue); |
+ }); |
+ |
+ test('type extension of incorrect tag', () { |
+ var divBarCreated = new Element.tag("div", Bar.tag); |
+ expect(divBarCreated.outerHtml, '<div is="x-bar"></div>'); |
+ expect(divBarCreated is Bar, isFalse); |
+ expect(divBarCreated is DivElement, isTrue); |
+ }); |
+ |
+ test('incorrect extension of custom tag', () { |
+ var fooBarCreated = new Element.tag(Foo.tag, Bar.tag); |
+ expect(fooBarCreated.outerHtml, anyOf( |
+ '<x-foo is="x-bar"></x-foo>', |
+ '<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" />' |
+ '<x-foo is="x-bar"></x-foo>')); |
+ expect(fooBarCreated is Foo, isTrue); |
+ }); |
+ |
+ test('incorrect extension of type extension', () { |
+ var barFooCreated = new Element.tag(Bar.tag, Foo.tag); |
+ expect(barFooCreated.outerHtml, '<x-bar is="x-foo"></x-bar>'); |
+ expect(barFooCreated is UnknownElement, isFalse); |
+ expect(barFooCreated is HtmlElement, isTrue); |
+ }); |
+ |
+ test('null type extension', () { |
+ var fooCreatedNull = new Element.tag(Foo.tag, null); |
+ expect(fooCreatedNull.outerHtml, anyOf(Foo.outerHtmlStrings)); |
+ expect(fooCreatedNull is Foo, isTrue); |
+ }); |
+ |
+ test('empty type extension', () { |
+ var fooCreatedEmpty = new Element.tag(Foo.tag, ""); |
+ expect(fooCreatedEmpty.outerHtml, anyOf(Foo.outerHtmlStrings)); |
+ expect(fooCreatedEmpty is Foo, isTrue); |
+ }); |
+ }); |
+ }); |
+ |
+ group('namespaces', () { |
+ setUp(registerTypes); |
+ |
+ test('createElementNS', () { |
+ var fooCreatedNS = |
+ document.createElementNS("http://www.w3.org/1999/xhtml", |
+ Foo.tag, null); |
+ expect(fooCreatedNS.outerHtml, anyOf(Foo.outerHtmlStrings)); |
+ expect(fooCreatedNS is Foo, isTrue); |
+ |
+ var barCreatedNS = |
+ document.createElementNS("http://www.w3.org/1999/xhtml", "input", |
+ Bar.tag); |
+ expect(barCreatedNS.outerHtml, Bar.outerHtmlString); |
+ expect(barCreatedNS is Bar, isTrue); |
+ expect(isFormControl(barCreatedNS), isTrue); |
+ |
+ expect(() => |
+ document.createElementNS( |
+ 'http://example.com/2013/no-such-namespace', |
+ 'xml:lang', 'x-bar'), throws); |
+ }); |
+ }); |
+ |
+ group('parsing', () { |
+ setUp(registerTypes); |
+ |
+ test('parsing', () { |
+ createElementFromHtml(html) { |
+ var container = new DivElement()..setInnerHtml(html, |
+ treeSanitizer: new NullTreeSanitizer()); |
+ upgradeCustomElements(container); |
+ return container.firstChild; |
+ } |
+ |
+ var fooParsed = createElementFromHtml('<x-foo>'); |
+ expect(fooParsed is Foo, isTrue); |
+ |
+ var barParsed = createElementFromHtml('<input is=x-bar>'); |
+ expect(barParsed is Bar, isTrue); |
+ expect(isFormControl(barParsed), isTrue); |
+ |
+ var divFooParsed = createElementFromHtml('<div is=x-foo>'); |
+ expect(divFooParsed is Foo, isFalse); |
+ expect(divFooParsed is DivElement, isTrue); |
+ |
+ var namedBarParsed = createElementFromHtml('<x-bar>'); |
+ expect(namedBarParsed is Bar, isFalse); |
+ // Polyfill does not convert parsed unregistered custom elements to |
+ // HtmlElement. |
+ // expect(namedBarParsed is UnknownElement, isFalse); |
+ expect(namedBarParsed is HtmlElement, isTrue); |
+ |
+ var divBarParsed = createElementFromHtml('<div is=x-bar>'); |
+ expect(divBarParsed is Bar, isFalse); |
+ expect(divBarParsed is DivElement, isTrue); |
+ }); |
+ }); |
+ |
+ group('functional', () { |
+ setUp(registerTypes); |
+ |
+ test('canvas', () { |
+ var canvas = new MyCanvas(); |
+ canvas.fillAsRed(); |
+ }); |
+ }); |
+} |