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

fix(core): fix #989, remove unuse code, use shorter name to reduce bundle size #990

Merged
merged 7 commits into from
Jan 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ script:
- node_modules/.bin/gulp lint
- node_modules/.bin/gulp format:enforce
- node_modules/.bin/gulp build
- node_modules/.bin/gulp filesize
- scripts/closure/closure_compiler.sh
- node_modules/.bin/gulp promisetest
- npm run test:phantomjs-single
Expand All @@ -35,4 +36,4 @@ script:
- node_modules/.bin/karma start karma-build-sauce-selenium3-mocha.conf.js --single-run
- node_modules/.bin/gulp test/node
- node simple-server.js 2>&1> server.log&
- node ./test/webdriver/test.sauce.js
- node ./test/webdriver/test.sauce.js
27 changes: 27 additions & 0 deletions check-file-size.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @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
*/
const fs = require('fs');

module.exports = function(config) {
let chkResult = true;
config.targets.forEach(target => {
if (target.checkTarget) {
try {
const stats = fs.statSync(target.path);
if (stats.size > target.limit) {
console.error(`file ${target.path} size over limit, limit is ${target.limit}, actual is ${stats.size}`);
chkResult = false;
}
} catch (err) {
console.error(`failed to get filesize: ${target.path}`);
chkResult = false;
}
}
});
return chkResult;
};
9 changes: 9 additions & 0 deletions file-size-limit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"targets": [
{
"path": "dist/zone.min.js",
"checkTarget": true,
"limit": 40000
}
]
}
21 changes: 21 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ gulp.task('build/zone-patch-electron.min.js', ['compile-esm'], function(cb) {
return generateScript('./lib/extra/electron.ts', 'zone-patch-electron.min.js', true, cb);
});

gulp.task('build/zone-patch-user-media.js', ['compile-esm'], function(cb) {
return generateScript('./lib/browser/webapis-user-media.ts', 'zone-patch-user-media.js', false, cb);
});

gulp.task('build/zone-patch-user-media.min.js', ['compile-esm'], function(cb) {
return generateScript('./lib/browser/webapis-user-media.ts', 'zone-patch-user-media.min.js', true, cb);
});

gulp.task('build/bluebird.js', ['compile-esm'], function(cb) {
return generateScript('./lib/extra/bluebird.ts', 'zone-bluebird.js', false, cb);
});
Expand Down Expand Up @@ -287,6 +295,8 @@ gulp.task('build', [
'build/zone-patch-cordova.min.js',
'build/zone-patch-electron.js',
'build/zone-patch-electron.min.js',
'build/zone-patch-user-media.js',
'build/zone-patch-user-media.min.js',
'build/zone-mix.js',
'build/bluebird.js',
'build/bluebird.min.js',
Expand Down Expand Up @@ -400,3 +410,14 @@ gulp.task('promisetest', ['build/zone-node.js'], (cb) => {
}
});
});

// check dist file size limitation
gulp.task('filesize', ['build'], (cb) => {
const checker = require('./check-file-size');
const result = checker(require('./file-size-limit.json'));
if (result) {
cb();
} else {
cb('check file size failed');
}
});
1 change: 1 addition & 0 deletions karma-dist.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = function (config) {
config.files.push('build/test/test_fake_polyfill.js');
config.files.push('build/test/custom_error.js');
config.files.push('dist/zone.js');
config.files.push('dist/zone-patch-user-media.js');
config.files.push('dist/async-test.js');
config.files.push('dist/fake-async-test.js');
config.files.push('dist/long-stack-trace-zone.js');
Expand Down
101 changes: 44 additions & 57 deletions lib/browser/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import {findEventTasks} from '../common/events';
import {patchTimer} from '../common/timers';
import {patchArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, wrapFunctionArgs, zoneSymbol} from '../common/utils';
import {bindArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, scheduleMacroTaskWithCurrentZone, ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, zoneSymbol} from '../common/utils';

import {propertyPatch} from './define-property';
import {eventTargetPatch, patchEvent} from './event-target';
Expand All @@ -22,24 +22,24 @@ import {registerElementPatch} from './register-element';
Zone.__load_patch('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.patchOnProperties = patchOnProperties;
api.patchMethod = patchMethod;
api.patchArguments = patchArguments;
api.bindArguments = bindArguments;
});

Zone.__load_patch('timers', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
Zone.__load_patch('timers', (global: any) => {
const set = 'set';
const clear = 'clear';
patchTimer(global, set, clear, 'Timeout');
patchTimer(global, set, clear, 'Interval');
patchTimer(global, set, clear, 'Immediate');
});

Zone.__load_patch('requestAnimationFrame', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
Zone.__load_patch('requestAnimationFrame', (global: any) => {
patchTimer(global, 'request', 'cancel', 'AnimationFrame');
patchTimer(global, 'mozRequest', 'mozCancel', 'AnimationFrame');
patchTimer(global, 'webkitRequest', 'webkitCancel', 'AnimationFrame');
});

Zone.__load_patch('blocking', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
Zone.__load_patch('blocking', (global: any, Zone: ZoneType) => {
const blockingMethods = ['alert', 'prompt', 'confirm'];
for (let i = 0; i < blockingMethods.length; i++) {
const name = blockingMethods[i];
Expand Down Expand Up @@ -77,18 +77,18 @@ Zone.__load_patch('on_property', (global: any, Zone: ZoneType, api: _ZonePrivate
registerElementPatch(global);
});

Zone.__load_patch('canvas', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
Zone.__load_patch('canvas', (global: any) => {
const HTMLCanvasElement = global['HTMLCanvasElement'];
if (typeof HTMLCanvasElement !== 'undefined' && HTMLCanvasElement.prototype &&
HTMLCanvasElement.prototype.toBlob) {
patchMacroTask(HTMLCanvasElement.prototype, 'toBlob', (self: any, args: any[]) => {
return {name: 'HTMLCanvasElement.toBlob', target: self, callbackIndex: 0, args: args};
return {name: 'HTMLCanvasElement.toBlob', target: self, cbIdx: 0, args: args};
});
}
});

Zone.__load_patch('XHR', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
// Treat XMLHTTPRequest as a macrotask.
Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
// Treat XMLHttpRequest as a macrotask.
patchXHR(global);

const XHR_TASK = zoneSymbol('xhrTask');
Expand All @@ -105,21 +105,20 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
}

function patchXHR(window: any) {
const XMLHttpRequestPrototype: any = XMLHttpRequest.prototype;

function findPendingTask(target: any) {
const pendingTask: Task = target[XHR_TASK];
return pendingTask;
return target[XHR_TASK];
}

const SYMBOL_ADDEVENTLISTENER = zoneSymbol('addEventListener');
const SYMBOL_REMOVEEVENTLISTENER = zoneSymbol('removeEventListener');

let oriAddListener = (XMLHttpRequest.prototype as any)[SYMBOL_ADDEVENTLISTENER];
let oriRemoveListener = (XMLHttpRequest.prototype as any)[SYMBOL_REMOVEEVENTLISTENER];
let oriAddListener = XMLHttpRequestPrototype[ZONE_SYMBOL_ADD_EVENT_LISTENER];
let oriRemoveListener = XMLHttpRequestPrototype[ZONE_SYMBOL_REMOVE_EVENT_LISTENER];
if (!oriAddListener) {
const XMLHttpRequestEventTarget = window['XMLHttpRequestEventTarget'];
if (XMLHttpRequestEventTarget) {
oriAddListener = XMLHttpRequestEventTarget.prototype[SYMBOL_ADDEVENTLISTENER];
oriRemoveListener = XMLHttpRequestEventTarget.prototype[SYMBOL_REMOVEEVENTLISTENER];
const XMLHttpRequestEventTargetPrototype = XMLHttpRequestEventTarget.prototype;
oriAddListener = XMLHttpRequestEventTargetPrototype[ZONE_SYMBOL_ADD_EVENT_LISTENER];
oriRemoveListener = XMLHttpRequestEventTargetPrototype[ZONE_SYMBOL_REMOVE_EVENT_LISTENER];
}
}

Expand All @@ -133,12 +132,12 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
// remove existing event listener
const listener = target[XHR_LISTENER];
if (!oriAddListener) {
oriAddListener = target[SYMBOL_ADDEVENTLISTENER];
oriRemoveListener = target[SYMBOL_REMOVEEVENTLISTENER];
oriAddListener = target[ZONE_SYMBOL_ADD_EVENT_LISTENER];
oriRemoveListener = target[ZONE_SYMBOL_REMOVE_EVENT_LISTENER];
}

if (listener) {
oriRemoveListener.apply(target, [READY_STATE_CHANGE, listener]);
oriRemoveListener.call(target, READY_STATE_CHANGE, listener);
}
const newListener = target[XHR_LISTENER] = () => {
if (target.readyState === target.DONE) {
Expand All @@ -149,7 +148,7 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
}
}
};
oriAddListener.apply(target, [READY_STATE_CHANGE, newListener]);
oriAddListener.call(target, READY_STATE_CHANGE, newListener);

const storedTask: Task = target[XHR_TASK];
if (!storedTask) {
Expand All @@ -170,17 +169,16 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
return abortNative.apply(data.target, data.args);
}

const openNative: Function = patchMethod(
window.XMLHttpRequest.prototype, 'open', () => function(self: any, args: any[]) {
const openNative: Function =
patchMethod(XMLHttpRequestPrototype, 'open', () => function(self: any, args: any[]) {
self[XHR_SYNC] = args[2] == false;
self[XHR_URL] = args[1];
return openNative.apply(self, args);
});

const XMLHTTPREQUEST_SOURCE = 'XMLHttpRequest.send';
const sendNative: Function = patchMethod(
window.XMLHttpRequest.prototype, 'send', () => function(self: any, args: any[]) {
const zone = Zone.current;
const sendNative: Function =
patchMethod(XMLHttpRequestPrototype, 'send', () => function(self: any, args: any[]) {
if (self[XHR_SYNC]) {
// if the XHR is sync there is no task to schedule, just execute the code.
return sendNative.apply(self, args);
Expand All @@ -193,49 +191,38 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
args: args,
aborted: false
};
return zone.scheduleMacroTask(
return scheduleMacroTaskWithCurrentZone(
XMLHTTPREQUEST_SOURCE, placeholderCallback, options, scheduleTask, clearTask);
}
});

const STRING_TYPE = 'string';

const abortNative = patchMethod(
window.XMLHttpRequest.prototype, 'abort',
(delegate: Function) => function(self: any, args: any[]) {
const task: Task = findPendingTask(self);
if (task && typeof task.type == STRING_TYPE) {
// If the XHR has already completed, do nothing.
// If the XHR has already been aborted, do nothing.
// Fix #569, call abort multiple times before done will cause
// macroTask task count be negative number
if (task.cancelFn == null || (task.data && (<XHROptions>task.data).aborted)) {
return;
}
task.zone.cancelTask(task);
}
// Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no
// task
// to cancel. Do nothing.
});
const abortNative = patchMethod(XMLHttpRequestPrototype, 'abort', () => function(self: any) {
const task: Task = findPendingTask(self);
if (task && typeof task.type == 'string') {
// If the XHR has already completed, do nothing.
// If the XHR has already been aborted, do nothing.
// Fix #569, call abort multiple times before done will cause
// macroTask task count be negative number
if (task.cancelFn == null || (task.data && (<XHROptions>task.data).aborted)) {
return;
}
task.zone.cancelTask(task);
}
// Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no
// task
// to cancel. Do nothing.
});
}
});

Zone.__load_patch('geolocation', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
Zone.__load_patch('geolocation', (global: any) => {
/// GEO_LOCATION
if (global['navigator'] && global['navigator'].geolocation) {
patchPrototype(global['navigator'].geolocation, ['getCurrentPosition', 'watchPosition']);
}
});

Zone.__load_patch('getUserMedia', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
let navigator = global['navigator'];
if (navigator && navigator.getUserMedia) {
navigator.getUserMedia = wrapFunctionArgs(navigator.getUserMedia);
}
});

Zone.__load_patch('PromiseRejectionEvent', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
Zone.__load_patch('PromiseRejectionEvent', (global: any, Zone: ZoneType) => {
// handle unhandled promise rejection
function findPromiseRejectionHandler(evtName: string) {
return function(e: any) {
Expand Down
9 changes: 3 additions & 6 deletions lib/browser/define-property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@ const _getOwnPropertyDescriptor = (Object as any)[zoneSymbol('getOwnPropertyDesc
Object.getOwnPropertyDescriptor;
const _create = Object.create;
const unconfigurablesKey = zoneSymbol('unconfigurables');
const PROTOTYPE = 'prototype';
const OBJECT = 'object';
const UNDEFINED = 'undefined';

export function propertyPatch() {
Object.defineProperty = function(obj, prop, desc) {
if (isUnconfigurable(obj, prop)) {
throw new TypeError('Cannot assign to read only property \'' + prop + '\' of ' + obj);
}
const originalConfigurableFlag = desc.configurable;
if (prop !== PROTOTYPE) {
if (prop !== 'prototype') {
desc = rewriteDescriptor(obj, prop, desc);
}
return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag);
Expand All @@ -41,7 +38,7 @@ export function propertyPatch() {
};

Object.create = <any>function(obj: any, proto: any) {
if (typeof proto === OBJECT && !Object.isFrozen(proto)) {
if (typeof proto === 'object' && !Object.isFrozen(proto)) {
Object.keys(proto).forEach(function(prop) {
proto[prop] = rewriteDescriptor(obj, prop, proto[prop]);
});
Expand Down Expand Up @@ -92,7 +89,7 @@ function _tryDefineProperty(obj: any, prop: string, desc: any, originalConfigura
if (desc.configurable) {
// In case of errors, when the configurable flag was likely set by rewriteDescriptor(), let's
// retry with the original flag value
if (typeof originalConfigurableFlag == UNDEFINED) {
if (typeof originalConfigurableFlag == 'undefined') {
delete desc.configurable;
} else {
desc.configurable = originalConfigurableFlag;
Expand Down
8 changes: 5 additions & 3 deletions lib/browser/event-target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/

import {FALSE_STR, globalSources, patchEventPrototype, patchEventTarget, TRUE_STR, ZONE_SYMBOL_PREFIX, zoneSymbolEventNames} from '../common/events';
import {attachOriginToPatched, isIEOrEdge, zoneSymbol} from '../common/utils';
import {globalSources, patchEventPrototype, patchEventTarget, zoneSymbolEventNames} from '../common/events';
import {FALSE_STR, isIEOrEdge, TRUE_STR, ZONE_SYMBOL_PREFIX} from '../common/utils';

import {eventNames} from './property-descriptor';

Expand Down Expand Up @@ -101,7 +101,9 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) {
const type = _global[apis[i]];
apiTypes.push(type && type.prototype);
}
patchEventTarget(_global, apiTypes, {validateHandler: checkIEAndCrossContext});
// vh is validateHandler to check event handler
// is valid or not(for security check)
patchEventTarget(_global, apiTypes, {vh: checkIEAndCrossContext});
api.patchEventTarget = patchEventTarget;

return true;
Expand Down
Loading