@@ -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
@@ -59,6 +59,7 @@ RenderResult.build = function(env, scope, template, options, contextualElement)
5959 ownerNode = rootNode . ownerNode ;
6060 shouldSetContent = true ;
6161 } else {
62+ // creating the root render node
6263 rootNode = dom . createMorph ( null , fragment . firstChild , fragment . lastChild , contextualElement ) ;
6364 ownerNode = rootNode ;
6465 initializeNode ( rootNode , ownerNode ) ;
@@ -75,6 +76,14 @@ RenderResult.build = function(env, scope, template, options, contextualElement)
7576 return new RenderResult ( env , scope , options , rootNode , ownerNode , nodes , fragment , template , shouldSetContent ) ;
7677} ;
7778
79+ RenderResult . rehydrate = function ( env , scope , template , options ) {
80+ let rootNode = options . renderNode ;
81+ let ownerNode = rootNode . ownerNode ;
82+ let shouldSetContent = false ;
83+
84+ return new RenderResult ( env , scope , options , rootNode , ownerNode , rootNode . childNodes , null , template , shouldSetContent ) ;
85+ } ;
86+
7887export function manualElement ( tagName , attributes , _isEmpty ) {
7988 var statements = [ ] ;
8089
@@ -318,3 +327,132 @@ export function getCachedFragment(template, env) {
318327
319328 return fragment ;
320329}
330+
331+ export function rehydrateNode ( serializedNodes , renderNode ) {
332+ let dom = renderNode . domHelper ;
333+ let context = renderNode . firstNode . parentNode ;
334+ let cache = Object . create ( null ) ;
335+
336+ renderNode . childNodes = serializedNodes . map ( childNode => _rehydrateNode ( renderNode , childNode , dom , context , cache ) ) ;
337+ return renderNode ;
338+ }
339+
340+ function _rehydrateNode ( owner , renderNode , dom , context , cache ) {
341+ let element , node ;
342+
343+ switch ( renderNode . type ) {
344+ case 'attr' :
345+ element = elementFromId ( dom , context , renderNode . element , cache ) ;
346+ node = dom . createAttrMorph ( element , renderNode . attrName ) ;
347+ break ;
348+ case 'range' :
349+ element = elementFromId ( dom , context , renderNode . parentNode , cache ) ;
350+ node = dom . createMorphAt ( element , renderNode . firstNode , renderNode . lastNode ) ;
351+ node . lastYielded = LastYielded . fromTemplateId ( renderNode . templateId ) ;
352+ node . childNodes = renderNode . childNodes && renderNode . childNodes . map ( childNode => _rehydrateNode ( node , childNode , dom , context , cache ) ) ;
353+ break ;
354+ }
355+
356+ initializeNode ( node , owner ) ;
357+ return node ;
358+ }
359+
360+ function elementFromId ( dom , context , id , cache ) {
361+ if ( id in cache ) {
362+ return cache [ id ] ;
363+ }
364+
365+ let element = context . querySelector ( `[data-hbs-node="${ id } "]` ) ;
366+ dom . removeAttribute ( element , 'data-hbs-node' ) ;
367+ cache [ id ] = element ;
368+ return element ;
369+ }
370+
371+ export function serializeNode ( env , renderNode ) {
372+ let serializationContext = { id : 0 } ;
373+
374+ return renderNode . childNodes . map ( childNode => _serializeNode ( env , childNode , serializationContext ) ) ;
375+
376+ //return [{
377+ //type: 'attr',
378+ //element: "0",
379+ //attrName: 'title'
380+ //}, {
381+ //type: 'range',
382+ //parentNode: "0",
383+ //firstNode: 0,
384+ //lastNode: 0
385+ //}];
386+ }
387+
388+ function _serializeNode ( env , renderNode , serializationContext ) {
389+ let dom = env . dom ;
390+ if ( renderNode instanceof dom . MorphClass ) {
391+ let parent = renderNode . firstNode . parentNode ;
392+ let { firstNode, lastNode } = parentOffsets ( dom , parent , renderNode ) ;
393+
394+ return {
395+ type : 'range' ,
396+ childNodes : renderNode . childNodes && renderNode . childNodes . map ( childNode => _serializeNode ( env , childNode , serializationContext ) ) ,
397+ parentNode : idFromElement ( dom , parent , serializationContext ) ,
398+ templateId : renderNode . lastYielded && env . hooks . serializeLastYielded ( env , renderNode ) ,
399+ firstNode,
400+ lastNode
401+ } ;
402+ } else if ( renderNode instanceof dom . AttrMorphClass ) {
403+ return {
404+ type : 'attr' ,
405+ element : idFromElement ( dom , renderNode . element , serializationContext ) ,
406+ attrName : renderNode . attrName
407+ } ;
408+ }
409+ }
410+
411+ function parentOffsets ( dom , parent , renderNode ) {
412+ let current = parent . firstChild ;
413+ let firstNeedle = renderNode . firstNode ;
414+ let lastNeedle = renderNode . lastNode ;
415+ let firstNode , lastNode ;
416+
417+ while ( current !== firstNeedle ) {
418+ current = current . nextSibling ;
419+ }
420+
421+ firstNode = current ;
422+
423+ while ( current !== lastNeedle ) {
424+ current = current . nextSibling ;
425+ }
426+
427+ lastNode = current ;
428+
429+ return { firstNode, lastNode } ;
430+ }
431+
432+ function idFromElement ( dom , element , serializationContext ) {
433+ let id = dom . getAttribute ( element , 'data-hbs-node' ) ;
434+
435+ if ( id ) {
436+ return id ;
437+ }
438+
439+ id = ( serializationContext . id ++ ) + '' ;
440+ dom . setAttribute ( element , 'data-hbs-node' , id ) ;
441+ return id ;
442+ }
443+
444+ export function LastYielded ( self , template , shadowTemplate , templateId ) {
445+ this . self = self ;
446+ this . template = template ;
447+ this . shadowTemplate = shadowTemplate ;
448+ this . templateId = templateId ;
449+ }
450+
451+ LastYielded . fromTemplateId = function ( templateId ) {
452+ return new LastYielded ( null , null , null , templateId ) ;
453+ } ;
454+
455+ LastYielded . prototype . isStableTemplate = function ( nextTemplate ) {
456+ return ! this . shadowTemplate && nextTemplate === this . template ;
457+ } ;
458+
0 commit comments