| 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();
|
| + });
|
| + });
|
| +}
|
|
|