diff --git a/integration/_payload-limits.json b/integration/_payload-limits.json index edcb9b1800981..1b13ca56bd3a5 100644 --- a/integration/_payload-limits.json +++ b/integration/_payload-limits.json @@ -3,7 +3,7 @@ "master": { "uncompressed": { "runtime": 1497, - "main": 164945, + "main": 166739, "polyfills": 43626 } } diff --git a/integration/side-effects/snapshots/animations-browser/esm2015.js b/integration/side-effects/snapshots/animations-browser/esm2015.js index 780ec46ce9af9..a23be397a1edf 100644 --- a/integration/side-effects/snapshots/animations-browser/esm2015.js +++ b/integration/side-effects/snapshots/animations-browser/esm2015.js @@ -1,14 +1,3 @@ import "@angular/animations"; import "@angular/core"; - -function isNode() { - return "undefined" !== typeof process; -} - -const _isNode = isNode(); - -if (_isNode || "undefined" !== typeof Element) if (_isNode || Element.prototype.matches) ; else { - const proto = Element.prototype; - const fn = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector; -} diff --git a/integration/side-effects/snapshots/animations-browser/esm5.js b/integration/side-effects/snapshots/animations-browser/esm5.js index 729322a2d502a..58aec1ffc5c05 100644 --- a/integration/side-effects/snapshots/animations-browser/esm5.js +++ b/integration/side-effects/snapshots/animations-browser/esm5.js @@ -3,14 +3,3 @@ import "tslib"; import "@angular/animations"; import "@angular/core"; - -function isNode() { - return "undefined" !== typeof process; -} - -var _isNode = isNode(); - -if (_isNode || "undefined" !== typeof Element) if (_isNode || Element.prototype.matches) ; else { - var proto = Element.prototype; - var fn_1 = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector; -} diff --git a/integration/side-effects/snapshots/elements/esm2015.js b/integration/side-effects/snapshots/elements/esm2015.js index 0e8151832e5a8..38f33e40ed9f2 100644 --- a/integration/side-effects/snapshots/elements/esm2015.js +++ b/integration/side-effects/snapshots/elements/esm2015.js @@ -3,7 +3,3 @@ import "@angular/core"; import "rxjs"; import "rxjs/operators"; - -const elProto = Element.prototype; - -const matches = elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector || elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector; diff --git a/integration/side-effects/snapshots/elements/esm5.js b/integration/side-effects/snapshots/elements/esm5.js index 07189e8bada0e..4500888aa361c 100644 --- a/integration/side-effects/snapshots/elements/esm5.js +++ b/integration/side-effects/snapshots/elements/esm5.js @@ -5,7 +5,3 @@ import "@angular/core"; import "rxjs"; import "rxjs/operators"; - -var elProto = Element.prototype; - -var matches = elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector || elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector; diff --git a/integration/side-effects/snapshots/platform-browser/esm2015.js b/integration/side-effects/snapshots/platform-browser/esm2015.js index 62cb36ba1424a..aa3513a1903ce 100644 --- a/integration/side-effects/snapshots/platform-browser/esm2015.js +++ b/integration/side-effects/snapshots/platform-browser/esm2015.js @@ -1,17 +1,3 @@ import "@angular/common"; -import { ɵglobal } from "@angular/core"; - -let nodeContains; - -if (ɵglobal["Node"]) nodeContains = ɵglobal["Node"].prototype.contains || function(node) { - return !!(16 & this.compareDocumentPosition(node)); -}; - -const ɵ0 = function(v) { - return "__zone_symbol__" + v; -}; - -const __symbol__ = "undefined" !== typeof Zone && Zone["__symbol__"] || ɵ0; - -const blackListedEvents = "undefined" !== typeof Zone && Zone[__symbol__("BLACK_LISTED_EVENTS")]; +import "@angular/core"; diff --git a/integration/side-effects/snapshots/platform-browser/esm5.js b/integration/side-effects/snapshots/platform-browser/esm5.js index 3608753e37220..013438f34070c 100644 --- a/integration/side-effects/snapshots/platform-browser/esm5.js +++ b/integration/side-effects/snapshots/platform-browser/esm5.js @@ -2,18 +2,4 @@ import "tslib"; import "@angular/common"; -import { ɵglobal } from "@angular/core"; - -var nodeContains; - -if (ɵglobal["Node"]) nodeContains = ɵglobal["Node"].prototype.contains || function(node) { - return !!(16 & this.compareDocumentPosition(node)); -}; - -var ɵ0 = function(v) { - return "__zone_symbol__" + v; -}; - -var __symbol__ = "undefined" !== typeof Zone && Zone["__symbol__"] || ɵ0; - -var blackListedEvents = "undefined" !== typeof Zone && Zone[__symbol__("BLACK_LISTED_EVENTS")]; +import "@angular/core"; diff --git a/package.json b/package.json index 8f99a0ad9e300..c3cfaa216cb72 100644 --- a/package.json +++ b/package.json @@ -155,6 +155,7 @@ "sauce-connect": "https://saucelabs.com/downloads/sc-4.5.1-linux.tar.gz", "semver": "5.4.1", "tslint-eslint-rules": "4.1.1", + "tslint-no-toplevel-property-access": "0.0.2", "tsutils": "2.27.2", "universal-analytics": "0.4.15", "vlq": "0.2.2", diff --git a/packages/animations/browser/src/dsl/style_normalization/web_animations_style_normalizer.ts b/packages/animations/browser/src/dsl/style_normalization/web_animations_style_normalizer.ts index 2a79684e9081c..9cefed0d08284 100644 --- a/packages/animations/browser/src/dsl/style_normalization/web_animations_style_normalizer.ts +++ b/packages/animations/browser/src/dsl/style_normalization/web_animations_style_normalizer.ts @@ -34,9 +34,10 @@ export class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer { } } -const DIMENSIONAL_PROP_MAP = makeBooleanMap( - 'width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective' - .split(',')); +const DIMENSIONAL_PROP_MAP = + (() => makeBooleanMap( + 'width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective' + .split(',')))(); function makeBooleanMap(keys: string[]): {[key: string]: boolean} { const map: {[key: string]: boolean} = {}; diff --git a/packages/animations/browser/src/render/shared.ts b/packages/animations/browser/src/render/shared.ts index 9d769e0b2f82a..81f769d71371f 100644 --- a/packages/animations/browser/src/render/shared.ts +++ b/packages/animations/browser/src/render/shared.ts @@ -158,16 +158,20 @@ if (_isNode || typeof Element !== 'undefined') { // this is well supported in all browsers _contains = (elm1: any, elm2: any) => { return elm1.contains(elm2) as boolean; }; - if (_isNode || Element.prototype.matches) { - _matches = (element: any, selector: string) => element.matches(selector); - } else { - const proto = Element.prototype as any; - const fn = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || - proto.oMatchesSelector || proto.webkitMatchesSelector; - if (fn) { - _matches = (element: any, selector: string) => fn.apply(element, [selector]); + _matches = (() => { + if (_isNode || Element.prototype.matches) { + return (element: any, selector: string) => element.matches(selector); + } else { + const proto = Element.prototype as any; + const fn = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || + proto.oMatchesSelector || proto.webkitMatchesSelector; + if (fn) { + return (element: any, selector: string) => fn.apply(element, [selector]); + } else { + return _matches; + } } - } + })(); _query = (element: any, selector: string, multi: boolean): any[] => { let results: any[] = []; diff --git a/packages/core/src/di/injector.ts b/packages/core/src/di/injector.ts index cff4e614e71a3..3216018e5a694 100644 --- a/packages/core/src/di/injector.ts +++ b/packages/core/src/di/injector.ts @@ -117,7 +117,6 @@ const enum OptionFlags { CheckParent = 1 << 2, Default = CheckSelf | CheckParent } -const NULL_INJECTOR = Injector.NULL; const NO_NEW_LINE = 'ɵ'; export class StaticInjector implements Injector { @@ -127,7 +126,7 @@ export class StaticInjector implements Injector { private _records: Map; constructor( - providers: StaticProvider[], parent: Injector = NULL_INJECTOR, source: string|null = null) { + providers: StaticProvider[], parent: Injector = Injector.NULL, source: string|null = null) { this.parent = parent; this.source = source; const records = this._records = new Map(); @@ -304,7 +303,7 @@ function resolveToken( records, // If we don't know how to resolve dependency and we should not check parent for it, // than pass in Null injector. - !childRecord && !(options & OptionFlags.CheckParent) ? NULL_INJECTOR : parent, + !childRecord && !(options & OptionFlags.CheckParent) ? Injector.NULL : parent, options & OptionFlags.Optional ? null : Injector.THROW_IF_NOT_FOUND, InjectFlags.Default)); } diff --git a/packages/core/src/render3/empty.ts b/packages/core/src/render3/empty.ts index a3870a64cda26..d0494193fd7c8 100644 --- a/packages/core/src/render3/empty.ts +++ b/packages/core/src/render3/empty.ts @@ -19,6 +19,10 @@ export const EMPTY_ARRAY: any[] = []; // freezing the values prevents any code from accidentally inserting new values in if (typeof ngDevMode !== 'undefined' && ngDevMode) { + // These property accesses can be ignored because ngDevMode will be set to false + // when optimizing code and the whole if statement will be dropped. + // tslint:disable-next-line:no-toplevel-property-access Object.freeze(EMPTY_OBJ); + // tslint:disable-next-line:no-toplevel-property-access Object.freeze(EMPTY_ARRAY); } diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index 096af666226cd..d7f049f99b895 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -45,7 +45,7 @@ import {getComponentViewByIndex, getNativeByIndex, getNativeByTNode, getTNode, i * A permanent marker promise which signifies that the current CD tree is * clean. */ -const _CLEAN_PROMISE = Promise.resolve(null); +const _CLEAN_PROMISE = (() => Promise.resolve(null))(); export const enum BindingDirection { Input, diff --git a/packages/core/src/render3/interfaces/injector.ts b/packages/core/src/render3/interfaces/injector.ts index e3c0e5541e7a7..5fc27c72fe023 100644 --- a/packages/core/src/render3/interfaces/injector.ts +++ b/packages/core/src/render3/interfaces/injector.ts @@ -241,10 +241,10 @@ export class NodeInjectorFactory { } } -const FactoryPrototype = NodeInjectorFactory.prototype; export function isFactory(obj: any): obj is NodeInjectorFactory { // See: https://jsperf.com/instanceof-vs-getprototypeof - return obj !== null && typeof obj == 'object' && Object.getPrototypeOf(obj) == FactoryPrototype; + return obj !== null && typeof obj == 'object' && + Object.getPrototypeOf(obj) == NodeInjectorFactory.prototype; } // Note: This hack is necessary so we don't erroneously get a circular dependency diff --git a/packages/core/src/render3/jit/environment.ts b/packages/core/src/render3/jit/environment.ts index e4a070f611182..1518a0e7f62e8 100644 --- a/packages/core/src/render3/jit/environment.ts +++ b/packages/core/src/render3/jit/environment.ts @@ -17,125 +17,126 @@ import * as sanitization from '../../sanitization/sanitization'; * * This should be kept up to date with the public exports of @angular/core. */ -export const angularCoreEnv: {[name: string]: Function} = { - 'ΔdefineBase': r3.ΔdefineBase, - 'ΔdefineComponent': r3.ΔdefineComponent, - 'ΔdefineDirective': r3.ΔdefineDirective, - 'ΔdefineInjectable': ΔdefineInjectable, - 'ΔdefineInjector': ΔdefineInjector, - 'ΔdefineNgModule': r3.ΔdefineNgModule, - 'ΔdefinePipe': r3.ΔdefinePipe, - 'ΔdirectiveInject': r3.ΔdirectiveInject, - 'ΔgetFactoryOf': r3.ΔgetFactoryOf, - 'ΔgetInheritedFactory': r3.ΔgetInheritedFactory, - 'Δinject': Δinject, - 'ΔinjectAttribute': r3.ΔinjectAttribute, - 'ΔtemplateRefExtractor': r3.ΔtemplateRefExtractor, - 'ΔNgOnChangesFeature': r3.ΔNgOnChangesFeature, - 'ΔProvidersFeature': r3.ΔProvidersFeature, - 'ΔInheritDefinitionFeature': r3.ΔInheritDefinitionFeature, - 'ΔelementAttribute': r3.ΔelementAttribute, - 'Δbind': r3.Δbind, - 'Δcontainer': r3.Δcontainer, - 'ΔnextContext': r3.ΔnextContext, - 'ΔcontainerRefreshStart': r3.ΔcontainerRefreshStart, - 'ΔcontainerRefreshEnd': r3.ΔcontainerRefreshEnd, - 'ΔnamespaceHTML': r3.ΔnamespaceHTML, - 'ΔnamespaceMathML': r3.ΔnamespaceMathML, - 'ΔnamespaceSVG': r3.ΔnamespaceSVG, - 'ΔenableBindings': r3.ΔenableBindings, - 'ΔdisableBindings': r3.ΔdisableBindings, - 'ΔallocHostVars': r3.ΔallocHostVars, - 'ΔelementStart': r3.ΔelementStart, - 'ΔelementEnd': r3.ΔelementEnd, - 'Δelement': r3.Δelement, - 'ΔelementContainerStart': r3.ΔelementContainerStart, - 'ΔelementContainerEnd': r3.ΔelementContainerEnd, - 'ΔpureFunction0': r3.ΔpureFunction0, - 'ΔpureFunction1': r3.ΔpureFunction1, - 'ΔpureFunction2': r3.ΔpureFunction2, - 'ΔpureFunction3': r3.ΔpureFunction3, - 'ΔpureFunction4': r3.ΔpureFunction4, - 'ΔpureFunction5': r3.ΔpureFunction5, - 'ΔpureFunction6': r3.ΔpureFunction6, - 'ΔpureFunction7': r3.ΔpureFunction7, - 'ΔpureFunction8': r3.ΔpureFunction8, - 'ΔpureFunctionV': r3.ΔpureFunctionV, - 'ΔgetCurrentView': r3.ΔgetCurrentView, - 'ΔrestoreView': r3.ΔrestoreView, - 'Δinterpolation1': r3.Δinterpolation1, - 'Δinterpolation2': r3.Δinterpolation2, - 'Δinterpolation3': r3.Δinterpolation3, - 'Δinterpolation4': r3.Δinterpolation4, - 'Δinterpolation5': r3.Δinterpolation5, - 'Δinterpolation6': r3.Δinterpolation6, - 'Δinterpolation7': r3.Δinterpolation7, - 'Δinterpolation8': r3.Δinterpolation8, - 'ΔinterpolationV': r3.ΔinterpolationV, - 'Δlistener': r3.Δlistener, - 'Δload': r3.Δload, - 'Δprojection': r3.Δprojection, - 'ΔelementProperty': r3.ΔelementProperty, - 'ΔcomponentHostSyntheticProperty': r3.ΔcomponentHostSyntheticProperty, - 'ΔcomponentHostSyntheticListener': r3.ΔcomponentHostSyntheticListener, - 'ΔpipeBind1': r3.ΔpipeBind1, - 'ΔpipeBind2': r3.ΔpipeBind2, - 'ΔpipeBind3': r3.ΔpipeBind3, - 'ΔpipeBind4': r3.ΔpipeBind4, - 'ΔpipeBindV': r3.ΔpipeBindV, - 'ΔprojectionDef': r3.ΔprojectionDef, - 'Δproperty': r3.Δproperty, - 'ΔpropertyInterpolate': r3.ΔpropertyInterpolate, - 'ΔpropertyInterpolate1': r3.ΔpropertyInterpolate1, - 'ΔpropertyInterpolate2': r3.ΔpropertyInterpolate2, - 'ΔpropertyInterpolate3': r3.ΔpropertyInterpolate3, - 'ΔpropertyInterpolate4': r3.ΔpropertyInterpolate4, - 'ΔpropertyInterpolate5': r3.ΔpropertyInterpolate5, - 'ΔpropertyInterpolate6': r3.ΔpropertyInterpolate6, - 'ΔpropertyInterpolate7': r3.ΔpropertyInterpolate7, - 'ΔpropertyInterpolate8': r3.ΔpropertyInterpolate8, - 'ΔpropertyInterpolateV': r3.ΔpropertyInterpolateV, - 'Δpipe': r3.Δpipe, - 'ΔqueryRefresh': r3.ΔqueryRefresh, - 'ΔviewQuery': r3.ΔviewQuery, - 'ΔstaticViewQuery': r3.ΔstaticViewQuery, - 'ΔstaticContentQuery': r3.ΔstaticContentQuery, - 'ΔloadViewQuery': r3.ΔloadViewQuery, - 'ΔcontentQuery': r3.ΔcontentQuery, - 'ΔloadContentQuery': r3.ΔloadContentQuery, - 'Δreference': r3.Δreference, - 'ΔelementHostAttrs': r3.ΔelementHostAttrs, - 'ΔclassMap': r3.ΔclassMap, - 'Δstyling': r3.Δstyling, - 'ΔstyleMap': r3.ΔstyleMap, - 'ΔstyleProp': r3.ΔstyleProp, - 'ΔstylingApply': r3.ΔstylingApply, - 'ΔclassProp': r3.ΔclassProp, - 'Δselect': r3.Δselect, - 'Δtemplate': r3.Δtemplate, - 'Δtext': r3.Δtext, - 'ΔtextBinding': r3.ΔtextBinding, - 'ΔembeddedViewStart': r3.ΔembeddedViewStart, - 'ΔembeddedViewEnd': r3.ΔembeddedViewEnd, - 'Δi18n': r3.Δi18n, - 'Δi18nAttributes': r3.Δi18nAttributes, - 'Δi18nExp': r3.Δi18nExp, - 'Δi18nStart': r3.Δi18nStart, - 'Δi18nEnd': r3.Δi18nEnd, - 'Δi18nApply': r3.Δi18nApply, - 'Δi18nPostprocess': r3.Δi18nPostprocess, - 'Δi18nLocalize': r3.Δi18nLocalize, - 'ΔresolveWindow': r3.ΔresolveWindow, - 'ΔresolveDocument': r3.ΔresolveDocument, - 'ΔresolveBody': r3.ΔresolveBody, - 'ΔsetComponentScope': r3.ΔsetComponentScope, - 'ΔsetNgModuleScope': r3.ΔsetNgModuleScope, +export const angularCoreEnv: {[name: string]: Function} = + (() => ({ + 'ΔdefineBase': r3.ΔdefineBase, + 'ΔdefineComponent': r3.ΔdefineComponent, + 'ΔdefineDirective': r3.ΔdefineDirective, + 'ΔdefineInjectable': ΔdefineInjectable, + 'ΔdefineInjector': ΔdefineInjector, + 'ΔdefineNgModule': r3.ΔdefineNgModule, + 'ΔdefinePipe': r3.ΔdefinePipe, + 'ΔdirectiveInject': r3.ΔdirectiveInject, + 'ΔgetFactoryOf': r3.ΔgetFactoryOf, + 'ΔgetInheritedFactory': r3.ΔgetInheritedFactory, + 'Δinject': Δinject, + 'ΔinjectAttribute': r3.ΔinjectAttribute, + 'ΔtemplateRefExtractor': r3.ΔtemplateRefExtractor, + 'ΔNgOnChangesFeature': r3.ΔNgOnChangesFeature, + 'ΔProvidersFeature': r3.ΔProvidersFeature, + 'ΔInheritDefinitionFeature': r3.ΔInheritDefinitionFeature, + 'ΔelementAttribute': r3.ΔelementAttribute, + 'Δbind': r3.Δbind, + 'Δcontainer': r3.Δcontainer, + 'ΔnextContext': r3.ΔnextContext, + 'ΔcontainerRefreshStart': r3.ΔcontainerRefreshStart, + 'ΔcontainerRefreshEnd': r3.ΔcontainerRefreshEnd, + 'ΔnamespaceHTML': r3.ΔnamespaceHTML, + 'ΔnamespaceMathML': r3.ΔnamespaceMathML, + 'ΔnamespaceSVG': r3.ΔnamespaceSVG, + 'ΔenableBindings': r3.ΔenableBindings, + 'ΔdisableBindings': r3.ΔdisableBindings, + 'ΔallocHostVars': r3.ΔallocHostVars, + 'ΔelementStart': r3.ΔelementStart, + 'ΔelementEnd': r3.ΔelementEnd, + 'Δelement': r3.Δelement, + 'ΔelementContainerStart': r3.ΔelementContainerStart, + 'ΔelementContainerEnd': r3.ΔelementContainerEnd, + 'ΔpureFunction0': r3.ΔpureFunction0, + 'ΔpureFunction1': r3.ΔpureFunction1, + 'ΔpureFunction2': r3.ΔpureFunction2, + 'ΔpureFunction3': r3.ΔpureFunction3, + 'ΔpureFunction4': r3.ΔpureFunction4, + 'ΔpureFunction5': r3.ΔpureFunction5, + 'ΔpureFunction6': r3.ΔpureFunction6, + 'ΔpureFunction7': r3.ΔpureFunction7, + 'ΔpureFunction8': r3.ΔpureFunction8, + 'ΔpureFunctionV': r3.ΔpureFunctionV, + 'ΔgetCurrentView': r3.ΔgetCurrentView, + 'ΔrestoreView': r3.ΔrestoreView, + 'Δinterpolation1': r3.Δinterpolation1, + 'Δinterpolation2': r3.Δinterpolation2, + 'Δinterpolation3': r3.Δinterpolation3, + 'Δinterpolation4': r3.Δinterpolation4, + 'Δinterpolation5': r3.Δinterpolation5, + 'Δinterpolation6': r3.Δinterpolation6, + 'Δinterpolation7': r3.Δinterpolation7, + 'Δinterpolation8': r3.Δinterpolation8, + 'ΔinterpolationV': r3.ΔinterpolationV, + 'Δlistener': r3.Δlistener, + 'Δload': r3.Δload, + 'Δprojection': r3.Δprojection, + 'ΔelementProperty': r3.ΔelementProperty, + 'ΔcomponentHostSyntheticProperty': r3.ΔcomponentHostSyntheticProperty, + 'ΔcomponentHostSyntheticListener': r3.ΔcomponentHostSyntheticListener, + 'ΔpipeBind1': r3.ΔpipeBind1, + 'ΔpipeBind2': r3.ΔpipeBind2, + 'ΔpipeBind3': r3.ΔpipeBind3, + 'ΔpipeBind4': r3.ΔpipeBind4, + 'ΔpipeBindV': r3.ΔpipeBindV, + 'ΔprojectionDef': r3.ΔprojectionDef, + 'Δproperty': r3.Δproperty, + 'ΔpropertyInterpolate': r3.ΔpropertyInterpolate, + 'ΔpropertyInterpolate1': r3.ΔpropertyInterpolate1, + 'ΔpropertyInterpolate2': r3.ΔpropertyInterpolate2, + 'ΔpropertyInterpolate3': r3.ΔpropertyInterpolate3, + 'ΔpropertyInterpolate4': r3.ΔpropertyInterpolate4, + 'ΔpropertyInterpolate5': r3.ΔpropertyInterpolate5, + 'ΔpropertyInterpolate6': r3.ΔpropertyInterpolate6, + 'ΔpropertyInterpolate7': r3.ΔpropertyInterpolate7, + 'ΔpropertyInterpolate8': r3.ΔpropertyInterpolate8, + 'ΔpropertyInterpolateV': r3.ΔpropertyInterpolateV, + 'Δpipe': r3.Δpipe, + 'ΔqueryRefresh': r3.ΔqueryRefresh, + 'ΔviewQuery': r3.ΔviewQuery, + 'ΔstaticViewQuery': r3.ΔstaticViewQuery, + 'ΔstaticContentQuery': r3.ΔstaticContentQuery, + 'ΔloadViewQuery': r3.ΔloadViewQuery, + 'ΔcontentQuery': r3.ΔcontentQuery, + 'ΔloadContentQuery': r3.ΔloadContentQuery, + 'Δreference': r3.Δreference, + 'ΔelementHostAttrs': r3.ΔelementHostAttrs, + 'ΔclassMap': r3.ΔclassMap, + 'Δstyling': r3.Δstyling, + 'ΔstyleMap': r3.ΔstyleMap, + 'ΔstyleProp': r3.ΔstyleProp, + 'ΔstylingApply': r3.ΔstylingApply, + 'ΔclassProp': r3.ΔclassProp, + 'Δselect': r3.Δselect, + 'Δtemplate': r3.Δtemplate, + 'Δtext': r3.Δtext, + 'ΔtextBinding': r3.ΔtextBinding, + 'ΔembeddedViewStart': r3.ΔembeddedViewStart, + 'ΔembeddedViewEnd': r3.ΔembeddedViewEnd, + 'Δi18n': r3.Δi18n, + 'Δi18nAttributes': r3.Δi18nAttributes, + 'Δi18nExp': r3.Δi18nExp, + 'Δi18nStart': r3.Δi18nStart, + 'Δi18nEnd': r3.Δi18nEnd, + 'Δi18nApply': r3.Δi18nApply, + 'Δi18nPostprocess': r3.Δi18nPostprocess, + 'Δi18nLocalize': r3.Δi18nLocalize, + 'ΔresolveWindow': r3.ΔresolveWindow, + 'ΔresolveDocument': r3.ΔresolveDocument, + 'ΔresolveBody': r3.ΔresolveBody, + 'ΔsetComponentScope': r3.ΔsetComponentScope, + 'ΔsetNgModuleScope': r3.ΔsetNgModuleScope, - 'ΔsanitizeHtml': sanitization.ΔsanitizeHtml, - 'ΔsanitizeStyle': sanitization.ΔsanitizeStyle, - 'ΔdefaultStyleSanitizer': sanitization.ΔdefaultStyleSanitizer, - 'ΔsanitizeResourceUrl': sanitization.ΔsanitizeResourceUrl, - 'ΔsanitizeScript': sanitization.ΔsanitizeScript, - 'ΔsanitizeUrl': sanitization.ΔsanitizeUrl, - 'ΔsanitizeUrlOrResourceUrl': sanitization.ΔsanitizeUrlOrResourceUrl, -}; + 'ΔsanitizeHtml': sanitization.ΔsanitizeHtml, + 'ΔsanitizeStyle': sanitization.ΔsanitizeStyle, + 'ΔdefaultStyleSanitizer': sanitization.ΔdefaultStyleSanitizer, + 'ΔsanitizeResourceUrl': sanitization.ΔsanitizeResourceUrl, + 'ΔsanitizeScript': sanitization.ΔsanitizeScript, + 'ΔsanitizeUrl': sanitization.ΔsanitizeUrl, + 'ΔsanitizeUrlOrResourceUrl': sanitization.ΔsanitizeUrlOrResourceUrl, + }))(); diff --git a/packages/core/src/render3/util/misc_utils.ts b/packages/core/src/render3/util/misc_utils.ts index 0514f1896ced1..2deedccd1836f 100644 --- a/packages/core/src/render3/util/misc_utils.ts +++ b/packages/core/src/render3/util/misc_utils.ts @@ -48,9 +48,10 @@ export function stringifyForError(value: any) { export const defaultScheduler = - (typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame || // browser only - setTimeout // everything else - ).bind(global); + (() => + (typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame || // browser only + setTimeout // everything else + ).bind(global))(); /** * diff --git a/packages/core/src/util/empty.ts b/packages/core/src/util/empty.ts index 46dc61bdf634e..d1d8ce9a1bebd 100644 --- a/packages/core/src/util/empty.ts +++ b/packages/core/src/util/empty.ts @@ -19,6 +19,10 @@ export const EMPTY_ARRAY: any[] = []; // freezing the values prevents any code from accidentally inserting new values in if (typeof ngDevMode !== 'undefined' && ngDevMode) { + // These property accesses can be ignored because ngDevMode will be set to false + // when optimizing code and the whole if statement will be dropped. + // tslint:disable-next-line:no-toplevel-property-access Object.freeze(EMPTY_OBJ); + // tslint:disable-next-line:no-toplevel-property-access Object.freeze(EMPTY_ARRAY); } diff --git a/packages/core/src/util/microtask.ts b/packages/core/src/util/microtask.ts index 40edbac49dcaa..fdc8a2b4f6443 100644 --- a/packages/core/src/util/microtask.ts +++ b/packages/core/src/util/microtask.ts @@ -6,8 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ - -const promise: Promise = Promise.resolve(0); +const promise: Promise = (() => Promise.resolve(0))(); declare const Zone: any; diff --git a/packages/core/src/util/ng_i18n_closure_mode.ts b/packages/core/src/util/ng_i18n_closure_mode.ts index be1231060d4ee..1945dae272ecf 100644 --- a/packages/core/src/util/ng_i18n_closure_mode.ts +++ b/packages/core/src/util/ng_i18n_closure_mode.ts @@ -16,8 +16,12 @@ declare global { * NOTE: changes to the `ngI18nClosureMode` name must be synced with `compiler-cli/src/tooling.ts`. */ if (typeof ngI18nClosureMode === 'undefined') { + // These property accesses can be ignored because ngI18nClosureMode will be set to false + // when optimizing code and the whole if statement will be dropped. // Make sure to refer to ngI18nClosureMode as ['ngI18nClosureMode'] for closure. + // tslint:disable-next-line:no-toplevel-property-access global['ngI18nClosureMode'] = // TODO(FW-1250): validate that this actually, you know, works. + // tslint:disable-next-line:no-toplevel-property-access typeof goog !== 'undefined' && typeof goog.getMsg === 'function'; } diff --git a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json index adb95aa96cff2..a57178edd47dd 100644 --- a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json +++ b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json @@ -50,9 +50,6 @@ { "name": "FLAGS" }, - { - "name": "FactoryPrototype" - }, { "name": "HEADER_OFFSET" }, diff --git a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json index 7abadbcaf8615..414f37283cb63 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -41,9 +41,6 @@ { "name": "FLAGS" }, - { - "name": "FactoryPrototype" - }, { "name": "HEADER_OFFSET" }, diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index 761b3d1220096..1fbcba97b2520 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -83,9 +83,6 @@ { "name": "FLAGS" }, - { - "name": "FactoryPrototype" - }, { "name": "HEADER_OFFSET" }, diff --git a/packages/elements/src/utils.ts b/packages/elements/src/utils.ts index 0491485777443..2333eb40b34a4 100644 --- a/packages/elements/src/utils.ts +++ b/packages/elements/src/utils.ts @@ -7,9 +7,11 @@ */ import {ComponentFactoryResolver, Injector, Type} from '@angular/core'; -const elProto = Element.prototype as any; -const matches = elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector || - elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector; +const matches = (() => { + const elProto = Element.prototype as any; + return elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector || + elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector; +})(); /** * Provide methods for scheduling the execution of a callback. diff --git a/packages/forms/src/directives/ng_form.ts b/packages/forms/src/directives/ng_form.ts index e7a067bcd5c61..ba0d59b62ef41 100644 --- a/packages/forms/src/directives/ng_form.ts +++ b/packages/forms/src/directives/ng_form.ts @@ -23,7 +23,7 @@ export const formDirectiveProvider: any = { useExisting: forwardRef(() => NgForm) }; -const resolvedPromise = Promise.resolve(null); +const resolvedPromise = (() => Promise.resolve(null))(); /** * @description diff --git a/packages/forms/src/directives/ng_model.ts b/packages/forms/src/directives/ng_model.ts index 15ab847972820..b4e252a9cb9c6 100644 --- a/packages/forms/src/directives/ng_model.ts +++ b/packages/forms/src/directives/ng_model.ts @@ -43,7 +43,7 @@ export const formControlBinding: any = { * - this is just one extra run no matter how many `ngModel` have been changed. * - this is a general problem when using `exportAs` for directives! */ -const resolvedPromise = Promise.resolve(null); +const resolvedPromise = (() => Promise.resolve(null))(); /** * @description diff --git a/packages/http/src/static_request.ts b/packages/http/src/static_request.ts index f55fa8acd0fe6..c48cd252cb585 100644 --- a/packages/http/src/static_request.ts +++ b/packages/http/src/static_request.ts @@ -185,7 +185,7 @@ function urlEncodeParams(params: {[key: string]: any}): URLSearchParams { const noop = function() {}; const w = typeof window == 'object' ? window : noop; -const FormData = (w as any /** TODO #9100 */)['FormData'] || noop; -const Blob = (w as any /** TODO #9100 */)['Blob'] || noop; +const FormData = (() => (w as any /** TODO #9100 */)['FormData'] || noop)(); +const Blob = (() => (w as any /** TODO #9100 */)['Blob'] || noop)(); export const ArrayBuffer: ArrayBufferConstructor = - (w as any /** TODO #9100 */)['ArrayBuffer'] || noop; + (() => (w as any /** TODO #9100 */)['ArrayBuffer'] || noop)(); diff --git a/packages/platform-browser/src/browser/browser_adapter.ts b/packages/platform-browser/src/browser/browser_adapter.ts index dbe7baf085cce..d40cf891eb93f 100644 --- a/packages/platform-browser/src/browser/browser_adapter.ts +++ b/packages/platform-browser/src/browser/browser_adapter.ts @@ -63,13 +63,15 @@ const _chromeNumKeyPadMap = { '\x90': 'NumLock' }; -let nodeContains: (a: any, b: any) => boolean; +const nodeContains: (a: any, b: any) => boolean = (() => { + if (global['Node']) { + return global['Node'].prototype.contains || function(node: any) { + return !!(this.compareDocumentPosition(node) & 16); + }; + } -if (global['Node']) { - nodeContains = global['Node'].prototype.contains || function(node) { - return !!(this.compareDocumentPosition(node) & 16); - }; -} + return undefined as any; +})(); /** * A `DomAdapter` powered by full browser DOM APIs. diff --git a/packages/platform-browser/src/dom/debug/ng_probe.ts b/packages/platform-browser/src/dom/debug/ng_probe.ts index d033a681453c8..2ed9656c3b009 100644 --- a/packages/platform-browser/src/dom/debug/ng_probe.ts +++ b/packages/platform-browser/src/dom/debug/ng_probe.ts @@ -6,13 +6,14 @@ * found in the LICENSE file at https://angular.io/license */ -import * as core from '@angular/core'; +import {APP_INITIALIZER, ApplicationRef, DebugNode, NgProbeToken, NgZone, Optional, Provider, getDebugNode} from '@angular/core'; + import {exportNgVar} from '../util'; -const CORE_TOKENS = { - 'ApplicationRef': core.ApplicationRef, - 'NgZone': core.NgZone, -}; +const CORE_TOKENS = (() => ({ + 'ApplicationRef': ApplicationRef, + 'NgZone': NgZone, + }))(); const INSPECT_GLOBAL_NAME = 'probe'; const CORE_TOKENS_GLOBAL_NAME = 'coreTokens'; @@ -22,17 +23,17 @@ const CORE_TOKENS_GLOBAL_NAME = 'coreTokens'; * null if the given native element does not have an Angular view associated * with it. */ -export function inspectNativeElement(element: any): core.DebugNode|null { - return core.getDebugNode(element); +export function inspectNativeElement(element: any): DebugNode|null { + return getDebugNode(element); } -export function _createNgProbe(coreTokens: core.NgProbeToken[]): any { +export function _createNgProbe(coreTokens: NgProbeToken[]): any { exportNgVar(INSPECT_GLOBAL_NAME, inspectNativeElement); exportNgVar(CORE_TOKENS_GLOBAL_NAME, {...CORE_TOKENS, ..._ngProbeTokensToMap(coreTokens || [])}); return () => inspectNativeElement; } -function _ngProbeTokensToMap(tokens: core.NgProbeToken[]): {[name: string]: any} { +function _ngProbeTokensToMap(tokens: NgProbeToken[]): {[name: string]: any} { return tokens.reduce((prev: any, t: any) => (prev[t.name] = t.token, prev), {}); } @@ -48,12 +49,12 @@ export const ELEMENT_PROBE_PROVIDERS__POST_R3__ = []; /** * Providers which support debugging Angular applications (e.g. via `ng.probe`). */ -export const ELEMENT_PROBE_PROVIDERS__PRE_R3__: core.Provider[] = [ +export const ELEMENT_PROBE_PROVIDERS__PRE_R3__: Provider[] = [ { - provide: core.APP_INITIALIZER, + provide: APP_INITIALIZER, useFactory: _createNgProbe, deps: [ - [core.NgProbeToken, new core.Optional()], + [NgProbeToken, new Optional()], ], multi: true, }, diff --git a/packages/platform-browser/src/dom/dom_renderer.ts b/packages/platform-browser/src/dom/dom_renderer.ts index 16be147431773..ae04ba7aeec78 100644 --- a/packages/platform-browser/src/dom/dom_renderer.ts +++ b/packages/platform-browser/src/dom/dom_renderer.ts @@ -231,7 +231,7 @@ class DefaultDomRenderer2 implements Renderer2 { } } -const AT_CHARCODE = '@'.charCodeAt(0); +const AT_CHARCODE = (() => '@'.charCodeAt(0))(); function checkNoSyntheticProp(name: string, nameKind: string) { if (name.charCodeAt(0) === AT_CHARCODE) { throw new Error( diff --git a/packages/platform-browser/src/dom/events/dom_events.ts b/packages/platform-browser/src/dom/events/dom_events.ts index 9684bcd252455..2d3045eb15b68 100644 --- a/packages/platform-browser/src/dom/events/dom_events.ts +++ b/packages/platform-browser/src/dom/events/dom_events.ts @@ -18,9 +18,8 @@ import {EventManagerPlugin} from './event_manager'; * addEventListener by 3x. */ const __symbol__ = - (typeof Zone !== 'undefined') && (Zone as any)['__symbol__'] || function(v: string): string { - return '__zone_symbol__' + v; - }; + (() => (typeof Zone !== 'undefined') && (Zone as any)['__symbol__'] || + function(v: string): string { return '__zone_symbol__' + v; })(); const ADD_EVENT_LISTENER: 'addEventListener' = __symbol__('addEventListener'); const REMOVE_EVENT_LISTENER: 'removeEventListener' = __symbol__('removeEventListener'); @@ -35,13 +34,18 @@ const NATIVE_REMOVE_LISTENER = 'removeEventListener'; const stopSymbol = '__zone_symbol__propagationStopped'; const stopMethodSymbol = '__zone_symbol__stopImmediatePropagation'; -const blackListedEvents: string[] = - (typeof Zone !== 'undefined') && (Zone as any)[__symbol__('BLACK_LISTED_EVENTS')]; -let blackListedMap: {[eventName: string]: string}; -if (blackListedEvents) { - blackListedMap = {}; - blackListedEvents.forEach(eventName => { blackListedMap[eventName] = eventName; }); -} + +const blackListedMap = (() => { + const blackListedEvents: string[] = + (typeof Zone !== 'undefined') && (Zone as any)[__symbol__('BLACK_LISTED_EVENTS')]; + if (blackListedEvents) { + const res: {[eventName: string]: string} = {}; + blackListedEvents.forEach(eventName => { res[eventName] = eventName; }); + return res; + } + return undefined; +})(); + const isBlackListedEvent = function(eventName: string) { if (!blackListedMap) { diff --git a/tslint.json b/tslint.json index d12df37dde114..91b52d2fe3ffa 100644 --- a/tslint.json +++ b/tslint.json @@ -2,7 +2,8 @@ "rulesDirectory": [ "dist/tools/tslint", "node_modules/vrsource-tslint-rules/rules", - "node_modules/tslint-eslint-rules/dist/rules" + "node_modules/tslint-eslint-rules/dist/rules", + "node_modules/tslint-no-toplevel-property-access/rules" ], "rules": { "file-header": [ @@ -18,6 +19,18 @@ "no-jasmine-focus": true, "no-var-keyword": true, "require-internal-with-underscore": true, + "no-toplevel-property-access": [ + true, + "packages/animations/src/", + "packages/animations/browser/", + "packages/common/src/", + "packages/core/src/", + "packages/elements/src/", + "packages/forms/src/", + "packages/http/src/", + "packages/platform-browser/src/", + "packages/router/src/" + ], "semicolon": [ true ], @@ -56,4 +69,4 @@ "function" ] } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index d7e6cc0af062a..7ef946bf05f6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10977,6 +10977,11 @@ tslint-eslint-rules@4.1.1: tslib "^1.0.0" tsutils "^1.4.0" +tslint-no-toplevel-property-access@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/tslint-no-toplevel-property-access/-/tslint-no-toplevel-property-access-0.0.2.tgz#c9b19bbd525ea7b8577e5ada601cc8625b4ed004" + integrity sha512-Oc+UUurlGLBkgeUSGxMoTpRUpaXsjqzQCEAYrYQyuU8330fi5FKlye5n53y87EJ24AlfdoxMPV7DJfFOADapfg== + tslint@5.7.0: version "5.7.0" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.7.0.tgz#c25e0d0c92fa1201c2bc30e844e08e682b4f3552"