mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(ui): detect composed accessibility copy
This commit is contained in:
@@ -78,6 +78,28 @@ function pushRawCopySegments(
|
||||
}
|
||||
}
|
||||
|
||||
function collectStaticStringSegments(node: ts.Expression): string[] {
|
||||
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
|
||||
return [node.text];
|
||||
}
|
||||
if (ts.isTemplateExpression(node)) {
|
||||
return [node.head.text, ...node.templateSpans.map((span) => span.literal.text)];
|
||||
}
|
||||
if (ts.isParenthesizedExpression(node)) {
|
||||
return collectStaticStringSegments(node.expression);
|
||||
}
|
||||
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.PlusToken) {
|
||||
return [...collectStaticStringSegments(node.left), ...collectStaticStringSegments(node.right)];
|
||||
}
|
||||
if (ts.isConditionalExpression(node)) {
|
||||
return [
|
||||
...collectStaticStringSegments(node.whenTrue),
|
||||
...collectStaticStringSegments(node.whenFalse),
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
async function walkSourceFiles(dir: string): Promise<string[]> {
|
||||
const entries = await readdir(dir, { withFileTypes: true });
|
||||
const files: string[] = [];
|
||||
@@ -154,16 +176,17 @@ export function collectControlUiRawCopyFromSource(params: {
|
||||
nameArg &&
|
||||
valueArg &&
|
||||
(ts.isStringLiteral(nameArg) || ts.isNoSubstitutionTemplateLiteral(nameArg)) &&
|
||||
RAW_COPY_ATTRIBUTE_NAMES.has(nameArg.text) &&
|
||||
(ts.isStringLiteral(valueArg) || ts.isNoSubstitutionTemplateLiteral(valueArg))
|
||||
RAW_COPY_ATTRIBUTE_NAMES.has(nameArg.text)
|
||||
) {
|
||||
pushRawCopyFinding(findings, {
|
||||
kind: "html-attribute",
|
||||
line: toLine(valueArg.getStart(sourceFile)),
|
||||
name: nameArg.text,
|
||||
path: repoPath,
|
||||
text: valueArg.text,
|
||||
});
|
||||
for (const text of collectStaticStringSegments(valueArg)) {
|
||||
pushRawCopyFinding(findings, {
|
||||
kind: "html-attribute",
|
||||
line: toLine(valueArg.getStart(sourceFile)),
|
||||
name: nameArg.text,
|
||||
path: repoPath,
|
||||
text,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ts.isTaggedTemplateExpression(node) && node.tag.getText(sourceFile) === "html") {
|
||||
|
||||
@@ -214,7 +214,7 @@ describe("control-ui-i18n process runner", () => {
|
||||
|
||||
it("finds raw text and attributes split by template interpolation", () => {
|
||||
const source =
|
||||
'const jsx = <button aria-label="Archive" />; const view = html`<button title="Delete ${name}">Delete ${name}</button>`; const image = html`<img alt="Preview" />`; menu.setAttribute("aria-label", "Selection actions");';
|
||||
'const jsx = <button aria-label="Archive" />; const view = html`<button title="Delete ${name}">Delete ${name}</button>`; const image = html`<img alt="Preview" />`; menu.setAttribute("aria-label", "Selection actions"); reply.setAttribute("aria-label", `Reply to ${name}`); file.setAttribute("title", "Open " + fileName);';
|
||||
const sourceFile = ts.createSourceFile(
|
||||
"ui/src/pages/example.ts",
|
||||
source,
|
||||
@@ -235,6 +235,8 @@ describe("control-ui-i18n process runner", () => {
|
||||
{ kind: "html-attribute", text: "Delete" },
|
||||
{ kind: "html-text", text: "Delete" },
|
||||
{ kind: "html-attribute", text: "Selection actions" },
|
||||
{ kind: "html-attribute", text: "Reply to" },
|
||||
{ kind: "html-attribute", text: "Open" },
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user