From 11213c67492d2dee2d4f4e0561ee057fecc65774 Mon Sep 17 00:00:00 2001 From: "JiaLi.Passion" Date: Sun, 7 Jan 2018 00:36:11 +0900 Subject: [PATCH 1/7] fix(core): fix #989, remove unuse code, use shorter name to reduce bundle size --- gulpfile.js | 10 ++ lib/browser/browser.ts | 105 +++++++------- lib/browser/define-property.ts | 11 +- lib/browser/event-target.ts | 22 +-- lib/browser/property-descriptor.ts | 40 +++--- lib/browser/register-element.ts | 15 +- lib/browser/shadydom.ts | 4 +- lib/browser/webapis-media-query.ts | 7 +- lib/browser/webapis-notification.ts | 4 +- lib/browser/webapis-rtc-peer-connection.ts | 4 +- lib/browser/webapis-user-media.ts | 20 +++ lib/browser/websocket.ts | 18 +-- lib/common/events.ts | 154 ++++++++++----------- lib/common/promise.ts | 51 +++---- lib/common/timers.ts | 38 +++-- lib/common/to-string.ts | 9 +- lib/common/utils.ts | 100 +++++++------ lib/extra/bluebird.ts | 6 +- lib/extra/cordova.ts | 10 +- lib/extra/electron.ts | 16 ++- lib/node/events.ts | 22 +-- lib/node/fs.ts | 6 +- lib/node/node.ts | 26 ++-- lib/rxjs/rxjs.ts | 8 +- lib/zone-spec/fake-async-test.ts | 2 +- lib/zone.ts | 27 +++- test/browser-zone-setup.ts | 3 +- test/browser_entry_point.ts | 1 - test/common/util.spec.ts | 28 +--- test/common_tests.ts | 4 +- test/zone-spec/fake-async-test.spec.ts | 6 +- 31 files changed, 388 insertions(+), 389 deletions(-) create mode 100644 lib/browser/webapis-user-media.ts diff --git a/gulpfile.js b/gulpfile.js index 0bb8c47fb..71a099320 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -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); }); @@ -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', diff --git a/lib/browser/browser.ts b/lib/browser/browser.ts index ce9a77c22..03f3b00db 100644 --- a/lib/browser/browser.ts +++ b/lib/browser/browser.ts @@ -12,20 +12,20 @@ import {findEventTasks} from '../common/events'; import {patchTimer} from '../common/timers'; -import {patchArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, wrapFunctionArgs, zoneSymbol} from '../common/utils'; +import {bindArguments, i, j, o, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, r, zoneSymbol} from '../common/utils'; import {propertyPatch} from './define-property'; import {eventTargetPatch, patchEvent} from './event-target'; import {propertyDescriptorPatch} from './property-descriptor'; import {registerElementPatch} from './register-element'; -Zone.__load_patch('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('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 as any).l('timers', (global: any) => { const set = 'set'; const clear = 'clear'; patchTimer(global, set, clear, 'Timeout'); @@ -33,27 +33,27 @@ Zone.__load_patch('timers', (global: any, Zone: ZoneType, api: _ZonePrivate) => patchTimer(global, set, clear, 'Immediate'); }); -Zone.__load_patch('requestAnimationFrame', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('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 as any).l('blocking', (global: any, Zone: ZoneType) => { const blockingMethods = ['alert', 'prompt', 'confirm']; for (let i = 0; i < blockingMethods.length; i++) { const name = blockingMethods[i]; patchMethod(global, name, (delegate, symbol, name) => { return function(s: any, args: any[]) { - return Zone.current.run(delegate, global, args, name); + return (Zone as any).c.r(delegate, global, args, name); }; }); } }); -Zone.__load_patch('EventTarget', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('EventTarget', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // load blackListEvents from global - const SYMBOL_BLACK_LISTED_EVENTS = Zone.__symbol__('BLACK_LISTED_EVENTS'); + const SYMBOL_BLACK_LISTED_EVENTS = (Zone as any).s('BLACK_LISTED_EVENTS'); if (global[SYMBOL_BLACK_LISTED_EVENTS]) { (Zone as any)[SYMBOL_BLACK_LISTED_EVENTS] = global[SYMBOL_BLACK_LISTED_EVENTS]; } @@ -71,23 +71,23 @@ Zone.__load_patch('EventTarget', (global: any, Zone: ZoneType, api: _ZonePrivate patchClass('FileReader'); }); -Zone.__load_patch('on_property', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('on_property', (global: any, Zone: ZoneType, api: _ZonePrivate) => { propertyDescriptorPatch(api, global); propertyPatch(); registerElementPatch(global); }); -Zone.__load_patch('canvas', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('canvas', (global: any) => { const HTMLCanvasElement = global['HTMLCanvasElement']; - if (typeof HTMLCanvasElement !== 'undefined' && HTMLCanvasElement.prototype && + if (typeof HTMLCanvasElement !== o && 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) => { +(Zone as any).l('XHR', (global: any, Zone: ZoneType) => { // Treat XMLHTTPRequest as a macrotask. patchXHR(global); @@ -105,21 +105,21 @@ 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; } - 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[i]; + let oriRemoveListener = XMLHttpRequestPrototype[j]; if (!oriAddListener) { const XMLHttpRequestEventTarget = window['XMLHttpRequestEventTarget']; if (XMLHttpRequestEventTarget) { - oriAddListener = XMLHttpRequestEventTarget.prototype[SYMBOL_ADDEVENTLISTENER]; - oriRemoveListener = XMLHttpRequestEventTarget.prototype[SYMBOL_REMOVEEVENTLISTENER]; + const XMLHttpRequestEventTargetPrototype = XMLHttpRequestEventTarget.prototype; + oriAddListener = XMLHttpRequestEventTargetPrototype[i]; + oriRemoveListener = XMLHttpRequestEventTargetPrototype[j]; } } @@ -133,8 +133,8 @@ 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[i]; + oriRemoveListener = target[j]; } if (listener) { @@ -170,17 +170,17 @@ 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[]) { + const zone = (Zone as any).c; if (self[XHR_SYNC]) { // if the XHR is sync there is no task to schedule, just execute the code. return sendNative.apply(self, args); @@ -193,49 +193,38 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType, api: _ZonePrivate) => { args: args, aborted: false }; - return zone.scheduleMacroTask( + return zone.sc( 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 && (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 == r) { + // 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 && (task.data).aborted)) { + return; + } + (task.zone as any).ct(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 as any).l('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 as any).l('PromiseRejectionEvent', (global: any, Zone: ZoneType) => { // handle unhandled promise rejection function findPromiseRejectionHandler(evtName: string) { return function(e: any) { diff --git a/lib/browser/define-property.ts b/lib/browser/define-property.ts index 2a2f0e18f..ae966c86e 100644 --- a/lib/browser/define-property.ts +++ b/lib/browser/define-property.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {zoneSymbol} from '../common/utils'; +import {o, p, zoneSymbol} from '../common/utils'; /* * This is necessary for Chrome and Chrome mobile, to enable * things like redefining `createdCallback` on an element. @@ -17,9 +17,6 @@ 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) { @@ -27,7 +24,7 @@ export function propertyPatch() { 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); @@ -41,7 +38,7 @@ export function propertyPatch() { }; Object.create = function(obj: any, proto: any) { - if (typeof proto === OBJECT && !Object.isFrozen(proto)) { + if (typeof proto === p && !Object.isFrozen(proto)) { Object.keys(proto).forEach(function(prop) { proto[prop] = rewriteDescriptor(obj, prop, proto[prop]); }); @@ -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 == o) { delete desc.configurable; } else { desc.configurable = originalConfigurableFlag; diff --git a/lib/browser/event-target.ts b/lib/browser/event-target.ts index 2972cfbd6..d0bb6a897 100644 --- a/lib/browser/event-target.ts +++ b/lib/browser/event-target.ts @@ -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 {ens, gs, patchEventPrototype, patchEventTarget} from '../common/events'; +import {isIEOrEdge, k, l, m} from '../common/utils'; import {eventNames} from './property-descriptor'; @@ -45,19 +45,19 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) { // predefine all __zone_symbol__ + eventName + true/false string for (let i = 0; i < eventNames.length; i++) { const eventName = eventNames[i]; - const falseEventName = eventName + FALSE_STR; - const trueEventName = eventName + TRUE_STR; - const symbol = ZONE_SYMBOL_PREFIX + falseEventName; - const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName; - zoneSymbolEventNames[eventName] = {}; - zoneSymbolEventNames[eventName][FALSE_STR] = symbol; - zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture; + const falseEventName = eventName + l; + const trueEventName = eventName + k; + const symbol = m + falseEventName; + const symbolCapture = m + trueEventName; + ens[eventName] = {}; + ens[eventName][l] = symbol; + ens[eventName][k] = symbolCapture; } // predefine all task.source string for (let i = 0; i < WTF_ISSUE_555.length; i++) { const target: any = WTF_ISSUE_555_ARRAY[i]; - const targets: any = globalSources[target] = {}; + const targets: any = gs[target] = {}; for (let j = 0; j < eventNames.length; j++) { const eventName = eventNames[j]; targets[eventName] = target + ADD_EVENT_LISTENER_SOURCE + eventName; @@ -101,7 +101,7 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) { const type = _global[apis[i]]; apiTypes.push(type && type.prototype); } - patchEventTarget(_global, apiTypes, {validateHandler: checkIEAndCrossContext}); + patchEventTarget(_global, apiTypes, {vh: checkIEAndCrossContext}); api.patchEventTarget = patchEventTarget; return true; diff --git a/lib/browser/property-descriptor.ts b/lib/browser/property-descriptor.ts index 55c2df789..f8945947e 100644 --- a/lib/browser/property-descriptor.ts +++ b/lib/browser/property-descriptor.ts @@ -10,7 +10,7 @@ * @suppress {globalThis} */ -import {isBrowser, isMix, isNode, patchClass, patchOnProperties, zoneSymbol} from '../common/utils'; +import {a, b, d, isBrowser, isMix, isNode, o, patchClass, patchOnProperties, zoneSymbol} from '../common/utils'; import * as webSocketPatch from './websocket'; @@ -265,21 +265,19 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { return; } - const supportsWebSocket = typeof WebSocket !== 'undefined'; + const supportsWebSocket = typeof WebSocket !== o; if (canPatchViaPropertyDescriptor()) { const ignoreProperties: IgnoreProperty[] = _global.__Zone_ignore_on_properties; // for browsers that we can patch the descriptor: Chrome & Firefox if (isBrowser) { + const w: any = window; // in IE/Edge, onProp not exist in window object, but in WindowPrototype // so we need to pass WindowPrototype to check onProp exist or not - patchFilteredProperties( - window, eventNames.concat(['messageerror']), ignoreProperties, - Object.getPrototypeOf(window)); + patchFilteredProperties(w, eventNames.concat(['messageerror']), ignoreProperties, d(w)); patchFilteredProperties(Document.prototype, eventNames, ignoreProperties); - if (typeof(window)['SVGElement'] !== 'undefined') { - patchFilteredProperties( - (window)['SVGElement'].prototype, eventNames, ignoreProperties); + if (typeof w['SVGElement'] !== o) { + patchFilteredProperties(w['SVGElement'].prototype, eventNames, ignoreProperties); } patchFilteredProperties(Element.prototype, eventNames, ignoreProperties); patchFilteredProperties(HTMLElement.prototype, eventNames, ignoreProperties); @@ -292,11 +290,11 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { patchFilteredProperties(HTMLFrameElement.prototype, frameEventNames, ignoreProperties); patchFilteredProperties(HTMLIFrameElement.prototype, frameEventNames, ignoreProperties); - const HTMLMarqueeElement = (window as any)['HTMLMarqueeElement']; + const HTMLMarqueeElement = w['HTMLMarqueeElement']; if (HTMLMarqueeElement) { patchFilteredProperties(HTMLMarqueeElement.prototype, marqueeEventNames, ignoreProperties); } - const Worker = (window as any)['Worker']; + const Worker = w['Worker']; if (Worker) { patchFilteredProperties(Worker.prototype, workerEventNames, ignoreProperties); } @@ -308,7 +306,7 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype, XMLHttpRequestEventNames, ignoreProperties); } - if (typeof IDBIndex !== 'undefined') { + if (typeof IDBIndex !== o) { patchFilteredProperties(IDBIndex.prototype, IDBIndexEventNames, ignoreProperties); patchFilteredProperties(IDBRequest.prototype, IDBIndexEventNames, ignoreProperties); patchFilteredProperties(IDBOpenDBRequest.prototype, IDBIndexEventNames, ignoreProperties); @@ -330,15 +328,17 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { } function canPatchViaPropertyDescriptor() { - if ((isBrowser || isMix) && !Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'onclick') && - typeof Element !== 'undefined') { + if ((isBrowser || isMix) && !a(HTMLElement.prototype, 'onclick') && typeof Element !== o) { // WebKit https://bugs.webkit.org/show_bug.cgi?id=134364 // IDL interface attributes are not configurable - const desc = Object.getOwnPropertyDescriptor(Element.prototype, 'onclick'); + const desc = a(Element.prototype, 'onclick'); if (desc && !desc.configurable) return false; } - const xhrDesc = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, 'onreadystatechange'); + const ON_READY_STATE_CHANGE = 'onreadystatechange'; + const XMLHttpRequestPrototype = XMLHttpRequest.prototype; + + const xhrDesc = a(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE); // add enumerable and configurable here because in opera // by default XMLHttpRequest.prototype.onreadystatechange is undefined @@ -347,7 +347,7 @@ function canPatchViaPropertyDescriptor() { // and if XMLHttpRequest.prototype.onreadystatechange is undefined, // we should set a real desc instead a fake one if (xhrDesc) { - Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', { + b(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, { enumerable: true, configurable: true, get: function() { @@ -357,11 +357,11 @@ function canPatchViaPropertyDescriptor() { const req = new XMLHttpRequest(); const result = !!req.onreadystatechange; // restore original desc - Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', xhrDesc || {}); + b(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, xhrDesc || {}); return result; } else { - const SYMBOL_FAKE_ONREADYSTATECHANGE = zoneSymbol('fakeonreadystatechange'); - Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', { + const SYMBOL_FAKE_ONREADYSTATECHANGE = zoneSymbol('fake'); + b(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, { enumerable: true, configurable: true, get: function() { @@ -398,7 +398,7 @@ function patchViaCapturingAllTheEvents() { } while (elt) { if (elt[onproperty] && !elt[onproperty][unboundKey]) { - bound = Zone.current.wrap(elt[onproperty], source); + bound = (Zone as any).c.w(elt[onproperty], source); bound[unboundKey] = elt[onproperty]; elt[onproperty] = bound; } diff --git a/lib/browser/register-element.ts b/lib/browser/register-element.ts index 0f6f9a49a..74e1ccd05 100644 --- a/lib/browser/register-element.ts +++ b/lib/browser/register-element.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {attachOriginToPatched, isBrowser, isMix} from '../common/utils'; +import {a, attachOriginToPatched, isBrowser, isMix} from '../common/utils'; import {_redefineProperty} from './define-property'; @@ -23,16 +23,17 @@ export function registerElementPatch(_global: any) { if (opts && opts.prototype) { callbacks.forEach(function(callback) { const source = 'Document.registerElement::' + callback; - if (opts.prototype.hasOwnProperty(callback)) { - const descriptor = Object.getOwnPropertyDescriptor(opts.prototype, callback); + const p = opts.prototype; + if (p.hasOwnProperty(callback)) { + const descriptor = a(p, callback); if (descriptor && descriptor.value) { - descriptor.value = Zone.current.wrap(descriptor.value, source); + descriptor.value = (Zone as any).c.w(descriptor.value, source); _redefineProperty(opts.prototype, callback, descriptor); } else { - opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source); + p[callback] = (Zone as any).c.w(p[callback], source); } - } else if (opts.prototype[callback]) { - opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source); + } else if (p[callback]) { + p[callback] = (Zone as any).c.w(p[callback], source); } }); } diff --git a/lib/browser/shadydom.ts b/lib/browser/shadydom.ts index 2a0173a84..d02590204 100644 --- a/lib/browser/shadydom.ts +++ b/lib/browser/shadydom.ts @@ -5,7 +5,7 @@ * 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 */ -Zone.__load_patch('shadydom', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('shadydom', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // https://github.com/angular/zone.js/issues/782 // in web components, shadydom will patch addEventListener/removeEventListener of // Node.prototype and WindowPrototype, this will have conflict with zone.js @@ -21,4 +21,4 @@ Zone.__load_patch('shadydom', (global: any, Zone: ZoneType, api: _ZonePrivate) = (Node.prototype as any)[Zone.__symbol__('removeEventListener')] = null; api.patchEventTarget(global, [Node.prototype]); } -}); \ No newline at end of file +}); diff --git a/lib/browser/webapis-media-query.ts b/lib/browser/webapis-media-query.ts index d1fcd53d8..b26831327 100644 --- a/lib/browser/webapis-media-query.ts +++ b/lib/browser/webapis-media-query.ts @@ -5,11 +5,10 @@ * 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 */ -Zone.__load_patch('mediaQuery', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('mediaQuery', (global: any, Zone: ZoneType, api: _ZonePrivate) => { if (!global['MediaQueryList']) { return; } api.patchEventTarget( - global, [global['MediaQueryList'].prototype], - {addEventListenerFnName: 'addListener', removeEventListenerFnName: 'removeListener'}); -}); \ No newline at end of file + global, [global['MediaQueryList'].prototype], {add: 'addListener', rm: 'removeListener'}); +}); diff --git a/lib/browser/webapis-notification.ts b/lib/browser/webapis-notification.ts index 1bccaa9c9..b714b3830 100644 --- a/lib/browser/webapis-notification.ts +++ b/lib/browser/webapis-notification.ts @@ -5,7 +5,7 @@ * 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 */ -Zone.__load_patch('notification', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('notification', (global: any, Zone: ZoneType, api: _ZonePrivate) => { const Notification = global['Notification']; if (!Notification || !Notification.prototype) { return; @@ -15,4 +15,4 @@ Zone.__load_patch('notification', (global: any, Zone: ZoneType, api: _ZonePrivat return; } api.patchOnProperties(Notification.prototype, null); -}); \ No newline at end of file +}); diff --git a/lib/browser/webapis-rtc-peer-connection.ts b/lib/browser/webapis-rtc-peer-connection.ts index 2551ae234..666b4482d 100644 --- a/lib/browser/webapis-rtc-peer-connection.ts +++ b/lib/browser/webapis-rtc-peer-connection.ts @@ -5,7 +5,7 @@ * 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 */ -Zone.__load_patch('RTCPeerConnection', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('RTCPeerConnection', (global: any, Zone: ZoneType, api: _ZonePrivate) => { const RTCPeerConnection = global['RTCPeerConnection']; if (!RTCPeerConnection) { return; @@ -22,5 +22,5 @@ Zone.__load_patch('RTCPeerConnection', (global: any, Zone: ZoneType, api: _ZoneP RTCPeerConnection.prototype[addSymbol] = null; RTCPeerConnection.prototype[removeSymbol] = null; - api.patchEventTarget(global, [RTCPeerConnection.prototype], {useGlobalCallback: false}); + api.patchEventTarget(global, [RTCPeerConnection.prototype], {useG: false}); }); diff --git a/lib/browser/webapis-user-media.ts b/lib/browser/webapis-user-media.ts new file mode 100644 index 000000000..f93085a83 --- /dev/null +++ b/lib/browser/webapis-user-media.ts @@ -0,0 +1,20 @@ +/** + * @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 + */ +(Zone as any).l('getUserMedia', (global: any, Zone: any, api: _ZonePrivate) => { + function wrapFunctionArgs(func: Function, source?: string): Function { + return function() { + const args = Array.prototype.slice.call(arguments); + const wrappedArgs = api.bindArguments(args, source ? source : (func as any).name); + return func.apply(this, wrappedArgs); + }; + } + let navigator = global['navigator']; + if (navigator && navigator.getUserMedia) { + navigator.getUserMedia = wrapFunctionArgs(navigator.getUserMedia); + } +}); diff --git a/lib/browser/websocket.ts b/lib/browser/websocket.ts index d9f3354c9..5714b6c77 100644 --- a/lib/browser/websocket.ts +++ b/lib/browser/websocket.ts @@ -7,7 +7,7 @@ */ import {patchEventTarget} from '../common/events'; -import {patchOnProperties} from '../common/utils'; +import {a, e, f, g, h, patchOnProperties} from '../common/utils'; // we have to patch the instance since the proto is non-configurable export function apply(api: _ZonePrivate, _global: any) { @@ -17,27 +17,27 @@ export function apply(api: _ZonePrivate, _global: any) { if (!(_global).EventTarget) { patchEventTarget(_global, [WS.prototype]); } - (_global).WebSocket = function(a: any, b: any) { - const socket = arguments.length > 1 ? new WS(a, b) : new WS(a); + (_global).WebSocket = function(x: any, y: any) { + const socket = arguments.length > 1 ? new WS(x, y) : new WS(x); let proxySocket: any; let proxySocketProto: any; // Safari 7.0 has non-configurable own 'onmessage' and friends properties on the socket instance - const onmessageDesc = Object.getOwnPropertyDescriptor(socket, 'onmessage'); + const onmessageDesc = a(socket, 'onmessage'); if (onmessageDesc && onmessageDesc.configurable === false) { - proxySocket = Object.create(socket); + proxySocket = e(socket); // socket have own property descriptor 'onopen', 'onmessage', 'onclose', 'onerror' // but proxySocket not, so we will keep socket as prototype and pass it to // patchOnProperties method proxySocketProto = socket; - ['addEventListener', 'removeEventListener', 'send', 'close'].forEach(function(propName) { + [g, h, 'send', 'close'].forEach(function(propName) { proxySocket[propName] = function() { - const args = Array.prototype.slice.call(arguments); - if (propName === 'addEventListener' || propName === 'removeEventListener') { + const args = f.call(arguments); + if (propName === g || propName === h) { const eventName = args.length > 0 ? args[0] : undefined; if (eventName) { - const propertySymbol = Zone.__symbol__('ON_PROPERTY' + eventName); + const propertySymbol = (Zone as any).s('ON_PROPERTY' + eventName); socket[propertySymbol] = proxySocket[propertySymbol]; } } diff --git a/lib/common/events.ts b/lib/common/events.ts index c5424a782..5b349ab75 100644 --- a/lib/common/events.ts +++ b/lib/common/events.ts @@ -10,56 +10,56 @@ * @suppress {missingRequire} */ -import {attachOriginToPatched, zoneSymbol} from './utils'; +import {attachOriginToPatched, d, g, h, k, l, m, n, p, zoneSymbol} from './utils'; -export const TRUE_STR = 'true'; -export const FALSE_STR = 'false'; - -export interface EventTaskData extends TaskData { readonly isUsingGlobalCallback?: boolean; } +/** @internal **/ +interface EventTaskData extends TaskData { + // use global callback or not + readonly useG?: boolean; +} // an identifier to tell ZoneTask do not create a new invoke closure -export const OPTIMIZED_ZONE_EVENT_TASK_DATA: EventTaskData = { - isUsingGlobalCallback: true +const OPTIMIZED_ZONE_EVENT_TASK_DATA: EventTaskData = { + useG: true }; -export const zoneSymbolEventNames: any = {}; -export const globalSources: any = {}; - -export const CONSTRUCTOR_NAME = 'name'; - -export const FUNCTION_TYPE = 'function'; -export const OBJECT_TYPE = 'object'; - -export const ZONE_SYMBOL_PREFIX = '__zone_symbol__'; +export const ens: any = {}; +export const gs: any = {}; const EVENT_NAME_SYMBOL_REGX = /^__zone_symbol__(\w+)(true|false)$/; - const IMMEDIATE_PROPAGATION_SYMBOL = ('__zone_symbol__propagationStopped'); export interface PatchEventTargetOptions { - validateHandler?: (nativeDelegate: any, delegate: any, target: any, args: any) => boolean; - addEventListenerFnName?: string; - removeEventListenerFnName?: string; - prependEventListenerFnName?: string; - listenersFnName?: string; - removeAllFnName?: string; - useGlobalCallback?: boolean; - checkDuplicate?: boolean; - returnTarget?: boolean; - compareTaskCallbackVsDelegate?: (task: any, delegate: any) => boolean; + // validateHandler + vh?: (nativeDelegate: any, delegate: any, target: any, args: any) => boolean; + // addEventListener function name + add?: string; + // removeEventListener function name + rm?: string; + // prependEventListener function name + prepend?: string; + // listeners function name + listeners?: string; + // removeAllListeners function name + rmAll?: string; + // useGlobalCallback flag + useG?: boolean; + // check duplicate flag when addEventListener + chkDup?: boolean; + // return target flag when addEventListener + rt?: boolean; + // event compare handler + diff?: (task: any, delegate: any) => boolean; } export function patchEventTarget( _global: any, apis: any[], patchOptions?: PatchEventTargetOptions) { - const ADD_EVENT_LISTENER = - (patchOptions && patchOptions.addEventListenerFnName) || 'addEventListener'; - const REMOVE_EVENT_LISTENER = - (patchOptions && patchOptions.removeEventListenerFnName) || 'removeEventListener'; + const ADD_EVENT_LISTENER = (patchOptions && patchOptions.add) || g; + const REMOVE_EVENT_LISTENER = (patchOptions && patchOptions.rm) || h; - const LISTENERS_EVENT_LISTENER = - (patchOptions && patchOptions.listenersFnName) || 'eventListeners'; + const LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.listeners) || 'eventListeners'; const REMOVE_ALL_LISTENERS_EVENT_LISTENER = - (patchOptions && patchOptions.removeAllFnName) || 'removeAllListeners'; + (patchOptions && patchOptions.rmAll) || 'removeAllListeners'; const zoneSymbolAddEventListener = zoneSymbol(ADD_EVENT_LISTENER); @@ -75,7 +75,7 @@ export function patchEventTarget( return; } const delegate = task.callback; - if (typeof delegate === OBJECT_TYPE && delegate.handleEvent) { + if (typeof delegate === p && delegate.handleEvent) { // create the bind version of handleEvent when invoke task.callback = (event: Event) => delegate.handleEvent(event); task.originalDelegate = delegate; @@ -83,7 +83,7 @@ export function patchEventTarget( // invoke static task.invoke task.invoke(task, target, [event]); const options = task.options; - if (options && typeof options === 'object' && options.once) { + if (options && typeof options === p && options.once) { // if options.once is true, after invoke once remove listener here // only browser need to do this, nodejs eventEmitter will cal removeListener // inside EventEmitter.once @@ -103,7 +103,7 @@ export function patchEventTarget( // event.target is needed for Samusung TV and SourceBuffer // || global is needed https://github.com/angular/zone.js/issues/190 const target: any = this || event.target || _global; - const tasks = target[zoneSymbolEventNames[event.type][FALSE_STR]]; + const tasks = target[ens[event.type][l]]; if (tasks) { // invoke all tasks which attached to current target with given event.type and capture = false // for performance concern, if task.length === 1, just invoke @@ -135,7 +135,7 @@ export function patchEventTarget( // event.target is needed for Samusung TV and SourceBuffer // || global is needed https://github.com/angular/zone.js/issues/190 const target: any = this || event.target || _global; - const tasks = target[zoneSymbolEventNames[event.type][TRUE_STR]]; + const tasks = target[ens[event.type][k]]; if (tasks) { // invoke all tasks which attached to current target with given event.type and capture = false // for performance concern, if task.length === 1, just invoke @@ -162,24 +162,24 @@ export function patchEventTarget( } let useGlobalCallback = true; - if (patchOptions && patchOptions.useGlobalCallback !== undefined) { - useGlobalCallback = patchOptions.useGlobalCallback; + if (patchOptions && patchOptions.useG !== undefined) { + useGlobalCallback = patchOptions.useG; } - const validateHandler = patchOptions && patchOptions.validateHandler; + const validateHandler = patchOptions && patchOptions.vh; let checkDuplicate = true; - if (patchOptions && patchOptions.checkDuplicate !== undefined) { - checkDuplicate = patchOptions.checkDuplicate; + if (patchOptions && patchOptions.chkDup !== undefined) { + checkDuplicate = patchOptions.chkDup; } let returnTarget = false; - if (patchOptions && patchOptions.returnTarget !== undefined) { - returnTarget = patchOptions.returnTarget; + if (patchOptions && patchOptions.rt !== undefined) { + returnTarget = patchOptions.rt; } let proto = obj; while (proto && !proto.hasOwnProperty(ADD_EVENT_LISTENER)) { - proto = Object.getPrototypeOf(proto); + proto = d(proto); } if (!proto && obj[ADD_EVENT_LISTENER]) { // somehow we did not find it, but we can see it. This happens on IE for Window properties. @@ -207,9 +207,9 @@ export function patchEventTarget( proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER]; let nativePrependEventListener: any; - if (patchOptions && patchOptions.prependEventListenerFnName) { - nativePrependEventListener = proto[zoneSymbol(patchOptions.prependEventListenerFnName)] = - proto[patchOptions.prependEventListenerFnName]; + if (patchOptions && patchOptions.prepend) { + nativePrependEventListener = proto[zoneSymbol(patchOptions.prepend)] = + proto[patchOptions.prepend]; } const customScheduleGlobal = function(task: Task) { @@ -230,10 +230,10 @@ export function patchEventTarget( // from Zone.prototype.cancelTask, we should remove the task // from tasksList of target first if (!task.isRemoved) { - const symbolEventNames = zoneSymbolEventNames[task.eventName]; + const symbolEventNames = ens[task.eventName]; let symbolEventName; if (symbolEventNames) { - symbolEventName = symbolEventNames[task.capture ? TRUE_STR : FALSE_STR]; + symbolEventName = symbolEventNames[task.capture ? k : l]; } const existingTasks = symbolEventName && task.target[symbolEventName]; if (existingTasks) { @@ -286,26 +286,24 @@ export function patchEventTarget( const compareTaskCallbackVsDelegate = function(task: any, delegate: any) { const typeOfDelegate = typeof delegate; - if ((typeOfDelegate === FUNCTION_TYPE && task.callback === delegate) || - (typeOfDelegate === OBJECT_TYPE && task.originalDelegate === delegate)) { + if ((typeOfDelegate === n && task.callback === delegate) || + (typeOfDelegate === p && task.originalDelegate === delegate)) { // same callback, same capture, same event name, just return return true; } return false; }; - const compare = (patchOptions && patchOptions.compareTaskCallbackVsDelegate) ? - patchOptions.compareTaskCallbackVsDelegate : - compareTaskCallbackVsDelegate; + const compare = + (patchOptions && patchOptions.diff) ? patchOptions.diff : compareTaskCallbackVsDelegate; - const blackListedEvents: string[] = (Zone as any)[Zone.__symbol__('BLACK_LISTED_EVENTS')]; + const blackListedEvents: string[] = (Zone as any)[(Zone as any).s('BLACK_LISTED_EVENTS')]; const makeAddListener = function( nativeListener: any, addSource: string, customScheduleFn: any, customCancelFn: any, returnTarget = false, prepend = false) { return function() { const target = this || _global; - const targetZone = Zone.current; let delegate = arguments[1]; if (!delegate) { return nativeListener.apply(this, arguments); @@ -315,7 +313,7 @@ export function patchEventTarget( // case here to improve addEventListener performance // we will create the bind delegate when invoke let isHandleEvent = false; - if (typeof delegate !== FUNCTION_TYPE) { + if (typeof delegate !== n) { if (!delegate.handleEvent) { return nativeListener.apply(this, arguments); } @@ -351,21 +349,21 @@ export function patchEventTarget( once = options ? !!options.once : false; } - const zone = Zone.current; - const symbolEventNames = zoneSymbolEventNames[eventName]; + const zone = (Zone as any).c; + const symbolEventNames = ens[eventName]; let symbolEventName; if (!symbolEventNames) { // the code is duplicate, but I just want to get some better performance - const falseEventName = eventName + FALSE_STR; - const trueEventName = eventName + TRUE_STR; - const symbol = ZONE_SYMBOL_PREFIX + falseEventName; - const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName; - zoneSymbolEventNames[eventName] = {}; - zoneSymbolEventNames[eventName][FALSE_STR] = symbol; - zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture; + const falseEventName = eventName + l; + const trueEventName = eventName + k; + const symbol = m + falseEventName; + const symbolCapture = m + trueEventName; + ens[eventName] = {}; + ens[eventName][l] = symbol; + ens[eventName][k] = symbolCapture; symbolEventName = capture ? symbolCapture : symbol; } else { - symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR]; + symbolEventName = symbolEventNames[capture ? k : l]; } let existingTasks = target[symbolEventName]; let isExisting = false; @@ -384,8 +382,8 @@ export function patchEventTarget( existingTasks = target[symbolEventName] = []; } let source; - const constructorName = target.constructor[CONSTRUCTOR_NAME]; - const targetSource = globalSources[constructorName]; + const constructorName = target.constructor['name']; + const targetSource = gs[constructorName]; if (targetSource) { source = targetSource[eventName]; } @@ -414,7 +412,7 @@ export function patchEventTarget( } const task: any = - zone.scheduleEventTask(source, delegate, data, customScheduleFn, customCancelFn); + (zone as any).se(source, delegate, data, customScheduleFn, customCancelFn); // should clear taskData.target to avoid memory leak // issue, https://github.com/angular/angular/issues/20442 @@ -485,10 +483,10 @@ export function patchEventTarget( return; } - const symbolEventNames = zoneSymbolEventNames[eventName]; + const symbolEventNames = ens[eventName]; let symbolEventName; if (symbolEventNames) { - symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR]; + symbolEventName = symbolEventNames[capture ? k : l]; } const existingTasks = symbolEventName && target[symbolEventName]; if (existingTasks) { @@ -505,7 +503,7 @@ export function patchEventTarget( (existingTask as any).allRemoved = true; target[symbolEventName] = null; } - existingTask.zone.cancelTask(existingTask); + (existingTask.zone as any).ct(existingTask); return; } } @@ -553,10 +551,10 @@ export function patchEventTarget( // remove removeListener listener finally this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].apply(this, ['removeListener']); } else { - const symbolEventNames = zoneSymbolEventNames[eventName]; + const symbolEventNames = ens[eventName]; if (symbolEventNames) { - const symbolEventName = symbolEventNames[FALSE_STR]; - const symbolCaptureEventName = symbolEventNames[TRUE_STR]; + const symbolEventName = symbolEventNames[l]; + const symbolCaptureEventName = symbolEventNames[k]; const tasks = target[symbolEventName]; const captureTasks = target[symbolCaptureEventName]; diff --git a/lib/common/promise.ts b/lib/common/promise.ts index 7d0484f4a..c9a7a0ddf 100644 --- a/lib/common/promise.ts +++ b/lib/common/promise.ts @@ -5,7 +5,12 @@ * 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 */ -Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePrivate) => { + const a = Object.getOwnPropertyDescriptor; + const b = Object.defineProperty; + const n = 'function'; + const p = 'object'; + function readableObjectToString(obj: any) { if (obj && obj.toString === Object.prototype.toString) { const className = obj.constructor && obj.constructor.name; @@ -48,7 +53,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr while (_uncaughtPromiseErrors.length) { const uncaughtPromiseError: UncaughtPromiseError = _uncaughtPromiseErrors.shift(); try { - uncaughtPromiseError.zone.runGuarded(() => { + (uncaughtPromiseError.zone as any).rg(() => { throw uncaughtPromiseError; }); } catch (error) { @@ -64,7 +69,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr api.onUnhandledError(e); try { const handler = (Zone as any)[UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL]; - if (handler && typeof handler === 'function') { + if (handler && typeof handler === n) { handler.apply(this, [e]); } } catch (err) { @@ -117,8 +122,6 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr }; const TYPE_ERROR = 'Promise resolved with itself'; - const OBJECT = 'object'; - const FUNCTION = 'function'; const CURRENT_TASK_TRACE_SYMBOL = __symbol__('currentTaskTrace'); // Promise Resolution @@ -132,7 +135,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr // should only get value.then once based on promise spec. let then: any = null; try { - if (typeof value === OBJECT || typeof value === FUNCTION) { + if (typeof value === p || typeof value === n) { then = value && value.then; } } catch (err) { @@ -147,7 +150,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr (value as any)[symbolState] !== UNRESOLVED) { clearRejectedNoCatch(>value); resolvePromise(promise, (value as any)[symbolState], (value as any)[symbolValue]); - } else if (state !== REJECTED && typeof then === FUNCTION) { + } else if (state !== REJECTED && typeof then === n) { try { then.apply(value, [ onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false)) @@ -170,9 +173,8 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr (Zone.currentTask.data as any)[creationTrace]; if (trace) { // only keep the long stack trace into error when in longStackTraceZone - Object.defineProperty( - value, CURRENT_TASK_TRACE_SYMBOL, - {configurable: true, enumerable: false, writable: true, value: trace}); + b(value, CURRENT_TASK_TRACE_SYMBOL, + {configurable: true, enumerable: false, writable: true, value: trace}); } } @@ -190,7 +192,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr const error: UncaughtPromiseError = err; error.rejection = value; error.promise = promise; - error.zone = Zone.current; + error.zone = (Zone as any).c; error.task = Zone.currentTask; _uncaughtPromiseErrors.push(error); api.scheduleMicroTask(); // to make sure that it is running @@ -212,7 +214,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr // eventHandler try { const handler = (Zone as any)[REJECTION_HANDLED_HANDLER]; - if (handler && typeof handler === FUNCTION) { + if (handler && typeof handler === n) { handler.apply(this, [{rejection: (promise as any)[symbolValue], promise: promise}]); } } catch (err) { @@ -231,12 +233,13 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr onFulfilled?: (value: R) => U1, onRejected?: (error: any) => U2): void { clearRejectedNoCatch(promise); const delegate = (promise as any)[symbolState] ? - (typeof onFulfilled === FUNCTION) ? onFulfilled : forwardResolution : - (typeof onRejected === FUNCTION) ? onRejected : forwardRejection; - zone.scheduleMicroTask(source, () => { + (typeof onFulfilled === n) ? onFulfilled : forwardResolution : + (typeof onRejected === n) ? onRejected : forwardRejection; + (zone as any).si(source, () => { try { resolvePromise( - chainPromise, true, zone.run(delegate, undefined, [(promise as any)[symbolValue]])); + chainPromise, true, + (zone as any).r(delegate, undefined, [(promise as any)[symbolValue]])); } catch (error) { resolvePromise(chainPromise, false, error); } @@ -331,7 +334,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr null): Promise { const chainPromise: Promise = new (this.constructor as typeof ZoneAwarePromise)(null); - const zone = Zone.current; + const zone = (Zone as any).c; if ((this as any)[symbolState] == UNRESOLVED) { ((this as any)[symbolValue]).push(zone, chainPromise, onFulfilled, onRejected); } else { @@ -353,9 +356,9 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr ZoneAwarePromise['all'] = ZoneAwarePromise.all; const NativePromise = global[symbolPromise] = global['Promise']; - const ZONE_AWARE_PROMISE = Zone.__symbol__('ZoneAwarePromise'); + const ZONE_AWARE_PROMISE = (Zone as any).s('ZoneAwarePromise'); - let desc = Object.getOwnPropertyDescriptor(global, 'Promise'); + let desc = a(global, 'Promise'); if (!desc || desc.configurable) { desc && delete desc.writable; desc && delete desc.value; @@ -388,7 +391,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr } }; - Object.defineProperty(global, 'Promise', desc); + b(global, 'Promise', desc); } global['Promise'] = ZoneAwarePromise; @@ -403,9 +406,9 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr // check Ctor.prototype.then propertyDescritor is writable or not // in meteor env, writable is false, we have to make it to be true. - const prop = Object.getOwnPropertyDescriptor(Ctor.prototype, 'then'); + const prop = a(Ctor.prototype, 'then'); if (prop && prop.writable === false && prop.configurable) { - Object.defineProperty(Ctor.prototype, 'then', {writable: true}); + b(Ctor.prototype, 'then', {writable: true}); } Ctor.prototype.then = function(onResolve: any, onReject: any) { @@ -435,12 +438,12 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr patchThen(NativePromise); let fetch = global['fetch']; - if (typeof fetch == FUNCTION) { + if (typeof fetch == n) { global['fetch'] = zoneify(fetch); } } // This is not part of public API, but it is useful for tests, so we expose it. - (Promise as any)[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; + (Promise as any)[(Zone as any).s('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; return ZoneAwarePromise; }); diff --git a/lib/common/timers.ts b/lib/common/timers.ts index 5f8d9aa1e..82266f0ad 100644 --- a/lib/common/timers.ts +++ b/lib/common/timers.ts @@ -10,7 +10,7 @@ * @suppress {missingRequire} */ -import {patchMethod, zoneSymbol} from './utils'; +import {n, patchMethod, q, r, zoneSymbol} from './utils'; const taskSymbol = zoneSymbol('zoneTask'); @@ -26,12 +26,6 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam cancelName += nameSuffix; const tasksByHandleId: {[id: number]: Task} = {}; - const NUMBER = 'number'; - const STRING = 'string'; - const FUNCTION = 'function'; - const INTERVAL = 'Interval'; - const TIMEOUT = 'Timeout'; - const NOT_SCHEDULED = 'notScheduled'; function scheduleTask(task: Task) { const data = task.data; @@ -45,7 +39,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam // setInterval return; } - if (typeof data.handleId === NUMBER) { + if (typeof data.handleId === q) { // in non-nodejs env, we remove timerId // from local cache delete tasksByHandleId[data.handleId]; @@ -67,21 +61,21 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam setNative = patchMethod(window, setName, (delegate: Function) => function(self: any, args: any[]) { - if (typeof args[0] === FUNCTION) { - const zone = Zone.current; + if (typeof args[0] === n) { + const zone = (Zone as any).c; const options: TimerOptions = { handleId: null, - isPeriodic: nameSuffix === INTERVAL, - delay: (nameSuffix === TIMEOUT || nameSuffix === INTERVAL) ? args[1] || 0 : null, + isPeriodic: nameSuffix === 'Interval', + delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 : null, args: args }; - const task = zone.scheduleMacroTask(setName, args[0], options, scheduleTask, clearTask); + const task = (zone as any).sc(setName, args[0], options, scheduleTask, clearTask); if (!task) { return task; } // Node.js must additionally support the ref and unref functions. const handle: any = (task.data).handleId; - if (typeof handle === NUMBER) { + if (typeof handle === q) { // for non nodejs env, we save handleId: task // mapping in local cache for clearTimeout tasksByHandleId[handle] = task; @@ -93,12 +87,12 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam // check whether handle is null, because some polyfill or browser // may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame - if (handle && handle.ref && handle.unref && typeof handle.ref === FUNCTION && - typeof handle.unref === FUNCTION) { + if (handle && handle.ref && handle.unref && typeof handle.ref === n && + typeof handle.unref === n) { (task).ref = (handle).ref.bind(handle); (task).unref = (handle).unref.bind(handle); } - if (typeof handle === NUMBER || handle) { + if (typeof handle === q || handle) { return handle; } return task; @@ -112,7 +106,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam patchMethod(window, cancelName, (delegate: Function) => function(self: any, args: any[]) { const id = args[0]; let task: Task; - if (typeof id === NUMBER) { + if (typeof id === q) { // non nodejs env. task = tasksByHandleId[id]; } else { @@ -123,16 +117,16 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam task = id; } } - if (task && typeof task.type === STRING) { - if (task.state !== NOT_SCHEDULED && + if (task && typeof task.type === r) { + if (task.state !== 'notScheduled' && (task.cancelFn && task.data.isPeriodic || task.runCount === 0)) { - if (typeof id === NUMBER) { + if (typeof id === q) { delete tasksByHandleId[id]; } else if (id) { id[taskSymbol] = null; } // Do not cancel already canceled functions - task.zone.cancelTask(task); + (task.zone as any).ct(task); } } else { // cause an error by calling it directly. diff --git a/lib/common/to-string.ts b/lib/common/to-string.ts index 9e7d7fe71..0499f6016 100644 --- a/lib/common/to-string.ts +++ b/lib/common/to-string.ts @@ -5,24 +5,23 @@ * 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 */ -import {zoneSymbol} from './utils'; +import {n, zoneSymbol} from './utils'; // override Function.prototype.toString to make zone.js patched function // look like native function -Zone.__load_patch('toString', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('toString', (global: any, Zone: ZoneType) => { // patch Func.prototype.toString to let them look like native const originalFunctionToString = (Zone as any)['__zone_symbol__originalToString'] = Function.prototype.toString; - const FUNCTION = 'function'; const ORIGINAL_DELEGATE_SYMBOL = zoneSymbol('OriginalDelegate'); const PROMISE_SYMBOL = zoneSymbol('Promise'); const ERROR_SYMBOL = zoneSymbol('Error'); Function.prototype.toString = function() { - if (typeof this === FUNCTION) { + if (typeof this === n) { const originalDelegate = this[ORIGINAL_DELEGATE_SYMBOL]; if (originalDelegate) { - if (typeof originalDelegate === FUNCTION) { + if (typeof originalDelegate === n) { return originalFunctionToString.apply(this[ORIGINAL_DELEGATE_SYMBOL], arguments); } else { return Object.prototype.toString.call(originalDelegate); diff --git a/lib/common/utils.ts b/lib/common/utils.ts index 938935f77..b792439a1 100644 --- a/lib/common/utils.ts +++ b/lib/common/utils.ts @@ -11,50 +11,51 @@ * @suppress {undefinedVars,globalThis,missingRequire} */ +// issue #989, to reduce bundle size, use short name +export const a = Object.getOwnPropertyDescriptor; +export const b = Object.defineProperty; +export const c = Object.defineProperties; +export const d = Object.getPrototypeOf; +export const e = Object.create; +export const f = Array.prototype.slice; +export const g = 'addEventListener'; +export const h = 'removeEventListener'; +export const i = (Zone as any).s(g); +export const j = (Zone as any).s(h); +export const k = 'true'; +export const l = 'false'; +export const m = '__zone_symbol__'; +export const n = 'function'; +export const o = 'undefined'; +export const p = 'object'; +export const q = 'number'; +export const r = 'string'; + // Hack since TypeScript isn't compiling this for a worker. declare const WorkerGlobalScope: any; export const zoneSymbol = Zone.__symbol__; -const _global: any = - typeof window === 'object' && window || typeof self === 'object' && self || global; +const _global: any = typeof window === p && window || typeof self === p && self || global; -const FUNCTION = 'function'; -const UNDEFINED = 'undefined'; const REMOVE_ATTRIBUTE = 'removeAttribute'; const NULL_ON_PROP_VALUE: any[] = [null]; export function bindArguments(args: any[], source: string): any[] { for (let i = args.length - 1; i >= 0; i--) { - if (typeof args[i] === FUNCTION) { - args[i] = Zone.current.wrap(args[i], source + '_' + i); + if (typeof args[i] === n) { + args[i] = (Zone as any).c.w(args[i], source + '_' + i); } } return args; } -export function wrapFunctionArgs(func: Function, source?: string): Function { - return function() { - const args = Array.prototype.slice.call(arguments); - const wrappedArgs = bindArguments(args, source ? source : (func as any).name); - return func.apply(this, wrappedArgs); - }; -} - -export function patchArguments(target: any, name: string, source: string): Function { - return patchMethod( - target, name, - (delegate: Function, delegateName: string, name: string) => (self: any, args: any[]) => { - return delegate && delegate.apply(self, bindArguments(args, source)); - }); -} - export function patchPrototype(prototype: any, fnNames: string[]) { const source = prototype.constructor['name']; for (let i = 0; i < fnNames.length; i++) { const name = fnNames[i]; const delegate = prototype[name]; if (delegate) { - const prototypeDesc = Object.getOwnPropertyDescriptor(prototype, name); + const prototypeDesc = a(prototype, name); if (!isPropertyWritable(prototypeDesc)) { continue; } @@ -78,7 +79,7 @@ export function isPropertyWritable(propertyDesc: any) { return false; } - if (typeof propertyDesc.get === FUNCTION && typeof propertyDesc.set === UNDEFINED) { + if (typeof propertyDesc.get === n && typeof propertyDesc.set === o) { return false; } @@ -86,23 +87,23 @@ export function isPropertyWritable(propertyDesc: any) { } export const isWebWorker: boolean = - (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope); + (typeof WorkerGlobalScope !== o && self instanceof WorkerGlobalScope); // Make sure to access `process` through `_global` so that WebPack does not accidently browserify // this code. export const isNode: boolean = - (!('nw' in _global) && typeof _global.process !== 'undefined' && + (!('nw' in _global) && typeof _global.process !== o && {}.toString.call(_global.process) === '[object process]'); export const isBrowser: boolean = - !isNode && !isWebWorker && !!(typeof window !== 'undefined' && (window as any)['HTMLElement']); + !isNode && !isWebWorker && !!(typeof window !== o && (window as any)['HTMLElement']); // we are in electron of nw, so we are both browser and nodejs // Make sure to access `process` through `_global` so that WebPack does not accidently browserify // this code. -export const isMix: boolean = typeof _global.process !== 'undefined' && +export const isMix: boolean = typeof _global.process !== o && {}.toString.call(_global.process) === '[object process]' && !isWebWorker && - !!(typeof window !== 'undefined' && (window as any)['HTMLElement']); + !!(typeof window !== o && (window as any)['HTMLElement']); const zoneSymbolEventNames: {[eventName: string]: string} = {}; @@ -128,10 +129,10 @@ const wrapFn = function(event: Event) { }; export function patchProperty(obj: any, prop: string, prototype?: any) { - let desc = Object.getOwnPropertyDescriptor(obj, prop); + let desc = a(obj, prop); if (!desc && prototype) { // when patch window object, use prototype to check prop exist or not - const prototypeDesc = Object.getOwnPropertyDescriptor(prototype, prop); + const prototypeDesc = a(prototype, prop); if (prototypeDesc) { desc = {enumerable: true, configurable: true}; } @@ -181,7 +182,7 @@ export function patchProperty(obj: any, prop: string, prototype?: any) { originalDescSet.apply(target, NULL_ON_PROP_VALUE); } - if (typeof newValue === 'function') { + if (typeof newValue === n) { target[eventNameSymbol] = newValue; target.addEventListener(eventName, wrapFn, false); } else { @@ -214,7 +215,7 @@ export function patchProperty(obj: any, prop: string, prototype?: any) { let value = originalDescGet && originalDescGet.apply(this); if (value) { desc.set.apply(this, [value]); - if (typeof target[REMOVE_ATTRIBUTE] === FUNCTION) { + if (typeof target[REMOVE_ATTRIBUTE] === n) { target.removeAttribute(prop); } return value; @@ -223,7 +224,7 @@ export function patchProperty(obj: any, prop: string, prototype?: any) { return null; }; - Object.defineProperty(obj, prop, desc); + b(obj, prop, desc); } export function patchOnProperties(obj: any, properties: string[], prototype?: any) { @@ -286,15 +287,15 @@ export function patchClass(className: string) { // https://bugs.webkit.org/show_bug.cgi?id=44721 if (className === 'XMLHttpRequest' && prop === 'responseBlob') continue; (function(prop) { - if (typeof instance[prop] === 'function') { + if (typeof instance[prop] === n) { _global[className].prototype[prop] = function() { return this[originalInstanceKey][prop].apply(this[originalInstanceKey], arguments); }; } else { - Object.defineProperty(_global[className].prototype, prop, { + b(_global[className].prototype, prop, { set: function(fn) { - if (typeof fn === 'function') { - this[originalInstanceKey][prop] = Zone.current.wrap(fn, className + '.' + prop); + if (typeof fn === n) { + this[originalInstanceKey][prop] = (Zone as any).c.w(fn, className + '.' + prop); // keep callback in wrapped function so we can // use it in Function.prototype.toString to return // the native one. @@ -324,7 +325,7 @@ export function patchMethod( any): Function { let proto = target; while (proto && !proto.hasOwnProperty(name)) { - proto = Object.getPrototypeOf(proto); + proto = d(proto); } if (!proto && target[name]) { // somehow we did not find it, but we can see it. This happens on IE for Window properties. @@ -337,7 +338,7 @@ export function patchMethod( delegate = proto[delegateName] = proto[name]; // check whether proto[name] is writable // some property is readonly in safari, such as HtmlCanvasElement.prototype.toBlob - const desc = proto && Object.getOwnPropertyDescriptor(proto, name); + const desc = proto && a(proto, name); if (isPropertyWritable(desc)) { const patchDelegate = patchFn(delegate, delegateName, name); proto[name] = function() { @@ -352,7 +353,7 @@ export function patchMethod( export interface MacroTaskMeta extends TaskData { name: string; target: any; - callbackIndex: number; + cbIdx: number; args: any[]; } @@ -363,7 +364,7 @@ export function patchMacroTask( function scheduleTask(task: Task) { const data = task.data; - data.args[data.callbackIndex] = function() { + data.args[data.cbIdx] = function() { task.invoke.apply(this, arguments); }; setNative.apply(data.target, data.args); @@ -372,9 +373,8 @@ export function patchMacroTask( setNative = patchMethod(obj, funcName, (delegate: Function) => function(self: any, args: any[]) { const meta = metaCreator(self, args); - if (meta.callbackIndex >= 0 && typeof args[meta.callbackIndex] === 'function') { - const task = Zone.current.scheduleMacroTask( - meta.name, args[meta.callbackIndex], meta, scheduleTask, null); + if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === n) { + const task = (Zone as any).c.sc(meta.name, args[meta.cbIdx], meta, scheduleTask, null); return task; } else { // cause an error by calling it directly. @@ -386,7 +386,7 @@ export function patchMacroTask( export interface MicroTaskMeta extends TaskData { name: string; target: any; - callbackIndex: number; + cbIdx: number; args: any[]; } @@ -396,7 +396,7 @@ export function patchMicroTask( function scheduleTask(task: Task) { const data = task.data; - data.args[data.callbackIndex] = function() { + data.args[data.cbIdx] = function() { task.invoke.apply(this, arguments); }; setNative.apply(data.target, data.args); @@ -405,9 +405,8 @@ export function patchMicroTask( setNative = patchMethod(obj, funcName, (delegate: Function) => function(self: any, args: any[]) { const meta = metaCreator(self, args); - if (meta.callbackIndex >= 0 && typeof args[meta.callbackIndex] === 'function') { - const task = - Zone.current.scheduleMicroTask(meta.name, args[meta.callbackIndex], meta, scheduleTask); + if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === n) { + const task = (Zone as any).c.si(meta.name, args[meta.cbIdx], meta, scheduleTask); return task; } else { // cause an error by calling it directly. @@ -432,7 +431,6 @@ export function isIEOrEdge() { try { const ua = window.navigator.userAgent; - const msie = ua.indexOf('MSIE '); if (ua.indexOf('MSIE ') !== -1 || ua.indexOf('Trident/') !== -1 || ua.indexOf('Edge/') !== -1) { ieOrEdge = true; } diff --git a/lib/extra/bluebird.ts b/lib/extra/bluebird.ts index 0a70f5cbf..d3f9b9cca 100644 --- a/lib/extra/bluebird.ts +++ b/lib/extra/bluebird.ts @@ -5,7 +5,7 @@ * 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 */ -Zone.__load_patch('bluebird', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('bluebird', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // TODO: @JiaLiPassion, we can automatically patch bluebird // if global.Promise = Bluebird, but sometimes in nodejs, // global.Promise is not Bluebird, and Bluebird is just be @@ -14,7 +14,7 @@ Zone.__load_patch('bluebird', (global: any, Zone: ZoneType, api: _ZonePrivate) = const BLUEBIRD = 'bluebird'; (Zone as any)[Zone.__symbol__(BLUEBIRD)] = function patchBluebird(Bluebird: any) { Bluebird.setScheduler((fn: Function) => { - Zone.current.scheduleMicroTask(BLUEBIRD, fn); + (Zone as any).c.si(BLUEBIRD, fn); }); }; -}); \ No newline at end of file +}); diff --git a/lib/extra/cordova.ts b/lib/extra/cordova.ts index 5f8518ce5..4d32a46a0 100644 --- a/lib/extra/cordova.ts +++ b/lib/extra/cordova.ts @@ -5,7 +5,7 @@ * 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 */ -Zone.__load_patch('cordova', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('cordova', (global: any, Zone: ZoneType, api: _ZonePrivate) => { if (global.cordova) { const SUCCESS_SOURCE = 'cordova.exec.success'; const ERROR_SOURCE = 'cordova.exec.error'; @@ -13,17 +13,17 @@ Zone.__load_patch('cordova', (global: any, Zone: ZoneType, api: _ZonePrivate) => const nativeExec: Function = api.patchMethod( global.cordova, 'exec', (delegate: Function) => function(self: any, args: any[]) { if (args.length > 0 && typeof args[0] === FUNCTION) { - args[0] = Zone.current.wrap(args[0], SUCCESS_SOURCE); + args[0] = (Zone as any).c.w(args[0], SUCCESS_SOURCE); } if (args.length > 1 && typeof args[1] === FUNCTION) { - args[1] = Zone.current.wrap(args[1], ERROR_SOURCE); + args[1] = (Zone as any).c.w(args[1], ERROR_SOURCE); } return nativeExec.apply(self, args); }); } }); -Zone.__load_patch('cordova.FileReader', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('cordova.FileReader', (global: any, Zone: ZoneType, api: _ZonePrivate) => { if (global.cordova && typeof global['FileReader'] !== 'undefined') { document.addEventListener('deviceReady', () => { const FileReader = global['FileReader']; @@ -38,4 +38,4 @@ Zone.__load_patch('cordova.FileReader', (global: any, Zone: ZoneType, api: _Zone }); }); } -}); \ No newline at end of file +}); diff --git a/lib/extra/electron.ts b/lib/extra/electron.ts index 7f618f48c..9ed842b21 100644 --- a/lib/extra/electron.ts +++ b/lib/extra/electron.ts @@ -5,17 +5,21 @@ * 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 */ -Zone.__load_patch('electron', (global: any, Zone: ZoneType, api: _ZonePrivate) => { - const FUNCTION = 'function'; +(Zone as any).l('electron', (global: any, Zone: ZoneType, api: _ZonePrivate) => { + function patchArguments(target: any, name: string, source: string): Function { + return api.patchMethod(target, name, (delegate: Function) => (self: any, args: any[]) => { + return delegate && delegate.apply(self, api.bindArguments(args, source)); + }); + } const {desktopCapturer, shell, CallbackRegistry} = require('electron'); // patch api in renderer process directly // desktopCapturer if (desktopCapturer) { - api.patchArguments(desktopCapturer, 'getSources', 'electron.desktopCapturer.getSources'); + patchArguments(desktopCapturer, 'getSources', 'electron.desktopCapturer.getSources'); } // shell if (shell) { - api.patchArguments(shell, 'openExternal', 'electron.shell.openExternal'); + patchArguments(shell, 'openExternal', 'electron.shell.openExternal'); } // patch api in main process through CallbackRegistry @@ -23,5 +27,5 @@ Zone.__load_patch('electron', (global: any, Zone: ZoneType, api: _ZonePrivate) = return; } - api.patchArguments(CallbackRegistry.prototype, 'add', 'CallbackRegistry.add'); -}); \ No newline at end of file + patchArguments(CallbackRegistry.prototype, 'add', 'CallbackRegistry.add'); +}); diff --git a/lib/node/events.ts b/lib/node/events.ts index 3130b93ad..223721f1d 100644 --- a/lib/node/events.ts +++ b/lib/node/events.ts @@ -6,9 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {globalSources, patchEventTarget, zoneSymbolEventNames} from '../common/events'; +import {ens, gs, patchEventTarget} from '../common/events'; -Zone.__load_patch('EventEmitter', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('EventEmitter', (global: any, Zone: ZoneType, api: _ZonePrivate) => { const callAndReturnFirstParam = (fn: (self: any, args: any[]) => any) => { return (self: any, args: any[]) => { fn(self, args); @@ -34,15 +34,15 @@ Zone.__load_patch('EventEmitter', (global: any, Zone: ZoneType, api: _ZonePrivat function patchEventEmitterMethods(obj: any) { const result = patchEventTarget(global, [obj], { - useGlobalCallback: false, - addEventListenerFnName: EE_ADD_LISTENER, - removeEventListenerFnName: EE_REMOVE_LISTENER, - prependEventListenerFnName: EE_PREPEND_LISTENER, - removeAllFnName: EE_REMOVE_ALL_LISTENER, - listenersFnName: EE_LISTENERS, - checkDuplicate: false, - returnTarget: true, - compareTaskCallbackVsDelegate: compareTaskCallbackVsDelegate + useG: false, + add: EE_ADD_LISTENER, + rm: EE_REMOVE_LISTENER, + prepend: EE_PREPEND_LISTENER, + rmAll: EE_REMOVE_ALL_LISTENER, + listeners: EE_LISTENERS, + chkDup: false, + rt: true, + diff: compareTaskCallbackVsDelegate }); if (result && result[0]) { obj[EE_ON] = obj[EE_ADD_LISTENER]; diff --git a/lib/node/fs.ts b/lib/node/fs.ts index 79de87a30..11c115436 100644 --- a/lib/node/fs.ts +++ b/lib/node/fs.ts @@ -8,7 +8,7 @@ import {patchMacroTask} from '../common/utils'; -Zone.__load_patch('fs', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('fs', (global: any, Zone: ZoneType, api: _ZonePrivate) => { let fs: any; try { fs = require('fs'); @@ -32,10 +32,10 @@ Zone.__load_patch('fs', (global: any, Zone: ZoneType, api: _ZonePrivate) => { return { name: 'fs.' + name, args: args, - callbackIndex: args.length > 0 ? args.length - 1 : -1, + cbIdx: args.length > 0 ? args.length - 1 : -1, target: self }; }); }); } -}); \ No newline at end of file +}); diff --git a/lib/node/node.ts b/lib/node/node.ts index 78111dc79..388d00195 100644 --- a/lib/node/node.ts +++ b/lib/node/node.ts @@ -11,18 +11,18 @@ import './fs'; import {findEventTasks} from '../common/events'; import {patchTimer} from '../common/timers'; -import {isMix, patchArguments, patchMacroTask, patchMethod, patchMicroTask, patchOnProperties} from '../common/utils'; +import {bindArguments, f, isMix, patchMacroTask, patchMethod, patchMicroTask, patchOnProperties} from '../common/utils'; const set = 'set'; const clear = 'clear'; -Zone.__load_patch('node_util', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('node_util', (global: any, Zone: ZoneType, api: _ZonePrivate) => { api.patchOnProperties = patchOnProperties; api.patchMethod = patchMethod; - api.patchArguments = patchArguments; + api.bindArguments = bindArguments; }); -Zone.__load_patch('node_timers', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('node_timers', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // Timers let globalUseTimeoutFromTimer = false; try { @@ -76,20 +76,20 @@ Zone.__load_patch('node_timers', (global: any, Zone: ZoneType, api: _ZonePrivate }); // patch process related methods -Zone.__load_patch('nextTick', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('nextTick', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // patch nextTick as microTask patchMicroTask(process, 'nextTick', (self: any, args: any[]) => { return { name: 'process.nextTick', args: args, - callbackIndex: (args.length > 0 && typeof args[0] === 'function') ? 0 : -1, + cbIdx: (args.length > 0 && typeof args[0] === 'function') ? 0 : -1, target: process }; }); }); -Zone.__load_patch( - 'handleUnhandledPromiseRejection', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any) + .l('handleUnhandledPromiseRejection', (global: any, Zone: ZoneType, api: _ZonePrivate) => { (Zone as any)[api.symbol('unhandledPromiseRejectionHandler')] = findProcessPromiseRejectionHandler('unhandledRejection'); @@ -116,7 +116,7 @@ Zone.__load_patch( // Crypto -Zone.__load_patch('crypto', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('crypto', (global: any, Zone: ZoneType, api: _ZonePrivate) => { let crypto: any; try { crypto = require('crypto'); @@ -131,7 +131,7 @@ Zone.__load_patch('crypto', (global: any, Zone: ZoneType, api: _ZonePrivate) => return { name: 'crypto.' + name, args: args, - callbackIndex: (args.length > 0 && typeof args[args.length - 1] === 'function') ? + cbIdx: (args.length > 0 && typeof args[args.length - 1] === 'function') ? args.length - 1 : -1, target: crypto @@ -141,15 +141,15 @@ Zone.__load_patch('crypto', (global: any, Zone: ZoneType, api: _ZonePrivate) => } }); -Zone.__load_patch('console', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +(Zone as any).l('console', (global: any, Zone: ZoneType, api: _ZonePrivate) => { const consoleMethods = ['dir', 'log', 'info', 'error', 'warn', 'assert', 'debug', 'timeEnd', 'trace']; consoleMethods.forEach((m: string) => { const originalMethod = (console as any)[Zone.__symbol__(m)] = (console as any)[m]; if (originalMethod) { (console as any)[m] = function() { - const args = Array.prototype.slice.call(arguments); - if (Zone.current === Zone.root) { + const args = f.call(arguments); + if ((Zone as any).c === Zone.root) { return originalMethod.apply(this, args); } else { return Zone.root.run(originalMethod, this, args); diff --git a/lib/rxjs/rxjs.ts b/lib/rxjs/rxjs.ts index 23d5287a9..11c116b8a 100644 --- a/lib/rxjs/rxjs.ts +++ b/lib/rxjs/rxjs.ts @@ -19,14 +19,11 @@ import {Subscriber} from 'rxjs/Subscriber'; import {Subscription} from 'rxjs/Subscription'; import {rxSubscriber} from 'rxjs/symbol/rxSubscriber'; -(Zone as any).__load_patch('rxjs', (global: any, Zone: ZoneType, api: any) => { +(Zone as any).__load_patch('rxjs', (global: any, Zone: ZoneType) => { const symbol: (symbolString: string) => string = (Zone as any).__symbol__; - const subscribeSource = 'rxjs.subscribe'; const nextSource = 'rxjs.Subscriber.next'; const errorSource = 'rxjs.Subscriber.error'; const completeSource = 'rxjs.Subscriber.complete'; - const unsubscribeSource = 'rxjs.Subscriber.unsubscribe'; - const teardownSource = 'rxjs.Subscriber.teardownLogic'; const empty = { closed: true, @@ -321,7 +318,6 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber'; } const scheduleSymbol = symbol('scheduleSymbol'); - const flushSymbol = symbol('flushSymbol'); const zoneSymbol = symbol('zone'); if (asap[scheduleSymbol]) { return; @@ -359,4 +355,4 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber'; patchObservableFactoryArgs(Observable, 'fromEventPattern'); patchMulticast(); patchImmediate(asap); -}); \ No newline at end of file +}); diff --git a/lib/zone-spec/fake-async-test.ts b/lib/zone-spec/fake-async-test.ts index 5123743a5..31f1fae35 100644 --- a/lib/zone-spec/fake-async-test.ts +++ b/lib/zone-spec/fake-async-test.ts @@ -330,7 +330,7 @@ // arguments let addtionalArgs: any[]; if (args) { - let callbackIndex = (task.data as any).callbackIndex; + let callbackIndex = (task.data as any).cbIdx; if (typeof args.length === 'number' && args.length > callbackIndex + 1) { addtionalArgs = Array.prototype.slice.call(args, callbackIndex + 1); } diff --git a/lib/zone.ts b/lib/zone.ts index 038a88e74..d65149400 100644 --- a/lib/zone.ts +++ b/lib/zone.ts @@ -327,7 +327,7 @@ interface _ZonePrivate { (target: any, name: string, patchFn: (delegate: Function, delegateName: string, name: string) => (self: any, args: any[]) => any) => Function; - patchArguments: (target: any, name: string, source: string) => Function; + bindArguments: (args: any[], source: string) => any[]; } /** @internal */ @@ -656,7 +656,7 @@ const Zone: ZoneType = (function(global: any) { } static get root(): AmbientZone { - let zone = Zone.current; + let zone = Zone.c; while (zone.parent) { zone = zone.parent; } @@ -667,6 +667,10 @@ const Zone: ZoneType = (function(global: any) { return _currentZoneFrame.zone; } + static get c(): AmbientZone { + return _currentZoneFrame.zone; + } + static get currentTask(): Task { return _currentTask; } @@ -1167,7 +1171,8 @@ const Zone: ZoneType = (function(global: any) { this.cancelFn = cancelFn; this.callback = callback; const self = this; - if (type === eventTask && options && (options as any).isUsingGlobalCallback) { + // TODO: @JiaLiPassion options should have interface + if (type === eventTask && options && (options as any).useG) { this.invoke = ZoneTask.invokeTask; } else { this.invoke = function() { @@ -1318,7 +1323,7 @@ const Zone: ZoneType = (function(global: any) { patchEventTarget: () => [], patchOnProperties: noop, patchMethod: () => noop, - patchArguments: () => noop, + bindArguments: () => null, setNativePromise: (NativePromise: any) => { // sometimes NativePromise.resolve static function // is not ready yet, (such as core-js/es6.promise) @@ -1338,7 +1343,19 @@ const Zone: ZoneType = (function(global: any) { return '__zone_symbol__' + name; } - performanceMeasure('Zone', 'Zone'); + const z: any = Zone.prototype; + z.w = z.wrap; + z.f = z.fork; + z.r = z.run; + z.rg = z.runGuarded; + z.rt = z.runTask; + z.st = z.scheduleTask; + z.sc = z.scheduleMacroTask; + z.si = z.scheduleMicroTask; + z.se = z.scheduleEventTask; + z.ct = z.cancelTask; + (Zone as any).l = Zone.__load_patch; + (Zone as any).s = Zone.__symbol__; return global['Zone'] = Zone; })(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global); diff --git a/test/browser-zone-setup.ts b/test/browser-zone-setup.ts index 1c16e96a8..bdefeff31 100644 --- a/test/browser-zone-setup.ts +++ b/test/browser-zone-setup.ts @@ -10,6 +10,7 @@ if (typeof window !== 'undefined') { } import '../lib/common/to-string'; import '../lib/browser/browser'; +import '../lib/browser/webapis-user-media'; import '../lib/zone-spec/async-test'; import '../lib/zone-spec/fake-async-test'; import '../lib/zone-spec/long-stack-trace'; @@ -17,4 +18,4 @@ import '../lib/zone-spec/proxy'; import '../lib/zone-spec/sync-test'; import '../lib/zone-spec/task-tracking'; import '../lib/zone-spec/wtf'; -import '../lib/extra/cordova'; \ No newline at end of file +import '../lib/extra/cordova'; diff --git a/test/browser_entry_point.ts b/test/browser_entry_point.ts index 0d49c69af..4ec6e5776 100644 --- a/test/browser_entry_point.ts +++ b/test/browser_entry_point.ts @@ -25,4 +25,3 @@ import './browser/Worker.spec'; import './mocha-patch.spec'; import './jasmine-patch.spec'; import './extra/cordova.spec'; -import './rxjs/rxjs.spec'; \ No newline at end of file diff --git a/test/common/util.spec.ts b/test/common/util.spec.ts index 9d450cab1..b6b122d10 100644 --- a/test/common/util.spec.ts +++ b/test/common/util.spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {patchMethod, patchProperty, patchPrototype, wrapFunctionArgs, zoneSymbol} from '../../lib/common/utils'; +import {patchMethod, patchProperty, patchPrototype, zoneSymbol} from '../../lib/common/utils'; describe('utils', function() { @@ -329,30 +329,4 @@ describe('utils', function() { expect(log).toEqual(['property2']); }); }); - - describe('wrapFunctionArgs', () => { - it('wrapFunctionArgs should make function arguments in zone', () => { - const func = function(arg1: string, arg2: Function, arg3: Function) { - arg2(arg1); - arg3(arg1); - }; - - const zone = Zone.current.fork({name: 'wrap'}); - - wrapFunctionArgs(func); - - zone.run(() => { - func( - 'test', - function(arg: string) { - expect(arg).toEqual('test'); - expect(Zone.current.name).toEqual(zone.name); - }, - function(arg: string) { - expect(arg).toEqual('test'); - expect(Zone.current.name).toEqual(zone.name); - }); - }); - }); - }); }); diff --git a/test/common_tests.ts b/test/common_tests.ts index 186274955..bb507dec6 100644 --- a/test/common_tests.ts +++ b/test/common_tests.ts @@ -21,6 +21,6 @@ import './zone-spec/sync-test.spec'; import './zone-spec/fake-async-test.spec'; import './zone-spec/proxy.spec'; import './zone-spec/task-tracking.spec'; -import './rxjs/rxjs.spec'; +// import './rxjs/rxjs.spec'; -Error.stackTraceLimit = Number.POSITIVE_INFINITY; \ No newline at end of file +Error.stackTraceLimit = Number.POSITIVE_INFINITY; diff --git a/test/zone-spec/fake-async-test.spec.ts b/test/zone-spec/fake-async-test.spec.ts index 8c53da96b..7e2dfe5c8 100644 --- a/test/zone-spec/fake-async-test.spec.ts +++ b/test/zone-spec/fake-async-test.spec.ts @@ -732,7 +732,7 @@ describe('FakeAsyncTestZoneSpec', () => { patchMacroTask( TestClass.prototype, 'myTimeout', (self: any, args: any[]) => - ({name: 'TestClass.myTimeout', target: self, callbackIndex: 0, args: args})); + ({name: 'TestClass.myTimeout', target: self, cbIdx: 0, args: args})); const testClass = new TestClass(); testClass.myTimeout(function(callbackArgs: any) { @@ -758,7 +758,7 @@ describe('FakeAsyncTestZoneSpec', () => { patchMacroTask( TestClass.prototype, 'myTimeout', (self: any, args: any[]) => - ({name: 'TestClass.myTimeout', target: self, callbackIndex: 0, args: args})); + ({name: 'TestClass.myTimeout', target: self, cbIdx: 0, args: args})); const testClass = new TestClass(); testClass.myTimeout(() => { @@ -787,7 +787,7 @@ describe('FakeAsyncTestZoneSpec', () => { patchMacroTask( TestClass.prototype, 'myInterval', (self: any, args: any[]) => - ({name: 'TestClass.myInterval', target: self, callbackIndex: 0, args: args})); + ({name: 'TestClass.myInterval', target: self, cbIdx: 0, args: args})); const testClass = new TestClass(); const id = testClass.myInterval(() => { From 0bb96642c59e5d760cac283b92af0ae8be631876 Mon Sep 17 00:00:00 2001 From: "JiaLi.Passion" Date: Sun, 7 Jan 2018 17:40:12 +0900 Subject: [PATCH 2/7] fix(core): fix shorter name closure conflict --- karma-dist.conf.js | 1 + lib/common/utils.ts | 12 +++++++----- test/browser/browser.spec.ts | 1 - test/closure/zone.closure.ts | 8 +++++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/karma-dist.conf.js b/karma-dist.conf.js index f6788e1ab..517088ac8 100644 --- a/karma-dist.conf.js +++ b/karma-dist.conf.js @@ -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'); diff --git a/lib/common/utils.ts b/lib/common/utils.ts index b792439a1..0d95b4596 100644 --- a/lib/common/utils.ts +++ b/lib/common/utils.ts @@ -31,11 +31,14 @@ export const p = 'object'; export const q = 'number'; export const r = 'string'; + // Hack since TypeScript isn't compiling this for a worker. declare const WorkerGlobalScope: any; export const zoneSymbol = Zone.__symbol__; -const _global: any = typeof window === p && window || typeof self === p && self || global; +const iw = typeof window !== o; +const w: any = iw ? window : undefined; +const _global: any = iw && w || typeof self === p && self || global; const REMOVE_ATTRIBUTE = 'removeAttribute'; const NULL_ON_PROP_VALUE: any[] = [null]; @@ -95,15 +98,14 @@ export const isNode: boolean = (!('nw' in _global) && typeof _global.process !== o && {}.toString.call(_global.process) === '[object process]'); -export const isBrowser: boolean = - !isNode && !isWebWorker && !!(typeof window !== o && (window as any)['HTMLElement']); +export const isBrowser: boolean = !isNode && !isWebWorker && !!(iw && w['HTMLElement']); // we are in electron of nw, so we are both browser and nodejs // Make sure to access `process` through `_global` so that WebPack does not accidently browserify // this code. export const isMix: boolean = typeof _global.process !== o && {}.toString.call(_global.process) === '[object process]' && !isWebWorker && - !!(typeof window !== o && (window as any)['HTMLElement']); + !!(iw && w['HTMLElement']); const zoneSymbolEventNames: {[eventName: string]: string} = {}; @@ -430,7 +432,7 @@ export function isIEOrEdge() { isDetectedIEOrEdge = true; try { - const ua = window.navigator.userAgent; + const ua = w.navigator.userAgent; if (ua.indexOf('MSIE ') !== -1 || ua.indexOf('Trident/') !== -1 || ua.indexOf('Edge/') !== -1) { ieOrEdge = true; } diff --git a/test/browser/browser.spec.ts b/test/browser/browser.spec.ts index 5365aeb21..6276d1e8e 100644 --- a/test/browser/browser.spec.ts +++ b/test/browser/browser.spec.ts @@ -2504,7 +2504,6 @@ describe('Zone', function() { const zone = Zone.current.fork({name: 'media'}); zone.run(() => { const constraints = {audio: true, video: {width: 1280, height: 720}}; - navigator.getUserMedia( constraints, () => { diff --git a/test/closure/zone.closure.ts b/test/closure/zone.closure.ts index e9ad5389d..3e5cc3470 100644 --- a/test/closure/zone.closure.ts +++ b/test/closure/zone.closure.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import '../../dist/zone-node'; - +const shortKeys = ['w', 'f', 'r', 'rg', 'rt', 'st', 'sc', 'si', 'se', 'ct']; const testClosureFunction = () => { const logs: string[] = []; // call all Zone exposed functions @@ -69,7 +69,9 @@ const testClosureFunction = () => { logs.push('get' + keyZone.get('key')); logs.push('root' + Zone.root.name); Object.keys((Zone as any).prototype).forEach(key => { - logs.push(key); + if (shortKeys.indexOf(key) === -1) { + logs.push(key); + } }); Object.keys(testZoneSpec).forEach(key => { logs.push(key); @@ -139,4 +141,4 @@ process['on']('uncaughtException', (err: any) => { process['exit'](1); }); -testClosureFunction(); \ No newline at end of file +testClosureFunction(); From bbb7a21b66fd28d415b270200bb2e67cc137e14d Mon Sep 17 00:00:00 2001 From: "JiaLi.Passion" Date: Sun, 7 Jan 2018 22:17:58 +0900 Subject: [PATCH 3/7] fix(core): add comment for shorter var/function name --- lib/browser/browser.ts | 9 +++++++++ lib/browser/define-property.ts | 2 ++ lib/browser/event-target.ts | 10 ++++++++++ lib/browser/property-descriptor.ts | 5 +++++ lib/browser/register-element.ts | 1 + lib/browser/websocket.ts | 3 +++ lib/common/events.ts | 15 +++++++++++++++ lib/common/promise.ts | 17 +++++++++++++++++ lib/common/timers.ts | 11 +++++++++++ lib/common/to-string.ts | 1 + lib/common/utils.ts | 20 +++++++++++++++++++- lib/zone.ts | 12 ++++++++++++ 12 files changed, 105 insertions(+), 1 deletion(-) diff --git a/lib/browser/browser.ts b/lib/browser/browser.ts index 03f3b00db..39981ba64 100644 --- a/lib/browser/browser.ts +++ b/lib/browser/browser.ts @@ -45,6 +45,7 @@ import {registerElementPatch} from './register-element'; const name = blockingMethods[i]; patchMethod(global, name, (delegate, symbol, name) => { return function(s: any, args: any[]) { + // Zone.current.run return (Zone as any).c.r(delegate, global, args, name); }; }); @@ -53,6 +54,7 @@ import {registerElementPatch} from './register-element'; (Zone as any).l('EventTarget', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // load blackListEvents from global + // Zone.__symbol__ const SYMBOL_BLACK_LISTED_EVENTS = (Zone as any).s('BLACK_LISTED_EVENTS'); if (global[SYMBOL_BLACK_LISTED_EVENTS]) { (Zone as any)[SYMBOL_BLACK_LISTED_EVENTS] = global[SYMBOL_BLACK_LISTED_EVENTS]; @@ -79,6 +81,7 @@ import {registerElementPatch} from './register-element'; (Zone as any).l('canvas', (global: any) => { const HTMLCanvasElement = global['HTMLCanvasElement']; + // o is 'undefined' if (typeof HTMLCanvasElement !== o && HTMLCanvasElement.prototype && HTMLCanvasElement.prototype.toBlob) { patchMacroTask(HTMLCanvasElement.prototype, 'toBlob', (self: any, args: any[]) => { @@ -133,6 +136,8 @@ import {registerElementPatch} from './register-element'; // remove existing event listener const listener = target[XHR_LISTENER]; if (!oriAddListener) { + // i is addEventListener zoneSymbol + // j is removeEventListener zoneSymbol oriAddListener = target[i]; oriRemoveListener = target[j]; } @@ -180,6 +185,7 @@ import {registerElementPatch} from './register-element'; const XMLHTTPREQUEST_SOURCE = 'XMLHttpRequest.send'; const sendNative: Function = patchMethod(XMLHttpRequestPrototype, 'send', () => function(self: any, args: any[]) { + // Zone.current const zone = (Zone as any).c; if (self[XHR_SYNC]) { // if the XHR is sync there is no task to schedule, just execute the code. @@ -193,6 +199,7 @@ import {registerElementPatch} from './register-element'; args: args, aborted: false }; + // Zone.scheduleMacroTask return zone.sc( XMLHTTPREQUEST_SOURCE, placeholderCallback, options, scheduleTask, clearTask); } @@ -200,6 +207,7 @@ import {registerElementPatch} from './register-element'; const abortNative = patchMethod(XMLHttpRequestPrototype, 'abort', () => function(self: any) { const task: Task = findPendingTask(self); + // r is 'string' if (task && typeof task.type == r) { // If the XHR has already completed, do nothing. // If the XHR has already been aborted, do nothing. @@ -208,6 +216,7 @@ import {registerElementPatch} from './register-element'; if (task.cancelFn == null || (task.data && (task.data).aborted)) { return; } + // Zone.cancelTask (task.zone as any).ct(task); } // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no diff --git a/lib/browser/define-property.ts b/lib/browser/define-property.ts index ae966c86e..c727bba63 100644 --- a/lib/browser/define-property.ts +++ b/lib/browser/define-property.ts @@ -38,6 +38,7 @@ export function propertyPatch() { }; Object.create = function(obj: any, proto: any) { + // o is 'object' string if (typeof proto === p && !Object.isFrozen(proto)) { Object.keys(proto).forEach(function(prop) { proto[prop] = rewriteDescriptor(obj, prop, proto[prop]); @@ -89,6 +90,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 + // o is 'undefined' string if (typeof originalConfigurableFlag == o) { delete desc.configurable; } else { diff --git a/lib/browser/event-target.ts b/lib/browser/event-target.ts index d0bb6a897..cf957239b 100644 --- a/lib/browser/event-target.ts +++ b/lib/browser/event-target.ts @@ -45,18 +45,26 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) { // predefine all __zone_symbol__ + eventName + true/false string for (let i = 0; i < eventNames.length; i++) { const eventName = eventNames[i]; + // l is 'false' string const falseEventName = eventName + l; + // k is 'true' string const trueEventName = eventName + k; + // m is '__zone_symbol__' string const symbol = m + falseEventName; + // m is '__zone_symbol__' string const symbolCapture = m + trueEventName; + // ens is globalEventNames cache ens[eventName] = {}; + // l is 'false' string ens[eventName][l] = symbol; + // k is 'true' string ens[eventName][k] = symbolCapture; } // predefine all task.source string for (let i = 0; i < WTF_ISSUE_555.length; i++) { const target: any = WTF_ISSUE_555_ARRAY[i]; + // gs is global source cache const targets: any = gs[target] = {}; for (let j = 0; j < eventNames.length; j++) { const eventName = eventNames[j]; @@ -101,6 +109,8 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) { const type = _global[apis[i]]; apiTypes.push(type && type.prototype); } + // vh is validateHandler to check event handler + // is valid or not(for security check) patchEventTarget(_global, apiTypes, {vh: checkIEAndCrossContext}); api.patchEventTarget = patchEventTarget; diff --git a/lib/browser/property-descriptor.ts b/lib/browser/property-descriptor.ts index f8945947e..070e3a6fe 100644 --- a/lib/browser/property-descriptor.ts +++ b/lib/browser/property-descriptor.ts @@ -265,6 +265,7 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { return; } + // o is 'undefined' string const supportsWebSocket = typeof WebSocket !== o; if (canPatchViaPropertyDescriptor()) { const ignoreProperties: IgnoreProperty[] = _global.__Zone_ignore_on_properties; @@ -306,6 +307,7 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype, XMLHttpRequestEventNames, ignoreProperties); } + // o is 'undefined' string if (typeof IDBIndex !== o) { patchFilteredProperties(IDBIndex.prototype, IDBIndexEventNames, ignoreProperties); patchFilteredProperties(IDBRequest.prototype, IDBIndexEventNames, ignoreProperties); @@ -338,6 +340,7 @@ function canPatchViaPropertyDescriptor() { const ON_READY_STATE_CHANGE = 'onreadystatechange'; const XMLHttpRequestPrototype = XMLHttpRequest.prototype; + // a is Object.getOwnPropertyDescriptor const xhrDesc = a(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE); // add enumerable and configurable here because in opera @@ -347,6 +350,7 @@ function canPatchViaPropertyDescriptor() { // and if XMLHttpRequest.prototype.onreadystatechange is undefined, // we should set a real desc instead a fake one if (xhrDesc) { + // b is Object.defineProperty b(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, { enumerable: true, configurable: true, @@ -398,6 +402,7 @@ function patchViaCapturingAllTheEvents() { } while (elt) { if (elt[onproperty] && !elt[onproperty][unboundKey]) { + // Zone.current.wrap bound = (Zone as any).c.w(elt[onproperty], source); bound[unboundKey] = elt[onproperty]; elt[onproperty] = bound; diff --git a/lib/browser/register-element.ts b/lib/browser/register-element.ts index 74e1ccd05..ad877c52d 100644 --- a/lib/browser/register-element.ts +++ b/lib/browser/register-element.ts @@ -25,6 +25,7 @@ export function registerElementPatch(_global: any) { const source = 'Document.registerElement::' + callback; const p = opts.prototype; if (p.hasOwnProperty(callback)) { + // a is Object.getOwnPropertyDescriptor const descriptor = a(p, callback); if (descriptor && descriptor.value) { descriptor.value = (Zone as any).c.w(descriptor.value, source); diff --git a/lib/browser/websocket.ts b/lib/browser/websocket.ts index 5714b6c77..7ecc54232 100644 --- a/lib/browser/websocket.ts +++ b/lib/browser/websocket.ts @@ -24,13 +24,16 @@ export function apply(api: _ZonePrivate, _global: any) { let proxySocketProto: any; // Safari 7.0 has non-configurable own 'onmessage' and friends properties on the socket instance + // a is Object.getOwnPropertyDescriptor const onmessageDesc = a(socket, 'onmessage'); if (onmessageDesc && onmessageDesc.configurable === false) { + // e is Object.create proxySocket = e(socket); // socket have own property descriptor 'onopen', 'onmessage', 'onclose', 'onerror' // but proxySocket not, so we will keep socket as prototype and pass it to // patchOnProperties method proxySocketProto = socket; + // g is `addEventListener`, h is `removeEventListener` string [g, h, 'send', 'close'].forEach(function(propName) { proxySocket[propName] = function() { const args = f.call(arguments); diff --git a/lib/common/events.ts b/lib/common/events.ts index 5b349ab75..bb5666332 100644 --- a/lib/common/events.ts +++ b/lib/common/events.ts @@ -75,6 +75,7 @@ export function patchEventTarget( return; } const delegate = task.callback; + // p is 'object' string if (typeof delegate === p && delegate.handleEvent) { // create the bind version of handleEvent when invoke task.callback = (event: Event) => delegate.handleEvent(event); @@ -83,6 +84,7 @@ export function patchEventTarget( // invoke static task.invoke task.invoke(task, target, [event]); const options = task.options; + // p is 'object' string if (options && typeof options === p && options.once) { // if options.once is true, after invoke once remove listener here // only browser need to do this, nodejs eventEmitter will cal removeListener @@ -103,6 +105,7 @@ export function patchEventTarget( // event.target is needed for Samusung TV and SourceBuffer // || global is needed https://github.com/angular/zone.js/issues/190 const target: any = this || event.target || _global; + // l is 'false' string const tasks = target[ens[event.type][l]]; if (tasks) { // invoke all tasks which attached to current target with given event.type and capture = false @@ -135,6 +138,7 @@ export function patchEventTarget( // event.target is needed for Samusung TV and SourceBuffer // || global is needed https://github.com/angular/zone.js/issues/190 const target: any = this || event.target || _global; + // k is 'true' string const tasks = target[ens[event.type][k]]; if (tasks) { // invoke all tasks which attached to current target with given event.type and capture = false @@ -179,6 +183,7 @@ export function patchEventTarget( let proto = obj; while (proto && !proto.hasOwnProperty(ADD_EVENT_LISTENER)) { + // d is Object.getPrototypeOf proto = d(proto); } if (!proto && obj[ADD_EVENT_LISTENER]) { @@ -230,9 +235,11 @@ export function patchEventTarget( // from Zone.prototype.cancelTask, we should remove the task // from tasksList of target first if (!task.isRemoved) { + // ens is event names cache const symbolEventNames = ens[task.eventName]; let symbolEventName; if (symbolEventNames) { + // k is 'true' string, l is 'false' string symbolEventName = symbolEventNames[task.capture ? k : l]; } const existingTasks = symbolEventName && task.target[symbolEventName]; @@ -286,6 +293,7 @@ export function patchEventTarget( const compareTaskCallbackVsDelegate = function(task: any, delegate: any) { const typeOfDelegate = typeof delegate; + // n is 'function' string, p is 'object' string if ((typeOfDelegate === n && task.callback === delegate) || (typeOfDelegate === p && task.originalDelegate === delegate)) { // same callback, same capture, same event name, just return @@ -313,6 +321,7 @@ export function patchEventTarget( // case here to improve addEventListener performance // we will create the bind delegate when invoke let isHandleEvent = false; + // n is 'function' string if (typeof delegate !== n) { if (!delegate.handleEvent) { return nativeListener.apply(this, arguments); @@ -349,16 +358,20 @@ export function patchEventTarget( once = options ? !!options.once : false; } + // Zone.current const zone = (Zone as any).c; const symbolEventNames = ens[eventName]; let symbolEventName; if (!symbolEventNames) { // the code is duplicate, but I just want to get some better performance + // l is 'false' string, k is 'true' string const falseEventName = eventName + l; const trueEventName = eventName + k; + // m is '__zone_symbol__' string const symbol = m + falseEventName; const symbolCapture = m + trueEventName; ens[eventName] = {}; + // l is 'false' string, k is 'true' string ens[eventName][l] = symbol; ens[eventName][k] = symbolCapture; symbolEventName = capture ? symbolCapture : symbol; @@ -411,6 +424,7 @@ export function patchEventTarget( (data as any).taskData = taskData; } + // Zone.scehduleEventTask const task: any = (zone as any).se(source, delegate, data, customScheduleFn, customCancelFn); @@ -553,6 +567,7 @@ export function patchEventTarget( } else { const symbolEventNames = ens[eventName]; if (symbolEventNames) { + // l is 'false' string, k is 'true' string const symbolEventName = symbolEventNames[l]; const symbolCaptureEventName = symbolEventNames[k]; diff --git a/lib/common/promise.ts b/lib/common/promise.ts index c9a7a0ddf..26c470089 100644 --- a/lib/common/promise.ts +++ b/lib/common/promise.ts @@ -53,6 +53,7 @@ while (_uncaughtPromiseErrors.length) { const uncaughtPromiseError: UncaughtPromiseError = _uncaughtPromiseErrors.shift(); try { + // zone.runGuarded (uncaughtPromiseError.zone as any).rg(() => { throw uncaughtPromiseError; }); @@ -69,6 +70,7 @@ api.onUnhandledError(e); try { const handler = (Zone as any)[UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL]; + // n is 'function' if (handler && typeof handler === n) { handler.apply(this, [e]); } @@ -135,6 +137,7 @@ // should only get value.then once based on promise spec. let then: any = null; try { + // p is 'object', n is 'function' string if (typeof value === p || typeof value === n) { then = value && value.then; } @@ -150,6 +153,7 @@ (value as any)[symbolState] !== UNRESOLVED) { clearRejectedNoCatch(>value); resolvePromise(promise, (value as any)[symbolState], (value as any)[symbolValue]); + // n is 'function' string } else if (state !== REJECTED && typeof then === n) { try { then.apply(value, [ @@ -173,6 +177,7 @@ (Zone.currentTask.data as any)[creationTrace]; if (trace) { // only keep the long stack trace into error when in longStackTraceZone + // b is Object.defineProperty b(value, CURRENT_TASK_TRACE_SYMBOL, {configurable: true, enumerable: false, writable: true, value: trace}); } @@ -192,6 +197,7 @@ const error: UncaughtPromiseError = err; error.rejection = value; error.promise = promise; + // Zone.current error.zone = (Zone as any).c; error.task = Zone.currentTask; _uncaughtPromiseErrors.push(error); @@ -214,6 +220,7 @@ // eventHandler try { const handler = (Zone as any)[REJECTION_HANDLED_HANDLER]; + // n is 'function' string if (handler && typeof handler === n) { handler.apply(this, [{rejection: (promise as any)[symbolValue], promise: promise}]); } @@ -233,10 +240,12 @@ onFulfilled?: (value: R) => U1, onRejected?: (error: any) => U2): void { clearRejectedNoCatch(promise); const delegate = (promise as any)[symbolState] ? + // n is 'function' string (typeof onFulfilled === n) ? onFulfilled : forwardResolution : (typeof onRejected === n) ? onRejected : forwardRejection; (zone as any).si(source, () => { try { + // zone.run resolvePromise( chainPromise, true, (zone as any).r(delegate, undefined, [(promise as any)[symbolValue]])); @@ -334,6 +343,7 @@ null): Promise { const chainPromise: Promise = new (this.constructor as typeof ZoneAwarePromise)(null); + // Zone.current const zone = (Zone as any).c; if ((this as any)[symbolState] == UNRESOLVED) { ((this as any)[symbolValue]).push(zone, chainPromise, onFulfilled, onRejected); @@ -356,8 +366,10 @@ ZoneAwarePromise['all'] = ZoneAwarePromise.all; const NativePromise = global[symbolPromise] = global['Promise']; + // Zone.__symbol__ const ZONE_AWARE_PROMISE = (Zone as any).s('ZoneAwarePromise'); + // a is Object.getOwnPropertyDescriptor let desc = a(global, 'Promise'); if (!desc || desc.configurable) { desc && delete desc.writable; @@ -391,6 +403,7 @@ } }; + // b is Object.defineProperty b(global, 'Promise', desc); } @@ -406,8 +419,10 @@ // check Ctor.prototype.then propertyDescritor is writable or not // in meteor env, writable is false, we have to make it to be true. + // a is Object.getOwnPropertyDescritor const prop = a(Ctor.prototype, 'then'); if (prop && prop.writable === false && prop.configurable) { + // b is Object.defineProperty b(Ctor.prototype, 'then', {writable: true}); } @@ -438,12 +453,14 @@ patchThen(NativePromise); let fetch = global['fetch']; + // n is 'function' if (typeof fetch == n) { global['fetch'] = zoneify(fetch); } } // This is not part of public API, but it is useful for tests, so we expose it. + // s is '__symbol__' (Promise as any)[(Zone as any).s('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; return ZoneAwarePromise; }); diff --git a/lib/common/timers.ts b/lib/common/timers.ts index 82266f0ad..f7d8b7825 100644 --- a/lib/common/timers.ts +++ b/lib/common/timers.ts @@ -39,6 +39,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam // setInterval return; } + // q is 'number' string if (typeof data.handleId === q) { // in non-nodejs env, we remove timerId // from local cache @@ -61,7 +62,9 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam setNative = patchMethod(window, setName, (delegate: Function) => function(self: any, args: any[]) { + // n is 'function' string if (typeof args[0] === n) { + // Zone.current const zone = (Zone as any).c; const options: TimerOptions = { handleId: null, @@ -69,12 +72,14 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 : null, args: args }; + // Zone.scheduleMacroTask const task = (zone as any).sc(setName, args[0], options, scheduleTask, clearTask); if (!task) { return task; } // Node.js must additionally support the ref and unref functions. const handle: any = (task.data).handleId; + // q is 'number' string if (typeof handle === q) { // for non nodejs env, we save handleId: task // mapping in local cache for clearTimeout @@ -87,11 +92,13 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam // check whether handle is null, because some polyfill or browser // may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame + // n is 'function' string if (handle && handle.ref && handle.unref && typeof handle.ref === n && typeof handle.unref === n) { (task).ref = (handle).ref.bind(handle); (task).unref = (handle).unref.bind(handle); } + // q is 'number' string if (typeof handle === q || handle) { return handle; } @@ -106,6 +113,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam patchMethod(window, cancelName, (delegate: Function) => function(self: any, args: any[]) { const id = args[0]; let task: Task; + // q is 'number' string if (typeof id === q) { // non nodejs env. task = tasksByHandleId[id]; @@ -117,15 +125,18 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam task = id; } } + // r is 'string' if (task && typeof task.type === r) { if (task.state !== 'notScheduled' && (task.cancelFn && task.data.isPeriodic || task.runCount === 0)) { + // q is 'number' string if (typeof id === q) { delete tasksByHandleId[id]; } else if (id) { id[taskSymbol] = null; } // Do not cancel already canceled functions + // zone.cancelTask (task.zone as any).ct(task); } } else { diff --git a/lib/common/to-string.ts b/lib/common/to-string.ts index 0499f6016..c2f7a8c9a 100644 --- a/lib/common/to-string.ts +++ b/lib/common/to-string.ts @@ -18,6 +18,7 @@ import {n, zoneSymbol} from './utils'; const PROMISE_SYMBOL = zoneSymbol('Promise'); const ERROR_SYMBOL = zoneSymbol('Error'); Function.prototype.toString = function() { + // n is 'function' string if (typeof this === n) { const originalDelegate = this[ORIGINAL_DELEGATE_SYMBOL]; if (originalDelegate) { diff --git a/lib/common/utils.ts b/lib/common/utils.ts index 0d95b4596..8ef229442 100644 --- a/lib/common/utils.ts +++ b/lib/common/utils.ts @@ -12,26 +12,44 @@ */ // issue #989, to reduce bundle size, use short name + +/** Object.getOwnPropertyDescriptor */ export const a = Object.getOwnPropertyDescriptor; +/** Object.defineProperty */ export const b = Object.defineProperty; +/** Object.defineProperties */ export const c = Object.defineProperties; +/** Object.getPrototypeOf */ export const d = Object.getPrototypeOf; +/** Object.create */ export const e = Object.create; +/** Array.prototype.slice */ export const f = Array.prototype.slice; +/** addEventListener string const */ export const g = 'addEventListener'; +/** removeEventListener string const */ export const h = 'removeEventListener'; +/** zoneSymbol addEventListener */ export const i = (Zone as any).s(g); +/** zoneSymbol removeEventListener */ export const j = (Zone as any).s(h); +/** true string const */ export const k = 'true'; +/** false string const */ export const l = 'false'; +/** __zone_symbol__ string const */ export const m = '__zone_symbol__'; +/** function type string const */ export const n = 'function'; +/** undefined type string const */ export const o = 'undefined'; +/** object type string const */ export const p = 'object'; +/** number type string const */ export const q = 'number'; +/** string type string const */ export const r = 'string'; - // Hack since TypeScript isn't compiling this for a worker. declare const WorkerGlobalScope: any; diff --git a/lib/zone.ts b/lib/zone.ts index d65149400..43df0a7a5 100644 --- a/lib/zone.ts +++ b/lib/zone.ts @@ -1345,17 +1345,29 @@ const Zone: ZoneType = (function(global: any) { performanceMeasure('Zone', 'Zone'); const z: any = Zone.prototype; + /** shorter for Zone.prototype.wrap */ z.w = z.wrap; + /** shorter for Zone.prototype.fork */ z.f = z.fork; + /** shorter for Zone.prototype.run */ z.r = z.run; + /** shorter for Zone.prototype.runGuarded */ z.rg = z.runGuarded; + /** shorter for Zone.prototype.runTask */ z.rt = z.runTask; + /** shorter for Zone.prototype.scheduleTask */ z.st = z.scheduleTask; + /** shorter for Zone.prototype.scheduleMacroTask */ z.sc = z.scheduleMacroTask; + /** shorter for Zone.prototype.scheduleMicroTask */ z.si = z.scheduleMicroTask; + /** shorter for Zone.prototype.scheduleEventTask */ z.se = z.scheduleEventTask; + /** shorter for Zone.prototype.cancelTask */ z.ct = z.cancelTask; + /** shorter for Zone.__load_patch */ (Zone as any).l = Zone.__load_patch; + /** shorter for Zone.__symbol__ */ (Zone as any).s = Zone.__symbol__; return global['Zone'] = Zone; })(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global); From 5928f9ea6bb367618530e5b5c91b657495b57650 Mon Sep 17 00:00:00 2001 From: "JiaLi.Passion" Date: Mon, 8 Jan 2018 11:36:44 +0900 Subject: [PATCH 4/7] fix(core): add file check script in travis build --- check-file-size.js | 27 +++++++++++++++++++++++++++ file-size-limit.json | 9 +++++++++ gulpfile.js | 11 +++++++++++ 3 files changed, 47 insertions(+) create mode 100644 check-file-size.js create mode 100644 file-size-limit.json diff --git a/check-file-size.js b/check-file-size.js new file mode 100644 index 000000000..6c109a445 --- /dev/null +++ b/check-file-size.js @@ -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; +}; diff --git a/file-size-limit.json b/file-size-limit.json new file mode 100644 index 000000000..2c03611e5 --- /dev/null +++ b/file-size-limit.json @@ -0,0 +1,9 @@ +{ + "targets": [ + { + "path": "dist/zone.min.js", + "checkTarget": true, + "limit": 40000 + } + ] +} diff --git a/gulpfile.js b/gulpfile.js index 71a099320..b524bf3ca 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -410,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'); + } +}); From 3e445e457dca6db32425274fa97cb64040b2e1a2 Mon Sep 17 00:00:00 2001 From: "JiaLi.Passion" Date: Mon, 8 Jan 2018 17:39:33 +0900 Subject: [PATCH 5/7] fix(core): add rxjs test --- .travis.yml | 3 ++- test/common_tests.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ee2d8bdd7..fc734678d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 @@ -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 \ No newline at end of file + - node ./test/webdriver/test.sauce.js diff --git a/test/common_tests.ts b/test/common_tests.ts index bb507dec6..2fbb7ecfd 100644 --- a/test/common_tests.ts +++ b/test/common_tests.ts @@ -21,6 +21,6 @@ import './zone-spec/sync-test.spec'; import './zone-spec/fake-async-test.spec'; import './zone-spec/proxy.spec'; import './zone-spec/task-tracking.spec'; -// import './rxjs/rxjs.spec'; +import './rxjs/rxjs.spec'; Error.stackTraceLimit = Number.POSITIVE_INFINITY; From 9c30aaa072955770e25a1dbc9e895c47bf7d33d4 Mon Sep 17 00:00:00 2001 From: "JiaLi.Passion" Date: Tue, 9 Jan 2018 15:17:01 +0900 Subject: [PATCH 6/7] fix(core): remove unreadable short names --- lib/browser/browser.ts | 66 +++++----- lib/browser/define-property.ts | 8 +- lib/browser/event-target.ts | 28 ++--- lib/browser/property-descriptor.ts | 41 +++---- lib/browser/register-element.ts | 19 ++- lib/browser/shadydom.ts | 2 +- lib/browser/webapis-media-query.ts | 2 +- lib/browser/webapis-notification.ts | 2 +- lib/browser/webapis-rtc-peer-connection.ts | 4 +- lib/browser/webapis-user-media.ts | 2 +- lib/browser/websocket.ts | 18 ++- lib/closure/zone_externs.js | 24 ++-- lib/common/error-rewrite.ts | 7 +- lib/common/events.ts | 134 +++++++++------------ lib/common/promise.ts | 79 +++++------- lib/common/timers.ts | 61 ++++------ lib/common/to-string.ts | 9 +- lib/common/utils.ts | 107 +++++++--------- lib/extra/bluebird.ts | 4 +- lib/extra/cordova.ts | 12 +- lib/extra/electron.ts | 8 +- lib/node/events.ts | 18 +-- lib/node/fs.ts | 2 +- lib/node/node.ts | 24 ++-- lib/rxjs/rxjs.ts | 8 +- lib/zone-spec/fake-async-test.ts | 10 +- lib/zone.ts | 34 +----- test/closure/zone.closure.ts | 5 +- 28 files changed, 301 insertions(+), 437 deletions(-) diff --git a/lib/browser/browser.ts b/lib/browser/browser.ts index 39981ba64..78f51ebcc 100644 --- a/lib/browser/browser.ts +++ b/lib/browser/browser.ts @@ -12,20 +12,20 @@ import {findEventTasks} from '../common/events'; import {patchTimer} from '../common/timers'; -import {bindArguments, i, j, o, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, r, zoneSymbol} from '../common/utils'; +import {bindArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, 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'; import {propertyDescriptorPatch} from './property-descriptor'; import {registerElementPatch} from './register-element'; -(Zone as any).l('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => { api.patchOnProperties = patchOnProperties; api.patchMethod = patchMethod; api.bindArguments = bindArguments; }); -(Zone as any).l('timers', (global: any) => { +Zone.__load_patch('timers', (global: any) => { const set = 'set'; const clear = 'clear'; patchTimer(global, set, clear, 'Timeout'); @@ -33,29 +33,27 @@ import {registerElementPatch} from './register-element'; patchTimer(global, set, clear, 'Immediate'); }); -(Zone as any).l('requestAnimationFrame', (global: any) => { +Zone.__load_patch('requestAnimationFrame', (global: any) => { patchTimer(global, 'request', 'cancel', 'AnimationFrame'); patchTimer(global, 'mozRequest', 'mozCancel', 'AnimationFrame'); patchTimer(global, 'webkitRequest', 'webkitCancel', 'AnimationFrame'); }); -(Zone as any).l('blocking', (global: any, Zone: ZoneType) => { +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]; patchMethod(global, name, (delegate, symbol, name) => { return function(s: any, args: any[]) { - // Zone.current.run - return (Zone as any).c.r(delegate, global, args, name); + return Zone.current.run(delegate, global, args, name); }; }); } }); -(Zone as any).l('EventTarget', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('EventTarget', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // load blackListEvents from global - // Zone.__symbol__ - const SYMBOL_BLACK_LISTED_EVENTS = (Zone as any).s('BLACK_LISTED_EVENTS'); + const SYMBOL_BLACK_LISTED_EVENTS = Zone.__symbol__('BLACK_LISTED_EVENTS'); if (global[SYMBOL_BLACK_LISTED_EVENTS]) { (Zone as any)[SYMBOL_BLACK_LISTED_EVENTS] = global[SYMBOL_BLACK_LISTED_EVENTS]; } @@ -73,16 +71,15 @@ import {registerElementPatch} from './register-element'; patchClass('FileReader'); }); -(Zone as any).l('on_property', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('on_property', (global: any, Zone: ZoneType, api: _ZonePrivate) => { propertyDescriptorPatch(api, global); propertyPatch(); registerElementPatch(global); }); -(Zone as any).l('canvas', (global: any) => { +Zone.__load_patch('canvas', (global: any) => { const HTMLCanvasElement = global['HTMLCanvasElement']; - // o is 'undefined' - if (typeof HTMLCanvasElement !== o && HTMLCanvasElement.prototype && + if (typeof HTMLCanvasElement !== 'undefined' && HTMLCanvasElement.prototype && HTMLCanvasElement.prototype.toBlob) { patchMacroTask(HTMLCanvasElement.prototype, 'toBlob', (self: any, args: any[]) => { return {name: 'HTMLCanvasElement.toBlob', target: self, cbIdx: 0, args: args}; @@ -90,8 +87,8 @@ import {registerElementPatch} from './register-element'; } }); -(Zone as any).l('XHR', (global: any, Zone: ZoneType) => { - // 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'); @@ -111,18 +108,17 @@ import {registerElementPatch} from './register-element'; const XMLHttpRequestPrototype: any = XMLHttpRequest.prototype; function findPendingTask(target: any) { - const pendingTask: Task = target[XHR_TASK]; - return pendingTask; + return target[XHR_TASK]; } - let oriAddListener = XMLHttpRequestPrototype[i]; - let oriRemoveListener = XMLHttpRequestPrototype[j]; + let oriAddListener = XMLHttpRequestPrototype[ZONE_SYMBOL_ADD_EVENT_LISTENER]; + let oriRemoveListener = XMLHttpRequestPrototype[ZONE_SYMBOL_REMOVE_EVENT_LISTENER]; if (!oriAddListener) { const XMLHttpRequestEventTarget = window['XMLHttpRequestEventTarget']; if (XMLHttpRequestEventTarget) { const XMLHttpRequestEventTargetPrototype = XMLHttpRequestEventTarget.prototype; - oriAddListener = XMLHttpRequestEventTargetPrototype[i]; - oriRemoveListener = XMLHttpRequestEventTargetPrototype[j]; + oriAddListener = XMLHttpRequestEventTargetPrototype[ZONE_SYMBOL_ADD_EVENT_LISTENER]; + oriRemoveListener = XMLHttpRequestEventTargetPrototype[ZONE_SYMBOL_REMOVE_EVENT_LISTENER]; } } @@ -136,14 +132,12 @@ import {registerElementPatch} from './register-element'; // remove existing event listener const listener = target[XHR_LISTENER]; if (!oriAddListener) { - // i is addEventListener zoneSymbol - // j is removeEventListener zoneSymbol - oriAddListener = target[i]; - oriRemoveListener = target[j]; + 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) { @@ -154,7 +148,7 @@ import {registerElementPatch} from './register-element'; } } }; - oriAddListener.apply(target, [READY_STATE_CHANGE, newListener]); + oriAddListener.call(target, READY_STATE_CHANGE, newListener); const storedTask: Task = target[XHR_TASK]; if (!storedTask) { @@ -185,8 +179,7 @@ import {registerElementPatch} from './register-element'; const XMLHTTPREQUEST_SOURCE = 'XMLHttpRequest.send'; const sendNative: Function = patchMethod(XMLHttpRequestPrototype, 'send', () => function(self: any, args: any[]) { - // Zone.current - const zone = (Zone as any).c; + const zone = Zone.current; if (self[XHR_SYNC]) { // if the XHR is sync there is no task to schedule, just execute the code. return sendNative.apply(self, args); @@ -199,16 +192,14 @@ import {registerElementPatch} from './register-element'; args: args, aborted: false }; - // Zone.scheduleMacroTask - return zone.sc( + return zone.scheduleMacroTask( XMLHTTPREQUEST_SOURCE, placeholderCallback, options, scheduleTask, clearTask); } }); const abortNative = patchMethod(XMLHttpRequestPrototype, 'abort', () => function(self: any) { const task: Task = findPendingTask(self); - // r is 'string' - if (task && typeof task.type == r) { + 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 @@ -216,8 +207,7 @@ import {registerElementPatch} from './register-element'; if (task.cancelFn == null || (task.data && (task.data).aborted)) { return; } - // Zone.cancelTask - (task.zone as any).ct(task); + task.zone.cancelTask(task); } // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no // task @@ -226,14 +216,14 @@ import {registerElementPatch} from './register-element'; } }); -(Zone as any).l('geolocation', (global: any) => { +Zone.__load_patch('geolocation', (global: any) => { /// GEO_LOCATION if (global['navigator'] && global['navigator'].geolocation) { patchPrototype(global['navigator'].geolocation, ['getCurrentPosition', 'watchPosition']); } }); -(Zone as any).l('PromiseRejectionEvent', (global: any, Zone: ZoneType) => { +Zone.__load_patch('PromiseRejectionEvent', (global: any, Zone: ZoneType) => { // handle unhandled promise rejection function findPromiseRejectionHandler(evtName: string) { return function(e: any) { diff --git a/lib/browser/define-property.ts b/lib/browser/define-property.ts index c727bba63..00193832e 100644 --- a/lib/browser/define-property.ts +++ b/lib/browser/define-property.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {o, p, zoneSymbol} from '../common/utils'; +import {zoneSymbol} from '../common/utils'; /* * This is necessary for Chrome and Chrome mobile, to enable * things like redefining `createdCallback` on an element. @@ -38,8 +38,7 @@ export function propertyPatch() { }; Object.create = function(obj: any, proto: any) { - // o is 'object' string - if (typeof proto === p && !Object.isFrozen(proto)) { + if (typeof proto === 'object' && !Object.isFrozen(proto)) { Object.keys(proto).forEach(function(prop) { proto[prop] = rewriteDescriptor(obj, prop, proto[prop]); }); @@ -90,8 +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 - // o is 'undefined' string - if (typeof originalConfigurableFlag == o) { + if (typeof originalConfigurableFlag == 'undefined') { delete desc.configurable; } else { desc.configurable = originalConfigurableFlag; diff --git a/lib/browser/event-target.ts b/lib/browser/event-target.ts index cf957239b..4a67d7567 100644 --- a/lib/browser/event-target.ts +++ b/lib/browser/event-target.ts @@ -6,8 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {ens, gs, patchEventPrototype, patchEventTarget} from '../common/events'; -import {isIEOrEdge, k, l, m} 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'; @@ -45,27 +45,19 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) { // predefine all __zone_symbol__ + eventName + true/false string for (let i = 0; i < eventNames.length; i++) { const eventName = eventNames[i]; - // l is 'false' string - const falseEventName = eventName + l; - // k is 'true' string - const trueEventName = eventName + k; - // m is '__zone_symbol__' string - const symbol = m + falseEventName; - // m is '__zone_symbol__' string - const symbolCapture = m + trueEventName; - // ens is globalEventNames cache - ens[eventName] = {}; - // l is 'false' string - ens[eventName][l] = symbol; - // k is 'true' string - ens[eventName][k] = symbolCapture; + const falseEventName = eventName + FALSE_STR; + const trueEventName = eventName + TRUE_STR; + const symbol = ZONE_SYMBOL_PREFIX + falseEventName; + const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName; + zoneSymbolEventNames[eventName] = {}; + zoneSymbolEventNames[eventName][FALSE_STR] = symbol; + zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture; } // predefine all task.source string for (let i = 0; i < WTF_ISSUE_555.length; i++) { const target: any = WTF_ISSUE_555_ARRAY[i]; - // gs is global source cache - const targets: any = gs[target] = {}; + const targets: any = globalSources[target] = {}; for (let j = 0; j < eventNames.length; j++) { const eventName = eventNames[j]; targets[eventName] = target + ADD_EVENT_LISTENER_SOURCE + eventName; diff --git a/lib/browser/property-descriptor.ts b/lib/browser/property-descriptor.ts index 070e3a6fe..00ac86b1c 100644 --- a/lib/browser/property-descriptor.ts +++ b/lib/browser/property-descriptor.ts @@ -10,7 +10,7 @@ * @suppress {globalThis} */ -import {a, b, d, isBrowser, isMix, isNode, o, patchClass, patchOnProperties, zoneSymbol} from '../common/utils'; +import {isBrowser, isMix, isNode, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, ObjectGetPrototypeOf, patchClass, patchOnProperties, zoneSymbol} from '../common/utils'; import * as webSocketPatch from './websocket'; @@ -265,20 +265,22 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { return; } - // o is 'undefined' string - const supportsWebSocket = typeof WebSocket !== o; + const supportsWebSocket = typeof WebSocket !== 'undefined'; if (canPatchViaPropertyDescriptor()) { const ignoreProperties: IgnoreProperty[] = _global.__Zone_ignore_on_properties; // for browsers that we can patch the descriptor: Chrome & Firefox if (isBrowser) { - const w: any = window; + const internalWindow: any = window; // in IE/Edge, onProp not exist in window object, but in WindowPrototype // so we need to pass WindowPrototype to check onProp exist or not - patchFilteredProperties(w, eventNames.concat(['messageerror']), ignoreProperties, d(w)); + patchFilteredProperties( + internalWindow, eventNames.concat(['messageerror']), ignoreProperties, + ObjectGetPrototypeOf(internalWindow)); patchFilteredProperties(Document.prototype, eventNames, ignoreProperties); - if (typeof w['SVGElement'] !== o) { - patchFilteredProperties(w['SVGElement'].prototype, eventNames, ignoreProperties); + if (typeof internalWindow['SVGElement'] !== 'undefined') { + patchFilteredProperties( + internalWindow['SVGElement'].prototype, eventNames, ignoreProperties); } patchFilteredProperties(Element.prototype, eventNames, ignoreProperties); patchFilteredProperties(HTMLElement.prototype, eventNames, ignoreProperties); @@ -291,11 +293,11 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { patchFilteredProperties(HTMLFrameElement.prototype, frameEventNames, ignoreProperties); patchFilteredProperties(HTMLIFrameElement.prototype, frameEventNames, ignoreProperties); - const HTMLMarqueeElement = w['HTMLMarqueeElement']; + const HTMLMarqueeElement = internalWindow['HTMLMarqueeElement']; if (HTMLMarqueeElement) { patchFilteredProperties(HTMLMarqueeElement.prototype, marqueeEventNames, ignoreProperties); } - const Worker = w['Worker']; + const Worker = internalWindow['Worker']; if (Worker) { patchFilteredProperties(Worker.prototype, workerEventNames, ignoreProperties); } @@ -307,8 +309,7 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype, XMLHttpRequestEventNames, ignoreProperties); } - // o is 'undefined' string - if (typeof IDBIndex !== o) { + if (typeof IDBIndex !== 'undefined') { patchFilteredProperties(IDBIndex.prototype, IDBIndexEventNames, ignoreProperties); patchFilteredProperties(IDBRequest.prototype, IDBIndexEventNames, ignoreProperties); patchFilteredProperties(IDBOpenDBRequest.prototype, IDBIndexEventNames, ignoreProperties); @@ -330,18 +331,18 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { } function canPatchViaPropertyDescriptor() { - if ((isBrowser || isMix) && !a(HTMLElement.prototype, 'onclick') && typeof Element !== o) { + if ((isBrowser || isMix) && !ObjectGetOwnPropertyDescriptor(HTMLElement.prototype, 'onclick') && + typeof Element !== 'undefined') { // WebKit https://bugs.webkit.org/show_bug.cgi?id=134364 // IDL interface attributes are not configurable - const desc = a(Element.prototype, 'onclick'); + const desc = ObjectGetOwnPropertyDescriptor(Element.prototype, 'onclick'); if (desc && !desc.configurable) return false; } const ON_READY_STATE_CHANGE = 'onreadystatechange'; const XMLHttpRequestPrototype = XMLHttpRequest.prototype; - // a is Object.getOwnPropertyDescriptor - const xhrDesc = a(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE); + const xhrDesc = ObjectGetOwnPropertyDescriptor(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE); // add enumerable and configurable here because in opera // by default XMLHttpRequest.prototype.onreadystatechange is undefined @@ -350,8 +351,7 @@ function canPatchViaPropertyDescriptor() { // and if XMLHttpRequest.prototype.onreadystatechange is undefined, // we should set a real desc instead a fake one if (xhrDesc) { - // b is Object.defineProperty - b(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, { + ObjectDefineProperty(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, { enumerable: true, configurable: true, get: function() { @@ -361,11 +361,11 @@ function canPatchViaPropertyDescriptor() { const req = new XMLHttpRequest(); const result = !!req.onreadystatechange; // restore original desc - b(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, xhrDesc || {}); + ObjectDefineProperty(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, xhrDesc || {}); return result; } else { const SYMBOL_FAKE_ONREADYSTATECHANGE = zoneSymbol('fake'); - b(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, { + ObjectDefineProperty(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, { enumerable: true, configurable: true, get: function() { @@ -402,8 +402,7 @@ function patchViaCapturingAllTheEvents() { } while (elt) { if (elt[onproperty] && !elt[onproperty][unboundKey]) { - // Zone.current.wrap - bound = (Zone as any).c.w(elt[onproperty], source); + bound = Zone.current.wrap(elt[onproperty], source); bound[unboundKey] = elt[onproperty]; elt[onproperty] = bound; } diff --git a/lib/browser/register-element.ts b/lib/browser/register-element.ts index ad877c52d..d558e2dd1 100644 --- a/lib/browser/register-element.ts +++ b/lib/browser/register-element.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {a, attachOriginToPatched, isBrowser, isMix} from '../common/utils'; +import {attachOriginToPatched, isBrowser, isMix, ObjectGetOwnPropertyDescriptor} from '../common/utils'; import {_redefineProperty} from './define-property'; @@ -23,23 +23,22 @@ export function registerElementPatch(_global: any) { if (opts && opts.prototype) { callbacks.forEach(function(callback) { const source = 'Document.registerElement::' + callback; - const p = opts.prototype; - if (p.hasOwnProperty(callback)) { - // a is Object.getOwnPropertyDescriptor - const descriptor = a(p, callback); + const prototype = opts.prototype; + if (prototype.hasOwnProperty(callback)) { + const descriptor = ObjectGetOwnPropertyDescriptor(prototype, callback); if (descriptor && descriptor.value) { - descriptor.value = (Zone as any).c.w(descriptor.value, source); + descriptor.value = Zone.current.wrap(descriptor.value, source); _redefineProperty(opts.prototype, callback, descriptor); } else { - p[callback] = (Zone as any).c.w(p[callback], source); + prototype[callback] = Zone.current.wrap(prototype[callback], source); } - } else if (p[callback]) { - p[callback] = (Zone as any).c.w(p[callback], source); + } else if (prototype[callback]) { + prototype[callback] = Zone.current.wrap(prototype[callback], source); } }); } - return _registerElement.apply(document, [name, opts]); + return _registerElement.call(document, name, opts); }; attachOriginToPatched((document).registerElement, _registerElement); diff --git a/lib/browser/shadydom.ts b/lib/browser/shadydom.ts index d02590204..f308308cd 100644 --- a/lib/browser/shadydom.ts +++ b/lib/browser/shadydom.ts @@ -5,7 +5,7 @@ * 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 */ -(Zone as any).l('shadydom', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('shadydom', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // https://github.com/angular/zone.js/issues/782 // in web components, shadydom will patch addEventListener/removeEventListener of // Node.prototype and WindowPrototype, this will have conflict with zone.js diff --git a/lib/browser/webapis-media-query.ts b/lib/browser/webapis-media-query.ts index b26831327..0bb841826 100644 --- a/lib/browser/webapis-media-query.ts +++ b/lib/browser/webapis-media-query.ts @@ -5,7 +5,7 @@ * 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 */ -(Zone as any).l('mediaQuery', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('mediaQuery', (global: any, Zone: ZoneType, api: _ZonePrivate) => { if (!global['MediaQueryList']) { return; } diff --git a/lib/browser/webapis-notification.ts b/lib/browser/webapis-notification.ts index b714b3830..2d663e73c 100644 --- a/lib/browser/webapis-notification.ts +++ b/lib/browser/webapis-notification.ts @@ -5,7 +5,7 @@ * 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 */ -(Zone as any).l('notification', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('notification', (global: any, Zone: ZoneType, api: _ZonePrivate) => { const Notification = global['Notification']; if (!Notification || !Notification.prototype) { return; diff --git a/lib/browser/webapis-rtc-peer-connection.ts b/lib/browser/webapis-rtc-peer-connection.ts index 666b4482d..5930445ef 100644 --- a/lib/browser/webapis-rtc-peer-connection.ts +++ b/lib/browser/webapis-rtc-peer-connection.ts @@ -5,7 +5,7 @@ * 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 */ -(Zone as any).l('RTCPeerConnection', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('RTCPeerConnection', (global: any, Zone: ZoneType, api: _ZonePrivate) => { const RTCPeerConnection = global['RTCPeerConnection']; if (!RTCPeerConnection) { return; @@ -18,7 +18,7 @@ RTCPeerConnection.prototype.removeEventListener = RTCPeerConnection.prototype[removeSymbol]; // RTCPeerConnection extends EventTarget, so we must clear the symbol - // to allow pathc RTCPeerConnection.prototype.addEventListener again + // to allow patch RTCPeerConnection.prototype.addEventListener again RTCPeerConnection.prototype[addSymbol] = null; RTCPeerConnection.prototype[removeSymbol] = null; diff --git a/lib/browser/webapis-user-media.ts b/lib/browser/webapis-user-media.ts index f93085a83..6d2cf5b98 100644 --- a/lib/browser/webapis-user-media.ts +++ b/lib/browser/webapis-user-media.ts @@ -5,7 +5,7 @@ * 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 */ -(Zone as any).l('getUserMedia', (global: any, Zone: any, api: _ZonePrivate) => { +Zone.__load_patch('getUserMedia', (global: any, Zone: any, api: _ZonePrivate) => { function wrapFunctionArgs(func: Function, source?: string): Function { return function() { const args = Array.prototype.slice.call(arguments); diff --git a/lib/browser/websocket.ts b/lib/browser/websocket.ts index 7ecc54232..ab3cc0d41 100644 --- a/lib/browser/websocket.ts +++ b/lib/browser/websocket.ts @@ -7,7 +7,7 @@ */ import {patchEventTarget} from '../common/events'; -import {a, e, f, g, h, patchOnProperties} from '../common/utils'; +import {ADD_EVENT_LISTENER_STR, ArraySlice, ObjectCreate, ObjectGetOwnPropertyDescriptor, patchOnProperties, REMOVE_EVENT_LISTENER_STR} from '../common/utils'; // we have to patch the instance since the proto is non-configurable export function apply(api: _ZonePrivate, _global: any) { @@ -24,23 +24,21 @@ export function apply(api: _ZonePrivate, _global: any) { let proxySocketProto: any; // Safari 7.0 has non-configurable own 'onmessage' and friends properties on the socket instance - // a is Object.getOwnPropertyDescriptor - const onmessageDesc = a(socket, 'onmessage'); + const onmessageDesc = ObjectGetOwnPropertyDescriptor(socket, 'onmessage'); if (onmessageDesc && onmessageDesc.configurable === false) { - // e is Object.create - proxySocket = e(socket); + proxySocket = ObjectCreate(socket); // socket have own property descriptor 'onopen', 'onmessage', 'onclose', 'onerror' // but proxySocket not, so we will keep socket as prototype and pass it to // patchOnProperties method proxySocketProto = socket; - // g is `addEventListener`, h is `removeEventListener` string - [g, h, 'send', 'close'].forEach(function(propName) { + [ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR, 'send', 'close'].forEach(function( + propName) { proxySocket[propName] = function() { - const args = f.call(arguments); - if (propName === g || propName === h) { + const args = ArraySlice.call(arguments); + if (propName === ADD_EVENT_LISTENER_STR || propName === REMOVE_EVENT_LISTENER_STR) { const eventName = args.length > 0 ? args[0] : undefined; if (eventName) { - const propertySymbol = (Zone as any).s('ON_PROPERTY' + eventName); + const propertySymbol = Zone.__symbol__('ON_PROPERTY' + eventName); socket[propertySymbol] = proxySocket[propertySymbol]; } } diff --git a/lib/closure/zone_externs.js b/lib/closure/zone_externs.js index 1fdf456b8..08a4c68c7 100644 --- a/lib/closure/zone_externs.js +++ b/lib/closure/zone_externs.js @@ -48,7 +48,7 @@ Zone.root; * Returns a value associated with the `key`. * * If the current zone does not have a key, the request is delegated to the parent zone. Use - * [ZoneSpec.properties] to configure the set of properties asseciated with the current zone. + * [ZoneSpec.properties] to configure the set of properties associated with the current zone. * * @param {!string} key The key to retrieve. * @returns {?} The value for the key, or `undefined` if not found. @@ -206,18 +206,18 @@ ZoneSpec.prototype.onIntercept; /** * Allows interception of the callback invocation. - * + * * @type { - * undefined|?function(ZoneDelegate, Zone, Zone, Function, Object, Array, string): * + * undefined|?function(ZoneDelegate, Zone, Zone, Function, Object, Array, string): * * } */ -ZoneSpec.prototype.onInvoke; +ZoneSpec.prototype.onInvoke; /** * Allows interception of the error handling. * * @type { - * undefined|?function(ZoneDelegate, Zone, Zone, Object): boolean + * undefined|?function(ZoneDelegate, Zone, Zone, Object): boolean * } */ ZoneSpec.prototype.onHandleError; @@ -226,7 +226,7 @@ ZoneSpec.prototype.onHandleError; * Allows interception of task scheduling. * * @type { - * undefined|?function(ZoneDelegate, Zone, Zone, Task): Task + * undefined|?function(ZoneDelegate, Zone, Zone, Task): Task * } */ ZoneSpec.prototype.onScheduleTask; @@ -238,16 +238,16 @@ ZoneSpec.prototype.onScheduleTask; * undefined|?function(ZoneDelegate, Zone, Zone, Task, Object, Array): * * } */ -ZoneSpec.prototype.onInvokeTask; +ZoneSpec.prototype.onInvokeTask; /** * Allows interception of task cancelation. * * @type { - * undefined|?function(ZoneDelegate, Zone, Zone, Task): * + * undefined|?function(ZoneDelegate, Zone, Zone, Task): * * } */ -ZoneSpec.prototype.onCancelTask; +ZoneSpec.prototype.onCancelTask; /** * Notifies of changes to the task queue empty status. * @@ -275,7 +275,7 @@ ZoneDelegate.prototype.fork = function(targetZone, zoneSpec) {}; * @param {!Zone} targetZone the [Zone] which originally received the request. * @param {!Function} callback the callback function passed into `wrap` function * @param {string=} source the argument passed into the `wrap` method. - * @returns {!Function} + * @returns {!Function} */ ZoneDelegate.prototype.intercept = function(targetZone, callback, source) {}; @@ -316,7 +316,7 @@ ZoneDelegate.prototype.invokeTask = function(targetZone, task, applyThis, applyA ZoneDelegate.prototype.cancelTask = function(targetZone, task) {}; /** * @param {!Zone} targetZone The [Zone] which originally received the request. - * @param {!HasTaskState} hasTaskState + * @param {!HasTaskState} hasTaskState */ ZoneDelegate.prototype.hasTask = function(targetZone, hasTaskState) {}; @@ -439,4 +439,4 @@ Error.prototype.zoneAwareStack; /** * @type {?string} */ -Error.prototype.originalStack; \ No newline at end of file +Error.prototype.originalStack; diff --git a/lib/common/error-rewrite.ts b/lib/common/error-rewrite.ts index e9ea0639d..dcd5b3970 100644 --- a/lib/common/error-rewrite.ts +++ b/lib/common/error-rewrite.ts @@ -189,7 +189,7 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => { } } } - return value.apply(this, [error, structuredStackTrace]); + return value.call(this, error, structuredStackTrace); }; } }); @@ -218,7 +218,7 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => { let frame = frames.shift(); // On safari it is possible to have stack frame with no line number. // This check makes sure that we don't filter frames on name only (must have - // linenumber) + // line number) if (/:\d+:\d+/.test(frame)) { // Get rid of the path so that we don't accidentally find function name in path. // In chrome the separator is `(` and `@` in FF and safari @@ -283,8 +283,7 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => { // all kinds of tasks with one error thrown. childDetectZone.run(() => { childDetectZone.runGuarded(() => { - const fakeTransitionTo = - (toState: TaskState, fromState1: TaskState, fromState2: TaskState) => {}; + const fakeTransitionTo = () => {}; childDetectZone.scheduleEventTask( blacklistedStackFramesSymbol, () => { diff --git a/lib/common/events.ts b/lib/common/events.ts index bb5666332..49bc6fe16 100644 --- a/lib/common/events.ts +++ b/lib/common/events.ts @@ -10,7 +10,7 @@ * @suppress {missingRequire} */ -import {attachOriginToPatched, d, g, h, k, l, m, n, p, zoneSymbol} from './utils'; +import {ADD_EVENT_LISTENER_STR, attachOriginToPatched, FALSE_STR, ObjectGetPrototypeOf, REMOVE_EVENT_LISTENER_STR, TRUE_STR, ZONE_SYMBOL_PREFIX, zoneSymbol} from './utils'; /** @internal **/ interface EventTaskData extends TaskData { @@ -23,8 +23,8 @@ const OPTIMIZED_ZONE_EVENT_TASK_DATA: EventTaskData = { useG: true }; -export const ens: any = {}; -export const gs: any = {}; +export const zoneSymbolEventNames: any = {}; +export const globalSources: any = {}; const EVENT_NAME_SYMBOL_REGX = /^__zone_symbol__(\w+)(true|false)$/; const IMMEDIATE_PROPAGATION_SYMBOL = ('__zone_symbol__propagationStopped'); @@ -54,8 +54,8 @@ export interface PatchEventTargetOptions { export function patchEventTarget( _global: any, apis: any[], patchOptions?: PatchEventTargetOptions) { - const ADD_EVENT_LISTENER = (patchOptions && patchOptions.add) || g; - const REMOVE_EVENT_LISTENER = (patchOptions && patchOptions.rm) || h; + const ADD_EVENT_LISTENER = (patchOptions && patchOptions.add) || ADD_EVENT_LISTENER_STR; + const REMOVE_EVENT_LISTENER = (patchOptions && patchOptions.rm) || REMOVE_EVENT_LISTENER_STR; const LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.listeners) || 'eventListeners'; const REMOVE_ALL_LISTENERS_EVENT_LISTENER = @@ -75,8 +75,7 @@ export function patchEventTarget( return; } const delegate = task.callback; - // p is 'object' string - if (typeof delegate === p && delegate.handleEvent) { + if (typeof delegate === 'object' && delegate.handleEvent) { // create the bind version of handleEvent when invoke task.callback = (event: Event) => delegate.handleEvent(event); task.originalDelegate = delegate; @@ -84,13 +83,12 @@ export function patchEventTarget( // invoke static task.invoke task.invoke(task, target, [event]); const options = task.options; - // p is 'object' string - if (options && typeof options === p && options.once) { + if (options && typeof options === 'object' && options.once) { // if options.once is true, after invoke once remove listener here // only browser need to do this, nodejs eventEmitter will cal removeListener // inside EventEmitter.once const delegate = task.originalDelegate ? task.originalDelegate : task.callback; - target[REMOVE_EVENT_LISTENER].apply(target, [event.type, delegate, options]); + target[REMOVE_EVENT_LISTENER].call(target, event.type, delegate, options); } }; @@ -102,11 +100,10 @@ export function patchEventTarget( if (!event) { return; } - // event.target is needed for Samusung TV and SourceBuffer + // event.target is needed for Samsung TV and SourceBuffer // || global is needed https://github.com/angular/zone.js/issues/190 const target: any = this || event.target || _global; - // l is 'false' string - const tasks = target[ens[event.type][l]]; + const tasks = target[zoneSymbolEventNames[event.type][FALSE_STR]]; if (tasks) { // invoke all tasks which attached to current target with given event.type and capture = false // for performance concern, if task.length === 1, just invoke @@ -135,11 +132,10 @@ export function patchEventTarget( if (!event) { return; } - // event.target is needed for Samusung TV and SourceBuffer + // event.target is needed for Samsung TV and SourceBuffer // || global is needed https://github.com/angular/zone.js/issues/190 const target: any = this || event.target || _global; - // k is 'true' string - const tasks = target[ens[event.type][k]]; + const tasks = target[zoneSymbolEventNames[event.type][TRUE_STR]]; if (tasks) { // invoke all tasks which attached to current target with given event.type and capture = false // for performance concern, if task.length === 1, just invoke @@ -183,8 +179,7 @@ export function patchEventTarget( let proto = obj; while (proto && !proto.hasOwnProperty(ADD_EVENT_LISTENER)) { - // d is Object.getPrototypeOf - proto = d(proto); + proto = ObjectGetPrototypeOf(proto); } if (!proto && obj[ADD_EVENT_LISTENER]) { // somehow we did not find it, but we can see it. This happens on IE for Window properties. @@ -217,17 +212,16 @@ export function patchEventTarget( proto[patchOptions.prepend]; } - const customScheduleGlobal = function(task: Task) { + const customScheduleGlobal = function() { // if there is already a task for the eventName + capture, // just return, because we use the shared globalZoneAwareCallback here. if (taskData.isExisting) { return; } - return nativeAddEventListener.apply(taskData.target, [ - taskData.eventName, - taskData.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, - taskData.options - ]); + return nativeAddEventListener.call( + taskData.target, taskData.eventName, + taskData.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, + taskData.options); }; const customCancelGlobal = function(task: any) { @@ -235,12 +229,10 @@ export function patchEventTarget( // from Zone.prototype.cancelTask, we should remove the task // from tasksList of target first if (!task.isRemoved) { - // ens is event names cache - const symbolEventNames = ens[task.eventName]; + const symbolEventNames = zoneSymbolEventNames[task.eventName]; let symbolEventName; if (symbolEventNames) { - // k is 'true' string, l is 'false' string - symbolEventName = symbolEventNames[task.capture ? k : l]; + symbolEventName = symbolEventNames[task.capture ? TRUE_STR : FALSE_STR]; } const existingTasks = symbolEventName && task.target[symbolEventName]; if (existingTasks) { @@ -267,25 +259,23 @@ export function patchEventTarget( if (!task.allRemoved) { return; } - return nativeRemoveEventListener.apply(task.target, [ - task.eventName, task.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, - task.options - ]); + return nativeRemoveEventListener.call( + task.target, task.eventName, + task.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, task.options); }; const customScheduleNonGlobal = function(task: Task) { - return nativeAddEventListener.apply( - taskData.target, [taskData.eventName, task.invoke, taskData.options]); + return nativeAddEventListener.call( + taskData.target, taskData.eventName, task.invoke, taskData.options); }; const customSchedulePrepend = function(task: Task) { - return nativePrependEventListener.apply( - taskData.target, [taskData.eventName, task.invoke, taskData.options]); + return nativePrependEventListener.call( + taskData.target, taskData.eventName, task.invoke, taskData.options); }; const customCancelNonGlobal = function(task: any) { - return nativeRemoveEventListener.apply( - task.target, [task.eventName, task.invoke, task.options]); + return nativeRemoveEventListener.call(task.target, task.eventName, task.invoke, task.options); }; const customSchedule = useGlobalCallback ? customScheduleGlobal : customScheduleNonGlobal; @@ -293,19 +283,15 @@ export function patchEventTarget( const compareTaskCallbackVsDelegate = function(task: any, delegate: any) { const typeOfDelegate = typeof delegate; - // n is 'function' string, p is 'object' string - if ((typeOfDelegate === n && task.callback === delegate) || - (typeOfDelegate === p && task.originalDelegate === delegate)) { - // same callback, same capture, same event name, just return - return true; - } - return false; + return (typeOfDelegate === 'function' && task.callback === delegate) || + (typeOfDelegate === 'object' && task.originalDelegate === delegate); + }; const compare = (patchOptions && patchOptions.diff) ? patchOptions.diff : compareTaskCallbackVsDelegate; - const blackListedEvents: string[] = (Zone as any)[(Zone as any).s('BLACK_LISTED_EVENTS')]; + const blackListedEvents: string[] = (Zone as any)[Zone.__symbol__('BLACK_LISTED_EVENTS')]; const makeAddListener = function( nativeListener: any, addSource: string, customScheduleFn: any, customCancelFn: any, @@ -321,8 +307,7 @@ export function patchEventTarget( // case here to improve addEventListener performance // we will create the bind delegate when invoke let isHandleEvent = false; - // n is 'function' string - if (typeof delegate !== n) { + if (typeof delegate !== 'function') { if (!delegate.handleEvent) { return nativeListener.apply(this, arguments); } @@ -358,25 +343,21 @@ export function patchEventTarget( once = options ? !!options.once : false; } - // Zone.current - const zone = (Zone as any).c; - const symbolEventNames = ens[eventName]; + const zone = Zone.current; + const symbolEventNames = zoneSymbolEventNames[eventName]; let symbolEventName; if (!symbolEventNames) { // the code is duplicate, but I just want to get some better performance - // l is 'false' string, k is 'true' string - const falseEventName = eventName + l; - const trueEventName = eventName + k; - // m is '__zone_symbol__' string - const symbol = m + falseEventName; - const symbolCapture = m + trueEventName; - ens[eventName] = {}; - // l is 'false' string, k is 'true' string - ens[eventName][l] = symbol; - ens[eventName][k] = symbolCapture; + const falseEventName = eventName + FALSE_STR; + const trueEventName = eventName + TRUE_STR; + const symbol = ZONE_SYMBOL_PREFIX + falseEventName; + const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName; + zoneSymbolEventNames[eventName] = {}; + zoneSymbolEventNames[eventName][FALSE_STR] = symbol; + zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture; symbolEventName = capture ? symbolCapture : symbol; } else { - symbolEventName = symbolEventNames[capture ? k : l]; + symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR]; } let existingTasks = target[symbolEventName]; let isExisting = false; @@ -396,7 +377,7 @@ export function patchEventTarget( } let source; const constructorName = target.constructor['name']; - const targetSource = gs[constructorName]; + const targetSource = globalSources[constructorName]; if (targetSource) { source = targetSource[eventName]; } @@ -419,14 +400,13 @@ export function patchEventTarget( const data = useGlobalCallback ? OPTIMIZED_ZONE_EVENT_TASK_DATA : null; - // keep taskData into data to allow onScheduleEventTask to acess the task information + // keep taskData into data to allow onScheduleEventTask to access the task information if (data) { (data as any).taskData = taskData; } - // Zone.scehduleEventTask const task: any = - (zone as any).se(source, delegate, data, customScheduleFn, customCancelFn); + zone.scheduleEventTask(source, delegate, data, customScheduleFn, customCancelFn); // should clear taskData.target to avoid memory leak // issue, https://github.com/angular/angular/issues/20442 @@ -497,16 +477,15 @@ export function patchEventTarget( return; } - const symbolEventNames = ens[eventName]; + const symbolEventNames = zoneSymbolEventNames[eventName]; let symbolEventName; if (symbolEventNames) { - symbolEventName = symbolEventNames[capture ? k : l]; + symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR]; } const existingTasks = symbolEventName && target[symbolEventName]; if (existingTasks) { for (let i = 0; i < existingTasks.length; i++) { const existingTask = existingTasks[i]; - const typeOfDelegate = typeof delegate; if (compare(existingTask, delegate)) { existingTasks.splice(i, 1); // set isRemoved to data for faster invokeTask check @@ -517,7 +496,7 @@ export function patchEventTarget( (existingTask as any).allRemoved = true; target[symbolEventName] = null; } - (existingTask.zone as any).ct(existingTask); + existingTask.zone.cancelTask(existingTask); return; } } @@ -559,17 +538,16 @@ export function patchEventTarget( // so just keep removeListener eventListener until // all other eventListeners are removed if (evtName && evtName !== 'removeListener') { - this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].apply(this, [evtName]); + this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, evtName); } } // remove removeListener listener finally - this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].apply(this, ['removeListener']); + this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, 'removeListener'); } else { - const symbolEventNames = ens[eventName]; + const symbolEventNames = zoneSymbolEventNames[eventName]; if (symbolEventNames) { - // l is 'false' string, k is 'true' string - const symbolEventName = symbolEventNames[l]; - const symbolCaptureEventName = symbolEventNames[k]; + const symbolEventName = symbolEventNames[FALSE_STR]; + const symbolCaptureEventName = symbolEventNames[TRUE_STR]; const tasks = target[symbolEventName]; const captureTasks = target[symbolCaptureEventName]; @@ -579,7 +557,7 @@ export function patchEventTarget( for (let i = 0; i < removeTasks.length; i++) { const task = removeTasks[i]; let delegate = task.originalDelegate ? task.originalDelegate : task.callback; - this[REMOVE_EVENT_LISTENER].apply(this, [eventName, delegate, task.options]); + this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options); } } @@ -588,7 +566,7 @@ export function patchEventTarget( for (let i = 0; i < removeTasks.length; i++) { const task = removeTasks[i]; let delegate = task.originalDelegate ? task.originalDelegate : task.callback; - this[REMOVE_EVENT_LISTENER].apply(this, [eventName, delegate, task.options]); + this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options); } } } diff --git a/lib/common/promise.ts b/lib/common/promise.ts index 26c470089..75e0766a9 100644 --- a/lib/common/promise.ts +++ b/lib/common/promise.ts @@ -5,11 +5,9 @@ * 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 */ -(Zone as any).l('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePrivate) => { - const a = Object.getOwnPropertyDescriptor; - const b = Object.defineProperty; - const n = 'function'; - const p = 'object'; +Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePrivate) => { + const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + const ObjectDefineProperty = Object.defineProperty; function readableObjectToString(obj: any) { if (obj && obj.toString === Object.prototype.toString) { @@ -53,8 +51,7 @@ while (_uncaughtPromiseErrors.length) { const uncaughtPromiseError: UncaughtPromiseError = _uncaughtPromiseErrors.shift(); try { - // zone.runGuarded - (uncaughtPromiseError.zone as any).rg(() => { + uncaughtPromiseError.zone.runGuarded(() => { throw uncaughtPromiseError; }); } catch (error) { @@ -70,9 +67,8 @@ api.onUnhandledError(e); try { const handler = (Zone as any)[UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL]; - // n is 'function' - if (handler && typeof handler === n) { - handler.apply(this, [e]); + if (handler && typeof handler === 'function') { + handler.call(this, e); } } catch (err) { } @@ -137,8 +133,7 @@ // should only get value.then once based on promise spec. let then: any = null; try { - // p is 'object', n is 'function' string - if (typeof value === p || typeof value === n) { + if (typeof value === 'object' || typeof value === 'function') { then = value && value.then; } } catch (err) { @@ -153,12 +148,11 @@ (value as any)[symbolState] !== UNRESOLVED) { clearRejectedNoCatch(>value); resolvePromise(promise, (value as any)[symbolState], (value as any)[symbolValue]); - // n is 'function' string - } else if (state !== REJECTED && typeof then === n) { + } else if (state !== REJECTED && typeof then === 'function') { try { - then.apply(value, [ - onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false)) - ]); + then.call( + value, onceWrapper(makeResolver(promise, state)), + onceWrapper(makeResolver(promise, false))); } catch (err) { onceWrapper(() => { resolvePromise(promise, false, err); @@ -177,9 +171,9 @@ (Zone.currentTask.data as any)[creationTrace]; if (trace) { // only keep the long stack trace into error when in longStackTraceZone - // b is Object.defineProperty - b(value, CURRENT_TASK_TRACE_SYMBOL, - {configurable: true, enumerable: false, writable: true, value: trace}); + ObjectDefineProperty( + value, CURRENT_TASK_TRACE_SYMBOL, + {configurable: true, enumerable: false, writable: true, value: trace}); } } @@ -197,8 +191,7 @@ const error: UncaughtPromiseError = err; error.rejection = value; error.promise = promise; - // Zone.current - error.zone = (Zone as any).c; + error.zone = Zone.current; error.task = Zone.currentTask; _uncaughtPromiseErrors.push(error); api.scheduleMicroTask(); // to make sure that it is running @@ -220,9 +213,8 @@ // eventHandler try { const handler = (Zone as any)[REJECTION_HANDLED_HANDLER]; - // n is 'function' string - if (handler && typeof handler === n) { - handler.apply(this, [{rejection: (promise as any)[symbolValue], promise: promise}]); + if (handler && typeof handler === 'function') { + handler.call(this, {rejection: (promise as any)[symbolValue], promise: promise}); } } catch (err) { } @@ -240,15 +232,12 @@ onFulfilled?: (value: R) => U1, onRejected?: (error: any) => U2): void { clearRejectedNoCatch(promise); const delegate = (promise as any)[symbolState] ? - // n is 'function' string - (typeof onFulfilled === n) ? onFulfilled : forwardResolution : - (typeof onRejected === n) ? onRejected : forwardRejection; - (zone as any).si(source, () => { + (typeof onFulfilled === 'function') ? onFulfilled : forwardResolution : + (typeof onRejected === 'function') ? onRejected : forwardRejection; + zone.scheduleMicroTask(source, () => { try { - // zone.run resolvePromise( - chainPromise, true, - (zone as any).r(delegate, undefined, [(promise as any)[symbolValue]])); + chainPromise, true, zone.run(delegate, undefined, [(promise as any)[symbolValue]])); } catch (error) { resolvePromise(chainPromise, false, error); } @@ -343,8 +332,7 @@ null): Promise { const chainPromise: Promise = new (this.constructor as typeof ZoneAwarePromise)(null); - // Zone.current - const zone = (Zone as any).c; + const zone = Zone.current; if ((this as any)[symbolState] == UNRESOLVED) { ((this as any)[symbolValue]).push(zone, chainPromise, onFulfilled, onRejected); } else { @@ -366,11 +354,9 @@ ZoneAwarePromise['all'] = ZoneAwarePromise.all; const NativePromise = global[symbolPromise] = global['Promise']; - // Zone.__symbol__ - const ZONE_AWARE_PROMISE = (Zone as any).s('ZoneAwarePromise'); + const ZONE_AWARE_PROMISE = Zone.__symbol__('ZoneAwarePromise'); - // a is Object.getOwnPropertyDescriptor - let desc = a(global, 'Promise'); + let desc = ObjectGetOwnPropertyDescriptor(global, 'Promise'); if (!desc || desc.configurable) { desc && delete desc.writable; desc && delete desc.value; @@ -403,8 +389,7 @@ } }; - // b is Object.defineProperty - b(global, 'Promise', desc); + ObjectDefineProperty(global, 'Promise', desc); } global['Promise'] = ZoneAwarePromise; @@ -417,13 +402,11 @@ // Keep a reference to the original method. proto[symbolThen] = originalThen; - // check Ctor.prototype.then propertyDescritor is writable or not + // check Ctor.prototype.then propertyDescriptor is writable or not // in meteor env, writable is false, we have to make it to be true. - // a is Object.getOwnPropertyDescritor - const prop = a(Ctor.prototype, 'then'); + const prop = ObjectGetOwnPropertyDescriptor(Ctor.prototype, 'then'); if (prop && prop.writable === false && prop.configurable) { - // b is Object.defineProperty - b(Ctor.prototype, 'then', {writable: true}); + ObjectDefineProperty(Ctor.prototype, 'then', {writable: true}); } Ctor.prototype.then = function(onResolve: any, onReject: any) { @@ -453,14 +436,12 @@ patchThen(NativePromise); let fetch = global['fetch']; - // n is 'function' - if (typeof fetch == n) { + if (typeof fetch == 'function') { global['fetch'] = zoneify(fetch); } } // This is not part of public API, but it is useful for tests, so we expose it. - // s is '__symbol__' - (Promise as any)[(Zone as any).s('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; + (Promise as any)[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; return ZoneAwarePromise; }); diff --git a/lib/common/timers.ts b/lib/common/timers.ts index f7d8b7825..1185f8a23 100644 --- a/lib/common/timers.ts +++ b/lib/common/timers.ts @@ -10,7 +10,7 @@ * @suppress {missingRequire} */ -import {n, patchMethod, q, r, zoneSymbol} from './utils'; +import {patchMethod, zoneSymbol} from './utils'; const taskSymbol = zoneSymbol('zoneTask'); @@ -33,21 +33,19 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam try { task.invoke.apply(this, arguments); } finally { - if (task.data && task.data.isPeriodic) { - // issue-934, task will be cancelled - // even it is a periodic task such as - // setInterval - return; - } - // q is 'number' string - if (typeof data.handleId === q) { - // in non-nodejs env, we remove timerId - // from local cache - delete tasksByHandleId[data.handleId]; - } else if (data.handleId) { - // Node returns complex objects as handleIds - // we remove task reference from timer object - (data.handleId as any)[taskSymbol] = null; + // issue-934, task will be cancelled + // even it is a periodic task such as + // setInterval + if (!(task.data && task.data.isPeriodic)) { + if (typeof data.handleId === 'number') { + // in non-nodejs env, we remove timerId + // from local cache + delete tasksByHandleId[data.handleId]; + } else if (data.handleId) { + // Node returns complex objects as handleIds + // we remove task reference from timer object + (data.handleId as any)[taskSymbol] = null; + } } } } @@ -62,25 +60,22 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam setNative = patchMethod(window, setName, (delegate: Function) => function(self: any, args: any[]) { - // n is 'function' string - if (typeof args[0] === n) { + if (typeof args[0] === 'function') { // Zone.current - const zone = (Zone as any).c; + const zone = Zone.current; const options: TimerOptions = { handleId: null, isPeriodic: nameSuffix === 'Interval', delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 : null, args: args }; - // Zone.scheduleMacroTask - const task = (zone as any).sc(setName, args[0], options, scheduleTask, clearTask); + const task = zone.scheduleMacroTask(setName, args[0], options, scheduleTask, clearTask); if (!task) { return task; } // Node.js must additionally support the ref and unref functions. const handle: any = (task.data).handleId; - // q is 'number' string - if (typeof handle === q) { + if (typeof handle === 'number') { // for non nodejs env, we save handleId: task // mapping in local cache for clearTimeout tasksByHandleId[handle] = task; @@ -92,14 +87,12 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam // check whether handle is null, because some polyfill or browser // may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame - // n is 'function' string - if (handle && handle.ref && handle.unref && typeof handle.ref === n && - typeof handle.unref === n) { + if (handle && handle.ref && handle.unref && typeof handle.ref === 'function' && + typeof handle.unref === 'function') { (task).ref = (handle).ref.bind(handle); (task).unref = (handle).unref.bind(handle); } - // q is 'number' string - if (typeof handle === q || handle) { + if (typeof handle === 'number' || handle) { return handle; } return task; @@ -113,8 +106,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam patchMethod(window, cancelName, (delegate: Function) => function(self: any, args: any[]) { const id = args[0]; let task: Task; - // q is 'number' string - if (typeof id === q) { + if (typeof id === 'number') { // non nodejs env. task = tasksByHandleId[id]; } else { @@ -125,19 +117,16 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam task = id; } } - // r is 'string' - if (task && typeof task.type === r) { + if (task && typeof task.type === 'string') { if (task.state !== 'notScheduled' && (task.cancelFn && task.data.isPeriodic || task.runCount === 0)) { - // q is 'number' string - if (typeof id === q) { + if (typeof id === 'number') { delete tasksByHandleId[id]; } else if (id) { id[taskSymbol] = null; } // Do not cancel already canceled functions - // zone.cancelTask - (task.zone as any).ct(task); + task.zone.cancelTask(task); } } else { // cause an error by calling it directly. diff --git a/lib/common/to-string.ts b/lib/common/to-string.ts index c2f7a8c9a..a486ff423 100644 --- a/lib/common/to-string.ts +++ b/lib/common/to-string.ts @@ -5,11 +5,11 @@ * 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 */ -import {n, zoneSymbol} from './utils'; +import {zoneSymbol} from './utils'; // override Function.prototype.toString to make zone.js patched function // look like native function -(Zone as any).l('toString', (global: any, Zone: ZoneType) => { +Zone.__load_patch('toString', (global: any, Zone: ZoneType) => { // patch Func.prototype.toString to let them look like native const originalFunctionToString = (Zone as any)['__zone_symbol__originalToString'] = Function.prototype.toString; @@ -18,11 +18,10 @@ import {n, zoneSymbol} from './utils'; const PROMISE_SYMBOL = zoneSymbol('Promise'); const ERROR_SYMBOL = zoneSymbol('Error'); Function.prototype.toString = function() { - // n is 'function' string - if (typeof this === n) { + if (typeof this === 'function') { const originalDelegate = this[ORIGINAL_DELEGATE_SYMBOL]; if (originalDelegate) { - if (typeof originalDelegate === n) { + if (typeof originalDelegate === 'function') { return originalFunctionToString.apply(this[ORIGINAL_DELEGATE_SYMBOL], arguments); } else { return Object.prototype.toString.call(originalDelegate); diff --git a/lib/common/utils.ts b/lib/common/utils.ts index 8ef229442..ba0b6d3f6 100644 --- a/lib/common/utils.ts +++ b/lib/common/utils.ts @@ -14,57 +14,45 @@ // issue #989, to reduce bundle size, use short name /** Object.getOwnPropertyDescriptor */ -export const a = Object.getOwnPropertyDescriptor; +export const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; /** Object.defineProperty */ -export const b = Object.defineProperty; -/** Object.defineProperties */ -export const c = Object.defineProperties; +export const ObjectDefineProperty = Object.defineProperty; /** Object.getPrototypeOf */ -export const d = Object.getPrototypeOf; +export const ObjectGetPrototypeOf = Object.getPrototypeOf; /** Object.create */ -export const e = Object.create; +export const ObjectCreate = Object.create; /** Array.prototype.slice */ -export const f = Array.prototype.slice; +export const ArraySlice = Array.prototype.slice; /** addEventListener string const */ -export const g = 'addEventListener'; +export const ADD_EVENT_LISTENER_STR = 'addEventListener'; /** removeEventListener string const */ -export const h = 'removeEventListener'; +export const REMOVE_EVENT_LISTENER_STR = 'removeEventListener'; /** zoneSymbol addEventListener */ -export const i = (Zone as any).s(g); +export const ZONE_SYMBOL_ADD_EVENT_LISTENER = Zone.__symbol__(ADD_EVENT_LISTENER_STR); /** zoneSymbol removeEventListener */ -export const j = (Zone as any).s(h); +export const ZONE_SYMBOL_REMOVE_EVENT_LISTENER = Zone.__symbol__(REMOVE_EVENT_LISTENER_STR); /** true string const */ -export const k = 'true'; +export const TRUE_STR = 'true'; /** false string const */ -export const l = 'false'; +export const FALSE_STR = 'false'; /** __zone_symbol__ string const */ -export const m = '__zone_symbol__'; -/** function type string const */ -export const n = 'function'; -/** undefined type string const */ -export const o = 'undefined'; -/** object type string const */ -export const p = 'object'; -/** number type string const */ -export const q = 'number'; -/** string type string const */ -export const r = 'string'; +export const ZONE_SYMBOL_PREFIX = '__zone_symbol__'; // Hack since TypeScript isn't compiling this for a worker. declare const WorkerGlobalScope: any; export const zoneSymbol = Zone.__symbol__; -const iw = typeof window !== o; -const w: any = iw ? window : undefined; -const _global: any = iw && w || typeof self === p && self || global; +const isWindowExists = typeof window !== 'undefined'; +const internalWindow: any = isWindowExists ? window : undefined; +const _global: any = isWindowExists && internalWindow || typeof self === 'object' && self || global; const REMOVE_ATTRIBUTE = 'removeAttribute'; const NULL_ON_PROP_VALUE: any[] = [null]; export function bindArguments(args: any[], source: string): any[] { for (let i = args.length - 1; i >= 0; i--) { - if (typeof args[i] === n) { - args[i] = (Zone as any).c.w(args[i], source + '_' + i); + if (typeof args[i] === 'function') { + args[i] = Zone.current.wrap(args[i], source + '_' + i); } } return args; @@ -76,7 +64,7 @@ export function patchPrototype(prototype: any, fnNames: string[]) { const name = fnNames[i]; const delegate = prototype[name]; if (delegate) { - const prototypeDesc = a(prototype, name); + const prototypeDesc = ObjectGetOwnPropertyDescriptor(prototype, name); if (!isPropertyWritable(prototypeDesc)) { continue; } @@ -100,30 +88,27 @@ export function isPropertyWritable(propertyDesc: any) { return false; } - if (typeof propertyDesc.get === n && typeof propertyDesc.set === o) { - return false; - } - - return true; + return !(typeof propertyDesc.get === 'function' && typeof propertyDesc.set === 'undefined'); } export const isWebWorker: boolean = - (typeof WorkerGlobalScope !== o && self instanceof WorkerGlobalScope); + (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope); -// Make sure to access `process` through `_global` so that WebPack does not accidently browserify +// Make sure to access `process` through `_global` so that WebPack does not accidentally browserify // this code. export const isNode: boolean = - (!('nw' in _global) && typeof _global.process !== o && + (!('nw' in _global) && typeof _global.process !== 'undefined' && {}.toString.call(_global.process) === '[object process]'); -export const isBrowser: boolean = !isNode && !isWebWorker && !!(iw && w['HTMLElement']); +export const isBrowser: boolean = + !isNode && !isWebWorker && !!(isWindowExists && internalWindow['HTMLElement']); // we are in electron of nw, so we are both browser and nodejs -// Make sure to access `process` through `_global` so that WebPack does not accidently browserify +// Make sure to access `process` through `_global` so that WebPack does not accidentally browserify // this code. -export const isMix: boolean = typeof _global.process !== o && +export const isMix: boolean = typeof _global.process !== 'undefined' && {}.toString.call(_global.process) === '[object process]' && !isWebWorker && - !!(iw && w['HTMLElement']); + !!(isWindowExists && internalWindow['HTMLElement']); const zoneSymbolEventNames: {[eventName: string]: string} = {}; @@ -149,10 +134,10 @@ const wrapFn = function(event: Event) { }; export function patchProperty(obj: any, prop: string, prototype?: any) { - let desc = a(obj, prop); + let desc = ObjectGetOwnPropertyDescriptor(obj, prop); if (!desc && prototype) { // when patch window object, use prototype to check prop exist or not - const prototypeDesc = a(prototype, prop); + const prototypeDesc = ObjectGetOwnPropertyDescriptor(prototype, prop); if (prototypeDesc) { desc = {enumerable: true, configurable: true}; } @@ -202,7 +187,7 @@ export function patchProperty(obj: any, prop: string, prototype?: any) { originalDescSet.apply(target, NULL_ON_PROP_VALUE); } - if (typeof newValue === n) { + if (typeof newValue === 'function') { target[eventNameSymbol] = newValue; target.addEventListener(eventName, wrapFn, false); } else { @@ -232,10 +217,10 @@ export function patchProperty(obj: any, prop: string, prototype?: any) { // the onclick will be evaluated when first time event was triggered or // the property is accessed, https://github.com/angular/zone.js/issues/525 // so we should use original native get to retrieve the handler - let value = originalDescGet && originalDescGet.apply(this); + let value = originalDescGet && originalDescGet.call(this); if (value) { - desc.set.apply(this, [value]); - if (typeof target[REMOVE_ATTRIBUTE] === n) { + desc.set.call(this, value); + if (typeof target[REMOVE_ATTRIBUTE] === 'function') { target.removeAttribute(prop); } return value; @@ -244,7 +229,7 @@ export function patchProperty(obj: any, prop: string, prototype?: any) { return null; }; - b(obj, prop, desc); + ObjectDefineProperty(obj, prop, desc); } export function patchOnProperties(obj: any, properties: string[], prototype?: any) { @@ -307,15 +292,15 @@ export function patchClass(className: string) { // https://bugs.webkit.org/show_bug.cgi?id=44721 if (className === 'XMLHttpRequest' && prop === 'responseBlob') continue; (function(prop) { - if (typeof instance[prop] === n) { + if (typeof instance[prop] === 'function') { _global[className].prototype[prop] = function() { return this[originalInstanceKey][prop].apply(this[originalInstanceKey], arguments); }; } else { - b(_global[className].prototype, prop, { + ObjectDefineProperty(_global[className].prototype, prop, { set: function(fn) { - if (typeof fn === n) { - this[originalInstanceKey][prop] = (Zone as any).c.w(fn, className + '.' + prop); + if (typeof fn === 'function') { + this[originalInstanceKey][prop] = Zone.current.wrap(fn, className + '.' + prop); // keep callback in wrapped function so we can // use it in Function.prototype.toString to return // the native one. @@ -345,7 +330,7 @@ export function patchMethod( any): Function { let proto = target; while (proto && !proto.hasOwnProperty(name)) { - proto = d(proto); + proto = ObjectGetPrototypeOf(proto); } if (!proto && target[name]) { // somehow we did not find it, but we can see it. This happens on IE for Window properties. @@ -358,7 +343,7 @@ export function patchMethod( delegate = proto[delegateName] = proto[name]; // check whether proto[name] is writable // some property is readonly in safari, such as HtmlCanvasElement.prototype.toBlob - const desc = proto && a(proto, name); + const desc = proto && ObjectGetOwnPropertyDescriptor(proto, name); if (isPropertyWritable(desc)) { const patchDelegate = patchFn(delegate, delegateName, name); proto[name] = function() { @@ -393,9 +378,8 @@ export function patchMacroTask( setNative = patchMethod(obj, funcName, (delegate: Function) => function(self: any, args: any[]) { const meta = metaCreator(self, args); - if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === n) { - const task = (Zone as any).c.sc(meta.name, args[meta.cbIdx], meta, scheduleTask, null); - return task; + if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') { + return Zone.current.scheduleMacroTask(meta.name, args[meta.cbIdx], meta, scheduleTask, null); } else { // cause an error by calling it directly. return delegate.apply(self, args); @@ -425,9 +409,8 @@ export function patchMicroTask( setNative = patchMethod(obj, funcName, (delegate: Function) => function(self: any, args: any[]) { const meta = metaCreator(self, args); - if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === n) { - const task = (Zone as any).c.si(meta.name, args[meta.cbIdx], meta, scheduleTask); - return task; + if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') { + return Zone.current.scheduleMicroTask(meta.name, args[meta.cbIdx], meta, scheduleTask); } else { // cause an error by calling it directly. return delegate.apply(self, args); @@ -450,7 +433,7 @@ export function isIEOrEdge() { isDetectedIEOrEdge = true; try { - const ua = w.navigator.userAgent; + const ua = internalWindow.navigator.userAgent; if (ua.indexOf('MSIE ') !== -1 || ua.indexOf('Trident/') !== -1 || ua.indexOf('Edge/') !== -1) { ieOrEdge = true; } diff --git a/lib/extra/bluebird.ts b/lib/extra/bluebird.ts index d3f9b9cca..dd7f27743 100644 --- a/lib/extra/bluebird.ts +++ b/lib/extra/bluebird.ts @@ -5,7 +5,7 @@ * 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 */ -(Zone as any).l('bluebird', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('bluebird', (global: any, Zone: ZoneType) => { // TODO: @JiaLiPassion, we can automatically patch bluebird // if global.Promise = Bluebird, but sometimes in nodejs, // global.Promise is not Bluebird, and Bluebird is just be @@ -14,7 +14,7 @@ const BLUEBIRD = 'bluebird'; (Zone as any)[Zone.__symbol__(BLUEBIRD)] = function patchBluebird(Bluebird: any) { Bluebird.setScheduler((fn: Function) => { - (Zone as any).c.si(BLUEBIRD, fn); + Zone.current.scheduleMicroTask(BLUEBIRD, fn); }); }; }); diff --git a/lib/extra/cordova.ts b/lib/extra/cordova.ts index 4d32a46a0..0365248ec 100644 --- a/lib/extra/cordova.ts +++ b/lib/extra/cordova.ts @@ -5,25 +5,25 @@ * 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 */ -(Zone as any).l('cordova', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('cordova', (global: any, Zone: ZoneType, api: _ZonePrivate) => { if (global.cordova) { const SUCCESS_SOURCE = 'cordova.exec.success'; const ERROR_SOURCE = 'cordova.exec.error'; const FUNCTION = 'function'; - const nativeExec: Function = api.patchMethod( - global.cordova, 'exec', (delegate: Function) => function(self: any, args: any[]) { + const nativeExec: Function = + api.patchMethod(global.cordova, 'exec', () => function(self: any, args: any[]) { if (args.length > 0 && typeof args[0] === FUNCTION) { - args[0] = (Zone as any).c.w(args[0], SUCCESS_SOURCE); + args[0] = Zone.current.wrap(args[0], SUCCESS_SOURCE); } if (args.length > 1 && typeof args[1] === FUNCTION) { - args[1] = (Zone as any).c.w(args[1], ERROR_SOURCE); + args[1] = Zone.current.wrap(args[1], ERROR_SOURCE); } return nativeExec.apply(self, args); }); } }); -(Zone as any).l('cordova.FileReader', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('cordova.FileReader', (global: any, Zone: ZoneType) => { if (global.cordova && typeof global['FileReader'] !== 'undefined') { document.addEventListener('deviceReady', () => { const FileReader = global['FileReader']; diff --git a/lib/extra/electron.ts b/lib/extra/electron.ts index 9ed842b21..eee5b552b 100644 --- a/lib/extra/electron.ts +++ b/lib/extra/electron.ts @@ -5,13 +5,13 @@ * 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 */ -(Zone as any).l('electron', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('electron', (global: any, Zone: ZoneType, api: _ZonePrivate) => { function patchArguments(target: any, name: string, source: string): Function { return api.patchMethod(target, name, (delegate: Function) => (self: any, args: any[]) => { return delegate && delegate.apply(self, api.bindArguments(args, source)); }); } - const {desktopCapturer, shell, CallbackRegistry} = require('electron'); + const {desktopCapturer, shell, CallbacksRegistry} = require('electron'); // patch api in renderer process directly // desktopCapturer if (desktopCapturer) { @@ -23,9 +23,9 @@ } // patch api in main process through CallbackRegistry - if (!CallbackRegistry) { + if (!CallbacksRegistry) { return; } - patchArguments(CallbackRegistry.prototype, 'add', 'CallbackRegistry.add'); + patchArguments(CallbacksRegistry.prototype, 'add', 'CallbackRegistry.add'); }); diff --git a/lib/node/events.ts b/lib/node/events.ts index 223721f1d..d7eda2596 100644 --- a/lib/node/events.ts +++ b/lib/node/events.ts @@ -6,16 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {ens, gs, patchEventTarget} from '../common/events'; - -(Zone as any).l('EventEmitter', (global: any, Zone: ZoneType, api: _ZonePrivate) => { - const callAndReturnFirstParam = (fn: (self: any, args: any[]) => any) => { - return (self: any, args: any[]) => { - fn(self, args); - return self; - }; - }; +import {patchEventTarget} from '../common/events'; +Zone.__load_patch('EventEmitter', (global: any) => { // For EventEmitter const EE_ADD_LISTENER = 'addListener'; const EE_PREPEND_LISTENER = 'prependListener'; @@ -25,11 +18,8 @@ import {ens, gs, patchEventTarget} from '../common/events'; const EE_ON = 'on'; const compareTaskCallbackVsDelegate = function(task: any, delegate: any) { - if (task.callback === delegate || task.callback.listener === delegate) { - // same callback, same capture, same event name, just return - return true; - } - return false; + // same callback, same capture, same event name, just return + return task.callback === delegate || task.callback.listener === delegate; }; function patchEventEmitterMethods(obj: any) { diff --git a/lib/node/fs.ts b/lib/node/fs.ts index 11c115436..9af536abc 100644 --- a/lib/node/fs.ts +++ b/lib/node/fs.ts @@ -8,7 +8,7 @@ import {patchMacroTask} from '../common/utils'; -(Zone as any).l('fs', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('fs', () => { let fs: any; try { fs = require('fs'); diff --git a/lib/node/node.ts b/lib/node/node.ts index 388d00195..b4ab2f9e6 100644 --- a/lib/node/node.ts +++ b/lib/node/node.ts @@ -11,18 +11,18 @@ import './fs'; import {findEventTasks} from '../common/events'; import {patchTimer} from '../common/timers'; -import {bindArguments, f, isMix, patchMacroTask, patchMethod, patchMicroTask, patchOnProperties} from '../common/utils'; +import {ArraySlice, bindArguments, isMix, patchMacroTask, patchMethod, patchMicroTask, patchOnProperties} from '../common/utils'; const set = 'set'; const clear = 'clear'; -(Zone as any).l('node_util', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('node_util', (global: any, Zone: ZoneType, api: _ZonePrivate) => { api.patchOnProperties = patchOnProperties; api.patchMethod = patchMethod; api.bindArguments = bindArguments; }); -(Zone as any).l('node_timers', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('node_timers', (global: any, Zone: ZoneType) => { // Timers let globalUseTimeoutFromTimer = false; try { @@ -47,7 +47,7 @@ const clear = 'clear'; patchTimer(timers, set, clear, 'Interval'); patchTimer(timers, set, clear, 'Immediate'); } catch (error) { - // timers module not exists, for example, when we using nativescript + // timers module not exists, for example, when we using nativeScript // timers is not available } if (isMix) { @@ -65,7 +65,7 @@ const clear = 'clear'; patchTimer(global, set, clear, 'Immediate'); } else { // global use timers setTimeout, but not equals - // this happenes when use nodejs v0.10.x, global setTimeout will + // this happens when use nodejs v0.10.x, global setTimeout will // use a lazy load version of timers setTimeout // we should not double patch timer's setTimeout // so we only store the __symbol__ for consistency @@ -76,7 +76,7 @@ const clear = 'clear'; }); // patch process related methods -(Zone as any).l('nextTick', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('nextTick', () => { // patch nextTick as microTask patchMicroTask(process, 'nextTick', (self: any, args: any[]) => { return { @@ -88,8 +88,8 @@ const clear = 'clear'; }); }); -(Zone as any) - .l('handleUnhandledPromiseRejection', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch( + 'handleUnhandledPromiseRejection', (global: any, Zone: ZoneType, api: _ZonePrivate) => { (Zone as any)[api.symbol('unhandledPromiseRejectionHandler')] = findProcessPromiseRejectionHandler('unhandledRejection'); @@ -116,7 +116,7 @@ const clear = 'clear'; // Crypto -(Zone as any).l('crypto', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('crypto', () => { let crypto: any; try { crypto = require('crypto'); @@ -141,15 +141,15 @@ const clear = 'clear'; } }); -(Zone as any).l('console', (global: any, Zone: ZoneType, api: _ZonePrivate) => { +Zone.__load_patch('console', (global: any, Zone: ZoneType) => { const consoleMethods = ['dir', 'log', 'info', 'error', 'warn', 'assert', 'debug', 'timeEnd', 'trace']; consoleMethods.forEach((m: string) => { const originalMethod = (console as any)[Zone.__symbol__(m)] = (console as any)[m]; if (originalMethod) { (console as any)[m] = function() { - const args = f.call(arguments); - if ((Zone as any).c === Zone.root) { + const args = ArraySlice.call(arguments); + if (Zone.current === Zone.root) { return originalMethod.apply(this, args); } else { return Zone.root.run(originalMethod, this, args); diff --git a/lib/rxjs/rxjs.ts b/lib/rxjs/rxjs.ts index 11c116b8a..71344a460 100644 --- a/lib/rxjs/rxjs.ts +++ b/lib/rxjs/rxjs.ts @@ -25,6 +25,8 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber'; const errorSource = 'rxjs.Subscriber.error'; const completeSource = 'rxjs.Subscriber.complete'; + const ObjectDefineProperties = Object.defineProperties; + const empty = { closed: true, next(value: any): void{}, @@ -58,7 +60,7 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber'; const _subscribe = ObservablePrototype[_symbolSubscribe] = ObservablePrototype._subscribe; const subscribe = ObservablePrototype[symbolSubscribe] = ObservablePrototype.subscribe; - Object.defineProperties(Observable.prototype, { + ObjectDefineProperties(Observable.prototype, { _zone: {value: null, writable: true, configurable: true}, _zoneSource: {value: null, writable: true, configurable: true}, _zoneSubscribe: {value: null, writable: true, configurable: true}, @@ -109,7 +111,7 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber'; const unsubscribeSymbol = symbol('unsubscribe'); const unsubscribe = (Subscription.prototype as any)[unsubscribeSymbol] = Subscription.prototype.unsubscribe; - Object.defineProperties(Subscription.prototype, { + ObjectDefineProperties(Subscription.prototype, { _zone: {value: null, writable: true, configurable: true}, _zoneUnsubscribe: {value: null, writable: true, configurable: true}, _unsubscribe: { @@ -341,7 +343,7 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber'; return work.apply(this, arguments); } }; - return schedule.apply(this, [patchedWork, delay, state]); + return schedule.call(this, patchedWork, delay, state); }; }; diff --git a/lib/zone-spec/fake-async-test.ts b/lib/zone-spec/fake-async-test.ts index 31f1fae35..72ef0e115 100644 --- a/lib/zone-spec/fake-async-test.ts +++ b/lib/zone-spec/fake-async-test.ts @@ -182,7 +182,7 @@ namePrefix: string, private trackPendingRequestAnimationFrame = false, private macroTaskOptions?: MacroTaskOptions[]) { this.name = 'fakeAsyncTestZone for ' + namePrefix; - // in case user can't access the construction of FakyAsyncTestSpec + // in case user can't access the construction of FakeAsyncTestSpec // user can also define macroTaskOptions by define a global variable. if (!this.macroTaskOptions) { this.macroTaskOptions = global[Zone.__symbol__('FakeAsyncTestMacroTask')]; @@ -328,16 +328,16 @@ // should pass additional arguments to callback if have any // currently we know process.nextTick will have such additional // arguments - let addtionalArgs: any[]; + let additionalArgs: any[]; if (args) { let callbackIndex = (task.data as any).cbIdx; if (typeof args.length === 'number' && args.length > callbackIndex + 1) { - addtionalArgs = Array.prototype.slice.call(args, callbackIndex + 1); + additionalArgs = Array.prototype.slice.call(args, callbackIndex + 1); } } this._microtasks.push({ func: task.invoke, - args: addtionalArgs, + args: additionalArgs, target: task.data && (task.data as any).target }); break; @@ -378,7 +378,7 @@ task.data['handleId'] = this._setInterval(task.invoke, delay, callbackArgs); task.data.isPeriodic = true; } else { - // not periodic, use setTimout to simulate + // not periodic, use setTimeout to simulate task.data['handleId'] = this._setTimeout(task.invoke, delay, callbackArgs); } break; diff --git a/lib/zone.ts b/lib/zone.ts index 43df0a7a5..76efc031a 100644 --- a/lib/zone.ts +++ b/lib/zone.ts @@ -656,7 +656,7 @@ const Zone: ZoneType = (function(global: any) { } static get root(): AmbientZone { - let zone = Zone.c; + let zone = Zone.current; while (zone.parent) { zone = zone.parent; } @@ -667,10 +667,6 @@ const Zone: ZoneType = (function(global: any) { return _currentZoneFrame.zone; } - static get c(): AmbientZone { - return _currentZoneFrame.zone; - } - static get currentTask(): Task { return _currentTask; } @@ -1176,7 +1172,7 @@ const Zone: ZoneType = (function(global: any) { this.invoke = ZoneTask.invokeTask; } else { this.invoke = function() { - return ZoneTask.invokeTask.apply(global, [self, this, arguments]); + return ZoneTask.invokeTask.call(global, self, this, arguments); }; } } @@ -1292,7 +1288,6 @@ const Zone: ZoneType = (function(global: any) { } } } - const showError: boolean = !(Zone as any)[__symbol__('ignoreConsoleErrorUncaughtError')]; _api.microtaskDrainDone(); _isDrainingMicrotaskQueue = false; } @@ -1344,30 +1339,5 @@ const Zone: ZoneType = (function(global: any) { } performanceMeasure('Zone', 'Zone'); - const z: any = Zone.prototype; - /** shorter for Zone.prototype.wrap */ - z.w = z.wrap; - /** shorter for Zone.prototype.fork */ - z.f = z.fork; - /** shorter for Zone.prototype.run */ - z.r = z.run; - /** shorter for Zone.prototype.runGuarded */ - z.rg = z.runGuarded; - /** shorter for Zone.prototype.runTask */ - z.rt = z.runTask; - /** shorter for Zone.prototype.scheduleTask */ - z.st = z.scheduleTask; - /** shorter for Zone.prototype.scheduleMacroTask */ - z.sc = z.scheduleMacroTask; - /** shorter for Zone.prototype.scheduleMicroTask */ - z.si = z.scheduleMicroTask; - /** shorter for Zone.prototype.scheduleEventTask */ - z.se = z.scheduleEventTask; - /** shorter for Zone.prototype.cancelTask */ - z.ct = z.cancelTask; - /** shorter for Zone.__load_patch */ - (Zone as any).l = Zone.__load_patch; - /** shorter for Zone.__symbol__ */ - (Zone as any).s = Zone.__symbol__; return global['Zone'] = Zone; })(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global); diff --git a/test/closure/zone.closure.ts b/test/closure/zone.closure.ts index 3e5cc3470..b065efde1 100644 --- a/test/closure/zone.closure.ts +++ b/test/closure/zone.closure.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ import '../../dist/zone-node'; -const shortKeys = ['w', 'f', 'r', 'rg', 'rt', 'st', 'sc', 'si', 'se', 'ct']; const testClosureFunction = () => { const logs: string[] = []; // call all Zone exposed functions @@ -69,9 +68,7 @@ const testClosureFunction = () => { logs.push('get' + keyZone.get('key')); logs.push('root' + Zone.root.name); Object.keys((Zone as any).prototype).forEach(key => { - if (shortKeys.indexOf(key) === -1) { - logs.push(key); - } + logs.push(key); }); Object.keys(testZoneSpec).forEach(key => { logs.push(key); From 48ebd3e2c4db3d99ae8f125cacf91d6588b3d6e8 Mon Sep 17 00:00:00 2001 From: "JiaLi.Passion" Date: Tue, 9 Jan 2018 16:07:35 +0900 Subject: [PATCH 7/7] fix(core): add helper method in util.ts to shorter zone.wrap/scehduleMacroTask --- lib/browser/browser.ts | 5 ++--- lib/browser/property-descriptor.ts | 4 ++-- lib/browser/register-element.ts | 8 ++++---- lib/common/timers.ts | 7 +++---- lib/common/utils.ts | 17 ++++++++++++++--- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/lib/browser/browser.ts b/lib/browser/browser.ts index 78f51ebcc..bba9994d7 100644 --- a/lib/browser/browser.ts +++ b/lib/browser/browser.ts @@ -12,7 +12,7 @@ import {findEventTasks} from '../common/events'; import {patchTimer} from '../common/timers'; -import {bindArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, 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'; @@ -179,7 +179,6 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => { const XMLHTTPREQUEST_SOURCE = 'XMLHttpRequest.send'; const sendNative: Function = patchMethod(XMLHttpRequestPrototype, 'send', () => function(self: any, args: any[]) { - const zone = Zone.current; if (self[XHR_SYNC]) { // if the XHR is sync there is no task to schedule, just execute the code. return sendNative.apply(self, args); @@ -192,7 +191,7 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => { args: args, aborted: false }; - return zone.scheduleMacroTask( + return scheduleMacroTaskWithCurrentZone( XMLHTTPREQUEST_SOURCE, placeholderCallback, options, scheduleTask, clearTask); } }); diff --git a/lib/browser/property-descriptor.ts b/lib/browser/property-descriptor.ts index 00ac86b1c..c381abfda 100644 --- a/lib/browser/property-descriptor.ts +++ b/lib/browser/property-descriptor.ts @@ -10,7 +10,7 @@ * @suppress {globalThis} */ -import {isBrowser, isMix, isNode, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, ObjectGetPrototypeOf, patchClass, patchOnProperties, zoneSymbol} from '../common/utils'; +import {isBrowser, isMix, isNode, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, ObjectGetPrototypeOf, patchClass, patchOnProperties, wrapWithCurrentZone, zoneSymbol} from '../common/utils'; import * as webSocketPatch from './websocket'; @@ -402,7 +402,7 @@ function patchViaCapturingAllTheEvents() { } while (elt) { if (elt[onproperty] && !elt[onproperty][unboundKey]) { - bound = Zone.current.wrap(elt[onproperty], source); + bound = wrapWithCurrentZone(elt[onproperty], source); bound[unboundKey] = elt[onproperty]; elt[onproperty] = bound; } diff --git a/lib/browser/register-element.ts b/lib/browser/register-element.ts index d558e2dd1..aa1abbd7a 100644 --- a/lib/browser/register-element.ts +++ b/lib/browser/register-element.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {attachOriginToPatched, isBrowser, isMix, ObjectGetOwnPropertyDescriptor} from '../common/utils'; +import {attachOriginToPatched, isBrowser, isMix, ObjectGetOwnPropertyDescriptor, wrapWithCurrentZone} from '../common/utils'; import {_redefineProperty} from './define-property'; @@ -27,13 +27,13 @@ export function registerElementPatch(_global: any) { if (prototype.hasOwnProperty(callback)) { const descriptor = ObjectGetOwnPropertyDescriptor(prototype, callback); if (descriptor && descriptor.value) { - descriptor.value = Zone.current.wrap(descriptor.value, source); + descriptor.value = wrapWithCurrentZone(descriptor.value, source); _redefineProperty(opts.prototype, callback, descriptor); } else { - prototype[callback] = Zone.current.wrap(prototype[callback], source); + prototype[callback] = wrapWithCurrentZone(prototype[callback], source); } } else if (prototype[callback]) { - prototype[callback] = Zone.current.wrap(prototype[callback], source); + prototype[callback] = wrapWithCurrentZone(prototype[callback], source); } }); } diff --git a/lib/common/timers.ts b/lib/common/timers.ts index 1185f8a23..bdec80baf 100644 --- a/lib/common/timers.ts +++ b/lib/common/timers.ts @@ -10,7 +10,7 @@ * @suppress {missingRequire} */ -import {patchMethod, zoneSymbol} from './utils'; +import {patchMethod, scheduleMacroTaskWithCurrentZone, zoneSymbol} from './utils'; const taskSymbol = zoneSymbol('zoneTask'); @@ -61,15 +61,14 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam setNative = patchMethod(window, setName, (delegate: Function) => function(self: any, args: any[]) { if (typeof args[0] === 'function') { - // Zone.current - const zone = Zone.current; const options: TimerOptions = { handleId: null, isPeriodic: nameSuffix === 'Interval', delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 : null, args: args }; - const task = zone.scheduleMacroTask(setName, args[0], options, scheduleTask, clearTask); + const task = + scheduleMacroTaskWithCurrentZone(setName, args[0], options, scheduleTask, clearTask); if (!task) { return task; } diff --git a/lib/common/utils.ts b/lib/common/utils.ts index ba0b6d3f6..958bd863d 100644 --- a/lib/common/utils.ts +++ b/lib/common/utils.ts @@ -38,6 +38,16 @@ export const FALSE_STR = 'false'; /** __zone_symbol__ string const */ export const ZONE_SYMBOL_PREFIX = '__zone_symbol__'; +export function wrapWithCurrentZone(callback: T, source: string): T { + return Zone.current.wrap(callback, source); +} + +export function scheduleMacroTaskWithCurrentZone( + source: string, callback: Function, data: TaskData, customSchedule: (task: Task) => void, + customCancel: (task: Task) => void): MacroTask { + return Zone.current.scheduleMacroTask(source, callback, data, customSchedule, customCancel); +} + // Hack since TypeScript isn't compiling this for a worker. declare const WorkerGlobalScope: any; @@ -52,7 +62,7 @@ const NULL_ON_PROP_VALUE: any[] = [null]; export function bindArguments(args: any[], source: string): any[] { for (let i = args.length - 1; i >= 0; i--) { if (typeof args[i] === 'function') { - args[i] = Zone.current.wrap(args[i], source + '_' + i); + args[i] = wrapWithCurrentZone(args[i], source + '_' + i); } } return args; @@ -300,7 +310,7 @@ export function patchClass(className: string) { ObjectDefineProperty(_global[className].prototype, prop, { set: function(fn) { if (typeof fn === 'function') { - this[originalInstanceKey][prop] = Zone.current.wrap(fn, className + '.' + prop); + this[originalInstanceKey][prop] = wrapWithCurrentZone(fn, className + '.' + prop); // keep callback in wrapped function so we can // use it in Function.prototype.toString to return // the native one. @@ -379,7 +389,8 @@ export function patchMacroTask( setNative = patchMethod(obj, funcName, (delegate: Function) => function(self: any, args: any[]) { const meta = metaCreator(self, args); if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') { - return Zone.current.scheduleMacroTask(meta.name, args[meta.cbIdx], meta, scheduleTask, null); + return scheduleMacroTaskWithCurrentZone( + meta.name, args[meta.cbIdx], meta, scheduleTask, null); } else { // cause an error by calling it directly. return delegate.apply(self, args);