fix(compiler): skip when trimming / removing whitespaces (#19310)
Fixes #19304
This commit is contained in:
parent
9ad4b3bd31
commit
13613d4acb
|
@ -14,6 +14,12 @@ export const PRESERVE_WS_ATTR_NAME = 'ngPreserveWhitespaces';
|
||||||
|
|
||||||
const SKIP_WS_TRIM_TAGS = new Set(['pre', 'template', 'textarea', 'script', 'style']);
|
const SKIP_WS_TRIM_TAGS = new Set(['pre', 'template', 'textarea', 'script', 'style']);
|
||||||
|
|
||||||
|
// Equivalent to \s with \u00a0 (non-breaking space) excluded.
|
||||||
|
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
|
||||||
|
const WS_CHARS = ' \f\n\r\t\v\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff';
|
||||||
|
const NO_WS_REGEXP = new RegExp(`[^${WS_CHARS}]`);
|
||||||
|
const WS_REPLACE_REGEXP = new RegExp(`[${WS_CHARS}]{2,}`, 'g');
|
||||||
|
|
||||||
function hasPreserveWhitespacesAttr(attrs: html.Attribute[]): boolean {
|
function hasPreserveWhitespacesAttr(attrs: html.Attribute[]): boolean {
|
||||||
return attrs.some((attr: html.Attribute) => attr.name === PRESERVE_WS_ATTR_NAME);
|
return attrs.some((attr: html.Attribute) => attr.name === PRESERVE_WS_ATTR_NAME);
|
||||||
}
|
}
|
||||||
|
@ -63,10 +69,11 @@ class WhitespaceVisitor implements html.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
visitText(text: html.Text, context: any): any {
|
visitText(text: html.Text, context: any): any {
|
||||||
const isBlank = text.value.trim().length === 0;
|
const isNotBlank = text.value.match(NO_WS_REGEXP);
|
||||||
|
|
||||||
if (!isBlank) {
|
if (isNotBlank) {
|
||||||
return new html.Text(replaceNgsp(text.value).replace(/\s\s+/g, ' '), text.sourceSpan);
|
return new html.Text(
|
||||||
|
replaceNgsp(text.value).replace(WS_REPLACE_REGEXP, ' '), text.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -64,6 +64,16 @@ export function main() {
|
||||||
expect(parseAndRemoveWS(' \n foo \t ')).toEqual([[html.Text, ' foo ', 0]]);
|
expect(parseAndRemoveWS(' \n foo \t ')).toEqual([[html.Text, ' foo ', 0]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not replace ', () => {
|
||||||
|
expect(parseAndRemoveWS(' ')).toEqual([[html.Text, '\u00a0', 0]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not replace sequences of ', () => {
|
||||||
|
expect(parseAndRemoveWS(' foo ')).toEqual([
|
||||||
|
[html.Text, '\u00a0\u00a0foo\u00a0\u00a0', 0]
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not replace single tab and newline with spaces', () => {
|
it('should not replace single tab and newline with spaces', () => {
|
||||||
expect(parseAndRemoveWS('\nfoo')).toEqual([[html.Text, '\nfoo', 0]]);
|
expect(parseAndRemoveWS('\nfoo')).toEqual([[html.Text, '\nfoo', 0]]);
|
||||||
expect(parseAndRemoveWS('\tfoo')).toEqual([[html.Text, '\tfoo', 0]]);
|
expect(parseAndRemoveWS('\tfoo')).toEqual([[html.Text, '\tfoo', 0]]);
|
||||||
|
|
Loading…
Reference in New Issue