feat: exclude unlisted pages from backlink sources

Respect the file.data.unlisted convention. Pages marked unlisted are no
longer shown as backlink sources on other pages. The backlinks list on an
unlisted page itself is still rendered normally -- users who reached the
page by direct URL should still see its incoming references.

Extracts the filter predicate into a named selectBacklinkSources() helper
and exports it alongside a BacklinkCandidate type so consumers and tests
can exercise the filter logic directly. Adds 3 unit tests covering
unlisted exclusion, explicit unlisted: false passthrough, and basic
source selection.
This commit is contained in:
saberzero1 2026-04-11 13:49:59 +02:00
parent e6817e968e
commit dbcda79720
No known key found for this signature in database
7 changed files with 709 additions and 47 deletions

View file

@ -9,4 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Respect the `file.data.unlisted` convention. Pages marked `unlisted` are never shown as backlink sources on other pages. The backlinks list on an unlisted page itself is still rendered normally so users who reached the page by direct URL can see its incoming references.
- Exported `selectBacklinkSources` helper and `BacklinkCandidate` type for testing and reuse.
- Unit tests for `selectBacklinkSources` covering the unlisted-filter behavior.
- Initial Quartz community plugin template.

View file

@ -1,10 +1,8 @@
import { simplifySlug as simplifySlug$1, joinSegments } from '@quartz-community/utils';
import { classNames } from '@quartz-community/utils/lang';
import { simplifySlug, resolveRelative } from '@quartz-community/utils/path';
import { jsxs, jsx } from 'preact/jsx-runtime';
// src/util/lang.ts
function classNames(...classes) {
return classes.filter(Boolean).join(" ");
}
// src/i18n/locales/en-US.ts
var en_US_default = {
@ -16,9 +14,328 @@ var en_US_default = {
}
};
// src/i18n/locales/ar-SA.ts
var ar_SA_default = {
components: {
backlinks: {
title: "\u0648\u0635\u0644\u0627\u062A \u0627\u0644\u0639\u0648\u062F\u0629",
noBacklinksFound: "\u0644\u0627 \u064A\u0648\u062C\u062F \u0648\u0635\u0644\u0627\u062A \u0639\u0648\u062F\u0629"
}
}
};
// src/i18n/locales/ca-ES.ts
var ca_ES_default = {
components: {
backlinks: {
title: "Retroenlla\xE7",
noBacklinksFound: "No s'han trobat retroenlla\xE7os"
}
}
};
// src/i18n/locales/cs-CZ.ts
var cs_CZ_default = {
components: {
backlinks: {
title: "P\u0159\xEDchoz\xED odkazy",
noBacklinksFound: "Nenalezeny \u017E\xE1dn\xE9 p\u0159\xEDchoz\xED odkazy"
}
}
};
// src/i18n/locales/de-DE.ts
var de_DE_default = {
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "Keine Backlinks gefunden"
}
}
};
// src/i18n/locales/en-GB.ts
var en_GB_default = {
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "No backlinks found"
}
}
};
// src/i18n/locales/es-ES.ts
var es_ES_default = {
components: {
backlinks: {
title: "Retroenlaces",
noBacklinksFound: "No se han encontrado retroenlaces"
}
}
};
// src/i18n/locales/fa-IR.ts
var fa_IR_default = {
components: {
backlinks: {
title: "\u0628\u06A9\u200C\u0644\u06CC\u0646\u06A9\u200C\u0647\u0627",
noBacklinksFound: "\u0628\u062F\u0648\u0646 \u0628\u06A9\u200C\u0644\u06CC\u0646\u06A9"
}
}
};
// src/i18n/locales/fi-FI.ts
var fi_FI_default = {
components: {
backlinks: {
title: "Takalinkit",
noBacklinksFound: "Takalinkkej\xE4 ei l\xF6ytynyt"
}
}
};
// src/i18n/locales/fr-FR.ts
var fr_FR_default = {
components: {
backlinks: {
title: "Liens retour",
noBacklinksFound: "Aucun lien retour trouv\xE9"
}
}
};
// src/i18n/locales/he-IL.ts
var he_IL_default = {
components: {
backlinks: {
title: "\u05E7\u05D9\u05E9\u05D5\u05E8\u05D9\u05DD \u05D7\u05D5\u05D6\u05E8\u05D9\u05DD",
noBacklinksFound: "\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05E7\u05D9\u05E9\u05D5\u05E8\u05D9\u05DD \u05D7\u05D5\u05D6\u05E8\u05D9\u05DD"
}
}
};
// src/i18n/locales/hu-HU.ts
var hu_HU_default = {
components: {
backlinks: {
title: "Visszautal\xE1sok",
noBacklinksFound: "Nincs visszautal\xE1s"
}
}
};
// src/i18n/locales/id-ID.ts
var id_ID_default = {
components: {
backlinks: {
title: "Tautan Balik",
noBacklinksFound: "Tidak ada tautan balik ditemukan"
}
}
};
// src/i18n/locales/it-IT.ts
var it_IT_default = {
components: {
backlinks: {
title: "Link entranti",
noBacklinksFound: "Nessun link entrante"
}
}
};
// src/i18n/locales/ja-JP.ts
var ja_JP_default = {
components: {
backlinks: {
title: "\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF",
noBacklinksFound: "\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF\u306F\u3042\u308A\u307E\u305B\u3093"
}
}
};
// src/i18n/locales/kk-KZ.ts
var kk_KZ_default = {
components: {
backlinks: {
title: "\u0410\u0440\u0442\u049B\u0430 \u0441\u0456\u043B\u0442\u0435\u043C\u0435\u043B\u0435\u0440",
noBacklinksFound: "\u0410\u0440\u0442\u049B\u0430 \u0441\u0456\u043B\u0442\u0435\u043C\u0435\u043B\u0435\u0440 \u0442\u0430\u0431\u044B\u043B\u043C\u0430\u0434\u044B"
}
}
};
// src/i18n/locales/ko-KR.ts
var ko_KR_default = {
components: {
backlinks: {
title: "\uBC31\uB9C1\uD06C",
noBacklinksFound: "\uBC31\uB9C1\uD06C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
}
}
};
// src/i18n/locales/lt-LT.ts
var lt_LT_default = {
components: {
backlinks: {
title: "Atgalin\u0117s Nuorodos",
noBacklinksFound: "Atgalini\u0173 Nuorod\u0173 Nerasta"
}
}
};
// src/i18n/locales/nb-NO.ts
var nb_NO_default = {
components: {
backlinks: {
title: "Tilbakekoblinger",
noBacklinksFound: "Ingen tilbakekoblinger funnet"
}
}
};
// src/i18n/locales/nl-NL.ts
var nl_NL_default = {
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "Geen backlinks gevonden"
}
}
};
// src/i18n/locales/pl-PL.ts
var pl_PL_default = {
components: {
backlinks: {
title: "Odno\u015Bniki zwrotne",
noBacklinksFound: "Brak po\u0142\u0105cze\u0144 zwrotnych"
}
}
};
// src/i18n/locales/pt-BR.ts
var pt_BR_default = {
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "Sem backlinks encontrados"
}
}
};
// src/i18n/locales/ro-RO.ts
var ro_RO_default = {
components: {
backlinks: {
title: "Leg\u0103turi \xEEnapoi",
noBacklinksFound: "Nu s-au g\u0103sit leg\u0103turi \xEEnapoi"
}
}
};
// src/i18n/locales/ru-RU.ts
var ru_RU_default = {
components: {
backlinks: {
title: "\u041E\u0431\u0440\u0430\u0442\u043D\u044B\u0435 \u0441\u0441\u044B\u043B\u043A\u0438",
noBacklinksFound: "\u041E\u0431\u0440\u0430\u0442\u043D\u044B\u0435 \u0441\u0441\u044B\u043B\u043A\u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442"
}
}
};
// src/i18n/locales/th-TH.ts
var th_TH_default = {
components: {
backlinks: {
title: "\u0E2B\u0E19\u0E49\u0E32\u0E17\u0E35\u0E48\u0E01\u0E25\u0E48\u0E32\u0E27\u0E16\u0E36\u0E07",
noBacklinksFound: "\u0E44\u0E21\u0E48\u0E21\u0E35\u0E2B\u0E19\u0E49\u0E32\u0E17\u0E35\u0E48\u0E42\u0E22\u0E07\u0E21\u0E32\u0E2B\u0E19\u0E49\u0E32\u0E19\u0E35\u0E49"
}
}
};
// src/i18n/locales/tr-TR.ts
var tr_TR_default = {
components: {
backlinks: {
title: "Backlinkler",
noBacklinksFound: "Backlink bulunamad\u0131"
}
}
};
// src/i18n/locales/uk-UA.ts
var uk_UA_default = {
components: {
backlinks: {
title: "\u0417\u0432\u043E\u0440\u043E\u0442\u043D\u0456 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
noBacklinksFound: "\u0417\u0432\u043E\u0440\u043E\u0442\u043D\u0438\u0445 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u044C \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E"
}
}
};
// src/i18n/locales/vi-VN.ts
var vi_VN_default = {
components: {
backlinks: {
title: "Li\xEAn k\u1EBFt ng\u01B0\u1EE3c",
noBacklinksFound: "Kh\xF4ng c\xF3 li\xEAn k\u1EBFt ng\u01B0\u1EE3c n\xE0o"
}
}
};
// src/i18n/locales/zh-CN.ts
var zh_CN_default = {
components: {
backlinks: {
title: "\u53CD\u5411\u94FE\u63A5",
noBacklinksFound: "\u65E0\u6CD5\u627E\u5230\u53CD\u5411\u94FE\u63A5"
}
}
};
// src/i18n/locales/zh-TW.ts
var zh_TW_default = {
components: {
backlinks: {
title: "\u53CD\u5411\u9023\u7D50",
noBacklinksFound: "\u7121\u6CD5\u627E\u5230\u53CD\u5411\u9023\u7D50"
}
}
};
// src/i18n/index.ts
var locales = {
"en-US": en_US_default
"en-US": en_US_default,
"ar-SA": ar_SA_default,
"ca-ES": ca_ES_default,
"cs-CZ": cs_CZ_default,
"de-DE": de_DE_default,
"en-GB": en_GB_default,
"es-ES": es_ES_default,
"fa-IR": fa_IR_default,
"fi-FI": fi_FI_default,
"fr-FR": fr_FR_default,
"he-IL": he_IL_default,
"hu-HU": hu_HU_default,
"id-ID": id_ID_default,
"it-IT": it_IT_default,
"ja-JP": ja_JP_default,
"kk-KZ": kk_KZ_default,
"ko-KR": ko_KR_default,
"lt-LT": lt_LT_default,
"nb-NO": nb_NO_default,
"nl-NL": nl_NL_default,
"pl-PL": pl_PL_default,
"pt-BR": pt_BR_default,
"ro-RO": ro_RO_default,
"ru-RU": ru_RU_default,
"th-TH": th_TH_default,
"tr-TR": tr_TR_default,
"uk-UA": uk_UA_default,
"vi-VN": vi_VN_default,
"zh-CN": zh_CN_default,
"zh-TW": zh_TW_default
};
function i18n(locale) {
return locales[locale] || en_US_default;
@ -26,21 +343,6 @@ function i18n(locale) {
// src/components/styles/backlinks.scss
var backlinks_default = ".backlinks {\n flex-direction: column;\n}\n.backlinks > h3 {\n font-size: 1rem;\n margin: 0;\n}\n.backlinks > ul.overflow {\n list-style: none;\n padding: 0;\n margin: 0.5rem 0;\n max-height: calc(100% - 2rem);\n overscroll-behavior: contain;\n}\n.backlinks > ul.overflow > li > a {\n background-color: transparent;\n}";
function simplifySlug(fp) {
return simplifySlug$1(fp);
}
function resolveRelative(current, target) {
const simplified = simplifySlug(target);
const rootPath = pathToRoot(current);
return joinSegments(rootPath, simplified);
}
function pathToRoot(slug) {
let rootPath = slug.split("/").filter((x) => x !== "").slice(0, -1).map((_) => "..").join("/");
if (rootPath.length === 0) {
rootPath = ".";
}
return rootPath;
}
var OverflowList = ({
children,
...props
@ -83,6 +385,9 @@ document.addEventListener("nav", (e) => {
var defaultOptions = {
hideWhenEmpty: true
};
function selectBacklinkSources(allFiles, currentSlug) {
return allFiles.filter((file) => file.unlisted !== true && file.links?.includes(currentSlug));
}
var Backlinks_default = ((opts) => {
const options = { ...defaultOptions, ...opts };
const { OverflowList: OverflowList2, overflowListAfterDOMLoaded } = OverflowList_default();
@ -94,7 +399,7 @@ var Backlinks_default = ((opts) => {
}) => {
const slug = simplifySlug(fileData.slug);
const locale = cfg.locale ?? "en-US";
const backlinkFiles = allFiles.filter((file) => file.links?.includes(slug));
const backlinkFiles = selectBacklinkSources(allFiles, slug);
if (options.hideWhenEmpty && backlinkFiles.length === 0) {
return null;
}

File diff suppressed because one or more lines are too long

347
dist/index.js vendored
View file

@ -1,10 +1,8 @@
import { simplifySlug as simplifySlug$1, joinSegments } from '@quartz-community/utils';
import { classNames } from '@quartz-community/utils/lang';
import { simplifySlug, resolveRelative } from '@quartz-community/utils/path';
import { jsxs, jsx } from 'preact/jsx-runtime';
// src/util/lang.ts
function classNames(...classes) {
return classes.filter(Boolean).join(" ");
}
// src/i18n/locales/en-US.ts
var en_US_default = {
@ -16,9 +14,328 @@ var en_US_default = {
}
};
// src/i18n/locales/ar-SA.ts
var ar_SA_default = {
components: {
backlinks: {
title: "\u0648\u0635\u0644\u0627\u062A \u0627\u0644\u0639\u0648\u062F\u0629",
noBacklinksFound: "\u0644\u0627 \u064A\u0648\u062C\u062F \u0648\u0635\u0644\u0627\u062A \u0639\u0648\u062F\u0629"
}
}
};
// src/i18n/locales/ca-ES.ts
var ca_ES_default = {
components: {
backlinks: {
title: "Retroenlla\xE7",
noBacklinksFound: "No s'han trobat retroenlla\xE7os"
}
}
};
// src/i18n/locales/cs-CZ.ts
var cs_CZ_default = {
components: {
backlinks: {
title: "P\u0159\xEDchoz\xED odkazy",
noBacklinksFound: "Nenalezeny \u017E\xE1dn\xE9 p\u0159\xEDchoz\xED odkazy"
}
}
};
// src/i18n/locales/de-DE.ts
var de_DE_default = {
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "Keine Backlinks gefunden"
}
}
};
// src/i18n/locales/en-GB.ts
var en_GB_default = {
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "No backlinks found"
}
}
};
// src/i18n/locales/es-ES.ts
var es_ES_default = {
components: {
backlinks: {
title: "Retroenlaces",
noBacklinksFound: "No se han encontrado retroenlaces"
}
}
};
// src/i18n/locales/fa-IR.ts
var fa_IR_default = {
components: {
backlinks: {
title: "\u0628\u06A9\u200C\u0644\u06CC\u0646\u06A9\u200C\u0647\u0627",
noBacklinksFound: "\u0628\u062F\u0648\u0646 \u0628\u06A9\u200C\u0644\u06CC\u0646\u06A9"
}
}
};
// src/i18n/locales/fi-FI.ts
var fi_FI_default = {
components: {
backlinks: {
title: "Takalinkit",
noBacklinksFound: "Takalinkkej\xE4 ei l\xF6ytynyt"
}
}
};
// src/i18n/locales/fr-FR.ts
var fr_FR_default = {
components: {
backlinks: {
title: "Liens retour",
noBacklinksFound: "Aucun lien retour trouv\xE9"
}
}
};
// src/i18n/locales/he-IL.ts
var he_IL_default = {
components: {
backlinks: {
title: "\u05E7\u05D9\u05E9\u05D5\u05E8\u05D9\u05DD \u05D7\u05D5\u05D6\u05E8\u05D9\u05DD",
noBacklinksFound: "\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05E7\u05D9\u05E9\u05D5\u05E8\u05D9\u05DD \u05D7\u05D5\u05D6\u05E8\u05D9\u05DD"
}
}
};
// src/i18n/locales/hu-HU.ts
var hu_HU_default = {
components: {
backlinks: {
title: "Visszautal\xE1sok",
noBacklinksFound: "Nincs visszautal\xE1s"
}
}
};
// src/i18n/locales/id-ID.ts
var id_ID_default = {
components: {
backlinks: {
title: "Tautan Balik",
noBacklinksFound: "Tidak ada tautan balik ditemukan"
}
}
};
// src/i18n/locales/it-IT.ts
var it_IT_default = {
components: {
backlinks: {
title: "Link entranti",
noBacklinksFound: "Nessun link entrante"
}
}
};
// src/i18n/locales/ja-JP.ts
var ja_JP_default = {
components: {
backlinks: {
title: "\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF",
noBacklinksFound: "\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF\u306F\u3042\u308A\u307E\u305B\u3093"
}
}
};
// src/i18n/locales/kk-KZ.ts
var kk_KZ_default = {
components: {
backlinks: {
title: "\u0410\u0440\u0442\u049B\u0430 \u0441\u0456\u043B\u0442\u0435\u043C\u0435\u043B\u0435\u0440",
noBacklinksFound: "\u0410\u0440\u0442\u049B\u0430 \u0441\u0456\u043B\u0442\u0435\u043C\u0435\u043B\u0435\u0440 \u0442\u0430\u0431\u044B\u043B\u043C\u0430\u0434\u044B"
}
}
};
// src/i18n/locales/ko-KR.ts
var ko_KR_default = {
components: {
backlinks: {
title: "\uBC31\uB9C1\uD06C",
noBacklinksFound: "\uBC31\uB9C1\uD06C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
}
}
};
// src/i18n/locales/lt-LT.ts
var lt_LT_default = {
components: {
backlinks: {
title: "Atgalin\u0117s Nuorodos",
noBacklinksFound: "Atgalini\u0173 Nuorod\u0173 Nerasta"
}
}
};
// src/i18n/locales/nb-NO.ts
var nb_NO_default = {
components: {
backlinks: {
title: "Tilbakekoblinger",
noBacklinksFound: "Ingen tilbakekoblinger funnet"
}
}
};
// src/i18n/locales/nl-NL.ts
var nl_NL_default = {
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "Geen backlinks gevonden"
}
}
};
// src/i18n/locales/pl-PL.ts
var pl_PL_default = {
components: {
backlinks: {
title: "Odno\u015Bniki zwrotne",
noBacklinksFound: "Brak po\u0142\u0105cze\u0144 zwrotnych"
}
}
};
// src/i18n/locales/pt-BR.ts
var pt_BR_default = {
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "Sem backlinks encontrados"
}
}
};
// src/i18n/locales/ro-RO.ts
var ro_RO_default = {
components: {
backlinks: {
title: "Leg\u0103turi \xEEnapoi",
noBacklinksFound: "Nu s-au g\u0103sit leg\u0103turi \xEEnapoi"
}
}
};
// src/i18n/locales/ru-RU.ts
var ru_RU_default = {
components: {
backlinks: {
title: "\u041E\u0431\u0440\u0430\u0442\u043D\u044B\u0435 \u0441\u0441\u044B\u043B\u043A\u0438",
noBacklinksFound: "\u041E\u0431\u0440\u0430\u0442\u043D\u044B\u0435 \u0441\u0441\u044B\u043B\u043A\u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442"
}
}
};
// src/i18n/locales/th-TH.ts
var th_TH_default = {
components: {
backlinks: {
title: "\u0E2B\u0E19\u0E49\u0E32\u0E17\u0E35\u0E48\u0E01\u0E25\u0E48\u0E32\u0E27\u0E16\u0E36\u0E07",
noBacklinksFound: "\u0E44\u0E21\u0E48\u0E21\u0E35\u0E2B\u0E19\u0E49\u0E32\u0E17\u0E35\u0E48\u0E42\u0E22\u0E07\u0E21\u0E32\u0E2B\u0E19\u0E49\u0E32\u0E19\u0E35\u0E49"
}
}
};
// src/i18n/locales/tr-TR.ts
var tr_TR_default = {
components: {
backlinks: {
title: "Backlinkler",
noBacklinksFound: "Backlink bulunamad\u0131"
}
}
};
// src/i18n/locales/uk-UA.ts
var uk_UA_default = {
components: {
backlinks: {
title: "\u0417\u0432\u043E\u0440\u043E\u0442\u043D\u0456 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
noBacklinksFound: "\u0417\u0432\u043E\u0440\u043E\u0442\u043D\u0438\u0445 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u044C \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E"
}
}
};
// src/i18n/locales/vi-VN.ts
var vi_VN_default = {
components: {
backlinks: {
title: "Li\xEAn k\u1EBFt ng\u01B0\u1EE3c",
noBacklinksFound: "Kh\xF4ng c\xF3 li\xEAn k\u1EBFt ng\u01B0\u1EE3c n\xE0o"
}
}
};
// src/i18n/locales/zh-CN.ts
var zh_CN_default = {
components: {
backlinks: {
title: "\u53CD\u5411\u94FE\u63A5",
noBacklinksFound: "\u65E0\u6CD5\u627E\u5230\u53CD\u5411\u94FE\u63A5"
}
}
};
// src/i18n/locales/zh-TW.ts
var zh_TW_default = {
components: {
backlinks: {
title: "\u53CD\u5411\u9023\u7D50",
noBacklinksFound: "\u7121\u6CD5\u627E\u5230\u53CD\u5411\u9023\u7D50"
}
}
};
// src/i18n/index.ts
var locales = {
"en-US": en_US_default
"en-US": en_US_default,
"ar-SA": ar_SA_default,
"ca-ES": ca_ES_default,
"cs-CZ": cs_CZ_default,
"de-DE": de_DE_default,
"en-GB": en_GB_default,
"es-ES": es_ES_default,
"fa-IR": fa_IR_default,
"fi-FI": fi_FI_default,
"fr-FR": fr_FR_default,
"he-IL": he_IL_default,
"hu-HU": hu_HU_default,
"id-ID": id_ID_default,
"it-IT": it_IT_default,
"ja-JP": ja_JP_default,
"kk-KZ": kk_KZ_default,
"ko-KR": ko_KR_default,
"lt-LT": lt_LT_default,
"nb-NO": nb_NO_default,
"nl-NL": nl_NL_default,
"pl-PL": pl_PL_default,
"pt-BR": pt_BR_default,
"ro-RO": ro_RO_default,
"ru-RU": ru_RU_default,
"th-TH": th_TH_default,
"tr-TR": tr_TR_default,
"uk-UA": uk_UA_default,
"vi-VN": vi_VN_default,
"zh-CN": zh_CN_default,
"zh-TW": zh_TW_default
};
function i18n(locale) {
return locales[locale] || en_US_default;
@ -26,21 +343,6 @@ function i18n(locale) {
// src/components/styles/backlinks.scss
var backlinks_default = ".backlinks {\n flex-direction: column;\n}\n.backlinks > h3 {\n font-size: 1rem;\n margin: 0;\n}\n.backlinks > ul.overflow {\n list-style: none;\n padding: 0;\n margin: 0.5rem 0;\n max-height: calc(100% - 2rem);\n overscroll-behavior: contain;\n}\n.backlinks > ul.overflow > li > a {\n background-color: transparent;\n}";
function simplifySlug(fp) {
return simplifySlug$1(fp);
}
function resolveRelative(current, target) {
const simplified = simplifySlug(target);
const rootPath = pathToRoot(current);
return joinSegments(rootPath, simplified);
}
function pathToRoot(slug) {
let rootPath = slug.split("/").filter((x) => x !== "").slice(0, -1).map((_) => "..").join("/");
if (rootPath.length === 0) {
rootPath = ".";
}
return rootPath;
}
var OverflowList = ({
children,
...props
@ -83,6 +385,9 @@ document.addEventListener("nav", (e) => {
var defaultOptions = {
hideWhenEmpty: true
};
function selectBacklinkSources(allFiles, currentSlug) {
return allFiles.filter((file) => file.unlisted !== true && file.links?.includes(currentSlug));
}
var Backlinks_default = ((opts) => {
const options = { ...defaultOptions, ...opts };
const { OverflowList: OverflowList2, overflowListAfterDOMLoaded } = OverflowList_default();
@ -94,7 +399,7 @@ var Backlinks_default = ((opts) => {
}) => {
const slug = simplifySlug(fileData.slug);
const locale = cfg.locale ?? "en-US";
const backlinkFiles = allFiles.filter((file) => file.links?.includes(slug));
const backlinkFiles = selectBacklinkSources(allFiles, slug);
if (options.hideWhenEmpty && backlinkFiles.length === 0) {
return null;
}

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View file

@ -17,6 +17,20 @@ const defaultOptions: BacklinksOptions = {
hideWhenEmpty: true,
};
export interface BacklinkCandidate {
unlisted?: boolean;
links?: string[];
slug?: string;
frontmatter?: { title?: string };
}
export function selectBacklinkSources<T extends BacklinkCandidate>(
allFiles: T[],
currentSlug: string,
): T[] {
return allFiles.filter((file) => file.unlisted !== true && file.links?.includes(currentSlug));
}
export default ((opts?: Partial<BacklinksOptions>) => {
const options: BacklinksOptions = { ...defaultOptions, ...opts };
const { OverflowList, overflowListAfterDOMLoaded } = OverflowListFactory();
@ -29,9 +43,7 @@ export default ((opts?: Partial<BacklinksOptions>) => {
}: QuartzComponentProps & { displayClass?: string }) => {
const slug = simplifySlug(fileData.slug as string);
const locale = cfg.locale ?? "en-US";
const backlinkFiles = (
allFiles as Array<{ links?: string[]; slug?: string; frontmatter?: { title?: string } }>
).filter((file) => file.links?.includes(slug));
const backlinkFiles = selectBacklinkSources(allFiles as BacklinkCandidate[], slug);
if (options.hideWhenEmpty && backlinkFiles.length === 0) {
return null;
}

View file

@ -1,5 +1,7 @@
import { describe, it, expect } from "vitest";
import { simplifySlug, resolveRelative } from "../src/util/path";
import { selectBacklinkSources } from "../src/components/Backlinks";
import type { BacklinkCandidate } from "../src/components/Backlinks";
describe("path utilities", () => {
it("simplifySlug removes index suffix", () => {
@ -17,3 +19,37 @@ describe("path utilities", () => {
expect(result).toContain("..");
});
});
describe("selectBacklinkSources", () => {
const pages: BacklinkCandidate[] = [
{ slug: "a", links: ["target"], frontmatter: { title: "A" } },
{ slug: "b", links: ["other"], frontmatter: { title: "B" } },
{ slug: "c", links: ["target"], frontmatter: { title: "C" }, unlisted: true },
{ slug: "d", links: ["target"], frontmatter: { title: "D" } },
{ slug: "e", frontmatter: { title: "E no links" } },
];
it("returns only pages whose links include the current slug", () => {
const result = selectBacklinkSources(pages, "target");
const slugs = result.map((f) => f.slug);
expect(slugs).toContain("a");
expect(slugs).toContain("d");
expect(slugs).not.toContain("b");
expect(slugs).not.toContain("e");
});
it("excludes unlisted pages from backlink sources", () => {
const result = selectBacklinkSources(pages, "target");
const slugs = result.map((f) => f.slug);
expect(slugs).not.toContain("c");
});
it("treats explicit unlisted: false the same as undefined", () => {
const inputs: BacklinkCandidate[] = [
{ slug: "listed", links: ["target"], unlisted: false },
{ slug: "unlisted", links: ["target"], unlisted: true },
];
const result = selectBacklinkSources(inputs, "target");
expect(result.map((f) => f.slug)).toEqual(["listed"]);
});
});