@ng-prism/core 21.7.2 → 21.8.1
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 +4 -4
- package/dist/app/index.d.ts +2 -2
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +4 -1
- package/dist/app/panels/a11y/a11y-audit.service.d.ts +2 -0
- package/dist/app/panels/a11y/a11y-audit.service.d.ts.map +1 -1
- package/dist/app/panels/a11y/a11y-audit.service.js +15 -2
- package/dist/app/panels/a11y/a11y-keyboard.component.d.ts +1 -2
- package/dist/app/panels/a11y/a11y-keyboard.component.d.ts.map +1 -1
- package/dist/app/panels/a11y/a11y-keyboard.component.js +4 -5
- package/dist/app/panels/a11y/a11y-panel.component.d.ts +2 -1
- package/dist/app/panels/a11y/a11y-panel.component.d.ts.map +1 -1
- package/dist/app/panels/a11y/a11y-panel.component.js +10 -19
- package/dist/app/panels/a11y/a11y-sr.component.d.ts +1 -2
- package/dist/app/panels/a11y/a11y-sr.component.d.ts.map +1 -1
- package/dist/app/panels/a11y/a11y-sr.component.js +4 -5
- package/dist/app/panels/a11y/a11y-tree.component.d.ts +3 -2
- package/dist/app/panels/a11y/a11y-tree.component.d.ts.map +1 -1
- package/dist/app/panels/a11y/a11y-tree.component.js +21 -9
- package/dist/app/panels/controls/prism-controls-panel.component.d.ts +3 -2
- package/dist/app/panels/controls/prism-controls-panel.component.d.ts.map +1 -1
- package/dist/app/panels/controls/prism-controls-panel.component.js +5 -4
- package/dist/app/panels/events/prism-events-panel.component.d.ts +3 -1
- package/dist/app/panels/events/prism-events-panel.component.d.ts.map +1 -1
- package/dist/app/panels/events/prism-events-panel.component.js +5 -4
- package/dist/app/renderer/prism-renderer.component.d.ts.map +1 -1
- package/dist/app/renderer/prism-renderer.component.js +8 -5
- package/dist/app/renderer/snippet-generator.d.ts.map +1 -1
- package/dist/app/renderer/snippet-generator.js +6 -3
- package/dist/app/services/prism-persistence.service.d.ts +20 -0
- package/dist/app/services/prism-persistence.service.d.ts.map +1 -0
- package/dist/app/services/prism-persistence.service.js +139 -0
- package/dist/app/services/prism-renderer.service.d.ts.map +1 -1
- package/dist/app/services/prism-renderer.service.js +8 -2
- package/dist/app/services/prism-url-state.service.d.ts.map +1 -1
- package/dist/app/services/prism-url-state.service.js +12 -2
- package/dist/app/shell/prism-shell.component.d.ts +1 -0
- package/dist/app/shell/prism-shell.component.d.ts.map +1 -1
- package/dist/app/shell/prism-shell.component.js +4 -1
- package/dist/builder/config-loader/config-loader.d.ts.map +1 -1
- package/dist/builder/config-loader/config-loader.js +9 -3
- package/dist/builder/plugin-runner/plugin-runner.d.ts.map +1 -1
- package/dist/builder/plugin-runner/plugin-runner.js +40 -14
- package/dist/builder/scanner/component.scanner.js +9 -4
- package/dist/builder/scanner/entry-point-discovery.js +24 -15
- package/dist/builder/serve/index.d.ts.map +1 -1
- package/dist/builder/serve/index.js +8 -4
- package/dist/builder/shared/prism-pipeline.js +11 -3
- package/dist/builder/watcher/prism-watcher.d.ts.map +1 -1
- package/dist/builder/watcher/prism-watcher.js +31 -20
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/plugin/define-config.d.ts.map +1 -1
- package/dist/plugin/define-config.js +20 -0
- package/dist/plugin/plugin.types.d.ts +2 -0
- package/dist/plugin/plugin.types.d.ts.map +1 -1
- package/dist/schematics/ng-add/index.d.ts.map +1 -1
- package/dist/schematics/ng-add/index.js +91 -59
- package/package.json +1 -1
|
@@ -113,9 +113,12 @@ export class PrismRendererComponent {
|
|
|
113
113
|
return;
|
|
114
114
|
}
|
|
115
115
|
this.activeOverlay.set(null);
|
|
116
|
+
const requestedPanelId = panel.id;
|
|
116
117
|
panel.loadOverlayComponent().then((c) => {
|
|
117
|
-
this.overlayCache.set(
|
|
118
|
-
this.
|
|
118
|
+
this.overlayCache.set(requestedPanelId, c);
|
|
119
|
+
if (this.panelService.activePanelId() === requestedPanelId) {
|
|
120
|
+
this.activeOverlay.set(c);
|
|
121
|
+
}
|
|
119
122
|
});
|
|
120
123
|
return;
|
|
121
124
|
}
|
|
@@ -220,7 +223,7 @@ export class PrismRendererComponent {
|
|
|
220
223
|
i0.ɵɵstyleProp("--zoom", ctx.canvasService.zoom());
|
|
221
224
|
i0.ɵɵadvance(3);
|
|
222
225
|
i0.ɵɵconditional(ctx.activeOverlay() ? 9 : -1);
|
|
223
|
-
} }, dependencies: [PrismCanvasRulersComponent, NgComponentOutlet], styles: ["[_nghost-%COMP%] { display: block; min-height: 0; flex: 1; }\n\n .prism-canvas-stage[_ngcontent-%COMP%] {\n position: relative;\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 32px;\n min-height: 200px;\n height: 100%;\n background-color: var(--prism-bg-surface);\n background-image: radial-gradient(circle, var(--prism-dot) 1px, transparent 1px);\n background-size: 20px 20px;\n transition: filter var(--dur-base);\n }\n\n .prism-canvas-stage[data-bg=\"plain\"][_ngcontent-%COMP%] {\n background-image: none;\n }\n .prism-canvas-stage[data-bg=\"light\"][_ngcontent-%COMP%] {\n background-color: var(--prism-void-light, #f7f5fc);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--prism-primary-from) 15%, transparent) 1px, transparent 1px);\n }\n .prism-canvas-stage[data-bg=\"dark\"][_ngcontent-%COMP%] {\n background-color: var(--prism-void-dark, #07050f);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--prism-primary) 18%, transparent) 1px, transparent 1px);\n }\n .prism-canvas-stage[data-bg=\"checker\"][_ngcontent-%COMP%] {\n background-image:\n linear-gradient(45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--prism-border) 75%);\n background-size: 16px 16px;\n background-position: 0 0, 0 8px, 8px -8px, -8px 0;\n }\n\n .stage-crosshair[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n pointer-events: none;\n opacity: 0;\n transition: opacity var(--dur-base);\n }\n .stage-crosshair.visible[_ngcontent-%COMP%] { opacity: 1; }\n .stage-crosshair[_ngcontent-%COMP%]::before, \n .stage-crosshair[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n background: color-mix(in srgb, var(--prism-primary) 20%, transparent);\n }\n .stage-crosshair[_ngcontent-%COMP%]::before { left: 0; right: 0; top: 50%; height: 1px; }\n .stage-crosshair[_ngcontent-%COMP%]::after { top: 0; bottom: 0; left: 50%; width: 1px; }\n\n .canvas-badges[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n left: 20px;\n display: flex;\n gap: 6px;\n pointer-events: none;\n }\n .c-badge[_ngcontent-%COMP%] {\n font-family: var(--font-mono);\n font-size: var(--fs-xs);\n padding: 3px 7px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--prism-bg-elevated) 90%, transparent);\n border: 1px solid var(--prism-border);\n color: var(--prism-text-muted);\n backdrop-filter: blur(8px);\n }\n\n .demo-wrap[_ngcontent-%COMP%] {\n position: relative;\n transform: scale(var(--zoom, 1));\n transition: transform 0.18s;\n }"], changeDetection: 0 });
|
|
226
|
+
} }, dependencies: [PrismCanvasRulersComponent, NgComponentOutlet], styles: ["[_nghost-%COMP%] { display: block; min-height: 0; flex: 1; }\n\n .prism-canvas-stage[_ngcontent-%COMP%] {\n position: relative;\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 32px;\n min-height: 200px;\n height: 100%;\n background-color: var(--prism-bg-surface);\n background-image: radial-gradient(circle, var(--prism-dot) 1px, transparent 1px);\n background-size: 20px 20px;\n transition: filter var(--dur-base);\n }\n\n .prism-canvas-stage[data-bg=\"plain\"][_ngcontent-%COMP%] {\n background-image: none;\n }\n .prism-canvas-stage[data-bg=\"light\"][_ngcontent-%COMP%] {\n background-color: var(--prism-void-light, #f7f5fc);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--prism-primary-from) 15%, transparent) 1px, transparent 1px);\n }\n .prism-canvas-stage[data-bg=\"dark\"][_ngcontent-%COMP%] {\n background-color: var(--prism-void-dark, #07050f);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--prism-primary) 18%, transparent) 1px, transparent 1px);\n }\n .prism-canvas-stage[data-bg=\"checker\"][_ngcontent-%COMP%] {\n background-image:\n linear-gradient(45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--prism-border) 75%);\n background-size: 16px 16px;\n background-position: 0 0, 0 8px, 8px -8px, -8px 0;\n }\n\n .stage-crosshair[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n pointer-events: none;\n opacity: 0;\n transition: opacity var(--dur-base);\n }\n .stage-crosshair.visible[_ngcontent-%COMP%] { opacity: 1; }\n .stage-crosshair[_ngcontent-%COMP%]::before, \n .stage-crosshair[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n background: color-mix(in srgb, var(--prism-primary) 20%, transparent);\n }\n .stage-crosshair[_ngcontent-%COMP%]::before { left: 0; right: 0; top: 50%; height: 1px; }\n .stage-crosshair[_ngcontent-%COMP%]::after { top: 0; bottom: 0; left: 50%; width: 1px; }\n\n .canvas-badges[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n left: 20px;\n display: flex;\n gap: 6px;\n pointer-events: none;\n }\n .c-badge[_ngcontent-%COMP%] {\n font-family: var(--font-mono);\n font-size: var(--fs-xs);\n padding: 3px 7px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--prism-bg-elevated) 90%, transparent);\n border: 1px solid var(--prism-border);\n color: var(--prism-text-muted);\n backdrop-filter: blur(8px);\n }\n\n .demo-wrap[_ngcontent-%COMP%] {\n position: relative;\n transform: scale(var(--zoom, 1));\n transition: transform 0.18s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n }"], changeDetection: 0 });
|
|
224
227
|
}
|
|
225
228
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismRendererComponent, [{
|
|
226
229
|
type: Component,
|
|
@@ -250,11 +253,11 @@ export class PrismRendererComponent {
|
|
|
250
253
|
}
|
|
251
254
|
</div>
|
|
252
255
|
</div>
|
|
253
|
-
`, styles: ["\n :host { display: block; min-height: 0; flex: 1; }\n\n .prism-canvas-stage {\n position: relative;\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 32px;\n min-height: 200px;\n height: 100%;\n background-color: var(--prism-bg-surface);\n background-image: radial-gradient(circle, var(--prism-dot) 1px, transparent 1px);\n background-size: 20px 20px;\n transition: filter var(--dur-base);\n }\n\n .prism-canvas-stage[data-bg=\"plain\"] {\n background-image: none;\n }\n .prism-canvas-stage[data-bg=\"light\"] {\n background-color: var(--prism-void-light, #f7f5fc);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--prism-primary-from) 15%, transparent) 1px, transparent 1px);\n }\n .prism-canvas-stage[data-bg=\"dark\"] {\n background-color: var(--prism-void-dark, #07050f);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--prism-primary) 18%, transparent) 1px, transparent 1px);\n }\n .prism-canvas-stage[data-bg=\"checker\"] {\n background-image:\n linear-gradient(45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--prism-border) 75%);\n background-size: 16px 16px;\n background-position: 0 0, 0 8px, 8px -8px, -8px 0;\n }\n\n .stage-crosshair {\n position: absolute;\n inset: 0;\n pointer-events: none;\n opacity: 0;\n transition: opacity var(--dur-base);\n }\n .stage-crosshair.visible { opacity: 1; }\n .stage-crosshair::before,\n .stage-crosshair::after {\n content: '';\n position: absolute;\n background: color-mix(in srgb, var(--prism-primary) 20%, transparent);\n }\n .stage-crosshair::before { left: 0; right: 0; top: 50%; height: 1px; }\n .stage-crosshair::after { top: 0; bottom: 0; left: 50%; width: 1px; }\n\n .canvas-badges {\n position: absolute;\n top: 12px;\n left: 20px;\n display: flex;\n gap: 6px;\n pointer-events: none;\n }\n .c-badge {\n font-family: var(--font-mono);\n font-size: var(--fs-xs);\n padding: 3px 7px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--prism-bg-elevated) 90%, transparent);\n border: 1px solid var(--prism-border);\n color: var(--prism-text-muted);\n backdrop-filter: blur(8px);\n }\n\n .demo-wrap {\n position: relative;\n transform: scale(var(--zoom, 1));\n transition: transform 0.18s;\n }\n\n "] }]
|
|
256
|
+
`, styles: ["\n :host { display: block; min-height: 0; flex: 1; }\n\n .prism-canvas-stage {\n position: relative;\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 32px;\n min-height: 200px;\n height: 100%;\n background-color: var(--prism-bg-surface);\n background-image: radial-gradient(circle, var(--prism-dot) 1px, transparent 1px);\n background-size: 20px 20px;\n transition: filter var(--dur-base);\n }\n\n .prism-canvas-stage[data-bg=\"plain\"] {\n background-image: none;\n }\n .prism-canvas-stage[data-bg=\"light\"] {\n background-color: var(--prism-void-light, #f7f5fc);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--prism-primary-from) 15%, transparent) 1px, transparent 1px);\n }\n .prism-canvas-stage[data-bg=\"dark\"] {\n background-color: var(--prism-void-dark, #07050f);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--prism-primary) 18%, transparent) 1px, transparent 1px);\n }\n .prism-canvas-stage[data-bg=\"checker\"] {\n background-image:\n linear-gradient(45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--prism-border) 75%);\n background-size: 16px 16px;\n background-position: 0 0, 0 8px, 8px -8px, -8px 0;\n }\n\n .stage-crosshair {\n position: absolute;\n inset: 0;\n pointer-events: none;\n opacity: 0;\n transition: opacity var(--dur-base);\n }\n .stage-crosshair.visible { opacity: 1; }\n .stage-crosshair::before,\n .stage-crosshair::after {\n content: '';\n position: absolute;\n background: color-mix(in srgb, var(--prism-primary) 20%, transparent);\n }\n .stage-crosshair::before { left: 0; right: 0; top: 50%; height: 1px; }\n .stage-crosshair::after { top: 0; bottom: 0; left: 50%; width: 1px; }\n\n .canvas-badges {\n position: absolute;\n top: 12px;\n left: 20px;\n display: flex;\n gap: 6px;\n pointer-events: none;\n }\n .c-badge {\n font-family: var(--font-mono);\n font-size: var(--fs-xs);\n padding: 3px 7px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--prism-bg-elevated) 90%, transparent);\n border: 1px solid var(--prism-border);\n color: var(--prism-text-muted);\n backdrop-filter: blur(8px);\n }\n\n .demo-wrap {\n position: relative;\n transform: scale(var(--zoom, 1));\n transition: transform 0.18s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n }\n\n "] }]
|
|
254
257
|
}], () => [], { outlet: [{ type: i0.ViewChild, args: ['outlet', { ...{
|
|
255
258
|
read: ViewContainerRef,
|
|
256
259
|
}, isSignal: true }] }] }); })();
|
|
257
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismRendererComponent, { className: "PrismRendererComponent", filePath: "app/renderer/prism-renderer.component.ts", lineNumber:
|
|
260
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismRendererComponent, { className: "PrismRendererComponent", filePath: "app/renderer/prism-renderer.component.ts", lineNumber: 155 }); })();
|
|
258
261
|
function parseContentToNodes(content) {
|
|
259
262
|
if (typeof content === 'string') {
|
|
260
263
|
return [htmlToNodes(content)];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snippet-generator.d.ts","sourceRoot":"","sources":["../../../src/app/renderer/snippet-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAEvE,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"snippet-generator.d.ts","sourceRoot":"","sources":["../../../src/app/renderer/snippet-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAEvE,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;CAC/B;AAoBD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,EAAE,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,EAClC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,gBAAgB,CAAC,EAAE,uBAAuB,GACzC,MAAM,CA2DR"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
function escapeAttrValue(value) {
|
|
2
|
+
return String(value).replace(/&/g, '&').replace(/"/g, '"');
|
|
3
|
+
}
|
|
1
4
|
function pushAttribute(attributes, name, value) {
|
|
2
5
|
if (typeof value === 'string') {
|
|
3
|
-
attributes.push(`${name}="${value}"`);
|
|
6
|
+
attributes.push(`${name}="${escapeAttrValue(value)}"`);
|
|
4
7
|
}
|
|
5
8
|
else if (typeof value === 'boolean') {
|
|
6
9
|
attributes.push(`[${name}]="true"`);
|
|
@@ -12,7 +15,7 @@ function pushAttribute(attributes, name, value) {
|
|
|
12
15
|
attributes.push(`[${name}]="yourData"`);
|
|
13
16
|
}
|
|
14
17
|
else {
|
|
15
|
-
attributes.push(`[${name}]="${
|
|
18
|
+
attributes.push(`[${name}]="${escapeAttrValue(value)}"`);
|
|
16
19
|
}
|
|
17
20
|
}
|
|
18
21
|
export function generateSnippet(selector, inputs, values, explicitKeys, content, directiveOptions) {
|
|
@@ -92,7 +95,7 @@ function generateDirectiveSnippet(selector, inputs, values, explicitKeys, conten
|
|
|
92
95
|
tag = host.selector;
|
|
93
96
|
if (host.inputs) {
|
|
94
97
|
for (const [k, v] of Object.entries(host.inputs)) {
|
|
95
|
-
hostAttrs.push(`${k}="${
|
|
98
|
+
hostAttrs.push(`${k}="${escapeAttrValue(v)}"`);
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class PrismPersistenceService {
|
|
3
|
+
private readonly config;
|
|
4
|
+
private readonly navigationService;
|
|
5
|
+
private readonly rendererService;
|
|
6
|
+
private readonly a11yPanelState;
|
|
7
|
+
private readonly a11yPerspective;
|
|
8
|
+
private readonly injector;
|
|
9
|
+
private suppressSync;
|
|
10
|
+
private writeTimer;
|
|
11
|
+
private lastSerialized;
|
|
12
|
+
init(): void;
|
|
13
|
+
private restoreFromStorage;
|
|
14
|
+
private setupSyncEffect;
|
|
15
|
+
private writeDebounced;
|
|
16
|
+
private serialize;
|
|
17
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PrismPersistenceService, never>;
|
|
18
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<PrismPersistenceService>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=prism-persistence.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prism-persistence.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-persistence.service.ts"],"names":[],"mappings":";AAqBA,qBACa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiE;IACxF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IACpE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiC;IAChE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkC;IAClE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAE7C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,cAAc,CAAuB;IAE7C,IAAI,IAAI,IAAI;IAOZ,OAAO,CAAC,kBAAkB;IA6C1B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,SAAS;yCA7FN,uBAAuB;6CAAvB,uBAAuB;CAwHnC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { effect, inject, Injectable, Injector } from '@angular/core';
|
|
2
|
+
import { PRISM_CONFIG } from '../tokens/prism-tokens.js';
|
|
3
|
+
import { A11yPanelStateService } from '../panels/a11y/a11y-panel-state.service.js';
|
|
4
|
+
import { A11yPerspectiveService } from '../panels/a11y/a11y-perspective.service.js';
|
|
5
|
+
import { PrismNavigationService } from './prism-navigation.service.js';
|
|
6
|
+
import { PrismRendererService } from './prism-renderer.service.js';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
const STORAGE_KEY = 'ng-prism:state';
|
|
9
|
+
const SCHEMA_VERSION = 1;
|
|
10
|
+
const DEBOUNCE_MS = 200;
|
|
11
|
+
export class PrismPersistenceService {
|
|
12
|
+
config = inject(PRISM_CONFIG, { optional: true }) ?? {};
|
|
13
|
+
navigationService = inject(PrismNavigationService);
|
|
14
|
+
rendererService = inject(PrismRendererService);
|
|
15
|
+
a11yPanelState = inject(A11yPanelStateService);
|
|
16
|
+
a11yPerspective = inject(A11yPerspectiveService);
|
|
17
|
+
injector = inject(Injector);
|
|
18
|
+
suppressSync = false;
|
|
19
|
+
writeTimer = null;
|
|
20
|
+
lastSerialized = null;
|
|
21
|
+
init() {
|
|
22
|
+
if (this.config.persistState === false)
|
|
23
|
+
return;
|
|
24
|
+
const { raw } = this.restoreFromStorage();
|
|
25
|
+
if (raw !== null)
|
|
26
|
+
this.lastSerialized = raw;
|
|
27
|
+
this.setupSyncEffect();
|
|
28
|
+
}
|
|
29
|
+
restoreFromStorage() {
|
|
30
|
+
let parsed = null;
|
|
31
|
+
let raw = null;
|
|
32
|
+
try {
|
|
33
|
+
raw = sessionStorage.getItem(STORAGE_KEY);
|
|
34
|
+
if (raw)
|
|
35
|
+
parsed = JSON.parse(raw);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
parsed = null;
|
|
39
|
+
raw = null;
|
|
40
|
+
}
|
|
41
|
+
if (!parsed || parsed.version !== SCHEMA_VERSION)
|
|
42
|
+
return { raw: null };
|
|
43
|
+
this.suppressSync = true;
|
|
44
|
+
try {
|
|
45
|
+
const a11yTabs = ['violations', 'keyboard', 'tree', 'sr'];
|
|
46
|
+
if (parsed.a11y?.activeTab && a11yTabs.includes(parsed.a11y.activeTab)) {
|
|
47
|
+
this.a11yPanelState.activeTab.set(parsed.a11y.activeTab);
|
|
48
|
+
}
|
|
49
|
+
if (parsed.a11y?.perspective === 'visual' || parsed.a11y?.perspective === 'screen-reader') {
|
|
50
|
+
this.a11yPerspective.mode.set(parsed.a11y.perspective);
|
|
51
|
+
}
|
|
52
|
+
const activeComp = this.navigationService.activeComponent();
|
|
53
|
+
if (activeComp && parsed.inputs) {
|
|
54
|
+
const bucket = parsed.inputs[activeComp.meta.className];
|
|
55
|
+
if (bucket && bucket.variantIndex === this.rendererService.activeVariantIndex()) {
|
|
56
|
+
const validKeys = new Set(activeComp.meta.inputs.map((i) => i.name));
|
|
57
|
+
const filtered = {};
|
|
58
|
+
for (const [k, v] of Object.entries(bucket.values)) {
|
|
59
|
+
if (validKeys.has(k) || k === '__prismContent__')
|
|
60
|
+
filtered[k] = v;
|
|
61
|
+
}
|
|
62
|
+
if (Object.keys(filtered).length > 0) {
|
|
63
|
+
this.rendererService.inputValues.set({
|
|
64
|
+
...this.rendererService.inputValues(),
|
|
65
|
+
...filtered,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
this.suppressSync = false;
|
|
73
|
+
}
|
|
74
|
+
return { raw };
|
|
75
|
+
}
|
|
76
|
+
setupSyncEffect() {
|
|
77
|
+
effect(() => {
|
|
78
|
+
this.navigationService.activeComponent();
|
|
79
|
+
this.rendererService.activeVariantIndex();
|
|
80
|
+
this.rendererService.inputValues();
|
|
81
|
+
this.a11yPanelState.activeTab();
|
|
82
|
+
this.a11yPerspective.mode();
|
|
83
|
+
if (this.suppressSync)
|
|
84
|
+
return;
|
|
85
|
+
this.writeDebounced();
|
|
86
|
+
}, { injector: this.injector });
|
|
87
|
+
}
|
|
88
|
+
writeDebounced() {
|
|
89
|
+
if (this.writeTimer)
|
|
90
|
+
clearTimeout(this.writeTimer);
|
|
91
|
+
this.writeTimer = setTimeout(() => {
|
|
92
|
+
this.writeTimer = null;
|
|
93
|
+
const state = this.serialize();
|
|
94
|
+
const next = JSON.stringify(state);
|
|
95
|
+
if (next === this.lastSerialized)
|
|
96
|
+
return;
|
|
97
|
+
try {
|
|
98
|
+
sessionStorage.setItem(STORAGE_KEY, next);
|
|
99
|
+
this.lastSerialized = next;
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
console.warn('[ng-prism] Failed to persist state:', err);
|
|
103
|
+
}
|
|
104
|
+
}, DEBOUNCE_MS);
|
|
105
|
+
}
|
|
106
|
+
serialize() {
|
|
107
|
+
const activeComp = this.navigationService.activeComponent();
|
|
108
|
+
const variantIndex = this.rendererService.activeVariantIndex();
|
|
109
|
+
const values = this.rendererService.inputValues();
|
|
110
|
+
let inputs = {};
|
|
111
|
+
if (this.lastSerialized) {
|
|
112
|
+
try {
|
|
113
|
+
const prev = JSON.parse(this.lastSerialized);
|
|
114
|
+
if (prev.version === SCHEMA_VERSION)
|
|
115
|
+
inputs = { ...prev.inputs };
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
inputs = {};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (activeComp) {
|
|
122
|
+
inputs[activeComp.meta.className] = { variantIndex, values: { ...values } };
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
version: SCHEMA_VERSION,
|
|
126
|
+
inputs,
|
|
127
|
+
a11y: {
|
|
128
|
+
activeTab: this.a11yPanelState.activeTab(),
|
|
129
|
+
perspective: this.a11yPerspective.mode(),
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
static ɵfac = function PrismPersistenceService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PrismPersistenceService)(); };
|
|
134
|
+
static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: PrismPersistenceService, factory: PrismPersistenceService.ɵfac, providedIn: 'root' });
|
|
135
|
+
}
|
|
136
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismPersistenceService, [{
|
|
137
|
+
type: Injectable,
|
|
138
|
+
args: [{ providedIn: 'root' }]
|
|
139
|
+
}], null, null); })();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-renderer.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-renderer.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;;AAGrE,qBACa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IAEpE,QAAQ,CAAC,kBAAkB,iDAAa;IACxC,QAAQ,CAAC,WAAW,kEAAuC;IAC3D,QAAQ,CAAC,aAAa,sFAAkE;IACxF,QAAQ,CAAC,eAAe,yDAAgC;IAExD,OAAO,CAAC,cAAc,CAAuB;IAE7C,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAM/C,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"prism-renderer.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-renderer.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;;AAGrE,qBACa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IAEpE,QAAQ,CAAC,kBAAkB,iDAAa;IACxC,QAAQ,CAAC,WAAW,kEAAuC;IAC3D,QAAQ,CAAC,aAAa,sFAAkE;IACxF,QAAQ,CAAC,eAAe,yDAAgC;IAExD,OAAO,CAAC,cAAc,CAAuB;IAE7C,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAM/C,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IA2CnD,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMlC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAI/C,OAAO,CAAC,YAAY;yCArET,oBAAoB;6CAApB,oBAAoB;CA8GhC"}
|
|
@@ -16,7 +16,7 @@ export class PrismRendererService {
|
|
|
16
16
|
reconcileForComponent(comp) {
|
|
17
17
|
const prev = this._lastClassName;
|
|
18
18
|
this._lastClassName = comp.meta.className;
|
|
19
|
-
if (prev !== comp.meta.className) {
|
|
19
|
+
if (prev !== null && prev !== comp.meta.className) {
|
|
20
20
|
this.activeVariantIndex.set(0);
|
|
21
21
|
this.applyVariant(0, comp);
|
|
22
22
|
return;
|
|
@@ -25,6 +25,12 @@ export class PrismRendererService {
|
|
|
25
25
|
const maxIndex = Math.max(0, variants.length - 1);
|
|
26
26
|
const preservedIndex = Math.min(this.activeVariantIndex(), maxIndex);
|
|
27
27
|
this.activeVariantIndex.set(preservedIndex);
|
|
28
|
+
const defaults = {};
|
|
29
|
+
for (const input of comp.meta.inputs) {
|
|
30
|
+
if (input.defaultValue !== undefined) {
|
|
31
|
+
defaults[input.name] = input.defaultValue;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
28
34
|
const validKeys = new Set(comp.meta.inputs.map((i) => i.name));
|
|
29
35
|
const currentValues = this.inputValues();
|
|
30
36
|
const preserved = {};
|
|
@@ -35,7 +41,7 @@ export class PrismRendererService {
|
|
|
35
41
|
}
|
|
36
42
|
const variant = variants[preservedIndex];
|
|
37
43
|
const variantInputs = variant?.inputs ?? {};
|
|
38
|
-
const merged = { ...variantInputs, ...preserved };
|
|
44
|
+
const merged = { ...defaults, ...variantInputs, ...preserved };
|
|
39
45
|
if (comp.meta.componentMeta.isDirective && variant?.content && preserved['__prismContent__'] === undefined) {
|
|
40
46
|
merged['__prismContent__'] = typeof variant.content === 'string' ? variant.content : '';
|
|
41
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-url-state.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-url-state.service.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"prism-url-state.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-url-state.service.ts"],"names":[],"mappings":";AAgBA,qBACa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IACpE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAE7C,OAAO,CAAC,YAAY,CAAS;IAE7B,IAAI,IAAI,IAAI;IAkBZ,OAAO,CAAC,cAAc;IA0CtB,OAAO,CAAC,UAAU;yCAtEP,oBAAoB;6CAApB,oBAAoB;CA+GhC"}
|
|
@@ -10,6 +10,8 @@ const PARAM_PAGE = 'page';
|
|
|
10
10
|
const PARAM_VARIANT = 'variant';
|
|
11
11
|
const PARAM_VIEW = 'view';
|
|
12
12
|
const DEFAULT_VIEW = 'renderer';
|
|
13
|
+
const PARAM_PANEL = 'panel';
|
|
14
|
+
const DEFAULT_PANEL = 'controls';
|
|
13
15
|
export class PrismUrlStateService {
|
|
14
16
|
manifestService = inject(PrismManifestService);
|
|
15
17
|
navigationService = inject(PrismNavigationService);
|
|
@@ -26,9 +28,10 @@ export class PrismUrlStateService {
|
|
|
26
28
|
const item = this.navigationService.activeItem();
|
|
27
29
|
const variantIndex = this.rendererService.activeVariantIndex();
|
|
28
30
|
const viewId = this.panelService.activeViewId();
|
|
31
|
+
const panelId = this.panelService.activePanelId();
|
|
29
32
|
if (this.suppressSync)
|
|
30
33
|
return;
|
|
31
|
-
this.writeToUrl(item, variantIndex, viewId);
|
|
34
|
+
this.writeToUrl(item, variantIndex, viewId, panelId);
|
|
32
35
|
}, { injector: this.injector });
|
|
33
36
|
window.addEventListener('popstate', () => this.restoreFromUrl());
|
|
34
37
|
}
|
|
@@ -38,6 +41,7 @@ export class PrismUrlStateService {
|
|
|
38
41
|
const pageTitle = params.get(PARAM_PAGE);
|
|
39
42
|
const variantParam = params.get(PARAM_VARIANT);
|
|
40
43
|
const viewId = params.get(PARAM_VIEW);
|
|
44
|
+
const panelId = params.get(PARAM_PANEL);
|
|
41
45
|
this.suppressSync = true;
|
|
42
46
|
try {
|
|
43
47
|
if (componentClassName) {
|
|
@@ -64,12 +68,15 @@ export class PrismUrlStateService {
|
|
|
64
68
|
if (viewId) {
|
|
65
69
|
this.panelService.activeViewId.set(viewId);
|
|
66
70
|
}
|
|
71
|
+
if (panelId) {
|
|
72
|
+
this.panelService.activePanelId.set(panelId);
|
|
73
|
+
}
|
|
67
74
|
}
|
|
68
75
|
finally {
|
|
69
76
|
this.suppressSync = false;
|
|
70
77
|
}
|
|
71
78
|
}
|
|
72
|
-
writeToUrl(item, variantIndex, viewId) {
|
|
79
|
+
writeToUrl(item, variantIndex, viewId, panelId) {
|
|
73
80
|
const params = new URLSearchParams();
|
|
74
81
|
if (item?.kind === 'component') {
|
|
75
82
|
params.set(PARAM_COMPONENT, item.data.meta.className);
|
|
@@ -83,6 +90,9 @@ export class PrismUrlStateService {
|
|
|
83
90
|
if (viewId && viewId !== DEFAULT_VIEW) {
|
|
84
91
|
params.set(PARAM_VIEW, viewId);
|
|
85
92
|
}
|
|
93
|
+
if (panelId && panelId !== DEFAULT_PANEL) {
|
|
94
|
+
params.set(PARAM_PANEL, panelId);
|
|
95
|
+
}
|
|
86
96
|
const queryString = params.toString();
|
|
87
97
|
const newUrl = queryString
|
|
88
98
|
? `${window.location.pathname}?${queryString}`
|
|
@@ -10,6 +10,7 @@ export declare class PrismShellComponent {
|
|
|
10
10
|
protected readonly panelService: PrismPanelService;
|
|
11
11
|
private readonly pluginService;
|
|
12
12
|
private readonly urlStateService;
|
|
13
|
+
private readonly persistenceService;
|
|
13
14
|
protected readonly viewPanels: import("@angular/core").Signal<import("../../plugin/plugin.types.js").PanelDefinition[]>;
|
|
14
15
|
protected readonly showPanel: import("@angular/core").Signal<boolean>;
|
|
15
16
|
protected readonly shellStyle: import("@angular/core").Signal<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-shell.component.d.ts","sourceRoot":"","sources":["../../../src/app/shell/prism-shell.component.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;;
|
|
1
|
+
{"version":3,"file":"prism-shell.component.d.ts","sourceRoot":"","sources":["../../../src/app/shell/prism-shell.component.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;;AAkBvE,qBA2Pa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,SAAS,CAAC,QAAQ,CAAC,iBAAiB,yBAAkC;IACtE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,SAAS,CAAC,QAAQ,CAAC,MAAM,qBAA8B;IACvD,SAAS,CAAC,QAAQ,CAAC,YAAY,oBAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;IAC5D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAmC;IAEtE,SAAS,CAAC,QAAQ,CAAC,UAAU,2FAG1B;IAEH,SAAS,CAAC,QAAQ,CAAC,SAAS,0CAK1B;IAEF,SAAS,CAAC,QAAQ,CAAC,UAAU,yCAG1B;;IAiCH,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI;yCA1DhC,mBAAmB;2CAAnB,mBAAmB;CA2E/B"}
|
|
@@ -14,6 +14,7 @@ import { PrismSidebarComponent } from '../sidebar/prism-sidebar.component.js';
|
|
|
14
14
|
import { PrismPageRendererComponent } from '../page-renderer/prism-page-renderer.component.js';
|
|
15
15
|
import { BUILTIN_PANELS } from '../panels/builtin-panels.js';
|
|
16
16
|
import { PrismUrlStateService } from '../services/prism-url-state.service.js';
|
|
17
|
+
import { PrismPersistenceService } from '../services/prism-persistence.service.js';
|
|
17
18
|
import { PrismViewTabBarComponent } from '../view-tab-bar/prism-view-tab-bar.component.js';
|
|
18
19
|
import { PrismViewPanelHostComponent } from '../view-tab-bar/prism-view-panel-host.component.js';
|
|
19
20
|
import { PrismResizerDirective } from '../directives/prism-resizer.directive.js';
|
|
@@ -105,6 +106,7 @@ export class PrismShellComponent {
|
|
|
105
106
|
panelService = inject(PrismPanelService);
|
|
106
107
|
pluginService = inject(PrismPluginService);
|
|
107
108
|
urlStateService = inject(PrismUrlStateService);
|
|
109
|
+
persistenceService = inject(PrismPersistenceService);
|
|
108
110
|
viewPanels = computed(() => [
|
|
109
111
|
...BUILTIN_PANELS.filter((p) => p.placement === 'view'),
|
|
110
112
|
...this.pluginService.viewPanels(),
|
|
@@ -120,6 +122,7 @@ export class PrismShellComponent {
|
|
|
120
122
|
this.themeService.applyConfigOverrides(this.config);
|
|
121
123
|
this.navigationService.selectFirst();
|
|
122
124
|
this.urlStateService.init();
|
|
125
|
+
this.persistenceService.init();
|
|
123
126
|
let lastItemKey = null;
|
|
124
127
|
effect(() => {
|
|
125
128
|
const item = this.navigationService.activeItem();
|
|
@@ -309,4 +312,4 @@ export class PrismShellComponent {
|
|
|
309
312
|
type: HostListener,
|
|
310
313
|
args: ['document:keydown', ['$event']]
|
|
311
314
|
}] }); })();
|
|
312
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismShellComponent, { className: "PrismShellComponent", filePath: "app/shell/prism-shell.component.ts", lineNumber:
|
|
315
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismShellComponent, { className: "PrismShellComponent", filePath: "app/shell/prism-shell.component.ts", lineNumber: 284 }); })();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/builder/config-loader/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAK3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,wBAAsB,UAAU,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/builder/config-loader/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAK3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,wBAAsB,UAAU,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAsCrF"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import '@angular/compiler';
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
|
|
3
|
-
import {
|
|
3
|
+
import { resolve, sep } from 'path';
|
|
4
4
|
import { pathToFileURL } from 'url';
|
|
5
5
|
import ts from 'typescript';
|
|
6
6
|
const DEFAULT_CONFIG_FILE = 'ng-prism.config.ts';
|
|
7
7
|
export async function loadConfig(options) {
|
|
8
8
|
const configFileName = options.configFileName ?? DEFAULT_CONFIG_FILE;
|
|
9
|
-
const
|
|
9
|
+
const workspaceRoot = resolve(options.workspaceRoot);
|
|
10
|
+
const configPath = resolve(workspaceRoot, configFileName);
|
|
11
|
+
if (configPath !== workspaceRoot && !configPath.startsWith(workspaceRoot + sep)) {
|
|
12
|
+
throw new Error(`ng-prism: configFile "${configFileName}" resolves outside workspace root (${workspaceRoot}). ` +
|
|
13
|
+
`Provide a path relative to the workspace.`);
|
|
14
|
+
}
|
|
10
15
|
if (!existsSync(configPath)) {
|
|
11
16
|
return {};
|
|
12
17
|
}
|
|
@@ -19,7 +24,8 @@ export async function loadConfig(options) {
|
|
|
19
24
|
esModuleInterop: true,
|
|
20
25
|
},
|
|
21
26
|
});
|
|
22
|
-
const
|
|
27
|
+
const uniqueSuffix = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
28
|
+
const tempPath = configPath.replace(/\.ts$/, `.${uniqueSuffix}.tmp.mjs`);
|
|
23
29
|
try {
|
|
24
30
|
writeFileSync(tempPath, transpiled.outputText, 'utf-8');
|
|
25
31
|
const module = await import(pathToFileURL(tempPath).href);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-runner.d.ts","sourceRoot":"","sources":["../../../src/builder/plugin-runner/plugin-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin-runner.d.ts","sourceRoot":"","sources":["../../../src/builder/plugin-runner/plugin-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,8BAA8B,CAAC;AAmBnG,wBAAsB,cAAc,CAClC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,aAAa,EAAE,GACvB,OAAO,CAAC,aAAa,CAAC,CAuDxB"}
|
|
@@ -1,25 +1,46 @@
|
|
|
1
|
+
function pluginLabel(plugin) {
|
|
2
|
+
return plugin.name ? `"${plugin.name}"` : '<unnamed>';
|
|
3
|
+
}
|
|
4
|
+
function wrapPluginError(plugin, hook, target, err) {
|
|
5
|
+
const cause = err instanceof Error ? err.message : String(err);
|
|
6
|
+
const wrapped = new Error(`ng-prism: plugin ${pluginLabel(plugin)} failed in ${hook} for ${target} — ${cause}`, err instanceof Error ? { cause: err } : undefined);
|
|
7
|
+
if (err instanceof Error && err.stack) {
|
|
8
|
+
wrapped.stack = `${wrapped.message}\nCaused by: ${err.stack}`;
|
|
9
|
+
}
|
|
10
|
+
return wrapped;
|
|
11
|
+
}
|
|
1
12
|
export async function runPluginHooks(manifest, plugins) {
|
|
2
|
-
|
|
3
|
-
for (
|
|
4
|
-
let current =
|
|
13
|
+
const components = [...manifest.components];
|
|
14
|
+
for (let i = 0; i < components.length; i++) {
|
|
15
|
+
let current = components[i];
|
|
5
16
|
for (const plugin of plugins) {
|
|
6
17
|
if (plugin.onComponentScanned) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
18
|
+
try {
|
|
19
|
+
const result = await plugin.onComponentScanned(current);
|
|
20
|
+
if (result) {
|
|
21
|
+
current = result;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
throw wrapPluginError(plugin, 'onComponentScanned', `component "${current.className}"`, err);
|
|
10
26
|
}
|
|
11
27
|
}
|
|
12
28
|
}
|
|
13
|
-
components[
|
|
29
|
+
components[i] = current;
|
|
14
30
|
}
|
|
15
|
-
|
|
31
|
+
const pages = [...(manifest.pages ?? [])];
|
|
16
32
|
for (let i = 0; i < pages.length; i++) {
|
|
17
33
|
let current = pages[i];
|
|
18
34
|
for (const plugin of plugins) {
|
|
19
35
|
if (plugin.onPageScanned) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
36
|
+
try {
|
|
37
|
+
const result = await plugin.onPageScanned(current);
|
|
38
|
+
if (result) {
|
|
39
|
+
current = result;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
throw wrapPluginError(plugin, 'onPageScanned', `page "${current.title}"`, err);
|
|
23
44
|
}
|
|
24
45
|
}
|
|
25
46
|
}
|
|
@@ -28,9 +49,14 @@ export async function runPluginHooks(manifest, plugins) {
|
|
|
28
49
|
let result = { components, pages };
|
|
29
50
|
for (const plugin of plugins) {
|
|
30
51
|
if (plugin.onManifestReady) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
52
|
+
try {
|
|
53
|
+
const updated = await plugin.onManifestReady(result);
|
|
54
|
+
if (updated) {
|
|
55
|
+
result = updated;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
throw wrapPluginError(plugin, 'onManifestReady', 'manifest', err);
|
|
34
60
|
}
|
|
35
61
|
}
|
|
36
62
|
}
|
|
@@ -16,14 +16,14 @@ export function scanComponents(exports, checker) {
|
|
|
16
16
|
const showcaseDecorator = findDecorator(classDecl, 'Showcase');
|
|
17
17
|
if (!showcaseDecorator)
|
|
18
18
|
continue;
|
|
19
|
-
const
|
|
19
|
+
const className = classDecl.name?.text ?? 'Anonymous';
|
|
20
|
+
const showcaseConfig = extractShowcaseConfig(showcaseDecorator, className);
|
|
20
21
|
if (!showcaseConfig)
|
|
21
22
|
continue;
|
|
22
23
|
const componentMeta = extractComponentMeta(classDecl);
|
|
23
24
|
const inputs = extractInputs(classDecl, checker);
|
|
24
25
|
const outputs = extractOutputs(classDecl, checker);
|
|
25
26
|
const filePath = classDecl.getSourceFile().fileName;
|
|
26
|
-
const className = classDecl.name?.text ?? 'Anonymous';
|
|
27
27
|
if (hasDecoratorInputs(classDecl)) {
|
|
28
28
|
console.warn(`⚠ ng-prism: ${className} uses @Input() decorators which are not fully supported. ` +
|
|
29
29
|
`Migrate to input() signals for full ng-prism support.`);
|
|
@@ -48,13 +48,18 @@ function hasDecoratorInputs(classDecl) {
|
|
|
48
48
|
}
|
|
49
49
|
return false;
|
|
50
50
|
}
|
|
51
|
-
function extractShowcaseConfig(decorator) {
|
|
51
|
+
function extractShowcaseConfig(decorator, className) {
|
|
52
52
|
const arg = getDecoratorArgument(decorator);
|
|
53
53
|
if (!arg)
|
|
54
54
|
return undefined;
|
|
55
55
|
const raw = evaluateExpression(arg);
|
|
56
|
-
if (!raw || typeof raw !== 'object'
|
|
56
|
+
if (!raw || typeof raw !== 'object')
|
|
57
57
|
return undefined;
|
|
58
|
+
if (!('title' in raw)) {
|
|
59
|
+
console.warn(`⚠ ng-prism: ${className} has @Showcase without a "title" field — skipping. ` +
|
|
60
|
+
`Add a title so it can appear in the styleguide.`);
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
58
63
|
const obj = raw;
|
|
59
64
|
const config = {
|
|
60
65
|
title: obj['title'],
|
|
@@ -6,6 +6,24 @@ export function discoverSecondaryEntryPoints(libraryRoot, baseImportPath) {
|
|
|
6
6
|
return entryPoints;
|
|
7
7
|
}
|
|
8
8
|
function findNgPackageJsons(dir, libraryRoot, baseImportPath, result) {
|
|
9
|
+
const isLibraryRoot = dir === libraryRoot;
|
|
10
|
+
const ngPackagePath = join(dir, 'ng-package.json');
|
|
11
|
+
if (existsSync(ngPackagePath)) {
|
|
12
|
+
const ngPackage = JSON.parse(readFileSync(ngPackagePath, 'utf-8'));
|
|
13
|
+
if (!ngPackage.dest) {
|
|
14
|
+
const entryFile = ngPackage.lib?.entryFile ?? 'public-api.ts';
|
|
15
|
+
const entryFilePath = join(dir, entryFile);
|
|
16
|
+
if (existsSync(entryFilePath)) {
|
|
17
|
+
const relDir = relative(libraryRoot, dir);
|
|
18
|
+
const importPath = relDir === ''
|
|
19
|
+
? baseImportPath
|
|
20
|
+
: posix.join(baseImportPath, relDir.split('\\').join('/'));
|
|
21
|
+
result.push({ entryFile: entryFilePath, importPath });
|
|
22
|
+
}
|
|
23
|
+
if (!isLibraryRoot)
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
9
27
|
let entries;
|
|
10
28
|
try {
|
|
11
29
|
entries = readdirSync(dir);
|
|
@@ -17,22 +35,13 @@ function findNgPackageJsons(dir, libraryRoot, baseImportPath, result) {
|
|
|
17
35
|
if (entry === 'node_modules' || entry === '.git')
|
|
18
36
|
continue;
|
|
19
37
|
const fullPath = join(dir, entry);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (!existsSync(ngPackagePath)) {
|
|
24
|
-
findNgPackageJsons(fullPath, libraryRoot, baseImportPath, result);
|
|
25
|
-
continue;
|
|
38
|
+
try {
|
|
39
|
+
if (!statSync(fullPath).isDirectory())
|
|
40
|
+
continue;
|
|
26
41
|
}
|
|
27
|
-
|
|
28
|
-
if (ngPackage.dest)
|
|
42
|
+
catch {
|
|
29
43
|
continue;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (!existsSync(entryFilePath))
|
|
33
|
-
continue;
|
|
34
|
-
const relDir = relative(libraryRoot, fullPath);
|
|
35
|
-
const importPath = posix.join(baseImportPath, relDir.split('\\').join('/'));
|
|
36
|
-
result.push({ entryFile: entryFilePath, importPath });
|
|
44
|
+
}
|
|
45
|
+
findNgPackageJsons(fullPath, libraryRoot, baseImportPath, result);
|
|
37
46
|
}
|
|
38
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/builder/serve/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAA2C,MAAM,2BAA2B,CAAC;AACjH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAGjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/builder/serve/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAA2C,MAAM,2BAA2B,CAAC;AACjH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAGjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AA+DtD,QAAA,MAAM,OAAO,EAAE,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,UAAU,CAAyD,CAAC;AACrH,eAAe,OAAO,CAAC"}
|