diff --git a/src/components/CommitDiff.ts b/src/components/CommitDiff.ts index a1bcd27..40b2bab 100644 --- a/src/components/CommitDiff.ts +++ b/src/components/CommitDiff.ts @@ -1,13 +1,22 @@ export const CommitDiff = createDiffComponent({ getAdditionsElement: () => - document.querySelector("#toc>*>strong:nth-child(2)"), + querySelectorFirst( + // 2023 + "#toc>*>strong:nth-child(2)", + // 2025-10-24 + "#diff-content-parent .fgColor-success", + ), getDeletionsElement: () => - document.querySelector("#toc>*>strong:nth-child(3)"), + querySelectorFirst( + // 2023 + "#toc>*>strong:nth-child(3)", + // 2025-10-24 + "#diff-content-parent .fgColor-danger", + ), addSpinnerToPage(spinner) { - const container = this.getDeletionsElement()?.parentElement; - container?.appendChild(spinner); + this.getDeletionsElement()?.after(spinner); }, getAdditionsText: (count) => i18n.t("diffs.additionsText", count), getDeletionsText: (count) => i18n.t("diffs.deletionsText", count), - getGeneratedText: (count) => i18n.t("diffs.generatedText", count), + getGeneratedText: (count) => i18n.t("diffs.generatedText", [count]), }); diff --git a/src/components/CompareDiff.ts b/src/components/CompareDiff.ts index 9d52728..7b7dc49 100644 --- a/src/components/CompareDiff.ts +++ b/src/components/CompareDiff.ts @@ -1,13 +1,21 @@ export const CompareDiff = createDiffComponent({ getAdditionsElement: () => - document.querySelectorAll(".toc-diff-stats>strong")[0], + querySelectorFirst( + // 2023 + [".toc-diff-stats>strong", 0], + // 2025-10-24 + ), getDeletionsElement: () => - document.querySelectorAll(".toc-diff-stats>strong")[1], + querySelectorFirst( + // 2023 + [".toc-diff-stats>strong", 1], + // 2025-10-24 + ), addSpinnerToPage(spinner) { const container = this.getDeletionsElement()?.parentElement; container?.appendChild(spinner); }, getAdditionsText: (count) => i18n.t("diffs.additionsText", count), getDeletionsText: (count) => i18n.t("diffs.deletionsText", count), - getGeneratedText: (count) => i18n.t("diffs.generatedText", count), + getGeneratedText: (count) => i18n.t("diffs.generatedText", [count]), }); diff --git a/src/components/PrDiff.ts b/src/components/PrDiff.ts index 1a16930..5efcc9f 100644 --- a/src/components/PrDiff.ts +++ b/src/components/PrDiff.ts @@ -1,8 +1,18 @@ export const PrDiff = createDiffComponent({ getAdditionsElement: () => - document.querySelector("#diffstat .color-fg-success"), + querySelectorFirst( + // 2023 + "#diffstat .color-fg-success", + // 2025-10-24 + "*[data-component=PH_Navigation] .f6.text-bold.fgColor-success", + ), getDeletionsElement: () => - document.querySelector("#diffstat .color-fg-danger"), + querySelectorFirst( + // 2023 + "#diffstat .color-fg-danger", + // 2025-10-24 + "*[data-component=PH_Navigation] .f6.text-bold.fgColor-danger", + ), addSpinnerToPage(spinner) { const deletions = this.getDeletionsElement(); deletions?.replaceWith(deletions, spinner); diff --git a/src/components/createDiffComponent.ts b/src/components/createDiffComponent.ts index 4fcf80f..fd89d4f 100644 --- a/src/components/createDiffComponent.ts +++ b/src/components/createDiffComponent.ts @@ -47,6 +47,12 @@ export function createDiffComponent(options: { generated.textContent = " " + options.getGeneratedText(stats.exclude.changes); generated.style.color = GREY_COLOR; + console.log(additions?.classList); + generated.classList.add( + ...[...(additions?.classList ?? [])].filter( + (className) => !className.toLowerCase().includes("fg"), + ), + ); const generatedAdditionsText = i18n.t("diffs.additionsSymbol", [ stats.exclude.additions, ]); diff --git a/src/entrypoints/content.ts b/src/entrypoints/content.ts index 06d4d7b..304ea1e 100644 --- a/src/entrypoints/content.ts +++ b/src/entrypoints/content.ts @@ -1,12 +1,17 @@ +const mountId = Math.random(); + export default defineContentScript({ matches: ["*://*.github.com/*"], runAt: "document_end", - main() { + main(ctx) { main(); // TODO: schedule next interval for 1 second AFTER the main function finishes. If the main // function takes more than 1 second, it might cause problems. - setInterval(main, SECOND); + const loop = ctx.setInterval(main, SECOND); + ctx.setTimeout(() => { + clearInterval(loop); + }, 10 * SECOND); }, }); @@ -16,19 +21,19 @@ function main() { if (!repo || !owner) return; const pr = getCurrentPr(); - if (pr) return replaceCount({ type: "pr", repo, owner, pr }, PrDiff); + if (pr) return replaceCount({ mountId, type: "pr", repo, owner, pr }, PrDiff); const commitHash = getCurrentRef(); if (commitHash) return replaceCount( - { type: "commit", repo, owner, ref: commitHash }, + { mountId, type: "commit", repo, owner, ref: commitHash }, CommitDiff, ); const commitRefs = getCurrentCompare(); if (commitRefs) return replaceCount( - { type: "compare", repo, owner, commitRefs }, + { mountId, type: "compare", repo, owner, commitRefs }, CompareDiff, ); } diff --git a/src/locales/en.yml b/src/locales/en.yml index ede6904..4fc37c2 100644 --- a/src/locales/en.yml +++ b/src/locales/en.yml @@ -9,9 +9,7 @@ diffs: deletionsText: 1: $1 deletion n: $1 deletions - generatedText: - 1: $1 generated line. - n: $1 generated lines. + generatedText: $1 generated additionsSymbol: +$1 deletionsSymbol: −$1 generatedSymbol: ⌁$1 diff --git a/src/utils/constants.ts b/src/utils/constants.ts index b3e75f6..dcf9a5b 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -2,5 +2,5 @@ export const DEFAULT_CUSTOM_LIST_ALL = `*.lock *.lock.* *-lock*`; -export const GREY_COLOR = "var(--color-fg-muted)"; +export const GREY_COLOR = "var(--color-fg-muted, var(--fgColor-muted))"; export const DIFF_COMPONENT_ID = "github-better-line-counts"; diff --git a/src/utils/github/service.ts b/src/utils/github/service.ts index 7a82172..d92286b 100644 --- a/src/utils/github/service.ts +++ b/src/utils/github/service.ts @@ -10,6 +10,8 @@ export const [registerGithubService, getGithubService] = defineProxyService( ); function createGithubService(api: GithubApi) { + const mountCache: { [mountId: number]: RecalculateResult } = {}; + /** * Returns a list of generated files that should be excluded from diff counts. * @@ -122,11 +124,18 @@ function createGithubService(api: GithubApi) { async recalculateDiff( options: RecalculateOptions, ): Promise { + // Cache the result if the same content script tries to get the result multiple times. + if (mountCache[options.mountId]) { + logger.debug("[recalculateDiff] Using mount cache"); + return mountCache[options.mountId]; + } + const ref = await getCurrentCommit(options); const cacheKey = getCacheKey(ref, options); const cached = await commitHashDiffsCache.get(cacheKey); if (cached) { logger.debug("[recalculateDiff] Using cached result"); + mountCache[options.mountId] = cached; return cached; } @@ -172,6 +181,8 @@ function createGithubService(api: GithubApi) { include: calculateDiffForFiles(include), }; await commitHashDiffsCache.set(cacheKey, result, 2 * HOUR); + + mountCache[options.mountId] = result; return result; }, @@ -187,6 +198,7 @@ export type RecalculateOptions = | RecalculateCompareOptions; export interface RecalculatePrOptions { + mountId: number; type: "pr"; owner: string; repo: string; @@ -194,6 +206,7 @@ export interface RecalculatePrOptions { } export interface RecalculateCommitOptions { + mountId: number; type: "commit"; owner: string; repo: string; @@ -201,6 +214,7 @@ export interface RecalculateCommitOptions { } export interface RecalculateCompareOptions { + mountId: number; type: "compare"; owner: string; repo: string; diff --git a/src/utils/querySelectorFirst.ts b/src/utils/querySelectorFirst.ts new file mode 100644 index 0000000..04ea7df --- /dev/null +++ b/src/utils/querySelectorFirst.ts @@ -0,0 +1,10 @@ +export function querySelectorFirst( + ...selectors: Array +): HTMLElement | undefined { + for (const selector of selectors) { + const element = Array.isArray(selector) + ? document.querySelectorAll(selector[0])[selector[1]] + : document.querySelector(selector); + if (element) return element; + } +}