@livetemplate/client 0.1.0
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/README.md +179 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +19 -0
- package/dist/constants.js.map +1 -0
- package/dist/dom/directives.d.ts +13 -0
- package/dist/dom/directives.d.ts.map +1 -0
- package/dist/dom/directives.js +137 -0
- package/dist/dom/directives.js.map +1 -0
- package/dist/dom/event-delegation.d.ts +24 -0
- package/dist/dom/event-delegation.d.ts.map +1 -0
- package/dist/dom/event-delegation.js +437 -0
- package/dist/dom/event-delegation.js.map +1 -0
- package/dist/dom/focus-manager.d.ts +19 -0
- package/dist/dom/focus-manager.d.ts.map +1 -0
- package/dist/dom/focus-manager.js +144 -0
- package/dist/dom/focus-manager.js.map +1 -0
- package/dist/dom/form-disabler.d.ts +8 -0
- package/dist/dom/form-disabler.d.ts.map +1 -0
- package/dist/dom/form-disabler.js +32 -0
- package/dist/dom/form-disabler.js.map +1 -0
- package/dist/dom/loading-indicator.d.ts +9 -0
- package/dist/dom/loading-indicator.d.ts.map +1 -0
- package/dist/dom/loading-indicator.js +50 -0
- package/dist/dom/loading-indicator.js.map +1 -0
- package/dist/dom/modal-manager.d.ts +11 -0
- package/dist/dom/modal-manager.d.ts.map +1 -0
- package/dist/dom/modal-manager.js +62 -0
- package/dist/dom/modal-manager.js.map +1 -0
- package/dist/dom/observer-manager.d.ts +19 -0
- package/dist/dom/observer-manager.d.ts.map +1 -0
- package/dist/dom/observer-manager.js +64 -0
- package/dist/dom/observer-manager.js.map +1 -0
- package/dist/livetemplate-client.browser.js +44 -0
- package/dist/livetemplate-client.browser.js.map +7 -0
- package/dist/livetemplate-client.d.ts +106 -0
- package/dist/livetemplate-client.d.ts.map +1 -0
- package/dist/livetemplate-client.js +507 -0
- package/dist/livetemplate-client.js.map +1 -0
- package/dist/state/form-lifecycle-manager.d.ts +19 -0
- package/dist/state/form-lifecycle-manager.d.ts.map +1 -0
- package/dist/state/form-lifecycle-manager.js +64 -0
- package/dist/state/form-lifecycle-manager.js.map +1 -0
- package/dist/state/tree-renderer.d.ts +27 -0
- package/dist/state/tree-renderer.d.ts.map +1 -0
- package/dist/state/tree-renderer.js +359 -0
- package/dist/state/tree-renderer.js.map +1 -0
- package/dist/tests/event-delegation.test.d.ts +2 -0
- package/dist/tests/event-delegation.test.d.ts.map +1 -0
- package/dist/tests/event-delegation.test.js +102 -0
- package/dist/tests/event-delegation.test.js.map +1 -0
- package/dist/tests/focus-manager.test.d.ts +2 -0
- package/dist/tests/focus-manager.test.d.ts.map +1 -0
- package/dist/tests/focus-manager.test.js +45 -0
- package/dist/tests/focus-manager.test.js.map +1 -0
- package/dist/tests/form-disabler.test.d.ts +2 -0
- package/dist/tests/form-disabler.test.d.ts.map +1 -0
- package/dist/tests/form-disabler.test.js +35 -0
- package/dist/tests/form-disabler.test.js.map +1 -0
- package/dist/tests/form-lifecycle-manager.test.d.ts +2 -0
- package/dist/tests/form-lifecycle-manager.test.d.ts.map +1 -0
- package/dist/tests/form-lifecycle-manager.test.js +90 -0
- package/dist/tests/form-lifecycle-manager.test.js.map +1 -0
- package/dist/tests/modal-manager.test.d.ts +2 -0
- package/dist/tests/modal-manager.test.d.ts.map +1 -0
- package/dist/tests/modal-manager.test.js +80 -0
- package/dist/tests/modal-manager.test.js.map +1 -0
- package/dist/tests/rate-limit.test.d.ts +2 -0
- package/dist/tests/rate-limit.test.d.ts.map +1 -0
- package/dist/tests/rate-limit.test.js +38 -0
- package/dist/tests/rate-limit.test.js.map +1 -0
- package/dist/tests/test-conditional-debug.test.d.ts +8 -0
- package/dist/tests/test-conditional-debug.test.d.ts.map +1 -0
- package/dist/tests/test-conditional-debug.test.js +187 -0
- package/dist/tests/test-conditional-debug.test.js.map +1 -0
- package/dist/tests/test-reconstruction.test.d.ts +8 -0
- package/dist/tests/test-reconstruction.test.d.ts.map +1 -0
- package/dist/tests/test-reconstruction.test.js +284 -0
- package/dist/tests/test-reconstruction.test.js.map +1 -0
- package/dist/transport/websocket.d.ts +62 -0
- package/dist/transport/websocket.d.ts.map +1 -0
- package/dist/transport/websocket.js +194 -0
- package/dist/transport/websocket.js.map +1 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/logger.d.ts +32 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +77 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/rate-limit.d.ts +10 -0
- package/dist/utils/rate-limit.d.ts.map +1 -0
- package/dist/utils/rate-limit.js +37 -0
- package/dist/utils/rate-limit.js.map +1 -0
- package/dist/utils/testing.d.ts +14 -0
- package/dist/utils/testing.d.ts.map +1 -0
- package/dist/utils/testing.js +51 -0
- package/dist/utils/testing.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-disabler.d.ts","sourceRoot":"","sources":["../../dom/form-disabler.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI;IAYtC,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI;CAWtC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FormDisabler = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Enables and disables all form controls inside the LiveTemplate wrapper.
|
|
6
|
+
*/
|
|
7
|
+
class FormDisabler {
|
|
8
|
+
disable(wrapper) {
|
|
9
|
+
if (!wrapper)
|
|
10
|
+
return;
|
|
11
|
+
const forms = wrapper.querySelectorAll("form");
|
|
12
|
+
forms.forEach((form) => {
|
|
13
|
+
const inputs = form.querySelectorAll("input, textarea, select, button");
|
|
14
|
+
inputs.forEach((input) => {
|
|
15
|
+
input.disabled = true;
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
enable(wrapper) {
|
|
20
|
+
if (!wrapper)
|
|
21
|
+
return;
|
|
22
|
+
const forms = wrapper.querySelectorAll("form");
|
|
23
|
+
forms.forEach((form) => {
|
|
24
|
+
const inputs = form.querySelectorAll("input, textarea, select, button");
|
|
25
|
+
inputs.forEach((input) => {
|
|
26
|
+
input.disabled = false;
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.FormDisabler = FormDisabler;
|
|
32
|
+
//# sourceMappingURL=form-disabler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-disabler.js","sourceRoot":"","sources":["../../dom/form-disabler.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,YAAY;IACvB,OAAO,CAAC,OAAuB;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,iCAAiC,CAAC,CAAC;YACxE,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACtB,KAA0B,CAAC,QAAQ,GAAG,IAAI,CAAC;YAC9C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,OAAuB;QAC5B,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,iCAAiC,CAAC,CAAC;YACxE,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACtB,KAA0B,CAAC,QAAQ,GAAG,KAAK,CAAC;YAC/C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAxBD,oCAwBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loading-indicator.d.ts","sourceRoot":"","sources":["../../dom/loading-indicator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAA4B;IAEvC,IAAI,IAAI,IAAI;IAgCZ,IAAI,IAAI,IAAI;CAQb"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LoadingIndicator = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Handles showing and hiding the global LiveTemplate loading indicator.
|
|
6
|
+
*/
|
|
7
|
+
class LoadingIndicator {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.bar = null;
|
|
10
|
+
}
|
|
11
|
+
show() {
|
|
12
|
+
if (this.bar)
|
|
13
|
+
return;
|
|
14
|
+
const bar = document.createElement("div");
|
|
15
|
+
bar.style.cssText = `
|
|
16
|
+
position: fixed;
|
|
17
|
+
top: 0;
|
|
18
|
+
left: 0;
|
|
19
|
+
right: 0;
|
|
20
|
+
height: 3px;
|
|
21
|
+
background: linear-gradient(90deg, #3b82f6 0%, #60a5fa 50%, #3b82f6 100%);
|
|
22
|
+
background-size: 200% 100%;
|
|
23
|
+
z-index: 9999;
|
|
24
|
+
animation: lvt-loading-shimmer 1.5s ease-in-out infinite;
|
|
25
|
+
`;
|
|
26
|
+
if (!document.getElementById("lvt-loading-styles")) {
|
|
27
|
+
const style = document.createElement("style");
|
|
28
|
+
style.id = "lvt-loading-styles";
|
|
29
|
+
style.textContent = `
|
|
30
|
+
@keyframes lvt-loading-shimmer {
|
|
31
|
+
0% { background-position: 200% 0; }
|
|
32
|
+
100% { background-position: -200% 0; }
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
document.head.appendChild(style);
|
|
36
|
+
}
|
|
37
|
+
document.body.insertBefore(bar, document.body.firstChild);
|
|
38
|
+
this.bar = bar;
|
|
39
|
+
}
|
|
40
|
+
hide() {
|
|
41
|
+
if (!this.bar)
|
|
42
|
+
return;
|
|
43
|
+
if (this.bar.parentNode) {
|
|
44
|
+
this.bar.parentNode.removeChild(this.bar);
|
|
45
|
+
}
|
|
46
|
+
this.bar = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.LoadingIndicator = LoadingIndicator;
|
|
50
|
+
//# sourceMappingURL=loading-indicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loading-indicator.js","sourceRoot":"","sources":["../../dom/loading-indicator.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,gBAAgB;IAA7B;QACU,QAAG,GAAuB,IAAI,CAAC;IA0CzC,CAAC;IAxCC,IAAI;QACF,IAAI,IAAI,CAAC,GAAG;YAAE,OAAO;QAErB,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1C,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG;;;;;;;;;;KAUnB,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAC9C,KAAK,CAAC,EAAE,GAAG,oBAAoB,CAAC;YAChC,KAAK,CAAC,WAAW,GAAG;;;;;OAKnB,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,OAAO;QAEtB,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;IAClB,CAAC;CACF;AA3CD,4CA2CC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Logger } from "../utils/logger";
|
|
2
|
+
/**
|
|
3
|
+
* Manages client-side modal interactions for LiveTemplate.
|
|
4
|
+
*/
|
|
5
|
+
export declare class ModalManager {
|
|
6
|
+
private readonly logger;
|
|
7
|
+
constructor(logger: Logger);
|
|
8
|
+
open(modalId: string): void;
|
|
9
|
+
close(modalId: string): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=modal-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal-manager.d.ts","sourceRoot":"","sources":["../../dom/modal-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;GAEG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAE3C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAiD3B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAc7B"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModalManager = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Manages client-side modal interactions for LiveTemplate.
|
|
6
|
+
*/
|
|
7
|
+
class ModalManager {
|
|
8
|
+
constructor(logger) {
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
}
|
|
11
|
+
open(modalId) {
|
|
12
|
+
const modal = document.getElementById(modalId);
|
|
13
|
+
if (!modal) {
|
|
14
|
+
this.logger.warn(`Modal with id="${modalId}" not found`);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
modal.removeAttribute("hidden");
|
|
18
|
+
modal.style.display = "flex";
|
|
19
|
+
modal.setAttribute("aria-hidden", "false");
|
|
20
|
+
modal.dispatchEvent(new CustomEvent("lvt:modal-opened", { bubbles: true }));
|
|
21
|
+
this.logger.info(`Opened modal: ${modalId}`);
|
|
22
|
+
const firstInput = modal.querySelector("input, textarea, select");
|
|
23
|
+
if (firstInput) {
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
const activeElement = document.activeElement;
|
|
26
|
+
const isVisible = (element) => {
|
|
27
|
+
if (!element) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (element === document.body) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
// Use offsetParent and bounding rects to determine visibility without hitting layout too hard.
|
|
34
|
+
if (element.offsetParent !== null) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return element.getClientRects().length > 0;
|
|
38
|
+
};
|
|
39
|
+
const shouldMoveFocus = !activeElement ||
|
|
40
|
+
!modal.contains(activeElement) ||
|
|
41
|
+
!isVisible(activeElement);
|
|
42
|
+
if (shouldMoveFocus) {
|
|
43
|
+
firstInput.focus();
|
|
44
|
+
}
|
|
45
|
+
}, 100);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
close(modalId) {
|
|
49
|
+
const modal = document.getElementById(modalId);
|
|
50
|
+
if (!modal) {
|
|
51
|
+
this.logger.warn(`Modal with id="${modalId}" not found`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
modal.setAttribute("hidden", "");
|
|
55
|
+
modal.style.display = "none";
|
|
56
|
+
modal.setAttribute("aria-hidden", "true");
|
|
57
|
+
modal.dispatchEvent(new CustomEvent("lvt:modal-closed", { bubbles: true }));
|
|
58
|
+
this.logger.info(`Closed modal: ${modalId}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.ModalManager = ModalManager;
|
|
62
|
+
//# sourceMappingURL=modal-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal-manager.js","sourceRoot":"","sources":["../../dom/modal-manager.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,MAAa,YAAY;IACvB,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAE/C,IAAI,CAAC,OAAe;QAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,OAAO,aAAa,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAChC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC7B,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC3C,KAAK,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;QAE7C,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CACpC,yBAAyB,CACJ,CAAC;QACxB,IAAI,UAAU,EAAE,CAAC;YACf,UAAU,CAAC,GAAG,EAAE;gBACd,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAmC,CAAC;gBACnE,MAAM,SAAS,GAAG,CAAC,OAA2B,EAAW,EAAE;oBACzD,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,OAAO,KAAK,CAAC;oBACf,CAAC;oBAED,IAAI,OAAO,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;wBAC9B,OAAO,IAAI,CAAC;oBACd,CAAC;oBAED,+FAA+F;oBAC/F,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;wBAClC,OAAO,IAAI,CAAC;oBACd,CAAC;oBAED,OAAO,OAAO,CAAC,cAAc,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC7C,CAAC,CAAC;gBAEF,MAAM,eAAe,GACnB,CAAC,aAAa;oBACd,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC;oBAC9B,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;gBAE5B,IAAI,eAAe,EAAE,CAAC;oBACpB,UAAU,CAAC,KAAK,EAAE,CAAC;gBACrB,CAAC;YACH,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAe;QACnB,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,OAAO,aAAa,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACjC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC7B,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC1C,KAAK,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC;CACF;AAlED,oCAkEC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Logger } from "../utils/logger";
|
|
2
|
+
export interface ObserverContext {
|
|
3
|
+
getWrapperElement(): Element | null;
|
|
4
|
+
send(message: any): void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Manages LiveTemplate observers such as infinite scroll and DOM mutations.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ObserverManager {
|
|
10
|
+
private readonly context;
|
|
11
|
+
private readonly logger;
|
|
12
|
+
private infiniteScrollObserver;
|
|
13
|
+
private mutationObserver;
|
|
14
|
+
constructor(context: ObserverContext, logger: Logger);
|
|
15
|
+
setupInfiniteScrollObserver(): void;
|
|
16
|
+
setupInfiniteScrollMutationObserver(): void;
|
|
17
|
+
teardown(): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=observer-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer-manager.d.ts","sourceRoot":"","sources":["../../dom/observer-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,iBAAiB,IAAI,OAAO,GAAG,IAAI,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,eAAe;IAKxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,sBAAsB,CAAqC;IACnE,OAAO,CAAC,gBAAgB,CAAiC;gBAGtC,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,MAAM;IAGjC,2BAA2B,IAAI,IAAI;IA6BnC,mCAAmC,IAAI,IAAI;IAoB3C,QAAQ,IAAI,IAAI;CAUjB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ObserverManager = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Manages LiveTemplate observers such as infinite scroll and DOM mutations.
|
|
6
|
+
*/
|
|
7
|
+
class ObserverManager {
|
|
8
|
+
constructor(context, logger) {
|
|
9
|
+
this.context = context;
|
|
10
|
+
this.logger = logger;
|
|
11
|
+
this.infiniteScrollObserver = null;
|
|
12
|
+
this.mutationObserver = null;
|
|
13
|
+
}
|
|
14
|
+
setupInfiniteScrollObserver() {
|
|
15
|
+
const wrapperElement = this.context.getWrapperElement();
|
|
16
|
+
if (!wrapperElement)
|
|
17
|
+
return;
|
|
18
|
+
const sentinel = document.getElementById("scroll-sentinel");
|
|
19
|
+
if (!sentinel) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (this.infiniteScrollObserver) {
|
|
23
|
+
this.infiniteScrollObserver.disconnect();
|
|
24
|
+
}
|
|
25
|
+
this.infiniteScrollObserver = new IntersectionObserver((entries) => {
|
|
26
|
+
if (entries[0].isIntersecting) {
|
|
27
|
+
this.logger.debug("Sentinel visible, sending load_more action");
|
|
28
|
+
this.context.send({ action: "load_more" });
|
|
29
|
+
}
|
|
30
|
+
}, {
|
|
31
|
+
rootMargin: "200px",
|
|
32
|
+
});
|
|
33
|
+
this.infiniteScrollObserver.observe(sentinel);
|
|
34
|
+
this.logger.debug("Observer set up successfully");
|
|
35
|
+
}
|
|
36
|
+
setupInfiniteScrollMutationObserver() {
|
|
37
|
+
const wrapperElement = this.context.getWrapperElement();
|
|
38
|
+
if (!wrapperElement)
|
|
39
|
+
return;
|
|
40
|
+
if (this.mutationObserver) {
|
|
41
|
+
this.mutationObserver.disconnect();
|
|
42
|
+
}
|
|
43
|
+
this.mutationObserver = new MutationObserver(() => {
|
|
44
|
+
this.setupInfiniteScrollObserver();
|
|
45
|
+
});
|
|
46
|
+
this.mutationObserver.observe(wrapperElement, {
|
|
47
|
+
childList: true,
|
|
48
|
+
subtree: true,
|
|
49
|
+
});
|
|
50
|
+
this.logger.debug("MutationObserver set up successfully");
|
|
51
|
+
}
|
|
52
|
+
teardown() {
|
|
53
|
+
if (this.infiniteScrollObserver) {
|
|
54
|
+
this.infiniteScrollObserver.disconnect();
|
|
55
|
+
this.infiniteScrollObserver = null;
|
|
56
|
+
}
|
|
57
|
+
if (this.mutationObserver) {
|
|
58
|
+
this.mutationObserver.disconnect();
|
|
59
|
+
this.mutationObserver = null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.ObserverManager = ObserverManager;
|
|
64
|
+
//# sourceMappingURL=observer-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer-manager.js","sourceRoot":"","sources":["../../dom/observer-manager.ts"],"names":[],"mappings":";;;AAOA;;GAEG;AACH,MAAa,eAAe;IAI1B,YACmB,OAAwB,EACxB,MAAc;QADd,YAAO,GAAP,OAAO,CAAiB;QACxB,WAAM,GAAN,MAAM,CAAQ;QALzB,2BAAsB,GAAgC,IAAI,CAAC;QAC3D,qBAAgB,GAA4B,IAAI,CAAC;IAKtD,CAAC;IAEJ,2BAA2B;QACzB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACxD,IAAI,CAAC,cAAc;YAAE,OAAO;QAE5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,sBAAsB,GAAG,IAAI,oBAAoB,CACpD,CAAC,OAAO,EAAE,EAAE;YACV,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;gBAChE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC,EACD;YACE,UAAU,EAAE,OAAO;SACpB,CACF,CAAC;QAEF,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACpD,CAAC;IAED,mCAAmC;QACjC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACxD,IAAI,CAAC,cAAc;YAAE,OAAO;QAE5B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC;QACrC,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE;YAChD,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,cAAc,EAAE;YAC5C,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC5D,CAAC;IAED,QAAQ;QACN,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,CAAC;YACzC,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QACrC,CAAC;QACD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;IACH,CAAC;CACF;AApED,0CAoEC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";var LiveTemplateClient=(()=>{var se=Object.defineProperty;var Fe=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var Re=Object.prototype.hasOwnProperty;var _e=(a,e)=>{for(var t in e)se(a,t,{get:e[t],enumerable:!0})},De=(a,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Oe(e))!Re.call(a,n)&&n!==t&&se(a,n,{get:()=>e[n],enumerable:!(r=Fe(e,n))||r.enumerable});return a};var Ie=a=>De(se({},"__esModule",{value:!0}),a);var Xe={};_e(Xe,{LiveTemplateClient:()=>te,compareHTML:()=>Me,loadAndApplyUpdate:()=>Le});var fe=11;function He(a,e){var t=e.attributes,r,n,i,o,s;if(!(e.nodeType===fe||a.nodeType===fe)){for(var l=t.length-1;l>=0;l--)r=t[l],n=r.name,i=r.namespaceURI,o=r.value,i?(n=r.localName||n,s=a.getAttributeNS(i,n),s!==o&&(r.prefix==="xmlns"&&(n=r.name),a.setAttributeNS(i,n,o))):(s=a.getAttribute(n),s!==o&&a.setAttribute(n,o));for(var c=a.attributes,d=c.length-1;d>=0;d--)r=c[d],n=r.name,i=r.namespaceURI,i?(n=r.localName||n,e.hasAttributeNS(i,n)||a.removeAttributeNS(i,n)):e.hasAttribute(n)||a.removeAttribute(n)}}var P,We="http://www.w3.org/1999/xhtml",_=typeof document=="undefined"?void 0:document,Ce=!!_&&"content"in _.createElement("template"),Ne=!!_&&_.createRange&&"createContextualFragment"in _.createRange();function Ue(a){var e=_.createElement("template");return e.innerHTML=a,e.content.childNodes[0]}function $e(a){P||(P=_.createRange(),P.selectNode(_.body));var e=P.createContextualFragment(a);return e.childNodes[0]}function Be(a){var e=_.createElement("body");return e.innerHTML=a,e.childNodes[0]}function Ve(a){return a=a.trim(),Ce?Ue(a):Ne?$e(a):Be(a)}function j(a,e){var t=a.nodeName,r=e.nodeName,n,i;return t===r?!0:(n=t.charCodeAt(0),i=r.charCodeAt(0),n<=90&&i>=97?t===r.toUpperCase():i<=90&&n>=97?r===t.toUpperCase():!1)}function Ke(a,e){return!e||e===We?_.createElement(a):_.createElementNS(e,a)}function Pe(a,e){for(var t=a.firstChild;t;){var r=t.nextSibling;e.appendChild(t),t=r}return e}function ae(a,e,t){a[t]!==e[t]&&(a[t]=e[t],a[t]?a.setAttribute(t,""):a.removeAttribute(t))}var me={OPTION:function(a,e){var t=a.parentNode;if(t){var r=t.nodeName.toUpperCase();r==="OPTGROUP"&&(t=t.parentNode,r=t&&t.nodeName.toUpperCase()),r==="SELECT"&&!t.hasAttribute("multiple")&&(a.hasAttribute("selected")&&!e.selected&&(a.setAttribute("selected","selected"),a.removeAttribute("selected")),t.selectedIndex=-1)}ae(a,e,"selected")},INPUT:function(a,e){ae(a,e,"checked"),ae(a,e,"disabled"),a.value!==e.value&&(a.value=e.value),e.hasAttribute("value")||a.removeAttribute("value")},TEXTAREA:function(a,e){var t=e.value;a.value!==t&&(a.value=t);var r=a.firstChild;if(r){var n=r.nodeValue;if(n==t||!t&&n==a.placeholder)return;r.nodeValue=t}},SELECT:function(a,e){if(!e.hasAttribute("multiple")){for(var t=-1,r=0,n=a.firstChild,i,o;n;)if(o=n.nodeName&&n.nodeName.toUpperCase(),o==="OPTGROUP")i=n,n=i.firstChild,n||(n=i.nextSibling,i=null);else{if(o==="OPTION"){if(n.hasAttribute("selected")){t=r;break}r++}n=n.nextSibling,!n&&i&&(n=i.nextSibling,i=null)}a.selectedIndex=t}}},$=1,ve=11,be=3,ye=8;function W(){}function je(a){if(a)return a.getAttribute&&a.getAttribute("id")||a.id}function qe(a){return function(t,r,n){if(n||(n={}),typeof r=="string")if(t.nodeName==="#document"||t.nodeName==="HTML"||t.nodeName==="BODY"){var i=r;r=_.createElement("html"),r.innerHTML=i}else r=Ve(r);else r.nodeType===ve&&(r=r.firstElementChild);var o=n.getNodeKey||je,s=n.onBeforeNodeAdded||W,l=n.onNodeAdded||W,c=n.onBeforeElUpdated||W,d=n.onElUpdated||W,A=n.onBeforeNodeDiscarded||W,m=n.onNodeDiscarded||W,f=n.onBeforeElChildrenUpdated||W,F=n.skipFromChildren||W,M=n.addChild||function(g,p){return g.appendChild(p)},b=n.childrenOnly===!0,h=Object.create(null),u=[];function y(g){u.push(g)}function O(g,p){if(g.nodeType===$)for(var T=g.firstChild;T;){var v=void 0;p&&(v=o(T))?y(v):(m(T),T.firstChild&&O(T,p)),T=T.nextSibling}}function x(g,p,T){A(g)!==!1&&(p&&p.removeChild(g),m(g),O(g,T))}function w(g){if(g.nodeType===$||g.nodeType===ve)for(var p=g.firstChild;p;){var T=o(p);T&&(h[T]=p),w(p),p=p.nextSibling}}w(t);function S(g){l(g);for(var p=g.firstChild;p;){var T=p.nextSibling,v=o(p);if(v){var E=h[v];E&&j(p,E)?(p.parentNode.replaceChild(E,p),R(E,p)):S(p)}else S(p);p=T}}function k(g,p,T){for(;p;){var v=p.nextSibling;(T=o(p))?y(T):x(p,g,!0),p=v}}function R(g,p,T){var v=o(p);if(v&&delete h[v],!T){var E=c(g,p);if(E===!1||(E instanceof HTMLElement&&(g=E,w(g)),a(g,p),d(g),f(g,p)===!1))return}g.nodeName!=="TEXTAREA"?C(g,p):me.TEXTAREA(g,p)}function C(g,p){var T=F(g,p),v=p.firstChild,E=g.firstChild,N,D,U,V,I;e:for(;v;){for(V=v.nextSibling,N=o(v);!T&&E;){if(U=E.nextSibling,v.isSameNode&&v.isSameNode(E)){v=V,E=U;continue e}D=o(E);var K=E.nodeType,H=void 0;if(K===v.nodeType&&(K===$?(N?N!==D&&((I=h[N])?U===I?H=!1:(g.insertBefore(I,E),D?y(D):x(E,g,!0),E=I,D=o(E)):H=!1):D&&(H=!1),H=H!==!1&&j(E,v),H&&R(E,v)):(K===be||K==ye)&&(H=!0,E.nodeValue!==v.nodeValue&&(E.nodeValue=v.nodeValue))),H){v=V,E=U;continue e}D?y(D):x(E,g,!0),E=U}if(N&&(I=h[N])&&j(I,v))T||M(g,I),R(I,v);else{var ie=s(v);ie!==!1&&(ie&&(v=ie),v.actualize&&(v=v.actualize(g.ownerDocument||_)),M(g,v),S(v))}v=V,E=U}k(g,E,D);var he=me[g.nodeName];he&&he(g,p)}var L=t,B=L.nodeType,pe=r.nodeType;if(!b){if(B===$)pe===$?j(t,r)||(m(t),L=Pe(t,Ke(r.nodeName,r.namespaceURI))):L=r;else if(B===be||B===ye){if(pe===B)return L.nodeValue!==r.nodeValue&&(L.nodeValue=r.nodeValue),L;L=r}}if(L===r)m(t);else{if(r.isSameNode&&r.isSameNode(L))return;if(R(L,r,b),u)for(var ne=0,xe=u.length;ne<xe;ne++){var re=h[u[ne]];re&&x(re,re.parentNode,!1)}}return!b&&L!==t&&t.parentNode&&(L.actualize&&(L=L.actualize(t.ownerDocument||_)),t.parentNode.replaceChild(L,t)),L}}var ze=qe(He),Ee=ze;var oe=["text","textarea","number","email","password","search","tel","url","date","time","datetime-local","color","range"];var q=class{constructor(e){this.logger=e;this.wrapperElement=null;this.focusableElements=[];this.lastFocusedElement=null;this.lastFocusedSelectionStart=null;this.lastFocusedSelectionEnd=null}attach(e){this.wrapperElement=e,e&&(this.updateFocusableElements(),this.setupFocusTracking())}reset(){this.wrapperElement=null,this.focusableElements=[],this.lastFocusedElement=null,this.lastFocusedSelectionStart=null,this.lastFocusedSelectionEnd=null}updateFocusableElements(){if(!this.wrapperElement)return;let r=`${oe.map(n=>n==="textarea"?"textarea:not([disabled])":`input[type="${n}"]:not([disabled])`).join(", ")}, select:not([disabled]), button:not([disabled]), [contenteditable="true"], [tabindex]:not([tabindex="-1"])`;this.focusableElements=Array.from(this.wrapperElement.querySelectorAll(r))}setupFocusTracking(){if(!this.wrapperElement)return;let e=this.wrapperElement.getAttribute("data-lvt-id"),t=`__lvt_focus_tracker_${e}`,r=`__lvt_blur_tracker_${e}`,n=o=>{var l;let s=o.target;!s||!((l=this.wrapperElement)!=null&&l.contains(s))||(this.isTextualInput(s)||s instanceof HTMLSelectElement)&&(this.lastFocusedElement=s,this.logger.debug("[Focus] Tracked focus on:",s.tagName,s.id||s.getAttribute("name")),this.isTextualInput(s)&&(this.lastFocusedSelectionStart=s.selectionStart,this.lastFocusedSelectionEnd=s.selectionEnd))},i=o=>{var l;let s=o.target;!s||!((l=this.wrapperElement)!=null&&l.contains(s))||this.isTextualInput(s)&&s===this.lastFocusedElement&&(this.lastFocusedSelectionStart=s.selectionStart,this.lastFocusedSelectionEnd=s.selectionEnd,this.logger.debug("[Focus] Saved cursor on blur:",this.lastFocusedSelectionStart,"-",this.lastFocusedSelectionEnd))};document[t]&&document.removeEventListener("focus",document[t],!0),document[r]&&document.removeEventListener("blur",document[r],!0),document[t]=n,document[r]=i,document.addEventListener("focus",n,!0),document.addEventListener("blur",i,!0),this.logger.debug("[Focus] Focus tracking set up")}restoreFocusedElement(){var n,i,o;if(this.logger.debug("[Focus] restoreFocusedElement - lastFocusedElement:",(n=this.lastFocusedElement)==null?void 0:n.tagName,((i=this.lastFocusedElement)==null?void 0:i.id)||((o=this.lastFocusedElement)==null?void 0:o.getAttribute("name"))),!this.lastFocusedElement||!this.wrapperElement){this.logger.debug("[Focus] No element to restore");return}let e=this.getElementSelector(this.lastFocusedElement);if(this.logger.debug("[Focus] Selector for last focused:",e),!e){this.logger.debug("[Focus] Could not generate selector");return}let t=null;if(e.startsWith("data-focus-index-")){this.updateFocusableElements();let s=parseInt(e.replace("data-focus-index-",""),10);t=this.focusableElements[s]||null,this.logger.debug("[Focus] Found by index:",s,t==null?void 0:t.tagName)}else t=this.wrapperElement.querySelector(e),this.logger.debug("[Focus] Found by selector:",e,t==null?void 0:t.tagName);if(!t){this.logger.debug("[Focus] Element not found in updated DOM");return}let r=t.matches(":focus");this.logger.debug("[Focus] Already focused:",r),r||(t.focus(),this.logger.debug("[Focus] Restored focus")),this.isTextualInput(t)&&this.lastFocusedSelectionStart!==null&&this.lastFocusedSelectionEnd!==null&&(t.setSelectionRange(this.lastFocusedSelectionStart,this.lastFocusedSelectionEnd),this.logger.debug("[Focus] Restored cursor:",this.lastFocusedSelectionStart,"-",this.lastFocusedSelectionEnd))}isTextualInput(e){return e instanceof HTMLTextAreaElement?!0:e instanceof HTMLInputElement?oe.indexOf(e.type)>=0:!1}getLastFocusedElement(){return this.lastFocusedElement}getElementSelector(e){if(e.id)return`#${e.id}`;if(e.name)return`[name="${e.name}"]`;if(e.getAttribute("data-key"))return`[data-key="${e.getAttribute("data-key")}"]`;let t=this.focusableElements.indexOf(e);return t>=0?`data-focus-index-${t}`:null}};function we(a){a.querySelectorAll("[lvt-scroll]").forEach(t=>{let r=t,n=r.getAttribute("lvt-scroll"),i=r.getAttribute("lvt-scroll-behavior")||"auto",o=parseInt(r.getAttribute("lvt-scroll-threshold")||"100",10);if(n)switch(n){case"bottom":r.scrollTo({top:r.scrollHeight,behavior:i});break;case"bottom-sticky":{r.scrollHeight-r.scrollTop-r.clientHeight<=o&&r.scrollTo({top:r.scrollHeight,behavior:i});break}case"top":r.scrollTo({top:0,behavior:i});break;case"preserve":break;default:console.warn(`Unknown lvt-scroll mode: ${n}`)}})}function Se(a){a.querySelectorAll("[lvt-highlight]").forEach(t=>{let r=t.getAttribute("lvt-highlight"),n=parseInt(t.getAttribute("lvt-highlight-duration")||"500",10),i=t.getAttribute("lvt-highlight-color")||"#ffc107";if(!r)return;let o=t,s=o.style.backgroundColor,l=o.style.transition;o.style.transition=`background-color ${n}ms ease-out`,o.style.backgroundColor=i,setTimeout(()=>{o.style.backgroundColor=s,setTimeout(()=>{o.style.transition=l},n)},50)})}function Ae(a){if(a.querySelectorAll("[lvt-animate]").forEach(t=>{let r=t.getAttribute("lvt-animate"),n=parseInt(t.getAttribute("lvt-animate-duration")||"300",10);if(!r)return;let i=t;switch(i.style.setProperty("--lvt-animate-duration",`${n}ms`),r){case"fade":i.style.animation="lvt-fade-in var(--lvt-animate-duration) ease-out";break;case"slide":i.style.animation="lvt-slide-in var(--lvt-animate-duration) ease-out";break;case"scale":i.style.animation="lvt-scale-in var(--lvt-animate-duration) ease-out";break;default:console.warn(`Unknown lvt-animate mode: ${r}`)}i.addEventListener("animationend",()=>{i.style.animation=""},{once:!0})}),!document.getElementById("lvt-animate-styles")){let t=document.createElement("style");t.id="lvt-animate-styles",t.textContent=`
|
|
2
|
+
@keyframes lvt-fade-in {
|
|
3
|
+
from { opacity: 0; }
|
|
4
|
+
to { opacity: 1; }
|
|
5
|
+
}
|
|
6
|
+
@keyframes lvt-slide-in {
|
|
7
|
+
from {
|
|
8
|
+
opacity: 0;
|
|
9
|
+
transform: translateY(-10px);
|
|
10
|
+
}
|
|
11
|
+
to {
|
|
12
|
+
opacity: 1;
|
|
13
|
+
transform: translateY(0);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
@keyframes lvt-scale-in {
|
|
17
|
+
from {
|
|
18
|
+
opacity: 0;
|
|
19
|
+
transform: scale(0.95);
|
|
20
|
+
}
|
|
21
|
+
to {
|
|
22
|
+
opacity: 1;
|
|
23
|
+
transform: scale(1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`,document.head.appendChild(t)}}function le(a,e){let t=null;return function(...n){let i=this;t!==null&&clearTimeout(t),t=window.setTimeout(()=>{a.apply(i,n)},e)}}function ce(a,e){let t=!1;return function(...n){let i=this;t||(a.apply(i,n),t=!0,setTimeout(()=>{t=!1},e))}}var z=class{constructor(e,t){this.context=e;this.logger=t}setupEventDelegation(){let e=this.context.getWrapperElement();if(!e)return;let t=["click","submit","change","input","keydown","keyup","focus","blur","mouseenter","mouseleave"],r=e.getAttribute("data-lvt-id"),n=this.context.getRateLimitedHandlers();t.forEach(i=>{let o=`__lvt_delegated_${i}_${r}`,s=document[o];s&&document.removeEventListener(i,s,!1);let l=c=>{var M;let d=this.context.getWrapperElement();if(!d)return;i==="submit"&&(window.__lvtSubmitListenerTriggered=!0,window.__lvtSubmitEventTarget=(M=c.target)==null?void 0:M.tagName),this.logger.debug("Event listener triggered:",i,c.target);let A=c.target;if(!A)return;let m=A,f=!1;for(;m;){if(m===d){f=!0;break}m=m.parentElement}if(i==="submit"&&(window.__lvtInWrapper=f,window.__lvtWrapperElement=d.getAttribute("data-lvt-id")),!f)return;let F=`lvt-${i}`;for(m=A;m&&m!==d.parentElement;){let b=m.getAttribute(F),h=m;if(!b&&(i==="change"||i==="input")){let u=m.closest("form");u&&u.hasAttribute("lvt-change")&&(b=u.getAttribute("lvt-change"),h=u)}if(b&&h){if(i==="submit"&&(window.__lvtActionFound=b,window.__lvtActionElement=h.tagName),i==="submit"&&c.preventDefault(),(i==="keydown"||i==="keyup")&&h.hasAttribute("lvt-key")){let w=h.getAttribute("lvt-key");if(w&&c.key!==w){m=m.parentElement;continue}}let u=h,y=()=>{if(this.logger.debug("handleAction called",{action:b,eventType:i,targetElement:u}),b==="delete"&&u.hasAttribute("lvt-confirm")){let S=u.getAttribute("lvt-confirm")||"Are you sure you want to delete this item?";if(!confirm(S)){this.logger.debug("Delete action cancelled by user");return}}let w={action:b,data:{}};if(u instanceof HTMLFormElement){this.logger.debug("Processing form element");let S=new FormData(u),k=Array.from(u.querySelectorAll('input[type="checkbox"][name]')),R=new Set(k.map(C=>C.name));R.forEach(C=>{w.data[C]=!1}),S.forEach((C,L)=>{R.has(L)?(w.data[L]=!0,this.logger.debug("Converted checkbox",L,"to true")):w.data[L]=this.context.parseValue(C)}),this.logger.debug("Form data collected:",w.data)}else if(i==="change"||i==="input"){if(u instanceof HTMLInputElement){let S=u.name||"value";w.data[S]=this.context.parseValue(u.value)}else if(u instanceof HTMLSelectElement){let S=u.name||"value";w.data[S]=this.context.parseValue(u.value)}else if(u instanceof HTMLTextAreaElement){let S=u.name||"value";w.data[S]=this.context.parseValue(u.value)}}if(Array.from(u.attributes).forEach(S=>{if(S.name.startsWith("lvt-data-")){let k=S.name.replace("lvt-data-","");w.data[k]=this.context.parseValue(S.value)}}),Array.from(u.attributes).forEach(S=>{if(S.name.startsWith("lvt-value-")){let k=S.name.replace("lvt-value-","");w.data[k]=this.context.parseValue(S.value)}}),i==="submit"&&u instanceof HTMLFormElement){let k=c.submitter,R=null;k&&k.hasAttribute("lvt-disable-with")&&(R=k.textContent,k.disabled=!0,k.textContent=k.getAttribute("lvt-disable-with"),this.logger.debug("Disabled submit button")),this.context.setActiveSubmission(u,k||null,R),u.dispatchEvent(new CustomEvent("lvt:pending",{detail:w})),this.logger.debug("Emitted lvt:pending event")}this.logger.debug("About to send message:",w),this.logger.debug("WebSocket state:",this.context.getWebSocketReadyState()),this.context.send(w),this.logger.debug("send() called")},O=h.getAttribute("lvt-throttle"),x=h.getAttribute("lvt-debounce");if(O||x){n.has(h)||n.set(h,new Map);let w=n.get(h),S=`${i}:${b}`,k=w.get(S);if(!k){if(O){let R=parseInt(O,10);k=ce(y,R)}else if(x){let R=parseInt(x,10);k=le(y,R)}k&&w.set(S,k)}k&&k()}else i==="submit"&&(window.__lvtBeforeHandleAction=!0),y(),i==="submit"&&(window.__lvtAfterHandleAction=!0);return}m=m.parentElement}};document[o]=l,document.addEventListener(i,l,!1),this.logger.debug("Registered event listener:",i,"with key:",o)})}setupWindowEventDelegation(){let e=this.context.getWrapperElement();if(!e)return;let t=["keydown","keyup","scroll","resize","focus","blur"],r=e.getAttribute("data-lvt-id"),n=this.context.getRateLimitedHandlers();t.forEach(i=>{let o=`__lvt_window_${i}_${r}`,s=window[o];s&&window.removeEventListener(i,s);let l=c=>{let d=this.context.getWrapperElement();if(!d)return;let A=`lvt-window-${i}`;d.querySelectorAll(`[${A}]`).forEach(f=>{let F=f.getAttribute(A);if(!F)return;if((i==="keydown"||i==="keyup")&&f.hasAttribute("lvt-key")){let y=f.getAttribute("lvt-key");if(y&&c.key!==y)return}let M={action:F,data:{}};Array.from(f.attributes).forEach(y=>{if(y.name.startsWith("lvt-data-")){let O=y.name.replace("lvt-data-","");M.data[O]=this.context.parseValue(y.value)}}),Array.from(f.attributes).forEach(y=>{if(y.name.startsWith("lvt-value-")){let O=y.name.replace("lvt-value-","");M.data[O]=this.context.parseValue(y.value)}});let b=f.getAttribute("lvt-throttle"),h=f.getAttribute("lvt-debounce"),u=()=>this.context.send(M);if(b||h){n.has(f)||n.set(f,new Map);let y=n.get(f),O=`window-${i}:${F}`,x=y.get(O);if(!x){if(b){let w=parseInt(b,10);x=ce(u,w)}else if(h){let w=parseInt(h,10);x=le(u,w)}x&&y.set(O,x)}x&&x()}else u()})};window[o]=l,window.addEventListener(i,l)})}setupClickAwayDelegation(){let e=this.context.getWrapperElement();if(!e)return;let r=`__lvt_click_away_${e.getAttribute("data-lvt-id")}`,n=document[r];n&&document.removeEventListener("click",n);let i=o=>{let s=this.context.getWrapperElement();if(!s)return;let l=o.target;s.querySelectorAll("[lvt-click-away]").forEach(d=>{if(!d.contains(l)){let A=d.getAttribute("lvt-click-away");if(!A)return;let m={action:A,data:{}};Array.from(d.attributes).forEach(f=>{if(f.name.startsWith("lvt-data-")){let F=f.name.replace("lvt-data-","");m.data[F]=this.context.parseValue(f.value)}}),Array.from(d.attributes).forEach(f=>{if(f.name.startsWith("lvt-value-")){let F=f.name.replace("lvt-value-","");m.data[F]=this.context.parseValue(f.value)}}),this.context.send(m)}})};document[r]=i,document.addEventListener("click",i)}setupModalDelegation(){let e=this.context.getWrapperElement();if(!e)return;let t=e.getAttribute("data-lvt-id"),r=`__lvt_modal_open_${t}`,n=document[r];n&&document.removeEventListener("click",n);let i=M=>{var y;let b=this.context.getWrapperElement();if(!b)return;let h=(y=M.target)==null?void 0:y.closest("[lvt-modal-open]");if(!h||!b.contains(h))return;let u=h.getAttribute("lvt-modal-open");u&&(M.preventDefault(),this.context.openModal(u))};document[r]=i,document.addEventListener("click",i);let o=`__lvt_modal_close_${t}`,s=document[o];s&&document.removeEventListener("click",s);let l=M=>{var y;let b=this.context.getWrapperElement();if(!b)return;let h=(y=M.target)==null?void 0:y.closest("[lvt-modal-close]");if(!h||!b.contains(h))return;let u=h.getAttribute("lvt-modal-close");u&&(M.preventDefault(),this.context.closeModal(u))};document[o]=l,document.addEventListener("click",l);let c=`__lvt_modal_backdrop_${t}`,d=document[c];d&&document.removeEventListener("click",d);let A=M=>{let b=M.target;if(!b.hasAttribute("data-modal-backdrop"))return;let h=b.getAttribute("data-modal-id");h&&this.context.closeModal(h)};document[c]=A,document.addEventListener("click",A);let m=`__lvt_modal_escape_${t}`,f=document[m];f&&document.removeEventListener("keydown",f);let F=M=>{if(M.key!=="Escape")return;let b=this.context.getWrapperElement();if(!b)return;let h=b.querySelectorAll('[role="dialog"]:not([hidden])');if(h.length>0){let u=h[h.length-1];u.id&&this.context.closeModal(u.id)}};document[m]=F,document.addEventListener("keydown",F)}};var G=class{constructor(e,t){this.context=e;this.logger=t;this.infiniteScrollObserver=null;this.mutationObserver=null}setupInfiniteScrollObserver(){if(!this.context.getWrapperElement())return;let t=document.getElementById("scroll-sentinel");t&&(this.infiniteScrollObserver&&this.infiniteScrollObserver.disconnect(),this.infiniteScrollObserver=new IntersectionObserver(r=>{r[0].isIntersecting&&(this.logger.debug("Sentinel visible, sending load_more action"),this.context.send({action:"load_more"}))},{rootMargin:"200px"}),this.infiniteScrollObserver.observe(t),this.logger.debug("Observer set up successfully"))}setupInfiniteScrollMutationObserver(){let e=this.context.getWrapperElement();e&&(this.mutationObserver&&this.mutationObserver.disconnect(),this.mutationObserver=new MutationObserver(()=>{this.setupInfiniteScrollObserver()}),this.mutationObserver.observe(e,{childList:!0,subtree:!0}),this.logger.debug("MutationObserver set up successfully"))}teardown(){this.infiniteScrollObserver&&(this.infiniteScrollObserver.disconnect(),this.infiniteScrollObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null)}};var J=class{constructor(e){this.logger=e}open(e){let t=document.getElementById(e);if(!t){this.logger.warn(`Modal with id="${e}" not found`);return}t.removeAttribute("hidden"),t.style.display="flex",t.setAttribute("aria-hidden","false"),t.dispatchEvent(new CustomEvent("lvt:modal-opened",{bubbles:!0})),this.logger.info(`Opened modal: ${e}`);let r=t.querySelector("input, textarea, select");r&&setTimeout(()=>{let n=document.activeElement,i=s=>s?s===document.body||s.offsetParent!==null?!0:s.getClientRects().length>0:!1;(!n||!t.contains(n)||!i(n))&&r.focus()},100)}close(e){let t=document.getElementById(e);if(!t){this.logger.warn(`Modal with id="${e}" not found`);return}t.setAttribute("hidden",""),t.style.display="none",t.setAttribute("aria-hidden","true"),t.dispatchEvent(new CustomEvent("lvt:modal-closed",{bubbles:!0})),this.logger.info(`Closed modal: ${e}`)}};var X=class{constructor(){this.bar=null}show(){if(this.bar)return;let e=document.createElement("div");if(e.style.cssText=`
|
|
27
|
+
position: fixed;
|
|
28
|
+
top: 0;
|
|
29
|
+
left: 0;
|
|
30
|
+
right: 0;
|
|
31
|
+
height: 3px;
|
|
32
|
+
background: linear-gradient(90deg, #3b82f6 0%, #60a5fa 50%, #3b82f6 100%);
|
|
33
|
+
background-size: 200% 100%;
|
|
34
|
+
z-index: 9999;
|
|
35
|
+
animation: lvt-loading-shimmer 1.5s ease-in-out infinite;
|
|
36
|
+
`,!document.getElementById("lvt-loading-styles")){let t=document.createElement("style");t.id="lvt-loading-styles",t.textContent=`
|
|
37
|
+
@keyframes lvt-loading-shimmer {
|
|
38
|
+
0% { background-position: 200% 0; }
|
|
39
|
+
100% { background-position: -200% 0; }
|
|
40
|
+
}
|
|
41
|
+
`,document.head.appendChild(t)}document.body.insertBefore(e,document.body.firstChild),this.bar=e}hide(){this.bar&&(this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar),this.bar=null)}};var Y=class{disable(e){if(!e)return;e.querySelectorAll("form").forEach(r=>{r.querySelectorAll("input, textarea, select, button").forEach(i=>{i.disabled=!0})})}enable(e){if(!e)return;e.querySelectorAll("form").forEach(r=>{r.querySelectorAll("input, textarea, select, button").forEach(i=>{i.disabled=!1})})}};var Q=class{constructor(e){this.logger=e;this.treeState={};this.rangeState={};this.rangeIdKeys={}}applyUpdate(e){let t=!1;for(let[n,i]of Object.entries(e))if(Array.isArray(i)&&i.length>0&&Array.isArray(i[0])&&typeof i[0][0]=="string")this.treeState[n]=i,t=!0;else{let s=this.treeState[n],l=typeof i=="object"&&i!==null&&!Array.isArray(i)?this.deepMergeTreeNodes(s,i):i;JSON.stringify(s)!==JSON.stringify(l)&&(this.treeState[n]=l,t=!0)}return{html:this.reconstructFromTree(this.treeState,""),changed:t}}reset(){this.treeState={},this.rangeState={},this.rangeIdKeys={}}getTreeState(){return{...this.treeState}}getStaticStructure(){return this.treeState.s||null}deepMergeTreeNodes(e,t){if(typeof t!="object"||t===null||Array.isArray(t)||typeof e!="object"||e===null||Array.isArray(e))return t;let r={...e};for(let[n,i]of Object.entries(t))typeof i=="object"&&i!==null&&!Array.isArray(i)&&typeof r[n]=="object"&&r[n]!==null&&!Array.isArray(r[n])?r[n]=this.deepMergeTreeNodes(r[n],i):r[n]=i;return r}reconstructFromTree(e,t){if(e.s&&Array.isArray(e.s)){let r="";for(let n=0;n<e.s.length;n++){let i=e.s[n];if(r+=i,n<e.s.length-1){let o=n.toString();if(e[o]!==void 0){let s=t?`${t}.${o}`:o;r+=this.renderValue(e[o],o,s)}}}return r=r.replace(/<root>/g,"").replace(/<\/root>/g,""),r}return this.renderValue(e,"",t)}renderValue(e,t,r){if(e==null||typeof e=="string"&&e.startsWith("{{")&&e.endsWith("}}"))return"";if(typeof e=="object"&&!Array.isArray(e)){if(e.d&&Array.isArray(e.d)&&e.s&&Array.isArray(e.s)){let n=r||t||"";return n&&(this.rangeState[n]={items:e.d,statics:e.s},e.m&&typeof e.m=="object"&&typeof e.m.idKey=="string"&&(this.rangeIdKeys[n]=e.m.idKey)),this.renderRangeStructure(e,t,r)}if("s"in e&&Array.isArray(e.s))return this.reconstructFromTree(e,r||"")}return Array.isArray(e)?e.length>0&&Array.isArray(e[0])&&typeof e[0][0]=="string"?this.applyDifferentialOperations(e,r):e.map((n,i)=>{let o=i.toString(),s=r?`${r}.${o}`:o;return typeof n=="object"&&n&&n.s?this.reconstructFromTree(n,s):this.renderValue(n,o,s)}).join(""):(typeof e=="object"&&(this.logger.error("Object value reached string conversion; this will render as [object Object]."),this.logger.isDebugEnabled()&&this.logger.debug("Value diagnostics:",{valueType:typeof e,isArray:Array.isArray(e),keys:Object.keys(e),hasStatics:!!e.s,hasDynamics:!!e.d,value:e})),String(e))}renderRangeStructure(e,t,r){let{d:n,s:i}=e;if(!n||!Array.isArray(n))return"";if(n.length===0){if(e.else){let o="else",s=r?`${r}.else`:"else";return this.renderValue(e.else,o,s)}return""}return i&&Array.isArray(i)?n.map((o,s)=>{let l="";for(let c=0;c<i.length;c++)if(l+=i[c],c<i.length-1){let d=c.toString();if(o[d]!==void 0){let A=r?`${r}.${s}.${d}`:`${s}.${d}`;l+=this.renderValue(o[d],d,A)}}return l}).join(""):n.map((o,s)=>{let l=s.toString(),c=r?`${r}.${l}`:l;return this.renderValue(o,l,c)}).join("")}applyDifferentialOperations(e,t){if(!t||!this.rangeState[t])return"";let r=this.rangeState[t],n=[...r.items],i=r.statics;for(let s of e){if(!Array.isArray(s)||s.length<2)continue;switch(s[0]){case"r":{let c=this.findItemIndexByKey(n,s[1],i,t);c>=0&&n.splice(c,1);break}case"u":{let c=this.findItemIndexByKey(n,s[1],i,t),d=s[2];c>=0&&d&&(n[c]={...n[c],...d});break}case"a":{this.addItemsToRange(n,s[1],s[2],r,!1),s[3]&&typeof s[3]=="object"&&s[3].idKey&&(this.rangeIdKeys[t||""]=s[3].idKey);break}case"p":{this.addItemsToRange(n,s[1],s[2],r,!0);break}case"i":{let c=this.findItemIndexByKey(n,s[1],i,t);if(c>=0){let d=Array.isArray(s[2])?s[2]:[s[2]];n.splice(c+1,0,...d)}break}case"o":{let c=s[1],d=[],A=new Map;for(let m of n){let f=this.getItemKey(m,i,t);f&&A.set(f,m)}for(let m of c){let f=A.get(m);f&&d.push(f)}n.length=0,n.push(...d);break}default:break}}this.rangeState[t]={items:n,statics:r.statics},this.treeState[t]={d:n,s:r.statics};let o=this.getCurrentRangeStructure(t);return o&&o.s?this.renderItemsWithStatics(n,o.s):n.map(s=>this.renderValue(s)).join("")}getCurrentRangeStructure(e){if(this.rangeState[e])return{d:this.rangeState[e].items,s:this.rangeState[e].statics};let t=this.treeState[e];return t&&typeof t=="object"&&t.s?t:null}renderItemsWithStatics(e,t){let r=e.map(n=>{let i="";for(let o=0;o<t.length;o++)if(i+=t[o],o<t.length-1){let s=o.toString();n[s]!==void 0&&(i+=this.renderValue(n[s]))}return i}).join("");return this.logger.isDebugEnabled()&&(this.logger.debug("[renderItemsWithStatics] statics:",t),this.logger.debug("[renderItemsWithStatics] items count:",e.length),this.logger.debug("[renderItemsWithStatics] result snippet:",r.substring(0,200))),r}addItemsToRange(e,t,r,n,i){if(r&&(n.statics=r),!t)return;let o=Array.isArray(t)?t:[t];i?e.unshift(...o):e.push(...o)}getItemKey(e,t,r){if(!r||!this.rangeIdKeys[r])return null;let n=this.rangeIdKeys[r];return e[n]||null}findItemIndexByKey(e,t,r,n){return e.findIndex(i=>this.getItemKey(i,r,n)===t)}};var Z=class{constructor(e){this.modalManager=e;this.activeForm=null;this.activeButton=null;this.originalButtonText=null}setActiveSubmission(e,t,r){this.activeForm=e,this.activeButton=t,this.originalButtonText=r}handleResponse(e){this.activeForm&&this.activeForm.dispatchEvent(new CustomEvent("lvt:done",{detail:e})),e.success?this.handleSuccess(e):this.handleError(e),this.restoreFormState()}reset(){this.restoreFormState()}handleSuccess(e){if(!this.activeForm)return;this.activeForm.dispatchEvent(new CustomEvent("lvt:success",{detail:e}));let t=this.activeForm.closest('[role="dialog"]');t&&t.id&&this.modalManager.close(t.id),this.activeForm.hasAttribute("lvt-preserve")||this.activeForm.reset()}handleError(e){this.activeForm&&this.activeForm.dispatchEvent(new CustomEvent("lvt:error",{detail:e}))}restoreFormState(){this.activeButton&&this.originalButtonText!==null&&(this.activeButton.disabled=!1,this.activeButton.textContent=this.originalButtonText),this.activeForm=null,this.activeButton=null,this.originalButtonText=null}};var de=class{constructor(e){this.options=e;this.socket=null;this.reconnectTimer=null;this.manuallyClosed=!1;this.reconnectAttempts=0}connect(){this.manuallyClosed=!1,this.clearReconnectTimer(),this.socket=new WebSocket(this.options.url);let e=this.socket;e.onopen=()=>{var t,r;this.reconnectAttempts=0,(r=(t=this.options).onOpen)==null||r.call(t,e)},e.onmessage=t=>{var r,n;(n=(r=this.options).onMessage)==null||n.call(r,t)},e.onclose=t=>{var r,n;(n=(r=this.options).onClose)==null||n.call(r,t),!this.manuallyClosed&&this.options.autoReconnect&&this.scheduleReconnect()},e.onerror=t=>{var r,n;(n=(r=this.options).onError)==null||n.call(r,t)}}send(e){this.socket&&this.socket.readyState===WebSocket.OPEN&&this.socket.send(e)}disconnect(){this.manuallyClosed=!0,this.clearReconnectTimer(),this.socket&&(this.socket.close(),this.socket=null)}getSocket(){return this.socket}scheduleReconnect(){var s,l,c,d,A;this.clearReconnectTimer();let e=(s=this.options.maxReconnectAttempts)!=null?s:10;if(e>0&&this.reconnectAttempts>=e){(c=(l=this.options).onReconnectFailed)==null||c.call(l);return}this.reconnectAttempts++;let t=(d=this.options.reconnectDelay)!=null?d:1e3,r=(A=this.options.maxReconnectDelay)!=null?A:16e3,n=t*Math.pow(2,this.reconnectAttempts-1),i=Math.random()*1e3,o=Math.min(n+i,r);this.reconnectTimer=window.setTimeout(()=>{var m,f;(f=(m=this.options).onReconnectAttempt)==null||f.call(m,this.reconnectAttempts,o),this.connect()},o)}clearReconnectTimer(){this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}},ee=class{constructor(e){this.config=e;this.transport=null}async connect(){let e=this.getLiveUrl();return await Ge(e,this.config.logger)?(this.transport=new de({url:this.getWebSocketUrl(),autoReconnect:this.config.options.autoReconnect,reconnectDelay:this.config.options.reconnectDelay,maxReconnectDelay:16e3,maxReconnectAttempts:10,onOpen:()=>{this.config.onConnected()},onMessage:r=>{try{let n=JSON.parse(r.data);this.config.onMessage(n,r)}catch(n){this.config.logger.error("Failed to parse WebSocket message:",n)}},onClose:()=>{this.config.onDisconnected()},onReconnectAttempt:(r,n)=>{var i,o;(o=(i=this.config).onReconnectAttempt)==null||o.call(i,r,n)},onReconnectFailed:()=>{var r,n;(n=(r=this.config).onReconnectFailed)==null||n.call(r)},onError:r=>{var n,i;(i=(n=this.config).onError)==null||i.call(n,r)}}),this.transport.connect(),{usingWebSocket:!0}):{usingWebSocket:!1,initialState:await Je(e,this.config.logger)}}disconnect(){var e;(e=this.transport)==null||e.disconnect(),this.transport=null}send(e){var t;(t=this.transport)==null||t.send(e)}getReadyState(){var e,t;return(t=(e=this.transport)==null?void 0:e.getSocket())==null?void 0:t.readyState}getSocket(){var e,t;return(t=(e=this.transport)==null?void 0:e.getSocket())!=null?t:null}getWebSocketUrl(){let e=this.config.options.liveUrl||"/live",t=this.config.options.wsUrl;return t||`ws://${window.location.host}${e}`}getLiveUrl(){return this.config.options.liveUrl||window.location.pathname}};async function Ge(a,e){try{let r=(await fetch(a,{method:"HEAD"})).headers.get("X-LiveTemplate-WebSocket");return r?r==="enabled":!0}catch(t){return e==null||e.warn("Failed to check WebSocket availability:",t),!0}}async function Je(a,e){try{let t=await fetch(a,{method:"GET",credentials:"include",headers:{Accept:"application/json"}});if(!t.ok)throw new Error(`Failed to fetch initial state: ${t.status}`);return await t.json()}catch(t){return e==null||e.warn("Failed to fetch initial state:",t),null}}var ke={silent:0,error:1,warn:2,info:3,debug:4},Te="LiveTemplate",ue=class a{constructor(e,t=[],r=console){this.state=e;this.scope=t;this.sink=r}setLevel(e){this.state.level=e}getLevel(){return this.state.level}child(e){return new a(this.state,[...this.scope,e],this.sink)}isDebugEnabled(){return this.shouldLog("debug")}error(...e){this.log("error","error",e)}warn(...e){this.log("warn","warn",e)}info(...e){this.log("info","info",e)}debug(...e){this.log("debug","debug",e)}log(e,t,r){if(!this.shouldLog(e))return;(this.sink[t]||console[t]||console.log).apply(this.sink,[this.formatPrefix(),...r])}shouldLog(e){return ke[e]<=ke[this.state.level]}formatPrefix(){return this.scope.length===0?`[${Te}]`:`[${Te}:${this.scope.join(":")}]`}};function ge(a={}){var r,n;let e={level:(r=a.level)!=null?r:"info"},t=Array.isArray(a.scope)?a.scope:a.scope?[a.scope]:[];return new ue(e,t,(n=a.sink)!=null?n:console)}async function Le(a,e){try{let t=globalThis==null?void 0:globalThis.require;if(typeof t=="function"){let i=t("fs"),o=JSON.parse(i.readFileSync(e,"utf8"));return a.applyUpdate(o)}let n=await(await fetch(e)).json();return a.applyUpdate(n)}catch(t){throw new Error(`Failed to load update from ${e}: ${t}`)}}function Me(a,e){let t=[],r=c=>c.replace(/\s+/g," ").replace(/>\s+</g,"><").trim(),n=r(a),i=r(e);if(n===i)return{match:!0,differences:[]};let o=n.split(`
|
|
42
|
+
`),s=i.split(`
|
|
43
|
+
`),l=Math.max(o.length,s.length);for(let c=0;c<l;c++){let d=o[c]||"",A=s[c]||"";d!==A&&(t.push(`Line ${c+1}:`),t.push(` Expected: ${d}`),t.push(` Actual: ${A}`))}return{match:!1,differences:t}}var te=class a{constructor(e={}){this.lvtId=null;this.ws=null;this.wrapperElement=null;this.useHTTP=!1;this.sessionCookie=null;this.rateLimitedHandlers=new WeakMap;this.isInitialized=!1;this.messageCount=0;let{logger:t,logLevel:r,debug:n,...i}=e,o=r!=null?r:n?"debug":"info",s=t!=null?t:ge({level:o});t?r?t.setLevel(r):n&&t.setLevel("debug"):s.setLevel(o),this.logger=s.child("Client"),this.options={autoReconnect:!1,reconnectDelay:1e3,liveUrl:window.location.pathname,...i},this.treeRenderer=new Q(this.logger.child("TreeRenderer")),this.focusManager=new q(this.logger.child("FocusManager")),this.modalManager=new J(this.logger.child("ModalManager")),this.formLifecycleManager=new Z(this.modalManager),this.loadingIndicator=new X,this.formDisabler=new Y,this.eventDelegator=new z({getWrapperElement:()=>this.wrapperElement,getRateLimitedHandlers:()=>this.rateLimitedHandlers,parseValue:l=>this.parseValue(l),send:l=>this.send(l),setActiveSubmission:(l,c,d)=>this.formLifecycleManager.setActiveSubmission(l,c,d),openModal:l=>this.modalManager.open(l),closeModal:l=>this.modalManager.close(l),getWebSocketReadyState:()=>this.webSocketManager.getReadyState()},this.logger.child("EventDelegator")),this.observerManager=new G({getWrapperElement:()=>this.wrapperElement,send:l=>this.send(l)},this.logger.child("ObserverManager")),this.webSocketManager=new ee({options:this.options,logger:this.logger.child("Transport"),onConnected:()=>{var l,c,d;this.ws=this.webSocketManager.getSocket(),this.logger.info("WebSocket connected"),(c=(l=this.options).onConnect)==null||c.call(l),(d=this.wrapperElement)==null||d.dispatchEvent(new Event("lvt:connected"))},onDisconnected:()=>{var l,c,d;this.ws=null,this.logger.info("WebSocket disconnected"),(c=(l=this.options).onDisconnect)==null||c.call(l),(d=this.wrapperElement)==null||d.dispatchEvent(new Event("lvt:disconnected"))},onMessage:(l,c)=>{this.handleWebSocketPayload(l,c)},onReconnectAttempt:()=>{this.logger.info("Attempting to reconnect...")},onError:l=>{var c,d;this.logger.error("WebSocket error:",l),(d=(c=this.options).onError)==null||d.call(c,l)}})}static autoInit(){let e=ge({scope:"Client:autoInit"}),t=()=>{let r=document.querySelector("[data-lvt-id]");if(r){let n=new a;n.wrapperElement=r,r.getAttribute("data-lvt-loading")==="true"&&(n.loadingIndicator.show(),n.formDisabler.disable(n.wrapperElement)),n.connect().catch(o=>{e.error("Auto-initialization connect failed:",o)}),window.liveTemplateClient=n}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",t):t()}handleWebSocketPayload(e,t){var r,n;t&&(window.__lastWSMessage=t.data,window.__wsMessages||(window.__wsMessages=[]),window.__wsMessages.push(e)),this.isInitialized||(this.loadingIndicator.hide(),this.formDisabler.enable(this.wrapperElement),this.wrapperElement&&this.wrapperElement.hasAttribute("data-lvt-loading")&&this.wrapperElement.removeAttribute("data-lvt-loading"),this.isInitialized=!0),this.wrapperElement&&(this.updateDOM(this.wrapperElement,e.tree,e.meta),this.messageCount++,window.__wsMessageCount=this.messageCount,this.wrapperElement.dispatchEvent(new CustomEvent("lvt:updated",{detail:{messageCount:this.messageCount,action:(r=e.meta)==null?void 0:r.action,success:(n=e.meta)==null?void 0:n.success}})))}async connect(e="[data-lvt-id]"){var r,n;if(this.wrapperElement=document.querySelector(e),!this.wrapperElement)throw new Error(`LiveTemplate wrapper not found with selector: ${e}`);this.webSocketManager.disconnect();let t=await this.webSocketManager.connect();this.useHTTP=!t.usingWebSocket,this.useHTTP&&(this.ws=null,this.logger.info("WebSocket not available, using HTTP mode"),(n=(r=this.options).onConnect)==null||n.call(r),t.initialState&&this.wrapperElement&&this.handleWebSocketPayload(t.initialState)),this.eventDelegator.setupEventDelegation(),this.eventDelegator.setupWindowEventDelegation(),this.eventDelegator.setupClickAwayDelegation(),this.eventDelegator.setupModalDelegation(),this.focusManager.attach(this.wrapperElement),this.observerManager.setupInfiniteScrollObserver(),this.observerManager.setupInfiniteScrollMutationObserver()}disconnect(){this.webSocketManager.disconnect(),this.ws=null,this.useHTTP=!1,this.observerManager.teardown(),this.formLifecycleManager.reset(),this.loadingIndicator.hide(),this.formDisabler.enable(this.wrapperElement)}isReady(){let e=this.wrapperElement;return!e||e.hasAttribute("data-lvt-loading")?!1:this.useHTTP?!0:this.webSocketManager.getReadyState()===WebSocket.OPEN}send(e){window.__lvtSendCalled=!0,window.__lvtMessageAction=e==null?void 0:e.action;let t=this.webSocketManager.getReadyState();this.logger.isDebugEnabled()&&this.logger.debug("send() invoked",{message:e,useHTTP:this.useHTTP,hasWebSocket:t!==void 0,readyState:t}),this.useHTTP?(this.logger.debug("Using HTTP mode for send"),window.__lvtSendPath="http",this.sendHTTP(e)):t===WebSocket.OPEN?(this.logger.debug("Sending via WebSocket"),window.__lvtSendPath="websocket",window.__lvtWSMessage=JSON.stringify(e),this.webSocketManager.send(JSON.stringify(e)),this.logger.debug("WebSocket send complete"),window.__lvtWSSendComplete=!0):t!==void 0?(this.logger.warn(`WebSocket not ready (state: ${t}), using HTTP fallback`),window.__lvtSendPath="http-fallback",this.sendHTTP(e)):(this.logger.error("No transport available"),window.__lvtSendPath="no-transport")}async sendHTTP(e){try{let t=this.options.liveUrl||"/live",r=await fetch(t,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(e)});if(!r.ok)throw new Error(`HTTP request failed: ${r.status}`);let n=await r.json();this.wrapperElement&&this.updateDOM(this.wrapperElement,n.tree,n.meta)}catch(t){this.logger.error("Failed to send HTTP request:",t)}}parseValue(e){let t=parseFloat(e);return!isNaN(t)&&e.trim()===t.toString()?t:e==="true"?!0:e==="false"?!1:e}applyUpdate(e){return this.treeRenderer.applyUpdate(e)}applyUpdateToHTML(e,t){let r=this.applyUpdate(t);if(!this.lvtId){let c=e.match(/data-lvt-id="([^"]+)"/);c&&(this.lvtId=c[1])}let n=r.html;if(!e.match(/<body>([\s\S]*?)<\/body>/))return e;let l=`<div data-lvt-id="${this.lvtId||"lvt-unknown"}">`+n+"</div>";return e.replace(/<body>[\s\S]*?<\/body>/,`<body>${l}</body>`)}updateDOM(e,t,r){let n=this.applyUpdate(t),i=s=>!s||typeof s!="object"?!1:s.s&&Array.isArray(s.s)?!0:Object.values(s).some(l=>i(l));if(!n.changed&&!i(t))return;let o=document.createElement(e.tagName);this.logger.isDebugEnabled()&&(this.logger.debug("[updateDOM] element.tagName:",e.tagName),this.logger.debug("[updateDOM] result.html (first 500 chars):",n.html.substring(0,500)),this.logger.debug("[updateDOM] Has <table> tag:",n.html.includes("<table>")),this.logger.debug("[updateDOM] Has <tbody> tag:",n.html.includes("<tbody>")),this.logger.debug("[updateDOM] Has <tr> tag:",n.html.includes("<tr"))),o.innerHTML=n.html,this.logger.isDebugEnabled()&&(this.logger.debug("[updateDOM] tempWrapper.innerHTML (first 500 chars):",o.innerHTML.substring(0,500)),this.logger.debug("[updateDOM] tempWrapper has <table>:",o.innerHTML.includes("<table>")),this.logger.debug("[updateDOM] tempWrapper has <tbody>:",o.innerHTML.includes("<tbody>")),this.logger.debug("[updateDOM] tempWrapper has <tr>:",o.innerHTML.includes("<tr"))),Ee(e,o,{childrenOnly:!0,getNodeKey:s=>{if(s.nodeType===1)return s.getAttribute("data-key")||s.getAttribute("data-lvt-key")||void 0},onBeforeElUpdated:(s,l)=>{let c=this.focusManager.getLastFocusedElement();return c&&this.focusManager.isTextualInput(s)&&s===c&&(l.value=s.value),s.isEqualNode(l)?!1:(this.executeLifecycleHook(s,"lvt-updated"),!0)},onNodeAdded:s=>{s.nodeType===Node.ELEMENT_NODE&&this.executeLifecycleHook(s,"lvt-mounted")},onBeforeNodeDiscarded:s=>(s.nodeType===Node.ELEMENT_NODE&&this.executeLifecycleHook(s,"lvt-destroyed"),!0)}),this.focusManager.restoreFocusedElement(),we(e),Se(e),Ae(e),r&&this.formLifecycleManager.handleResponse(r)}executeLifecycleHook(e,t){let r=e.getAttribute(t);if(r)try{new Function("element",r).call(e,e)}catch(n){this.logger.error(`Error executing ${t} hook:`,n)}}reset(){this.treeRenderer.reset(),this.focusManager.reset(),this.observerManager.teardown(),this.formLifecycleManager.reset(),this.loadingIndicator.hide(),this.formDisabler.enable(this.wrapperElement),this.lvtId=null}getTreeState(){return this.treeRenderer.getTreeState()}getStaticStructure(){return this.treeRenderer.getStaticStructure()}};typeof window!="undefined"&&te.autoInit();return Ie(Xe);})();
|
|
44
|
+
//# sourceMappingURL=livetemplate-client.browser.js.map
|