165 lines
5.3 KiB
TypeScript
165 lines
5.3 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
/*
|
|
* check that document.registerElement(name, { prototype: proto });
|
|
* is properly patched
|
|
*/
|
|
|
|
import {ifEnvSupports} from '../test-util';
|
|
|
|
function registerElement() {
|
|
return ('registerElement' in document) && (typeof customElements === 'undefined');
|
|
}
|
|
(<any>registerElement).message = 'document.registerElement';
|
|
|
|
describe(
|
|
'document.registerElement', ifEnvSupports(registerElement, function() {
|
|
// register a custom element for each callback
|
|
const callbackNames = ['created', 'attached', 'detached', 'attributeChanged'];
|
|
const callbacks: any = {};
|
|
const testZone = Zone.current.fork({name: 'test'});
|
|
let customElements;
|
|
|
|
customElements = testZone.run(function() {
|
|
callbackNames.forEach(function(callbackName) {
|
|
const fullCallbackName = callbackName + 'Callback';
|
|
const proto = Object.create(HTMLElement.prototype);
|
|
(proto as any)[fullCallbackName] = function(arg: any) { callbacks[callbackName](arg); };
|
|
(<any>document).registerElement('x-' + callbackName.toLowerCase(), {prototype: proto});
|
|
});
|
|
});
|
|
|
|
it('should work with createdCallback', function(done) {
|
|
callbacks.created = function() {
|
|
expect(Zone.current).toBe(testZone);
|
|
done();
|
|
};
|
|
|
|
document.createElement('x-created');
|
|
});
|
|
|
|
|
|
it('should work with attachedCallback', function(done) {
|
|
callbacks.attached = function() {
|
|
expect(Zone.current).toBe(testZone);
|
|
done();
|
|
};
|
|
|
|
const elt = document.createElement('x-attached');
|
|
document.body.appendChild(elt);
|
|
document.body.removeChild(elt);
|
|
});
|
|
|
|
|
|
it('should work with detachedCallback', function(done) {
|
|
callbacks.detached = function() {
|
|
expect(Zone.current).toBe(testZone);
|
|
done();
|
|
};
|
|
|
|
const elt = document.createElement('x-detached');
|
|
document.body.appendChild(elt);
|
|
document.body.removeChild(elt);
|
|
});
|
|
|
|
|
|
it('should work with attributeChanged', function(done) {
|
|
callbacks.attributeChanged = function() {
|
|
expect(Zone.current).toBe(testZone);
|
|
done();
|
|
};
|
|
|
|
const elt = document.createElement('x-attributechanged');
|
|
elt.id = 'bar';
|
|
});
|
|
|
|
|
|
it('should work with non-writable, non-configurable prototypes created with defineProperty',
|
|
function(done) {
|
|
testZone.run(function() {
|
|
const proto = Object.create(HTMLElement.prototype);
|
|
|
|
Object.defineProperty(
|
|
proto, 'createdCallback',
|
|
<any>{writable: false, configurable: false, value: checkZone});
|
|
|
|
(<any>document).registerElement('x-prop-desc', {prototype: proto});
|
|
|
|
function checkZone() {
|
|
expect(Zone.current).toBe(testZone);
|
|
done();
|
|
}
|
|
});
|
|
|
|
const elt = document.createElement('x-prop-desc');
|
|
});
|
|
|
|
|
|
it('should work with non-writable, non-configurable prototypes created with defineProperties',
|
|
function(done) {
|
|
testZone.run(function() {
|
|
const proto = Object.create(HTMLElement.prototype);
|
|
|
|
Object.defineProperties(
|
|
proto,
|
|
{createdCallback: <any>{writable: false, configurable: false, value: checkZone}});
|
|
|
|
(<any>document).registerElement('x-props-desc', {prototype: proto});
|
|
|
|
function checkZone() {
|
|
expect(Zone.current).toBe(testZone);
|
|
done();
|
|
}
|
|
});
|
|
|
|
const elt = document.createElement('x-props-desc');
|
|
});
|
|
|
|
it('should not throw with frozen prototypes ', function() {
|
|
testZone.run(function() {
|
|
const proto = Object.create(HTMLElement.prototype, Object.freeze(<PropertyDescriptorMap>{
|
|
createdCallback:
|
|
<PropertyDescriptor>{value: () => {}, writable: true, configurable: true}
|
|
}));
|
|
|
|
Object.defineProperty(
|
|
proto, 'createdCallback', <any>{writable: false, configurable: false});
|
|
|
|
expect(function() {
|
|
(<any>document).registerElement('x-frozen-desc', {prototype: proto});
|
|
}).not.toThrow();
|
|
});
|
|
});
|
|
|
|
|
|
it('should check bind callback if not own property', function(done) {
|
|
testZone.run(function() {
|
|
const originalProto = {createdCallback: checkZone};
|
|
|
|
const secondaryProto = Object.create(originalProto);
|
|
expect(secondaryProto.createdCallback).toBe(originalProto.createdCallback);
|
|
|
|
(<any>document).registerElement('x-inherited-callback', {prototype: secondaryProto});
|
|
expect(secondaryProto.createdCallback).not.toBe(originalProto.createdCallback);
|
|
|
|
function checkZone() {
|
|
expect(Zone.current).toBe(testZone);
|
|
done();
|
|
}
|
|
|
|
const elt = document.createElement('x-inherited-callback');
|
|
});
|
|
});
|
|
|
|
|
|
it('should not throw if no options passed to registerElement', function() {
|
|
expect(function() { (<any>document).registerElement('x-no-opts'); }).not.toThrow();
|
|
});
|
|
}));
|