@aigne/afs-ui 1.11.0-beta.12
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/LICENSE.md +26 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +10 -0
- package/dist/aup-protocol.cjs +235 -0
- package/dist/aup-protocol.d.cts +78 -0
- package/dist/aup-protocol.d.cts.map +1 -0
- package/dist/aup-protocol.d.mts +78 -0
- package/dist/aup-protocol.d.mts.map +1 -0
- package/dist/aup-protocol.mjs +235 -0
- package/dist/aup-protocol.mjs.map +1 -0
- package/dist/aup-registry.cjs +2489 -0
- package/dist/aup-registry.mjs +2487 -0
- package/dist/aup-registry.mjs.map +1 -0
- package/dist/aup-spec.cjs +1467 -0
- package/dist/aup-spec.mjs +1466 -0
- package/dist/aup-spec.mjs.map +1 -0
- package/dist/aup-types.cjs +165 -0
- package/dist/aup-types.d.cts +157 -0
- package/dist/aup-types.d.cts.map +1 -0
- package/dist/aup-types.d.mts +157 -0
- package/dist/aup-types.d.mts.map +1 -0
- package/dist/aup-types.mjs +157 -0
- package/dist/aup-types.mjs.map +1 -0
- package/dist/backend.cjs +14 -0
- package/dist/backend.d.cts +104 -0
- package/dist/backend.d.cts.map +1 -0
- package/dist/backend.d.mts +104 -0
- package/dist/backend.d.mts.map +1 -0
- package/dist/backend.mjs +13 -0
- package/dist/backend.mjs.map +1 -0
- package/dist/degradation.cjs +85 -0
- package/dist/degradation.d.cts +17 -0
- package/dist/degradation.d.cts.map +1 -0
- package/dist/degradation.d.mts +17 -0
- package/dist/degradation.d.mts.map +1 -0
- package/dist/degradation.mjs +84 -0
- package/dist/degradation.mjs.map +1 -0
- package/dist/index.cjs +36 -0
- package/dist/index.d.cts +12 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.mjs +13 -0
- package/dist/runtime.cjs +117 -0
- package/dist/runtime.d.cts +59 -0
- package/dist/runtime.d.cts.map +1 -0
- package/dist/runtime.d.mts +59 -0
- package/dist/runtime.d.mts.map +1 -0
- package/dist/runtime.mjs +118 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/session.cjs +159 -0
- package/dist/session.d.cts +80 -0
- package/dist/session.d.cts.map +1 -0
- package/dist/session.d.mts +80 -0
- package/dist/session.d.mts.map +1 -0
- package/dist/session.mjs +159 -0
- package/dist/session.mjs.map +1 -0
- package/dist/snapshot.cjs +162 -0
- package/dist/snapshot.mjs +163 -0
- package/dist/snapshot.mjs.map +1 -0
- package/dist/term-page.cjs +264 -0
- package/dist/term-page.mjs +264 -0
- package/dist/term-page.mjs.map +1 -0
- package/dist/term.cjs +295 -0
- package/dist/term.d.cts +84 -0
- package/dist/term.d.cts.map +1 -0
- package/dist/term.d.mts +84 -0
- package/dist/term.d.mts.map +1 -0
- package/dist/term.mjs +296 -0
- package/dist/term.mjs.map +1 -0
- package/dist/tty.cjs +136 -0
- package/dist/tty.d.cts +53 -0
- package/dist/tty.d.cts.map +1 -0
- package/dist/tty.d.mts +53 -0
- package/dist/tty.d.mts.map +1 -0
- package/dist/tty.mjs +135 -0
- package/dist/tty.mjs.map +1 -0
- package/dist/ui-provider.cjs +4615 -0
- package/dist/ui-provider.d.cts +307 -0
- package/dist/ui-provider.d.cts.map +1 -0
- package/dist/ui-provider.d.mts +307 -0
- package/dist/ui-provider.d.mts.map +1 -0
- package/dist/ui-provider.mjs +4616 -0
- package/dist/ui-provider.mjs.map +1 -0
- package/dist/web-page/core.cjs +1388 -0
- package/dist/web-page/core.mjs +1387 -0
- package/dist/web-page/core.mjs.map +1 -0
- package/dist/web-page/css.cjs +1699 -0
- package/dist/web-page/css.mjs +1698 -0
- package/dist/web-page/css.mjs.map +1 -0
- package/dist/web-page/icons.cjs +248 -0
- package/dist/web-page/icons.mjs +248 -0
- package/dist/web-page/icons.mjs.map +1 -0
- package/dist/web-page/overlay-themes.cjs +514 -0
- package/dist/web-page/overlay-themes.mjs +513 -0
- package/dist/web-page/overlay-themes.mjs.map +1 -0
- package/dist/web-page/renderers/action.cjs +72 -0
- package/dist/web-page/renderers/action.mjs +72 -0
- package/dist/web-page/renderers/action.mjs.map +1 -0
- package/dist/web-page/renderers/broadcast.cjs +160 -0
- package/dist/web-page/renderers/broadcast.mjs +160 -0
- package/dist/web-page/renderers/broadcast.mjs.map +1 -0
- package/dist/web-page/renderers/calendar.cjs +137 -0
- package/dist/web-page/renderers/calendar.mjs +137 -0
- package/dist/web-page/renderers/calendar.mjs.map +1 -0
- package/dist/web-page/renderers/canvas.cjs +173 -0
- package/dist/web-page/renderers/canvas.mjs +173 -0
- package/dist/web-page/renderers/canvas.mjs.map +1 -0
- package/dist/web-page/renderers/cdn-loader.cjs +25 -0
- package/dist/web-page/renderers/cdn-loader.mjs +25 -0
- package/dist/web-page/renderers/cdn-loader.mjs.map +1 -0
- package/dist/web-page/renderers/chart.cjs +101 -0
- package/dist/web-page/renderers/chart.mjs +101 -0
- package/dist/web-page/renderers/chart.mjs.map +1 -0
- package/dist/web-page/renderers/deck.cjs +390 -0
- package/dist/web-page/renderers/deck.mjs +390 -0
- package/dist/web-page/renderers/deck.mjs.map +1 -0
- package/dist/web-page/renderers/device.cjs +1015 -0
- package/dist/web-page/renderers/device.mjs +1015 -0
- package/dist/web-page/renderers/device.mjs.map +1 -0
- package/dist/web-page/renderers/editor.cjs +127 -0
- package/dist/web-page/renderers/editor.mjs +127 -0
- package/dist/web-page/renderers/editor.mjs.map +1 -0
- package/dist/web-page/renderers/finance-chart.cjs +178 -0
- package/dist/web-page/renderers/finance-chart.mjs +178 -0
- package/dist/web-page/renderers/finance-chart.mjs.map +1 -0
- package/dist/web-page/renderers/frame.cjs +274 -0
- package/dist/web-page/renderers/frame.mjs +274 -0
- package/dist/web-page/renderers/frame.mjs.map +1 -0
- package/dist/web-page/renderers/globe.cjs +119 -0
- package/dist/web-page/renderers/globe.mjs +119 -0
- package/dist/web-page/renderers/globe.mjs.map +1 -0
- package/dist/web-page/renderers/input.cjs +137 -0
- package/dist/web-page/renderers/input.mjs +137 -0
- package/dist/web-page/renderers/input.mjs.map +1 -0
- package/dist/web-page/renderers/list.cjs +1243 -0
- package/dist/web-page/renderers/list.mjs +1243 -0
- package/dist/web-page/renderers/list.mjs.map +1 -0
- package/dist/web-page/renderers/map.cjs +126 -0
- package/dist/web-page/renderers/map.mjs +126 -0
- package/dist/web-page/renderers/map.mjs.map +1 -0
- package/dist/web-page/renderers/media.cjs +106 -0
- package/dist/web-page/renderers/media.mjs +106 -0
- package/dist/web-page/renderers/media.mjs.map +1 -0
- package/dist/web-page/renderers/moonphase.cjs +105 -0
- package/dist/web-page/renderers/moonphase.mjs +105 -0
- package/dist/web-page/renderers/moonphase.mjs.map +1 -0
- package/dist/web-page/renderers/natal-chart.cjs +222 -0
- package/dist/web-page/renderers/natal-chart.mjs +222 -0
- package/dist/web-page/renderers/natal-chart.mjs.map +1 -0
- package/dist/web-page/renderers/overlay.cjs +531 -0
- package/dist/web-page/renderers/overlay.mjs +531 -0
- package/dist/web-page/renderers/overlay.mjs.map +1 -0
- package/dist/web-page/renderers/table.cjs +74 -0
- package/dist/web-page/renderers/table.mjs +74 -0
- package/dist/web-page/renderers/table.mjs.map +1 -0
- package/dist/web-page/renderers/terminal.cjs +30 -0
- package/dist/web-page/renderers/terminal.mjs +30 -0
- package/dist/web-page/renderers/terminal.mjs.map +1 -0
- package/dist/web-page/renderers/text.cjs +109 -0
- package/dist/web-page/renderers/text.mjs +109 -0
- package/dist/web-page/renderers/text.mjs.map +1 -0
- package/dist/web-page/renderers/ticker.cjs +133 -0
- package/dist/web-page/renderers/ticker.mjs +133 -0
- package/dist/web-page/renderers/ticker.mjs.map +1 -0
- package/dist/web-page/renderers/time.cjs +69 -0
- package/dist/web-page/renderers/time.mjs +69 -0
- package/dist/web-page/renderers/time.mjs.map +1 -0
- package/dist/web-page/renderers/unknown.cjs +20 -0
- package/dist/web-page/renderers/unknown.mjs +20 -0
- package/dist/web-page/renderers/unknown.mjs.map +1 -0
- package/dist/web-page/renderers/view.cjs +161 -0
- package/dist/web-page/renderers/view.mjs +161 -0
- package/dist/web-page/renderers/view.mjs.map +1 -0
- package/dist/web-page/renderers/wm.cjs +669 -0
- package/dist/web-page/renderers/wm.mjs +669 -0
- package/dist/web-page/renderers/wm.mjs.map +1 -0
- package/dist/web-page/skeleton.cjs +103 -0
- package/dist/web-page/skeleton.mjs +103 -0
- package/dist/web-page/skeleton.mjs.map +1 -0
- package/dist/web-page.cjs +114 -0
- package/dist/web-page.d.cts +19 -0
- package/dist/web-page.d.cts.map +1 -0
- package/dist/web-page.d.mts +19 -0
- package/dist/web-page.d.mts.map +1 -0
- package/dist/web-page.mjs +115 -0
- package/dist/web-page.mjs.map +1 -0
- package/dist/web.cjs +827 -0
- package/dist/web.d.cts +144 -0
- package/dist/web.d.cts.map +1 -0
- package/dist/web.d.mts +144 -0
- package/dist/web.d.mts.map +1 -0
- package/dist/web.mjs +828 -0
- package/dist/web.mjs.map +1 -0
- package/dist/wm-state.cjs +172 -0
- package/dist/wm-state.mjs +171 -0
- package/dist/wm-state.mjs.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
//#region src/web-page/renderers/finance-chart.ts
|
|
2
|
+
const FINANCE_CHART_JS = `
|
|
3
|
+
// ── Finance Chart Primitive (TradingView Lightweight Charts v5) ──
|
|
4
|
+
|
|
5
|
+
function renderAupFinanceChart(node) {
|
|
6
|
+
var el = document.createElement("div");
|
|
7
|
+
el.className = "aup-finance-chart";
|
|
8
|
+
var p = node.props || {};
|
|
9
|
+
var variant = p.variant || "candlestick";
|
|
10
|
+
if (p.height) el.style.height = p.height;
|
|
11
|
+
else el.style.height = "400px";
|
|
12
|
+
|
|
13
|
+
var chartDiv = document.createElement("div");
|
|
14
|
+
chartDiv.style.width = "100%";
|
|
15
|
+
chartDiv.style.height = "100%";
|
|
16
|
+
el.appendChild(chartDiv);
|
|
17
|
+
|
|
18
|
+
function isDarkMode() {
|
|
19
|
+
var bg = getComputedStyle(document.documentElement).getPropertyValue("--bg").trim();
|
|
20
|
+
if (!bg) return true;
|
|
21
|
+
// Simple heuristic: dark if bg starts with # and first hex digit < 8
|
|
22
|
+
if (bg.charAt(0) === "#") {
|
|
23
|
+
var r = parseInt(bg.substring(1, 3), 16);
|
|
24
|
+
return r < 128;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function chartColors() {
|
|
30
|
+
var dark = isDarkMode();
|
|
31
|
+
return {
|
|
32
|
+
bg: "transparent",
|
|
33
|
+
text: dark ? "#d1d5db" : "#374151",
|
|
34
|
+
grid: dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.06)",
|
|
35
|
+
crosshair: dark ? "#6b7280" : "#9ca3af",
|
|
36
|
+
upColor: p.upColor || "#26a69a",
|
|
37
|
+
downColor: p.downColor || "#ef5350",
|
|
38
|
+
lineColor: p.lineColor || "#2962FF",
|
|
39
|
+
areaTop: p.areaTopColor || "rgba(41,98,255,0.4)",
|
|
40
|
+
areaBottom: p.areaBottomColor || "rgba(41,98,255,0)",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function initFinanceChart() {
|
|
45
|
+
if (typeof LightweightCharts === "undefined") {
|
|
46
|
+
var loading = document.createElement("div");
|
|
47
|
+
loading.className = "aup-finance-chart-loading";
|
|
48
|
+
loading.textContent = "Loading chart...";
|
|
49
|
+
el.insertBefore(loading, chartDiv);
|
|
50
|
+
loadScript("https://cdn.jsdelivr.net/npm/lightweight-charts@5/dist/lightweight-charts.standalone.production.js", function() {
|
|
51
|
+
if (loading.parentNode) loading.parentNode.removeChild(loading);
|
|
52
|
+
createFinanceChart();
|
|
53
|
+
});
|
|
54
|
+
} else {
|
|
55
|
+
createFinanceChart();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var chartInstance = null;
|
|
60
|
+
var primarySeries = null;
|
|
61
|
+
var volumeSeries = null;
|
|
62
|
+
|
|
63
|
+
function createFinanceChart() {
|
|
64
|
+
try {
|
|
65
|
+
var c = chartColors();
|
|
66
|
+
chartInstance = LightweightCharts.createChart(chartDiv, {
|
|
67
|
+
layout: { background: { type: "solid", color: c.bg }, textColor: c.text, fontFamily: "inherit" },
|
|
68
|
+
grid: { vertLines: { color: c.grid }, horzLines: { color: c.grid } },
|
|
69
|
+
crosshair: { vertLine: { color: c.crosshair, labelBackgroundColor: c.crosshair }, horzLine: { color: c.crosshair, labelBackgroundColor: c.crosshair } },
|
|
70
|
+
rightPriceScale: { borderColor: c.grid },
|
|
71
|
+
timeScale: { borderColor: c.grid, timeVisible: true },
|
|
72
|
+
autoSize: true,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Add primary series based on variant
|
|
76
|
+
if (variant === "candlestick") {
|
|
77
|
+
primarySeries = chartInstance.addSeries(LightweightCharts.CandlestickSeries, {
|
|
78
|
+
upColor: c.upColor, downColor: c.downColor, borderVisible: false,
|
|
79
|
+
wickUpColor: c.upColor, wickDownColor: c.downColor,
|
|
80
|
+
});
|
|
81
|
+
} else if (variant === "ohlc") {
|
|
82
|
+
primarySeries = chartInstance.addSeries(LightweightCharts.BarSeries, {
|
|
83
|
+
upColor: c.upColor, downColor: c.downColor,
|
|
84
|
+
});
|
|
85
|
+
} else if (variant === "trading-line") {
|
|
86
|
+
primarySeries = chartInstance.addSeries(LightweightCharts.LineSeries, {
|
|
87
|
+
color: c.lineColor, lineWidth: 2,
|
|
88
|
+
});
|
|
89
|
+
} else if (variant === "trading-area") {
|
|
90
|
+
primarySeries = chartInstance.addSeries(LightweightCharts.AreaSeries, {
|
|
91
|
+
lineColor: c.lineColor, topColor: c.areaTop, bottomColor: c.areaBottom, lineWidth: 2,
|
|
92
|
+
});
|
|
93
|
+
} else if (variant === "baseline") {
|
|
94
|
+
var bv = p.baseValue || 0;
|
|
95
|
+
primarySeries = chartInstance.addSeries(LightweightCharts.BaselineSeries, {
|
|
96
|
+
baseValue: { type: "price", price: bv },
|
|
97
|
+
topLineColor: c.upColor, topFillColor1: "rgba(38,166,154,0.28)", topFillColor2: "rgba(38,166,154,0)",
|
|
98
|
+
bottomLineColor: c.downColor, bottomFillColor1: "rgba(239,83,80,0)", bottomFillColor2: "rgba(239,83,80,0.28)",
|
|
99
|
+
});
|
|
100
|
+
} else if (variant === "volume") {
|
|
101
|
+
primarySeries = chartInstance.addSeries(LightweightCharts.HistogramSeries, {
|
|
102
|
+
priceFormat: { type: "volume" },
|
|
103
|
+
priceScaleId: "",
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Optional volume overlay (for candlestick/ohlc)
|
|
108
|
+
if (p.volumeData || p.showVolume) {
|
|
109
|
+
volumeSeries = chartInstance.addSeries(LightweightCharts.HistogramSeries, {
|
|
110
|
+
priceFormat: { type: "volume" },
|
|
111
|
+
priceScaleId: "volume",
|
|
112
|
+
});
|
|
113
|
+
chartInstance.priceScale("volume").applyOptions({
|
|
114
|
+
scaleMargins: { top: 0.8, bottom: 0 },
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Set data
|
|
119
|
+
var data = p.data || [];
|
|
120
|
+
if (data.length) {
|
|
121
|
+
primarySeries.setData(data);
|
|
122
|
+
if (volumeSeries && p.volumeData) volumeSeries.setData(p.volumeData);
|
|
123
|
+
chartInstance.timeScale().fitContent();
|
|
124
|
+
}
|
|
125
|
+
} catch(e) {
|
|
126
|
+
chartDiv.textContent = "Chart error: " + e.message;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function updateFinanceData(raw) {
|
|
131
|
+
var d = (typeof raw === "object" && raw !== null) ? raw : {};
|
|
132
|
+
if (d.content && typeof d.content === "object") d = d.content;
|
|
133
|
+
if (primarySeries && d.data) {
|
|
134
|
+
primarySeries.setData(d.data);
|
|
135
|
+
if (volumeSeries && d.volumeData) volumeSeries.setData(d.volumeData);
|
|
136
|
+
if (chartInstance) chartInstance.timeScale().fitContent();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src binding
|
|
141
|
+
if (node.src && window.afs) {
|
|
142
|
+
var loading = document.createElement("div");
|
|
143
|
+
loading.className = "aup-finance-chart-loading";
|
|
144
|
+
loading.textContent = "Loading data...";
|
|
145
|
+
el.insertBefore(loading, chartDiv);
|
|
146
|
+
|
|
147
|
+
function applyFinanceData(raw) {
|
|
148
|
+
if (loading.parentNode) loading.parentNode.removeChild(loading);
|
|
149
|
+
if (!chartInstance) {
|
|
150
|
+
// Chart not created yet — store data and init
|
|
151
|
+
var d = (typeof raw === "object" && raw !== null) ? raw : {};
|
|
152
|
+
if (d.content && typeof d.content === "object") d = d.content;
|
|
153
|
+
if (d.data) p.data = d.data;
|
|
154
|
+
if (d.volumeData) { p.volumeData = d.volumeData; p.showVolume = true; }
|
|
155
|
+
initFinanceChart();
|
|
156
|
+
} else {
|
|
157
|
+
updateFinanceData(raw);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
window.afs.read(node.src).then(applyFinanceData).catch(function(e) {
|
|
162
|
+
loading.textContent = "Data error: " + e.message;
|
|
163
|
+
});
|
|
164
|
+
window.afs.subscribe({ type: "afs:write", path: node.src }, function(event) {
|
|
165
|
+
if (event && event.data) applyFinanceData(event.data);
|
|
166
|
+
});
|
|
167
|
+
} else {
|
|
168
|
+
setTimeout(initFinanceChart, 0);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return el;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
`;
|
|
175
|
+
|
|
176
|
+
//#endregion
|
|
177
|
+
export { FINANCE_CHART_JS };
|
|
178
|
+
//# sourceMappingURL=finance-chart.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finance-chart.mjs","names":[],"sources":["../../../src/web-page/renderers/finance-chart.ts"],"sourcesContent":["export const FINANCE_CHART_JS = `\n // ── Finance Chart Primitive (TradingView Lightweight Charts v5) ──\n\n function renderAupFinanceChart(node) {\n var el = document.createElement(\"div\");\n el.className = \"aup-finance-chart\";\n var p = node.props || {};\n var variant = p.variant || \"candlestick\";\n if (p.height) el.style.height = p.height;\n else el.style.height = \"400px\";\n\n var chartDiv = document.createElement(\"div\");\n chartDiv.style.width = \"100%\";\n chartDiv.style.height = \"100%\";\n el.appendChild(chartDiv);\n\n function isDarkMode() {\n var bg = getComputedStyle(document.documentElement).getPropertyValue(\"--bg\").trim();\n if (!bg) return true;\n // Simple heuristic: dark if bg starts with # and first hex digit < 8\n if (bg.charAt(0) === \"#\") {\n var r = parseInt(bg.substring(1, 3), 16);\n return r < 128;\n }\n return true;\n }\n\n function chartColors() {\n var dark = isDarkMode();\n return {\n bg: \"transparent\",\n text: dark ? \"#d1d5db\" : \"#374151\",\n grid: dark ? \"rgba(255,255,255,0.06)\" : \"rgba(0,0,0,0.06)\",\n crosshair: dark ? \"#6b7280\" : \"#9ca3af\",\n upColor: p.upColor || \"#26a69a\",\n downColor: p.downColor || \"#ef5350\",\n lineColor: p.lineColor || \"#2962FF\",\n areaTop: p.areaTopColor || \"rgba(41,98,255,0.4)\",\n areaBottom: p.areaBottomColor || \"rgba(41,98,255,0)\",\n };\n }\n\n function initFinanceChart() {\n if (typeof LightweightCharts === \"undefined\") {\n var loading = document.createElement(\"div\");\n loading.className = \"aup-finance-chart-loading\";\n loading.textContent = \"Loading chart...\";\n el.insertBefore(loading, chartDiv);\n loadScript(\"https://cdn.jsdelivr.net/npm/lightweight-charts@5/dist/lightweight-charts.standalone.production.js\", function() {\n if (loading.parentNode) loading.parentNode.removeChild(loading);\n createFinanceChart();\n });\n } else {\n createFinanceChart();\n }\n }\n\n var chartInstance = null;\n var primarySeries = null;\n var volumeSeries = null;\n\n function createFinanceChart() {\n try {\n var c = chartColors();\n chartInstance = LightweightCharts.createChart(chartDiv, {\n layout: { background: { type: \"solid\", color: c.bg }, textColor: c.text, fontFamily: \"inherit\" },\n grid: { vertLines: { color: c.grid }, horzLines: { color: c.grid } },\n crosshair: { vertLine: { color: c.crosshair, labelBackgroundColor: c.crosshair }, horzLine: { color: c.crosshair, labelBackgroundColor: c.crosshair } },\n rightPriceScale: { borderColor: c.grid },\n timeScale: { borderColor: c.grid, timeVisible: true },\n autoSize: true,\n });\n\n // Add primary series based on variant\n if (variant === \"candlestick\") {\n primarySeries = chartInstance.addSeries(LightweightCharts.CandlestickSeries, {\n upColor: c.upColor, downColor: c.downColor, borderVisible: false,\n wickUpColor: c.upColor, wickDownColor: c.downColor,\n });\n } else if (variant === \"ohlc\") {\n primarySeries = chartInstance.addSeries(LightweightCharts.BarSeries, {\n upColor: c.upColor, downColor: c.downColor,\n });\n } else if (variant === \"trading-line\") {\n primarySeries = chartInstance.addSeries(LightweightCharts.LineSeries, {\n color: c.lineColor, lineWidth: 2,\n });\n } else if (variant === \"trading-area\") {\n primarySeries = chartInstance.addSeries(LightweightCharts.AreaSeries, {\n lineColor: c.lineColor, topColor: c.areaTop, bottomColor: c.areaBottom, lineWidth: 2,\n });\n } else if (variant === \"baseline\") {\n var bv = p.baseValue || 0;\n primarySeries = chartInstance.addSeries(LightweightCharts.BaselineSeries, {\n baseValue: { type: \"price\", price: bv },\n topLineColor: c.upColor, topFillColor1: \"rgba(38,166,154,0.28)\", topFillColor2: \"rgba(38,166,154,0)\",\n bottomLineColor: c.downColor, bottomFillColor1: \"rgba(239,83,80,0)\", bottomFillColor2: \"rgba(239,83,80,0.28)\",\n });\n } else if (variant === \"volume\") {\n primarySeries = chartInstance.addSeries(LightweightCharts.HistogramSeries, {\n priceFormat: { type: \"volume\" },\n priceScaleId: \"\",\n });\n }\n\n // Optional volume overlay (for candlestick/ohlc)\n if (p.volumeData || p.showVolume) {\n volumeSeries = chartInstance.addSeries(LightweightCharts.HistogramSeries, {\n priceFormat: { type: \"volume\" },\n priceScaleId: \"volume\",\n });\n chartInstance.priceScale(\"volume\").applyOptions({\n scaleMargins: { top: 0.8, bottom: 0 },\n });\n }\n\n // Set data\n var data = p.data || [];\n if (data.length) {\n primarySeries.setData(data);\n if (volumeSeries && p.volumeData) volumeSeries.setData(p.volumeData);\n chartInstance.timeScale().fitContent();\n }\n } catch(e) {\n chartDiv.textContent = \"Chart error: \" + e.message;\n }\n }\n\n function updateFinanceData(raw) {\n var d = (typeof raw === \"object\" && raw !== null) ? raw : {};\n if (d.content && typeof d.content === \"object\") d = d.content;\n if (primarySeries && d.data) {\n primarySeries.setData(d.data);\n if (volumeSeries && d.volumeData) volumeSeries.setData(d.volumeData);\n if (chartInstance) chartInstance.timeScale().fitContent();\n }\n }\n\n // src binding\n if (node.src && window.afs) {\n var loading = document.createElement(\"div\");\n loading.className = \"aup-finance-chart-loading\";\n loading.textContent = \"Loading data...\";\n el.insertBefore(loading, chartDiv);\n\n function applyFinanceData(raw) {\n if (loading.parentNode) loading.parentNode.removeChild(loading);\n if (!chartInstance) {\n // Chart not created yet — store data and init\n var d = (typeof raw === \"object\" && raw !== null) ? raw : {};\n if (d.content && typeof d.content === \"object\") d = d.content;\n if (d.data) p.data = d.data;\n if (d.volumeData) { p.volumeData = d.volumeData; p.showVolume = true; }\n initFinanceChart();\n } else {\n updateFinanceData(raw);\n }\n }\n\n window.afs.read(node.src).then(applyFinanceData).catch(function(e) {\n loading.textContent = \"Data error: \" + e.message;\n });\n window.afs.subscribe({ type: \"afs:write\", path: node.src }, function(event) {\n if (event && event.data) applyFinanceData(event.data);\n });\n } else {\n setTimeout(initFinanceChart, 0);\n }\n\n return el;\n }\n\n`;\n"],"mappings":";AAAA,MAAa,mBAAmB"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/web-page/renderers/frame.ts
|
|
3
|
+
const FRAME_JS = `
|
|
4
|
+
// ── Frame Renderer (sandboxed iframe for page isolation) ──
|
|
5
|
+
|
|
6
|
+
// Track known iframe contentWindows for origin validation
|
|
7
|
+
var _aupFrameWindows = new Set();
|
|
8
|
+
var _aupBridgeWindows = new Set();
|
|
9
|
+
var _aupBridgeOriginByWindow = new Map();
|
|
10
|
+
|
|
11
|
+
function _isHttpUrl(src) {
|
|
12
|
+
try {
|
|
13
|
+
var u = new URL(src, location.href);
|
|
14
|
+
return u.protocol === "http:" || u.protocol === "https:";
|
|
15
|
+
} catch (_ex) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function _isSameOriginUrl(src) {
|
|
21
|
+
try {
|
|
22
|
+
return new URL(src, location.href).origin === location.origin;
|
|
23
|
+
} catch (_ex) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function _resolveFrameSrc(rawSrc, bridgeRequested) {
|
|
29
|
+
var src = typeof rawSrc === "string" ? rawSrc.trim() : "";
|
|
30
|
+
if (!src) return null;
|
|
31
|
+
|
|
32
|
+
if (src.indexOf("/pages/") === 0) {
|
|
33
|
+
var pageId = src.replace(/^\\/pages\\//, "");
|
|
34
|
+
if (!pageId) return null;
|
|
35
|
+
var query = [];
|
|
36
|
+
if (_afsSessionId) query.push("sid=" + encodeURIComponent(_afsSessionId));
|
|
37
|
+
if (_afsSessionToken) query.push("st=" + encodeURIComponent(_afsSessionToken));
|
|
38
|
+
if (bridgeRequested) query.push("bridge=1");
|
|
39
|
+
var localUrl = location.origin + "/p/" + encodeURIComponent(pageId);
|
|
40
|
+
if (query.length) localUrl += "?" + query.join("&");
|
|
41
|
+
return { url: localUrl, bridgeEnabled: !!bridgeRequested };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (_isHttpUrl(src)) {
|
|
45
|
+
return {
|
|
46
|
+
url: src,
|
|
47
|
+
bridgeEnabled: !!bridgeRequested && _isSameOriginUrl(src),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function _normalizeSandbox(rawSandbox, bridgeEnabled) {
|
|
55
|
+
var base = ["allow-scripts", "allow-forms", "allow-popups"];
|
|
56
|
+
var allowed = {
|
|
57
|
+
"allow-downloads": 1,
|
|
58
|
+
"allow-forms": 1,
|
|
59
|
+
"allow-modals": 1,
|
|
60
|
+
"allow-orientation-lock": 1,
|
|
61
|
+
"allow-pointer-lock": 1,
|
|
62
|
+
"allow-popups": 1,
|
|
63
|
+
"allow-popups-to-escape-sandbox": 1,
|
|
64
|
+
"allow-presentation": 1,
|
|
65
|
+
"allow-same-origin": 1,
|
|
66
|
+
"allow-scripts": 1,
|
|
67
|
+
"allow-storage-access-by-user-activation": 1,
|
|
68
|
+
"allow-top-navigation": 1,
|
|
69
|
+
"allow-top-navigation-by-user-activation": 1,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
var seen = {};
|
|
73
|
+
var out = [];
|
|
74
|
+
var tokens = String(rawSandbox || "").split(/\\s+/);
|
|
75
|
+
for (var i = 0; i < tokens.length; i++) {
|
|
76
|
+
var token = tokens[i];
|
|
77
|
+
if (!token || !allowed[token] || seen[token]) continue;
|
|
78
|
+
seen[token] = 1;
|
|
79
|
+
out.push(token);
|
|
80
|
+
}
|
|
81
|
+
for (var j = 0; j < base.length; j++) {
|
|
82
|
+
if (!seen[base[j]]) out.push(base[j]);
|
|
83
|
+
}
|
|
84
|
+
if (!bridgeEnabled) {
|
|
85
|
+
out = out.filter(function(token) { return token !== "allow-same-origin"; });
|
|
86
|
+
}
|
|
87
|
+
return out.join(" ");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function _unregisterFrameWindow(iframe) {
|
|
91
|
+
var prev = iframe && iframe._aupTrackedWindow;
|
|
92
|
+
if (!prev) return;
|
|
93
|
+
_aupFrameWindows.delete(prev);
|
|
94
|
+
_aupBridgeWindows.delete(prev);
|
|
95
|
+
_aupBridgeOriginByWindow.delete(prev);
|
|
96
|
+
// Clean up bridge subscriptions owned by this window
|
|
97
|
+
if (window._aupBridgeSubsByWindow) {
|
|
98
|
+
var subIds = window._aupBridgeSubsByWindow.get(prev);
|
|
99
|
+
if (subIds) {
|
|
100
|
+
subIds.forEach(function(sid) {
|
|
101
|
+
if (window._aupBridgeSubs && window._aupBridgeSubs[sid]) {
|
|
102
|
+
try { window._aupBridgeSubs[sid](); } catch(_ex) {}
|
|
103
|
+
delete window._aupBridgeSubs[sid];
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
window._aupBridgeSubsByWindow.delete(prev);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
iframe._aupTrackedWindow = null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function _registerFrameWindow(iframe, bridgeEnabled, srcUrl) {
|
|
113
|
+
_unregisterFrameWindow(iframe);
|
|
114
|
+
try {
|
|
115
|
+
var win = iframe.contentWindow;
|
|
116
|
+
if (!win) return;
|
|
117
|
+
iframe._aupTrackedWindow = win;
|
|
118
|
+
_aupFrameWindows.add(win);
|
|
119
|
+
if (bridgeEnabled) {
|
|
120
|
+
_aupBridgeWindows.add(win);
|
|
121
|
+
try {
|
|
122
|
+
_aupBridgeOriginByWindow.set(win, new URL(srcUrl, location.href).origin);
|
|
123
|
+
} catch (_ex) {}
|
|
124
|
+
}
|
|
125
|
+
} catch (_ex) {}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function renderAupFrame(node) {
|
|
129
|
+
var el = document.createElement("div");
|
|
130
|
+
el.className = "aup-frame";
|
|
131
|
+
var p = node.props || {};
|
|
132
|
+
var src = typeof p.src === "string" ? p.src : "";
|
|
133
|
+
var bridge = !!p.bridge;
|
|
134
|
+
var loading = p.loading || "lazy";
|
|
135
|
+
var size = p.size || {};
|
|
136
|
+
var fallback = p.fallback || "";
|
|
137
|
+
|
|
138
|
+
if (size.width) el.setAttribute("data-size-width", "1");
|
|
139
|
+
if (size.height) el.setAttribute("data-size-height", "1");
|
|
140
|
+
|
|
141
|
+
if (!src) {
|
|
142
|
+
var placeholder = document.createElement("div");
|
|
143
|
+
placeholder.className = "aup-frame-error";
|
|
144
|
+
placeholder.innerHTML = '<span class="aup-frame-error-icon">\\u26a0</span>'
|
|
145
|
+
+ '<span class="aup-frame-error-msg">Frame: set src prop to embed a page</span>';
|
|
146
|
+
el.appendChild(placeholder);
|
|
147
|
+
return el;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
var resolved = _resolveFrameSrc(src, bridge);
|
|
151
|
+
if (!resolved) {
|
|
152
|
+
var invalid = document.createElement("div");
|
|
153
|
+
invalid.className = "aup-frame-error";
|
|
154
|
+
invalid.innerHTML = '<span class="aup-frame-error-icon">\\u26a0</span>'
|
|
155
|
+
+ '<span class="aup-frame-error-msg">Frame: src must be http(s) URL or /pages/*</span>';
|
|
156
|
+
el.appendChild(invalid);
|
|
157
|
+
return el;
|
|
158
|
+
}
|
|
159
|
+
var resolvedSrc = resolved.url;
|
|
160
|
+
var bridgeEnabled = !!resolved.bridgeEnabled;
|
|
161
|
+
var sandbox = _normalizeSandbox(p.sandbox, bridgeEnabled);
|
|
162
|
+
|
|
163
|
+
// Create iframe
|
|
164
|
+
var iframe = document.createElement("iframe");
|
|
165
|
+
iframe.setAttribute("sandbox", sandbox);
|
|
166
|
+
iframe.setAttribute("loading", loading === "eager" ? "eager" : "lazy");
|
|
167
|
+
iframe.setAttribute("referrerpolicy", "no-referrer");
|
|
168
|
+
if (p.transparent) { iframe.setAttribute("allowtransparency", "true"); iframe.style.background = "transparent"; el.style.background = "transparent"; }
|
|
169
|
+
if (p.overlay) {
|
|
170
|
+
// Override .aup-frame class styles that break overlay
|
|
171
|
+
el.className = "aup-frame-overlay";
|
|
172
|
+
el.style.cssText = "position:fixed;inset:0;z-index:99999;pointer-events:none;background:transparent;border:none;overflow:visible;margin:0;padding:0;min-height:0;";
|
|
173
|
+
iframe.style.cssText = "pointer-events:none;background:transparent;width:100%;height:100%;border:none;display:block;min-height:0;";
|
|
174
|
+
iframe.setAttribute("allowtransparency", "true");
|
|
175
|
+
el.setAttribute("data-aup-overlay", node.id || "");
|
|
176
|
+
iframe.onload = function() {
|
|
177
|
+
_registerFrameWindow(iframe, bridgeEnabled, resolvedSrc);
|
|
178
|
+
};
|
|
179
|
+
iframe.src = resolvedSrc;
|
|
180
|
+
el.appendChild(iframe);
|
|
181
|
+
setTimeout(function() { document.body.appendChild(el); }, 0);
|
|
182
|
+
return document.createElement("div");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Loading skeleton (non-overlay frames only)
|
|
186
|
+
var skeleton = document.createElement("div");
|
|
187
|
+
skeleton.className = "aup-frame-loading";
|
|
188
|
+
skeleton.innerHTML = '<div class="aup-frame-loading-bar"></div>';
|
|
189
|
+
el.appendChild(skeleton);
|
|
190
|
+
if (size.width) iframe.style.width = size.width;
|
|
191
|
+
if (size.height) { iframe.style.height = size.height; el.style.minHeight = "0"; }
|
|
192
|
+
|
|
193
|
+
iframe.onload = function() {
|
|
194
|
+
skeleton.remove();
|
|
195
|
+
_registerFrameWindow(iframe, bridgeEnabled, resolvedSrc);
|
|
196
|
+
// Fire AUP load event
|
|
197
|
+
if (node.events && node.events.load) {
|
|
198
|
+
_fireAupEvent(node.id, "load", {});
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
iframe.onerror = function() {
|
|
203
|
+
_showFrameError(el, skeleton, iframe, resolvedSrc, fallback, bridge, node);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// Also handle load errors via timeout — iframes don't reliably fire onerror
|
|
207
|
+
var errorTimer = setTimeout(function() {
|
|
208
|
+
if (skeleton.parentNode) {
|
|
209
|
+
// Still loading after 30s — likely broken
|
|
210
|
+
_showFrameError(el, skeleton, iframe, resolvedSrc, fallback, bridge, node);
|
|
211
|
+
}
|
|
212
|
+
}, 30000);
|
|
213
|
+
|
|
214
|
+
iframe.addEventListener("load", function() { clearTimeout(errorTimer); }, { once: true });
|
|
215
|
+
|
|
216
|
+
iframe.src = resolvedSrc;
|
|
217
|
+
el.appendChild(iframe);
|
|
218
|
+
|
|
219
|
+
return el;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function _showFrameError(wrapper, skeleton, iframe, src, fallback, bridge, node) {
|
|
223
|
+
if (skeleton.parentNode) skeleton.remove();
|
|
224
|
+
iframe.style.display = "none";
|
|
225
|
+
_unregisterFrameWindow(iframe);
|
|
226
|
+
|
|
227
|
+
// Remove existing error if retrying
|
|
228
|
+
var old = wrapper.querySelector(".aup-frame-error");
|
|
229
|
+
if (old) old.remove();
|
|
230
|
+
|
|
231
|
+
var errorEl = document.createElement("div");
|
|
232
|
+
errorEl.className = "aup-frame-error";
|
|
233
|
+
errorEl.innerHTML = '<span class="aup-frame-error-icon">\\u26a0</span>'
|
|
234
|
+
+ '<span class="aup-frame-error-msg">Failed to load page</span>';
|
|
235
|
+
|
|
236
|
+
var retryBtn = document.createElement("button");
|
|
237
|
+
retryBtn.className = "aup-frame-retry";
|
|
238
|
+
retryBtn.textContent = "Retry";
|
|
239
|
+
retryBtn.onclick = function() {
|
|
240
|
+
errorEl.remove();
|
|
241
|
+
iframe.style.display = "";
|
|
242
|
+
var retry = _resolveFrameSrc(fallback || src, bridge);
|
|
243
|
+
iframe.src = retry ? retry.url : src;
|
|
244
|
+
};
|
|
245
|
+
errorEl.appendChild(retryBtn);
|
|
246
|
+
wrapper.appendChild(errorEl);
|
|
247
|
+
|
|
248
|
+
// Fire AUP error event
|
|
249
|
+
if (node.events && node.events.error) {
|
|
250
|
+
_fireAupEvent(node.id, "error", { src: src });
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function _fireAupEvent(nodeId, event, data) {
|
|
255
|
+
// Check if this node lives inside a device container — route to device WS
|
|
256
|
+
var nodeEl = document.querySelector('[data-aup-id="' + nodeId + '"]');
|
|
257
|
+
if (nodeEl) {
|
|
258
|
+
var deviceEl = nodeEl.closest('[data-aup-device-id]');
|
|
259
|
+
if (deviceEl && deviceEl._aupDeviceWs && deviceEl._aupDeviceWs.readyState === 1) {
|
|
260
|
+
deviceEl._aupDeviceWs.send(JSON.stringify({
|
|
261
|
+
type: "aup_event", nodeId: nodeId, event: event, data: data
|
|
262
|
+
}));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Default: send to parent WS
|
|
267
|
+
if (ws && ws.readyState === 1) {
|
|
268
|
+
ws.send(JSON.stringify({ type: "aup_event", nodeId: nodeId, event: event, data: data }));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
`;
|
|
272
|
+
|
|
273
|
+
//#endregion
|
|
274
|
+
exports.FRAME_JS = FRAME_JS;
|