@vvfx/sdk 0.2.8 → 0.2.10
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/dist/config.js +231 -0
- package/dist/exporter/config.js +18 -0
- package/dist/exporter/const.js +71 -0
- package/dist/exporter/export-media.js +878 -0
- package/dist/exporter/exporter.js +121 -0
- package/dist/exporter/index.js +1 -0
- package/dist/exporter/types.js +1 -0
- package/dist/exporter/utils.js +190 -0
- package/dist/exporter/wav-audio.js +50 -0
- package/dist/gesture-handler/gizmo/adsorption-gizmo.js +227 -0
- package/dist/gesture-handler/gizmo/control-gizmo.js +149 -0
- package/dist/gesture-handler/gizmo/gizmo.js +17 -0
- package/dist/gesture-handler/gizmo/icon-gizmo.js +189 -0
- package/dist/gesture-handler/gizmo/index.js +6 -0
- package/dist/gesture-handler/gizmo/item-create-gizmo.js +256 -0
- package/dist/gesture-handler/gizmo/loading-gizmo.js +320 -0
- package/dist/gesture-handler/gizmo/mask-gizmo.js +648 -0
- package/dist/gesture-handler/gizmo/picture-cut-gizmo.js +550 -0
- package/dist/gesture-handler/gizmo/picture-expand-gizmo.js +491 -0
- package/dist/gesture-handler/gizmo/preference-gizmo.js +148 -0
- package/dist/gesture-handler/gizmo/selector-gizmo.d.ts +1 -1
- package/dist/gesture-handler/gizmo/selector-gizmo.js +468 -0
- package/dist/gesture-handler/gizmo/sprite-text-edit-gizmo.js +247 -0
- package/dist/gesture-handler/gizmo/text-gizmo.js +1033 -0
- package/dist/gesture-handler/gizmo/transform-gizmo.js +1199 -0
- package/dist/gesture-handler/gizmo/type.js +18 -0
- package/dist/gesture-handler/index.js +3 -0
- package/dist/gesture-handler/src/gesture-handler.js +770 -0
- package/dist/gesture-handler/src/icons.js +24 -0
- package/dist/gesture-handler/utils.js +40 -0
- package/dist/html-overlay/anchor-navigation-runtime.js +27 -0
- package/dist/html-overlay/auto-height-layout.d.ts +6 -0
- package/dist/html-overlay/auto-height-layout.js +7 -0
- package/dist/html-overlay/auto-height-runtime.js +132 -0
- package/dist/html-overlay/document-runtime.js +71 -0
- package/dist/html-overlay/document-transform.js +96 -0
- package/dist/html-overlay/dom-order.js +8 -0
- package/dist/html-overlay/host-message-runtime.js +24 -0
- package/dist/html-overlay/html-capture-runtime.js +282 -0
- package/dist/html-overlay/html-viewport-style.js +10 -0
- package/dist/html-overlay/index.js +1 -0
- package/dist/html-overlay/manager.d.ts +1 -0
- package/dist/html-overlay/manager.js +1677 -0
- package/dist/html-overlay/mime-utils.js +21 -0
- package/dist/html-overlay/overlay-transform.js +57 -0
- package/dist/html-overlay/path-utils.js +35 -0
- package/dist/html-overlay/shell-runtime.js +12 -0
- package/dist/index.cjs +34 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -75311
- package/dist/index.mjs +75337 -0
- package/dist/index.mjs.map +1 -0
- package/dist/layer-order.js +8 -0
- package/dist/math/box2.js +396 -0
- package/dist/math/circle.js +131 -0
- package/dist/math/euler.js +35 -0
- package/dist/math/index.js +13 -0
- package/dist/math/line2.js +153 -0
- package/dist/math/line3.js +36 -0
- package/dist/math/matrix4.js +207 -0
- package/dist/math/plane.js +52 -0
- package/dist/math/quaternion.js +3 -0
- package/dist/math/ray-caster.js +25 -0
- package/dist/math/ray.js +47 -0
- package/dist/math/type.js +1 -0
- package/dist/math/utils.js +77 -0
- package/dist/math/vector2.js +70 -0
- package/dist/math/vector3.js +60 -0
- package/dist/screen-shot/index.js +1 -0
- package/dist/screen-shot/screen-shot.js +113 -0
- package/dist/sdk-item/base-item.js +160 -0
- package/dist/sdk-item/card-item.js +131 -0
- package/dist/sdk-item/effects-item.js +144 -0
- package/dist/sdk-item/frame-item.js +217 -0
- package/dist/sdk-item/generator-item.js +188 -0
- package/dist/sdk-item/group-item.js +116 -0
- package/dist/sdk-item/index.js +39 -0
- package/dist/sdk-item/sprite-item.js +147 -0
- package/dist/sdk-item/text-item.js +223 -0
- package/dist/sdk-item/types.d.ts +1 -1
- package/dist/sdk-item/types.js +15 -0
- package/dist/sdk-item/video-item.js +174 -0
- package/dist/sdk.js +1908 -0
- package/dist/service/UndoRedo.js +79 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +2 -0
- package/dist/shared/player.d.ts +1 -1
- package/dist/shared/player.js +9 -0
- package/dist/shared/spec.d.ts +1 -0
- package/dist/shared/spec.js +1 -0
- package/dist/size-adapte/index.js +1 -0
- package/dist/size-adapte/size-adapt.js +395 -0
- package/dist/types.d.ts +5 -1
- package/dist/types.js +17 -0
- package/dist/utils/background-manager.js +189 -0
- package/dist/utils/common-utils.js +183 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/interaction-utils.js +205 -0
- package/dist/utils/json-data-utils.js +1529 -0
- package/dist/utils/layout-utils.js +1217 -0
- package/dist/utils/page-data-utils.js +5397 -0
- package/dist/utils/player-data-utils.js +48 -0
- package/dist/utils/types.js +8 -0
- package/dist/wireframe/common/box.js +18 -0
- package/dist/wireframe/common/dashed-line.js +21 -0
- package/dist/wireframe/common/line.js +17 -0
- package/dist/wireframe/common/pixi-ext.js +1 -0
- package/dist/wireframe/common/pixi.js +31 -0
- package/dist/wireframe/index.js +4 -0
- package/package.json +10 -3
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const assetsPrefix = 'https://mdn.alipayobjects.com/rms/uri/file/as/0.0.6';
|
|
2
|
+
export const cursorMap = {
|
|
3
|
+
normal: { type: 'preset', content: 'default' },
|
|
4
|
+
rotation: { type: 'svg', content: 'default', url: `${assetsPrefix}/icons/cursor-rotate-32.svg` },
|
|
5
|
+
circle: { type: 'svg', content: 'default', url: `${assetsPrefix}/icons/cursor-rotate-32.svg` },
|
|
6
|
+
scale: { type: 'svg', content: 'default', url: `${assetsPrefix}/icons/cursor-scale-32.svg` },
|
|
7
|
+
hand: { type: 'preset', content: 'grab' },
|
|
8
|
+
pointer: { type: 'preset', content: 'pointer' },
|
|
9
|
+
'text-create': { type: 'preset', content: 'text' },
|
|
10
|
+
'active-hand': { type: 'preset', content: 'grabbing' },
|
|
11
|
+
'frame-create': { type: 'preset', content: 'crosshair' },
|
|
12
|
+
'box-select': { type: 'preset', content: 'crosshair' },
|
|
13
|
+
'text-rotation': { type: 'svg', content: 'default', url: 'https://mdn.alipayobjects.com/huamei_ixsp8m/afts/img/A*R722QoloC44AAAAAKkAAAAgAev-aAQ/original' },
|
|
14
|
+
};
|
|
15
|
+
export async function loadCursorIcons() {
|
|
16
|
+
const cursorIconLoaders = Object.entries(cursorMap)
|
|
17
|
+
.filter((entry) => Boolean(entry[1].url))
|
|
18
|
+
.map(([key, value]) => fetch(value.url)
|
|
19
|
+
.then(res => res.text())
|
|
20
|
+
.then(text => cursorMap[key] = { ...value, content: text }));
|
|
21
|
+
await Promise.all(cursorIconLoaders).catch((e) => {
|
|
22
|
+
console.error(e);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Text } from '../wireframe';
|
|
2
|
+
// 截断逻辑
|
|
3
|
+
export function processText(textContent, style, width, maxLines) {
|
|
4
|
+
const lines = [];
|
|
5
|
+
let currentLine = '';
|
|
6
|
+
const chars = textContent.split('');
|
|
7
|
+
const tempText = new Text('', style);
|
|
8
|
+
for (let i = 0; i < chars.length; i++) {
|
|
9
|
+
const char = chars[i];
|
|
10
|
+
const testLine = currentLine + char;
|
|
11
|
+
tempText.text = testLine;
|
|
12
|
+
// 宽度检查
|
|
13
|
+
if (tempText.width > width) {
|
|
14
|
+
lines.push(currentLine);
|
|
15
|
+
// 行数检查
|
|
16
|
+
if (lines.length >= maxLines) {
|
|
17
|
+
// 最后一行添加...
|
|
18
|
+
const lastLine = lines[maxLines - 1];
|
|
19
|
+
if (lastLine.length > 2) {
|
|
20
|
+
lines[maxLines - 1] = lastLine.slice(0, -2) + '...';
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
lines[maxLines - 1] = '...';
|
|
24
|
+
}
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
currentLine = char;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
currentLine = testLine;
|
|
31
|
+
}
|
|
32
|
+
// 处理最后一行
|
|
33
|
+
if (i === chars.length - 1 && currentLine) {
|
|
34
|
+
lines.push(currentLine);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// 限制行数
|
|
38
|
+
const displayLines = lines.slice(0, maxLines);
|
|
39
|
+
return displayLines.join('\n');
|
|
40
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function withCardHTMLAnchorNavigationGuard(html, allowAnchorNavigation) {
|
|
2
|
+
if (allowAnchorNavigation === true) {
|
|
3
|
+
return html;
|
|
4
|
+
}
|
|
5
|
+
const script = `
|
|
6
|
+
<script data-vvfx-card-html-anchor-navigation-guard>
|
|
7
|
+
(() => {
|
|
8
|
+
document.addEventListener('click', event => {
|
|
9
|
+
const target = event.target;
|
|
10
|
+
if (!(target instanceof Element)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const anchor = target.closest('a[href]');
|
|
15
|
+
if (!anchor) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
event.preventDefault();
|
|
20
|
+
}, true);
|
|
21
|
+
})();
|
|
22
|
+
</script>`;
|
|
23
|
+
if (/<\/body>/i.test(html)) {
|
|
24
|
+
return html.replace(/<\/body>/i, `${script}</body>`);
|
|
25
|
+
}
|
|
26
|
+
return `${html}${script}`;
|
|
27
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function resolveTopAnchoredCardPosition({ nextHeight, position, previousHeight, scaleY, }) {
|
|
2
|
+
const normalizedScaleY = Number.isFinite(scaleY) ? scaleY : 1;
|
|
3
|
+
return [
|
|
4
|
+
position[0],
|
|
5
|
+
position[1] + (nextHeight - previousHeight) * normalizedScaleY / 2,
|
|
6
|
+
];
|
|
7
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export function createAutoHeightMessageListener(iframe, options) {
|
|
2
|
+
if (!options?.autoHeightId || !options.onAutoHeight) {
|
|
3
|
+
return () => {
|
|
4
|
+
// pass
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
const handleMessage = (event) => {
|
|
8
|
+
if (event.source !== iframe.contentWindow) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (isCardHTMLAutoHeightMessage(event.data, options.autoHeightId)) {
|
|
12
|
+
options.onAutoHeight?.(event.data.height);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const phase = getCardHTMLStreamRuntimePhase(event.data);
|
|
16
|
+
if (phase) {
|
|
17
|
+
options.onStreamRuntimePhase?.(phase);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
window.addEventListener('message', handleMessage);
|
|
21
|
+
return () => {
|
|
22
|
+
window.removeEventListener('message', handleMessage);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function getCardHTMLStreamRuntimePhase(data) {
|
|
26
|
+
if (typeof data !== 'object' || data === null) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const message = data;
|
|
30
|
+
if (message.type !== 'huamei:html-stream-runtime-status' || typeof message.payload !== 'object' || message.payload === null) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const phase = message.payload.phase;
|
|
34
|
+
return ['parsing', 'draining', 'complete', 'finalizing', 'disposed', 'error'].includes(String(phase))
|
|
35
|
+
? phase
|
|
36
|
+
: undefined;
|
|
37
|
+
}
|
|
38
|
+
export function isCardHTMLAutoHeightMessage(data, id) {
|
|
39
|
+
if (typeof data !== 'object' || data === null) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const message = data;
|
|
43
|
+
return message.source === 'vvfx-card-html-auto-height' &&
|
|
44
|
+
message.id === id &&
|
|
45
|
+
typeof message.height === 'number';
|
|
46
|
+
}
|
|
47
|
+
export function requestCardHTMLAutoHeight(iframe, id) {
|
|
48
|
+
iframe.contentWindow?.postMessage({
|
|
49
|
+
source: 'vvfx-card-html-auto-height-request',
|
|
50
|
+
id,
|
|
51
|
+
}, '*');
|
|
52
|
+
}
|
|
53
|
+
export function withCardHTMLAutoHeightBridge(html, id) {
|
|
54
|
+
if (!id) {
|
|
55
|
+
return html;
|
|
56
|
+
}
|
|
57
|
+
const script = `
|
|
58
|
+
<script data-vvfx-card-html-auto-height>
|
|
59
|
+
(() => {
|
|
60
|
+
const id = ${JSON.stringify(id)};
|
|
61
|
+
let frame = 0;
|
|
62
|
+
const getNodeHeight = (node) => {
|
|
63
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
64
|
+
if (window.getComputedStyle(node).position === 'fixed') {
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
const rect = node.getBoundingClientRect();
|
|
68
|
+
return rect.bottom + window.scrollY;
|
|
69
|
+
}
|
|
70
|
+
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim()) {
|
|
71
|
+
const range = document.createRange();
|
|
72
|
+
range.selectNodeContents(node);
|
|
73
|
+
const rects = Array.from(range.getClientRects());
|
|
74
|
+
range.detach();
|
|
75
|
+
return rects.reduce((height, rect) => Math.max(height, rect.bottom + window.scrollY), 0);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return 0;
|
|
79
|
+
};
|
|
80
|
+
const getContentHeight = (element) => {
|
|
81
|
+
if (!element) return 0;
|
|
82
|
+
return Array.from(element.childNodes).reduce((height, child) => {
|
|
83
|
+
return Math.max(height, getNodeHeight(child));
|
|
84
|
+
}, 0);
|
|
85
|
+
};
|
|
86
|
+
const getHeight = () => {
|
|
87
|
+
const body = document.body;
|
|
88
|
+
const root = document.documentElement;
|
|
89
|
+
const contentHeight = getContentHeight(body);
|
|
90
|
+
const scrollHeight = Math.max(root.scrollHeight, body ? body.scrollHeight : 0);
|
|
91
|
+
return Math.ceil(contentHeight > 0 ? contentHeight : scrollHeight);
|
|
92
|
+
};
|
|
93
|
+
const postHeight = () => {
|
|
94
|
+
frame = 0;
|
|
95
|
+
window.parent.postMessage({
|
|
96
|
+
source: 'vvfx-card-html-auto-height',
|
|
97
|
+
id,
|
|
98
|
+
height: getHeight(),
|
|
99
|
+
}, '*');
|
|
100
|
+
};
|
|
101
|
+
const schedule = () => {
|
|
102
|
+
if (frame) return;
|
|
103
|
+
frame = requestAnimationFrame(postHeight);
|
|
104
|
+
};
|
|
105
|
+
window.addEventListener('message', (event) => {
|
|
106
|
+
const message = event.data;
|
|
107
|
+
if (!message || message.source !== 'vvfx-card-html-auto-height-request' || message.id !== id) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
schedule();
|
|
112
|
+
});
|
|
113
|
+
window.addEventListener('load', schedule);
|
|
114
|
+
window.addEventListener('resize', schedule);
|
|
115
|
+
new ResizeObserver(schedule).observe(document.documentElement);
|
|
116
|
+
if (document.body) {
|
|
117
|
+
new ResizeObserver(schedule).observe(document.body);
|
|
118
|
+
new MutationObserver(schedule).observe(document.body, {
|
|
119
|
+
attributes: true,
|
|
120
|
+
childList: true,
|
|
121
|
+
subtree: true,
|
|
122
|
+
characterData: true,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
schedule();
|
|
126
|
+
})();
|
|
127
|
+
</script>`;
|
|
128
|
+
if (/<\/body>/i.test(html)) {
|
|
129
|
+
return html.replace(/<\/body>/i, `${script}</body>`);
|
|
130
|
+
}
|
|
131
|
+
return `${html}${script}`;
|
|
132
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createAutoHeightMessageListener, withCardHTMLAutoHeightBridge } from './auto-height-runtime';
|
|
2
|
+
import { createDocumentFileUrlFactory, normalizeDocumentFiles, transformHTMLDocument } from './document-transform';
|
|
3
|
+
import { createHostMessageListener } from './host-message-runtime';
|
|
4
|
+
import { normalizePath } from './path-utils';
|
|
5
|
+
import { withCardHTMLViewportStyle } from './html-viewport-style';
|
|
6
|
+
import { withCardHTMLAnchorNavigationGuard } from './anchor-navigation-runtime';
|
|
7
|
+
export function renderDocumentContent(overlay, content, options) {
|
|
8
|
+
const iframe = document.createElement('iframe');
|
|
9
|
+
const files = normalizeDocumentFiles(content.files);
|
|
10
|
+
const entry = normalizePath(content.entry);
|
|
11
|
+
const createFileUrl = createDocumentFileUrlFactory(files);
|
|
12
|
+
const messageCleanup = createHostMessageListener(iframe, content);
|
|
13
|
+
const autoHeightMessageCleanup = createAutoHeightMessageListener(iframe, options);
|
|
14
|
+
iframe.style.width = '100%';
|
|
15
|
+
iframe.style.height = '100%';
|
|
16
|
+
iframe.style.border = '0';
|
|
17
|
+
iframe.style.display = 'block';
|
|
18
|
+
if (content.sandbox === true || content.sandbox === undefined) {
|
|
19
|
+
iframe.setAttribute('sandbox', 'allow-scripts');
|
|
20
|
+
}
|
|
21
|
+
else if (typeof content.sandbox === 'string') {
|
|
22
|
+
iframe.setAttribute('sandbox', content.sandbox);
|
|
23
|
+
}
|
|
24
|
+
const entryHtml = files.get(entry) ?? '';
|
|
25
|
+
iframe.srcdoc = withCardHTMLAutoHeightBridge(withCardHTMLAnchorNavigationGuard(withCardHTMLViewportStyle(transformHTMLDocument(entry, entryHtml, createFileUrl)), content.allowAnchorNavigation), options?.autoHeightId);
|
|
26
|
+
overlay.appendChild(iframe);
|
|
27
|
+
return () => {
|
|
28
|
+
messageCleanup();
|
|
29
|
+
autoHeightMessageCleanup();
|
|
30
|
+
iframe.remove();
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function renderDOMContentInIframe(overlay, render, cleanup) {
|
|
34
|
+
const iframe = document.createElement('iframe');
|
|
35
|
+
let mount;
|
|
36
|
+
let disposed = false;
|
|
37
|
+
iframe.style.width = '100%';
|
|
38
|
+
iframe.style.height = '100%';
|
|
39
|
+
iframe.style.border = '0';
|
|
40
|
+
iframe.style.display = 'block';
|
|
41
|
+
const handleLoad = () => {
|
|
42
|
+
if (disposed) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (mount) {
|
|
46
|
+
cleanup?.(mount);
|
|
47
|
+
mount = undefined;
|
|
48
|
+
}
|
|
49
|
+
const doc = iframe.contentDocument;
|
|
50
|
+
if (!doc?.body) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
mount = doc.createElement('div');
|
|
54
|
+
mount.style.width = '100%';
|
|
55
|
+
mount.style.height = '100%';
|
|
56
|
+
doc.body.appendChild(mount);
|
|
57
|
+
render(mount);
|
|
58
|
+
};
|
|
59
|
+
iframe.addEventListener('load', handleLoad);
|
|
60
|
+
overlay.appendChild(iframe);
|
|
61
|
+
iframe.srcdoc = withCardHTMLViewportStyle('');
|
|
62
|
+
return () => {
|
|
63
|
+
disposed = true;
|
|
64
|
+
iframe.removeEventListener('load', handleLoad);
|
|
65
|
+
if (mount) {
|
|
66
|
+
cleanup?.(mount);
|
|
67
|
+
mount = undefined;
|
|
68
|
+
}
|
|
69
|
+
iframe.remove();
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { createDataUrl, getMimeType } from './mime-utils';
|
|
2
|
+
import { normalizePath, resolvePath, shouldRewriteResource, splitResourcePath } from './path-utils';
|
|
3
|
+
export function normalizeDocumentFiles(files) {
|
|
4
|
+
return new Map(Object.entries(files).map(([path, source]) => [normalizePath(path), source]));
|
|
5
|
+
}
|
|
6
|
+
export function createDocumentFileUrlFactory(files) {
|
|
7
|
+
const urlCache = new Map();
|
|
8
|
+
const resolving = new Set();
|
|
9
|
+
const createFileUrl = (rawPath, fromPath) => {
|
|
10
|
+
const { path, suffix } = splitResourcePath(rawPath);
|
|
11
|
+
const resolvedPath = resolvePath(path, fromPath);
|
|
12
|
+
if (!files.has(resolvedPath)) {
|
|
13
|
+
return rawPath;
|
|
14
|
+
}
|
|
15
|
+
let url = urlCache.get(resolvedPath);
|
|
16
|
+
if (!url) {
|
|
17
|
+
const source = files.get(resolvedPath) ?? '';
|
|
18
|
+
const transformedSource = resolving.has(resolvedPath)
|
|
19
|
+
? source
|
|
20
|
+
: transformDocumentFile(resolvedPath, source, createFileUrl, resolving);
|
|
21
|
+
url = createDataUrl(transformedSource, getMimeType(resolvedPath));
|
|
22
|
+
urlCache.set(resolvedPath, url);
|
|
23
|
+
}
|
|
24
|
+
return `${url}${suffix}`;
|
|
25
|
+
};
|
|
26
|
+
return createFileUrl;
|
|
27
|
+
}
|
|
28
|
+
export function transformDocumentFile(path, source, createFileUrl, resolving = new Set()) {
|
|
29
|
+
resolving.add(path);
|
|
30
|
+
try {
|
|
31
|
+
if (path.endsWith('.css')) {
|
|
32
|
+
return transformCSSDocument(path, source, createFileUrl);
|
|
33
|
+
}
|
|
34
|
+
if (path.endsWith('.js') || path.endsWith('.mjs')) {
|
|
35
|
+
return transformJSDocument(path, source, createFileUrl);
|
|
36
|
+
}
|
|
37
|
+
if (path.endsWith('.html') || path.endsWith('.htm')) {
|
|
38
|
+
return transformHTMLDocument(path, source, createFileUrl);
|
|
39
|
+
}
|
|
40
|
+
return source;
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
resolving.delete(path);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export function transformHTMLDocument(path, source, createFileUrl) {
|
|
47
|
+
return source
|
|
48
|
+
.replace(/\b(src|href)=("|')([^"']+)\2/g, (match, attr, quote, url) => {
|
|
49
|
+
if (!shouldRewriteResource(url)) {
|
|
50
|
+
return match;
|
|
51
|
+
}
|
|
52
|
+
return `${attr}=${quote}${createFileUrl(url, path)}${quote}`;
|
|
53
|
+
})
|
|
54
|
+
.replace(/<style\b([^>]*)>([\s\S]*?)<\/style>/gi, (_match, attrs, css) => {
|
|
55
|
+
return `<style${attrs}>${transformCSSDocument(path, css, createFileUrl)}</style>`;
|
|
56
|
+
})
|
|
57
|
+
.replace(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi, (_match, attrs, js) => {
|
|
58
|
+
return `<script${attrs}>${transformJSDocument(path, js, createFileUrl)}</script>`;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
export function transformCSSDocument(path, source, createFileUrl) {
|
|
62
|
+
return source
|
|
63
|
+
.replace(/url\(\s*(['"]?)([^'")]+)\1\s*\)/g, (match, quote, url) => {
|
|
64
|
+
if (!shouldRewriteResource(url)) {
|
|
65
|
+
return match;
|
|
66
|
+
}
|
|
67
|
+
return `url(${quote}${createFileUrl(url, path)}${quote})`;
|
|
68
|
+
})
|
|
69
|
+
.replace(/@import\s+(?:url\()?(['"])([^'"]+)\1\)?/g, (match, quote, url) => {
|
|
70
|
+
if (!shouldRewriteResource(url)) {
|
|
71
|
+
return match;
|
|
72
|
+
}
|
|
73
|
+
return `@import ${quote}${createFileUrl(url, path)}${quote}`;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function transformJSDocument(path, source, createFileUrl) {
|
|
77
|
+
return source
|
|
78
|
+
.replace(/\bfrom\s+(['"])([^'"]+)\1/g, (match, quote, url) => {
|
|
79
|
+
if (!shouldRewriteResource(url)) {
|
|
80
|
+
return match;
|
|
81
|
+
}
|
|
82
|
+
return `from ${quote}${createFileUrl(url, path)}${quote}`;
|
|
83
|
+
})
|
|
84
|
+
.replace(/\bimport\s+(['"])([^'"]+)\1/g, (match, quote, url) => {
|
|
85
|
+
if (!shouldRewriteResource(url)) {
|
|
86
|
+
return match;
|
|
87
|
+
}
|
|
88
|
+
return `import ${quote}${createFileUrl(url, path)}${quote}`;
|
|
89
|
+
})
|
|
90
|
+
.replace(/\bimport\(\s*(['"])([^'"]+)\1\s*\)/g, (match, quote, url) => {
|
|
91
|
+
if (!shouldRewriteResource(url)) {
|
|
92
|
+
return match;
|
|
93
|
+
}
|
|
94
|
+
return `import(${quote}${createFileUrl(url, path)}${quote})`;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function createHostMessageListener(iframe, content) {
|
|
2
|
+
if (!content.allowHostMessaging || !content.onMessage) {
|
|
3
|
+
return () => {
|
|
4
|
+
// pass
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
const handleMessage = (event) => {
|
|
8
|
+
if (event.source !== iframe.contentWindow || !isCardHTMLDocumentMessage(event.data)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
content.onMessage?.(event.data);
|
|
12
|
+
};
|
|
13
|
+
window.addEventListener('message', handleMessage);
|
|
14
|
+
return () => {
|
|
15
|
+
window.removeEventListener('message', handleMessage);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function isCardHTMLDocumentMessage(data) {
|
|
19
|
+
if (typeof data !== 'object' || data === null) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const message = data;
|
|
23
|
+
return message.source === 'vvfx-card-html' && typeof message.type === 'string';
|
|
24
|
+
}
|