@lvce-editor/iframe-worker 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,29 +1,12 @@
1
- const SemiColon = ';';
2
- const Space = ' ';
3
-
4
- const addSemicolon = line => {
5
- return line + SemiColon;
6
- };
7
-
8
- const getContentSecurityPolicy = items => {
9
- return items.map(addSemicolon).join(Space);
10
- };
11
-
12
- const getWebViewCsp = webView => {
13
- if (webView && webView.contentSecurityPolicy) {
14
- return getContentSecurityPolicy(webView.contentSecurityPolicy);
15
- }
16
- const csp = getContentSecurityPolicy([`default-src 'none'`, `script-src 'self'`, `style-src 'self'`, `img-src 'self'`, `media-src 'self'`]);
17
- return csp;
18
- };
19
-
20
1
  const createUrl = (protocol, host) => {
21
2
  return protocol + '//' + host;
22
3
  };
23
4
 
24
- const getWebViewFrameAncestors = (locationProtocol, locationHost) => {
25
- const frameAncestors = createUrl(locationProtocol, locationHost);
26
- return frameAncestors;
5
+ const createLocalHostUrl = (locationProtocol, locationHost, isGitpod, webViewPort) => {
6
+ if (isGitpod) {
7
+ return createUrl(locationProtocol, locationHost.replace('3000', `${webViewPort}`));
8
+ }
9
+ return `http://localhost:${webViewPort}`;
27
10
  };
28
11
 
29
12
  const Web = 1;
@@ -46,6 +29,7 @@ const getPlatform = () => {
46
29
  // @ts-ignore
47
30
  return PLATFORM;
48
31
  }
32
+ // @ts-ignore
49
33
  if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
50
34
  return Test;
51
35
  }
@@ -60,8 +44,257 @@ const getPlatform = () => {
60
44
  };
61
45
  const platform = getPlatform();
62
46
 
47
+ const getAssetDir = () => {
48
+ // @ts-ignore
49
+ if (typeof ASSET_DIR !== 'undefined') {
50
+ // @ts-ignore
51
+ return ASSET_DIR;
52
+ }
53
+ if (platform === Electron) {
54
+ return '';
55
+ }
56
+ return '';
57
+ };
58
+ const assetDir = getAssetDir();
59
+
60
+ const getWebViewHtml = (baseUrl, locationOrigin, elements) => {
61
+ if (!elements) {
62
+ return '';
63
+ }
64
+ const middle = [];
65
+ middle.push('<meta charset="utf-8">');
66
+ for (const element of elements) {
67
+ if (element.type === 'title') {
68
+ middle.push(`<title>${element.value}</title>`);
69
+ } else if (element.type === 'script') {
70
+ middle.push(`<script type="module" src="${locationOrigin}${assetDir}/js/preview-injected.js"></script>`);
71
+ middle.push(`<script type="module" src="${locationOrigin}${baseUrl}/${element.path}"></script>`);
72
+ } else if (element.type === 'css') {
73
+ middle.push(`<link rel="stylesheet" href="${locationOrigin}${baseUrl}/${element.path}" />`);
74
+ }
75
+ }
76
+ const middleHtml = middle.join('\n ');
77
+ let html = `<!DOCTYPE html>
78
+ <html>
79
+ <head>
80
+ ${middleHtml}
81
+ </head>
82
+ </html>
83
+ `;
84
+ return html;
85
+ };
86
+
63
87
  const WebView = 'lvce-oss-webview';
64
88
 
89
+ const getWebView$1 = (webViews, webViewId) => {
90
+ for (const webView of webViews) {
91
+ if (webView.id === webViewId) {
92
+ return webView;
93
+ }
94
+ }
95
+ return undefined;
96
+ };
97
+ const getWebViewPath = (webViews, webViewId) => {
98
+ const webView = getWebView$1(webViews, webViewId);
99
+ if (!webView) {
100
+ return '';
101
+ }
102
+ return webView.path;
103
+ };
104
+ const getWebViewUri = (webViews, webViewId) => {
105
+ const webViewPath = getWebViewPath(webViews, webViewId);
106
+ if (!webViewPath) {
107
+ return '';
108
+ }
109
+ if (webViewPath.startsWith('/')) {
110
+ // TODO make it work on windows also
111
+ return `file://${webViewPath}`;
112
+ }
113
+ return webViewPath;
114
+ };
115
+ const getIframeSrcRemote = (webViews, webViewPort, webViewId, locationProtocol, locationHost, isGitpod, root) => {
116
+ const webView = getWebView$1(webViews, webViewId);
117
+ const webViewUri = getWebViewUri(webViews, webViewId);
118
+ if (!webViewUri) {
119
+ return undefined;
120
+ }
121
+ let iframeSrc = webViewUri;
122
+ let webViewRoot = webViewUri;
123
+ if (platform === Electron) {
124
+ const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
125
+ iframeSrc = `${WebView}://-${relativePath}/`;
126
+ // TODO
127
+ } else if (platform === Remote) {
128
+ const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
129
+ if (webViewUri.startsWith('file://')) {
130
+ // ignore
131
+ webViewRoot = webViewUri.slice('file://'.length).replace('/index.html', '');
132
+ } else {
133
+ webViewRoot = root + relativePath;
134
+ }
135
+ iframeSrc = createLocalHostUrl(locationProtocol, locationHost, isGitpod, webViewPort);
136
+ }
137
+ let iframeContent = getWebViewHtml('', '', webView.elements);
138
+ // TODO either
139
+ // - load webviews the same as in web using blob urls
140
+ // - load webviews from a pattern like /webviews/:id/:fileName
141
+ iframeContent = iframeContent.replaceAll('/media/', '/').replaceAll('//', '/');
142
+ return {
143
+ srcDoc: '',
144
+ iframeSrc,
145
+ webViewRoot,
146
+ iframeContent
147
+ };
148
+ };
149
+
150
+ const getBlobUrl = (content, contentType) => {
151
+ const blob = new Blob([content], {
152
+ type: contentType
153
+ });
154
+ const url = URL.createObjectURL(blob); // TODO dispose
155
+ return url;
156
+ };
157
+
158
+ const getDefaultBaseUrl = webView => {
159
+ const {
160
+ remotePath,
161
+ path
162
+ } = webView;
163
+ if (remotePath) {
164
+ if (remotePath.endsWith('/index.html')) {
165
+ return remotePath.slice(0, -'/index.html'.length);
166
+ }
167
+ return remotePath;
168
+ }
169
+ if (path) {
170
+ if (path.endsWith('/index.html')) {
171
+ return path.slice(0, -'/index.html'.length);
172
+ }
173
+ return path;
174
+ }
175
+ return '';
176
+ };
177
+ const getWebViewBaseUrl = webView => {
178
+ const defaultBaseUrl = getDefaultBaseUrl(webView);
179
+ return defaultBaseUrl;
180
+ };
181
+
182
+ const getIframeSrc$1 = (webView, locationOrigin) => {
183
+ const baseUrl = getWebViewBaseUrl(webView);
184
+ const srcHtml = getWebViewHtml(baseUrl, locationOrigin, webView.elements);
185
+ if (srcHtml) {
186
+ const blobUrl = getBlobUrl(srcHtml, 'text/html');
187
+ return {
188
+ srcDoc: '',
189
+ iframeSrc: blobUrl,
190
+ webViewRoot: '',
191
+ iframeContent: ''
192
+ };
193
+ }
194
+ return undefined;
195
+ };
196
+
197
+ const getWebView = (webViews, webViewId) => {
198
+ for (const webView of webViews) {
199
+ if (webView.id === webViewId) {
200
+ return webView;
201
+ }
202
+ }
203
+ return undefined;
204
+ };
205
+
206
+ const normalizeLine$1 = line => {
207
+ if (line.startsWith('Error: ')) {
208
+ return line.slice(`Error: `.length);
209
+ }
210
+ if (line.startsWith('VError: ')) {
211
+ return line.slice(`VError: `.length);
212
+ }
213
+ return line;
214
+ };
215
+ const getCombinedMessage$1 = (error, message) => {
216
+ const stringifiedError = normalizeLine$1(`${error}`);
217
+ if (message) {
218
+ return `${message}: ${stringifiedError}`;
219
+ }
220
+ return stringifiedError;
221
+ };
222
+ const NewLine$2 = '\n';
223
+ const getNewLineIndex$1 = (string, startIndex = undefined) => {
224
+ return string.indexOf(NewLine$2, startIndex);
225
+ };
226
+ const mergeStacks$1 = (parent, child) => {
227
+ if (!child) {
228
+ return parent;
229
+ }
230
+ const parentNewLineIndex = getNewLineIndex$1(parent);
231
+ const childNewLineIndex = getNewLineIndex$1(child);
232
+ if (childNewLineIndex === -1) {
233
+ return parent;
234
+ }
235
+ const parentFirstLine = parent.slice(0, parentNewLineIndex);
236
+ const childRest = child.slice(childNewLineIndex);
237
+ const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
238
+ if (parentFirstLine.includes(childFirstLine)) {
239
+ return parentFirstLine + childRest;
240
+ }
241
+ return child;
242
+ };
243
+ let VError$1 = class VError extends Error {
244
+ constructor(error, message) {
245
+ const combinedMessage = getCombinedMessage$1(error, message);
246
+ super(combinedMessage);
247
+ this.name = 'VError';
248
+ if (error instanceof Error) {
249
+ this.stack = mergeStacks$1(this.stack, error.stack);
250
+ }
251
+ if (error.codeFrame) {
252
+ // @ts-ignore
253
+ this.codeFrame = error.codeFrame;
254
+ }
255
+ if (error.code) {
256
+ // @ts-ignore
257
+ this.code = error.code;
258
+ }
259
+ }
260
+ };
261
+
262
+ const getIframeSrc = (webViews, webViewId, webViewPort, root, isGitpod, locationProtocol, locationHost, locationOrigin) => {
263
+ try {
264
+ const webView = getWebView(webViews, webViewId);
265
+ if (platform === Web) {
266
+ return getIframeSrc$1(webView, locationOrigin);
267
+ }
268
+ return getIframeSrcRemote(webViews, webViewPort, webViewId, locationProtocol, locationHost, isGitpod, root);
269
+ } catch (error) {
270
+ throw new VError$1(error, `Failed to construct webview iframe src`);
271
+ }
272
+ };
273
+
274
+ const SemiColon = ';';
275
+ const Space = ' ';
276
+
277
+ const addSemicolon = line => {
278
+ return line + SemiColon;
279
+ };
280
+
281
+ const getContentSecurityPolicy = items => {
282
+ return items.map(addSemicolon).join(Space);
283
+ };
284
+
285
+ const getWebViewCsp = webView => {
286
+ if (webView && webView.contentSecurityPolicy) {
287
+ return getContentSecurityPolicy(webView.contentSecurityPolicy);
288
+ }
289
+ const csp = getContentSecurityPolicy([`default-src 'none'`, `script-src 'self'`, `style-src 'self'`, `img-src 'self'`, `media-src 'self'`]);
290
+ return csp;
291
+ };
292
+
293
+ const getWebViewFrameAncestors = (locationProtocol, locationHost) => {
294
+ const frameAncestors = createUrl(locationProtocol, locationHost);
295
+ return frameAncestors;
296
+ };
297
+
65
298
  const getWebViewOrigin = webViewPort => {
66
299
  // TODO don't hardcode protocol
67
300
  let origin = '';
@@ -104,7 +337,10 @@ const commandMap = {
104
337
  'Location.getHost': getHost,
105
338
  'Location.getOrigin': getOrigin,
106
339
  'Location.getProtocol': getProtocol,
340
+ 'WebView.getBaseUrl': getWebViewBaseUrl,
107
341
  'WebView.getFrameAncestors': getWebViewFrameAncestors,
342
+ 'WebView.getHtml': getWebViewHtml,
343
+ 'WebView.getIframeSrc': getIframeSrc,
108
344
  'WebView.getOrigin': getWebViewOrigin,
109
345
  'WebView.getSandbox': getIframeSandbox,
110
346
  'WebView.getWebViewCsp': getWebViewCsp
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/iframe-worker",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "",
5
5
  "main": "dist/iframeWorkerMain.js",
6
6
  "type": "module",