@@ -12,6 +12,8 @@ export const EVENT_TARGET_SEPARATOR = ':';
1212export const NG_CONTENT_ELEMENT_NAME = 'ng-content' ;
1313export const NG_SHADOW_ROOT_ELEMENT_NAME = 'shadow-root' ;
1414
15+ const MAX_IN_MEMORY_ELEMENTS_PER_TEMPLATE = 20 ;
16+
1517var CAMEL_CASE_REGEXP = / ( [ A - Z ] ) / g;
1618var DASH_CASE_REGEXP = / - ( [ a - z ] ) / g;
1719
@@ -57,8 +59,7 @@ export class ClonedProtoView {
5759
5860export function cloneAndQueryProtoView ( pv : DomProtoView , importIntoDocument : boolean ) :
5961 ClonedProtoView {
60- var templateContent = importIntoDocument ? DOM . importIntoDoc ( DOM . content ( pv . rootElement ) ) :
61- DOM . clone ( DOM . content ( pv . rootElement ) ) ;
62+ var templateContent = pv . cloneableTemplate . clone ( importIntoDocument ) ;
6263
6364 var boundElements = queryBoundElements ( templateContent , pv . isSingleElementFragment ) ;
6465 var boundTextNodes = queryBoundTextNodes ( templateContent , pv . rootTextNodeIndices , boundElements ,
@@ -140,3 +141,45 @@ export function prependAll(parentNode: Node, nodes: Node[]) {
140141 lastInsertedNode = node ;
141142 } ) ;
142143}
144+
145+ export interface CloneableTemplate { clone ( importIntoDoc : boolean ) : Node ; }
146+
147+ export class SerializedCloneableTemplate implements CloneableTemplate {
148+ templateString : string ;
149+ constructor ( templateRoot : Element ) { this . templateString = DOM . getInnerHTML ( templateRoot ) ; }
150+ clone ( importIntoDoc : boolean ) : Node {
151+ var result = DOM . content ( DOM . createTemplate ( this . templateString ) ) ;
152+ if ( importIntoDoc ) {
153+ result = DOM . adoptNode ( result ) ;
154+ }
155+ return result ;
156+ }
157+ }
158+
159+ export class ReferenceCloneableTemplate implements CloneableTemplate {
160+ constructor ( public templateRoot : Element ) { }
161+ clone ( importIntoDoc : boolean ) : Node {
162+ if ( importIntoDoc ) {
163+ return DOM . importIntoDoc ( DOM . content ( this . templateRoot ) ) ;
164+ } else {
165+ return DOM . clone ( DOM . content ( this . templateRoot ) ) ;
166+ }
167+ }
168+ }
169+
170+ export function prepareTemplateForClone ( templateRoot : Element ) : CloneableTemplate {
171+ var root = DOM . content ( templateRoot ) ;
172+ var elementCount = DOM . querySelectorAll ( root , '*' ) . length ;
173+ var firstChild = DOM . firstChild ( root ) ;
174+ var forceSerialize =
175+ isPresent ( firstChild ) && DOM . isCommentNode ( firstChild ) ? DOM . nodeValue ( firstChild ) : null ;
176+ if ( forceSerialize == 'nocache' ) {
177+ return new SerializedCloneableTemplate ( templateRoot ) ;
178+ } else if ( forceSerialize == 'cache' ) {
179+ return new ReferenceCloneableTemplate ( templateRoot ) ;
180+ } else if ( elementCount > MAX_IN_MEMORY_ELEMENTS_PER_TEMPLATE ) {
181+ return new SerializedCloneableTemplate ( templateRoot ) ;
182+ } else {
183+ return new ReferenceCloneableTemplate ( templateRoot ) ;
184+ }
185+ }
0 commit comments