diff --git a/go.mod b/go.mod index e957de1..5e2fc8d 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/kelseyhightower/envconfig v1.4.0 github.com/mattn/go-sqlite3 v1.14.24 github.com/pocketbase/dbx v1.11.0 - github.com/pocketbase/pocketbase v0.25.3 + github.com/pocketbase/pocketbase v0.25.5 github.com/spf13/cobra v1.8.1 github.com/yalue/merged_fs v1.3.0 golang.org/x/text v0.22.0 @@ -69,5 +69,5 @@ require ( modernc.org/libc v1.61.13 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.8.2 // indirect - modernc.org/sqlite v1.34.5 // indirect + modernc.org/sqlite v1.35.0 // indirect ) diff --git a/go.sum b/go.sum index 943c873..e74c7c1 100644 --- a/go.sum +++ b/go.sum @@ -159,6 +159,8 @@ github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs= github.com/pocketbase/pocketbase v0.25.3 h1:UaSBgxNc2aX5niwGnqZxkP5QTMJdvaFAk6uOh5qFfR4= github.com/pocketbase/pocketbase v0.25.3/go.mod h1:A5sg1OTyrlJCvBMIdXU7p61iUYXtGsRqwPRK0OEMZ9I= +github.com/pocketbase/pocketbase v0.25.5 h1:xVI7pi1n4Htq4irVgkGMfL/S1ZuypXoQ1Ykpg0+I3j0= +github.com/pocketbase/pocketbase v0.25.5/go.mod h1:gOnPr+g/GS+iqKh5XYXycdRWVGhiHY4c1H4TGjU9DDw= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -318,6 +320,8 @@ modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= modernc.org/sqlite v1.34.5 h1:Bb6SR13/fjp15jt70CL4f18JIN7p7dnMExd+UFnF15g= modernc.org/sqlite v1.34.5/go.mod h1:YLuNmX9NKs8wRNK2ko1LW1NGYcc9FkBO69JOt1AR9JE= +modernc.org/sqlite v1.35.0 h1:yQps4fegMnZFdphtzlfQTCNBWtS0CZv48pRpW3RFHRw= +modernc.org/sqlite v1.35.0/go.mod h1:9cr2sicr7jIaWTBKQmAxQLfBv9LL0su4ZTEV+utt3ic= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/views/assets/scripts.js b/views/assets/scripts.js index 19883d6..a9c264a 100644 --- a/views/assets/scripts.js +++ b/views/assets/scripts.js @@ -1,64 +1,154 @@ -const f = "script[xslt-onload]", i = "xslt-template", m = "xslt-transformed", c = /* @__PURE__ */ new Map(); -function u() { - let t = htmx.findAll(f); - for (let r of t) - p(r); -} -function p(t) { - if (t.getAttribute(m) === "true" || !t.hasAttribute(i)) - return; - let r = "#" + t.getAttribute(i), o = c.get(r); - if (!o) { - let s = htmx.find(r); - if (s) { - let l = s.innerHTML ? new DOMParser().parseFromString(s.innerHTML, "application/xml") : s.contentDocument; - o = new XSLTProcessor(), o.importStylesheet(l), c.set(r, o); - } else - throw new Error("Unknown XSLT template: " + r); - } - let a = new DOMParser().parseFromString(t.innerHTML, "application/xml"), e = o.transformToFragment(a, document), n = new XMLSerializer().serializeToString(e); - t.outerHTML = n; -} -function d() { - document.querySelectorAll("template[simple]").forEach((r) => { - let o = r.getAttribute("id"), a = r.content; - customElements.define( - o, - class extends HTMLElement { - constructor() { - super(), this.appendChild(a.cloneNode(!0)), this.slots = this.querySelectorAll("slot"); - } - connectedCallback() { - let e = []; - this.slots.forEach((n) => { - let s = n.getAttribute("name"), l = this.querySelector(`[slot="${s}"]`); - l && (n.replaceWith(l.cloneNode(!0)), e.push(l)); - }), e.forEach((n) => { - n.remove(); - }); - } - } - ); - }); -} -function h() { - u(), htmx.on("htmx:load", function(t) { - u(); - }), d(); -} -function T(t) { - t || (t = window.location.href); - const r = document.querySelectorAll("nav"); - if (r && r.length > 0) - for (const o of r) - o.querySelectorAll("a, [data-url]").forEach((e) => { - if (e.dataset.url && e.dataset.url !== "") { - let n = window.location.origin + e.dataset.url; - t.startsWith(n) ? e.setAttribute("aria-current", "page") : e.removeAttribute("aria-current"); - } else e.href && (t.startsWith(e.href) ? e.setAttribute("aria-current", "page") : e.removeAttribute("aria-current")); - }); -} -export { - T as setMenuActive, - h as setup +var p = (r) => { + throw TypeError(r); +}; +var L = (r, i, t) => i.has(r) || p("Cannot " + t); +var u = (r, i, t) => (L(r, i, "read from private field"), t ? t.call(r) : i.get(r)), o = (r, i, t) => i.has(r) ? p("Cannot add the same private member more than once") : i instanceof WeakSet ? i.add(r) : i.set(r, t), h = (r, i, t, e) => (L(r, i, "write to private field"), e ? e.call(r, t) : i.set(r, t), t), f = (r, i, t) => (L(r, i, "access private method"), t); +const v = "script[xslt-onload]", g = "xslt-template", w = "xslt-transformed", A = "filter-list"; +var a, c, T; +class S { + constructor() { + o(this, c); + o(this, a); + h(this, a, /* @__PURE__ */ new Map()); + } + setup() { + let i = htmx.findAll(v); + for (let t of i) + f(this, c, T).call(this, t); + } + hookupHTMX() { + htmx.on("htmx:load", (i) => { + this.setup(); + }); + } +} +a = new WeakMap(), c = new WeakSet(), T = function(i) { + if (i.getAttribute(w) === "true" || !i.hasAttribute(g)) + return; + let t = "#" + i.getAttribute(g), e = u(this, a).get(t); + if (!e) { + let d = htmx.find(t); + if (d) { + let E = d.innerHTML ? new DOMParser().parseFromString(d.innerHTML, "application/xml") : d.contentDocument; + e = new XSLTProcessor(), e.importStylesheet(E), u(this, a).set(t, e); + } else + throw new Error("Unknown XSLT template: " + t); + } + let s = new DOMParser().parseFromString(i.innerHTML, "application/xml"), b = e.transformToFragment(s, document), x = new XMLSerializer().serializeToString(b); + i.outerHTML = x; +}; +var n, l, _, m; +class k extends HTMLElement { + constructor() { + super(); + o(this, l); + o(this, n, !1); + this._items = [], this._url = "", this._filterstart = !1, this._placeholder = "Liste filtern...", this.render(); + } + static get observedAttributes() { + return ["data-url"]; + } + set items(t) { + Array.isArray(t) && (this._items = t, this.render()); + } + get items() { + return this._items; + } + connectedCallback() { + this._url = this.getAttribute("data-url") || "./", this._filterstart = this.getAttribute("data-filterstart") === "true", this._placeholder = this.getAttribute("data-placeholder") || "Liste filtern...", this._filterstart && h(this, n, !0), this.addEventListener("input", this.onInput.bind(this)), this.addEventListener("keydown", this.onEnter.bind(this)), this.addEventListener("focusin", this.onGainFocus.bind(this)), this.addEventListener("focusout", this.onLoseFocus.bind(this)); + } + attributeChangedCallback(t, e, s) { + t === "data-url" && e !== s && (this._url = s, this.render()), t === "data-filterstart" && e !== s && (this._filterstart = s === "true", this.render()), t === "data-placeholder" && e !== s && (this._placeholder = s, this.render()); + } + onInput(t) { + t.target && t.target.tagName.toLowerCase() === "input" && (this._filter = t.target.value, this.renderList()); + } + onGainFocus(t) { + t.target && t.target.tagName.toLowerCase() === "input" && (h(this, n, !1), this.renderList()); + } + onLoseFocus(t) { + t.target && t.target.tagName.toLowerCase() === "input" && (t.target.value = "", this._filter = "", this._filterstart && h(this, n, !0), this.renderList()); + } + onEnter(t) { + if (t.target && t.target.tagName.toLowerCase() === "input" && t.key === "Enter") { + t.preventDefault(); + const e = this.querySelector("a"); + e && e.click(); + } + } + setHREFFunc(t) { + this.getHREF = t, this.render(); + } + setLinkTextFunc(t) { + this.getLinkText = t, this.render(); + } + getHREF(t) { + if (t) { + if (!t.id) + return ""; + } else return ""; + return t.id; + } + getLinkText(t) { + if (t) { + if (!t.name) + return ""; + } else return ""; + return t.name; + } + renderList() { + let t = this.querySelector("#list"); + t && (t.outerHTML = this.List()); + } + render() { + this.innerHTML = ` +
+ ${this.Input()} + ${this.List()} +
+ `; + } + Input() { + return ` +
+ +
+ +
+
+ `; + } + List() { + let t = this._items; + return this._filter && (this._filterstart ? t = this._items.filter((e) => this.getLinkText(e).toLowerCase().startsWith(this._filter.toLowerCase())) : t = this._items.filter((e) => this.getLinkText(e).toLowerCase().includes(this._filter.toLowerCase()))), ` + + `; + } +} +n = new WeakMap(), l = new WeakSet(), _ = function(t) { + if (!t) + return ""; + let e = this.getHREF(t); + return e === "" || !window.location.href.endsWith(e) ? "" : "aria-current='page'"; +}, m = function() { + return u(this, n) ? "hidden" : ""; +}; +customElements.define(A, k); +export { + k as FilterList, + S as XSLTParseProcess }; diff --git a/views/assets/style.css b/views/assets/style.css index 7b7a19f..5d3d85d 100644 --- a/views/assets/style.css +++ b/views/assets/style.css @@ -1 +1 @@ -/*! tailwindcss v4.0.5 | MIT License | https://tailwindcss.com */@layer theme{:root,:host{--font-sans:"Source Sans 3","Merriweather Sans",ui-sans-serif;--font-serif:"Merriweather",ui-serif;--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-slate-100:oklch(.968 .007 247.896);--color-slate-200:oklch(.929 .013 255.508);--color-slate-600:oklch(.446 .043 257.281);--color-slate-700:oklch(.372 .044 257.287);--color-slate-800:oklch(.279 .041 260.031);--color-slate-900:oklch(.208 .042 265.755);--color-gray-200:oklch(.928 .006 264.531);--color-zinc-100:oklch(.967 .001 286.375);--color-zinc-200:oklch(.92 .004 286.32);--color-zinc-300:oklch(.871 .006 286.286);--color-stone-50:oklch(.985 .001 106.423);--color-stone-100:oklch(.97 .001 106.424);--color-stone-700:oklch(.374 .01 67.558);--color-stone-900:oklch(.216 .006 56.043);--color-white:#fff;--spacing:.25rem;--breakpoint-xl:80rem;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-bold:700;--tracking-wide:.025em;--ease-in:cubic-bezier(.4,0,1,1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-font-feature-settings:var(--font-sans--font-feature-settings);--default-font-variation-settings:var(--font-sans--font-variation-settings);--default-mono-font-family:var(--font-mono);--default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentColor)}::file-selector-button{border-color:var(--color-gray-200,currentColor)}}@layer components{html{font-size:16.5px}body{background-color:var(--color-stone-50)}h1,h2,h3,h4{font-family:var(--font-serif)}a{-webkit-hyphens:none;hyphens:none;color:var(--color-slate-700);text-decoration-line:underline;text-decoration-style:dotted}@media (hover:hover){a:hover{color:var(--color-slate-900);text-decoration-style:solid}}ul{margin-block:calc(var(--spacing)*2)}li{margin-left:calc(var(--spacing)*14);list-style-type:disc}@media (hover:hover){nav>a:hover{border-color:var(--color-zinc-200)!important}}nav>*{border-bottom-style:var(--tw-border-style);border-color:#0000;border-bottom-width:4px}nav>button[aria-current=true]{background-color:var(--color-slate-200)!important}nav a[aria-current=page]{color:var(--color-slate-800);border-color:var(--color-zinc-300)!important}main{flex-grow:1;flex-shrink:0}.small-caps{font-variant-caps:small-caps}.alphabet a[aria-current=page]{bottom:calc(var(--spacing)*-3);border-bottom-style:var(--tw-border-style);padding-top:calc(var(--spacing)*2);padding-bottom:calc(var(--spacing)*3);--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);border-bottom-width:1px;font-style:italic;position:relative;background-color:var(--color-stone-50)!important}.alphabet a:hover:not([aria-current=page]){padding-top:calc(var(--spacing)*.5);padding-bottom:calc(var(--spacing)*1);position:relative;background-color:var(--color-stone-50)!important}}@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-12{margin-top:calc(var(--spacing)*12)}.mr-1{margin-right:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.-ml-0\.5{margin-left:calc(var(--spacing)*-.5)}.ml-3{margin-left:calc(var(--spacing)*3)}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.h-1{height:calc(var(--spacing)*1)}.h-2{height:calc(var(--spacing)*2)}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-14{height:calc(var(--spacing)*14)}.h-full{height:100%}.min-h-14{min-height:calc(var(--spacing)*14)}.min-h-screen{min-height:100vh}.w-14{width:calc(var(--spacing)*14)}.w-full{width:100%}.max-w-\(--breakpoint-xl\){max-width:var(--breakpoint-xl)}.flex-grow{flex-grow:1}.grow-0{flex-grow:0}.translate-2{--tw-translate-x:calc(var(--spacing)*2);--tw-translate-y:calc(var(--spacing)*2);translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-end{justify-content:flex-end}.gap-x-3{column-gap:calc(var(--spacing)*3)}.gap-x-4{column-gap:calc(var(--spacing)*4)}.self-end{align-self:flex-end}.rounded{border-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-x{border-inline-style:var(--tw-border-style);border-inline-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-zinc-300{border-color:var(--color-zinc-300)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-stone-700{background-color:var(--color-stone-700)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-3\.5{padding-block:calc(var(--spacing)*3.5)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-3\.5{padding-top:calc(var(--spacing)*3.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.\!pr-2\.5{padding-right:calc(var(--spacing)*2.5)!important}.pr-2\.5{padding-right:calc(var(--spacing)*2.5)}.pb-1\.5{padding-bottom:calc(var(--spacing)*1.5)}.align-bottom{vertical-align:bottom}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-wrap{text-wrap:wrap}.text-slate-600{color:var(--color-slate-600)}.text-white{color:var(--color-white)}.italic{font-style:italic}.no-underline{text-decoration-line:none}.overline{text-decoration-line:overline}.underline{text-decoration-line:underline}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-75{--tw-duration:75ms;transition-duration:75ms}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.\[a-zA-Z\:\\-\\\.\]{a-zA-Z:\-\.}.odd\:bg-stone-100:nth-child(odd){background-color:var(--color-stone-100)}.even\:bg-zinc-100:nth-child(2n){background-color:var(--color-zinc-100)}@media (hover:hover){.hover\:cursor-pointer:hover{cursor:pointer}.hover\:bg-slate-100:hover{background-color:var(--color-slate-100)}.hover\:bg-stone-900:hover{background-color:var(--color-stone-900)}.hover\:text-slate-900:hover{color:var(--color-slate-900)}}.\[\&_td\]\:\!align-top td{vertical-align:top!important}.\[\&\>\*\]\:-mb-1\.5>*{margin-bottom:calc(var(--spacing)*-1.5)}.\[\&\>\*\]\:px-1\.5>*{padding-inline:calc(var(--spacing)*1.5)}.\[\&\>\*\]\:pt-1>*{padding-top:calc(var(--spacing)*1)}.\[\&\>a\]\:no-underline>a{text-decoration-line:none}.\[\&\>a\[aria-current\=\'page\'\]\]\:font-bold>a[aria-current=page]{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false} +/*! tailwindcss v4.0.5 | MIT License | https://tailwindcss.com */@layer theme{:root,:host{--font-sans:"Source Sans 3","Merriweather Sans",ui-sans-serif;--font-serif:"Merriweather",ui-serif;--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-slate-100:oklch(.968 .007 247.896);--color-slate-200:oklch(.929 .013 255.508);--color-slate-600:oklch(.446 .043 257.281);--color-slate-700:oklch(.372 .044 257.287);--color-slate-800:oklch(.279 .041 260.031);--color-slate-900:oklch(.208 .042 265.755);--color-gray-200:oklch(.928 .006 264.531);--color-zinc-100:oklch(.967 .001 286.375);--color-zinc-200:oklch(.92 .004 286.32);--color-zinc-300:oklch(.871 .006 286.286);--color-zinc-600:oklch(.442 .017 285.786);--color-stone-50:oklch(.985 .001 106.423);--color-stone-100:oklch(.97 .001 106.424);--color-stone-700:oklch(.374 .01 67.558);--color-stone-900:oklch(.216 .006 56.043);--color-white:#fff;--spacing:.25rem;--breakpoint-xl:80rem;--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-bold:700;--tracking-wide:.025em;--ease-in:cubic-bezier(.4,0,1,1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-font-feature-settings:var(--font-sans--font-feature-settings);--default-font-variation-settings:var(--font-sans--font-variation-settings);--default-mono-font-family:var(--font-mono);--default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentColor)}::file-selector-button{border-color:var(--color-gray-200,currentColor)}}@layer components{html{font-size:16.5px}body{background-color:var(--color-stone-50)}h1,h2,h3,h4{font-family:var(--font-serif)}a{-webkit-hyphens:none;hyphens:none;color:var(--color-slate-700);text-decoration-line:underline;text-decoration-style:dotted}@media (hover:hover){a:hover{color:var(--color-slate-900);text-decoration-style:solid}}ul{margin-block:calc(var(--spacing)*2)}li{margin-left:calc(var(--spacing)*14);list-style-type:disc}@media (hover:hover){nav>a:hover{border-color:var(--color-zinc-200)!important}}nav>*{border-bottom-style:var(--tw-border-style);border-color:#0000;border-bottom-width:4px}nav>button[aria-current=true]{background-color:var(--color-slate-200)!important}nav a[aria-current=page]{color:var(--color-slate-800);border-color:var(--color-zinc-300)!important}main{flex-grow:1;flex-shrink:0}.small-caps{font-variant-caps:small-caps}.alphabet a[aria-current=page]:not(.inactive){bottom:calc(var(--spacing)*-3);border-bottom-style:var(--tw-border-style);padding-top:calc(var(--spacing)*2);padding-bottom:calc(var(--spacing)*3);--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);border-bottom-width:1px;font-style:italic;position:relative;background-color:var(--color-stone-50)!important}.alphabet a:hover:not([aria-current=page]:not(.inactive)){padding-top:calc(var(--spacing)*.5);padding-bottom:calc(var(--spacing)*1);position:relative;background-color:var(--color-stone-50)!important}.headingcontainer:before{content:"";top:calc(var(--spacing)*0);background-color:var(--color-zinc-300);width:50%;height:1px;position:absolute;left:50%}.headingcontainer{margin-top:calc(var(--spacing)*10);border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--color-zinc-300);position:relative}.headingcontainer h1{--tw-translate-y: -50% ;width:min-content;translate:var(--tw-translate-x)var(--tw-translate-y);background-color:var(--color-stone-50);padding-inline:calc(var(--spacing)*3);font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);white-space:nowrap;margin-inline:auto;position:relative}}@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.relative{position:relative}.static{position:static}.float-right{float:right}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-12{margin-top:calc(var(--spacing)*12)}.mr-1{margin-right:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.-ml-0\.5{margin-left:calc(var(--spacing)*-.5)}.ml-3{margin-left:calc(var(--spacing)*3)}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.h-1{height:calc(var(--spacing)*1)}.h-2{height:calc(var(--spacing)*2)}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-14{height:calc(var(--spacing)*14)}.h-full{height:100%}.max-h-60{max-height:calc(var(--spacing)*60)}.min-h-14{min-height:calc(var(--spacing)*14)}.min-h-72{min-height:calc(var(--spacing)*72)}.min-h-screen{min-height:100vh}.w-14{width:calc(var(--spacing)*14)}.w-full{width:100%}.max-w-\(--breakpoint-xl\){max-width:var(--breakpoint-xl)}.max-w-96{max-width:calc(var(--spacing)*96)}.min-w-7{min-width:calc(var(--spacing)*7)}.min-w-96{min-width:calc(var(--spacing)*96)}.min-w-\[22\.5rem\]{min-width:22.5rem}.flex-grow,.grow{flex-grow:1}.grow-0{flex-grow:0}.translate-2{--tw-translate-x:calc(var(--spacing)*2);--tw-translate-y:calc(var(--spacing)*2);translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-end{justify-content:flex-end}.gap-x-3{column-gap:calc(var(--spacing)*3)}.gap-x-4{column-gap:calc(var(--spacing)*4)}.gap-y-4{row-gap:calc(var(--spacing)*4)}.self-end{align-self:flex-end}.overflow-auto{overflow:auto}.rounded{border-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-x{border-inline-style:var(--tw-border-style);border-inline-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-4{border-bottom-style:var(--tw-border-style);border-bottom-width:4px}.border-zinc-300{border-color:var(--color-zinc-300)}.border-zinc-600{border-color:var(--color-zinc-600)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-stone-50{background-color:var(--color-stone-50)}.bg-stone-100{background-color:var(--color-stone-100)}.bg-stone-700{background-color:var(--color-stone-700)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-3\.5{padding-block:calc(var(--spacing)*3.5)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-3\.5{padding-top:calc(var(--spacing)*3.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.\!pr-2\.5{padding-right:calc(var(--spacing)*2.5)!important}.pr-2\.5{padding-right:calc(var(--spacing)*2.5)}.pb-0{padding-bottom:calc(var(--spacing)*0)}.pb-0\.5{padding-bottom:calc(var(--spacing)*.5)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\.5{padding-bottom:calc(var(--spacing)*1.5)}.align-bottom{vertical-align:bottom}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-wrap{text-wrap:wrap}.text-slate-600{color:var(--color-slate-600)}.text-white{color:var(--color-white)}.italic{font-style:italic}.no-underline{text-decoration-line:none}.overline{text-decoration-line:overline}.underline{text-decoration-line:underline}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-75{--tw-duration:75ms;transition-duration:75ms}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.\[a-zA-Z\:\\-\\\.\]{a-zA-Z:\-\.}.placeholder\:italic::placeholder{font-style:italic}.odd\:bg-stone-100:nth-child(odd){background-color:var(--color-stone-100)}.even\:bg-zinc-100:nth-child(2n){background-color:var(--color-zinc-100)}@media (hover:hover){.hover\:cursor-pointer:hover{cursor:pointer}.hover\:bg-slate-100:hover{background-color:var(--color-slate-100)}.hover\:bg-slate-200:hover{background-color:var(--color-slate-200)}.hover\:bg-stone-900:hover{background-color:var(--color-stone-900)}.hover\:text-slate-900:hover{color:var(--color-slate-900)}}.\[\&_td\]\:\!align-top td{vertical-align:top!important}.\[\&\>\*\]\:-mb-1\.5>*{margin-bottom:calc(var(--spacing)*-1.5)}.\[\&\>\*\]\:px-1\.5>*{padding-inline:calc(var(--spacing)*1.5)}.\[\&\>\*\]\:pt-1>*{padding-top:calc(var(--spacing)*1)}.\[\&\>a\]\:no-underline>a{text-decoration-line:none}.\[\&\>a\[aria-current\=\'page\'\]\]\:font-bold>a[aria-current=page]{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false} diff --git a/views/layouts/components/_menu.gohtml b/views/layouts/components/_menu.gohtml index 6fa1b21..b870a7d 100644 --- a/views/layouts/components/_menu.gohtml +++ b/views/layouts/components/_menu.gohtml @@ -13,8 +13,7 @@ - - diff --git a/views/layouts/default/root.gohtml b/views/layouts/default/root.gohtml index af3ff86..f7cc032 100644 --- a/views/layouts/default/root.gohtml +++ b/views/layouts/default/root.gohtml @@ -20,16 +20,13 @@ + + - - - +
-
- -
+
{{ block "body" . }} {{ end }} diff --git a/views/routes/components/_alphabet.gohtml b/views/routes/components/_alphabet.gohtml index 8259c70..34039f0 100644 --- a/views/routes/components/_alphabet.gohtml +++ b/views/routes/components/_alphabet.gohtml @@ -1,19 +1,21 @@ {{ $model := . }} {{ if $model.letters }} -
-
+
+
{{ range $id, $r := .letters }} {{ $r }} {{ end }} @@ -21,28 +23,37 @@
-
- - -
- {{ end }} diff --git a/views/routes/components/_reihenfilter.gohtml b/views/routes/components/_reihenfilter.gohtml new file mode 100644 index 0000000..f34e7f0 --- /dev/null +++ b/views/routes/components/_reihenfilter.gohtml @@ -0,0 +1,51 @@ +{{ $model := . }} +
+ {{ if .agents }} + + + + {{ end }} + + {{ if .places }} + + + + {{ end }} + + {{ if .years }} + + + + {{ end }} +
diff --git a/views/routes/reihen/body.gohtml b/views/routes/reihen/body.gohtml index d92e014..89dfa63 100644 --- a/views/routes/reihen/body.gohtml +++ b/views/routes/reihen/body.gohtml @@ -1,14 +1,18 @@ {{ $model := . }} -
- {{ template "_alphabet" Dict "active" .letter "letters" .letters "search" .search }} +
+

Bände nach Reihentiteln

+
+ {{ template "_alphabet" Dict "active" .letter "letters" .letters "search" .search }} +
+
+ +
+ {{ template "_reihenfilter" . }}
- {{ if .search }} -
Reihen für {{ .search }} gefunden.
- {{ end }} {{ if or .series .altseries }} {{ range $id, $r := .series }}
@@ -33,41 +37,3 @@
{{ end }}
- -
- {{ if .agents }} -
- {{ range $id, $r := .agents }} - - {{ end }} -
- {{ end }} - - {{ if .places }} -
- {{ range $id, $r := .places }} - - {{ end }} -
- {{ end }} - - {{ if .years }} -
- {{ range $id, $r := .years }} - {{ if eq $r 0 }} -
- ohne Jahr -
- {{ else }} -
- {{ $r }} -
- {{ end }} - {{ end }} -
- {{ end }} -
diff --git a/views/transform/main.js b/views/transform/main.js index 5628f64..be103fc 100644 --- a/views/transform/main.js +++ b/views/transform/main.js @@ -1,48 +1,66 @@ +// INFO: We import this so vite processes the stylesheet import "./site.css"; const ATTR_XSLT_ONLOAD = "script[xslt-onload]"; const ATTR_XSLT_TEMPLATE = "xslt-template"; const ATTR_XSLT_STATE = "xslt-transformed"; +const FILTER_LIST_ELEMENT = "filter-list"; -const xslt_processors = new Map(); +class XSLTParseProcess { + #processors; -function setup_xslt() { - let els = htmx.findAll(ATTR_XSLT_ONLOAD); - for (let element of els) { - transform_xslt(element); - } -} - -function transform_xslt(element) { - if ( - element.getAttribute(ATTR_XSLT_STATE) === "true" || - !element.hasAttribute(ATTR_XSLT_TEMPLATE) - ) { - return; + constructor() { + this.#processors = new Map(); } - let templateId = "#" + element.getAttribute(ATTR_XSLT_TEMPLATE); - let processor = xslt_processors.get(templateId); - if (!processor) { - let template = htmx.find(templateId); - if (template) { - let content = template.innerHTML - ? new DOMParser().parseFromString(template.innerHTML, "application/xml") - : template.contentDocument; - processor = new XSLTProcessor(); - processor.importStylesheet(content); - xslt_processors.set(templateId, processor); - } else { - throw new Error("Unknown XSLT template: " + templateId); + setup() { + let els = htmx.findAll(ATTR_XSLT_ONLOAD); + for (let element of els) { + this.#transform_xslt(element); } } - let data = new DOMParser().parseFromString(element.innerHTML, "application/xml"); - let frag = processor.transformToFragment(data, document); - let s = new XMLSerializer().serializeToString(frag); - element.outerHTML = s; + hookupHTMX() { + // INFO: We can instead use afterSettle; and also clear the map with + // xslt_processors.clear(); + htmx.on("htmx:load", (_) => { + this.setup(); + }); + } + + #transform_xslt(element) { + if ( + element.getAttribute(ATTR_XSLT_STATE) === "true" || + !element.hasAttribute(ATTR_XSLT_TEMPLATE) + ) { + return; + } + + let templateId = "#" + element.getAttribute(ATTR_XSLT_TEMPLATE); + let processor = this.#processors.get(templateId); + if (!processor) { + let template = htmx.find(templateId); + if (template) { + let content = template.innerHTML + ? new DOMParser().parseFromString(template.innerHTML, "application/xml") + : template.contentDocument; + processor = new XSLTProcessor(); + processor.importStylesheet(content); + this.#processors.set(templateId, processor); + } else { + throw new Error("Unknown XSLT template: " + templateId); + } + } + + let data = new DOMParser().parseFromString(element.innerHTML, "application/xml"); + let frag = processor.transformToFragment(data, document); + let s = new XMLSerializer().serializeToString(frag); + element.outerHTML = s; + } } +// INFO: these is a function to define simple reusable templates which we don't need. +// Since we can include templates server-side. function setup_templates() { let templates = document.querySelectorAll("template[simple]"); templates.forEach((template) => { @@ -77,45 +95,213 @@ function setup_templates() { }); } -// INFO: This is intended to be callled once on website load -function setup() { - setup_xslt(); - - htmx.on("htmx:load", function (_) { - // INFO: We can instead use afterSettle; and also clear the map with - // xslt_processors.clear(); - setup_xslt(); - }); - - setup_templates(); -} - -function setMenuActive(url) { - if (!url) { - url = window.location.href; +class FilterList extends HTMLElement { + #hiddenlist = false; + constructor() { + super(); + this._items = []; + this._url = ""; + this._filterstart = false; + this._placeholder = "Liste filtern..."; + this.render(); } - const menus = document.querySelectorAll("nav"); - if (menus && menus.length > 0) { - for (const menu of menus) { - const links = menu.querySelectorAll("a, [data-url]"); - links.forEach((link) => { - if (link.dataset.url && link.dataset.url !== "") { - let fullurl = window.location.origin + link.dataset.url; - if (url.startsWith(fullurl)) { - link.setAttribute("aria-current", "page"); - } else { - link.removeAttribute("aria-current"); - } - } else if (link.href) { - if (url.startsWith(link.href)) { - link.setAttribute("aria-current", "page"); - } else { - link.removeAttribute("aria-current"); - } - } - }); + + static get observedAttributes() { + return ["data-url"]; + } + + set items(data) { + if (Array.isArray(data)) { + this._items = data; + this.render(); } } + + get items() { + return this._items; + } + + connectedCallback() { + this._url = this.getAttribute("data-url") || "./"; + this._filterstart = this.getAttribute("data-filterstart") === "true"; + this._placeholder = this.getAttribute("data-placeholder") || "Liste filtern..."; + + if (this._filterstart) { + this.#hiddenlist = true; + } + + this.addEventListener("input", this.onInput.bind(this)); + this.addEventListener("keydown", this.onEnter.bind(this)); + this.addEventListener("focusin", this.onGainFocus.bind(this)); + this.addEventListener("focusout", this.onLoseFocus.bind(this)); + } + + attributeChangedCallback(name, oldValue, newValue) { + if (name === "data-url" && oldValue !== newValue) { + this._url = newValue; + this.render(); + } + if (name === "data-filterstart" && oldValue !== newValue) { + this._filterstart = newValue === "true"; + this.render(); + } + if (name === "data-placeholder" && oldValue !== newValue) { + this._placeholder = newValue; + this.render(); + } + } + + onInput(e) { + if (e.target && e.target.tagName.toLowerCase() === "input") { + this._filter = e.target.value; + this.renderList(); + } + } + + onGainFocus(e) { + if (e.target && e.target.tagName.toLowerCase() === "input") { + this.#hiddenlist = false; + this.renderList(); + } + } + + onLoseFocus(e) { + if (e.target && e.target.tagName.toLowerCase() === "input") { + e.target.value = ""; + this._filter = ""; + if (this._filterstart) { + this.#hiddenlist = true; + } + this.renderList(); + } + } + + onEnter(e) { + if (e.target && e.target.tagName.toLowerCase() === "input" && e.key === "Enter") { + e.preventDefault(); + const link = this.querySelector("a"); + if (link) { + link.click(); + } + } + } + + setHREFFunc(fn) { + this.getHREF = fn; + this.render(); + } + + setLinkTextFunc(fn) { + this.getLinkText = fn; + this.render(); + } + + getHREF(item) { + if (!item) { + return ""; + } else if (!item.id) { + return ""; + } + return item.id; + } + + getLinkText(item) { + if (!item) { + return ""; + } else if (!item.name) { + return ""; + } + return item.name; + } + + #isActive(item) { + if (!item) { + return ""; + } + + let href = this.getHREF(item); + if (href === "") { + return ""; + } + + if (!window.location.href.endsWith(href)) { + return ""; + } + + return "aria-current='page'"; + } + + #hiddenList() { + if (this.#hiddenlist) { + return "hidden"; + } + return ""; + } + + renderList() { + let list = this.querySelector("#list"); + if (list) { + list.outerHTML = this.List(); + } + } + + render() { + this.innerHTML = ` +
+ ${this.Input()} + ${this.List()} +
+ `; + } + + Input() { + return ` +
+ +
+ +
+
+ `; + } + + List() { + let filtereditems = this._items; + if (this._filter) { + if (!this._filterstart) + filtereditems = this._items.filter((item) => { + return this.getLinkText(item).toLowerCase().includes(this._filter.toLowerCase()); + }); + else + filtereditems = this._items.filter((item) => { + return this.getLinkText(item).toLowerCase().startsWith(this._filter.toLowerCase()); + }); + } + + return ` + + `; + } } -export { setup, setMenuActive }; +customElements.define(FILTER_LIST_ELEMENT, FilterList); + +export { XSLTParseProcess, FilterList }; diff --git a/views/transform/site.css b/views/transform/site.css index bb59ab2..fa87c27 100644 --- a/views/transform/site.css +++ b/views/transform/site.css @@ -99,11 +99,24 @@ @apply font-variant-small-caps; } - .alphabet a[aria-current="page"] { + .alphabet a[aria-current="page"]:not(.inactive) { @apply pb-3 pt-2 font-bold italic !bg-stone-50 relative -bottom-3 border-b; } - .alphabet a:hover:not([aria-current="page"]) { + .alphabet a:hover:not([aria-current="page"]:not(.inactive)) { @apply pb-1 pt-0.5 !bg-stone-50 relative; } + + .headingcontainer:before { + content: ""; + @apply bg-zinc-300 w-[50%] absolute top-0 left-[50%] h-[1px]; + } + + .headingcontainer { + @apply mt-10 border-r border-zinc-300 relative; + } + + .headingcontainer h1 { + @apply text-3xl font-bold px-3 bg-stone-50 relative -translate-y-[50%] w-min whitespace-nowrap mx-auto; + } }