@@ -28,7 +28,7 @@ export default function render(template, env, scope, options) {
2828 return renderResult ;
2929}
3030
31- function RenderResult ( env , scope , options , rootNode , ownerNode , nodes , fragment , template , shouldSetContent ) {
31+ export function RenderResult ( env , scope , options , rootNode , ownerNode , nodes , fragment , template , shouldSetContent ) {
3232 this . root = rootNode ;
3333 this . fragment = fragment ;
3434
@@ -64,6 +64,7 @@ RenderResult.build = function(env, scope, template, options, contextualElement)
6464 ownerNode = rootNode . ownerNode ;
6565 shouldSetContent = true ;
6666 } else {
67+ // creating the root render node
6768 rootNode = dom . createMorph ( null , fragment . firstChild , fragment . lastChild , contextualElement ) ;
6869 ownerNode = rootNode ;
6970 initializeNode ( rootNode , ownerNode ) ;
@@ -80,6 +81,14 @@ RenderResult.build = function(env, scope, template, options, contextualElement)
8081 return new RenderResult ( env , scope , options , rootNode , ownerNode , nodes , fragment , template , shouldSetContent ) ;
8182} ;
8283
84+ RenderResult . rehydrate = function ( env , scope , template , options ) {
85+ let rootNode = options . renderNode ;
86+ let ownerNode = rootNode . ownerNode ;
87+ let shouldSetContent = false ;
88+
89+ return new RenderResult ( env , scope , options , rootNode , ownerNode , rootNode . childNodes , null , template , shouldSetContent ) ;
90+ } ;
91+
8392export function manualElement ( tagName , attributes , _isEmpty ) {
8493 var statements = [ ] ;
8594
@@ -324,3 +333,132 @@ export function getCachedFragment(template, env) {
324333
325334 return fragment ;
326335}
336+
337+ export function rehydrateNode ( serializedNodes , renderNode ) {
338+ let dom = renderNode . domHelper ;
339+ let context = renderNode . firstNode . parentNode ;
340+ let cache = Object . create ( null ) ;
341+
342+ renderNode . childNodes = serializedNodes . map ( childNode => _rehydrateNode ( renderNode , childNode , dom , context , cache ) ) ;
343+ return renderNode ;
344+ }
345+
346+ function _rehydrateNode ( owner , renderNode , dom , context , cache ) {
347+ let element , node ;
348+
349+ switch ( renderNode . type ) {
350+ case 'attr' :
351+ element = elementFromId ( dom , context , renderNode . element , cache ) ;
352+ node = dom . createAttrMorph ( element , renderNode . attrName ) ;
353+ break ;
354+ case 'range' :
355+ element = elementFromId ( dom , context , renderNode . parentNode , cache ) ;
356+ node = dom . createMorphAt ( element , renderNode . firstNode , renderNode . lastNode ) ;
357+ node . lastYielded = LastYielded . fromTemplateId ( renderNode . templateId ) ;
358+ node . childNodes = renderNode . childNodes && renderNode . childNodes . map ( childNode => _rehydrateNode ( node , childNode , dom , context , cache ) ) ;
359+ break ;
360+ }
361+
362+ initializeNode ( node , owner ) ;
363+ return node ;
364+ }
365+
366+ function elementFromId ( dom , context , id , cache ) {
367+ if ( id in cache ) {
368+ return cache [ id ] ;
369+ }
370+
371+ let element = context . querySelector ( `[data-hbs-node="${ id } "]` ) ;
372+ dom . removeAttribute ( element , 'data-hbs-node' ) ;
373+ cache [ id ] = element ;
374+ return element ;
375+ }
376+
377+ export function serializeNode ( env , renderNode ) {
378+ let serializationContext = { id : 0 } ;
379+
380+ return renderNode . childNodes . map ( childNode => _serializeNode ( env , childNode , serializationContext ) ) ;
381+
382+ //return [{
383+ //type: 'attr',
384+ //element: "0",
385+ //attrName: 'title'
386+ //}, {
387+ //type: 'range',
388+ //parentNode: "0",
389+ //firstNode: 0,
390+ //lastNode: 0
391+ //}];
392+ }
393+
394+ function _serializeNode ( env , renderNode , serializationContext ) {
395+ let dom = env . dom ;
396+ if ( renderNode instanceof dom . MorphClass ) {
397+ let parent = renderNode . firstNode . parentNode ;
398+ let { firstNode, lastNode } = parentOffsets ( dom , parent , renderNode ) ;
399+
400+ return {
401+ type : 'range' ,
402+ childNodes : renderNode . childNodes && renderNode . childNodes . map ( childNode => _serializeNode ( env , childNode , serializationContext ) ) ,
403+ parentNode : idFromElement ( dom , parent , serializationContext ) ,
404+ templateId : renderNode . lastYielded && env . hooks . serializeLastYielded ( env , renderNode ) ,
405+ firstNode,
406+ lastNode
407+ } ;
408+ } else if ( renderNode instanceof dom . AttrMorphClass ) {
409+ return {
410+ type : 'attr' ,
411+ element : idFromElement ( dom , renderNode . element , serializationContext ) ,
412+ attrName : renderNode . attrName
413+ } ;
414+ }
415+ }
416+
417+ function parentOffsets ( dom , parent , renderNode ) {
418+ let current = parent . firstChild ;
419+ let firstNeedle = renderNode . firstNode ;
420+ let lastNeedle = renderNode . lastNode ;
421+ let firstNode , lastNode ;
422+
423+ while ( current !== firstNeedle ) {
424+ current = current . nextSibling ;
425+ }
426+
427+ firstNode = current ;
428+
429+ while ( current !== lastNeedle ) {
430+ current = current . nextSibling ;
431+ }
432+
433+ lastNode = current ;
434+
435+ return { firstNode, lastNode } ;
436+ }
437+
438+ function idFromElement ( dom , element , serializationContext ) {
439+ let id = dom . getAttribute ( element , 'data-hbs-node' ) ;
440+
441+ if ( id ) {
442+ return id ;
443+ }
444+
445+ id = ( serializationContext . id ++ ) + '' ;
446+ dom . setAttribute ( element , 'data-hbs-node' , id ) ;
447+ return id ;
448+ }
449+
450+ export function LastYielded ( self , template , shadowTemplate , templateId ) {
451+ this . self = self ;
452+ this . template = template ;
453+ this . shadowTemplate = shadowTemplate ;
454+ this . templateId = templateId ;
455+ }
456+
457+ LastYielded . fromTemplateId = function ( templateId ) {
458+ return new LastYielded ( null , null , null , templateId ) ;
459+ } ;
460+
461+ LastYielded . prototype . isStableTemplate = function ( nextTemplate ) {
462+ return ! this . shadowTemplate && nextTemplate === this . template ;
463+ } ;
464+
0 commit comments