Skip to content

Commit 9fbf63d

Browse files
authored
Merge pull request #20627 from NullVoxPopuli/remove-escapeExpression
2 parents 8aa033d + 5131d7b commit 9fbf63d

File tree

4 files changed

+10
-62
lines changed

4 files changed

+10
-62
lines changed

packages/@ember/-internals/glimmer/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ export {
456456
type FunctionBasedHelper,
457457
type FunctionBasedHelperInstance,
458458
} from './lib/helper';
459-
export { SafeString, escapeExpression, htmlSafe, isHTMLSafe } from './lib/utils/string';
459+
export { SafeString, htmlSafe, isHTMLSafe } from './lib/utils/string';
460460
export { Renderer, _resetRenderers, renderSettled } from './lib/renderer';
461461
export {
462462
getTemplate,

packages/@ember/-internals/glimmer/lib/utils/string.ts

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import type { SafeString as GlimmerSafeString } from '@glimmer/runtime';
3838
@public
3939
*/
4040
export class SafeString implements GlimmerSafeString {
41-
private __string: string;
41+
private readonly __string: string;
4242

4343
constructor(string: string) {
4444
this.__string = string;
@@ -67,57 +67,6 @@ export class SafeString implements GlimmerSafeString {
6767
}
6868
}
6969

70-
const escape = {
71-
'&': '&',
72-
'<': '&lt;',
73-
'>': '&gt;',
74-
'"': '&quot;',
75-
"'": '&#x27;',
76-
'`': '&#x60;',
77-
'=': '&#x3D;',
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-
12170
/**
12271
Use this method to indicate that a string should be rendered as HTML
12372
when the string is used in a template. To say this another way,
@@ -177,6 +126,10 @@ export function htmlSafe(str: string): SafeString {
177126
*/
178127
export function isHTMLSafe(str: unknown): str is SafeString {
179128
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'
181134
);
182135
}

packages/ember/barrel.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ import {
5656
componentCapabilities,
5757
modifierCapabilities,
5858
setComponentManager,
59-
escapeExpression,
6059
getTemplates,
6160
setTemplates,
6261
template,
@@ -604,9 +603,8 @@ Reflect.set(Ember, 'RSVP', _RSVP);
604603

605604
interface EmberHandlebars {
606605
template: typeof template;
607-
Utils: {
608-
escapeExpression: typeof escapeExpression;
609-
};
606+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
607+
Utils: {};
610608
compile?: typeof compile;
611609
precompile?: typeof precompile;
612610
}
@@ -672,9 +670,7 @@ applicationRunLoadHooks('Ember.Application', EmberApplication);
672670

673671
let EmberHandlebars: EmberHandlebars = {
674672
template,
675-
Utils: {
676-
escapeExpression,
677-
},
673+
Utils: {},
678674
};
679675

680676
let EmberHTMLBars: EmberHTMLBars = {

packages/ember/tests/reexports_test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,6 @@ let allExports = [
339339
},
340340
test56,
341341
],
342-
['Handlebars.Utils.escapeExpression', '@ember/-internals/glimmer', 'escapeExpression', test56],
343342
['_Input', '@ember/-internals/glimmer', 'Input', test56],
344343
['_RegistryProxyMixin', '@ember/-internals/runtime', 'RegistryProxyMixin', test57],
345344
['_ContainerProxyMixin', '@ember/-internals/runtime', 'ContainerProxyMixin', test57],

0 commit comments

Comments
 (0)