@livenetworks/ashlar 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ln-confirm/README.md +2 -2
- package/components/ln-confirm/ln-confirm.js +1 -1
- package/components/ln-confirm/src/ln-confirm.js +1 -3
- package/components/ln-core/attrs.js +273 -273
- package/components/ln-core/events.js +122 -122
- package/components/ln-core/lifecycle.js +403 -403
- package/components/ln-debug/ln-debug.js +1 -1
- package/components/ln-debug/src/generated-attributes.js +1 -0
- package/components/ln-modal/ln-modal.js +1 -1
- package/components/ln-modal/ln-modal.scss +1 -1
- package/components/ln-modal/src/ln-modal.js +1 -0
- package/components/ln-router/README.md +33 -0
- package/components/ln-router/ln-router.js +1 -1
- package/components/ln-router/ln-router.schema.json +8 -0
- package/components/ln-router/src/ln-router.js +51 -28
- package/components/ln-router/src/router-model.js +85 -0
- package/components/ln-toast/ln-toast.js +1 -1
- package/components/ln-toast/ln-toast.scss +5 -1
- package/components/ln-toast/src/ln-toast.js +1 -1
- package/ln-ashlar.html-data.json +4 -0
- package/package.json +1 -1
- package/web-types.json +8 -1
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registerComponent, dispatch, dispatchCancelable, guardBody, findElements, shouldInterceptLink
|
|
3
3
|
} from '../../ln-core';
|
|
4
|
-
import { planRegions } from './router-model.js';
|
|
4
|
+
import { planRegions, normalizeBase, stripBase, toAbsoluteUrl } from './router-model.js';
|
|
5
|
+
|
|
6
|
+
function _getBase() {
|
|
7
|
+
if (typeof document === 'undefined') return '';
|
|
8
|
+
const outlet = document.querySelector('[data-ln-outlet]') || document.querySelector('[data-ln-router-base]');
|
|
9
|
+
if (outlet && outlet.hasAttribute('data-ln-router-base')) {
|
|
10
|
+
return normalizeBase(outlet.getAttribute('data-ln-router-base'));
|
|
11
|
+
}
|
|
12
|
+
const baseEl = document.querySelector('base[href]');
|
|
13
|
+
if (baseEl) {
|
|
14
|
+
try {
|
|
15
|
+
const u = new URL(baseEl.getAttribute('href'), window.location.origin);
|
|
16
|
+
return normalizeBase(u.pathname);
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return normalizeBase(baseEl.getAttribute('href'));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
5
23
|
|
|
6
24
|
// Singleton router implementation
|
|
7
25
|
export const router = {
|
|
@@ -11,10 +29,18 @@ export const router = {
|
|
|
11
29
|
replace: function (fullPath) {
|
|
12
30
|
_navigate(fullPath, { historyAction: 'replace' });
|
|
13
31
|
},
|
|
32
|
+
base: function () {
|
|
33
|
+
return _getBase();
|
|
34
|
+
},
|
|
35
|
+
toUrl: function (relPath) {
|
|
36
|
+
return toAbsoluteUrl(relPath, _getBase());
|
|
37
|
+
},
|
|
14
38
|
current: function () {
|
|
15
39
|
if (currentPath === null) return null;
|
|
16
40
|
return {
|
|
17
41
|
path: currentPath,
|
|
42
|
+
fullPath: currentFullPath,
|
|
43
|
+
base: currentBase,
|
|
18
44
|
params: currentParams,
|
|
19
45
|
query: currentQuery,
|
|
20
46
|
route: currentRoute,
|
|
@@ -42,6 +68,7 @@ const ATTRIBUTES = {
|
|
|
42
68
|
'data-ln-route-target': { effect: _reRegisterRoute, type: 'string', description: 'Target outlet element selector where route content is rendered' },
|
|
43
69
|
'data-ln-route-title': { effect: _reRegisterRoute, type: 'string', description: 'Document title template set when route is activated' },
|
|
44
70
|
'data-ln-route-keep': { type: 'boolean', fallback: false, description: 'Preserve mounted DOM nodes in memory instead of rebuilding' },
|
|
71
|
+
'data-ln-router-base': { type: 'string', description: 'Base URL prefix for subdirectory routing (e.g. "/spa")' },
|
|
45
72
|
'data-ln-router-hydrate': { type: 'boolean', fallback: false, description: 'Hydrate existing DOM content on initial router boot' }
|
|
46
73
|
};
|
|
47
74
|
|
|
@@ -57,6 +84,8 @@ let currentRegions = new Map();
|
|
|
57
84
|
|
|
58
85
|
let booted = false;
|
|
59
86
|
let currentPath = null;
|
|
87
|
+
let currentFullPath = null;
|
|
88
|
+
let currentBase = '';
|
|
60
89
|
let currentParams = {};
|
|
61
90
|
let currentQuery = {};
|
|
62
91
|
let currentRoute = null;
|
|
@@ -77,7 +106,7 @@ function _dispatchMaybeDeferred(target, name, detail) {
|
|
|
77
106
|
}
|
|
78
107
|
|
|
79
108
|
/**
|
|
80
|
-
* Normalize path: collapse trailing slash, strip query/hash, parse query.
|
|
109
|
+
* Normalize path: collapse trailing slash, strip query/hash, parse query, strip base.
|
|
81
110
|
*/
|
|
82
111
|
function _normalizePath(fullPath) {
|
|
83
112
|
// Absolute same-origin URLs (route() helpers, anchor.href) → reduce to
|
|
@@ -90,7 +119,7 @@ function _normalizePath(fullPath) {
|
|
|
90
119
|
} catch (e) { /* not a parseable URL — use fullPath as-is */ }
|
|
91
120
|
|
|
92
121
|
let [pathAndQuery] = fullPath.split('#');
|
|
93
|
-
let [
|
|
122
|
+
let [rawPath, queryString] = pathAndQuery.split('?');
|
|
94
123
|
|
|
95
124
|
const query = {};
|
|
96
125
|
if (queryString) {
|
|
@@ -100,12 +129,10 @@ function _normalizePath(fullPath) {
|
|
|
100
129
|
}
|
|
101
130
|
}
|
|
102
131
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
path = '/';
|
|
106
|
-
}
|
|
132
|
+
const base = _getBase();
|
|
133
|
+
const path = stripBase(rawPath, base);
|
|
107
134
|
|
|
108
|
-
return { path, query };
|
|
135
|
+
return { path, query, base };
|
|
109
136
|
}
|
|
110
137
|
|
|
111
138
|
/**
|
|
@@ -261,7 +288,8 @@ function _teardownOutlet(target) {
|
|
|
261
288
|
* swaps all regions that need it inside a single view transition.
|
|
262
289
|
*/
|
|
263
290
|
function _navigate(fullPath, opts = {}) {
|
|
264
|
-
const { path, query } = _normalizePath(fullPath);
|
|
291
|
+
const { path, query, base } = _normalizePath(fullPath);
|
|
292
|
+
const historyPath = toAbsoluteUrl(fullPath, base);
|
|
265
293
|
|
|
266
294
|
// 1. Per-region match
|
|
267
295
|
const regionMatches = new Map();
|
|
@@ -329,7 +357,8 @@ function _navigate(fullPath, opts = {}) {
|
|
|
329
357
|
// one match, regardless of whether the primary is among them.
|
|
330
358
|
const beforeEvent = dispatchCancelable(primaryTarget || document.body, 'ln-router:before-navigate', {
|
|
331
359
|
from: currentPath,
|
|
332
|
-
to:
|
|
360
|
+
to: historyPath,
|
|
361
|
+
path: path,
|
|
333
362
|
params: primaryMatch ? primaryMatch.params : {},
|
|
334
363
|
query
|
|
335
364
|
});
|
|
@@ -337,9 +366,9 @@ function _navigate(fullPath, opts = {}) {
|
|
|
337
366
|
|
|
338
367
|
// 7. History update (once per navigation)
|
|
339
368
|
if (opts.historyAction === 'push') {
|
|
340
|
-
window.history.pushState(null, '',
|
|
369
|
+
window.history.pushState(null, '', historyPath);
|
|
341
370
|
} else if (opts.historyAction === 'replace') {
|
|
342
|
-
window.history.replaceState(null, '',
|
|
371
|
+
window.history.replaceState(null, '', historyPath);
|
|
343
372
|
}
|
|
344
373
|
|
|
345
374
|
// 8. Atomic swap — one view transition wraps every region clear/mount.
|
|
@@ -395,7 +424,9 @@ function _navigate(fullPath, opts = {}) {
|
|
|
395
424
|
}
|
|
396
425
|
|
|
397
426
|
_dispatchMaybeDeferred(d.targetEl, 'ln-router:navigated', {
|
|
398
|
-
path:
|
|
427
|
+
path: path,
|
|
428
|
+
fullPath: historyPath,
|
|
429
|
+
base: base,
|
|
399
430
|
params: d.match.params,
|
|
400
431
|
query,
|
|
401
432
|
route: d.match.route,
|
|
@@ -406,10 +437,12 @@ function _navigate(fullPath, opts = {}) {
|
|
|
406
437
|
|
|
407
438
|
// State is read off the primary match — currentRoute is null on an
|
|
408
439
|
// aux-only navigation, which is what current() === null now hinges on.
|
|
409
|
-
currentPath
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
440
|
+
currentPath = path;
|
|
441
|
+
currentFullPath = historyPath;
|
|
442
|
+
currentBase = base;
|
|
443
|
+
currentQuery = query;
|
|
444
|
+
currentRoute = primaryMatch ? primaryMatch.route : null;
|
|
445
|
+
currentParams = primaryMatch ? primaryMatch.params : {};
|
|
413
446
|
|
|
414
447
|
// currentRegions reflects every region's match (null when unmatched).
|
|
415
448
|
// Built from regionMatches — never from the loop variable `match`.
|
|
@@ -455,20 +488,10 @@ function _queryEqual(a, b) {
|
|
|
455
488
|
|
|
456
489
|
function _onPopState() {
|
|
457
490
|
const fullPath = window.location.pathname + window.location.search;
|
|
458
|
-
// Fragment-only popstate guard: when Back/Forward changes ONLY the hash
|
|
459
|
-
// (path + query identical to the current SPA state), skip navigation so the
|
|
460
|
-
// primary outlet is not torn down and re-cloned. Hash-bound components
|
|
461
|
-
// (e.g. ln-modal) react to the accompanying hashchange independently.
|
|
462
|
-
//
|
|
463
|
-
// cur.query is the authoritative already-parsed query for the active route
|
|
464
|
-
// (currentQuery), so compare target.query against it directly. cur.path is
|
|
465
|
-
// the raw fullPath (retains the query string), so normalize it for the
|
|
466
|
-
// pathname comparison only — do NOT re-parse it for the query.
|
|
467
491
|
const cur = router.current();
|
|
468
492
|
if (cur && cur.path != null) {
|
|
469
493
|
const target = _normalizePath(fullPath);
|
|
470
|
-
|
|
471
|
-
if (currentPathNorm === target.path && _queryEqual(cur.query, target.query)) {
|
|
494
|
+
if (cur.path === target.path && _queryEqual(cur.query, target.query)) {
|
|
472
495
|
return;
|
|
473
496
|
}
|
|
474
497
|
}
|
|
@@ -48,3 +48,88 @@ export function planRegions(descriptors, { isHydration = false, hasPrimaryRegion
|
|
|
48
48
|
|
|
49
49
|
return { notFound, clears, swaps, owner };
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Normalizes a base URL string:
|
|
54
|
+
* - ensures leading slash
|
|
55
|
+
* - strips trailing slash
|
|
56
|
+
* - returns empty string if root '/' or empty
|
|
57
|
+
* e.g. '/spa/' -> '/spa', 'spa' -> '/spa', '/' -> '', '' -> ''
|
|
58
|
+
*
|
|
59
|
+
* @param {string|null|undefined} base
|
|
60
|
+
* @returns {string}
|
|
61
|
+
*/
|
|
62
|
+
export function normalizeBase(base) {
|
|
63
|
+
if (!base || typeof base !== 'string') return '';
|
|
64
|
+
let b = base.trim().replace(/\/+$/, '');
|
|
65
|
+
if (!b || b === '/') return '';
|
|
66
|
+
return b.startsWith('/') ? b : '/' + b;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Strips the base URL prefix from a pathname, returning the clean relative path.
|
|
71
|
+
* e.g. with base '/spa':
|
|
72
|
+
* '/spa/packages' -> '/packages'
|
|
73
|
+
* '/spa' -> '/'
|
|
74
|
+
* '/spa/' -> '/'
|
|
75
|
+
* '/packages' -> '/packages' (already relative)
|
|
76
|
+
* '/' -> '/'
|
|
77
|
+
*
|
|
78
|
+
* @param {string} path
|
|
79
|
+
* @param {string} [base]
|
|
80
|
+
* @returns {string}
|
|
81
|
+
*/
|
|
82
|
+
export function stripBase(path, base) {
|
|
83
|
+
const b = normalizeBase(base);
|
|
84
|
+
if (!b) return (path && path.replace(/\/+$/, '')) || '/';
|
|
85
|
+
|
|
86
|
+
const normalizedPath = (path || '/').replace(/\/+$/, '') || '/';
|
|
87
|
+
|
|
88
|
+
if (normalizedPath === b) {
|
|
89
|
+
return '/';
|
|
90
|
+
}
|
|
91
|
+
if (normalizedPath.startsWith(b + '/')) {
|
|
92
|
+
const rel = normalizedPath.slice(b.length);
|
|
93
|
+
return rel.replace(/\/+$/, '') || '/';
|
|
94
|
+
}
|
|
95
|
+
return normalizedPath;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Converts a relative path into an absolute path prefixed with base.
|
|
100
|
+
* Preserves query strings and hashes.
|
|
101
|
+
* e.g. with base '/spa':
|
|
102
|
+
* '/packages' -> '/spa/packages'
|
|
103
|
+
* '/' -> '/spa/'
|
|
104
|
+
* 'packages' -> '/spa/packages'
|
|
105
|
+
* '/spa/packages' -> '/spa/packages' (already prefixed)
|
|
106
|
+
*
|
|
107
|
+
* @param {string} relPath
|
|
108
|
+
* @param {string} [base]
|
|
109
|
+
* @returns {string}
|
|
110
|
+
*/
|
|
111
|
+
export function toAbsoluteUrl(relPath, base) {
|
|
112
|
+
const b = normalizeBase(base);
|
|
113
|
+
if (!b) return relPath || '/';
|
|
114
|
+
|
|
115
|
+
const str = relPath || '/';
|
|
116
|
+
const hashIdx = str.indexOf('#');
|
|
117
|
+
const pathAndQuery = hashIdx !== -1 ? str.slice(0, hashIdx) : str;
|
|
118
|
+
const hash = hashIdx !== -1 ? str.slice(hashIdx) : '';
|
|
119
|
+
|
|
120
|
+
const queryIdx = pathAndQuery.indexOf('?');
|
|
121
|
+
const pathname = queryIdx !== -1 ? pathAndQuery.slice(0, queryIdx) : pathAndQuery;
|
|
122
|
+
const queryString = queryIdx !== -1 ? pathAndQuery.slice(queryIdx) : '';
|
|
123
|
+
|
|
124
|
+
let absPath;
|
|
125
|
+
if (pathname === b) {
|
|
126
|
+
absPath = b + '/';
|
|
127
|
+
} else if (pathname.startsWith(b + '/')) {
|
|
128
|
+
absPath = pathname;
|
|
129
|
+
} else {
|
|
130
|
+
const cleanRel = pathname.startsWith('/') ? pathname : '/' + pathname;
|
|
131
|
+
absPath = cleanRel === '/' ? b + '/' : b + cleanRel;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return absPath + queryString + hash;
|
|
135
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(){"use strict";function $(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function _(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let o=null;for(let r=1;r<t.length;r++)if(t[r]&&t[r].nodeType===1){o=t[r];break}if(!_(o))return}e.apply(console,t)}}function U(e,t,n){const o=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,o),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:o}))}function A(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){A(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}const N={};function Q(e,t){N[e]=t}function J(e){return N[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=Q,window.lnCore.getDataMapper=J);function K(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,A(function(){new MutationObserver(function(){U(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const M={};function G(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];M[n]=t}function z(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return M[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=G,window.lnCore.getLocaleFallback=z,window.lnCore.ensureLocaleObserver=K);const v={};function B(e,t){v[e]||(v[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=v[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function X(e,t,n){if(e){const o=e.querySelector('[data-ln-template="'+t+'"]');if(o)return o.content.cloneNode(!0)}return B(t,n)}function S(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let l=0;l<n.length;l++){const a=n[l],c=a.getAttribute("data-ln-field");t[c]!=null&&(a.textContent=t[c])}const o=e.querySelectorAll("[data-ln-attr]");for(let l=0;l<o.length;l++){const a=o[l],c=a.getAttribute("data-ln-attr").split(",");for(let f=0;f<c.length;f++){const h=c[f].trim().split(":");if(h.length!==2)continue;const w=h[0].trim(),m=h[1].trim();t[m]!=null&&a.setAttribute(w,t[m])}}const r=e.querySelectorAll("[data-ln-show]");for(let l=0;l<r.length;l++){const a=r[l],c=a.getAttribute("data-ln-show");c in t&&a.classList.toggle("hidden",!t[c])}const i=e.querySelectorAll("[data-ln-class]");for(let l=0;l<i.length;l++){const a=i[l],c=a.getAttribute("data-ln-class").split(",");for(let f=0;f<c.length;f++){const h=c[f].trim().split(":");if(h.length!==2)continue;const w=h[0].trim(),m=h[1].trim();m in t&&a.classList.toggle(w,!!t[m])}}return e}function Y(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let o=0;o<n.length;o++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[o],t??null),n[o].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)S(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function F(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const i=n.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(l,a){return t[a]!==void 0?t[a]:""}))}const o=function(i,l){return t[l]!==void 0?t[l]:""},r=Array.from(e.querySelectorAll("*"));e.nodeType===1&&r.push(e);for(let i=0;i<r.length;i++){const l=r[i],a=l.attributes;for(let c=0;c<a.length;c++){const f=a[c];f.value.indexOf("{{")!==-1&&l.setAttribute(f.name,f.value.replace(/\{\{\s*(\w+)\s*\}\}/g,o))}}return e}function Z(e,t,n,o,r,i){const l={};for(let c=0;c<e.children.length;c++){const f=e.children[c],h=f.getAttribute("data-ln-render-key");h&&(l[h]=f)}const a=document.createDocumentFragment();for(let c=0;c<t.length;c++){const f=t[c],h=String(o(f));let w=l[h];if(w)r(w,f,c);else{const m=B(n,i);if(!m||(F(m,f),w=m.firstElementChild,!w))continue;w.setAttribute("data-ln-render-key",h),r(w,f,c)}a.appendChild(w)}e.textContent="",e.appendChild(a)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=F,window.lnCore.fill=S,window.lnCore.lnFill=Y,window.lnCore.renderList=Z);function R(e,t,n){const o=e.getAttribute(t);return o===null?n:o}function k(e,t,n){const o=parseInt(e.getAttribute(t),10);return isNaN(o)?n:o}function ee(e,t,n=!1){const o=e.getAttribute(t);if(o===null)return!!n;const r=o.trim().toLowerCase();return!(r==="false"||r==="0")}function te(e,t){return(e.getAttribute(t)||"").split(",").map(n=>n.trim()).filter(Boolean)}const E=new Map;function ne(e,t){const n=(e?e.join("|"):"")+"::"+t;if(E.has(n))return E.get(n);const o=new Set(e||[]),r=function(i,l){const a=i.getAttribute(l);return a!==null&&o.has(a)?a:t};return E.set(n,r),r}function oe(e,t,n){const o=parseFloat(e.getAttribute(t));return isNaN(o)?n:o}function re(e,t,n){const o=e.getAttribute(t);if(!o)return n;try{return JSON.parse(o)}catch{return n}}function j(e,t,n,o,r){if(!e||t===null)return!0;const i=o||"ln-component",l=e.type;if(l==="trigger"||l==="marker"||l==="string"||l==="list"||!l||t===""&&e.fallback!==void 0)return!0;const a=c=>{r?console.warn(c,r):console.warn(c)};if(l==="boolean"){const c=t.trim().toLowerCase();return c!==""&&c!=="true"&&c!=="false"&&c!=="1"&&c!=="0"?(a(`[${i}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(l==="enum"){const c=e.values||[];return c.includes(t)?!0:(a(`[${i}] Invalid value "${t}" for attribute "${n}". Allowed: ${c.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(l==="integer"){if(!/^-?\d+$/.test(t))return a(`[${i}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const c=parseInt(t,10);return e.min!==void 0&&c<e.min?(a(`[${i}] Value ${c} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&c>e.max?(a(`[${i}] Value ${c} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(l==="float")return isNaN(Number(t))?(a(`[${i}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(l==="json")try{return JSON.parse(t),!0}catch(c){return a(`[${i}] Invalid JSON for attribute "${n}": ${c.message}. Fallback: ${e.fallback}.`),!1}return!0}function ie(e,t,n){for(const o in n){const[r,i,l]=n[o];Object.defineProperty(e,o,{get:function(){return r(t,i,l)},enumerable:!0,configurable:!0})}return e}function le(e){const t={};for(const n in e){const o=e[n];if(!o||!o.prop)continue;let r=o.read;if(!r&&o.type)switch(o.type){case"enum":r=ne(o.values,o.fallback);break;case"integer":r=k;break;case"float":r=oe;break;case"boolean":r=ee;break;case"list":r=te;break;case"json":r=re;break;case"string":default:r=R;break}r||(r=R),t[o.prop]=[r,n,o.fallback]}return t}function se(e){const t={};for(const n in e){const o=e[n];o&&o.effect&&(t[n]=o.effect)}return Object.keys(t).length?t:null}function ae(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}function L(e,t,n,o){if(e.nodeType!==1)return;const i=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",l=Array.from(e.querySelectorAll(i));e.matches&&e.matches(i)&&l.push(e);for(const a of l)if(!a[n]){window.lnCore._persistSink&&a.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(a,t);try{a[n]=new o(a)}catch(c){console.error("["+n+"] init failed",a,c)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function ce(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function ue(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function W(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function de(e){const t=W(),n=e.observed||[];for(let o=0;o<n.length;o++){const r=n[o];t.byAttr.has(r)||t.byAttr.set(r,[]),t.byAttr.get(r).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const o in e.attributes){t.byDeclaredAttr.has(o)||t.byDeclaredAttr.set(o,[]);const r=t.byDeclaredAttr.get(o);r.some(i=>i.componentTag===e.componentTag)||r.push({spec:e.attributes[o],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const o=ae(e);if(o===null)t.reactiveWildcard.push(e);else for(const r of o)t.byReactive.has(r)||t.byReactive.set(r,[]),t.byReactive.get(r).push(e)}e.persist&&t.persist.push(e)}function H(e,t,n,o){for(let r=0;r<e.length;r++){const i=e[r];if(!t[i.attribute])continue;const l=i.effects&&i.effects[n];l?l(t,n,o):i.onAttrChange&&(!i.declared||i.declared.has(n))&&i.onAttrChange(t,n,o)}}function fe(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const o=W(),r=o.byAttr.get(n);if($()&&o.byDeclaredAttr&&o.byDeclaredAttr.has(n)&&_(t)){const i=o.byDeclaredAttr.get(n),l=t.getAttribute(n);for(let a=0;a<i.length;a++)j(i[a].spec,l,n,i[a].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||r)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const i=o.byReactive.get(n);i&&H(i,t,n,e.oldValue),o.reactiveWildcard.length&&H(o.reactiveWildcard,t,n,e.oldValue)}if(r)for(let i=0;i<r.length;i++){const l=r[i];if(l.handler){l.handler(t,n,e.oldValue);continue}l.onAttributeChange&&t[l.attribute]?l.onAttributeChange(t,n):(L(t,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(t))}}function we(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,A(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{fe(t[n])}catch(o){console.error("[ln-core] mutation handler failed",t[n].target,o)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function V(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function he(e){const t=V();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const o=t[n];if(o.onSubtreeChange){const r=o.query,i=e.target.nodeType===1?e.target.matches(r)?e.target:e.target.closest(r):e.target.parentElement?e.target.parentElement.closest(r):null;i&&o.onSubtreeChange(i,e)}}for(let n=0;n<e.addedNodes.length;n++){const o=e.addedNodes[n];if(o.nodeType===1)for(let r=0;r<t.length;r++){const i=t[r];L(o,i.selector,i.attribute,i.ComponentFn),i.onInit&&i.onInit(o)}}for(let n=0;n<e.removedNodes.length;n++){const o=e.removedNodes[n];if(o.nodeType===1)for(let r=0;r<t.length;r++){const i=t[r],l=i.query,a=Array.from(o.querySelectorAll(l));o.matches&&o.matches(l)&&a.push(o);for(let c=0;c<a.length;c++){const f=a[c];if(!document.contains(f)){const h=f[i.attribute];if(h&&typeof h.destroy=="function")try{h.destroy()}catch(w){console.error("["+i.attribute+"] destroy failed",f,w)}delete f[i.attribute]}}}}}}function pe(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,A(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const o=t[n];if(o.type==="childList")try{he(o)}catch(r){console.error("[ln-core] lifecycle handler failed",o.target,r)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function be(e,t,n,o,r={}){const i=r.extraAttributes||[],l=r.onAttributeChange||null,a=r.onSubtreeChange||null,c=r.onInit||null,f=r.onAttrChange||null,h=r.effects||null,w=r.attributes||null,m=w?se(w):h,O=w?new Set(Object.keys(w)):null,x=r.persist||null;function C(b){const g=b||document.body;if(L(g,e,t,n),w&&$())for(const y in w){const ke=w[y],q=Array.from(g.querySelectorAll("["+y+"]"));g.matches&&g.matches("["+y+"]")&&q.push(g);for(let I=0;I<q.length;I++){const D=q[I];_(D)&&j(ke,D.getAttribute(y),y,o,D)}}c&&c(g)}const s=[];if(e.indexOf("[")!==-1){const b=/\[([\w-]+)/g;let g;for(;(g=b.exec(e))!==null;)s.push(g[1])}else s.push(e);de({selector:e,attribute:t,componentTag:o,attributes:w,ComponentFn:n,onInit:c,observed:s.concat(i),onAttributeChange:l,onAttrChange:f,effects:m,declared:O,persist:x}),we();const d=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";V().push({selector:e,attribute:t,ComponentFn:n,onInit:c,onSubtreeChange:a,query:d}),pe(),window[t]=C;function p(){ce()>0?ue(function(){C(document.body)}):C(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",p):p(),C}function P(e){return(e||"").replace(/^#/,"")}function T(e){const t=e===void 0?location.hash:e,n={},o=P(t);if(!o)return n;const r=o.split("&");for(let i=0;i<r.length;i++){const l=r[i];if(!l)continue;const a=l.indexOf(":"),c=a>-1?l.slice(0,a):l,f=a>-1?l.slice(a+1):"";if(c)try{n[c]=decodeURIComponent(f)}catch{n[c]=f}}return n}function me(e){if(!e)return null;const t=T();return e in t?t[e]:null}function ge(e,t){if(!e)return;const n=T();t==null?delete n[e]:n[e]=String(t);const r=Object.keys(n).map(function(i){const l=n[i];return l===""?i:i+":"+encodeURIComponent(l)}).join("&");P(location.hash)!==r&&(location.hash=r)}function ye(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function Ce(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const o=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return o?t?o+"-"+t:o:t||null}function Ae(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function _e(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function ve(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function Se(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),o=e.slice(t+1),r=o?o.split(",").map(function(i){try{return decodeURIComponent(i)}catch{return i}}).filter(Boolean):[];return{key:n,values:r}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=T,window.lnCore.hashGet=me,window.lnCore.hashSet=ge,window.lnCore.hashLinkClick=ye,window.lnCore.resolveHashNamespace=Ce,window.lnCore.hashSortEncode=Ae,window.lnCore.hashSortDecode=_e,window.lnCore.hashFilterEncode=ve,window.lnCore.hashFilterDecode=Se),(function(){const e="data-ln-toast",t="lnToast",n="ln-toast-item";if(window[t]!==void 0)return;const o={"data-ln-toast":{type:"marker",description:"Initializes the toast notifications container"},"data-ln-toast-timeout":{prop:"timeoutDefault",type:"integer",read:k,fallback:6e3,min:500,description:"Default auto-dismiss timeout in ms"},"data-ln-toast-max":{prop:"max",type:"integer",read:k,fallback:5,min:1,description:"Maximum visible concurrent toast notifications"},"data-ln-toast-close":{type:"trigger",description:"Click dismiss trigger inside a toast item"},"data-ln-toast-item":{type:"marker",description:"Individual toast notification element"}},r=le(o);function i(s){if(!(!s||!(s instanceof HTMLElement))&&(s.hasAttribute("popover")||s.setAttribute("popover","manual"),typeof s.showPopover=="function")){if(s.matches(":popover-open"))try{s.hidePopover()}catch{}try{s.showPopover()}catch{}}}function l(s){if(!s||!(s instanceof HTMLElement))return;if(s.querySelectorAll("[data-ln-toast-item]").length===0&&typeof s.hidePopover=="function"&&s.matches(":popover-open"))try{s.hidePopover()}catch{}}function a(s){this.dom=s,ie(this,s,r);const u=Array.from(s.querySelectorAll("[data-ln-toast-item]"));for(;u.length>this.max;)s.removeChild(u.shift());for(const d of u)O(d,this);return u.length>0&&i(s),this}a.prototype.enqueue=function(s){if(!s)return;const u=c(s,this.dom);if(!u)return;const d=Number.isFinite(s.timeout)?s.timeout:this.timeoutDefault;h(this,u),d>0&&(u._timer=setTimeout(()=>w(u),d))},a.prototype.clear=function(){for(const s of Array.from(this.dom.querySelectorAll("[data-ln-toast-item]")))w(s)},a.prototype.destroy=function(){if(this.dom[t]){for(const s of Array.from(this.dom.querySelectorAll("[data-ln-toast-item]")))w(s);l(this.dom),delete this.dom[t]}};function c(s,u){const d=((s.type||"")+"").trim().toLowerCase(),p=X(u,n,"ln-toast");if(!p)return console.warn('[ln-toast] Template "'+n+'" not found'),null;S(p,{type:d,title:s.title,message:typeof s.message=="string"?s.message:void 0});const b=p.firstElementChild;if(!b)return null;b.hasAttribute("data-ln-toast-item")||b.setAttribute("data-ln-toast-item",""),b.classList.add("ln-enter");const g=b.querySelector(".body");g&&f(g,s);const y=b.querySelector("[data-ln-toast-close]");return y&&y.addEventListener("click",function(){w(b)}),b}function f(s,u){if(Array.isArray(u.message)){const d=document.createElement("ul");for(const p of u.message){const b=document.createElement("li");b.textContent=p,d.appendChild(b)}s.appendChild(d)}if(u.data&&u.data.errors){const d=document.createElement("ul");for(const p of Object.values(u.data.errors).flat()){const b=document.createElement("li");b.textContent=p,d.appendChild(b)}s.appendChild(d)}}function h(s,u){const d=Array.from(s.dom.querySelectorAll("[data-ln-toast-item]"));for(;d.length>=s.max&&d.length>0;)s.dom.removeChild(d.shift());s.dom.appendChild(u),i(s.dom),requestAnimationFrame(()=>u.classList.remove("ln-enter"))}function w(s){if(!s||!s.parentNode)return;const u=s.parentNode;clearTimeout(s._timer),s.classList.remove("ln-enter"),s.classList.add("ln-out"),setTimeout(()=>{s.parentNode&&(s.parentNode.removeChild(s),l(u))},200)}function m(s){let u=s&&s.container;return typeof u=="string"&&(u=document.querySelector(u)),u instanceof HTMLElement||(u=document.querySelector("["+e+"]")||document.getElementById("ln-toast-container")),u||null}function O(s,u){if(s._lnToastHydrated)return;s._lnToastHydrated=!0;const d=s.querySelector("[data-ln-toast-close]");d&&d.addEventListener("click",function(){w(s)});const p=+(s.getAttribute("data-ln-toast-timeout")??u.timeoutDefault);p>0&&(s._timer=setTimeout(function(){w(s)},p))}function x(s){const u=s.detail||{},d=m(u);if(!d){console.warn("[ln-toast] No toast container found");return}(d[t]||(d[t]=new a(d))).enqueue(u)}function C(s){const u=s&&s.detail||{};if(u.container){const d=m(u);d&&(d[t]||(d[t]=new a(d))).clear()}else{const d=document.querySelectorAll("["+e+"]");for(const p of Array.from(d))(p[t]||(p[t]=new a(p))).clear()}}A(function(){window.addEventListener("ln-toast:enqueue",x),window.addEventListener("ln-toast:clear",C),window.addEventListener("ln-modal:open",function(){const s=document.querySelectorAll("["+e+"]");for(const u of Array.from(s))u.querySelectorAll("[data-ln-toast-item]").length>0&&i(u)})},"ln-toast"),be(e,t,a,"ln-toast",{attributes:o})})()})();
|
|
1
|
+
(function(){"use strict";function $(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function _(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let o=null;for(let r=1;r<t.length;r++)if(t[r]&&t[r].nodeType===1){o=t[r];break}if(!_(o))return}e.apply(console,t)}}function U(e,t,n){const o=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,o),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:o}))}function A(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){A(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}const N={};function Q(e,t){N[e]=t}function J(e){return N[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=Q,window.lnCore.getDataMapper=J);function K(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,A(function(){new MutationObserver(function(){U(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const M={};function G(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];M[n]=t}function z(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return M[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=G,window.lnCore.getLocaleFallback=z,window.lnCore.ensureLocaleObserver=K);const v={};function B(e,t){v[e]||(v[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=v[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function X(e,t,n){if(e){const o=e.querySelector('[data-ln-template="'+t+'"]');if(o)return o.content.cloneNode(!0)}return B(t,n)}function S(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let l=0;l<n.length;l++){const a=n[l],c=a.getAttribute("data-ln-field");t[c]!=null&&(a.textContent=t[c])}const o=e.querySelectorAll("[data-ln-attr]");for(let l=0;l<o.length;l++){const a=o[l],c=a.getAttribute("data-ln-attr").split(",");for(let f=0;f<c.length;f++){const h=c[f].trim().split(":");if(h.length!==2)continue;const w=h[0].trim(),m=h[1].trim();t[m]!=null&&a.setAttribute(w,t[m])}}const r=e.querySelectorAll("[data-ln-show]");for(let l=0;l<r.length;l++){const a=r[l],c=a.getAttribute("data-ln-show");c in t&&a.classList.toggle("hidden",!t[c])}const i=e.querySelectorAll("[data-ln-class]");for(let l=0;l<i.length;l++){const a=i[l],c=a.getAttribute("data-ln-class").split(",");for(let f=0;f<c.length;f++){const h=c[f].trim().split(":");if(h.length!==2)continue;const w=h[0].trim(),m=h[1].trim();m in t&&a.classList.toggle(w,!!t[m])}}return e}function Y(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let o=0;o<n.length;o++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[o],t??null),n[o].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)S(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function F(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const i=n.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(l,a){return t[a]!==void 0?t[a]:""}))}const o=function(i,l){return t[l]!==void 0?t[l]:""},r=Array.from(e.querySelectorAll("*"));e.nodeType===1&&r.push(e);for(let i=0;i<r.length;i++){const l=r[i],a=l.attributes;for(let c=0;c<a.length;c++){const f=a[c];f.value.indexOf("{{")!==-1&&l.setAttribute(f.name,f.value.replace(/\{\{\s*(\w+)\s*\}\}/g,o))}}return e}function Z(e,t,n,o,r,i){const l={};for(let c=0;c<e.children.length;c++){const f=e.children[c],h=f.getAttribute("data-ln-render-key");h&&(l[h]=f)}const a=document.createDocumentFragment();for(let c=0;c<t.length;c++){const f=t[c],h=String(o(f));let w=l[h];if(w)r(w,f,c);else{const m=B(n,i);if(!m||(F(m,f),w=m.firstElementChild,!w))continue;w.setAttribute("data-ln-render-key",h),r(w,f,c)}a.appendChild(w)}e.textContent="",e.appendChild(a)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=F,window.lnCore.fill=S,window.lnCore.lnFill=Y,window.lnCore.renderList=Z);function R(e,t,n){const o=e.getAttribute(t);return o===null?n:o}function k(e,t,n){const o=parseInt(e.getAttribute(t),10);return isNaN(o)?n:o}function ee(e,t,n=!1){const o=e.getAttribute(t);if(o===null)return!!n;const r=o.trim().toLowerCase();return!(r==="false"||r==="0")}function te(e,t){return(e.getAttribute(t)||"").split(",").map(n=>n.trim()).filter(Boolean)}const E=new Map;function ne(e,t){const n=(e?e.join("|"):"")+"::"+t;if(E.has(n))return E.get(n);const o=new Set(e||[]),r=function(i,l){const a=i.getAttribute(l);return a!==null&&o.has(a)?a:t};return E.set(n,r),r}function oe(e,t,n){const o=parseFloat(e.getAttribute(t));return isNaN(o)?n:o}function re(e,t,n){const o=e.getAttribute(t);if(!o)return n;try{return JSON.parse(o)}catch{return n}}function j(e,t,n,o,r){if(!e||t===null)return!0;const i=o||"ln-component",l=e.type;if(l==="trigger"||l==="marker"||l==="string"||l==="list"||!l||t===""&&e.fallback!==void 0)return!0;const a=c=>{r?console.warn(c,r):console.warn(c)};if(l==="boolean"){const c=t.trim().toLowerCase();return c!==""&&c!=="true"&&c!=="false"&&c!=="1"&&c!=="0"?(a(`[${i}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(l==="enum"){const c=e.values||[];return c.includes(t)?!0:(a(`[${i}] Invalid value "${t}" for attribute "${n}". Allowed: ${c.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(l==="integer"){if(!/^-?\d+$/.test(t))return a(`[${i}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const c=parseInt(t,10);return e.min!==void 0&&c<e.min?(a(`[${i}] Value ${c} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&c>e.max?(a(`[${i}] Value ${c} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(l==="float")return isNaN(Number(t))?(a(`[${i}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(l==="json")try{return JSON.parse(t),!0}catch(c){return a(`[${i}] Invalid JSON for attribute "${n}": ${c.message}. Fallback: ${e.fallback}.`),!1}return!0}function ie(e,t,n){for(const o in n){const[r,i,l]=n[o];Object.defineProperty(e,o,{get:function(){return r(t,i,l)},enumerable:!0,configurable:!0})}return e}function le(e){const t={};for(const n in e){const o=e[n];if(!o||!o.prop)continue;let r=o.read;if(!r&&o.type)switch(o.type){case"enum":r=ne(o.values,o.fallback);break;case"integer":r=k;break;case"float":r=oe;break;case"boolean":r=ee;break;case"list":r=te;break;case"json":r=re;break;case"string":default:r=R;break}r||(r=R),t[o.prop]=[r,n,o.fallback]}return t}function se(e){const t={};for(const n in e){const o=e[n];o&&o.effect&&(t[n]=o.effect)}return Object.keys(t).length?t:null}function ae(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}function L(e,t,n,o){if(e.nodeType!==1)return;const i=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",l=Array.from(e.querySelectorAll(i));e.matches&&e.matches(i)&&l.push(e);for(const a of l)if(!a[n]){window.lnCore._persistSink&&a.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(a,t);try{a[n]=new o(a)}catch(c){console.error("["+n+"] init failed",a,c)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function ce(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function ue(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function W(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function de(e){const t=W(),n=e.observed||[];for(let o=0;o<n.length;o++){const r=n[o];t.byAttr.has(r)||t.byAttr.set(r,[]),t.byAttr.get(r).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const o in e.attributes){t.byDeclaredAttr.has(o)||t.byDeclaredAttr.set(o,[]);const r=t.byDeclaredAttr.get(o);r.some(i=>i.componentTag===e.componentTag)||r.push({spec:e.attributes[o],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const o=ae(e);if(o===null)t.reactiveWildcard.push(e);else for(const r of o)t.byReactive.has(r)||t.byReactive.set(r,[]),t.byReactive.get(r).push(e)}e.persist&&t.persist.push(e)}function H(e,t,n,o){for(let r=0;r<e.length;r++){const i=e[r];if(!t[i.attribute])continue;const l=i.effects&&i.effects[n];l?l(t,n,o):i.onAttrChange&&(!i.declared||i.declared.has(n))&&i.onAttrChange(t,n,o)}}function fe(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const o=W(),r=o.byAttr.get(n);if($()&&o.byDeclaredAttr&&o.byDeclaredAttr.has(n)&&_(t)){const i=o.byDeclaredAttr.get(n),l=t.getAttribute(n);for(let a=0;a<i.length;a++)j(i[a].spec,l,n,i[a].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||r)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const i=o.byReactive.get(n);i&&H(i,t,n,e.oldValue),o.reactiveWildcard.length&&H(o.reactiveWildcard,t,n,e.oldValue)}if(r)for(let i=0;i<r.length;i++){const l=r[i];if(l.handler){l.handler(t,n,e.oldValue);continue}l.onAttributeChange&&t[l.attribute]?l.onAttributeChange(t,n):(L(t,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(t))}}function we(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,A(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{fe(t[n])}catch(o){console.error("[ln-core] mutation handler failed",t[n].target,o)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function V(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function he(e){const t=V();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const o=t[n];if(o.onSubtreeChange){const r=o.query,i=e.target.nodeType===1?e.target.matches(r)?e.target:e.target.closest(r):e.target.parentElement?e.target.parentElement.closest(r):null;i&&o.onSubtreeChange(i,e)}}for(let n=0;n<e.addedNodes.length;n++){const o=e.addedNodes[n];if(o.nodeType===1)for(let r=0;r<t.length;r++){const i=t[r];L(o,i.selector,i.attribute,i.ComponentFn),i.onInit&&i.onInit(o)}}for(let n=0;n<e.removedNodes.length;n++){const o=e.removedNodes[n];if(o.nodeType===1)for(let r=0;r<t.length;r++){const i=t[r],l=i.query,a=Array.from(o.querySelectorAll(l));o.matches&&o.matches(l)&&a.push(o);for(let c=0;c<a.length;c++){const f=a[c];if(!document.contains(f)){const h=f[i.attribute];if(h&&typeof h.destroy=="function")try{h.destroy()}catch(w){console.error("["+i.attribute+"] destroy failed",f,w)}delete f[i.attribute]}}}}}}function pe(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,A(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const o=t[n];if(o.type==="childList")try{he(o)}catch(r){console.error("[ln-core] lifecycle handler failed",o.target,r)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function be(e,t,n,o,r={}){const i=r.extraAttributes||[],l=r.onAttributeChange||null,a=r.onSubtreeChange||null,c=r.onInit||null,f=r.onAttrChange||null,h=r.effects||null,w=r.attributes||null,m=w?se(w):h,O=w?new Set(Object.keys(w)):null,x=r.persist||null;function C(b){const g=b||document.body;if(L(g,e,t,n),w&&$())for(const y in w){const ke=w[y],q=Array.from(g.querySelectorAll("["+y+"]"));g.matches&&g.matches("["+y+"]")&&q.push(g);for(let I=0;I<q.length;I++){const D=q[I];_(D)&&j(ke,D.getAttribute(y),y,o,D)}}c&&c(g)}const s=[];if(e.indexOf("[")!==-1){const b=/\[([\w-]+)/g;let g;for(;(g=b.exec(e))!==null;)s.push(g[1])}else s.push(e);de({selector:e,attribute:t,componentTag:o,attributes:w,ComponentFn:n,onInit:c,observed:s.concat(i),onAttributeChange:l,onAttrChange:f,effects:m,declared:O,persist:x}),we();const d=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";V().push({selector:e,attribute:t,ComponentFn:n,onInit:c,onSubtreeChange:a,query:d}),pe(),window[t]=C;function p(){ce()>0?ue(function(){C(document.body)}):C(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",p):p(),C}function P(e){return(e||"").replace(/^#/,"")}function T(e){const t=e===void 0?location.hash:e,n={},o=P(t);if(!o)return n;const r=o.split("&");for(let i=0;i<r.length;i++){const l=r[i];if(!l)continue;const a=l.indexOf(":"),c=a>-1?l.slice(0,a):l,f=a>-1?l.slice(a+1):"";if(c)try{n[c]=decodeURIComponent(f)}catch{n[c]=f}}return n}function me(e){if(!e)return null;const t=T();return e in t?t[e]:null}function ge(e,t){if(!e)return;const n=T();t==null?delete n[e]:n[e]=String(t);const r=Object.keys(n).map(function(i){const l=n[i];return l===""?i:i+":"+encodeURIComponent(l)}).join("&");P(location.hash)!==r&&(location.hash=r)}function ye(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function Ce(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const o=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return o?t?o+"-"+t:o:t||null}function Ae(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function _e(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function ve(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function Se(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),o=e.slice(t+1),r=o?o.split(",").map(function(i){try{return decodeURIComponent(i)}catch{return i}}).filter(Boolean):[];return{key:n,values:r}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=T,window.lnCore.hashGet=me,window.lnCore.hashSet=ge,window.lnCore.hashLinkClick=ye,window.lnCore.resolveHashNamespace=Ce,window.lnCore.hashSortEncode=Ae,window.lnCore.hashSortDecode=_e,window.lnCore.hashFilterEncode=ve,window.lnCore.hashFilterDecode=Se),(function(){const e="data-ln-toast",t="lnToast",n="ln-toast-item";if(window[t]!==void 0)return;const o={"data-ln-toast":{type:"marker",description:"Initializes the toast notifications container"},"data-ln-toast-timeout":{prop:"timeoutDefault",type:"integer",read:k,fallback:6e3,min:500,description:"Default auto-dismiss timeout in ms"},"data-ln-toast-max":{prop:"max",type:"integer",read:k,fallback:5,min:1,description:"Maximum visible concurrent toast notifications"},"data-ln-toast-close":{type:"trigger",description:"Click dismiss trigger inside a toast item"},"data-ln-toast-item":{type:"marker",description:"Individual toast notification element"}},r=le(o);function i(s){if(!(!s||!(s instanceof HTMLElement))&&(s.hasAttribute("popover")||s.setAttribute("popover","manual"),typeof s.showPopover=="function")){if(s.matches(":popover-open"))try{s.hidePopover()}catch{}try{s.showPopover()}catch{}}}function l(s){if(!s||!(s instanceof HTMLElement))return;if(s.querySelectorAll("[data-ln-toast-item]").length===0&&typeof s.hidePopover=="function"&&s.matches(":popover-open"))try{s.hidePopover()}catch{}}function a(s){this.dom=s,ie(this,s,r);const u=Array.from(s.querySelectorAll("[data-ln-toast-item]"));for(;u.length>this.max;)s.removeChild(u.shift());for(const d of u)O(d,this);return u.length>0&&i(s),this}a.prototype.enqueue=function(s){if(!s)return;const u=c(s,this.dom);if(!u)return;const d=Number.isFinite(s.timeout)?s.timeout:this.timeoutDefault;h(this,u),d>0&&(u._timer=setTimeout(()=>w(u),d))},a.prototype.clear=function(){for(const s of Array.from(this.dom.querySelectorAll("[data-ln-toast-item]")))w(s)},a.prototype.destroy=function(){if(this.dom[t]){for(const s of Array.from(this.dom.querySelectorAll("[data-ln-toast-item]")))w(s);l(this.dom),delete this.dom[t]}};function c(s,u){const d=((s.type||"")+"").trim().toLowerCase(),p=X(u,n,"ln-toast");if(!p)return console.warn('[ln-toast] Template "'+n+'" not found'),null;S(p,{type:d,title:s.title,message:typeof s.message=="string"?s.message:void 0});const b=p.firstElementChild;if(!b)return null;b.hasAttribute("data-ln-toast-item")||b.setAttribute("data-ln-toast-item",""),b.classList.add("ln-enter");const g=b.querySelector(".body");g&&f(g,s);const y=b.querySelector("[data-ln-toast-close]");return y&&y.addEventListener("click",function(){w(b)}),b}function f(s,u){if(Array.isArray(u.message)){const d=document.createElement("ul");for(const p of u.message){const b=document.createElement("li");b.textContent=p,d.appendChild(b)}s.appendChild(d)}if(u.data&&u.data.errors){const d=document.createElement("ul");for(const p of Object.values(u.data.errors).flat()){const b=document.createElement("li");b.textContent=p,d.appendChild(b)}s.appendChild(d)}}function h(s,u){const d=Array.from(s.dom.querySelectorAll("[data-ln-toast-item]"));for(;d.length>=s.max&&d.length>0;)s.dom.removeChild(d.shift());s.dom.appendChild(u),i(s.dom),requestAnimationFrame(()=>u.classList.remove("ln-enter"))}function w(s){if(!s||!s.parentNode)return;const u=s.parentNode;clearTimeout(s._timer),s.classList.remove("ln-enter"),s.classList.add("ln-out"),setTimeout(()=>{s.parentNode&&(s.parentNode.removeChild(s),l(u))},200)}function m(s){let u=s&&s.container;return typeof u=="string"&&(u=document.querySelector(u)),u instanceof HTMLElement||(u=document.querySelector("["+e+"]")||document.getElementById("ln-toast-container")),u||null}function O(s,u){if(s._lnToastHydrated)return;s._lnToastHydrated=!0;const d=s.querySelector("[data-ln-toast-close]");d&&d.addEventListener("click",function(){w(s)});const p=+(s.getAttribute("data-ln-toast-timeout")??u.timeoutDefault);p>0&&(s._timer=setTimeout(function(){w(s)},p))}function x(s){const u=s.detail||{},d=m(u);if(!d){console.warn("[ln-toast] No toast container found");return}(d[t]||(d[t]=new a(d))).enqueue(u)}function C(s){const u=s&&s.detail||{};if(u.container){const d=m(u);d&&(d[t]||(d[t]=new a(d))).clear()}else{const d=document.querySelectorAll("["+e+"]");for(const p of Array.from(d))(p[t]||(p[t]=new a(p))).clear()}}A(function(){window.addEventListener("ln-toast:enqueue",x),window.addEventListener("ln-toast:clear",C),window.addEventListener("ln-modal:open",function(){const s=document.querySelectorAll("["+e+"], #ln-toast-container");for(const u of Array.from(s))u.querySelectorAll("[data-ln-toast-item]").length>0&&i(u)})},"ln-toast"),be(e,t,a,"ln-toast",{attributes:o})})()})();
|
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
// ==========================================================================
|
|
4
4
|
|
|
5
5
|
[data-ln-toast] {
|
|
6
|
+
position: fixed;
|
|
7
|
+
z-index: var(--z-toast, 50);
|
|
8
|
+
inset: auto;
|
|
9
|
+
right: var(--size-lg, 1.5rem);
|
|
10
|
+
bottom: var(--size-lg, 1.5rem);
|
|
6
11
|
border: none;
|
|
7
12
|
background: transparent;
|
|
8
|
-
inset: auto;
|
|
9
13
|
list-style: none;
|
|
10
14
|
padding: 0;
|
|
11
15
|
margin: 0;
|
|
@@ -218,7 +218,7 @@ import { guardBody, cloneTemplateScoped, fill, registerComponent, defineAttrs, a
|
|
|
218
218
|
window.addEventListener('ln-toast:enqueue', _onEnqueue);
|
|
219
219
|
window.addEventListener('ln-toast:clear', _onClear);
|
|
220
220
|
window.addEventListener('ln-modal:open', function () {
|
|
221
|
-
const containers = document.querySelectorAll("[" + DOM_SELECTOR + "]");
|
|
221
|
+
const containers = document.querySelectorAll("[" + DOM_SELECTOR + "], #ln-toast-container");
|
|
222
222
|
for (const container of Array.from(containers)) {
|
|
223
223
|
if (container.querySelectorAll("[data-ln-toast-item]").length > 0) {
|
|
224
224
|
_promoteTopLayer(container);
|
package/ln-ashlar.html-data.json
CHANGED
|
@@ -1054,6 +1054,10 @@
|
|
|
1054
1054
|
"name": "data-ln-route-title",
|
|
1055
1055
|
"description": "Document title template set when route is activated"
|
|
1056
1056
|
},
|
|
1057
|
+
{
|
|
1058
|
+
"name": "data-ln-router-base",
|
|
1059
|
+
"description": "Base URL prefix for subdirectory routing (e.g. "
|
|
1060
|
+
},
|
|
1057
1061
|
{
|
|
1058
1062
|
"name": "data-ln-router-hydrate",
|
|
1059
1063
|
"description": "Hydrate existing DOM content on initial router boot",
|
package/package.json
CHANGED
package/web-types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@livenetworks/ashlar",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.4",
|
|
5
5
|
"framework": "html",
|
|
6
6
|
"contributions": {
|
|
7
7
|
"html": {
|
|
@@ -1337,6 +1337,13 @@
|
|
|
1337
1337
|
"type": "string"
|
|
1338
1338
|
}
|
|
1339
1339
|
},
|
|
1340
|
+
{
|
|
1341
|
+
"name": "data-ln-router-base",
|
|
1342
|
+
"description": "Base URL prefix for subdirectory routing (e.g. ",
|
|
1343
|
+
"value": {
|
|
1344
|
+
"type": "string"
|
|
1345
|
+
}
|
|
1346
|
+
},
|
|
1340
1347
|
{
|
|
1341
1348
|
"name": "data-ln-router-hydrate",
|
|
1342
1349
|
"description": "Hydrate existing DOM content on initial router boot",
|