mirror of
https://github.com/dart-lang/sdk
synced 2024-10-01 19:29:09 +00:00
[3.0 alpha] Remove dart:html's deprecated document.registerElement & registerElement2 APIs
Change-Id: I07fc124c55d1aeb678f39a4d72d3b4f581025a10 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/273541 Reviewed-by: Srujan Gaddam <srujzs@google.com> Commit-Queue: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
98eedc6f22
commit
c91b73eaf7
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,3 +1,14 @@
|
|||
## 3.0.0
|
||||
|
||||
### Libraries
|
||||
|
||||
#### `dart:html`
|
||||
|
||||
- **Breaking change**: As previously announced, the deprecated `registerElement`
|
||||
and `registerElement2` methods in `Document` and `HtmlDocument` have been
|
||||
removed. See [#49536](https://github.com/dart-lang/sdk/issues/49536) for
|
||||
details.
|
||||
|
||||
## 2.19.0
|
||||
|
||||
### Language
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.7
|
||||
|
||||
// Test of the graph segmentation algorithm used by deferred loading
|
||||
// to determine which elements can be deferred and which libraries
|
||||
// much be included in the initial download (loaded eagerly).
|
||||
|
||||
import 'package:async_helper/async_helper.dart';
|
||||
import 'package:compiler/src/compiler.dart';
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:compiler/src/util/memory_compiler.dart';
|
||||
|
||||
void main() {
|
||||
asyncTest(() async {
|
||||
print('--test from kernel------------------------------------------------');
|
||||
await runTest();
|
||||
});
|
||||
}
|
||||
|
||||
runTest() async {
|
||||
CompilationResult result =
|
||||
await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
|
||||
Compiler compiler = result.compiler;
|
||||
var closedWorld = compiler.backendClosedWorldForTesting;
|
||||
var outputUnitForMember = closedWorld.outputUnitData.outputUnitForMember;
|
||||
var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
|
||||
var mainOutputUnit = closedWorld.outputUnitData.mainOutputUnit;
|
||||
var elementEnvironment = closedWorld.elementEnvironment;
|
||||
dynamic lib = elementEnvironment.lookupLibrary(Uri.parse("memory:lib.dart"));
|
||||
var customType = elementEnvironment.lookupClass(lib, "CustomType");
|
||||
var foo = elementEnvironment.lookupLibraryMember(lib, "foo");
|
||||
Expect.notEquals(mainOutputUnit, outputUnitForMember(foo));
|
||||
// Native elements are not deferred
|
||||
Expect.equals(mainOutputUnit, outputUnitForClass(customType));
|
||||
}
|
||||
|
||||
// The main library imports a file defining a custom element.
|
||||
// Registering this class implicitly causes the constructors to be
|
||||
// live. Check that this is handled.
|
||||
const Map<String, String> MEMORY_SOURCE_FILES = const {
|
||||
"main.dart": """
|
||||
import "lib.dart" deferred as a;
|
||||
import 'dart:html';
|
||||
|
||||
main() {
|
||||
document.registerElement("foo-tag", a.a);
|
||||
a.foo();
|
||||
}
|
||||
""",
|
||||
"lib.dart": """
|
||||
import 'dart:html';
|
||||
var a = CustomType;
|
||||
|
||||
class CustomType extends HtmlElement {
|
||||
factory CustomType() => null;
|
||||
CustomType.created() : super.created() ;
|
||||
}
|
||||
|
||||
foo() {}
|
||||
""",
|
||||
};
|
|
@ -10112,22 +10112,6 @@ class Document extends Node {
|
|||
|
||||
String queryCommandValue(String commandId) native;
|
||||
|
||||
@deprecated
|
||||
Function registerElement2(String type, [Map? options]) {
|
||||
if (options != null) {
|
||||
var options_1 = convertDartToNative_Dictionary(options);
|
||||
return _registerElement2_1(type, options_1);
|
||||
}
|
||||
return _registerElement2_2(type);
|
||||
}
|
||||
|
||||
@JSName('registerElement')
|
||||
@deprecated
|
||||
Function _registerElement2_1(type, options) native;
|
||||
@JSName('registerElement')
|
||||
@deprecated
|
||||
Function _registerElement2_2(type) native;
|
||||
|
||||
@JSName('webkitExitFullscreen')
|
||||
@SupportedBrowser(SupportedBrowser.CHROME)
|
||||
@SupportedBrowser(SupportedBrowser.SAFARI)
|
||||
|
@ -10424,29 +10408,6 @@ class Document extends Node {
|
|||
ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
|
||||
new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));
|
||||
|
||||
/// Checks if [registerElement] is supported on the current platform.
|
||||
@deprecated
|
||||
bool get supportsRegisterElement {
|
||||
return JS('bool', '("registerElement" in #)', this);
|
||||
}
|
||||
|
||||
/// *Deprecated*: use [supportsRegisterElement] instead.
|
||||
@deprecated
|
||||
bool get supportsRegister => supportsRegisterElement;
|
||||
|
||||
/// **Deprecated**: This is a legacy API based on a deprecated Web Components
|
||||
/// v0.5 specification. Web Components v0.5 doesn't work on modern browsers
|
||||
/// and can only be used with a polyfill.
|
||||
///
|
||||
/// The latest Web Components specification is supported indirectly via
|
||||
/// JSInterop and doesn't have an explicit API in the `dart:html` library.
|
||||
@deprecated
|
||||
void registerElement(String tag, Type customElementClass,
|
||||
{String? extendsTag}) {
|
||||
registerElement2(
|
||||
tag, {'prototype': customElementClass, 'extends': extendsTag});
|
||||
}
|
||||
|
||||
@pragma('dart2js:tryInline') // Almost all call sites have one argument.
|
||||
Element createElement(String tagName, [String? typeExtension]) {
|
||||
return (typeExtension == null)
|
||||
|
@ -17840,67 +17801,6 @@ class HtmlDocument extends Document {
|
|||
_webkitExitFullscreen();
|
||||
}
|
||||
|
||||
/**
|
||||
* **Deprecated**: This is a legacy API based on a deprecated Web Components
|
||||
* v0.5 specification. This method doesn't work on modern browsers and can
|
||||
* only be used with a polyfill.
|
||||
*
|
||||
* The latest Web Components specification is supported indirectly via
|
||||
* JSInterop and doesn't have an explicit API in the `dart:html` library.
|
||||
*
|
||||
* *Original documentation before deprecation*:
|
||||
*
|
||||
* Register a custom subclass of Element to be instantiatable by the DOM.
|
||||
*
|
||||
* This is necessary to allow the construction of any custom elements.
|
||||
*
|
||||
* The class being registered must either subclass HtmlElement or SvgElement.
|
||||
* If they subclass these directly then they can be used as:
|
||||
*
|
||||
* class FooElement extends HtmlElement{
|
||||
* void created() {
|
||||
* print('FooElement created!');
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* main() {
|
||||
* document.registerElement('x-foo', FooElement);
|
||||
* var myFoo = new Element.tag('x-foo');
|
||||
* // prints 'FooElement created!' to the console.
|
||||
* }
|
||||
*
|
||||
* The custom element can also be instantiated via HTML using the syntax
|
||||
* `<x-foo></x-foo>`
|
||||
*
|
||||
* Other elements can be subclassed as well:
|
||||
*
|
||||
* class BarElement extends InputElement{
|
||||
* void created() {
|
||||
* print('BarElement created!');
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* main() {
|
||||
* document.registerElement('x-bar', BarElement);
|
||||
* var myBar = new Element.tag('input', 'x-bar');
|
||||
* // prints 'BarElement created!' to the console.
|
||||
* }
|
||||
*
|
||||
* This custom element can also be instantiated via HTML using the syntax
|
||||
* `<input is="x-bar"></input>`
|
||||
*
|
||||
*/
|
||||
@deprecated
|
||||
Function registerElement2(String tag, [Map? options]) {
|
||||
return _registerCustomElement(JS('', 'window'), this, tag, options);
|
||||
}
|
||||
|
||||
/** *Deprecated*: use [registerElement] instead. */
|
||||
@deprecated
|
||||
void register(String tag, Type customElementClass, {String? extendsTag}) {
|
||||
return registerElement(tag, customElementClass, extendsTag: extendsTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static factory designed to expose `visibilitychange` events to event
|
||||
* handlers that are not necessarily instances of [Document].
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
// 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 attribute_changed_callback_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class A extends HtmlElement {
|
||||
static final tag = 'x-a';
|
||||
factory A() => new Element.tag(tag) as A;
|
||||
A.created() : super.created();
|
||||
|
||||
static var attributeChangedInvocations = 0;
|
||||
|
||||
void attributeChanged(name, oldValue, newValue) {
|
||||
attributeChangedInvocations++;
|
||||
}
|
||||
}
|
||||
|
||||
class B extends HtmlElement {
|
||||
static final tag = 'x-b';
|
||||
factory B() => new Element.tag(tag) as B;
|
||||
B.created() : super.created() {
|
||||
invocations.add('created');
|
||||
}
|
||||
|
||||
static var invocations = [];
|
||||
|
||||
Completer? completer;
|
||||
|
||||
void attributeChanged(name, oldValue, newValue) {
|
||||
invocations.add('$name: $oldValue => $newValue');
|
||||
if (completer != null) {
|
||||
completer!.complete('value changed to $newValue');
|
||||
completer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pump custom events polyfill events.
|
||||
void customElementsTakeRecords() {
|
||||
if (js.context.hasProperty('CustomElements')) {
|
||||
js.context['CustomElements'].callMethod('takeRecords');
|
||||
}
|
||||
}
|
||||
|
||||
main() async {
|
||||
// Adapted from Blink's fast/dom/custom/attribute-changed-callback test.
|
||||
|
||||
await customElementsReady;
|
||||
document.registerElement2(A.tag, {'prototype': A});
|
||||
document.registerElement2(B.tag, {'prototype': B});
|
||||
|
||||
group('fully_supported', () {
|
||||
test('transfer attribute changed callback', () {
|
||||
var element = new A();
|
||||
|
||||
element.attributes['a'] = 'b';
|
||||
expect(A.attributeChangedInvocations, 1);
|
||||
});
|
||||
|
||||
test('add, change and remove an attribute', () {
|
||||
var b = new B();
|
||||
|
||||
B.invocations = [];
|
||||
b.attributes['data-s'] = 't';
|
||||
expect(B.invocations, ['data-s: null => t']);
|
||||
|
||||
b.attributes['data-v'] = 'w';
|
||||
B.invocations = [];
|
||||
b.attributes['data-v'] = 'x';
|
||||
expect(B.invocations, ['data-v: w => x']);
|
||||
|
||||
B.invocations = [];
|
||||
b.attributes['data-v'] = 'x';
|
||||
expect(B.invocations, []);
|
||||
|
||||
b.attributes.remove('data-v');
|
||||
expect(B.invocations, ['data-v: x => null']);
|
||||
});
|
||||
|
||||
test('add, change ID', () {
|
||||
B.invocations = [];
|
||||
|
||||
var b = new B();
|
||||
var completer = new Completer();
|
||||
b.completer = completer;
|
||||
b.id = 'x';
|
||||
return completer.future
|
||||
.then((_) => expect(B.invocations, ['created', 'id: null => x']))
|
||||
.then((_) {
|
||||
B.invocations = [];
|
||||
var secondCompleter = new Completer();
|
||||
b.completer = secondCompleter;
|
||||
b.attributes.remove('id');
|
||||
return secondCompleter.future;
|
||||
}).then((_) => expect(B.invocations, ['id: x => null']));
|
||||
});
|
||||
});
|
||||
|
||||
group('unsupported_on_polyfill', () {
|
||||
// If these tests start passing, don't remove the status suppression. Move
|
||||
// the tests to the fullYy_supported group.
|
||||
|
||||
test('add, change classes', () {
|
||||
var b = new B();
|
||||
|
||||
B.invocations = [];
|
||||
b.classes.toggle('u');
|
||||
expect(B.invocations, ['class: null => u']);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> attribute_changed_callback_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running attribute_changed_callback_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,296 +0,0 @@
|
|||
// 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 created_callback_test;
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class A extends HtmlElement {
|
||||
static final tag = 'x-a';
|
||||
factory A() => new Element.tag(tag) as A;
|
||||
A.created() : super.created() {
|
||||
createdInvocations++;
|
||||
}
|
||||
|
||||
static int createdInvocations = 0;
|
||||
}
|
||||
|
||||
class B extends HtmlElement {
|
||||
static final tag = 'x-b';
|
||||
factory B() => new Element.tag(tag) as B;
|
||||
B.created() : super.created();
|
||||
}
|
||||
|
||||
class C extends HtmlElement {
|
||||
static final tag = 'x-c';
|
||||
factory C() => new Element.tag(tag) as C;
|
||||
C.created() : super.created() {
|
||||
createdInvocations++;
|
||||
|
||||
if (this.id != 'u') {
|
||||
return;
|
||||
}
|
||||
|
||||
var t = div.querySelector('#t');
|
||||
var v = div.querySelector('#v');
|
||||
var w = div.querySelector('#w');
|
||||
|
||||
expect(querySelector('x-b:not(:unresolved)'), this);
|
||||
expect(querySelectorAll(':unresolved'), [v, w]);
|
||||
|
||||
// As per:
|
||||
// http://www.w3.org/TR/2013/WD-custom-elements-20130514/#serializing-and-parsing
|
||||
// creation order is t, u, v, w (postorder).
|
||||
expect(t is C, isTrue);
|
||||
// Note, this is different from JavaScript where this would be false.
|
||||
expect(v is C, isTrue);
|
||||
}
|
||||
|
||||
static int createdInvocations = 0;
|
||||
static var div;
|
||||
}
|
||||
|
||||
main() async {
|
||||
// Adapted from Blink's
|
||||
// fast/dom/custom/created-callback test.
|
||||
|
||||
await customElementsReady;
|
||||
document.registerElement2(B.tag, {'prototype': B});
|
||||
document.registerElement2(C.tag, {'prototype': C});
|
||||
ErrorConstructorElement.register();
|
||||
|
||||
test('transfer created callback', () {
|
||||
document.registerElement2(A.tag, {'prototype': A as dynamic});
|
||||
var x = new A();
|
||||
expect(A.createdInvocations, 1);
|
||||
});
|
||||
|
||||
test('unresolved and created callback timing', () {
|
||||
var div = new DivElement();
|
||||
C.div = div;
|
||||
div.setInnerHtml("""
|
||||
<x-c id="t"></x-c>
|
||||
<x-b id="u"></x-b>
|
||||
<x-c id="v"></x-c>
|
||||
<x-b id="w"></x-b>
|
||||
""", treeSanitizer: NodeTreeSanitizer.trusted);
|
||||
|
||||
upgradeCustomElements(div);
|
||||
|
||||
expect(C.createdInvocations, 2);
|
||||
expect(div.querySelector('#w') is B, isTrue);
|
||||
});
|
||||
|
||||
test('nesting of constructors', NestedElement.test);
|
||||
|
||||
test('access while upgrading gets unupgraded element',
|
||||
AccessWhileUpgradingElement.test);
|
||||
|
||||
test('cannot call created constructor', () {
|
||||
expect(() {
|
||||
new B.created();
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot register without created', () {
|
||||
expect(() {
|
||||
document.registerElement2(
|
||||
MissingCreatedElement.tag, {'prototype': MissingCreatedElement});
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('throw on createElement does not upgrade', () {
|
||||
ErrorConstructorElement.callCount = 0;
|
||||
|
||||
var e;
|
||||
expectGlobalError(() {
|
||||
e = new Element.tag(ErrorConstructorElement.tag);
|
||||
});
|
||||
expect(ErrorConstructorElement.callCount, 1);
|
||||
expect(e is HtmlElement, isTrue);
|
||||
expect(e is ErrorConstructorElement, isFalse);
|
||||
|
||||
var dummy = new DivElement();
|
||||
dummy.append(e);
|
||||
e = dummy.firstChild;
|
||||
expect(ErrorConstructorElement.callCount, 1);
|
||||
});
|
||||
|
||||
test('throw on innerHtml does not upgrade', () {
|
||||
ErrorConstructorElement.callCount = 0;
|
||||
|
||||
var dummy = new DivElement();
|
||||
var tag = ErrorConstructorElement.tag;
|
||||
expectGlobalError(() {
|
||||
dummy.setInnerHtml('<$tag></$tag>',
|
||||
treeSanitizer: NodeTreeSanitizer.trusted);
|
||||
});
|
||||
|
||||
expect(ErrorConstructorElement.callCount, 1);
|
||||
|
||||
var e = dummy.firstChild;
|
||||
// Accessing should not re-run the constructor.
|
||||
expect(ErrorConstructorElement.callCount, 1);
|
||||
expect(e is HtmlElement, isTrue);
|
||||
expect(e is ErrorConstructorElement, isFalse);
|
||||
});
|
||||
|
||||
test('cannot register created with params', () {
|
||||
expect(() {
|
||||
document.registerElement2(
|
||||
'x-created-with-params', {'prototype': CreatedWithParametersElement});
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('created cannot be called from nested constructor',
|
||||
NestedCreatedConstructorElement.test);
|
||||
|
||||
// TODO(vsm): Port additional test from upstream here:
|
||||
// http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/dom/custom/created-callback.html?r1=156141&r2=156185
|
||||
}
|
||||
|
||||
class NestedElement extends HtmlElement {
|
||||
static final tag = 'x-nested';
|
||||
|
||||
final Element b = new B();
|
||||
|
||||
factory NestedElement() => new Element.tag(tag) as NestedElement;
|
||||
NestedElement.created() : super.created();
|
||||
|
||||
static void register() {
|
||||
document.registerElement2(tag, {'prototype': NestedElement});
|
||||
}
|
||||
|
||||
static void test() {
|
||||
register();
|
||||
|
||||
var e = new NestedElement();
|
||||
expect(e.b, isNotNull);
|
||||
expect(e.b is B, isTrue);
|
||||
expect(e is NestedElement, isTrue);
|
||||
}
|
||||
}
|
||||
|
||||
class AccessWhileUpgradingElement extends HtmlElement {
|
||||
static final tag = 'x-access-while-upgrading';
|
||||
|
||||
static late Element upgradingContext;
|
||||
static late Element upgradingContextChild;
|
||||
|
||||
final foo = runInitializerCode();
|
||||
|
||||
factory AccessWhileUpgradingElement() =>
|
||||
new Element.tag(tag) as AccessWhileUpgradingElement;
|
||||
AccessWhileUpgradingElement.created() : super.created();
|
||||
|
||||
static runInitializerCode() {
|
||||
upgradingContextChild = upgradingContext.firstChild as Element;
|
||||
|
||||
return 666;
|
||||
}
|
||||
|
||||
static void register() {
|
||||
document.registerElement2(tag, {'prototype': AccessWhileUpgradingElement});
|
||||
}
|
||||
|
||||
static void test() {
|
||||
register();
|
||||
|
||||
upgradingContext = new DivElement();
|
||||
upgradingContext.setInnerHtml('<$tag></$tag>',
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
dynamic child = upgradingContext.firstChild;
|
||||
|
||||
expect(child.foo, 666);
|
||||
expect(upgradingContextChild is HtmlElement, isFalse);
|
||||
expect(upgradingContextChild is AccessWhileUpgradingElement, isFalse,
|
||||
reason: 'Elements accessed while upgrading should not be upgraded.');
|
||||
}
|
||||
}
|
||||
|
||||
class MissingCreatedElement extends HtmlElement {
|
||||
static final tag = 'x-missing-created';
|
||||
|
||||
factory MissingCreatedElement() =>
|
||||
new Element.tag(tag) as MissingCreatedElement;
|
||||
}
|
||||
|
||||
class ErrorConstructorElement extends HtmlElement {
|
||||
static final tag = 'x-throws-in-constructor';
|
||||
static int callCount = 0;
|
||||
|
||||
factory ErrorConstructorElement() =>
|
||||
new Element.tag(tag) as ErrorConstructorElement;
|
||||
|
||||
ErrorConstructorElement.created() : super.created() {
|
||||
++callCount;
|
||||
throw new Exception('Just messin with ya');
|
||||
}
|
||||
|
||||
static void register() {
|
||||
document.registerElement2(tag, {'prototype': ErrorConstructorElement});
|
||||
}
|
||||
}
|
||||
|
||||
class NestedCreatedConstructorElement extends HtmlElement {
|
||||
static final tag = 'x-nested-created-constructor';
|
||||
|
||||
// Should not be able to call this here.
|
||||
final B b = constructB();
|
||||
static B? constructedB;
|
||||
|
||||
factory NestedCreatedConstructorElement() =>
|
||||
new Element.tag(tag) as NestedCreatedConstructorElement;
|
||||
NestedCreatedConstructorElement.created() : super.created();
|
||||
|
||||
static void register() {
|
||||
document
|
||||
.registerElement2(tag, {'prototype': NestedCreatedConstructorElement});
|
||||
}
|
||||
|
||||
// Try to run the created constructor, and record the results.
|
||||
static constructB() {
|
||||
// This should throw an exception.
|
||||
constructedB = new B.created();
|
||||
return constructedB;
|
||||
}
|
||||
|
||||
static void test() {
|
||||
register();
|
||||
|
||||
// Exception should have occurred on upgrade.
|
||||
var e;
|
||||
expectGlobalError(() {
|
||||
e = new Element.tag(tag);
|
||||
});
|
||||
expect(e is NestedCreatedConstructorElement, isFalse);
|
||||
expect(e is HtmlElement, isTrue);
|
||||
// Should not have been set.
|
||||
expect(constructedB, isNull);
|
||||
}
|
||||
}
|
||||
|
||||
class CreatedWithParametersElement extends HtmlElement {
|
||||
CreatedWithParametersElement.created(ignoredParam) : super.created();
|
||||
}
|
||||
|
||||
void expectGlobalError(Function test) {
|
||||
js.context['testExpectsGlobalError'] = true;
|
||||
try {
|
||||
test();
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} finally {
|
||||
js.context['testExpectsGlobalError'] = false;
|
||||
}
|
||||
var errors = js.context['testSuppressedGlobalErrors'];
|
||||
expect(errors['length'], 1);
|
||||
// Clear out the errors;
|
||||
js.context['testSuppressedGlobalErrors']['length'] = 0;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> created_callback_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running created_callback_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,145 +0,0 @@
|
|||
// 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_basic_test;
|
||||
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class Foo extends HtmlElement {
|
||||
static final tag = 'x-foo';
|
||||
factory Foo() => new Element.tag(tag) as Foo;
|
||||
Foo.created() : super.created();
|
||||
|
||||
get thisIsACustomClass => true;
|
||||
}
|
||||
|
||||
class Bar extends HtmlElement {
|
||||
static final tag = 'x-bar';
|
||||
factory Bar() => new Element.tag(tag) as Bar;
|
||||
Bar.created() : super.created();
|
||||
|
||||
get thisIsACustomClass => true;
|
||||
}
|
||||
|
||||
class Baz extends Foo {
|
||||
static final tag = 'x-baz';
|
||||
factory Baz() => new Element.tag(tag) as Baz;
|
||||
Baz.created() : super.created();
|
||||
|
||||
get thisIsAlsoACustomClass => true;
|
||||
}
|
||||
|
||||
class BadB {}
|
||||
|
||||
abstract class BadC extends HtmlElement {
|
||||
BadC.created() : super.created();
|
||||
}
|
||||
|
||||
main() async {
|
||||
// Adapted from Blink's fast/dom/custom/document-register-basic test.
|
||||
|
||||
await customElementsReady;
|
||||
|
||||
test('Testing document.registerElement2() basic behaviors', () {
|
||||
document.registerElement2(Foo.tag, {'prototype': Foo});
|
||||
|
||||
// Cannot register an existing dart:html type.
|
||||
expect(
|
||||
() => document.registerElement2('x-bad-a', {'prototype': HtmlElement}),
|
||||
throws);
|
||||
|
||||
// Invalid user type. Doesn't inherit from HtmlElement.
|
||||
expect(() => document.registerElement2('x-bad-b', {'prototype': BadB}),
|
||||
throws);
|
||||
|
||||
// Cannot register abstract class.
|
||||
expect(() => document.registerElement2('x-bad-c', {'prototype': BadC}),
|
||||
throws);
|
||||
|
||||
// Not a type.
|
||||
expect(() => document.registerElement2('x-bad-d', {'prototype': null}),
|
||||
throws);
|
||||
|
||||
// Cannot register system type.
|
||||
expect(() => document.registerElement2('x-bad-e', {'prototype': Object}),
|
||||
throws);
|
||||
|
||||
// Constructor initiated instantiation
|
||||
var createdFoo = new Foo();
|
||||
expect(createdFoo.thisIsACustomClass, isTrue);
|
||||
|
||||
// Dart type correctness
|
||||
expect(createdFoo is HtmlElement, isTrue);
|
||||
expect(createdFoo is Foo, isTrue);
|
||||
expect(createdFoo.runtimeType, Foo);
|
||||
|
||||
// Native getter
|
||||
expect(createdFoo.tagName, "X-FOO");
|
||||
|
||||
// Native setter
|
||||
createdFoo.innerHtml = "Hello";
|
||||
expect(createdFoo.text, "Hello");
|
||||
|
||||
// Native method
|
||||
var childDiv = new DivElement();
|
||||
createdFoo.append(childDiv);
|
||||
expect(createdFoo.lastChild, childDiv);
|
||||
|
||||
// Parser initiated instantiation
|
||||
var container = new DivElement()..id = "container";
|
||||
document.body!.append(container);
|
||||
container.setInnerHtml("<x-foo></x-foo>",
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
upgradeCustomElements(container);
|
||||
var parsedFoo = container.firstChild;
|
||||
|
||||
expect(parsedFoo is Foo, isTrue);
|
||||
expect((parsedFoo as Foo).tagName, "X-FOO");
|
||||
|
||||
// Ensuring the wrapper is retained
|
||||
var someProperty = new Expando();
|
||||
someProperty[parsedFoo] = "hello";
|
||||
expect(container.firstChild, parsedFoo);
|
||||
expect(someProperty[container.firstChild!], someProperty[parsedFoo]);
|
||||
|
||||
// Having another constructor
|
||||
document.registerElement2(Bar.tag, {'prototype': Bar});
|
||||
var createdBar = new Bar();
|
||||
expect(createdBar is Bar, isTrue);
|
||||
expect(createdBar is Foo, isFalse);
|
||||
expect(createdBar.tagName, "X-BAR");
|
||||
|
||||
// Having a subclass
|
||||
document.registerElement2(Baz.tag, {'prototype': Baz});
|
||||
var createdBaz = new Baz();
|
||||
expect(createdBaz.tagName, "X-BAZ");
|
||||
expect(createdBaz.thisIsACustomClass, isTrue);
|
||||
expect(createdBaz.thisIsAlsoACustomClass, isTrue);
|
||||
|
||||
// With irregular cases
|
||||
var createdUpperBar = new Element.tag("X-BAR");
|
||||
var createdMixedBar = new Element.tag("X-Bar");
|
||||
expect(createdUpperBar is Bar, isTrue);
|
||||
expect(createdUpperBar.tagName, "X-BAR");
|
||||
expect(createdMixedBar is Bar, isTrue);
|
||||
expect(createdMixedBar.tagName, "X-BAR");
|
||||
|
||||
container.setInnerHtml("<X-BAR></X-BAR><X-Bar></X-Bar>",
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
upgradeCustomElements(container);
|
||||
expect(container.firstChild is Bar, isTrue);
|
||||
expect((container.firstChild as Bar).tagName, "X-BAR");
|
||||
expect(container.lastChild is Bar, isTrue);
|
||||
expect((container.lastChild as Bar).tagName, "X-BAR");
|
||||
|
||||
// Constructors shouldn't interfere with each other
|
||||
expect((new Foo()).tagName, "X-FOO");
|
||||
expect((new Bar()).tagName, "X-BAR");
|
||||
expect((new Baz()).tagName, "X-BAZ");
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> document_register_basic_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running document_register_basic_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) 2020, 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.
|
||||
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
|
||||
test('can register custom template with webcomponents-lite polyfill', () {
|
||||
document.registerElement2(
|
||||
'my-element', {'prototype': MyElement, 'extends': 'template'});
|
||||
dynamic e = new Element.tag('template', 'my-element');
|
||||
document.body!.append(e);
|
||||
expect(e is TemplateElement, isTrue);
|
||||
expect(e.method(), 'value');
|
||||
});
|
||||
}
|
||||
|
||||
class MyElement extends TemplateElement {
|
||||
MyElement.created() : super.created();
|
||||
method() => 'value';
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> document_register_basic_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents-lite.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running document_register_basic_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,323 +0,0 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class Foo extends HtmlElement {
|
||||
static const tag = 'x-foo';
|
||||
static final List<String> outerHtmlStrings = [
|
||||
'<x-foo></x-foo>',
|
||||
'<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-foo></x-foo>'
|
||||
];
|
||||
factory Foo() => new Element.tag(tag) as Foo;
|
||||
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) as Bar;
|
||||
Bar.created() : super.created();
|
||||
}
|
||||
|
||||
class Baz extends Foo {
|
||||
static const tag = 'x-baz';
|
||||
static final List<String> outerHtmlStrings = [
|
||||
'<x-baz></x-baz>',
|
||||
'<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-baz></x-baz>'
|
||||
];
|
||||
factory Baz() => new Element.tag(tag) as Baz;
|
||||
Baz.created() : super.created();
|
||||
}
|
||||
|
||||
class Qux extends Bar {
|
||||
static const tag = 'x-qux';
|
||||
factory Qux() => new Element.tag('input', tag) as Qux;
|
||||
Qux.created() : super.created();
|
||||
}
|
||||
|
||||
class FooBad extends DivElement {
|
||||
static const tag = 'x-foo';
|
||||
factory FooBad() => new Element.tag('div', tag) as FooBad;
|
||||
FooBad.created() : super.created();
|
||||
}
|
||||
|
||||
class MyCanvas extends CanvasElement {
|
||||
static const tag = 'my-canvas';
|
||||
factory MyCanvas() => new Element.tag('canvas', tag) as MyCanvas;
|
||||
|
||||
MyCanvas.created() : super.created();
|
||||
|
||||
void fillAsRed() {
|
||||
width = 100;
|
||||
height = 100;
|
||||
|
||||
CanvasRenderingContext2D context =
|
||||
this.getContext('2d') as CanvasRenderingContext2D;
|
||||
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() async {
|
||||
// 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.registerElement2(Foo.tag, {'prototype': Foo});
|
||||
document.registerElement2(Bar.tag, {'prototype': Bar, 'extends': 'input'});
|
||||
document.registerElement2(Baz.tag, {'prototype': Baz});
|
||||
document.registerElement2(Qux.tag, {'prototype': Qux, 'extends': 'input'});
|
||||
document.registerElement2(
|
||||
MyCanvas.tag, {'prototype': MyCanvas, 'extends': 'canvas'});
|
||||
document.registerElement2(
|
||||
CustomCustomDiv.tag, {'prototype': CustomCustomDiv, 'extends': 'div'});
|
||||
}
|
||||
|
||||
await customElementsReady;
|
||||
|
||||
group('registration', () {
|
||||
test('cannot register twice', () {
|
||||
registerTypes();
|
||||
expect(
|
||||
() => document.registerElement2(
|
||||
FooBad.tag, {'prototype': Foo, 'extends': 'div'}),
|
||||
throws);
|
||||
});
|
||||
|
||||
test('cannot register for non-matching tag', () {
|
||||
registerTypes();
|
||||
expect(() {
|
||||
document.registerElement2(
|
||||
'x-input-div', {'prototype': Bar, 'extends': 'div'});
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot register type extension for custom tag', () {
|
||||
registerTypes();
|
||||
expect(() {
|
||||
document
|
||||
.registerElement2('x-custom-tag', {'prototype': CustomCustomDiv});
|
||||
}, throws);
|
||||
});
|
||||
});
|
||||
|
||||
group('construction', () {
|
||||
group('constructors', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
test('createElementNS', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
test('parsing', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
test('canvas', () {
|
||||
registerTypes();
|
||||
var canvas = new MyCanvas();
|
||||
canvas.fillAsRed();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> document_register_type_extensions_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running document_register_type_extensions_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class FooElement extends HtmlElement {
|
||||
static final tag = 'x-foo';
|
||||
|
||||
final int initializedField = 666;
|
||||
late js.JsObject _proxy = new js.JsObject.fromBrowserObject(this);
|
||||
|
||||
factory FooElement() => new Element.tag(tag) as FooElement;
|
||||
FooElement.created() : super.created();
|
||||
|
||||
String doSomething() => _proxy.callMethod('doSomething');
|
||||
|
||||
bool get fooCreated => _proxy['fooCreated'];
|
||||
}
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
var upgrader = document.createElementUpgrader(FooElement);
|
||||
js.context['upgradeListener'] = (e) {
|
||||
upgrader.upgrade(e);
|
||||
};
|
||||
|
||||
test('cannot create upgrader for interfaces', () {
|
||||
expect(() {
|
||||
// TODO(srujzs): Determine if this should be a static error.
|
||||
document.createElementUpgrader(HtmlElementInterface);
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot upgrade interfaces', () {
|
||||
expect(() {
|
||||
upgrader.upgrade(new HtmlElementInterface());
|
||||
// ^^^^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
|
||||
}, throws);
|
||||
});
|
||||
}
|
||||
|
||||
class HtmlElementInterface implements HtmlElement {
|
||||
// ^^^^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER
|
||||
HtmlElementInterface.created();
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class FooElement extends HtmlElement {
|
||||
static final tag = 'x-foo';
|
||||
|
||||
final int initializedField = 666;
|
||||
late js.JsObject _proxy = new js.JsObject.fromBrowserObject(this);
|
||||
|
||||
factory FooElement() => new Element.tag(tag) as FooElement;
|
||||
FooElement.created() : super.created();
|
||||
|
||||
String doSomething() => _proxy.callMethod('doSomething');
|
||||
|
||||
bool get fooCreated => _proxy['fooCreated'];
|
||||
}
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
var upgrader = document.createElementUpgrader(FooElement);
|
||||
js.context['upgradeListener'] = (e) {
|
||||
upgrader.upgrade(e);
|
||||
};
|
||||
|
||||
document.registerElement2('custom-element', {'prototype': CustomElement});
|
||||
|
||||
test('created gets proxied', () {
|
||||
var element = document.createElement(FooElement.tag);
|
||||
expect(element is FooElement, isTrue);
|
||||
expect((element as FooElement).initializedField, 666);
|
||||
expect(element.text, 'constructed');
|
||||
|
||||
js.context.callMethod('validateIsFoo', [element]);
|
||||
|
||||
expect(element.doSomething(), 'didSomething');
|
||||
expect(element.fooCreated, true);
|
||||
});
|
||||
|
||||
test('dart constructor works', () {
|
||||
var element = new FooElement();
|
||||
expect(element is FooElement, isTrue);
|
||||
expect(element.text, 'constructed');
|
||||
|
||||
js.context.callMethod('validateIsFoo', [element]);
|
||||
|
||||
expect(element.doSomething(), 'didSomething');
|
||||
});
|
||||
|
||||
test('cannot upgrade more than once', () {
|
||||
var fooElement = new FooElement();
|
||||
expect(() {
|
||||
upgrader.upgrade(fooElement);
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot upgrade non-matching elements', () {
|
||||
expect(() {
|
||||
upgrader.upgrade(new DivElement());
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot upgrade custom elements', () {
|
||||
var custom = new CustomElement();
|
||||
expect(() {
|
||||
upgrader.upgrade(custom);
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('can upgrade with extendsTag', () {
|
||||
var upgrader = document.createElementUpgrader(CustomDiv, extendsTag: 'div');
|
||||
var div = new DivElement();
|
||||
var customDiv = upgrader.upgrade(div);
|
||||
expect(customDiv is CustomDiv, isTrue);
|
||||
|
||||
var htmlElement = document.createElement('not-registered');
|
||||
expect(() {
|
||||
upgrader.upgrade(htmlElement);
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot create upgrader for built-in types', () {
|
||||
expect(() {
|
||||
document.createElementUpgrader(HtmlElement);
|
||||
}, throws);
|
||||
});
|
||||
}
|
||||
|
||||
class CustomDiv extends DivElement {
|
||||
CustomDiv.created() : super.created();
|
||||
}
|
||||
|
||||
class CustomElement extends HtmlElement {
|
||||
factory CustomElement() =>
|
||||
document.createElement('custom-element') as CustomElement;
|
||||
CustomElement.created() : super.created();
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> element_upgrade_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
|
||||
<body>
|
||||
<h1> Running element_upgrade_test </h1>
|
||||
|
||||
<script>
|
||||
var Foo = function() {};
|
||||
Foo.prototype = Object.create(HTMLElement.prototype);
|
||||
Foo.prototype.createdCallback = function() {
|
||||
this.fooCreated = true;
|
||||
this.textContent = 'constructed';
|
||||
|
||||
// Tell the Dart side that this was created.
|
||||
// For testing purposes, for real code this would use a different mechanism.
|
||||
window.upgradeListener(this);
|
||||
};
|
||||
|
||||
Foo.prototype.doSomething = function() {
|
||||
this.textContent = 'didSomething';
|
||||
return 'didSomething';
|
||||
};
|
||||
|
||||
Foo = document.registerElement('x-foo', Foo);
|
||||
|
||||
function validateIsFoo(element) {
|
||||
if (!(element instanceof Foo)) {
|
||||
throw Error('Element is not a Foo');
|
||||
}
|
||||
|
||||
if (!element.fooCreated) {
|
||||
throw Error('Expected fooCreated to be set');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright (c) 2020 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 entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
group('disconnected_subtree', () {
|
||||
var div = new DivElement();
|
||||
|
||||
setUp() {
|
||||
invocations = [];
|
||||
}
|
||||
|
||||
test('Enters a disconnected subtree of DOM', () {
|
||||
setUp();
|
||||
div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(div);
|
||||
|
||||
expect(invocations, ['created'],
|
||||
reason: 'the attached callback should not be invoked when inserted '
|
||||
'into a disconnected subtree');
|
||||
});
|
||||
|
||||
test('Leaves a disconnected subtree of DOM', () {
|
||||
setUp();
|
||||
div.innerHtml = '';
|
||||
expect(invocations, [],
|
||||
reason:
|
||||
'the detached callback should not be invoked when removed from a '
|
||||
'disconnected subtree');
|
||||
});
|
||||
|
||||
test('Enters a document with a view as a constituent of a subtree', () {
|
||||
setUp();
|
||||
div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(div);
|
||||
invocations = [];
|
||||
document.body!.append(div);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['attached'],
|
||||
reason:
|
||||
'the attached callback should be invoked when inserted into a '
|
||||
'document with a view as part of a subtree');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> disconnected_subtree_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running disconnected_subtree_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,66 +0,0 @@
|
|||
// Copyright (c) 2020 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 entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
group('standard_events', () {
|
||||
var a;
|
||||
setUp() {
|
||||
invocations = [];
|
||||
}
|
||||
|
||||
test('Created', () {
|
||||
setUp();
|
||||
a = new Element.tag('x-a');
|
||||
expect(invocations, ['created']);
|
||||
});
|
||||
|
||||
test('attached', () {
|
||||
setUp();
|
||||
document.body!.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['attached']);
|
||||
});
|
||||
|
||||
test('detached', () {
|
||||
setUp();
|
||||
a.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['detached']);
|
||||
});
|
||||
|
||||
var div = new DivElement();
|
||||
test('nesting does not trigger attached', () {
|
||||
setUp();
|
||||
div.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, []);
|
||||
});
|
||||
|
||||
test('nested entering triggers attached', () {
|
||||
setUp();
|
||||
document.body!.append(div);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['attached']);
|
||||
});
|
||||
|
||||
test('nested leaving triggers detached', () {
|
||||
setUp();
|
||||
div.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['detached']);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> entered_left_view_standard_events_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running entered_left_view_standard_events_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,75 +0,0 @@
|
|||
// 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 entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
var invocations = [];
|
||||
|
||||
class Foo extends HtmlElement {
|
||||
Foo.created() : super.created() {
|
||||
invocations.add('created');
|
||||
}
|
||||
|
||||
void attached() {
|
||||
invocations.add('attached');
|
||||
}
|
||||
|
||||
void enteredView() {
|
||||
// Deprecated name. Should never be called since we override "attached".
|
||||
invocations.add('enteredView');
|
||||
}
|
||||
|
||||
void detached() {
|
||||
invocations.add('detached');
|
||||
}
|
||||
|
||||
void leftView() {
|
||||
// Deprecated name. Should never be called since we override "detached".
|
||||
invocations.add('leftView');
|
||||
}
|
||||
|
||||
void attributeChanged(String name, String oldValue, String newValue) {
|
||||
invocations.add('attribute changed');
|
||||
}
|
||||
}
|
||||
|
||||
// Test that the deprecated callbacks still work.
|
||||
class FooOldCallbacks extends HtmlElement {
|
||||
FooOldCallbacks.created() : super.created() {
|
||||
invocations.add('created');
|
||||
}
|
||||
|
||||
void enteredView() {
|
||||
invocations.add('enteredView');
|
||||
}
|
||||
|
||||
void leftView() {
|
||||
invocations.add('leftView');
|
||||
}
|
||||
|
||||
void attributeChanged(String name, String oldValue, String newValue) {
|
||||
invocations.add('attribute changed');
|
||||
}
|
||||
}
|
||||
|
||||
var docA = document;
|
||||
var docB = document.implementation!.createHtmlDocument('');
|
||||
var nullSanitizer = new NullTreeSanitizer();
|
||||
|
||||
setupFunc() {
|
||||
// Adapted from Blink's
|
||||
// fast/dom/custom/attached-detached-document.html test.
|
||||
return customElementsReady.then((_) {
|
||||
document.registerElement2('x-a', {'prototype': Foo});
|
||||
document.registerElement2('x-a-old', {'prototype': FooOldCallbacks});
|
||||
});
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
// Copyright (c) 2020 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 entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
group('shadow_dom', () {
|
||||
var div;
|
||||
var s;
|
||||
setUp() {
|
||||
invocations = [];
|
||||
div = new DivElement();
|
||||
s = div.createShadowRoot();
|
||||
}
|
||||
|
||||
tearDown() {
|
||||
customElementsTakeRecords();
|
||||
}
|
||||
|
||||
test('Created in Shadow DOM that is not in a document', () {
|
||||
setUp();
|
||||
s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(s);
|
||||
|
||||
expect(invocations, ['created'],
|
||||
reason: 'the attached callback should not be invoked when entering a '
|
||||
'Shadow DOM subtree not in the document');
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Leaves Shadow DOM that is not in a document', () {
|
||||
setUp();
|
||||
s.innerHtml = '';
|
||||
expect(invocations, [],
|
||||
reason: 'the detached callback should not be invoked when leaving a '
|
||||
'Shadow DOM subtree not in the document');
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Enters a document with a view as a constituent of Shadow DOM', () {
|
||||
setUp();
|
||||
s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(s);
|
||||
|
||||
document.body!.append(div);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['created', 'attached'],
|
||||
reason: 'the attached callback should be invoked when inserted into '
|
||||
'a document with a view as part of Shadow DOM');
|
||||
|
||||
div.remove();
|
||||
customElementsTakeRecords();
|
||||
|
||||
expect(invocations, ['created', 'attached', 'detached'],
|
||||
reason: 'the detached callback should be invoked when removed from a '
|
||||
'document with a view as part of Shadow DOM');
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> shadow_dom_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running shadow_dom_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright (c) 2020 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 entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
// TODO(jmesserly): remove after deprecation period.
|
||||
group('standard_events_old_callback_names', () {
|
||||
var a;
|
||||
setUp() {
|
||||
invocations = [];
|
||||
}
|
||||
|
||||
test('Created', () {
|
||||
setUp();
|
||||
a = new Element.tag('x-a-old');
|
||||
expect(invocations, ['created']);
|
||||
});
|
||||
|
||||
test('enteredView', () {
|
||||
setUp();
|
||||
document.body!.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['enteredView']);
|
||||
});
|
||||
|
||||
test('leftView', () {
|
||||
setUp();
|
||||
a.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['leftView']);
|
||||
});
|
||||
|
||||
var div = new DivElement();
|
||||
test('nesting does not trigger enteredView', () {
|
||||
setUp();
|
||||
div.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, []);
|
||||
});
|
||||
|
||||
test('nested entering triggers enteredView', () {
|
||||
setUp();
|
||||
document.body!.append(div);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['enteredView']);
|
||||
});
|
||||
|
||||
test('nested leaving triggers leftView', () {
|
||||
setUp();
|
||||
div.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['leftView']);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> standard_events_old_callback_names_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running standard_events_old_callback_names_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright (c) 2020 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 entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
group('viewless_document', () {
|
||||
var a;
|
||||
setUp() {
|
||||
invocations = [];
|
||||
}
|
||||
|
||||
test('Created, owned by a document without a view', () {
|
||||
setUp();
|
||||
a = docB.createElement('x-a');
|
||||
expect(a.ownerDocument, docB,
|
||||
reason: 'new instance should be owned by the document the definition '
|
||||
'was registered with');
|
||||
expect(invocations, ['created'],
|
||||
reason: 'calling the constructor should invoke the created callback');
|
||||
});
|
||||
|
||||
test('Entered document without a view', () {
|
||||
setUp();
|
||||
docB.body!.append(a);
|
||||
expect(invocations, [],
|
||||
reason: 'attached callback should not be invoked when entering a '
|
||||
'document without a view');
|
||||
});
|
||||
|
||||
test('Attribute changed in document without a view', () {
|
||||
setUp();
|
||||
a.setAttribute('data-foo', 'bar');
|
||||
expect(invocations, ['attribute changed'],
|
||||
reason: 'changing an attribute should invoke the callback, even in a '
|
||||
'document without a view');
|
||||
});
|
||||
|
||||
test('Entered document with a view', () {
|
||||
setUp();
|
||||
document.body!.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['attached'],
|
||||
reason:
|
||||
'attached callback should be invoked when entering a document '
|
||||
'with a view');
|
||||
});
|
||||
|
||||
test('Left document with a view', () {
|
||||
setUp();
|
||||
a.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['detached'],
|
||||
reason: 'detached callback should be invoked when leaving a document '
|
||||
'with a view');
|
||||
});
|
||||
|
||||
test('Created in a document without a view', () {
|
||||
setUp();
|
||||
docB.body!.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(docB.body!);
|
||||
|
||||
expect(invocations, ['created'],
|
||||
reason: 'only created callback should be invoked when parsing a '
|
||||
'custom element in a document without a view');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> viewless_document_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running viewless_document_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,24 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// Regression test for CL 194523002.
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class A extends HtmlElement {
|
||||
static final tag = 'x-a';
|
||||
factory A() => new Element.tag(tag) as A;
|
||||
A.created() : super.created();
|
||||
}
|
||||
|
||||
main() async {
|
||||
// Adapted from Blink's
|
||||
// fast/dom/custom/constructor-calls-created-synchronously test.
|
||||
|
||||
await customElementsReady;
|
||||
document.registerElement2(A.tag, {'prototype': A});
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
// Copyright (c) 2020, 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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:expect/minitest.dart';
|
||||
|
||||
/**
|
||||
* Verifies that [actual] has the same graph structure as [expected].
|
||||
* Detects cycles and DAG structure in Maps and Lists.
|
||||
*/
|
||||
verifyGraph(expected, actual) {
|
||||
var eItems = [];
|
||||
var aItems = [];
|
||||
|
||||
message(path, reason) => path == ''
|
||||
? reason
|
||||
: reason == null ? "path: $path" : "path: $path, $reason";
|
||||
|
||||
walk(path, expected, actual) {
|
||||
if (expected is String || expected is num || expected == null) {
|
||||
expect(actual, equals(expected), reason: message(path, 'not equal'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Cycle or DAG?
|
||||
for (int i = 0; i < eItems.length; i++) {
|
||||
if (identical(expected, eItems[i])) {
|
||||
expect(actual, same(aItems[i]),
|
||||
reason: message(path, 'missing back or side edge'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < aItems.length; i++) {
|
||||
if (identical(actual, aItems[i])) {
|
||||
expect(expected, same(eItems[i]),
|
||||
reason: message(path, 'extra back or side edge'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
eItems.add(expected);
|
||||
aItems.add(actual);
|
||||
|
||||
if (expected is Blob) {
|
||||
expect(actual is Blob, isTrue, reason: '$actual is Blob');
|
||||
expect(expected.type, equals(actual.type),
|
||||
reason: message(path, '.type'));
|
||||
expect(expected.size, equals(actual.size),
|
||||
reason: message(path, '.size'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is ByteBuffer) {
|
||||
expect(actual is ByteBuffer, isTrue, reason: '$actual is ByteBuffer');
|
||||
expect(expected.lengthInBytes, equals(actual.lengthInBytes),
|
||||
reason: message(path, '.lengthInBytes'));
|
||||
// TODO(antonm): one can create a view on top of those
|
||||
// and check if contents identical. Let's do it later.
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is DateTime) {
|
||||
expect(actual is DateTime, isTrue, reason: '$actual is DateTime');
|
||||
expect(expected.millisecondsSinceEpoch,
|
||||
equals(actual.millisecondsSinceEpoch),
|
||||
reason: message(path, '.millisecondsSinceEpoch'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is ImageData) {
|
||||
expect(actual is ImageData, isTrue, reason: '$actual is ImageData');
|
||||
expect(expected.width, equals(actual.width),
|
||||
reason: message(path, '.width'));
|
||||
expect(expected.height, equals(actual.height),
|
||||
reason: message(path, '.height'));
|
||||
walk('$path.data', expected.data, actual.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is TypedData) {
|
||||
expect(actual is TypedData, isTrue, reason: '$actual is TypedData');
|
||||
walk('$path/.buffer', expected.buffer, actual.buffer);
|
||||
expect(expected.offsetInBytes, equals(actual.offsetInBytes),
|
||||
reason: message(path, '.offsetInBytes'));
|
||||
expect(expected.lengthInBytes, equals(actual.lengthInBytes),
|
||||
reason: message(path, '.lengthInBytes'));
|
||||
// And also fallback to elements check below.
|
||||
}
|
||||
|
||||
if (expected is List) {
|
||||
expect(actual, predicate((v) => v is List),
|
||||
reason: message(path, '$actual is List'));
|
||||
expect(actual.length, expected.length,
|
||||
reason: message(path, 'different list lengths'));
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
walk('$path[$i]', expected[i], actual[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is Map) {
|
||||
expect(actual, predicate((v) => v is Map),
|
||||
reason: message(path, '$actual is Map'));
|
||||
for (var key in expected.keys) {
|
||||
if (!actual.containsKey(key)) {
|
||||
expect(false, isTrue, reason: message(path, 'missing key "$key"'));
|
||||
}
|
||||
walk('$path["$key"]', expected[key], actual[key]);
|
||||
}
|
||||
for (var key in actual.keys) {
|
||||
if (!expected.containsKey(key)) {
|
||||
expect(false, isTrue, reason: message(path, 'extra key "$key"'));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
expect(false, isTrue, reason: 'Unhandled type: $expected');
|
||||
}
|
||||
|
||||
walk('', expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizer which does nothing.
|
||||
*/
|
||||
class NullTreeSanitizer implements NodeTreeSanitizer {
|
||||
void sanitizeTree(Node node) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that two DOM trees are equivalent.
|
||||
*/
|
||||
void validateNodeTree(Node a, Node b, [String path = '']) {
|
||||
path = '${path}${a.runtimeType}';
|
||||
expect(a.nodeType, b.nodeType, reason: '$path nodeTypes differ');
|
||||
expect(a.nodeValue, b.nodeValue, reason: '$path nodeValues differ');
|
||||
expect(a.text, b.text, reason: '$path texts differ');
|
||||
expect(a.nodes.length, b.nodes.length, reason: '$path nodes.lengths differ');
|
||||
|
||||
if (a is Element) {
|
||||
Element bE = b as Element;
|
||||
Element aE = a;
|
||||
|
||||
expect(aE.tagName, bE.tagName, reason: '$path tagNames differ');
|
||||
expect(aE.attributes.length, bE.attributes.length,
|
||||
reason: '$path attributes.lengths differ');
|
||||
for (var key in aE.attributes.keys) {
|
||||
expect(aE.attributes[key], bE.attributes[key],
|
||||
reason: '$path attribute [$key] values differ');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < a.nodes.length; ++i) {
|
||||
validateNodeTree(a.nodes[i], b.nodes[i], '$path[$i].');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade all custom elements in the subtree which have not been upgraded.
|
||||
*
|
||||
* This is needed to cover timing scenarios which the custom element polyfill
|
||||
* does not cover.
|
||||
*/
|
||||
void upgradeCustomElements(Node node) {
|
||||
if (js.context.hasProperty('CustomElements') &&
|
||||
js.context['CustomElements'].hasProperty('upgradeAll')) {
|
||||
js.context['CustomElements'].callMethod('upgradeAll', [node]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A future that completes once all custom elements in the initial HTML page
|
||||
* have been upgraded.
|
||||
*
|
||||
* This is needed because the native implementation can update the elements
|
||||
* while parsing the HTML document, but the custom element polyfill cannot,
|
||||
* so it completes this future once all elements are upgraded.
|
||||
*/
|
||||
// TODO(jmesserly): rename to webComponentsReady to match the event?
|
||||
Future customElementsReady = () {
|
||||
if (_isReady) return new Future.value();
|
||||
|
||||
// Not upgraded. Wait for the polyfill to fire the WebComponentsReady event.
|
||||
// Note: we listen on document (not on document.body) to allow this polyfill
|
||||
// to be loaded in the HEAD element.
|
||||
return document.on['WebComponentsReady'].first;
|
||||
}();
|
||||
|
||||
// Return true if we are using the polyfill and upgrade is complete, or if we
|
||||
// have native document.register and therefore the browser took care of it.
|
||||
// Otherwise return false, including the case where we can't find the polyfill.
|
||||
bool get _isReady {
|
||||
// If we don't have dart:js, assume things are ready
|
||||
if (js.context == null) return true;
|
||||
|
||||
var customElements = js.context['CustomElements'];
|
||||
if (customElements == null) {
|
||||
// Return true if native document.register, otherwise false.
|
||||
// (Maybe the polyfill isn't loaded yet. Wait for it.)
|
||||
return document.supportsRegisterElement;
|
||||
}
|
||||
|
||||
return customElements['ready'] == true;
|
||||
}
|
||||
|
||||
/**
|
||||
* *Note* this API is primarily intended for tests. In other code it is better
|
||||
* to write it in a style that works with or without the polyfill, rather than
|
||||
* using this method.
|
||||
*
|
||||
* Synchronously trigger evaluation of pending lifecycle events, which otherwise
|
||||
* need to wait for a [MutationObserver] to signal the changes in the polyfill.
|
||||
* This method can be used to resolve differences in timing between native and
|
||||
* polyfilled custom elements.
|
||||
*/
|
||||
void customElementsTakeRecords([Node? node]) {
|
||||
var customElements = js.context['CustomElements'];
|
||||
if (customElements == null) return;
|
||||
customElements.callMethod('takeRecords', [node]);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
// Copyright (c) 2015, 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_method_clash;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
class CustomElement extends HtmlElement {
|
||||
factory CustomElement() => new Element.tag('x-custom') as CustomElement;
|
||||
|
||||
CustomElement.created() : super.created() {}
|
||||
|
||||
// Try to clash with native 'appendChild' method.
|
||||
void appendChild() {
|
||||
throw 'Gotcha!';
|
||||
}
|
||||
}
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
|
||||
group('test', () {
|
||||
test('test', () {
|
||||
document.registerElement2('x-custom', {'prototype': CustomElement});
|
||||
CustomElement custom = new CustomElement();
|
||||
document.body!.children.add(custom);
|
||||
|
||||
// Will call appendChild in JS.
|
||||
custom.children.add(new DivElement()..text = 'Hello world!');
|
||||
|
||||
try {
|
||||
custom.appendChild(); // Make sure method is not tree shaken.
|
||||
fail('appendChild did not throw');
|
||||
} catch (e) {
|
||||
expect(e, equals('Gotcha!'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> custom_element_method_clash_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running custom_element_method_clash_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) 2015, 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_name_clash;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
class CustomElement extends HtmlElement {
|
||||
factory CustomElement() => new Element.tag('x-custom') as CustomElement;
|
||||
|
||||
CustomElement.created() : super.created() {}
|
||||
|
||||
// Try to clash with native 'appendChild' method.
|
||||
var appendChild = 123;
|
||||
}
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
|
||||
group('test', () {
|
||||
test('test', () {
|
||||
document.registerElement2('x-custom', {'prototype': CustomElement});
|
||||
CustomElement custom = new CustomElement();
|
||||
document.body!.children.add(custom);
|
||||
// Will call appendChild in JS.
|
||||
custom.children.add(new DivElement()..text = 'Hello world!');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> custom_element_name_clash_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running custom_element_name_clash_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,131 +0,0 @@
|
|||
// Copyright (c) 2015, 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.
|
||||
|
||||
// Regression test for http://dartbug.com/23127
|
||||
// Tests super calls to a custom element upgrade constructor with various
|
||||
// combinations of parameters and type arguments.
|
||||
|
||||
library custom_elements_23127_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
abstract class B1 extends HtmlElement {
|
||||
void action();
|
||||
|
||||
B1.created() : super.created() {
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class B1T<T> extends HtmlElement {
|
||||
void action();
|
||||
var qq = false;
|
||||
B1T.created() : super.created() {
|
||||
action();
|
||||
qq = this is T;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class B2 extends HtmlElement {
|
||||
void action();
|
||||
var qq;
|
||||
B2.created([a = 1, b = 2, c = 3])
|
||||
: qq = callTwice(() => ++a * ++b), // [a] and [b] are boxed.
|
||||
super.created() {
|
||||
action();
|
||||
qq = [qq, a, b, c];
|
||||
}
|
||||
}
|
||||
|
||||
abstract class B2T<T> extends HtmlElement {
|
||||
void action();
|
||||
var qq;
|
||||
B2T.created([a = 1, b = 2, c = 3])
|
||||
: qq = callTwice(() => ++a * ++b),
|
||||
super.created() {
|
||||
action();
|
||||
qq = [this is T, qq, a, b, c];
|
||||
}
|
||||
}
|
||||
|
||||
class C1 extends B1 {
|
||||
int z = 0;
|
||||
C1.created() : super.created();
|
||||
action() {
|
||||
z = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class C1T extends B1T {
|
||||
int z = 0;
|
||||
C1T.created() : super.created();
|
||||
action() {
|
||||
z = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class C2 extends B2 {
|
||||
int z = 0;
|
||||
C2.created() : super.created(20);
|
||||
action() {
|
||||
z = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class C2T extends B2T {
|
||||
int z = 0;
|
||||
C2T.created() : super.created(20);
|
||||
action() {
|
||||
z = 3;
|
||||
}
|
||||
}
|
||||
|
||||
var callTwice;
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
|
||||
callTwice = (f) {
|
||||
f();
|
||||
return f();
|
||||
};
|
||||
|
||||
group('baseline', () {
|
||||
test('C1', () {
|
||||
document.register('x-c1', C1);
|
||||
C1 e = document.createElement('x-c1') as C1;
|
||||
expect(e.z, 3);
|
||||
});
|
||||
});
|
||||
|
||||
group('c1t', () {
|
||||
test('C1T', () {
|
||||
document.register('x-c1t', C1T);
|
||||
C1T e = document.createElement('x-c1t') as C1T;
|
||||
expect(e.z, 3);
|
||||
expect(e.qq, true);
|
||||
});
|
||||
});
|
||||
|
||||
group('c2', () {
|
||||
test('C2', () {
|
||||
document.register('x-c2', C2);
|
||||
C2 e = document.createElement('x-c2') as C2;
|
||||
expect(e.z, 3);
|
||||
expect(e.qq, [88, 22, 4, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
group('c2t', () {
|
||||
test('C2T', () {
|
||||
document.register('x-c2t', C2T);
|
||||
C2T e = document.createElement('x-c2t') as C2T;
|
||||
expect(e.z, 3);
|
||||
expect(e.qq, [true, 88, 22, 4, 3]);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> custom_elements_23127_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running custom_elements_23127_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,179 +0,0 @@
|
|||
// 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:async_helper/async_minitest.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
class CustomMixin {
|
||||
var mixinMethodCalled;
|
||||
|
||||
void mixinMethod() {
|
||||
mixinMethodCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
class CustomType extends HtmlElement with CustomMixin {
|
||||
bool createdCalled = false;
|
||||
|
||||
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() async {
|
||||
await customElementsReady;
|
||||
|
||||
group('register', () {
|
||||
test('register', () {
|
||||
var tag = nextTag;
|
||||
document.registerElement(tag, CustomType);
|
||||
|
||||
var element = new Element.tag(tag) as CustomType;
|
||||
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) as CustomType;
|
||||
expect(element, isNotNull);
|
||||
expect(element is CustomType, isTrue);
|
||||
});
|
||||
|
||||
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('<div><$tag></$tag></div>');
|
||||
|
||||
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></$tag>',
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
upgradeCustomElements(element);
|
||||
document.body!.nodes.add(element);
|
||||
var queried = querySelector(tag) as CustomType;
|
||||
|
||||
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"></$tag>',
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
upgradeCustomElements(element);
|
||||
document.body!.nodes.add(element);
|
||||
var queried = querySelector('#someid') as CustomType;
|
||||
|
||||
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></$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) as CustomType;
|
||||
element.invokeMixinMethod();
|
||||
expect(element.mixinMethodCalled, isTrue);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> custom_elements_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running custom_elements_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -2,17 +2,159 @@
|
|||
// 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.
|
||||
|
||||
/// The test runner for DDC does not handle tests that import files using
|
||||
/// relative imports that reach outside of the directory containing the test
|
||||
/// (i.e. "../" imports). Since tests both in this directory and in "custom/"
|
||||
/// use utils.dart, it needs to be accessible from both places.
|
||||
///
|
||||
/// We could have every test outside of "custom/" import "custom/utils.dart",
|
||||
/// but that feels weird since "utils.dart" doesn't have anything to do with
|
||||
/// custom elements.
|
||||
///
|
||||
/// Instead, it lives there, but is exported from here for the tests in this
|
||||
/// directory to import.
|
||||
// TODO(rnystrom): If the DDC test runner is fixed to use a different module
|
||||
// root that handles "../" imports, move "custom/utils.dart" to here.
|
||||
export 'custom/utils.dart';
|
||||
import 'dart:html';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:expect/minitest.dart';
|
||||
|
||||
/**
|
||||
* Verifies that [actual] has the same graph structure as [expected].
|
||||
* Detects cycles and DAG structure in Maps and Lists.
|
||||
*/
|
||||
verifyGraph(expected, actual) {
|
||||
var eItems = [];
|
||||
var aItems = [];
|
||||
|
||||
message(path, reason) => path == ''
|
||||
? reason
|
||||
: reason == null
|
||||
? "path: $path"
|
||||
: "path: $path, $reason";
|
||||
|
||||
walk(path, expected, actual) {
|
||||
if (expected is String || expected is num || expected == null) {
|
||||
expect(actual, equals(expected), reason: message(path, 'not equal'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Cycle or DAG?
|
||||
for (int i = 0; i < eItems.length; i++) {
|
||||
if (identical(expected, eItems[i])) {
|
||||
expect(actual, same(aItems[i]),
|
||||
reason: message(path, 'missing back or side edge'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < aItems.length; i++) {
|
||||
if (identical(actual, aItems[i])) {
|
||||
expect(expected, same(eItems[i]),
|
||||
reason: message(path, 'extra back or side edge'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
eItems.add(expected);
|
||||
aItems.add(actual);
|
||||
|
||||
if (expected is Blob) {
|
||||
expect(actual is Blob, isTrue, reason: '$actual is Blob');
|
||||
expect(expected.type, equals(actual.type),
|
||||
reason: message(path, '.type'));
|
||||
expect(expected.size, equals(actual.size),
|
||||
reason: message(path, '.size'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is ByteBuffer) {
|
||||
expect(actual is ByteBuffer, isTrue, reason: '$actual is ByteBuffer');
|
||||
expect(expected.lengthInBytes, equals(actual.lengthInBytes),
|
||||
reason: message(path, '.lengthInBytes'));
|
||||
// TODO(antonm): one can create a view on top of those
|
||||
// and check if contents identical. Let's do it later.
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is DateTime) {
|
||||
expect(actual is DateTime, isTrue, reason: '$actual is DateTime');
|
||||
expect(expected.millisecondsSinceEpoch,
|
||||
equals(actual.millisecondsSinceEpoch),
|
||||
reason: message(path, '.millisecondsSinceEpoch'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is ImageData) {
|
||||
expect(actual is ImageData, isTrue, reason: '$actual is ImageData');
|
||||
expect(expected.width, equals(actual.width),
|
||||
reason: message(path, '.width'));
|
||||
expect(expected.height, equals(actual.height),
|
||||
reason: message(path, '.height'));
|
||||
walk('$path.data', expected.data, actual.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is TypedData) {
|
||||
expect(actual is TypedData, isTrue, reason: '$actual is TypedData');
|
||||
walk('$path/.buffer', expected.buffer, actual.buffer);
|
||||
expect(expected.offsetInBytes, equals(actual.offsetInBytes),
|
||||
reason: message(path, '.offsetInBytes'));
|
||||
expect(expected.lengthInBytes, equals(actual.lengthInBytes),
|
||||
reason: message(path, '.lengthInBytes'));
|
||||
// And also fallback to elements check below.
|
||||
}
|
||||
|
||||
if (expected is List) {
|
||||
expect(actual, predicate((v) => v is List),
|
||||
reason: message(path, '$actual is List'));
|
||||
expect(actual.length, expected.length,
|
||||
reason: message(path, 'different list lengths'));
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
walk('$path[$i]', expected[i], actual[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is Map) {
|
||||
expect(actual, predicate((v) => v is Map),
|
||||
reason: message(path, '$actual is Map'));
|
||||
for (var key in expected.keys) {
|
||||
if (!actual.containsKey(key)) {
|
||||
expect(false, isTrue, reason: message(path, 'missing key "$key"'));
|
||||
}
|
||||
walk('$path["$key"]', expected[key], actual[key]);
|
||||
}
|
||||
for (var key in actual.keys) {
|
||||
if (!expected.containsKey(key)) {
|
||||
expect(false, isTrue, reason: message(path, 'extra key "$key"'));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
expect(false, isTrue, reason: 'Unhandled type: $expected');
|
||||
}
|
||||
|
||||
walk('', expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizer which does nothing.
|
||||
*/
|
||||
class NullTreeSanitizer implements NodeTreeSanitizer {
|
||||
void sanitizeTree(Node node) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that two DOM trees are equivalent.
|
||||
*/
|
||||
void validateNodeTree(Node a, Node b, [String path = '']) {
|
||||
path = '${path}${a.runtimeType}';
|
||||
expect(a.nodeType, b.nodeType, reason: '$path nodeTypes differ');
|
||||
expect(a.nodeValue, b.nodeValue, reason: '$path nodeValues differ');
|
||||
expect(a.text, b.text, reason: '$path texts differ');
|
||||
expect(a.nodes.length, b.nodes.length, reason: '$path nodes.lengths differ');
|
||||
|
||||
if (a is Element) {
|
||||
Element bE = b as Element;
|
||||
Element aE = a;
|
||||
|
||||
expect(aE.tagName, bE.tagName, reason: '$path tagNames differ');
|
||||
expect(aE.attributes.length, bE.attributes.length,
|
||||
reason: '$path attributes.lengths differ');
|
||||
for (var key in aE.attributes.keys) {
|
||||
expect(aE.attributes[key], bE.attributes[key],
|
||||
reason: '$path attribute [$key] values differ');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < a.nodes.length; ++i) {
|
||||
validateNodeTree(a.nodes[i], b.nodes[i], '$path[$i].');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library attribute_changed_callback_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class A extends HtmlElement {
|
||||
static final tag = 'x-a';
|
||||
factory A() => new Element.tag(tag);
|
||||
A.created() : super.created();
|
||||
|
||||
static var attributeChangedInvocations = 0;
|
||||
|
||||
void attributeChanged(name, oldValue, newValue) {
|
||||
attributeChangedInvocations++;
|
||||
}
|
||||
}
|
||||
|
||||
class B extends HtmlElement {
|
||||
static final tag = 'x-b';
|
||||
factory B() => new Element.tag(tag);
|
||||
B.created() : super.created() {
|
||||
invocations.add('created');
|
||||
}
|
||||
|
||||
static var invocations = [];
|
||||
|
||||
Completer completer;
|
||||
|
||||
void attributeChanged(name, oldValue, newValue) {
|
||||
invocations.add('$name: $oldValue => $newValue');
|
||||
if (completer != null) {
|
||||
completer.complete('value changed to $newValue');
|
||||
completer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pump custom events polyfill events.
|
||||
void customElementsTakeRecords() {
|
||||
if (js.context.hasProperty('CustomElements')) {
|
||||
js.context['CustomElements'].callMethod('takeRecords');
|
||||
}
|
||||
}
|
||||
|
||||
main() async {
|
||||
// Adapted from Blink's fast/dom/custom/attribute-changed-callback test.
|
||||
|
||||
await customElementsReady;
|
||||
document.registerElement2(A.tag, {'prototype': A});
|
||||
document.registerElement2(B.tag, {'prototype': B});
|
||||
|
||||
group('fully_supported', () {
|
||||
test('transfer attribute changed callback', () {
|
||||
var element = new A();
|
||||
|
||||
element.attributes['a'] = 'b';
|
||||
expect(A.attributeChangedInvocations, 1);
|
||||
});
|
||||
|
||||
test('add, change and remove an attribute', () {
|
||||
var b = new B();
|
||||
|
||||
B.invocations = [];
|
||||
b.attributes['data-s'] = 't';
|
||||
expect(B.invocations, ['data-s: null => t']);
|
||||
|
||||
b.attributes['data-v'] = 'w';
|
||||
B.invocations = [];
|
||||
b.attributes['data-v'] = 'x';
|
||||
expect(B.invocations, ['data-v: w => x']);
|
||||
|
||||
B.invocations = [];
|
||||
b.attributes['data-v'] = 'x';
|
||||
expect(B.invocations, []);
|
||||
|
||||
b.attributes.remove('data-v');
|
||||
expect(B.invocations, ['data-v: x => null']);
|
||||
});
|
||||
|
||||
test('add, change ID', () {
|
||||
B.invocations = [];
|
||||
|
||||
var b = new B();
|
||||
var completer = new Completer();
|
||||
b.completer = completer;
|
||||
b.id = 'x';
|
||||
return completer.future
|
||||
.then((_) => expect(B.invocations, ['created', 'id: null => x']))
|
||||
.then((_) {
|
||||
B.invocations = [];
|
||||
var secondCompleter = new Completer();
|
||||
b.completer = secondCompleter;
|
||||
b.attributes.remove('id');
|
||||
return secondCompleter.future;
|
||||
}).then((_) => expect(B.invocations, ['id: x => null']));
|
||||
});
|
||||
});
|
||||
|
||||
group('unsupported_on_polyfill', () {
|
||||
// If these tests start passing, don't remove the status suppression. Move
|
||||
// the tests to the fullYy_supported group.
|
||||
|
||||
test('add, change classes', () {
|
||||
var b = new B();
|
||||
|
||||
B.invocations = [];
|
||||
b.classes.toggle('u');
|
||||
expect(B.invocations, ['class: null => u']);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> attribute_changed_callback_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running attribute_changed_callback_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,294 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library created_callback_test;
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class A extends HtmlElement {
|
||||
static final tag = 'x-a';
|
||||
factory A() => new Element.tag(tag);
|
||||
A.created() : super.created() {
|
||||
createdInvocations++;
|
||||
}
|
||||
|
||||
static int createdInvocations = 0;
|
||||
}
|
||||
|
||||
class B extends HtmlElement {
|
||||
static final tag = 'x-b';
|
||||
factory B() => new Element.tag(tag);
|
||||
B.created() : super.created();
|
||||
}
|
||||
|
||||
class C extends HtmlElement {
|
||||
static final tag = 'x-c';
|
||||
factory C() => new Element.tag(tag);
|
||||
C.created() : super.created() {
|
||||
createdInvocations++;
|
||||
|
||||
if (this.id != 'u') {
|
||||
return;
|
||||
}
|
||||
|
||||
var t = div.querySelector('#t');
|
||||
var v = div.querySelector('#v');
|
||||
var w = div.querySelector('#w');
|
||||
|
||||
expect(querySelector('x-b:not(:unresolved)'), this);
|
||||
expect(querySelectorAll(':unresolved'), [v, w]);
|
||||
|
||||
// As per:
|
||||
// http://www.w3.org/TR/2013/WD-custom-elements-20130514/#serializing-and-parsing
|
||||
// creation order is t, u, v, w (postorder).
|
||||
expect(t is C, isTrue);
|
||||
// Note, this is different from JavaScript where this would be false.
|
||||
expect(v is C, isTrue);
|
||||
}
|
||||
|
||||
static int createdInvocations = 0;
|
||||
static var div;
|
||||
}
|
||||
|
||||
main() async {
|
||||
// Adapted from Blink's
|
||||
// fast/dom/custom/created-callback test.
|
||||
|
||||
await customElementsReady;
|
||||
document.registerElement2(B.tag, {'prototype': B});
|
||||
document.registerElement2(C.tag, {'prototype': C});
|
||||
ErrorConstructorElement.register();
|
||||
|
||||
test('transfer created callback', () {
|
||||
document.registerElement2(A.tag, {'prototype': A as dynamic});
|
||||
var x = new A();
|
||||
expect(A.createdInvocations, 1);
|
||||
});
|
||||
|
||||
test('unresolved and created callback timing', () {
|
||||
var div = new DivElement();
|
||||
C.div = div;
|
||||
div.setInnerHtml("""
|
||||
<x-c id="t"></x-c>
|
||||
<x-b id="u"></x-b>
|
||||
<x-c id="v"></x-c>
|
||||
<x-b id="w"></x-b>
|
||||
""", treeSanitizer: NodeTreeSanitizer.trusted);
|
||||
|
||||
upgradeCustomElements(div);
|
||||
|
||||
expect(C.createdInvocations, 2);
|
||||
expect(div.querySelector('#w') is B, isTrue);
|
||||
});
|
||||
|
||||
test('nesting of constructors', NestedElement.test);
|
||||
|
||||
test('access while upgrading gets unupgraded element',
|
||||
AccessWhileUpgradingElement.test);
|
||||
|
||||
test('cannot call created constructor', () {
|
||||
expect(() {
|
||||
new B.created();
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot register without created', () {
|
||||
expect(() {
|
||||
document.registerElement2(
|
||||
MissingCreatedElement.tag, {'prototype': MissingCreatedElement});
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('throw on createElement does not upgrade', () {
|
||||
ErrorConstructorElement.callCount = 0;
|
||||
|
||||
var e;
|
||||
expectGlobalError(() {
|
||||
e = new Element.tag(ErrorConstructorElement.tag);
|
||||
});
|
||||
expect(ErrorConstructorElement.callCount, 1);
|
||||
expect(e is HtmlElement, isTrue);
|
||||
expect(e is ErrorConstructorElement, isFalse);
|
||||
|
||||
var dummy = new DivElement();
|
||||
dummy.append(e);
|
||||
e = dummy.firstChild;
|
||||
expect(ErrorConstructorElement.callCount, 1);
|
||||
});
|
||||
|
||||
test('throw on innerHtml does not upgrade', () {
|
||||
ErrorConstructorElement.callCount = 0;
|
||||
|
||||
var dummy = new DivElement();
|
||||
var tag = ErrorConstructorElement.tag;
|
||||
expectGlobalError(() {
|
||||
dummy.setInnerHtml('<$tag></$tag>',
|
||||
treeSanitizer: NodeTreeSanitizer.trusted);
|
||||
});
|
||||
|
||||
expect(ErrorConstructorElement.callCount, 1);
|
||||
|
||||
var e = dummy.firstChild;
|
||||
// Accessing should not re-run the constructor.
|
||||
expect(ErrorConstructorElement.callCount, 1);
|
||||
expect(e is HtmlElement, isTrue);
|
||||
expect(e is ErrorConstructorElement, isFalse);
|
||||
});
|
||||
|
||||
test('cannot register created with params', () {
|
||||
expect(() {
|
||||
document.registerElement2(
|
||||
'x-created-with-params', {'prototype': CreatedWithParametersElement});
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('created cannot be called from nested constructor',
|
||||
NestedCreatedConstructorElement.test);
|
||||
|
||||
// TODO(vsm): Port additional test from upstream here:
|
||||
// http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/dom/custom/created-callback.html?r1=156141&r2=156185
|
||||
}
|
||||
|
||||
class NestedElement extends HtmlElement {
|
||||
static final tag = 'x-nested';
|
||||
|
||||
final Element b = new B();
|
||||
|
||||
factory NestedElement() => new Element.tag(tag);
|
||||
NestedElement.created() : super.created();
|
||||
|
||||
static void register() {
|
||||
document.registerElement2(tag, {'prototype': NestedElement});
|
||||
}
|
||||
|
||||
static void test() {
|
||||
register();
|
||||
|
||||
var e = new NestedElement();
|
||||
expect(e.b, isNotNull);
|
||||
expect(e.b is B, isTrue);
|
||||
expect(e is NestedElement, isTrue);
|
||||
}
|
||||
}
|
||||
|
||||
class AccessWhileUpgradingElement extends HtmlElement {
|
||||
static final tag = 'x-access-while-upgrading';
|
||||
|
||||
static Element upgradingContext;
|
||||
static Element upgradingContextChild;
|
||||
|
||||
final foo = runInitializerCode();
|
||||
|
||||
factory AccessWhileUpgradingElement() => new Element.tag(tag);
|
||||
AccessWhileUpgradingElement.created() : super.created();
|
||||
|
||||
static runInitializerCode() {
|
||||
upgradingContextChild = upgradingContext.firstChild;
|
||||
|
||||
return 666;
|
||||
}
|
||||
|
||||
static void register() {
|
||||
document.registerElement2(tag, {'prototype': AccessWhileUpgradingElement});
|
||||
}
|
||||
|
||||
static void test() {
|
||||
register();
|
||||
|
||||
upgradingContext = new DivElement();
|
||||
upgradingContext.setInnerHtml('<$tag></$tag>',
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
dynamic child = upgradingContext.firstChild;
|
||||
|
||||
expect(child.foo, 666);
|
||||
expect(upgradingContextChild is HtmlElement, isFalse);
|
||||
expect(upgradingContextChild is AccessWhileUpgradingElement, isFalse,
|
||||
reason: 'Elements accessed while upgrading should not be upgraded.');
|
||||
}
|
||||
}
|
||||
|
||||
class MissingCreatedElement extends HtmlElement {
|
||||
static final tag = 'x-missing-created';
|
||||
|
||||
factory MissingCreatedElement() => new Element.tag(tag);
|
||||
}
|
||||
|
||||
class ErrorConstructorElement extends HtmlElement {
|
||||
static final tag = 'x-throws-in-constructor';
|
||||
static int callCount = 0;
|
||||
|
||||
factory ErrorConstructorElement() => new Element.tag(tag);
|
||||
|
||||
ErrorConstructorElement.created() : super.created() {
|
||||
++callCount;
|
||||
throw new Exception('Just messin with ya');
|
||||
}
|
||||
|
||||
static void register() {
|
||||
document.registerElement2(tag, {'prototype': ErrorConstructorElement});
|
||||
}
|
||||
}
|
||||
|
||||
class NestedCreatedConstructorElement extends HtmlElement {
|
||||
static final tag = 'x-nested-created-constructor';
|
||||
|
||||
// Should not be able to call this here.
|
||||
final B b = constructB();
|
||||
static B constructedB;
|
||||
|
||||
factory NestedCreatedConstructorElement() => new Element.tag(tag);
|
||||
NestedCreatedConstructorElement.created() : super.created();
|
||||
|
||||
static void register() {
|
||||
document
|
||||
.registerElement2(tag, {'prototype': NestedCreatedConstructorElement});
|
||||
}
|
||||
|
||||
// Try to run the created constructor, and record the results.
|
||||
static constructB() {
|
||||
// This should throw an exception.
|
||||
constructedB = new B.created();
|
||||
return constructedB;
|
||||
}
|
||||
|
||||
static void test() {
|
||||
register();
|
||||
|
||||
// Exception should have occurred on upgrade.
|
||||
var e;
|
||||
expectGlobalError(() {
|
||||
e = new Element.tag(tag);
|
||||
});
|
||||
expect(e is NestedCreatedConstructorElement, isFalse);
|
||||
expect(e is HtmlElement, isTrue);
|
||||
// Should not have been set.
|
||||
expect(constructedB, isNull);
|
||||
}
|
||||
}
|
||||
|
||||
class CreatedWithParametersElement extends HtmlElement {
|
||||
CreatedWithParametersElement.created(ignoredParam) : super.created();
|
||||
}
|
||||
|
||||
void expectGlobalError(Function test) {
|
||||
js.context['testExpectsGlobalError'] = true;
|
||||
try {
|
||||
test();
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} finally {
|
||||
js.context['testExpectsGlobalError'] = false;
|
||||
}
|
||||
var errors = js.context['testSuppressedGlobalErrors'];
|
||||
expect(errors['length'], 1);
|
||||
// Clear out the errors;
|
||||
js.context['testSuppressedGlobalErrors']['length'] = 0;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> created_callback_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running created_callback_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,147 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library document_register_basic_test;
|
||||
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class Foo extends HtmlElement {
|
||||
static final tag = 'x-foo';
|
||||
factory Foo() => new Element.tag(tag);
|
||||
Foo.created() : super.created();
|
||||
|
||||
get thisIsACustomClass => true;
|
||||
}
|
||||
|
||||
class Bar extends HtmlElement {
|
||||
static final tag = 'x-bar';
|
||||
factory Bar() => new Element.tag(tag);
|
||||
Bar.created() : super.created();
|
||||
|
||||
get thisIsACustomClass => true;
|
||||
}
|
||||
|
||||
class Baz extends Foo {
|
||||
static final tag = 'x-baz';
|
||||
factory Baz() => new Element.tag(tag);
|
||||
Baz.created() : super.created();
|
||||
|
||||
get thisIsAlsoACustomClass => true;
|
||||
}
|
||||
|
||||
class BadB {}
|
||||
|
||||
abstract class BadC extends HtmlElement {
|
||||
BadC.created() : super.created();
|
||||
}
|
||||
|
||||
main() async {
|
||||
// Adapted from Blink's fast/dom/custom/document-register-basic test.
|
||||
|
||||
await customElementsReady;
|
||||
|
||||
test('Testing document.registerElement2() basic behaviors', () {
|
||||
document.registerElement2(Foo.tag, {'prototype': Foo});
|
||||
|
||||
// Cannot register an existing dart:html type.
|
||||
expect(
|
||||
() => document.registerElement2('x-bad-a', {'prototype': HtmlElement}),
|
||||
throws);
|
||||
|
||||
// Invalid user type. Doesn't inherit from HtmlElement.
|
||||
expect(() => document.registerElement2('x-bad-b', {'prototype': BadB}),
|
||||
throws);
|
||||
|
||||
// Cannot register abstract class.
|
||||
expect(() => document.registerElement2('x-bad-c', {'prototype': BadC}),
|
||||
throws);
|
||||
|
||||
// Not a type.
|
||||
expect(() => document.registerElement2('x-bad-d', {'prototype': null}),
|
||||
throws);
|
||||
|
||||
// Cannot register system type.
|
||||
expect(() => document.registerElement2('x-bad-e', {'prototype': Object}),
|
||||
throws);
|
||||
|
||||
// Constructor initiated instantiation
|
||||
var createdFoo = new Foo();
|
||||
expect(createdFoo.thisIsACustomClass, isTrue);
|
||||
|
||||
// Dart type correctness
|
||||
expect(createdFoo is HtmlElement, isTrue);
|
||||
expect(createdFoo is Foo, isTrue);
|
||||
expect(createdFoo.runtimeType, Foo);
|
||||
|
||||
// Native getter
|
||||
expect(createdFoo.tagName, "X-FOO");
|
||||
|
||||
// Native setter
|
||||
createdFoo.innerHtml = "Hello";
|
||||
expect(createdFoo.text, "Hello");
|
||||
|
||||
// Native method
|
||||
var childDiv = new DivElement();
|
||||
createdFoo.append(childDiv);
|
||||
expect(createdFoo.lastChild, childDiv);
|
||||
|
||||
// Parser initiated instantiation
|
||||
var container = new DivElement()..id = "container";
|
||||
document.body.append(container);
|
||||
container.setInnerHtml("<x-foo></x-foo>",
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
upgradeCustomElements(container);
|
||||
var parsedFoo = container.firstChild;
|
||||
|
||||
expect(parsedFoo is Foo, isTrue);
|
||||
expect((parsedFoo as Foo).tagName, "X-FOO");
|
||||
|
||||
// Ensuring the wrapper is retained
|
||||
var someProperty = new Expando();
|
||||
someProperty[parsedFoo] = "hello";
|
||||
expect(container.firstChild, parsedFoo);
|
||||
expect(someProperty[container.firstChild], someProperty[parsedFoo]);
|
||||
|
||||
// Having another constructor
|
||||
document.registerElement2(Bar.tag, {'prototype': Bar});
|
||||
var createdBar = new Bar();
|
||||
expect(createdBar is Bar, isTrue);
|
||||
expect(createdBar is Foo, isFalse);
|
||||
expect(createdBar.tagName, "X-BAR");
|
||||
|
||||
// Having a subclass
|
||||
document.registerElement2(Baz.tag, {'prototype': Baz});
|
||||
var createdBaz = new Baz();
|
||||
expect(createdBaz.tagName, "X-BAZ");
|
||||
expect(createdBaz.thisIsACustomClass, isTrue);
|
||||
expect(createdBaz.thisIsAlsoACustomClass, isTrue);
|
||||
|
||||
// With irregular cases
|
||||
var createdUpperBar = new Element.tag("X-BAR");
|
||||
var createdMixedBar = new Element.tag("X-Bar");
|
||||
expect(createdUpperBar is Bar, isTrue);
|
||||
expect(createdUpperBar.tagName, "X-BAR");
|
||||
expect(createdMixedBar is Bar, isTrue);
|
||||
expect(createdMixedBar.tagName, "X-BAR");
|
||||
|
||||
container.setInnerHtml("<X-BAR></X-BAR><X-Bar></X-Bar>",
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
upgradeCustomElements(container);
|
||||
expect(container.firstChild is Bar, isTrue);
|
||||
expect((container.firstChild as Bar).tagName, "X-BAR");
|
||||
expect(container.lastChild is Bar, isTrue);
|
||||
expect((container.lastChild as Bar).tagName, "X-BAR");
|
||||
|
||||
// Constructors shouldn't interfere with each other
|
||||
expect((new Foo()).tagName, "X-FOO");
|
||||
expect((new Bar()).tagName, "X-BAR");
|
||||
expect((new Baz()).tagName, "X-BAZ");
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> document_register_basic_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running document_register_basic_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,25 +0,0 @@
|
|||
|
||||
// @dart = 2.9
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
|
||||
test('can register custom template with webcomponents-lite polyfill', () {
|
||||
document.registerElement2(
|
||||
'my-element', {'prototype': MyElement, 'extends': 'template'});
|
||||
dynamic e = new Element.tag('template', 'my-element');
|
||||
document.body.append(e);
|
||||
expect(e is TemplateElement, isTrue);
|
||||
expect(e.method(), 'value');
|
||||
});
|
||||
}
|
||||
|
||||
class MyElement extends TemplateElement {
|
||||
MyElement.created() : super.created();
|
||||
method() => 'value';
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> document_register_basic_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents-lite.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running document_register_basic_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,318 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
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;
|
||||
|
||||
CanvasRenderingContext2D 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() async {
|
||||
// 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.registerElement2(Foo.tag, {'prototype': Foo});
|
||||
document.registerElement2(Bar.tag, {'prototype': Bar, 'extends': 'input'});
|
||||
document.registerElement2(Baz.tag, {'prototype': Baz});
|
||||
document.registerElement2(Qux.tag, {'prototype': Qux, 'extends': 'input'});
|
||||
document.registerElement2(MyCanvas.tag, {'prototype': MyCanvas, 'extends': 'canvas'});
|
||||
document.registerElement2(CustomCustomDiv.tag, {'prototype': CustomCustomDiv,
|
||||
'extends': 'div'});
|
||||
}
|
||||
|
||||
await customElementsReady;
|
||||
|
||||
group('registration', () {
|
||||
test('cannot register twice', () {
|
||||
registerTypes();
|
||||
expect(() => document.registerElement2(FooBad.tag, {'prototype': Foo, 'extends': 'div'}),
|
||||
throws);
|
||||
});
|
||||
|
||||
test('cannot register for non-matching tag', () {
|
||||
registerTypes();
|
||||
expect(() {
|
||||
document.registerElement2('x-input-div', {'prototype': Bar, 'extends': 'div'});
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot register type extension for custom tag', () {
|
||||
registerTypes();
|
||||
expect(() {
|
||||
document.registerElement2('x-custom-tag', {'prototype': CustomCustomDiv});
|
||||
}, throws);
|
||||
});
|
||||
});
|
||||
|
||||
group('construction', () {
|
||||
group('constructors', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
test('createElementNS', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
test('parsing', () {
|
||||
registerTypes();
|
||||
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', () {
|
||||
test('canvas', () {
|
||||
registerTypes();
|
||||
var canvas = new MyCanvas();
|
||||
canvas.fillAsRed();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> document_register_type_extensions_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running document_register_type_extensions_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class FooElement extends HtmlElement {
|
||||
static final tag = 'x-foo';
|
||||
|
||||
final int initializedField = 666;
|
||||
js.JsObject _proxy;
|
||||
|
||||
factory FooElement() => new Element.tag(tag);
|
||||
FooElement.created() : super.created() {
|
||||
_proxy = new js.JsObject.fromBrowserObject(this);
|
||||
}
|
||||
|
||||
String doSomething() => _proxy.callMethod('doSomething');
|
||||
|
||||
bool get fooCreated => _proxy['fooCreated'];
|
||||
}
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
var upgrader = document.createElementUpgrader(FooElement);
|
||||
js.context['upgradeListener'] = (e) {
|
||||
upgrader.upgrade(e);
|
||||
};
|
||||
|
||||
test('cannot create upgrader for interfaces', () {
|
||||
expect(() {
|
||||
// TODO(srujzs): Determine if this should be a static error.
|
||||
document.createElementUpgrader(HtmlElementInterface);
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot upgrade interfaces', () {
|
||||
expect(() {
|
||||
upgrader.upgrade(new HtmlElementInterface());
|
||||
// ^^^^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
|
||||
}, throws);
|
||||
});
|
||||
}
|
||||
|
||||
class HtmlElementInterface implements HtmlElement {
|
||||
// ^^^^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER
|
||||
HtmlElementInterface.created();
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class FooElement extends HtmlElement {
|
||||
static final tag = 'x-foo';
|
||||
|
||||
final int initializedField = 666;
|
||||
js.JsObject _proxy;
|
||||
|
||||
factory FooElement() => new Element.tag(tag);
|
||||
FooElement.created() : super.created() {
|
||||
_proxy = new js.JsObject.fromBrowserObject(this);
|
||||
}
|
||||
|
||||
String doSomething() => _proxy.callMethod('doSomething');
|
||||
|
||||
bool get fooCreated => _proxy['fooCreated'];
|
||||
}
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
var upgrader = document.createElementUpgrader(FooElement);
|
||||
js.context['upgradeListener'] = (e) {
|
||||
upgrader.upgrade(e);
|
||||
};
|
||||
|
||||
document.registerElement2('custom-element', {'prototype': CustomElement});
|
||||
|
||||
test('created gets proxied', () {
|
||||
var element = document.createElement(FooElement.tag);
|
||||
expect(element is FooElement, isTrue);
|
||||
expect((element as FooElement).initializedField, 666);
|
||||
expect(element.text, 'constructed');
|
||||
|
||||
js.context.callMethod('validateIsFoo', [element]);
|
||||
|
||||
expect((element as FooElement).doSomething(), 'didSomething');
|
||||
expect((element as FooElement).fooCreated, true);
|
||||
});
|
||||
|
||||
test('dart constructor works', () {
|
||||
var element = new FooElement();
|
||||
expect(element is FooElement, isTrue);
|
||||
expect(element.text, 'constructed');
|
||||
|
||||
js.context.callMethod('validateIsFoo', [element]);
|
||||
|
||||
expect(element.doSomething(), 'didSomething');
|
||||
});
|
||||
|
||||
test('cannot upgrade more than once', () {
|
||||
var fooElement = new FooElement();
|
||||
expect(() {
|
||||
upgrader.upgrade(fooElement);
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot upgrade non-matching elements', () {
|
||||
expect(() {
|
||||
upgrader.upgrade(new DivElement());
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot upgrade custom elements', () {
|
||||
var custom = new CustomElement();
|
||||
expect(() {
|
||||
upgrader.upgrade(custom);
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('can upgrade with extendsTag', () {
|
||||
var upgrader = document.createElementUpgrader(CustomDiv, extendsTag: 'div');
|
||||
var div = new DivElement();
|
||||
var customDiv = upgrader.upgrade(div);
|
||||
expect(customDiv is CustomDiv, isTrue);
|
||||
|
||||
var htmlElement = document.createElement('not-registered');
|
||||
expect(() {
|
||||
upgrader.upgrade(htmlElement);
|
||||
}, throws);
|
||||
});
|
||||
|
||||
test('cannot create upgrader for built-in types', () {
|
||||
expect(() {
|
||||
document.createElementUpgrader(HtmlElement);
|
||||
}, throws);
|
||||
});
|
||||
}
|
||||
|
||||
class CustomDiv extends DivElement {
|
||||
CustomDiv.created() : super.created();
|
||||
}
|
||||
|
||||
class CustomElement extends HtmlElement {
|
||||
factory CustomElement() => document.createElement('custom-element');
|
||||
CustomElement.created() : super.created();
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> element_upgrade_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
|
||||
<body>
|
||||
<h1> Running element_upgrade_test </h1>
|
||||
|
||||
<script>
|
||||
var Foo = function() {};
|
||||
Foo.prototype = Object.create(HTMLElement.prototype);
|
||||
Foo.prototype.createdCallback = function() {
|
||||
this.fooCreated = true;
|
||||
this.textContent = 'constructed';
|
||||
|
||||
// Tell the Dart side that this was created.
|
||||
// For testing purposes, for real code this would use a different mechanism.
|
||||
window.upgradeListener(this);
|
||||
};
|
||||
|
||||
Foo.prototype.doSomething = function() {
|
||||
this.textContent = 'didSomething';
|
||||
return 'didSomething';
|
||||
};
|
||||
|
||||
Foo = document.registerElement('x-foo', Foo);
|
||||
|
||||
function validateIsFoo(element) {
|
||||
if (!(element instanceof Foo)) {
|
||||
throw Error('Element is not a Foo');
|
||||
}
|
||||
|
||||
if (!element.fooCreated) {
|
||||
throw Error('Expected fooCreated to be set');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) 2020 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
group('disconnected_subtree', () {
|
||||
var div = new DivElement();
|
||||
|
||||
setUp() {
|
||||
invocations = [];
|
||||
}
|
||||
|
||||
test('Enters a disconnected subtree of DOM', () {
|
||||
setUp();
|
||||
div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(div);
|
||||
|
||||
expect(invocations, ['created'],
|
||||
reason: 'the attached callback should not be invoked when inserted '
|
||||
'into a disconnected subtree');
|
||||
});
|
||||
|
||||
test('Leaves a disconnected subtree of DOM', () {
|
||||
setUp();
|
||||
div.innerHtml = '';
|
||||
expect(invocations, [],
|
||||
reason:
|
||||
'the detached callback should not be invoked when removed from a '
|
||||
'disconnected subtree');
|
||||
});
|
||||
|
||||
test('Enters a document with a view as a constituent of a subtree', () {
|
||||
setUp();
|
||||
div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(div);
|
||||
invocations = [];
|
||||
document.body.append(div);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['attached'],
|
||||
reason:
|
||||
'the attached callback should be invoked when inserted into a '
|
||||
'document with a view as part of a subtree');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> disconnected_subtree_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running disconnected_subtree_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright (c) 2020 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
group('standard_events', () {
|
||||
var a;
|
||||
setUp() {
|
||||
invocations = [];
|
||||
}
|
||||
|
||||
test('Created', () {
|
||||
setUp();
|
||||
a = new Element.tag('x-a');
|
||||
expect(invocations, ['created']);
|
||||
});
|
||||
|
||||
test('attached', () {
|
||||
setUp();
|
||||
document.body.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['attached']);
|
||||
});
|
||||
|
||||
test('detached', () {
|
||||
setUp();
|
||||
a.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['detached']);
|
||||
});
|
||||
|
||||
var div = new DivElement();
|
||||
test('nesting does not trigger attached', () {
|
||||
setUp();
|
||||
div.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, []);
|
||||
});
|
||||
|
||||
test('nested entering triggers attached', () {
|
||||
setUp();
|
||||
document.body.append(div);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['attached']);
|
||||
});
|
||||
|
||||
test('nested leaving triggers detached', () {
|
||||
setUp();
|
||||
div.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['detached']);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> entered_left_view_standard_events_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running entered_left_view_standard_events_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,79 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
var invocations = [];
|
||||
|
||||
class Foo extends HtmlElement {
|
||||
factory Foo() => null;
|
||||
Foo.created() : super.created() {
|
||||
invocations.add('created');
|
||||
}
|
||||
|
||||
void attached() {
|
||||
invocations.add('attached');
|
||||
}
|
||||
|
||||
void enteredView() {
|
||||
// Deprecated name. Should never be called since we override "attached".
|
||||
invocations.add('enteredView');
|
||||
}
|
||||
|
||||
void detached() {
|
||||
invocations.add('detached');
|
||||
}
|
||||
|
||||
void leftView() {
|
||||
// Deprecated name. Should never be called since we override "detached".
|
||||
invocations.add('leftView');
|
||||
}
|
||||
|
||||
void attributeChanged(String name, String oldValue, String newValue) {
|
||||
invocations.add('attribute changed');
|
||||
}
|
||||
}
|
||||
|
||||
// Test that the deprecated callbacks still work.
|
||||
class FooOldCallbacks extends HtmlElement {
|
||||
factory FooOldCallbacks() => null;
|
||||
FooOldCallbacks.created() : super.created() {
|
||||
invocations.add('created');
|
||||
}
|
||||
|
||||
void enteredView() {
|
||||
invocations.add('enteredView');
|
||||
}
|
||||
|
||||
void leftView() {
|
||||
invocations.add('leftView');
|
||||
}
|
||||
|
||||
void attributeChanged(String name, String oldValue, String newValue) {
|
||||
invocations.add('attribute changed');
|
||||
}
|
||||
}
|
||||
|
||||
var docA = document;
|
||||
var docB = document.implementation.createHtmlDocument('');
|
||||
var nullSanitizer = new NullTreeSanitizer();
|
||||
|
||||
setupFunc() {
|
||||
// Adapted from Blink's
|
||||
// fast/dom/custom/attached-detached-document.html test.
|
||||
return customElementsReady.then((_) {
|
||||
document.registerElement2('x-a', {'prototype': Foo});
|
||||
document.registerElement2('x-a-old', {'prototype': FooOldCallbacks});
|
||||
});
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright (c) 2020 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
group('shadow_dom', () {
|
||||
var div;
|
||||
var s;
|
||||
setUp() {
|
||||
invocations = [];
|
||||
div = new DivElement();
|
||||
s = div.createShadowRoot();
|
||||
}
|
||||
|
||||
tearDown() {
|
||||
customElementsTakeRecords();
|
||||
}
|
||||
|
||||
test('Created in Shadow DOM that is not in a document', () {
|
||||
setUp();
|
||||
s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(s);
|
||||
|
||||
expect(invocations, ['created'],
|
||||
reason: 'the attached callback should not be invoked when entering a '
|
||||
'Shadow DOM subtree not in the document');
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Leaves Shadow DOM that is not in a document', () {
|
||||
setUp();
|
||||
s.innerHtml = '';
|
||||
expect(invocations, [],
|
||||
reason: 'the detached callback should not be invoked when leaving a '
|
||||
'Shadow DOM subtree not in the document');
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Enters a document with a view as a constituent of Shadow DOM', () {
|
||||
setUp();
|
||||
s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(s);
|
||||
|
||||
document.body.append(div);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['created', 'attached'],
|
||||
reason: 'the attached callback should be invoked when inserted into '
|
||||
'a document with a view as part of Shadow DOM');
|
||||
|
||||
div.remove();
|
||||
customElementsTakeRecords();
|
||||
|
||||
expect(invocations, ['created', 'attached', 'detached'],
|
||||
reason: 'the detached callback should be invoked when removed from a '
|
||||
'document with a view as part of Shadow DOM');
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> shadow_dom_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running shadow_dom_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,69 +0,0 @@
|
|||
// Copyright (c) 2020 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
// TODO(jmesserly): remove after deprecation period.
|
||||
group('standard_events_old_callback_names', () {
|
||||
var a;
|
||||
setUp() {
|
||||
invocations = [];
|
||||
}
|
||||
|
||||
test('Created', () {
|
||||
setUp();
|
||||
a = new Element.tag('x-a-old');
|
||||
expect(invocations, ['created']);
|
||||
});
|
||||
|
||||
test('enteredView', () {
|
||||
setUp();
|
||||
document.body.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['enteredView']);
|
||||
});
|
||||
|
||||
test('leftView', () {
|
||||
setUp();
|
||||
a.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['leftView']);
|
||||
});
|
||||
|
||||
var div = new DivElement();
|
||||
test('nesting does not trigger enteredView', () {
|
||||
setUp();
|
||||
div.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, []);
|
||||
});
|
||||
|
||||
test('nested entering triggers enteredView', () {
|
||||
setUp();
|
||||
document.body.append(div);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['enteredView']);
|
||||
});
|
||||
|
||||
test('nested leaving triggers leftView', () {
|
||||
setUp();
|
||||
div.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['leftView']);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> standard_events_old_callback_names_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running standard_events_old_callback_names_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright (c) 2020 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library entered_left_view_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
|
||||
import 'entered_left_view_util.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
|
||||
main() async {
|
||||
await setupFunc();
|
||||
group('viewless_document', () {
|
||||
var a;
|
||||
setUp() {
|
||||
invocations = [];
|
||||
}
|
||||
|
||||
test('Created, owned by a document without a view', () {
|
||||
setUp();
|
||||
a = docB.createElement('x-a');
|
||||
expect(a.ownerDocument, docB,
|
||||
reason: 'new instance should be owned by the document the definition '
|
||||
'was registered with');
|
||||
expect(invocations, ['created'],
|
||||
reason: 'calling the constructor should invoke the created callback');
|
||||
});
|
||||
|
||||
test('Entered document without a view', () {
|
||||
setUp();
|
||||
docB.body.append(a);
|
||||
expect(invocations, [],
|
||||
reason: 'attached callback should not be invoked when entering a '
|
||||
'document without a view');
|
||||
});
|
||||
|
||||
test('Attribute changed in document without a view', () {
|
||||
setUp();
|
||||
a.setAttribute('data-foo', 'bar');
|
||||
expect(invocations, ['attribute changed'],
|
||||
reason: 'changing an attribute should invoke the callback, even in a '
|
||||
'document without a view');
|
||||
});
|
||||
|
||||
test('Entered document with a view', () {
|
||||
setUp();
|
||||
document.body.append(a);
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['attached'],
|
||||
reason:
|
||||
'attached callback should be invoked when entering a document '
|
||||
'with a view');
|
||||
});
|
||||
|
||||
test('Left document with a view', () {
|
||||
setUp();
|
||||
a.remove();
|
||||
customElementsTakeRecords();
|
||||
expect(invocations, ['detached'],
|
||||
reason: 'detached callback should be invoked when leaving a document '
|
||||
'with a view');
|
||||
});
|
||||
|
||||
test('Created in a document without a view', () {
|
||||
setUp();
|
||||
docB.body.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
|
||||
upgradeCustomElements(docB.body);
|
||||
|
||||
expect(invocations, ['created'],
|
||||
reason: 'only created callback should be invoked when parsing a '
|
||||
'custom element in a document without a view');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> viewless_document_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running viewless_document_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,26 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
// Regression test for CL 194523002.
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class A extends HtmlElement {
|
||||
static final tag = 'x-a';
|
||||
factory A() => new Element.tag(tag);
|
||||
A.created() : super.created();
|
||||
}
|
||||
|
||||
main() async {
|
||||
// Adapted from Blink's
|
||||
// fast/dom/custom/constructor-calls-created-synchronously test.
|
||||
|
||||
await customElementsReady;
|
||||
document.registerElement2(A.tag, {'prototype': A});
|
||||
}
|
|
@ -1,222 +0,0 @@
|
|||
|
||||
// @dart = 2.9
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:expect/minitest.dart';
|
||||
|
||||
/**
|
||||
* Verifies that [actual] has the same graph structure as [expected].
|
||||
* Detects cycles and DAG structure in Maps and Lists.
|
||||
*/
|
||||
verifyGraph(expected, actual) {
|
||||
var eItems = [];
|
||||
var aItems = [];
|
||||
|
||||
message(path, reason) => path == ''
|
||||
? reason
|
||||
: reason == null ? "path: $path" : "path: $path, $reason";
|
||||
|
||||
walk(path, expected, actual) {
|
||||
if (expected is String || expected is num || expected == null) {
|
||||
expect(actual, equals(expected), reason: message(path, 'not equal'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Cycle or DAG?
|
||||
for (int i = 0; i < eItems.length; i++) {
|
||||
if (identical(expected, eItems[i])) {
|
||||
expect(actual, same(aItems[i]),
|
||||
reason: message(path, 'missing back or side edge'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < aItems.length; i++) {
|
||||
if (identical(actual, aItems[i])) {
|
||||
expect(expected, same(eItems[i]),
|
||||
reason: message(path, 'extra back or side edge'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
eItems.add(expected);
|
||||
aItems.add(actual);
|
||||
|
||||
if (expected is Blob) {
|
||||
expect(actual is Blob, isTrue, reason: '$actual is Blob');
|
||||
expect(expected.type, equals(actual.type),
|
||||
reason: message(path, '.type'));
|
||||
expect(expected.size, equals(actual.size),
|
||||
reason: message(path, '.size'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is ByteBuffer) {
|
||||
expect(actual is ByteBuffer, isTrue, reason: '$actual is ByteBuffer');
|
||||
expect(expected.lengthInBytes, equals(actual.lengthInBytes),
|
||||
reason: message(path, '.lengthInBytes'));
|
||||
// TODO(antonm): one can create a view on top of those
|
||||
// and check if contents identical. Let's do it later.
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is DateTime) {
|
||||
expect(actual is DateTime, isTrue, reason: '$actual is DateTime');
|
||||
expect(expected.millisecondsSinceEpoch,
|
||||
equals(actual.millisecondsSinceEpoch),
|
||||
reason: message(path, '.millisecondsSinceEpoch'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is ImageData) {
|
||||
expect(actual is ImageData, isTrue, reason: '$actual is ImageData');
|
||||
expect(expected.width, equals(actual.width),
|
||||
reason: message(path, '.width'));
|
||||
expect(expected.height, equals(actual.height),
|
||||
reason: message(path, '.height'));
|
||||
walk('$path.data', expected.data, actual.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is TypedData) {
|
||||
expect(actual is TypedData, isTrue, reason: '$actual is TypedData');
|
||||
walk('$path/.buffer', expected.buffer, actual.buffer);
|
||||
expect(expected.offsetInBytes, equals(actual.offsetInBytes),
|
||||
reason: message(path, '.offsetInBytes'));
|
||||
expect(expected.lengthInBytes, equals(actual.lengthInBytes),
|
||||
reason: message(path, '.lengthInBytes'));
|
||||
// And also fallback to elements check below.
|
||||
}
|
||||
|
||||
if (expected is List) {
|
||||
expect(actual, predicate((v) => v is List),
|
||||
reason: message(path, '$actual is List'));
|
||||
expect(actual.length, expected.length,
|
||||
reason: message(path, 'different list lengths'));
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
walk('$path[$i]', expected[i], actual[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is Map) {
|
||||
expect(actual, predicate((v) => v is Map),
|
||||
reason: message(path, '$actual is Map'));
|
||||
for (var key in expected.keys) {
|
||||
if (!actual.containsKey(key)) {
|
||||
expect(false, isTrue, reason: message(path, 'missing key "$key"'));
|
||||
}
|
||||
walk('$path["$key"]', expected[key], actual[key]);
|
||||
}
|
||||
for (var key in actual.keys) {
|
||||
if (!expected.containsKey(key)) {
|
||||
expect(false, isTrue, reason: message(path, 'extra key "$key"'));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
expect(false, isTrue, reason: 'Unhandled type: $expected');
|
||||
}
|
||||
|
||||
walk('', expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizer which does nothing.
|
||||
*/
|
||||
class NullTreeSanitizer implements NodeTreeSanitizer {
|
||||
void sanitizeTree(Node node) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that two DOM trees are equivalent.
|
||||
*/
|
||||
void validateNodeTree(Node a, Node b, [String path = '']) {
|
||||
path = '${path}${a.runtimeType}';
|
||||
expect(a.nodeType, b.nodeType, reason: '$path nodeTypes differ');
|
||||
expect(a.nodeValue, b.nodeValue, reason: '$path nodeValues differ');
|
||||
expect(a.text, b.text, reason: '$path texts differ');
|
||||
expect(a.nodes.length, b.nodes.length, reason: '$path nodes.lengths differ');
|
||||
|
||||
if (a is Element) {
|
||||
Element bE = b;
|
||||
Element aE = a;
|
||||
|
||||
expect(aE.tagName, bE.tagName, reason: '$path tagNames differ');
|
||||
expect(aE.attributes.length, bE.attributes.length,
|
||||
reason: '$path attributes.lengths differ');
|
||||
for (var key in aE.attributes.keys) {
|
||||
expect(aE.attributes[key], bE.attributes[key],
|
||||
reason: '$path attribute [$key] values differ');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < a.nodes.length; ++i) {
|
||||
validateNodeTree(a.nodes[i], b.nodes[i], '$path[$i].');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade all custom elements in the subtree which have not been upgraded.
|
||||
*
|
||||
* This is needed to cover timing scenarios which the custom element polyfill
|
||||
* does not cover.
|
||||
*/
|
||||
void upgradeCustomElements(Node node) {
|
||||
if (js.context.hasProperty('CustomElements') &&
|
||||
js.context['CustomElements'].hasProperty('upgradeAll')) {
|
||||
js.context['CustomElements'].callMethod('upgradeAll', [node]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A future that completes once all custom elements in the initial HTML page
|
||||
* have been upgraded.
|
||||
*
|
||||
* This is needed because the native implementation can update the elements
|
||||
* while parsing the HTML document, but the custom element polyfill cannot,
|
||||
* so it completes this future once all elements are upgraded.
|
||||
*/
|
||||
// TODO(jmesserly): rename to webComponentsReady to match the event?
|
||||
Future customElementsReady = () {
|
||||
if (_isReady) return new Future.value();
|
||||
|
||||
// Not upgraded. Wait for the polyfill to fire the WebComponentsReady event.
|
||||
// Note: we listen on document (not on document.body) to allow this polyfill
|
||||
// to be loaded in the HEAD element.
|
||||
return document.on['WebComponentsReady'].first;
|
||||
}();
|
||||
|
||||
// Return true if we are using the polyfill and upgrade is complete, or if we
|
||||
// have native document.register and therefore the browser took care of it.
|
||||
// Otherwise return false, including the case where we can't find the polyfill.
|
||||
bool get _isReady {
|
||||
// If we don't have dart:js, assume things are ready
|
||||
if (js.context == null) return true;
|
||||
|
||||
var customElements = js.context['CustomElements'];
|
||||
if (customElements == null) {
|
||||
// Return true if native document.register, otherwise false.
|
||||
// (Maybe the polyfill isn't loaded yet. Wait for it.)
|
||||
return document.supportsRegisterElement;
|
||||
}
|
||||
|
||||
return customElements['ready'] == true;
|
||||
}
|
||||
|
||||
/**
|
||||
* *Note* this API is primarily intended for tests. In other code it is better
|
||||
* to write it in a style that works with or without the polyfill, rather than
|
||||
* using this method.
|
||||
*
|
||||
* Synchronously trigger evaluation of pending lifecycle events, which otherwise
|
||||
* need to wait for a [MutationObserver] to signal the changes in the polyfill.
|
||||
* This method can be used to resolve differences in timing between native and
|
||||
* polyfilled custom elements.
|
||||
*/
|
||||
void customElementsTakeRecords([Node node]) {
|
||||
var customElements = js.context['CustomElements'];
|
||||
if (customElements == null) return;
|
||||
customElements.callMethod('takeRecords', [node]);
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
// Copyright (c) 2015, 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library custom_elements_method_clash;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
class CustomElement extends HtmlElement {
|
||||
factory CustomElement() => new Element.tag('x-custom');
|
||||
|
||||
CustomElement.created() : super.created() {}
|
||||
|
||||
// Try to clash with native 'appendChild' method.
|
||||
void appendChild() {
|
||||
throw 'Gotcha!';
|
||||
}
|
||||
}
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
|
||||
group('test', () {
|
||||
test('test', () {
|
||||
document.registerElement2('x-custom', {'prototype': CustomElement});
|
||||
CustomElement custom = new CustomElement();
|
||||
document.body.children.add(custom);
|
||||
|
||||
// Will call appendChild in JS.
|
||||
custom.children.add(new DivElement()..text = 'Hello world!');
|
||||
|
||||
try {
|
||||
custom.appendChild(); // Make sure method is not tree shaken.
|
||||
fail('appendChild did not throw');
|
||||
} catch (e) {
|
||||
expect(e, equals('Gotcha!'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> custom_element_method_clash_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running custom_element_method_clash_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) 2015, 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library custom_elements_name_clash;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
class CustomElement extends HtmlElement {
|
||||
factory CustomElement() => new Element.tag('x-custom');
|
||||
|
||||
CustomElement.created() : super.created() {}
|
||||
|
||||
// Try to clash with native 'appendChild' method.
|
||||
var appendChild = 123;
|
||||
}
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
|
||||
group('test', () {
|
||||
test('test', () {
|
||||
document.registerElement2('x-custom', {'prototype': CustomElement});
|
||||
CustomElement custom = new CustomElement();
|
||||
document.body.children.add(custom);
|
||||
// Will call appendChild in JS.
|
||||
custom.children.add(new DivElement()..text = 'Hello world!');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> custom_element_name_clash_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running custom_element_name_clash_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,133 +0,0 @@
|
|||
// Copyright (c) 2015, 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
// Regression test for http://dartbug.com/23127
|
||||
// Tests super calls to a custom element upgrade constructor with various
|
||||
// combinations of parameters and type arguments.
|
||||
|
||||
library custom_elements_23127_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
abstract class B1 extends HtmlElement {
|
||||
void action();
|
||||
|
||||
B1.created() : super.created() {
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class B1T<T> extends HtmlElement {
|
||||
void action();
|
||||
var qq = false;
|
||||
B1T.created() : super.created() {
|
||||
action();
|
||||
qq = this is T;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class B2 extends HtmlElement {
|
||||
void action();
|
||||
var qq;
|
||||
B2.created([a = 1, b = 2, c = 3])
|
||||
: qq = callTwice(() => ++a * ++b), // [a] and [b] are boxed.
|
||||
super.created() {
|
||||
action();
|
||||
qq = [qq, a, b, c];
|
||||
}
|
||||
}
|
||||
|
||||
abstract class B2T<T> extends HtmlElement {
|
||||
void action();
|
||||
var qq;
|
||||
B2T.created([a = 1, b = 2, c = 3])
|
||||
: qq = callTwice(() => ++a * ++b),
|
||||
super.created() {
|
||||
action();
|
||||
qq = [this is T, qq, a, b, c];
|
||||
}
|
||||
}
|
||||
|
||||
class C1 extends B1 {
|
||||
int z;
|
||||
C1.created() : super.created();
|
||||
action() {
|
||||
z = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class C1T extends B1T {
|
||||
int z;
|
||||
C1T.created() : super.created();
|
||||
action() {
|
||||
z = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class C2 extends B2 {
|
||||
int z;
|
||||
C2.created() : super.created(20);
|
||||
action() {
|
||||
z = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class C2T extends B2T {
|
||||
int z;
|
||||
C2T.created() : super.created(20);
|
||||
action() {
|
||||
z = 3;
|
||||
}
|
||||
}
|
||||
|
||||
var callTwice;
|
||||
|
||||
main() async {
|
||||
await customElementsReady;
|
||||
|
||||
callTwice = (f) {
|
||||
f();
|
||||
return f();
|
||||
};
|
||||
|
||||
group('baseline', () {
|
||||
test('C1', () {
|
||||
document.register('x-c1', C1);
|
||||
C1 e = document.createElement('x-c1');
|
||||
expect(e.z, 3);
|
||||
});
|
||||
});
|
||||
|
||||
group('c1t', () {
|
||||
test('C1T', () {
|
||||
document.register('x-c1t', C1T);
|
||||
C1T e = document.createElement('x-c1t');
|
||||
expect(e.z, 3);
|
||||
expect(e.qq, true);
|
||||
});
|
||||
});
|
||||
|
||||
group('c2', () {
|
||||
test('C2', () {
|
||||
document.register('x-c2', C2);
|
||||
C2 e = document.createElement('x-c2');
|
||||
expect(e.z, 3);
|
||||
expect(e.qq, [88, 22, 4, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
group('c2t', () {
|
||||
test('C2T', () {
|
||||
document.register('x-c2t', C2T);
|
||||
C2T e = document.createElement('x-c2t');
|
||||
expect(e.z, 3);
|
||||
expect(e.qq, [true, 88, 22, 4, 3]);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> custom_elements_23127_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running custom_elements_23127_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,188 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library custom_elements_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:html';
|
||||
import 'package:async_helper/async_minitest.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() async {
|
||||
await customElementsReady;
|
||||
|
||||
group('register', () {
|
||||
test('register', () {
|
||||
var tag = nextTag;
|
||||
document.registerElement(tag, CustomType);
|
||||
|
||||
var element = new Element.tag(tag) as CustomType;
|
||||
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) as CustomType;
|
||||
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('<div><$tag></$tag></div>');
|
||||
|
||||
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></$tag>',
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
upgradeCustomElements(element);
|
||||
document.body.nodes.add(element);
|
||||
var queried = querySelector(tag) as CustomType;
|
||||
|
||||
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"></$tag>',
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
upgradeCustomElements(element);
|
||||
document.body.nodes.add(element);
|
||||
var queried = querySelector('#someid') as CustomType;
|
||||
|
||||
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></$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) as CustomType;
|
||||
element.invokeMixinMethod();
|
||||
expect(element.mixinMethodCalled, isTrue);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="dart.unittest" content="full-stack-traces">
|
||||
<title> custom_elements_test </title>
|
||||
<style>
|
||||
.unittest-table { font-family:monospace; border:1px; }
|
||||
.unittest-pass { background: #6b3;}
|
||||
.unittest-fail { background: #d55;}
|
||||
.unittest-error { background: #a11;}
|
||||
</style>
|
||||
<script src="/packages/web_components/webcomponents.js"></script>
|
||||
<script src="/packages/web_components/dart_support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Running custom_elements_test </h1>
|
||||
<script type="text/javascript"
|
||||
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
|
||||
%TEST_SCRIPTS%
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +1,157 @@
|
|||
/// The test runner for DDC does not handle tests that import files using
|
||||
/// relative imports that reach outside of the directory containing the test
|
||||
/// (i.e. "../" imports). Since tests both in this directory and in "custom/"
|
||||
/// use utils.dart, it needs to be accessible from both places.
|
||||
///
|
||||
/// We could have every test outside of "custom/" import "custom/utils.dart",
|
||||
/// but that feels weird since "utils.dart" doesn't have anything to do with
|
||||
/// custom elements.
|
||||
///
|
||||
/// Instead, it lives there, but is exported from here for the tests in this
|
||||
/// directory to import.
|
||||
// TODO(rnystrom): If the DDC test runner is fixed to use a different module
|
||||
// root that handles "../" imports, move "custom/utils.dart" to here.
|
||||
|
||||
// @dart = 2.9
|
||||
export 'custom/utils.dart';
|
||||
import 'dart:html';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:expect/minitest.dart';
|
||||
|
||||
/**
|
||||
* Verifies that [actual] has the same graph structure as [expected].
|
||||
* Detects cycles and DAG structure in Maps and Lists.
|
||||
*/
|
||||
verifyGraph(expected, actual) {
|
||||
var eItems = [];
|
||||
var aItems = [];
|
||||
|
||||
message(path, reason) => path == ''
|
||||
? reason
|
||||
: reason == null
|
||||
? "path: $path"
|
||||
: "path: $path, $reason";
|
||||
|
||||
walk(path, expected, actual) {
|
||||
if (expected is String || expected is num || expected == null) {
|
||||
expect(actual, equals(expected), reason: message(path, 'not equal'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Cycle or DAG?
|
||||
for (int i = 0; i < eItems.length; i++) {
|
||||
if (identical(expected, eItems[i])) {
|
||||
expect(actual, same(aItems[i]),
|
||||
reason: message(path, 'missing back or side edge'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < aItems.length; i++) {
|
||||
if (identical(actual, aItems[i])) {
|
||||
expect(expected, same(eItems[i]),
|
||||
reason: message(path, 'extra back or side edge'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
eItems.add(expected);
|
||||
aItems.add(actual);
|
||||
|
||||
if (expected is Blob) {
|
||||
expect(actual is Blob, isTrue, reason: '$actual is Blob');
|
||||
expect(expected.type, equals(actual.type),
|
||||
reason: message(path, '.type'));
|
||||
expect(expected.size, equals(actual.size),
|
||||
reason: message(path, '.size'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is ByteBuffer) {
|
||||
expect(actual is ByteBuffer, isTrue, reason: '$actual is ByteBuffer');
|
||||
expect(expected.lengthInBytes, equals(actual.lengthInBytes),
|
||||
reason: message(path, '.lengthInBytes'));
|
||||
// TODO(antonm): one can create a view on top of those
|
||||
// and check if contents identical. Let's do it later.
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is DateTime) {
|
||||
expect(actual is DateTime, isTrue, reason: '$actual is DateTime');
|
||||
expect(expected.millisecondsSinceEpoch,
|
||||
equals(actual.millisecondsSinceEpoch),
|
||||
reason: message(path, '.millisecondsSinceEpoch'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is ImageData) {
|
||||
expect(actual is ImageData, isTrue, reason: '$actual is ImageData');
|
||||
expect(expected.width, equals(actual.width),
|
||||
reason: message(path, '.width'));
|
||||
expect(expected.height, equals(actual.height),
|
||||
reason: message(path, '.height'));
|
||||
walk('$path.data', expected.data, actual.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is TypedData) {
|
||||
expect(actual is TypedData, isTrue, reason: '$actual is TypedData');
|
||||
walk('$path/.buffer', expected.buffer, actual.buffer);
|
||||
expect(expected.offsetInBytes, equals(actual.offsetInBytes),
|
||||
reason: message(path, '.offsetInBytes'));
|
||||
expect(expected.lengthInBytes, equals(actual.lengthInBytes),
|
||||
reason: message(path, '.lengthInBytes'));
|
||||
// And also fallback to elements check below.
|
||||
}
|
||||
|
||||
if (expected is List) {
|
||||
expect(actual, predicate((v) => v is List),
|
||||
reason: message(path, '$actual is List'));
|
||||
expect(actual.length, expected.length,
|
||||
reason: message(path, 'different list lengths'));
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
walk('$path[$i]', expected[i], actual[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is Map) {
|
||||
expect(actual, predicate((v) => v is Map),
|
||||
reason: message(path, '$actual is Map'));
|
||||
for (var key in expected.keys) {
|
||||
if (!actual.containsKey(key)) {
|
||||
expect(false, isTrue, reason: message(path, 'missing key "$key"'));
|
||||
}
|
||||
walk('$path["$key"]', expected[key], actual[key]);
|
||||
}
|
||||
for (var key in actual.keys) {
|
||||
if (!expected.containsKey(key)) {
|
||||
expect(false, isTrue, reason: message(path, 'extra key "$key"'));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
expect(false, isTrue, reason: 'Unhandled type: $expected');
|
||||
}
|
||||
|
||||
walk('', expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizer which does nothing.
|
||||
*/
|
||||
class NullTreeSanitizer implements NodeTreeSanitizer {
|
||||
void sanitizeTree(Node node) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that two DOM trees are equivalent.
|
||||
*/
|
||||
void validateNodeTree(Node a, Node b, [String path = '']) {
|
||||
path = '${path}${a.runtimeType}';
|
||||
expect(a.nodeType, b.nodeType, reason: '$path nodeTypes differ');
|
||||
expect(a.nodeValue, b.nodeValue, reason: '$path nodeValues differ');
|
||||
expect(a.text, b.text, reason: '$path texts differ');
|
||||
expect(a.nodes.length, b.nodes.length, reason: '$path nodes.lengths differ');
|
||||
|
||||
if (a is Element) {
|
||||
Element bE = b;
|
||||
Element aE = a;
|
||||
|
||||
expect(aE.tagName, bE.tagName, reason: '$path tagNames differ');
|
||||
expect(aE.attributes.length, bE.attributes.length,
|
||||
reason: '$path attributes.lengths differ');
|
||||
for (var key in aE.attributes.keys) {
|
||||
expect(aE.attributes[key], bE.attributes[key],
|
||||
reason: '$path attribute [$key] values differ');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < a.nodes.length; ++i) {
|
||||
validateNodeTree(a.nodes[i], b.nodes[i], '$path[$i].');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6737,9 +6737,11 @@
|
|||
"readyState": {},
|
||||
"referrer": {},
|
||||
"registerElement": {
|
||||
"dart_action": "suppress",
|
||||
"support_level": "deprecated"
|
||||
},
|
||||
"registerElement2": {
|
||||
"dart_action": "suppress",
|
||||
"support_level": "deprecated"
|
||||
},
|
||||
"rootElement": {
|
||||
|
|
|
@ -27,28 +27,6 @@ $!MEMBERS
|
|||
ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
|
||||
new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));
|
||||
|
||||
/// Checks if [registerElement] is supported on the current platform.
|
||||
@deprecated
|
||||
bool get supportsRegisterElement {
|
||||
return JS('bool', '("registerElement" in #)', this);
|
||||
}
|
||||
|
||||
/// *Deprecated*: use [supportsRegisterElement] instead.
|
||||
@deprecated
|
||||
bool get supportsRegister => supportsRegisterElement;
|
||||
|
||||
/// **Deprecated**: This is a legacy API based on a deprecated Web Components
|
||||
/// v0.5 specification. Web Components v0.5 doesn't work on modern browsers
|
||||
/// and can only be used with a polyfill.
|
||||
///
|
||||
/// The latest Web Components specification is supported indirectly via
|
||||
/// JSInterop and doesn't have an explicit API in the `dart:html` library.
|
||||
@deprecated
|
||||
void registerElement(String tag, Type customElementClass,
|
||||
{String$NULLABLE extendsTag}) {
|
||||
registerElement2(tag, {'prototype': customElementClass, 'extends': extendsTag});
|
||||
}
|
||||
|
||||
@pragma('dart2js:tryInline') // Almost all call sites have one argument.
|
||||
Element createElement(String tagName, [String$NULLABLE typeExtension]) {
|
||||
return (typeExtension == null)
|
||||
|
|
|
@ -62,68 +62,6 @@ $!MEMBERS
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* **Deprecated**: This is a legacy API based on a deprecated Web Components
|
||||
* v0.5 specification. This method doesn't work on modern browsers and can
|
||||
* only be used with a polyfill.
|
||||
*
|
||||
* The latest Web Components specification is supported indirectly via
|
||||
* JSInterop and doesn't have an explicit API in the `dart:html` library.
|
||||
*
|
||||
* *Original documentation before deprecation*:
|
||||
*
|
||||
* Register a custom subclass of Element to be instantiatable by the DOM.
|
||||
*
|
||||
* This is necessary to allow the construction of any custom elements.
|
||||
*
|
||||
* The class being registered must either subclass HtmlElement or SvgElement.
|
||||
* If they subclass these directly then they can be used as:
|
||||
*
|
||||
* class FooElement extends HtmlElement{
|
||||
* void created() {
|
||||
* print('FooElement created!');
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* main() {
|
||||
* document.registerElement('x-foo', FooElement);
|
||||
* var myFoo = new Element.tag('x-foo');
|
||||
* // prints 'FooElement created!' to the console.
|
||||
* }
|
||||
*
|
||||
* The custom element can also be instantiated via HTML using the syntax
|
||||
* `<x-foo></x-foo>`
|
||||
*
|
||||
* Other elements can be subclassed as well:
|
||||
*
|
||||
* class BarElement extends InputElement{
|
||||
* void created() {
|
||||
* print('BarElement created!');
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* main() {
|
||||
* document.registerElement('x-bar', BarElement);
|
||||
* var myBar = new Element.tag('input', 'x-bar');
|
||||
* // prints 'BarElement created!' to the console.
|
||||
* }
|
||||
*
|
||||
* This custom element can also be instantiated via HTML using the syntax
|
||||
* `<input is="x-bar"></input>`
|
||||
*
|
||||
*/
|
||||
@deprecated
|
||||
Function registerElement2(String tag, [Map$NULLABLE options]) {
|
||||
return _registerCustomElement(JS('', 'window'), this, tag, options);
|
||||
}
|
||||
|
||||
/** *Deprecated*: use [registerElement] instead. */
|
||||
@deprecated
|
||||
void register(String tag, Type customElementClass,
|
||||
{String$NULLABLE extendsTag}) {
|
||||
return registerElement(tag, customElementClass, extendsTag: extendsTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static factory designed to expose `visibilitychange` events to event
|
||||
* handlers that are not necessarily instances of [Document].
|
||||
|
|
Loading…
Reference in a new issue