Support formatting for Angular ICU expression (#15777)
Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
1 parent
23b3ca2f52
commit
153ffd5104
21 files changed
+370
-9
No files matched your search
@@ -0,0 +1,19 @@
|
|||||||
|
#### Support formatting for Angular ICU expression (#15777 by @sosukesuzuki)
|
||||||
|
|
||||||
|
Support two kinds of Angular ICU expressions: [`plural`](https://angular.dev/guide/i18n/translation-files#translate-plurals) and [`select`](https://angular.dev/guide/i18n/translation-files#translate-alternate-expressions).
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
```html
|
||||||
|
<span i18n>
|
||||||
|
Updated:
|
||||||
|
{minutes, plural,
|
||||||
|
=0 {just now}
|
||||||
|
=1 {one minute ago}
|
||||||
|
other {{{minutes}} minutes ago}
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span i18n>
|
||||||
|
The author is {gender, select, male {male} female {female} other {other}}
|
||||||
|
</span>
|
||||||
|
```
|
||||||
+1
-1
@@ -43,7 +43,7 @@
|
|||||||
"acorn": "8.11.2",
|
"acorn": "8.11.2",
|
||||||
"acorn-jsx": "5.3.2",
|
"acorn-jsx": "5.3.2",
|
||||||
"angular-estree-parser": "9.0.0",
|
"angular-estree-parser": "9.0.0",
|
||||||
"angular-html-parser": "5.0.2",
|
"angular-html-parser": "5.2.0",
|
||||||
"camelcase": "8.0.0",
|
"camelcase": "8.0.0",
|
||||||
"chalk": "5.3.0",
|
"chalk": "5.3.0",
|
||||||
"ci-info": "4.0.0",
|
"ci-info": "4.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
const NODES_KEYS = {
|
const NODES_KEYS = {
|
||||||
attrs: true,
|
attrs: true,
|
||||||
children: true,
|
children: true,
|
||||||
|
cases: true, // plural and select
|
||||||
|
expression: true, // for expansionCase
|
||||||
};
|
};
|
||||||
|
|
||||||
const NON_ENUMERABLE_PROPERTIES = new Set(["parent"]);
|
const NON_ENUMERABLE_PROPERTIES = new Set(["parent"]);
|
||||||
@@ -136,12 +138,12 @@ class Node {
|
|||||||
|
|
||||||
get prev() {
|
get prev() {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
return this.parent?.children[this.parent.children.indexOf(this) - 1];
|
return this.parent?.children?.[this.parent.children.indexOf(this) - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
get next() {
|
get next() {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
return this.parent?.children[this.parent.children.indexOf(this) + 1];
|
return this.parent?.children?.[this.parent.children.indexOf(this) + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// for element and attribute
|
// for element and attribute
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ const ignoredProperties = new Set([
|
|||||||
"tagDefinition",
|
"tagDefinition",
|
||||||
"tokens",
|
"tokens",
|
||||||
"valueTokens",
|
"valueTokens",
|
||||||
|
"switchValueSourceSpan",
|
||||||
|
"expSourceSpan",
|
||||||
|
"valueSourceSpan",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const embeddedAngularControlFlowBlocks = new Set([
|
const embeddedAngularControlFlowBlocks = new Set([
|
||||||
@@ -47,6 +50,10 @@ function clean(ast, newNode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ast.type === "angularIcuExpression") {
|
||||||
|
newNode.switchValue = ast.switchValue.trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clean.ignoredProperties = ignoredProperties;
|
clean.ignoredProperties = ignoredProperties;
|
||||||
|
|||||||
@@ -67,6 +67,16 @@ function normalizeAngularControlFlowBlock(node) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeAngularIcuExpression(node) {
|
||||||
|
if (node.type === "plural" || node.type === "select") {
|
||||||
|
node.clause = node.type;
|
||||||
|
node.type = "angularIcuExpression";
|
||||||
|
}
|
||||||
|
if (node.type === "expansionCase") {
|
||||||
|
node.type = "angularIcuCase";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {ParseOptions} parseOptions
|
* @param {ParseOptions} parseOptions
|
||||||
@@ -261,6 +271,16 @@ function ngHtmlParser(input, parseOptions, options) {
|
|||||||
|
|
||||||
visitAll(
|
visitAll(
|
||||||
new (class extends RecursiveVisitor {
|
new (class extends RecursiveVisitor {
|
||||||
|
// Angular does not visit to the children of expansionCase
|
||||||
|
// https://github.com/angular/angular/blob/e3a6bf9b6c3bef03df9bfc8f05b817bc875cbad6/packages/compiler/src/ml_parser/ast.ts#L161
|
||||||
|
visitExpansionCase(ast, context) {
|
||||||
|
if (name === "angular") {
|
||||||
|
// @ts-expect-error
|
||||||
|
this.visitChildren(context, (visit) => {
|
||||||
|
visit(ast.expression);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
visit(node) {
|
visit(node) {
|
||||||
restoreNameAndValue(node);
|
restoreNameAndValue(node);
|
||||||
addTagDefinition(node);
|
addTagDefinition(node);
|
||||||
@@ -374,6 +394,7 @@ function parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
normalizeAngularControlFlowBlock(node);
|
normalizeAngularControlFlowBlock(node);
|
||||||
|
normalizeAngularIcuExpression(node);
|
||||||
});
|
});
|
||||||
|
|
||||||
return ast;
|
return ast;
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import {
|
||||||
|
softline,
|
||||||
|
line,
|
||||||
|
indent,
|
||||||
|
join,
|
||||||
|
group,
|
||||||
|
} from "../../document/builders.js";
|
||||||
|
import htmlWhitespaceUtils from "../../utils/html-whitespace-utils.js";
|
||||||
|
import { printClosingTagEnd, printOpeningTagStart } from "./tag.js";
|
||||||
|
|
||||||
|
/*
|
||||||
|
<span i18n>
|
||||||
|
Updated {minutes, plural,
|
||||||
|
=0 {just now}
|
||||||
|
=1 {one minute ago}
|
||||||
|
other {{{minutes}} minutes ago}
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
*/
|
||||||
|
|
||||||
|
function printAngularIcuExpression(path, options, print) {
|
||||||
|
const { node } = path;
|
||||||
|
return [
|
||||||
|
printOpeningTagStart(node, options),
|
||||||
|
group([
|
||||||
|
node.switchValue.trim(),
|
||||||
|
", ",
|
||||||
|
node.clause,
|
||||||
|
node.cases.length > 0
|
||||||
|
? [",", indent([line, join(line, path.map(print, "cases"))])]
|
||||||
|
: "",
|
||||||
|
softline,
|
||||||
|
]),
|
||||||
|
printClosingTagEnd(node, options),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function printAngularIcuCase(path, options, print) {
|
||||||
|
const { node } = path;
|
||||||
|
return [
|
||||||
|
node.value,
|
||||||
|
" {",
|
||||||
|
group([
|
||||||
|
indent([
|
||||||
|
softline,
|
||||||
|
path.map(({ node }) => {
|
||||||
|
// FIXME: We need a fundamental solution.
|
||||||
|
// Like this: https://github.com/prettier/prettier/blob/c1ebae2e8303841e59bc02e9e719a93e964ab0e9/src/language-html/print-preprocess.js#L254
|
||||||
|
if (node.type === "text" && !htmlWhitespaceUtils.trim(node.value)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return print();
|
||||||
|
}, "expression"),
|
||||||
|
]),
|
||||||
|
softline,
|
||||||
|
]),
|
||||||
|
"}",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export { printAngularIcuExpression, printAngularIcuCase };
|
||||||
@@ -60,7 +60,8 @@ function printElement(path, options, print) {
|
|||||||
*/
|
*/
|
||||||
const shouldHugContent =
|
const shouldHugContent =
|
||||||
node.children.length === 1 &&
|
node.children.length === 1 &&
|
||||||
node.firstChild.type === "interpolation" &&
|
(node.firstChild.type === "interpolation" ||
|
||||||
|
node.firstChild.type === "angularIcuExpression") &&
|
||||||
node.firstChild.isLeadingSpaceSensitive &&
|
node.firstChild.isLeadingSpaceSensitive &&
|
||||||
!node.firstChild.hasLeadingSpaces &&
|
!node.firstChild.hasLeadingSpaces &&
|
||||||
node.lastChild.isTrailingSpaceSensitive &&
|
node.lastChild.isTrailingSpaceSensitive &&
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ function printClosingTagEndMarker(node, options) {
|
|||||||
return "]><!-->";
|
return "]><!-->";
|
||||||
case "interpolation":
|
case "interpolation":
|
||||||
return "}}";
|
return "}}";
|
||||||
|
case "angularIcuExpression":
|
||||||
|
return "}";
|
||||||
case "element":
|
case "element":
|
||||||
if (node.isSelfClosing) {
|
if (node.isSelfClosing) {
|
||||||
return "/>";
|
return "/>";
|
||||||
@@ -345,6 +347,8 @@ function printOpeningTagStartMarker(node) {
|
|||||||
return "{{";
|
return "{{";
|
||||||
case "docType":
|
case "docType":
|
||||||
return node.value === "html" ? "<!doctype" : "<!DOCTYPE";
|
return node.value === "html" ? "<!doctype" : "<!DOCTYPE";
|
||||||
|
case "angularIcuExpression":
|
||||||
|
return "{";
|
||||||
case "element":
|
case "element":
|
||||||
if (node.condition) {
|
if (node.condition) {
|
||||||
return `<!--[if ${node.condition}]><!--><${node.rawName}`;
|
return `<!--[if ${node.condition}]><!--><${node.rawName}`;
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ import {
|
|||||||
printAngularControlFlowBlockParameters,
|
printAngularControlFlowBlockParameters,
|
||||||
} from "./print/angular-control-flow-block.js";
|
} from "./print/angular-control-flow-block.js";
|
||||||
import getVisitorKeys from "./get-visitor-keys.js";
|
import getVisitorKeys from "./get-visitor-keys.js";
|
||||||
|
import {
|
||||||
|
printAngularIcuExpression,
|
||||||
|
printAngularIcuCase,
|
||||||
|
} from "./print/angular-icu-expression.js";
|
||||||
|
|
||||||
function genericPrint(path, options, print) {
|
function genericPrint(path, options, print) {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
@@ -49,6 +53,11 @@ function genericPrint(path, options, print) {
|
|||||||
case "angularControlFlowBlockParameter":
|
case "angularControlFlowBlockParameter":
|
||||||
return htmlWhitespaceUtils.trim(node.expression);
|
return htmlWhitespaceUtils.trim(node.expression);
|
||||||
|
|
||||||
|
case "angularIcuExpression":
|
||||||
|
return printAngularIcuExpression(path, options, print);
|
||||||
|
case "angularIcuCase":
|
||||||
|
return printAngularIcuCase(path, options, print);
|
||||||
|
|
||||||
case "ieConditionalStartComment":
|
case "ieConditionalStartComment":
|
||||||
case "ieConditionalEndComment":
|
case "ieConditionalEndComment":
|
||||||
return [printOpeningTagStart(node), printClosingTagEnd(node)];
|
return [printOpeningTagStart(node), printClosingTagEnd(node)];
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ const visitorKeys = {
|
|||||||
angularControlFlowBlock: ["children", "parameters"],
|
angularControlFlowBlock: ["children", "parameters"],
|
||||||
angularControlFlowBlockParameters: ["children"],
|
angularControlFlowBlockParameters: ["children"],
|
||||||
angularControlFlowBlockParameter: [],
|
angularControlFlowBlockParameter: [],
|
||||||
|
angularIcuExpression: ["cases"],
|
||||||
|
angularIcuCase: ["expression"],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default visitorKeys;
|
export default visitorKeys;
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`basic-plural-01.html format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["angular"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
<span i18n
|
||||||
|
>Updated
|
||||||
|
{minutes, plural,
|
||||||
|
=0 {just now}
|
||||||
|
=1 {one minute ago}
|
||||||
|
other {{{minutes}} minutes ago}
|
||||||
|
|
||||||
|
}</span>
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`basic-plural-02.html format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["angular"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
{ count, plural,
|
||||||
|
=0 {{ sex, select,
|
||||||
|
other {<p>deeply nested</p>}
|
||||||
|
}}
|
||||||
|
=other {a lot}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ count123, plural,
|
||||||
|
=0 {{ sex, select,
|
||||||
|
other {<p>deeply nested</p>}
|
||||||
|
}}
|
||||||
|
=other {a lot}
|
||||||
|
}
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
{count, plural, =0 {{sex, select, other {<p>deeply nested</p>}}} =other {a lot}}
|
||||||
|
|
||||||
|
{count123, plural,
|
||||||
|
=0 {{sex, select, other {<p>deeply nested</p>}}}
|
||||||
|
=other {a lot}
|
||||||
|
}
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`basic-plural-03.html format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["angular"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
<foo>
|
||||||
|
<bar>{VAR_PLURAL, plural, =0 {zero} =1 {un} =2 {deux} other {<pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="<b>" dispEnd="</b>">beaucoup</pc>} }</bar>
|
||||||
|
<baz>{VAR_PLURAL, plural, =0 {zero} =1 {one} =2 {two} other {<pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="<b>" dispEnd="</b>">many</pc>} }</baz>
|
||||||
|
</foo>
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
<foo>
|
||||||
|
<bar>{VAR_PLURAL, plural,
|
||||||
|
=0 {zero}
|
||||||
|
=1 {un}
|
||||||
|
=2 {deux}
|
||||||
|
other {
|
||||||
|
<pc
|
||||||
|
id="0"
|
||||||
|
equivStart="START_BOLD_TEXT"
|
||||||
|
equivEnd="CLOSE_BOLD_TEXT"
|
||||||
|
type="fmt"
|
||||||
|
dispStart="<b>"
|
||||||
|
dispEnd="</b>"
|
||||||
|
>beaucoup</pc
|
||||||
|
>
|
||||||
|
}
|
||||||
|
}</bar>
|
||||||
|
<baz>{VAR_PLURAL, plural,
|
||||||
|
=0 {zero}
|
||||||
|
=1 {one}
|
||||||
|
=2 {two}
|
||||||
|
other {
|
||||||
|
<pc
|
||||||
|
id="0"
|
||||||
|
equivStart="START_BOLD_TEXT"
|
||||||
|
equivEnd="CLOSE_BOLD_TEXT"
|
||||||
|
type="fmt"
|
||||||
|
dispStart="<b>"
|
||||||
|
dispEnd="</b>"
|
||||||
|
>many</pc
|
||||||
|
>
|
||||||
|
}
|
||||||
|
}</baz>
|
||||||
|
</foo>
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`basic-plural-04.html format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["angular"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
<foo>
|
||||||
|
<bar>{VAR_PLURAL, plural, =0 {Found no results} =1 {Found one result} other {Found <ph id="0" equiv="INTERPOLATION" disp="{{response.getItemsList().length}}"/> results} }</bar>
|
||||||
|
</foo>
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
<foo>
|
||||||
|
<bar>{VAR_PLURAL, plural,
|
||||||
|
=0 {Found no results}
|
||||||
|
=1 {Found one result}
|
||||||
|
other {
|
||||||
|
Found <ph
|
||||||
|
id="0"
|
||||||
|
equiv="INTERPOLATION"
|
||||||
|
disp="{{ response.getItemsList().length }}"
|
||||||
|
/> results
|
||||||
|
}
|
||||||
|
}</bar>
|
||||||
|
</foo>
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`basic-select-01.html format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["angular"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
<span i18n
|
||||||
|
>The author is {gender, select, male {male} female {female} other {other}
|
||||||
|
}</span>
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`basic-select-02.html format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["angular"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
<ng-template>{gender, select, male {male} female {female} other {other}}</ng-template>
|
||||||
|
<ng-container>{age, select, 10 {ten} 20 {twenty} other {other}}</ng-container>
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
<ng-template>{gender, select,
|
||||||
|
male {male}
|
||||||
|
female {female}
|
||||||
|
other {other}
|
||||||
|
}</ng-template>
|
||||||
|
<ng-container>{age, select, 10 {ten} 20 {twenty} other {other}}</ng-container>
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`combination-01.html format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["angular"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
<span i18n>Updated: {minutes, plural,
|
||||||
|
=0 {just now}
|
||||||
|
=1 {one minute ago}
|
||||||
|
other {{{minutes}} minutes ago by {gender, select, male {male} female {female} other {other}}}}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
<span i18n
|
||||||
|
>Updated:
|
||||||
|
{minutes, plural,
|
||||||
|
=0 {just now}
|
||||||
|
=1 {one minute ago}
|
||||||
|
other {
|
||||||
|
{{minutes}} minutes ago by {gender, select,
|
||||||
|
male {male}
|
||||||
|
female {female}
|
||||||
|
other {other}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{ count, plural,
|
||||||
|
=0 {{ sex, select,
|
||||||
|
other {<p>deeply nested</p>}
|
||||||
|
}}
|
||||||
|
=other {a lot}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ count123, plural,
|
||||||
|
=0 {{ sex, select,
|
||||||
|
other {<p>deeply nested</p>}
|
||||||
|
}}
|
||||||
|
=other {a lot}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<foo>
|
||||||
|
<bar>{VAR_PLURAL, plural, =0 {zero} =1 {un} =2 {deux} other {<pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="<b>" dispEnd="</b>">beaucoup</pc>} }</bar>
|
||||||
|
<baz>{VAR_PLURAL, plural, =0 {zero} =1 {one} =2 {two} other {<pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="<b>" dispEnd="</b>">many</pc>} }</baz>
|
||||||
|
</foo>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<foo>
|
||||||
|
<bar>{VAR_PLURAL, plural, =0 {Found no results} =1 {Found one result} other {Found <ph id="0" equiv="INTERPOLATION" disp="{{response.getItemsList().length}}"/> results} }</bar>
|
||||||
|
</foo>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<ng-template>{gender, select, male {male} female {female} other {other}}</ng-template>
|
||||||
|
<ng-container>{age, select, 10 {ten} 20 {twenty} other {other}}</ng-container>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<span i18n>Updated: {minutes, plural,
|
||||||
|
=0 {just now}
|
||||||
|
=1 {one minute ago}
|
||||||
|
other {{{minutes}} minutes ago by {gender, select, male {male} female {female} other {other}}}}
|
||||||
|
</span>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
run_spec(import.meta, ["angular"]);
|
||||||
@@ -1394,6 +1394,12 @@ exports[`visitor keys html 1`] = `
|
|||||||
"angularControlFlowBlockParameters": [
|
"angularControlFlowBlockParameters": [
|
||||||
"children",
|
"children",
|
||||||
],
|
],
|
||||||
|
"angularIcuCase": [
|
||||||
|
"expression",
|
||||||
|
],
|
||||||
|
"angularIcuExpression": [
|
||||||
|
"cases",
|
||||||
|
],
|
||||||
"attribute": [],
|
"attribute": [],
|
||||||
"cdata": [],
|
"cdata": [],
|
||||||
"comment": [],
|
"comment": [],
|
||||||
|
|||||||
@@ -2150,12 +2150,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"angular-html-parser@npm:5.0.2":
|
"angular-html-parser@npm:5.2.0":
|
||||||
version: 5.0.2
|
version: 5.2.0
|
||||||
resolution: "angular-html-parser@npm:5.0.2"
|
resolution: "angular-html-parser@npm:5.2.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: ^2.6.2
|
tslib: ^2.6.2
|
||||||
checksum: 86f8fc123e696b10878759c516d1876e4eff3d7cccf06cd22c2f572f44950e721480b44e2367802005f2638f3a84c7d7b826cd1fa0751387787f255097a5b401
|
checksum: 12253b32a064f945e4abb5b107287a9de3576b5404161374bd9a237381895de40b88a9b96e830a4a996724865f7ef298cd046869a56cd1acc714794870401e7f
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -7305,7 +7305,7 @@ __metadata:
|
|||||||
acorn: 8.11.2
|
acorn: 8.11.2
|
||||||
acorn-jsx: 5.3.2
|
acorn-jsx: 5.3.2
|
||||||
angular-estree-parser: 9.0.0
|
angular-estree-parser: 9.0.0
|
||||||
angular-html-parser: 5.0.2
|
angular-html-parser: 5.2.0
|
||||||
benchmark: 2.1.4
|
benchmark: 2.1.4
|
||||||
browserslist-to-esbuild: 1.2.0
|
browserslist-to-esbuild: 1.2.0
|
||||||
c8: 8.0.1
|
c8: 8.0.1
|
||||||
|
|||||||
Reference in new issue
Block a user