Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 427705f

Browse files
JiaLiPassionmhevery
authored andcommitted
feat(custom-element): patch customElement v1 APIs (#1133)
1 parent 60adc9c commit 427705f

11 files changed

Lines changed: 239 additions & 15 deletions

‎.travis.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,5 @@ script:
5454
- node_modules/.bin/karma start karma-build-sauce-selenium3-mocha.conf.js --single-run
5555
- node_modules/.bin/gulp test/node
5656
- node_modules/.bin/gulp test/node -no-patch-clock
57+
- cp ./test/browser/custom-element.spec.js ./build/test/browser
58+
- node_modules/.bin/karma start karma-dist-sauce-jasmine.es6.conf.js --single-run

‎file-size-limit.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"path": "dist/zone.min.js",
55
"checkTarget": true,
6-
"limit": 42050
6+
"limit": 42500
77
}
88
]
9-
}
9+
}

‎karma-build-jasmine.es6.conf.js‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
module.exports=function(config){
3+
require('./karma-build-jasmine.conf.js')(config);
4+
config.client.entrypoint='browser_es6_entry_point';
5+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
module.exports=function(config){
3+
require('./karma-dist-jasmine.conf.js')(config);
4+
require('./sauce.es6.conf')(config);
5+
config.client.entrypoint='browser_es6_entry_point';
6+
};

‎lib/browser/browser.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {bindArguments, patchClass, patchMacroTask, patchMethod, patchOnPropertie
1717
import{propertyPatch}from'./define-property';
1818
import{eventTargetPatch,patchEvent}from'./event-target';
1919
import{propertyDescriptorPatch}from'./property-descriptor';
20-
import{registerElementPatch}from'./register-element';
20+
import{patchCustomElements,registerElementPatch}from'./register-element';
2121

2222
Zone.__load_patch('util',(global: any,Zone: ZoneType,api: _ZonePrivate)=>{
2323
api.patchOnProperties=patchOnProperties;
@@ -74,7 +74,11 @@ Zone.__load_patch('EventTarget', (global: any, Zone: ZoneType, api: _ZonePrivate
7474
Zone.__load_patch('on_property',(global: any,Zone: ZoneType,api: _ZonePrivate)=>{
7575
propertyDescriptorPatch(api,global);
7676
propertyPatch();
77+
});
78+
79+
Zone.__load_patch('customElements',(global: any,Zone: ZoneType,api: _ZonePrivate)=>{
7780
registerElementPatch(global);
81+
patchCustomElements(global);
7882
});
7983

8084
Zone.__load_patch('canvas',(global: any)=>{

‎lib/browser/register-element.ts‎

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,16 @@ import {attachOriginToPatched, isBrowser, isMix, ObjectGetOwnPropertyDescriptor,
1010

1111
import{_redefineProperty}from'./define-property';
1212

13-
exportfunctionregisterElementPatch(_global: any){
14-
if((!isBrowser&&!isMix)||!('registerElement'in(<any>_global).document)){
13+
functionpatchCallbacks(target: any,targetName: string,method: string,callbacks: string[]){
14+
constsymbol=Zone.__symbol__(method);
15+
if(target[symbol]){
1516
return;
1617
}
17-
18-
const_registerElement=(<any>document).registerElement;
19-
constcallbacks=
20-
['createdCallback','attachedCallback','detachedCallback','attributeChangedCallback'];
21-
22-
(<any>document).registerElement=function(name: any,opts: any){
18+
constnativeDelegate=target[symbol]=target[method];
19+
target[method]=function(name: any,opts: any,options?: any){
2320
if(opts&&opts.prototype){
2421
callbacks.forEach(function(callback){
25-
constsource='Document.registerElement::'+callback;
22+
constsource=`${targetName}.${method}::`+callback;
2623
constprototype=opts.prototype;
2724
if(prototype.hasOwnProperty(callback)){
2825
constdescriptor=ObjectGetOwnPropertyDescriptor(prototype,callback);
@@ -38,8 +35,30 @@ export function registerElementPatch(_global: any) {
3835
});
3936
}
4037

41-
return_registerElement.call(document,name,opts);
38+
returnnativeDelegate.call(target,name,opts,options);
4239
};
4340

44-
attachOriginToPatched((<any>document).registerElement,_registerElement);
41+
attachOriginToPatched(target[method],nativeDelegate);
42+
}
43+
44+
exportfunctionregisterElementPatch(_global: any){
45+
if((!isBrowser&&!isMix)||!('registerElement'in(<any>_global).document)){
46+
return;
47+
}
48+
49+
constcallbacks=
50+
['createdCallback','attachedCallback','detachedCallback','attributeChangedCallback'];
51+
52+
patchCallbacks(document,'Document','registerElement',callbacks);
53+
}
54+
55+
exportfunctionpatchCustomElements(_global: any){
56+
if((!isBrowser&&!isMix)||!('customElements'in_global)){
57+
return;
58+
}
59+
60+
constcallbacks=
61+
['connectedCallback','disconnectedCallback','adoptedCallback','attributeChangedCallback'];
62+
63+
patchCallbacks(_global.customElements,'customElements','define',callbacks);
4564
}

‎package.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"closure:test": "scripts/closure/closure_compiler.sh",
2121
"format": "gulp format:enforce",
2222
"karma-jasmine": "karma start karma-build-jasmine.conf.js",
23+
"karma-jasmine:es6": "karma start karma-build-jasmine.es6.conf.js",
2324
"karma-jasmine:phantomjs": "karma start karma-build-jasmine-phantomjs.conf.js --single-run",
2425
"karma-jasmine:single": "karma start karma-build-jasmine.conf.js --single-run",
2526
"karma-jasmine:autoclose": "npm run karma-jasmine:single && npm run ws-client",
@@ -38,6 +39,7 @@
3839
"tsc:w": "tsc -w -p .",
3940
"tslint": "tslint -c tslint.json 'lib/**/*.ts'",
4041
"test": "npm run tsc && concurrently \"npm run tsc:w\"\"npm run ws-server\"\"npm run karma-jasmine\"",
42+
"test:es6": "npm run tsc && concurrently \"npm run tsc:w\"\"npm run ws-server\"\"npm run karma-jasmine:es6\"",
4143
"test:phantomjs": "npm run tsc && concurrently \"npm run tsc:w\"\"npm run ws-server\"\"npm run karma-jasmine:phantomjs\"",
4244
"test:phantomjs-single": "npm run tsc && concurrently \"npm run ws-server\"\"npm run karma-jasmine-phantomjs:autoclose\"",
4345
"test:single": "npm run tsc && concurrently \"npm run ws-server\"\"npm run karma-jasmine:autoclose\"",

‎sauce.es6.conf.js‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Sauce configuration
2+
3+
module.exports=function(config,ignoredLaunchers){
4+
// The WS server is not available with Sauce
5+
config.files.unshift('test/saucelabs.js');
6+
7+
varbasicLaunchers={
8+
'SL_CHROME_66': {base: 'SauceLabs',browserName: 'chrome',version: '66'},
9+
};
10+
11+
varcustomLaunchers={};
12+
if(!ignoredLaunchers){
13+
customLaunchers=basicLaunchers;
14+
}else{
15+
Object.keys(basicLaunchers).forEach(function(key){
16+
if(ignoredLaunchers
17+
.filter(function(ignore){
18+
returnignore===key;
19+
})
20+
.length===0){
21+
customLaunchers[key]=basicLaunchers[key];
22+
}
23+
});
24+
}
25+
26+
config.set({
27+
captureTimeout: 120000,
28+
browserNoActivityTimeout: 240000,
29+
30+
sauceLabs: {
31+
testName: 'Zone.js',
32+
startConnect: false,
33+
recordVideo: false,
34+
recordScreenshots: false,
35+
options: {
36+
'selenium-version': '2.53.0',
37+
'command-timeout': 600,
38+
'idle-timeout': 600,
39+
'max-duration': 5400
40+
}
41+
},
42+
43+
customLaunchers: customLaunchers,
44+
45+
browsers: Object.keys(customLaunchers),
46+
47+
reporters: ['dots','saucelabs'],
48+
49+
singleRun: true,
50+
51+
plugins: ['karma-*']
52+
});
53+
54+
if(process.env.TRAVIS){
55+
config.sauceLabs.build=
56+
'TRAVIS #'+process.env.TRAVIS_BUILD_NUMBER+' ('+process.env.TRAVIS_BUILD_ID+')';
57+
config.sauceLabs.tunnelIdentifier=process.env.TRAVIS_JOB_NUMBER;
58+
59+
process.env.SAUCE_ACCESS_KEY=process.env.SAUCE_ACCESS_KEY.split('').reverse().join('');
60+
}
61+
};
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
/*
10+
* check that document.registerElement(name, { prototype: proto });
11+
* is properly patched
12+
*/
13+
14+
functioncustomElementsSupport(){
15+
return'registerElement'indocument;
16+
}
17+
customElementsSupport.message='window.customElements';
18+
19+
describe('customElements',function(){
20+
consttestZone=Zone.current.fork({name: 'test'});
21+
constbridge={
22+
connectedCallback: ()=>{},
23+
disconnectedCallback: ()=>{},
24+
adoptedCallback: ()=>{},
25+
attributeChangedCallback: ()=>{}
26+
};
27+
28+
classTestCustomElementextendsHTMLElement{
29+
constructor(){
30+
super();
31+
}
32+
33+
staticgetobservedAttributes(){
34+
return['attr1','attr2'];
35+
}
36+
37+
connectedCallback(){
38+
returnbridge.connectedCallback();
39+
}
40+
41+
disconnectedCallback(){
42+
returnbridge.disconnectedCallback();
43+
}
44+
45+
attributeChangedCallback(attrName,oldVal,newVal){
46+
returnbridge.attributeChangedCallback(attrName,oldVal,newVal);
47+
}
48+
49+
adoptedCallback(){
50+
returnbridge.adoptedCallback();
51+
}
52+
}
53+
54+
testZone.run(()=>{
55+
customElements.define('x-test',TestCustomElement);
56+
});
57+
58+
letelt;
59+
60+
beforeEach(()=>{
61+
bridge.connectedCallback=()=>{};
62+
bridge.disconnectedCallback=()=>{};
63+
bridge.attributeChangedCallback=()=>{};
64+
bridge.adoptedCallback=()=>{};
65+
});
66+
67+
afterEach(()=>{
68+
if(elt){
69+
document.body.removeChild(elt);
70+
elt=null;
71+
}
72+
});
73+
74+
it('should work with connectedCallback',function(done){
75+
bridge.connectedCallback=function(){
76+
expect(Zone.current.name).toBe(testZone.name);
77+
done();
78+
};
79+
80+
elt=document.createElement('x-test');
81+
document.body.appendChild(elt);
82+
});
83+
84+
it('should work with disconnectedCallback',function(done){
85+
bridge.disconnectedCallback=function(){
86+
expect(Zone.current.name).toBe(testZone.name);
87+
done();
88+
};
89+
90+
elt=document.createElement('x-test');
91+
document.body.appendChild(elt);
92+
document.body.removeChild(elt);
93+
elt=null;
94+
});
95+
96+
it('should work with attributeChanged',function(done){
97+
bridge.attributeChangedCallback=function(attrName,oldVal,newVal){
98+
expect(Zone.current.name).toBe(testZone.name);
99+
expect(attrName).toEqual('attr1');
100+
expect(newVal).toEqual('value1');
101+
done();
102+
};
103+
104+
elt=document.createElement('x-test');
105+
document.body.appendChild(elt);
106+
elt.setAttribute('attr1','value1');
107+
});
108+
});

‎test/browser_es6_entry_point.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import'./browser/custom-element.spec';

0 commit comments

Comments
 (0)