@@ -38,7 +38,7 @@ import type { SafeString as GlimmerSafeString } from '@glimmer/runtime';
38
38
@public
39
39
*/
40
40
export class SafeString implements GlimmerSafeString {
41
- private __string : string ;
41
+ private readonly __string : string ;
42
42
43
43
constructor ( string : string ) {
44
44
this . __string = string ;
@@ -67,57 +67,6 @@ export class SafeString implements GlimmerSafeString {
67
67
}
68
68
}
69
69
70
- const escape = {
71
- '&' : '&' ,
72
- '<' : '<' ,
73
- '>' : '>' ,
74
- '"' : '"' ,
75
- "'" : ''' ,
76
- '`' : '`' ,
77
- '=' : '=' ,
78
- } ;
79
-
80
- const possible = / [ & < > " ' ` = ] / ;
81
- const badChars = / [ & < > " ' ` = ] / g;
82
-
83
- function escapeChar ( chr : keyof typeof escape ) {
84
- return escape [ chr ] ;
85
- }
86
-
87
- export function escapeExpression ( string : unknown ) : string {
88
- let s : string ;
89
- if ( typeof string !== 'string' ) {
90
- // don't escape SafeStrings, since they're already safe
91
- if ( isHTMLSafe ( string ) ) {
92
- return string . toHTML ( ) ;
93
- } else if ( string === null || string === undefined ) {
94
- return '' ;
95
- } else if ( ! string ) {
96
- return String ( string ) ;
97
- }
98
-
99
- // Force a string conversion as this will be done by the append regardless and
100
- // the regex test will do this transparently behind the scenes, causing issues if
101
- // an object's to string has escaped characters in it.
102
- s = String ( string ) ;
103
- } else {
104
- s = string ;
105
- }
106
-
107
- if ( ! possible . test ( s ) ) {
108
- return s ;
109
- }
110
-
111
- // SAFETY: this is technically a lie, but it's a true lie as long as the
112
- // invariant it depends on is upheld: `escapeChar` will always return a string
113
- // as long as its input is one of the characters in `escape`, and it will only
114
- // be called if it matches one of the characters in the `badChar` regex, which
115
- // is hand-maintained to match the set escaped. (It would be nice if TS could
116
- // "see" into the regex to see how this works, but that'd be quite a lot of
117
- // extra fanciness.)
118
- return s . replace ( badChars , escapeChar as ( s : string ) => string ) ;
119
- }
120
-
121
70
/**
122
71
Use this method to indicate that a string should be rendered as HTML
123
72
when the string is used in a template. To say this another way,
@@ -177,6 +126,10 @@ export function htmlSafe(str: string): SafeString {
177
126
*/
178
127
export function isHTMLSafe ( str : unknown ) : str is SafeString {
179
128
return (
180
- str !== null && typeof str === 'object' && 'toHTML' in str && typeof str . toHTML === 'function'
129
+ // SAFETY: cast `as SafeString` only present to make this check "legal"; we
130
+ // can further improve this by changing the behavior to do an `in` check
131
+ // instead, but that's worth landing as a separate change for bisecting if
132
+ // it happens to have an impact on e.g. perf.
133
+ str !== null && typeof str === 'object' && typeof ( str as SafeString ) . toHTML === 'function'
181
134
) ;
182
135
}
0 commit comments