11const { parse } = require ( "node-html-parser" ) ;
2- const { checkValue, ObjectId } = require ( "@cocreate/utils" ) ;
2+ const { checkValue, getRelativePath , ObjectId } = require ( "@cocreate/utils" ) ;
33const path = require ( "path" ) ;
44
55class CoCreateServerSideRender {
@@ -20,6 +20,8 @@ class CoCreateServerSideRender {
2020
2121 let dep = [ ] ;
2222 let dbCache = new Map ( ) ;
23+ let organization_id = file . organization_id ;
24+ const host = file . urlObject . hostname ;
2325
2426 async function render ( dom , lastKey ) {
2527 // Handle elements with [array][key][object]
@@ -59,6 +61,7 @@ class CoCreateServerSideRender {
5961 } else {
6062 data = await self . crud . send ( {
6163 method : "object.read" ,
64+ host,
6265 array,
6366 object : { _id } ,
6467 organization_id
@@ -97,24 +100,29 @@ class CoCreateServerSideRender {
97100 let src = el . getAttribute ( "src" ) ;
98101 if ( ! src ) continue ;
99102
103+ let path =
104+ el . getAttribute ( "path" ) || getRelativePath ( file . path ) ;
105+
106+ if ( path ) {
107+ src = src . replaceAll ( / \$ r e l a t i v e P a t h \/ ? / g, path ) ;
108+ }
109+
100110 // Construct actual pathname using src and the original URL
101- let basePath = new URL ( url ) . pathname ;
102- let resolvedPathname = new URL (
103- src ,
104- `http://localhost${ basePath } `
105- ) . pathname ;
106-
107- if ( resolvedPathname . endsWith ( "/" ) ) {
108- resolvedPathname += "index.html" ;
111+ let pathname = new URL ( src , `http://localhost${ file . path } ` )
112+ . pathname ;
113+
114+ if ( pathname . endsWith ( "/" ) ) {
115+ pathname += "index.html" ;
109116 }
110117 let $filter = {
111118 query : {
112- pathname : resolvedPathname
119+ pathname : pathname
113120 }
114121 } ; // Use filter to structure query
115122
116123 let data = await self . crud . send ( {
117124 method : "object.read" ,
125+ host,
118126 array : "files" ,
119127 object : "" ,
120128 $filter,
@@ -142,11 +150,16 @@ class CoCreateServerSideRender {
142150 return ObjectId ( ) . toString ( ) ; // Return its string representation
143151 } ) ;
144152
145- chunk = await render ( chunk ) ;
153+ // Parse chunk into DOM before recursive rendering
154+ let chunkDom = parse ( chunk ) ;
155+ chunkDom = await render ( chunkDom ) ;
146156
147157 el . setAttribute ( "rendered" , "" ) ;
148158 el . innerHTML = "" ;
149- el . appendChild ( chunk ) ;
159+ // Append all child nodes of chunkDom to el
160+ for ( const child of chunkDom . childNodes ) {
161+ el . appendChild ( child ) ;
162+ }
150163 }
151164 }
152165
@@ -177,14 +190,6 @@ class CoCreateServerSideRender {
177190 return dom . toString ( ) ;
178191 }
179192
180- getRelativePath ( path ) {
181- if ( ! path . endsWith ( "/" ) ) {
182- path += "/" ;
183- }
184- let depth = path . split ( "/" ) . filter ( Boolean ) . length ;
185- return depth > 0 ? "../" . repeat ( depth ) : "./" ;
186- }
187-
188193 createLanguageLinkTags ( file ) {
189194 let xDefault = file . path ;
190195
@@ -229,8 +234,9 @@ class CoCreateServerSideRender {
229234 let lang = file . lang ;
230235 if ( file . translations && ( langRegion || lang ) ) {
231236 for ( let translation of file . translations ) {
232- let elements = dom . querySelectorAll ( translation . selector ) ;
237+ let elements = dom . querySelectorAll ( translation . selector ) || [ ] ;
233238 for ( let el of elements ) {
239+ if ( ! el ) continue ;
234240 if ( translation . innerHTML ) {
235241 let content =
236242 translation . innerHTML [ langRegion ] ||
0 commit comments