1
1
// aliased utils
2
2
const isA = Array . isArray
3
- const replace = ( n , ...e ) => n . replace ( ...e )
4
3
5
4
// https://github.com/justin-schroeder/arrow-js/blob/31c1861075aabe29b67620b58a33c7fecb209c8f/src/html.ts#L166C1-L166C23
6
5
const delimiter = '➳❍'
7
6
const delimiterComment = `<!--${ delimiter } -->`
7
+ const delimiterRegexGlobal = new RegExp ( delimiterComment , 'g' )
8
8
9
9
//FIXME: Don't really need to handle
10
10
// const bookend = '❍⇚'
@@ -14,7 +14,6 @@ const eventRegex = /(@)(\w+)=["']$/
14
14
15
15
export function renderToString ( template ) {
16
16
const isT = 'isT' in template
17
-
18
17
// FIXME: not a template, throw an error instead,
19
18
// move the fault tolerant behavior to another function
20
19
if ( ! isT ) {
@@ -25,67 +24,68 @@ export function renderToString(template) {
25
24
26
25
let htmlString = renderResult [ 0 ]
27
26
const expressions = renderResult [ 1 ]
28
- let index = - 1
29
27
30
28
if ( ! expressions . length ) return htmlString
31
29
32
- return replace (
33
- htmlString ,
34
- new RegExp ( delimiterComment , 'g' ) ,
35
- ( ...matchers ) => {
36
- const str = matchers [ 0 ]
37
- const matchedAt = matchers [ 1 ]
38
- const matchedString = matchers [ 2 ]
39
- index += 1
40
-
41
- const beforeDelim = matchedString . slice ( 0 , matchedAt )
42
- const immediatelyFollowed = eventRegex . test ( beforeDelim )
43
- if ( immediatelyFollowed ) {
44
- return str
45
- }
46
- return interpolateExpressions ( str , expressions [ index ] )
30
+ return htmlString . replace ( delimiterRegexGlobal , matchReplace ( expressions ) )
31
+ }
32
+
33
+ function matchReplace ( expressions ) {
34
+ let index = - 1
35
+ return ( ...matchers ) => {
36
+ const str = matchers [ 0 ]
37
+ const matchedAt = matchers [ 1 ]
38
+ const matchedString = matchers [ 2 ]
39
+ index += 1
40
+
41
+ const beforeDelim = matchedString . slice ( 0 , matchedAt )
42
+ const immediatelyFollowed = eventRegex . test ( beforeDelim )
43
+
44
+ // check if we are on a event handler delimiter
45
+ // while rendering strings, we don't need this information
46
+ // so we remove it
47
+ if ( immediatelyFollowed ) {
48
+ return ''
47
49
}
48
- )
50
+
51
+ return interpolateExpressions ( expressions [ index ] )
52
+ }
49
53
}
50
54
51
- function interpolateExpressions ( htmlString , expressionInstance ) {
55
+ // Replace the htmlString's next occuring
56
+ function interpolateExpressions ( expressionInstance ) {
52
57
const isExpressionReactive = expressionInstance && expressionInstance . e
53
58
const isExpressionPartial = isExpressionReactive . isT
54
59
55
60
if ( ! isExpressionReactive ) {
56
- return replace ( htmlString , delimiterComment , expressionInstance ( ) )
61
+ return expressionInstance ( )
57
62
}
58
63
59
64
if ( isExpressionPartial ) {
60
- return replace (
61
- htmlString ,
62
- delimiterComment ,
63
- renderToString ( expressionInstance . e )
64
- )
65
+ return renderToString ( expressionInstance . e )
65
66
}
66
67
67
68
const watcherReturn = expressionInstance . e ( )
68
69
69
70
if (
70
71
typeof watcherReturn !== 'object' &&
71
- typeof watcherReturn !== 'function' &&
72
- ! isA ( watcherReturn )
72
+ typeof watcherReturn !== 'function'
73
73
) {
74
- return replace ( htmlString , delimiterComment , watcherReturn )
74
+ return watcherReturn
75
75
}
76
76
77
77
if ( isA ( watcherReturn ) ) {
78
- const result = watcherReturn . map ( x => {
78
+ return watcherReturn . reduce ( ( acc , x ) => {
79
79
if ( 'isT' in x ) {
80
- return renderToString ( x )
80
+ return acc + renderToString ( x )
81
81
}
82
- return x
83
- } )
84
- return result . join ( '' )
82
+ return acc + x
83
+ } , '' )
85
84
}
86
85
87
86
if ( watcherReturn && watcherReturn . isT ) {
88
- const _nestedHtmlString = renderToString ( watcherReturn )
89
- return replace ( htmlString , delimiterComment , _nestedHtmlString )
87
+ return renderToString ( watcherReturn )
90
88
}
89
+
90
+ return ''
91
91
}
0 commit comments