diff --git a/src/core/best-practices.js b/src/core/best-practices.js index ea48d5f2d1..557b8154ea 100644 --- a/src/core/best-practices.js +++ b/src/core/best-practices.js @@ -12,6 +12,7 @@ export const name = "core/best-practices"; const localizationStrings = { en: { best_practice: "Best Practice ", + best_practice_summary: "Best Practices Summary", }, ja: { best_practice: "最良実施例 ", @@ -22,6 +23,10 @@ const localizationStrings = { zh: { best_practice: "最佳实践 ", }, + fr: { + best_practice: "Bonne pratique ", + best_practice_summary: "Résumé des bonnes pratiques", + }, }; const l10n = getIntlData(localizationStrings); const lang = defaultLang in localizationStrings ? defaultLang : "en"; @@ -33,8 +38,13 @@ export function run() { const summaryItems = bpSummary ? document.createElement("ul") : null; [...bps].forEach((bp, num) => { const id = addId(bp, "bp"); + const customLabel = bp.dataset.label; + const rawLabel = customLabel || l10n.best_practice; + const label = `${rawLabel.trimEnd()} `; + const bdi = html`${label}${num + 1}`; + if (!customLabel) bdi.lang = lang; const localizedBpName = html`${l10n.best_practice}${num + 1}${bdi}`; // Make the summary items, if we have a summary @@ -57,7 +67,9 @@ export function run() { }); if (bps.length) { if (bpSummary) { - bpSummary.appendChild(html`

Best Practices Summary

`); + const summaryLabel = + bpSummary.dataset.label || l10n.best_practice_summary; + bpSummary.appendChild(html`

${summaryLabel}

`); if (summaryItems) bpSummary.appendChild(summaryItems); } } else if (bpSummary) { diff --git a/tests/spec/core/best-practices-spec.js b/tests/spec/core/best-practices-spec.js index 6d4a1fdd77..6dc31781e7 100644 --- a/tests/spec/core/best-practices-spec.js +++ b/tests/spec/core/best-practices-spec.js @@ -81,4 +81,79 @@ describe("Core — Best Practices", () => { ); expect(bps.querySelectorAll("ul li")).toHaveSize(3); }); + + it("uses custom labels from data-label attribute", async () => { + const body = ` +
+

Section

+ P1 +
+

P2

+
+
+
+
+ `; + const ops = { + config: makeBasicConfig(), + body, + }; + const doc = await makeRSDoc(ops); + const summary = doc.getElementById("bp-summary"); + expect(summary).toBeTruthy(); + const listItems = summary.querySelectorAll("li"); + expect(listItems[0].textContent.trim()).toBe("Principle 1: P1"); + expect(listItems[1].textContent.trim()).toBe("Principle 2: P2"); + const heading = summary.querySelector("h3"); + expect(heading.textContent).toContain("Principles Summary"); + + // Boxed practice: verify custom label appears in the visible marker + const selfLink = doc.querySelector(".advisement .self-link"); + expect(selfLink.textContent).toBe("Principle 2"); + + // Custom labels must not carry the built-in locale's lang attribute + const bdi = selfLink.querySelector("bdi"); + expect(bdi.hasAttribute("lang")).toBeFalse(); + }); + + it("sets lang attribute on bdi only for built-in localized labels", async () => { + const body = ` +
+

Section

+
+

BP1

+
+
+ `; + const ops = { + config: makeBasicConfig(), + body, + }; + const doc = await makeRSDoc(ops); + const bdi = doc.querySelector(".advisement .self-link bdi"); + expect(bdi.hasAttribute("lang")).toBeTrue(); + }); + + it("uses custom labels in boxed best practice containers", async () => { + const body = ` +
+

Section

+
+ Boxed P1 +

Details here.

+
+
+ `; + const ops = { + config: makeBasicConfig(), + body, + }; + const doc = await makeRSDoc(ops); + const container = doc.querySelector(".advisement"); + expect(container).toBeTruthy(); + const marker = container.querySelector(".marker"); + expect(marker.textContent).toContain("Principle 1"); + const bdi = marker.querySelector("bdi"); + expect(bdi.hasAttribute("lang")).toBeFalse(); + }); });