refactor: remove `keys()` and `values()` from MapWrapper

This commit is contained in:
Victor Berchet 2016-11-03 16:58:27 -07:00 committed by vikerman
parent 121e5080aa
commit ec92f4b198
19 changed files with 138 additions and 216 deletions

View File

@ -8,7 +8,7 @@
import {ChangeDetectionStrategy, SchemaMetadata, Type, ViewEncapsulation} from '@angular/core'; import {ChangeDetectionStrategy, SchemaMetadata, Type, ViewEncapsulation} from '@angular/core';
import {ListWrapper, MapWrapper} from './facade/collection'; import {ListWrapper} from './facade/collection';
import {isPresent} from './facade/lang'; import {isPresent} from './facade/lang';
import {LifecycleHooks} from './private_import_core'; import {LifecycleHooks} from './private_import_core';
import {CssSelector} from './selector'; import {CssSelector} from './selector';
@ -582,7 +582,7 @@ export function removeIdentifierDuplicates<T extends CompileMetadataWithIdentifi
} }
}); });
return MapWrapper.values(map); return Array.from(map.values());
} }
function _normalizeArray(obj: any[]): any[] { function _normalizeArray(obj: any[]): any[] {

View File

@ -10,7 +10,6 @@ import {Injectable, ViewEncapsulation} from '@angular/core';
import {CompileDirectiveMetadata, CompileStylesheetMetadata, CompileTemplateMetadata, CompileTypeMetadata} from './compile_metadata'; import {CompileDirectiveMetadata, CompileStylesheetMetadata, CompileTemplateMetadata, CompileTypeMetadata} from './compile_metadata';
import {CompilerConfig} from './config'; import {CompilerConfig} from './config';
import {MapWrapper} from './facade/collection';
import {isBlank, isPresent} from './facade/lang'; import {isBlank, isPresent} from './facade/lang';
import * as html from './ml_parser/ast'; import * as html from './ml_parser/ast';
import {HtmlParser} from './ml_parser/html_parser'; import {HtmlParser} from './ml_parser/html_parser';
@ -169,7 +168,7 @@ export class DirectiveNormalizer {
return this._loadMissingExternalStylesheets( return this._loadMissingExternalStylesheets(
stylesheet.styleUrls, loadedStylesheets); stylesheet.styleUrls, loadedStylesheets);
}))) })))
.then((_) => MapWrapper.values(loadedStylesheets)); .then((_) => Array.from(loadedStylesheets.values()));
} }
normalizeStylesheet(stylesheet: CompileStylesheetMetadata): CompileStylesheetMetadata { normalizeStylesheet(stylesheet: CompileStylesheetMetadata): CompileStylesheetMetadata {

View File

@ -13,7 +13,7 @@ import {AnimationParser} from './animation/animation_parser';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, CompileProviderMetadata, StaticSymbol, createHostComponentMeta} from './compile_metadata'; import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, CompileProviderMetadata, StaticSymbol, createHostComponentMeta} from './compile_metadata';
import {DirectiveNormalizer} from './directive_normalizer'; import {DirectiveNormalizer} from './directive_normalizer';
import {DirectiveWrapperCompileResult, DirectiveWrapperCompiler} from './directive_wrapper_compiler'; import {DirectiveWrapperCompileResult, DirectiveWrapperCompiler} from './directive_wrapper_compiler';
import {ListWrapper, MapWrapper} from './facade/collection'; import {ListWrapper} from './facade/collection';
import {Identifiers, resolveIdentifier, resolveIdentifierToken} from './identifiers'; import {Identifiers, resolveIdentifier, resolveIdentifierToken} from './identifiers';
import {CompileMetadataResolver} from './metadata_resolver'; import {CompileMetadataResolver} from './metadata_resolver';
import {NgModuleCompiler} from './ng_module_compiler'; import {NgModuleCompiler} from './ng_module_compiler';
@ -51,7 +51,7 @@ export function analyzeNgModules(
} }
}); });
const ngModuleMetas = MapWrapper.values(moduleMetasByRef); const ngModuleMetas = Array.from(moduleMetasByRef.values());
const ngModuleByPipeOrDirective = new Map<StaticSymbol, CompileNgModuleMetadata>(); const ngModuleByPipeOrDirective = new Map<StaticSymbol, CompileNgModuleMetadata>();
const ngModulesByFile = new Map<string, StaticSymbol[]>(); const ngModulesByFile = new Map<string, StaticSymbol[]>();
const ngDirectivesByFile = new Map<string, StaticSymbol[]>(); const ngDirectivesByFile = new Map<string, StaticSymbol[]>();

View File

@ -8,7 +8,6 @@
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileNgModuleMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata, CompileTypeMetadata} from './compile_metadata'; import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileNgModuleMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata, CompileTypeMetadata} from './compile_metadata';
import {MapWrapper} from './facade/collection';
import {isBlank, isPresent} from './facade/lang'; import {isBlank, isPresent} from './facade/lang';
import {Identifiers, resolveIdentifierToken} from './identifiers'; import {Identifiers, resolveIdentifierToken} from './identifiers';
import {ParseError, ParseSourceSpan} from './parse_util'; import {ParseError, ParseSourceSpan} from './parse_util';
@ -60,7 +59,7 @@ export class ProviderElementContext {
_resolveProvidersFromDirectives(directivesMeta, _sourceSpan, viewContext.errors); _resolveProvidersFromDirectives(directivesMeta, _sourceSpan, viewContext.errors);
this._contentQueries = _getContentQueries(directivesMeta); this._contentQueries = _getContentQueries(directivesMeta);
var queriedTokens = new Map<any, boolean>(); var queriedTokens = new Map<any, boolean>();
MapWrapper.values(this._allProviders).forEach((provider) => { Array.from(this._allProviders.values()).forEach((provider) => {
this._addQueryReadsTo(provider.token, queriedTokens); this._addQueryReadsTo(provider.token, queriedTokens);
}); });
refs.forEach((refAst) => { refs.forEach((refAst) => {
@ -72,7 +71,7 @@ export class ProviderElementContext {
} }
// create the providers that we know are eager first // create the providers that we know are eager first
MapWrapper.values(this._allProviders).forEach((provider) => { Array.from(this._allProviders.values()).forEach((provider) => {
const eager = provider.eager || isPresent(queriedTokens.get(provider.token.reference)); const eager = provider.eager || isPresent(queriedTokens.get(provider.token.reference));
if (eager) { if (eager) {
this._getOrCreateLocalProvider(provider.providerType, provider.token, true); this._getOrCreateLocalProvider(provider.providerType, provider.token, true);
@ -82,12 +81,14 @@ export class ProviderElementContext {
afterElement() { afterElement() {
// collect lazy providers // collect lazy providers
MapWrapper.values(this._allProviders).forEach((provider) => { Array.from(this._allProviders.values()).forEach((provider) => {
this._getOrCreateLocalProvider(provider.providerType, provider.token, false); this._getOrCreateLocalProvider(provider.providerType, provider.token, false);
}); });
} }
get transformProviders(): ProviderAst[] { return MapWrapper.values(this._transformedProviders); } get transformProviders(): ProviderAst[] {
return Array.from(this._transformedProviders.values());
}
get transformedDirectiveAsts(): DirectiveAst[] { get transformedDirectiveAsts(): DirectiveAst[] {
var sortedProviderTypes = this.transformProviders.map(provider => provider.token.identifier); var sortedProviderTypes = this.transformProviders.map(provider => provider.token.identifier);
@ -296,14 +297,14 @@ export class NgModuleProviderAnalyzer {
} }
parse(): ProviderAst[] { parse(): ProviderAst[] {
MapWrapper.values(this._allProviders).forEach((provider) => { Array.from(this._allProviders.values()).forEach((provider) => {
this._getOrCreateLocalProvider(provider.token, provider.eager); this._getOrCreateLocalProvider(provider.token, provider.eager);
}); });
if (this._errors.length > 0) { if (this._errors.length > 0) {
const errorString = this._errors.join('\n'); const errorString = this._errors.join('\n');
throw new Error(`Provider parse errors:\n${errorString}`); throw new Error(`Provider parse errors:\n${errorString}`);
} }
return MapWrapper.values(this._transformedProviders); return Array.from(this._transformedProviders.values());
} }
private _getOrCreateLocalProvider(token: CompileTokenMetadata, eager: boolean): ProviderAst { private _getOrCreateLocalProvider(token: CompileTokenMetadata, eager: boolean): ProviderAst {

View File

@ -10,7 +10,6 @@
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileIdentifierMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata} from '../compile_metadata'; import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileIdentifierMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata} from '../compile_metadata';
import {createDiTokenExpression} from '../compiler_util/identifier_util'; import {createDiTokenExpression} from '../compiler_util/identifier_util';
import {DirectiveWrapperCompiler, DirectiveWrapperExpressions} from '../directive_wrapper_compiler'; import {DirectiveWrapperCompiler, DirectiveWrapperExpressions} from '../directive_wrapper_compiler';
import {MapWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, identifierToken, resolveIdentifier, resolveIdentifierToken} from '../identifiers'; import {Identifiers, identifierToken, resolveIdentifier, resolveIdentifierToken} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
@ -169,21 +168,23 @@ export class CompileElement extends CompileNode {
// create all the provider instances, some in the view constructor, // create all the provider instances, some in the view constructor,
// some as getters. We rely on the fact that they are already sorted topologically. // some as getters. We rely on the fact that they are already sorted topologically.
MapWrapper.values(this._resolvedProviders).forEach((resolvedProvider) => { Array.from(this._resolvedProviders.values()).forEach((resolvedProvider) => {
const isDirectiveWrapper = resolvedProvider.providerType === ProviderAstType.Component || const isDirectiveWrapper = resolvedProvider.providerType === ProviderAstType.Component ||
resolvedProvider.providerType === ProviderAstType.Directive; resolvedProvider.providerType === ProviderAstType.Directive;
var providerValueExpressions = resolvedProvider.providers.map((provider) => { const providerValueExpressions = resolvedProvider.providers.map((provider) => {
if (isPresent(provider.useExisting)) { if (provider.useExisting) {
return this._getDependency( return this._getDependency(
resolvedProvider.providerType, resolvedProvider.providerType,
new CompileDiDependencyMetadata({token: provider.useExisting})); new CompileDiDependencyMetadata({token: provider.useExisting}));
} else if (isPresent(provider.useFactory)) { } else if (provider.useFactory) {
var deps = provider.deps || provider.useFactory.diDeps; const deps = provider.deps || provider.useFactory.diDeps;
var depsExpr = deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep)); const depsExpr =
deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep));
return o.importExpr(provider.useFactory).callFn(depsExpr); return o.importExpr(provider.useFactory).callFn(depsExpr);
} else if (isPresent(provider.useClass)) { } else if (provider.useClass) {
var deps = provider.deps || provider.useClass.diDeps; const deps = provider.deps || provider.useClass.diDeps;
var depsExpr = deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep)); const depsExpr =
deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep));
if (isDirectiveWrapper) { if (isDirectiveWrapper) {
const directiveWrapperIdentifier = new CompileIdentifierMetadata( const directiveWrapperIdentifier = new CompileIdentifierMetadata(
{name: DirectiveWrapperCompiler.dirWrapperClassName(provider.useClass)}); {name: DirectiveWrapperCompiler.dirWrapperClassName(provider.useClass)});
@ -217,7 +218,7 @@ export class CompileElement extends CompileNode {
directive.queries.forEach((queryMeta) => { this._addQuery(queryMeta, directiveInstance); }); directive.queries.forEach((queryMeta) => { this._addQuery(queryMeta, directiveInstance); });
} }
var queriesWithReads: _QueryWithRead[] = []; var queriesWithReads: _QueryWithRead[] = [];
MapWrapper.values(this._resolvedProviders).forEach((resolvedProvider) => { Array.from(this._resolvedProviders.values()).forEach((resolvedProvider) => {
var queriesForProvider = this._getQueriesFor(resolvedProvider.token); var queriesForProvider = this._getQueriesFor(resolvedProvider.token);
queriesWithReads.push( queriesWithReads.push(
...queriesForProvider.map(query => new _QueryWithRead(query, resolvedProvider.token))); ...queriesForProvider.map(query => new _QueryWithRead(query, resolvedProvider.token)));
@ -225,7 +226,7 @@ export class CompileElement extends CompileNode {
Object.keys(this.referenceTokens).forEach(varName => { Object.keys(this.referenceTokens).forEach(varName => {
var token = this.referenceTokens[varName]; var token = this.referenceTokens[varName];
var varValue: o.Expression; var varValue: o.Expression;
if (isPresent(token)) { if (token) {
varValue = this.instances.get(token.reference); varValue = this.instances.get(token.reference);
} else { } else {
varValue = this.renderNode; varValue = this.renderNode;
@ -256,7 +257,7 @@ export class CompileElement extends CompileNode {
} }
afterChildren(childNodeCount: number) { afterChildren(childNodeCount: number) {
MapWrapper.values(this._resolvedProviders).forEach((resolvedProvider) => { Array.from(this._resolvedProviders.values()).forEach((resolvedProvider) => {
// Note: afterChildren is called after recursing into children. // Note: afterChildren is called after recursing into children.
// This is good so that an injector match in an element that is closer to a requesting element // This is good so that an injector match in an element that is closer to a requesting element
// matches first. // matches first.
@ -271,11 +272,11 @@ export class CompileElement extends CompileNode {
this.nodeIndex, providerChildNodeCount, resolvedProvider, providerExpr)); this.nodeIndex, providerChildNodeCount, resolvedProvider, providerExpr));
}); });
MapWrapper.values(this._queries) Array.from(this._queries.values())
.forEach( .forEach(
(queries) => queries.forEach( queries => queries.forEach(
(query) => query.afterChildren( q =>
this.view.createMethod, this.view.updateContentQueriesMethod))); q.afterChildren(this.view.createMethod, this.view.updateContentQueriesMethod)));
} }
addContentNode(ngContentIndex: number, nodeExpr: CompileViewRootNode) { addContentNode(ngContentIndex: number, nodeExpr: CompileViewRootNode) {
@ -289,7 +290,7 @@ export class CompileElement extends CompileNode {
} }
getProviderTokens(): o.Expression[] { getProviderTokens(): o.Expression[] {
return MapWrapper.values(this._resolvedProviders) return Array.from(this._resolvedProviders.values())
.map((resolvedProvider) => createDiTokenExpression(resolvedProvider.token)); .map((resolvedProvider) => createDiTokenExpression(resolvedProvider.token));
} }

View File

@ -11,7 +11,6 @@ import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeMetadata
import {EventHandlerVars, NameResolver} from '../compiler_util/expression_converter'; import {EventHandlerVars, NameResolver} from '../compiler_util/expression_converter';
import {createPureProxy} from '../compiler_util/identifier_util'; import {createPureProxy} from '../compiler_util/identifier_util';
import {CompilerConfig} from '../config'; import {CompilerConfig} from '../config';
import {MapWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, resolveIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
@ -153,19 +152,21 @@ export class CompileView implements NameResolver {
} }
afterNodes() { afterNodes() {
MapWrapper.values(this.viewQueries) Array.from(this.viewQueries.values())
.forEach( .forEach(
(queries) => queries.forEach( queries => queries.forEach(
(query) => query.afterChildren(this.createMethod, this.updateViewQueriesMethod))); q => q.afterChildren(this.createMethod, this.updateViewQueriesMethod)));
} }
} }
function getViewType(component: CompileDirectiveMetadata, embeddedTemplateIndex: number): ViewType { function getViewType(component: CompileDirectiveMetadata, embeddedTemplateIndex: number): ViewType {
if (embeddedTemplateIndex > 0) { if (embeddedTemplateIndex > 0) {
return ViewType.EMBEDDED; return ViewType.EMBEDDED;
} else if (component.type.isHost) {
return ViewType.HOST;
} else {
return ViewType.COMPONENT;
} }
if (component.type.isHost) {
return ViewType.HOST;
}
return ViewType.COMPONENT;
} }

View File

@ -9,8 +9,6 @@
import {EventHandlerVars, convertActionBinding} from '../compiler_util/expression_converter'; import {EventHandlerVars, convertActionBinding} from '../compiler_util/expression_converter';
import {createInlineArray} from '../compiler_util/identifier_util'; import {createInlineArray} from '../compiler_util/identifier_util';
import {DirectiveWrapperExpressions} from '../directive_wrapper_compiler'; import {DirectiveWrapperExpressions} from '../directive_wrapper_compiler';
import {MapWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, resolveIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {BoundEventAst, DirectiveAst} from '../template_parser/template_ast'; import {BoundEventAst, DirectiveAst} from '../template_parser/template_ast';
@ -69,7 +67,7 @@ function subscribeToRenderEvents(
function subscribeToDirectiveEvents( function subscribeToDirectiveEvents(
usedEvents: Map<string, EventSummary>, directives: DirectiveAst[], usedEvents: Map<string, EventSummary>, directives: DirectiveAst[],
compileElement: CompileElement) { compileElement: CompileElement) {
const usedEventNames = MapWrapper.keys(usedEvents); const usedEventNames = Array.from(usedEvents.keys());
directives.forEach((dirAst) => { directives.forEach((dirAst) => {
const dirWrapper = compileElement.directiveWrapperInstance.get(dirAst.directive.type.reference); const dirWrapper = compileElement.directiveWrapperInstance.get(dirAst.directive.type.reference);
compileElement.view.createMethod.addStmts(DirectiveWrapperExpressions.subscribe( compileElement.view.createMethod.addStmts(DirectiveWrapperExpressions.subscribe(

View File

@ -6,8 +6,6 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MapWrapper} from '../../src/facade/collection';
const SVG_PREFIX = ':svg:'; const SVG_PREFIX = ':svg:';
// Element | Node interfaces // Element | Node interfaces
@ -109,8 +107,9 @@ export function extractSchema(): Map<string, string[]> {
function assertNoMissingTags(descMap: Map<string, string[]>): void { function assertNoMissingTags(descMap: Map<string, string[]>): void {
const extractedTags: string[] = []; const extractedTags: string[] = [];
MapWrapper.keys(descMap).forEach( Array.from(descMap.keys()).forEach((key: string) => {
(key: string) => { extractedTags.push(...key.split('|')[0].split('^')[0].split(',')); }); extractedTags.push(...key.split('|')[0].split('^')[0].split(','));
});
const missingTags = ALL_HTML_TAGS.split(',').filter(tag => extractedTags.indexOf(tag) == -1); const missingTags = ALL_HTML_TAGS.split(',').filter(tag => extractedTags.indexOf(tag) == -1);

View File

@ -7,8 +7,7 @@
*/ */
import {Injector} from '../di'; import {Injector} from '../di';
import {MapWrapper, Predicate} from '../facade/collection'; import {Predicate} from '../facade/collection';
import {isPresent} from '../facade/lang';
import {RenderDebugInfo} from '../render/api'; import {RenderDebugInfo} from '../render/api';
export class EventListener { constructor(public name: string, public callback: Function){}; } export class EventListener { constructor(public name: string, public callback: Function){}; }
@ -23,7 +22,7 @@ export class DebugNode {
constructor(nativeNode: any, parent: DebugNode, private _debugInfo: RenderDebugInfo) { constructor(nativeNode: any, parent: DebugNode, private _debugInfo: RenderDebugInfo) {
this.nativeNode = nativeNode; this.nativeNode = nativeNode;
if (isPresent(parent) && parent instanceof DebugElement) { if (parent && parent instanceof DebugElement) {
parent.addChild(this); parent.addChild(this);
} else { } else {
this.parent = null; this.parent = null;
@ -31,23 +30,19 @@ export class DebugNode {
this.listeners = []; this.listeners = [];
} }
get injector(): Injector { return isPresent(this._debugInfo) ? this._debugInfo.injector : null; } get injector(): Injector { return this._debugInfo ? this._debugInfo.injector : null; }
get componentInstance(): any { get componentInstance(): any { return this._debugInfo ? this._debugInfo.component : null; }
return isPresent(this._debugInfo) ? this._debugInfo.component : null;
}
get context(): any { return isPresent(this._debugInfo) ? this._debugInfo.context : null; } get context(): any { return this._debugInfo ? this._debugInfo.context : null; }
get references(): {[key: string]: any} { get references(): {[key: string]: any} {
return isPresent(this._debugInfo) ? this._debugInfo.references : null; return this._debugInfo ? this._debugInfo.references : null;
} }
get providerTokens(): any[] { get providerTokens(): any[] { return this._debugInfo ? this._debugInfo.providerTokens : null; }
return isPresent(this._debugInfo) ? this._debugInfo.providerTokens : null;
}
get source(): string { return isPresent(this._debugInfo) ? this._debugInfo.source : null; } get source(): string { return this._debugInfo ? this._debugInfo.source : null; }
} }
/** /**
@ -73,14 +68,14 @@ export class DebugElement extends DebugNode {
} }
addChild(child: DebugNode) { addChild(child: DebugNode) {
if (isPresent(child)) { if (child) {
this.childNodes.push(child); this.childNodes.push(child);
child.parent = this; child.parent = this;
} }
} }
removeChild(child: DebugNode) { removeChild(child: DebugNode) {
var childIndex = this.childNodes.indexOf(child); const childIndex = this.childNodes.indexOf(child);
if (childIndex !== -1) { if (childIndex !== -1) {
child.parent = null; child.parent = null;
this.childNodes.splice(childIndex, 1); this.childNodes.splice(childIndex, 1);
@ -88,14 +83,14 @@ export class DebugElement extends DebugNode {
} }
insertChildrenAfter(child: DebugNode, newChildren: DebugNode[]) { insertChildrenAfter(child: DebugNode, newChildren: DebugNode[]) {
var siblingIndex = this.childNodes.indexOf(child); const siblingIndex = this.childNodes.indexOf(child);
if (siblingIndex !== -1) { if (siblingIndex !== -1) {
var previousChildren = this.childNodes.slice(0, siblingIndex + 1); const previousChildren = this.childNodes.slice(0, siblingIndex + 1);
var nextChildren = this.childNodes.slice(siblingIndex + 1); const nextChildren = this.childNodes.slice(siblingIndex + 1);
this.childNodes = previousChildren.concat(newChildren, nextChildren); this.childNodes = previousChildren.concat(newChildren, nextChildren);
for (var i = 0; i < newChildren.length; ++i) { for (let i = 0; i < newChildren.length; ++i) {
var newChild = newChildren[i]; const newChild = newChildren[i];
if (isPresent(newChild.parent)) { if (newChild.parent) {
newChild.parent.removeChild(newChild); newChild.parent.removeChild(newChild);
} }
newChild.parent = this; newChild.parent = this;
@ -104,30 +99,24 @@ export class DebugElement extends DebugNode {
} }
query(predicate: Predicate<DebugElement>): DebugElement { query(predicate: Predicate<DebugElement>): DebugElement {
var results = this.queryAll(predicate); const results = this.queryAll(predicate);
return results.length > 0 ? results[0] : null; return results[0] || null;
} }
queryAll(predicate: Predicate<DebugElement>): DebugElement[] { queryAll(predicate: Predicate<DebugElement>): DebugElement[] {
var matches: DebugElement[] = []; const matches: DebugElement[] = [];
_queryElementChildren(this, predicate, matches); _queryElementChildren(this, predicate, matches);
return matches; return matches;
} }
queryAllNodes(predicate: Predicate<DebugNode>): DebugNode[] { queryAllNodes(predicate: Predicate<DebugNode>): DebugNode[] {
var matches: DebugNode[] = []; const matches: DebugNode[] = [];
_queryNodeChildren(this, predicate, matches); _queryNodeChildren(this, predicate, matches);
return matches; return matches;
} }
get children(): DebugElement[] { get children(): DebugElement[] {
var children: DebugElement[] = []; return this.childNodes.filter((node) => node instanceof DebugElement) as DebugElement[];
this.childNodes.forEach((node) => {
if (node instanceof DebugElement) {
children.push(node);
}
});
return children;
} }
triggerEventHandler(eventName: string, eventObj: any) { triggerEventHandler(eventName: string, eventObj: any) {
@ -173,7 +162,7 @@ function _queryNodeChildren(
} }
// Need to keep the nodes in a global Map so that multiple angular apps are supported. // Need to keep the nodes in a global Map so that multiple angular apps are supported.
var _nativeNodeToDebugNode = new Map<any, DebugNode>(); const _nativeNodeToDebugNode = new Map<any, DebugNode>();
/** /**
* @experimental * @experimental
@ -183,7 +172,7 @@ export function getDebugNode(nativeNode: any): DebugNode {
} }
export function getAllDebugNodes(): DebugNode[] { export function getAllDebugNodes(): DebugNode[] {
return MapWrapper.values(_nativeNodeToDebugNode); return Array.from(_nativeNodeToDebugNode.values());
} }
export function indexDebugNode(node: DebugNode) { export function indexDebugNode(node: DebugNode) {

View File

@ -6,8 +6,6 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MapWrapper} from '../facade/collection';
import {isBlank, isPresent} from '../facade/lang';
import {reflector} from '../reflection/reflection'; import {reflector} from '../reflection/reflection';
import {Type} from '../type'; import {Type} from '../type';
@ -103,16 +101,16 @@ export class ResolvedReflectiveFactory {
* Resolve a single provider. * Resolve a single provider.
*/ */
function resolveReflectiveFactory(provider: NormalizedProvider): ResolvedReflectiveFactory { function resolveReflectiveFactory(provider: NormalizedProvider): ResolvedReflectiveFactory {
var factoryFn: Function; let factoryFn: Function;
var resolvedDeps: ReflectiveDependency[]; let resolvedDeps: ReflectiveDependency[];
if (isPresent(provider.useClass)) { if (provider.useClass) {
var useClass = resolveForwardRef(provider.useClass); const useClass = resolveForwardRef(provider.useClass);
factoryFn = reflector.factory(useClass); factoryFn = reflector.factory(useClass);
resolvedDeps = _dependenciesFor(useClass); resolvedDeps = _dependenciesFor(useClass);
} else if (isPresent(provider.useExisting)) { } else if (provider.useExisting) {
factoryFn = (aliasInstance: any) => aliasInstance; factoryFn = (aliasInstance: any) => aliasInstance;
resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))]; resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
} else if (isPresent(provider.useFactory)) { } else if (provider.useFactory) {
factoryFn = provider.useFactory; factoryFn = provider.useFactory;
resolvedDeps = constructDependencies(provider.useFactory, provider.deps); resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
} else { } else {
@ -137,10 +135,10 @@ function resolveReflectiveProvider(provider: NormalizedProvider): ResolvedReflec
* Resolve a list of Providers. * Resolve a list of Providers.
*/ */
export function resolveReflectiveProviders(providers: Provider[]): ResolvedReflectiveProvider[] { export function resolveReflectiveProviders(providers: Provider[]): ResolvedReflectiveProvider[] {
var normalized = _normalizeProviders(providers, []); const normalized = _normalizeProviders(providers, []);
var resolved = normalized.map(resolveReflectiveProvider); const resolved = normalized.map(resolveReflectiveProvider);
return MapWrapper.values( const resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
mergeResolvedReflectiveProviders(resolved, new Map<number, ResolvedReflectiveProvider>())); return Array.from(resolvedProviderMap.values());
} }
/** /**
@ -152,22 +150,22 @@ export function mergeResolvedReflectiveProviders(
providers: ResolvedReflectiveProvider[], providers: ResolvedReflectiveProvider[],
normalizedProvidersMap: Map<number, ResolvedReflectiveProvider>): normalizedProvidersMap: Map<number, ResolvedReflectiveProvider>):
Map<number, ResolvedReflectiveProvider> { Map<number, ResolvedReflectiveProvider> {
for (var i = 0; i < providers.length; i++) { for (let i = 0; i < providers.length; i++) {
var provider = providers[i]; const provider = providers[i];
var existing = normalizedProvidersMap.get(provider.key.id); const existing = normalizedProvidersMap.get(provider.key.id);
if (isPresent(existing)) { if (existing) {
if (provider.multiProvider !== existing.multiProvider) { if (provider.multiProvider !== existing.multiProvider) {
throw new MixingMultiProvidersWithRegularProvidersError(existing, provider); throw new MixingMultiProvidersWithRegularProvidersError(existing, provider);
} }
if (provider.multiProvider) { if (provider.multiProvider) {
for (var j = 0; j < provider.resolvedFactories.length; j++) { for (let j = 0; j < provider.resolvedFactories.length; j++) {
existing.resolvedFactories.push(provider.resolvedFactories[j]); existing.resolvedFactories.push(provider.resolvedFactories[j]);
} }
} else { } else {
normalizedProvidersMap.set(provider.key.id, provider); normalizedProvidersMap.set(provider.key.id, provider);
} }
} else { } else {
var resolvedProvider: ResolvedReflectiveProvider; let resolvedProvider: ResolvedReflectiveProvider;
if (provider.multiProvider) { if (provider.multiProvider) {
resolvedProvider = new ResolvedReflectiveProvider_( resolvedProvider = new ResolvedReflectiveProvider_(
provider.key, provider.resolvedFactories.slice(), provider.multiProvider); provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
@ -204,26 +202,26 @@ export function constructDependencies(
if (!dependencies) { if (!dependencies) {
return _dependenciesFor(typeOrFunc); return _dependenciesFor(typeOrFunc);
} else { } else {
var params: any[][] = dependencies.map(t => [t]); const params: any[][] = dependencies.map(t => [t]);
return dependencies.map(t => _extractToken(typeOrFunc, t, params)); return dependencies.map(t => _extractToken(typeOrFunc, t, params));
} }
} }
function _dependenciesFor(typeOrFunc: any): ReflectiveDependency[] { function _dependenciesFor(typeOrFunc: any): ReflectiveDependency[] {
var params = reflector.parameters(typeOrFunc); const params = reflector.parameters(typeOrFunc);
if (!params) return []; if (!params) return [];
if (params.some(isBlank)) { if (params.some(p => p == null)) {
throw new NoAnnotationError(typeOrFunc, params); throw new NoAnnotationError(typeOrFunc, params);
} }
return params.map((p: any[]) => _extractToken(typeOrFunc, p, params)); return params.map(p => _extractToken(typeOrFunc, p, params));
} }
function _extractToken( function _extractToken(
typeOrFunc: any /** TODO #9100 */, metadata: any /** TODO #9100 */ /*any[] | any*/, typeOrFunc: any, metadata: any[] | any, params: any[][]): ReflectiveDependency {
params: any[][]): ReflectiveDependency { const depProps: any[] = [];
var depProps: any[] /** TODO #9100 */ = []; let token: any = null;
var token: any /** TODO #9100 */ = null; let optional = false;
var optional = false;
if (!Array.isArray(metadata)) { if (!Array.isArray(metadata)) {
if (metadata instanceof Inject) { if (metadata instanceof Inject) {
@ -233,11 +231,11 @@ function _extractToken(
} }
} }
var lowerBoundVisibility: any /** TODO #9100 */ = null; let lowerBoundVisibility: any = null;
var upperBoundVisibility: any /** TODO #9100 */ = null; let upperBoundVisibility: any = null;
for (var i = 0; i < metadata.length; ++i) { for (let i = 0; i < metadata.length; ++i) {
var paramMetadata = metadata[i]; let paramMetadata = metadata[i];
if (paramMetadata instanceof Type) { if (paramMetadata instanceof Type) {
token = paramMetadata; token = paramMetadata;
@ -261,7 +259,7 @@ function _extractToken(
token = resolveForwardRef(token); token = resolveForwardRef(token);
if (isPresent(token)) { if (token != null) {
return _createDependency(token, optional, lowerBoundVisibility, upperBoundVisibility, depProps); return _createDependency(token, optional, lowerBoundVisibility, upperBoundVisibility, depProps);
} else { } else {
throw new NoAnnotationError(typeOrFunc, params); throw new NoAnnotationError(typeOrFunc, params);
@ -269,9 +267,8 @@ function _extractToken(
} }
function _createDependency( function _createDependency(
token: any /** TODO #9100 */, optional: any /** TODO #9100 */, token: any, optional: boolean, lowerBoundVisibility: any, upperBoundVisibility: any,
lowerBoundVisibility: any /** TODO #9100 */, upperBoundVisibility: any /** TODO #9100 */, depProps: any[]): ReflectiveDependency {
depProps: any /** TODO #9100 */): ReflectiveDependency {
return new ReflectiveDependency( return new ReflectiveDependency(
ReflectiveKey.get(token), optional, lowerBoundVisibility, upperBoundVisibility, depProps); ReflectiveKey.get(token), optional, lowerBoundVisibility, upperBoundVisibility, depProps);
} }

View File

@ -7,7 +7,6 @@
*/ */
import {Injectable} from '../di'; import {Injectable} from '../di';
import {MapWrapper} from '../facade/collection';
import {scheduleMicroTask} from '../facade/lang'; import {scheduleMicroTask} from '../facade/lang';
import {NgZone} from '../zone/ng_zone'; import {NgZone} from '../zone/ng_zone';
@ -139,9 +138,9 @@ export class TestabilityRegistry {
getTestability(elem: any): Testability { return this._applications.get(elem); } getTestability(elem: any): Testability { return this._applications.get(elem); }
getAllTestabilities(): Testability[] { return MapWrapper.values(this._applications); } getAllTestabilities(): Testability[] { return Array.from(this._applications.values()); }
getAllRootElements(): any[] { return MapWrapper.keys(this._applications); } getAllRootElements(): any[] { return Array.from(this._applications.keys()); }
findTestabilityInTree(elem: Node, findInAncestors: boolean = true): Testability { findTestabilityInTree(elem: Node, findInAncestors: boolean = true): Testability {
return _testabilityGetter.findTestabilityInTree(this, elem, findInAncestors); return _testabilityGetter.findTestabilityInTree(this, elem, findInAncestors);

View File

@ -41,9 +41,11 @@ export function main() {
}); });
it('should detect equality for same content', () => { it('should detect equality for same content', () => {
expect(MapWrapper.createFromStringMap({'a': 1})).toEqual(MapWrapper.createFromStringMap({ const m1: Map<string, number> = new Map();
'a': 1 m1.set('a', 1);
})); const m2: Map<string, number> = new Map();
m2.set('a', 1);
expect(m1).toEqual(m2);
}); });
it('should detect missing entries', () => { it('should detect missing entries', () => {
@ -59,16 +61,19 @@ export function main() {
}); });
it('should detect additional entries', () => { it('should detect additional entries', () => {
expect(MapWrapper.createFromStringMap({ const m1: Map<string, number> = new Map();
'a': 1 m1.set('a', 1);
})).not.toEqual(MapWrapper.createFromStringMap({'a': 1, 'b': 1})); const m2: Map<string, number> = new Map();
m2.set('a', 1);
m2.set('b', 2);
expect(m1).not.toEqual(m2);
}); });
}); });
describe('spy objects', () => { describe('spy objects', () => {
let spyObj: any; let spyObj: any;
beforeEach(() => { spyObj = <any>new SpyTestObj(); }); beforeEach(() => { spyObj = new SpyTestObj(); });
it('should return a new spy func with no calls', it('should return a new spy func with no calls',
() => { expect(spyObj.spy('someFunc')).not.toHaveBeenCalled(); }); () => { expect(spyObj.spy('someFunc')).not.toHaveBeenCalled(); });
@ -98,8 +103,7 @@ export function main() {
}); });
it('should support stubs', () => { it('should support stubs', () => {
var s = SpyObject.stub({'a': 1}, {'b': 2}); const s = SpyObject.stub({'a': 1}, {'b': 2});
expect(s.a()).toEqual(1); expect(s.a()).toEqual(1);
expect(s.b()).toEqual(2); expect(s.b()).toEqual(2);
}); });

View File

@ -6,39 +6,16 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {getSymbolIterator, isBlank, isJsObject, isPresent} from './lang'; import {getSymbolIterator, isJsObject, isPresent} from './lang';
// Safari doesn't implement MapIterator.next(), which is used is Traceur's polyfill of Array.from
// TODO(mlaval): remove the work around once we have a working polyfill of Array.from
const _arrayFromMap: {(m: Map<any, any>, getValues: boolean): any[]} = (function() {
try {
if ((<any>(new Map()).values()).next) {
return function createArrayFromMap(m: Map<any, any>, getValues: boolean): any[] {
return getValues ? (<any>Array).from(m.values()) : (<any>Array).from(m.keys());
};
}
} catch (e) {
}
return function createArrayFromMapWithForeach(m: Map<any, any>, getValues: boolean): any[] {
var res = new Array(m.size), i = 0;
m.forEach((v, k) => {
res[i] = getValues ? v : k;
i++;
});
return res;
};
})();
export class MapWrapper { export class MapWrapper {
static createFromStringMap<T>(stringMap: {[key: string]: T}): Map<string, T> { static createFromStringMap<T>(stringMap: {[key: string]: T}): Map<string, T> {
var result = new Map<string, T>(); const result = new Map<string, T>();
for (var prop in stringMap) { for (let prop in stringMap) {
result.set(prop, stringMap[prop]); result.set(prop, stringMap[prop]);
} }
return result; return result;
} }
static keys<K>(m: Map<K, any>): K[] { return _arrayFromMap(m, false); }
static values<V>(m: Map<any, V>): V[] { return _arrayFromMap(m, true); }
} }
/** /**

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {ListWrapper, MapWrapper, StringMapWrapper} from '../src/collection'; import {ListWrapper, StringMapWrapper} from '../src/collection';
export function main() { export function main() {
describe('ListWrapper', () => { describe('ListWrapper', () => {
@ -35,45 +35,36 @@ export function main() {
() => { expect(StringMapWrapper.equals({}, {})).toBe(true); }); () => { expect(StringMapWrapper.equals({}, {})).toBe(true); });
it('should return true when comparing the same map', () => { it('should return true when comparing the same map', () => {
var m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3}; const m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3};
expect(StringMapWrapper.equals(m1, m1)).toBe(true); expect(StringMapWrapper.equals(m1, m1)).toBe(true);
}); });
it('should return true when comparing different maps with the same keys and values', () => { it('should return true when comparing different maps with the same keys and values', () => {
var m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3}; const m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3};
var m2: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3}; const m2: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3};
expect(StringMapWrapper.equals(m1, m2)).toBe(true); expect(StringMapWrapper.equals(m1, m2)).toBe(true);
}); });
it('should return false when comparing maps with different numbers of keys', () => { it('should return false when comparing maps with different numbers of keys', () => {
var m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3}; const m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3};
var m2: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3, 'd': 4}; const m2: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3, 'd': 4};
expect(StringMapWrapper.equals(m1, m2)).toBe(false); expect(StringMapWrapper.equals(m1, m2)).toBe(false);
expect(StringMapWrapper.equals(m2, m1)).toBe(false); expect(StringMapWrapper.equals(m2, m1)).toBe(false);
}); });
it('should return false when comparing maps with different keys', () => { it('should return false when comparing maps with different keys', () => {
var m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3}; const m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3};
var m2: {[key: string]: number} = {'a': 1, 'b': 2, 'CC': 3}; const m2: {[key: string]: number} = {'a': 1, 'b': 2, 'CC': 3};
expect(StringMapWrapper.equals(m1, m2)).toBe(false); expect(StringMapWrapper.equals(m1, m2)).toBe(false);
expect(StringMapWrapper.equals(m2, m1)).toBe(false); expect(StringMapWrapper.equals(m2, m1)).toBe(false);
}); });
it('should return false when comparing maps with different values', () => { it('should return false when comparing maps with different values', () => {
var m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3}; const m1: {[key: string]: number} = {'a': 1, 'b': 2, 'c': 3};
var m2: {[key: string]: number} = {'a': 1, 'b': 20, 'c': 3}; const m2: {[key: string]: number} = {'a': 1, 'b': 20, 'c': 3};
expect(StringMapWrapper.equals(m1, m2)).toBe(false); expect(StringMapWrapper.equals(m1, m2)).toBe(false);
expect(StringMapWrapper.equals(m2, m1)).toBe(false); expect(StringMapWrapper.equals(m2, m1)).toBe(false);
}); });
}); });
describe('MapWrapper', () => {
it('should return a list of keys values', () => {
var m = new Map();
m.set('a', 'b');
expect(MapWrapper.keys(m)).toEqual(['a']);
expect(MapWrapper.values(m)).toEqual(['b']);
});
});
}); });
} }

View File

@ -8,7 +8,6 @@
import {Directive, ElementRef, Host, Input, OnDestroy, Optional, Renderer, forwardRef} from '@angular/core'; import {Directive, ElementRef, Host, Input, OnDestroy, Optional, Renderer, forwardRef} from '@angular/core';
import {MapWrapper} from '../facade/collection';
import {isBlank, isPresent, isPrimitive, looseIdentical} from '../facade/lang'; import {isBlank, isPresent, isPrimitive, looseIdentical} from '../facade/lang';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
@ -108,7 +107,7 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
/** @internal */ /** @internal */
_getOptionId(value: any): string { _getOptionId(value: any): string {
for (let id of MapWrapper.keys(this._optionMap)) { for (let id of Array.from(this._optionMap.keys())) {
if (looseIdentical(this._optionMap.get(id), value)) return id; if (looseIdentical(this._optionMap.get(id), value)) return id;
} }
return null; return null;

View File

@ -8,7 +8,6 @@
import {Directive, ElementRef, Host, Input, OnDestroy, OpaqueToken, Optional, Renderer, Type, forwardRef} from '@angular/core'; import {Directive, ElementRef, Host, Input, OnDestroy, OpaqueToken, Optional, Renderer, Type, forwardRef} from '@angular/core';
import {MapWrapper} from '../facade/collection';
import {isBlank, isPresent, isPrimitive, looseIdentical} from '../facade/lang'; import {isBlank, isPresent, isPrimitive, looseIdentical} from '../facade/lang';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
@ -114,7 +113,7 @@ export class SelectMultipleControlValueAccessor implements ControlValueAccessor
/** @internal */ /** @internal */
_getOptionId(value: any): string { _getOptionId(value: any): string {
for (let id of MapWrapper.keys(this._optionMap)) { for (let id of Array.from(this._optionMap.keys())) {
if (looseIdentical(this._optionMap.get(id)._value, value)) return id; if (looseIdentical(this._optionMap.get(id)._value, value)) return id;
} }
return null; return null;

View File

@ -6,8 +6,6 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MapWrapper} from '../src/facade/collection';
/** /**
* Polyfill for [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers/Headers), as * Polyfill for [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers/Headers), as
* specified in the [Fetch Spec](https://fetch.spec.whatwg.org/#headers-class). * specified in the [Fetch Spec](https://fetch.spec.whatwg.org/#headers-class).
@ -128,7 +126,7 @@ export class Headers {
/** /**
* Returns the names of the headers * Returns the names of the headers
*/ */
keys(): string[] { return MapWrapper.values(this._normalizedNames); } keys(): string[] { return Array.from(this._normalizedNames.values()); }
/** /**
* Sets or overrides header value for given name. * Sets or overrides header value for given name.
@ -147,7 +145,7 @@ export class Headers {
/** /**
* Returns values of all headers. * Returns values of all headers.
*/ */
values(): string[][] { return MapWrapper.values(this._headers); } values(): string[][] { return Array.from(this._headers.values()); }
/** /**
* Returns string of all headers. * Returns string of all headers.

View File

@ -1,29 +0,0 @@
/**
* @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
*/
import {describe, it} from '@angular/core/testing/testing_internal';
// import {MapWrapper} from '../../src/facade/src/collection';
// import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
// import {DomTestbed, TestRootView, elRef} from './dom_testbed';
// import {
// ViewDefinition,
// RenderDirectiveMetadata,
// RenderViewRef,
// ViewEncapsulation
// } from '@angular/core/src/render/api';
export function main() {
describe('DomRenderer integration', () => {
it('should work', () => {
// TODO
});
});
}

View File

@ -8,18 +8,17 @@
import {NgZone} from '@angular/core'; import {NgZone} from '@angular/core';
import {MapWrapper} from './facade/collection'; import {global} from './facade/lang';
import {global, isPresent} from './facade/lang';
import {getDOM} from './private_import_platform-browser'; import {getDOM} from './private_import_platform-browser';
export class BrowserDetection { export class BrowserDetection {
private _overrideUa: string; private _overrideUa: string;
private get _ua(): string { private get _ua(): string {
if (isPresent(this._overrideUa)) { if (typeof this._overrideUa === 'string') {
return this._overrideUa; return this._overrideUa;
} else {
return getDOM() ? getDOM().getUserAgent() : '';
} }
return getDOM() ? getDOM().getUserAgent() : '';
} }
static setup() { browserDetection = new BrowserDetection(null); } static setup() { browserDetection = new BrowserDetection(null); }
@ -102,7 +101,7 @@ export function stringifyElement(el: any /** TODO #9100 */): string {
// Attributes in an ordered way // Attributes in an ordered way
var attributeMap = getDOM().attributeMap(el); var attributeMap = getDOM().attributeMap(el);
var keys: string[] = MapWrapper.keys(attributeMap).sort(); var keys: string[] = Array.from(attributeMap.keys()).sort();
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
var key = keys[i]; var key = keys[i];
var attValue = attributeMap.get(key); var attValue = attributeMap.get(key);
@ -116,7 +115,7 @@ export function stringifyElement(el: any /** TODO #9100 */): string {
// Children // Children
var childrenRoot = getDOM().templateAwareRoot(el); var childrenRoot = getDOM().templateAwareRoot(el);
var children = isPresent(childrenRoot) ? getDOM().childNodes(childrenRoot) : []; var children = childrenRoot ? getDOM().childNodes(childrenRoot) : [];
for (let j = 0; j < children.length; j++) { for (let j = 0; j < children.length; j++) {
result += stringifyElement(children[j]); result += stringifyElement(children[j]);
} }