electrobun 0.0.19-beta.12 → 0.0.19-beta.128

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.
Files changed (100) hide show
  1. package/BUILD.md +90 -0
  2. package/README.md +1 -1
  3. package/bin/electrobun.cjs +31 -11
  4. package/debug.js +5 -0
  5. package/dist/api/browser/builtinrpcSchema.ts +19 -0
  6. package/dist/api/browser/index.ts +409 -0
  7. package/dist/api/browser/rpc/webview.ts +79 -0
  8. package/dist/api/browser/stylesAndElements.ts +3 -0
  9. package/dist/api/browser/webviewtag.ts +586 -0
  10. package/dist/api/bun/ElectrobunConfig.ts +171 -0
  11. package/dist/api/bun/core/ApplicationMenu.ts +66 -0
  12. package/dist/api/bun/core/BrowserView.ts +349 -0
  13. package/dist/api/bun/core/BrowserWindow.ts +195 -0
  14. package/dist/api/bun/core/ContextMenu.ts +67 -0
  15. package/dist/api/bun/core/Paths.ts +5 -0
  16. package/dist/api/bun/core/Socket.ts +181 -0
  17. package/dist/api/bun/core/Tray.ts +121 -0
  18. package/dist/api/bun/core/Updater.ts +681 -0
  19. package/dist/api/bun/core/Utils.ts +48 -0
  20. package/dist/api/bun/events/ApplicationEvents.ts +14 -0
  21. package/dist/api/bun/events/event.ts +29 -0
  22. package/dist/api/bun/events/eventEmitter.ts +45 -0
  23. package/dist/api/bun/events/trayEvents.ts +9 -0
  24. package/dist/api/bun/events/webviewEvents.ts +16 -0
  25. package/dist/api/bun/events/windowEvents.ts +12 -0
  26. package/dist/api/bun/index.ts +47 -0
  27. package/dist/api/bun/proc/linux.md +43 -0
  28. package/dist/api/bun/proc/native.ts +1322 -0
  29. package/dist/api/shared/platform.ts +48 -0
  30. package/dist/main.js +54 -0
  31. package/package.json +11 -6
  32. package/src/cli/index.ts +1353 -239
  33. package/templates/hello-world/README.md +57 -0
  34. package/templates/hello-world/bun.lock +225 -0
  35. package/templates/hello-world/electrobun.config.ts +28 -0
  36. package/templates/hello-world/package.json +16 -0
  37. package/templates/hello-world/src/bun/index.ts +15 -0
  38. package/templates/hello-world/src/mainview/index.css +124 -0
  39. package/templates/hello-world/src/mainview/index.html +46 -0
  40. package/templates/hello-world/src/mainview/index.ts +1 -0
  41. package/templates/interactive-playground/README.md +26 -0
  42. package/templates/interactive-playground/assets/tray-icon.png +0 -0
  43. package/templates/interactive-playground/electrobun.config.ts +36 -0
  44. package/templates/interactive-playground/package-lock.json +36 -0
  45. package/templates/interactive-playground/package.json +15 -0
  46. package/templates/interactive-playground/src/bun/demos/files.ts +70 -0
  47. package/templates/interactive-playground/src/bun/demos/menus.ts +139 -0
  48. package/templates/interactive-playground/src/bun/demos/rpc.ts +83 -0
  49. package/templates/interactive-playground/src/bun/demos/system.ts +72 -0
  50. package/templates/interactive-playground/src/bun/demos/updates.ts +105 -0
  51. package/templates/interactive-playground/src/bun/demos/windows.ts +90 -0
  52. package/templates/interactive-playground/src/bun/index.ts +124 -0
  53. package/templates/interactive-playground/src/bun/types/rpc.ts +109 -0
  54. package/templates/interactive-playground/src/mainview/components/EventLog.ts +107 -0
  55. package/templates/interactive-playground/src/mainview/components/Sidebar.ts +65 -0
  56. package/templates/interactive-playground/src/mainview/components/Toast.ts +57 -0
  57. package/templates/interactive-playground/src/mainview/demos/FileDemo.ts +211 -0
  58. package/templates/interactive-playground/src/mainview/demos/MenuDemo.ts +102 -0
  59. package/templates/interactive-playground/src/mainview/demos/RPCDemo.ts +229 -0
  60. package/templates/interactive-playground/src/mainview/demos/TrayDemo.ts +132 -0
  61. package/templates/interactive-playground/src/mainview/demos/WebViewDemo.ts +411 -0
  62. package/templates/interactive-playground/src/mainview/demos/WindowDemo.ts +207 -0
  63. package/templates/interactive-playground/src/mainview/index.css +538 -0
  64. package/templates/interactive-playground/src/mainview/index.html +103 -0
  65. package/templates/interactive-playground/src/mainview/index.ts +238 -0
  66. package/templates/multitab-browser/README.md +34 -0
  67. package/templates/multitab-browser/bun.lock +224 -0
  68. package/templates/multitab-browser/electrobun.config.ts +32 -0
  69. package/templates/multitab-browser/package-lock.json +20 -0
  70. package/templates/multitab-browser/package.json +12 -0
  71. package/templates/multitab-browser/src/bun/index.ts +144 -0
  72. package/templates/multitab-browser/src/bun/tabManager.ts +200 -0
  73. package/templates/multitab-browser/src/bun/types/rpc.ts +78 -0
  74. package/templates/multitab-browser/src/mainview/index.css +487 -0
  75. package/templates/multitab-browser/src/mainview/index.html +94 -0
  76. package/templates/multitab-browser/src/mainview/index.ts +629 -0
  77. package/templates/photo-booth/README.md +108 -0
  78. package/templates/photo-booth/bun.lock +239 -0
  79. package/templates/photo-booth/electrobun.config.ts +28 -0
  80. package/templates/photo-booth/package.json +16 -0
  81. package/templates/photo-booth/src/bun/index.ts +92 -0
  82. package/templates/photo-booth/src/mainview/index.css +465 -0
  83. package/templates/photo-booth/src/mainview/index.html +124 -0
  84. package/templates/photo-booth/src/mainview/index.ts +499 -0
  85. package/tests/bun.lock +14 -0
  86. package/tests/electrobun.config.ts +45 -0
  87. package/tests/package-lock.json +36 -0
  88. package/tests/package.json +13 -0
  89. package/tests/src/bun/index.ts +100 -0
  90. package/tests/src/bun/test-runner.ts +508 -0
  91. package/tests/src/mainview/index.html +110 -0
  92. package/tests/src/mainview/index.ts +458 -0
  93. package/tests/src/mainview/styles/main.css +451 -0
  94. package/tests/src/testviews/tray-test.html +57 -0
  95. package/tests/src/testviews/webview-mask.html +114 -0
  96. package/tests/src/testviews/webview-navigation.html +36 -0
  97. package/tests/src/testviews/window-create.html +17 -0
  98. package/tests/src/testviews/window-events.html +29 -0
  99. package/tests/src/testviews/window-focus.html +37 -0
  100. package/tests/src/webviewtag/index.ts +11 -0
@@ -0,0 +1,586 @@
1
+ type WebviewEventTypes =
2
+ | "did-navigate"
3
+ | "did-navigate-in-page"
4
+ | "did-commit-navigation"
5
+ | "dom-ready";
6
+
7
+ type Rect = { x: number; y: number; width: number; height: number };
8
+
9
+ const ConfigureWebviewTags = (
10
+ enableWebviewTags: boolean,
11
+ internalRpc: (params: any) => any,
12
+ bunRpc: (params: any) => any
13
+ ) => {
14
+ if (!enableWebviewTags) {
15
+ return;
16
+ }
17
+
18
+ // todo: provide global types for <electrobun-webview> tag elements (like querySelector results etc.)
19
+
20
+ class WebviewTag extends HTMLElement {
21
+ // todo (yoav): come up with a better mechanism to eliminate collisions with bun created
22
+ // webviews
23
+ webviewId?: number; // = nextWebviewId++;
24
+
25
+ // rpc
26
+ internalRpc: any;
27
+ bunRpc: any;
28
+
29
+ // querySelectors for elements that you want to appear
30
+ // in front of the webview.
31
+ maskSelectors: Set<string> = new Set();
32
+
33
+ // observers
34
+ resizeObserver?: ResizeObserver;
35
+ // intersectionObserver?: IntersectionObserver;
36
+ // mutationObserver?: MutationObserver;
37
+
38
+ positionCheckLoop?: Timer;
39
+ positionCheckLoopReset?: Timer;
40
+
41
+ lastRect = {
42
+ x: 0,
43
+ y: 0,
44
+ width: 0,
45
+ height: 0,
46
+ };
47
+
48
+ lastMasksJSON: string = "";
49
+ lastMasks: Rect[] = [];
50
+
51
+ transparent: boolean = false;
52
+ passthroughEnabled: boolean = false;
53
+ hidden: boolean = false;
54
+ hiddenMirrorMode: boolean = false;
55
+ wasZeroRect: boolean = false;
56
+ isMirroring: boolean = false;
57
+ masks: string = '';
58
+
59
+ partition: string | null = null;
60
+
61
+ constructor() {
62
+ super();
63
+ this.internalRpc = internalRpc;
64
+ this.bunRpc = bunRpc;
65
+
66
+ // Give it a frame to be added to the dom and render before measuring
67
+ requestAnimationFrame(() => {
68
+ this.initWebview();
69
+ });
70
+ }
71
+
72
+ addMaskSelector(selector: string) {
73
+ this.maskSelectors.add(selector);
74
+ this.syncDimensions();
75
+ }
76
+
77
+ removeMaskSelector(selector: string) {
78
+ this.maskSelectors.delete(selector);
79
+ this.syncDimensions();
80
+ }
81
+
82
+ async initWebview() {
83
+ const rect = this.getBoundingClientRect();
84
+ this.lastRect = rect;
85
+
86
+ const url = this.src || this.getAttribute("src");
87
+ const html = this.html || this.getAttribute("html");
88
+
89
+ const maskSelectors = this.masks || this.getAttribute("masks");
90
+
91
+ if (maskSelectors) {
92
+ maskSelectors.split(',').forEach(s => {
93
+ this.maskSelectors.add(s);
94
+ })
95
+ }
96
+
97
+ const webviewId = await this.internalRpc.request.webviewTagInit({
98
+ hostWebviewId: window.__electrobunWebviewId,
99
+ windowId: window.__electrobunWindowId,
100
+ renderer: this.renderer,
101
+ url: url,
102
+ html: html,
103
+ preload: this.preload || this.getAttribute("preload") || null,
104
+ partition: this.partition || this.getAttribute("partition") || null,
105
+ frame: {
106
+ width: rect.width,
107
+ height: rect.height,
108
+ x: rect.x,
109
+ y: rect.y,
110
+ },
111
+ // todo: wire up to a param and a method to update them
112
+ navigationRules: null,
113
+ });
114
+
115
+ this.webviewId = webviewId;
116
+ this.id = `electrobun-webview-${webviewId}`;
117
+ // todo: replace bun -> webviewtag communication with a global instead of
118
+ // queryselector based on id
119
+ this.setAttribute("id", this.id);
120
+ }
121
+
122
+ asyncResolvers: {
123
+ [id: string]: { resolve: (arg: any) => void; reject: (arg: any) => void };
124
+ } = {};
125
+
126
+ callAsyncJavaScript({ script }: { script: string }) {
127
+ return new Promise((resolve, reject) => {
128
+ const messageId = "" + Date.now() + Math.random();
129
+ this.asyncResolvers[messageId] = {
130
+ resolve,
131
+ reject,
132
+ };
133
+
134
+ this.internalRpc.request.webviewTagCallAsyncJavaScript({
135
+ messageId,
136
+ webviewId: this.webviewId,
137
+ hostWebviewId: window.__electrobunWebviewId,
138
+ script,
139
+ });
140
+ });
141
+ }
142
+
143
+ setCallAsyncJavaScriptResponse(messageId: string, response: any) {
144
+ const resolvers = this.asyncResolvers[messageId];
145
+ delete this.asyncResolvers[messageId];
146
+ try {
147
+ response = JSON.parse(response);
148
+
149
+ if (response.result) {
150
+ resolvers.resolve(response.result);
151
+ } else {
152
+ resolvers.reject(response.error);
153
+ }
154
+ } catch (e: any) {
155
+ resolvers.reject(e.message);
156
+ }
157
+ }
158
+
159
+ async canGoBack() {
160
+ return this.internalRpc.request.webviewTagCanGoBack({ id: this.webviewId });
161
+ }
162
+
163
+ async canGoForward() {
164
+ return this.internalRpc.request.webviewTagCanGoForward({
165
+ id: this.webviewId,
166
+ });
167
+ }
168
+
169
+ // propertie setters/getters. keeps them in sync with dom attributes
170
+ updateAttr(name: string, value: string | null) {
171
+ if (value) {
172
+ this.setAttribute(name, value);
173
+ } else {
174
+ this.removeAttribute(name);
175
+ }
176
+ }
177
+
178
+ get src() {
179
+ return this.getAttribute("src");
180
+ }
181
+
182
+ set src(value) {
183
+ this.updateAttr("src", value);
184
+ }
185
+
186
+ get html() {
187
+ return this.getAttribute("html");
188
+ }
189
+
190
+ set html(value) {
191
+ this.updateAttr("html", value);
192
+ }
193
+
194
+ get preload() {
195
+ return this.getAttribute("preload");
196
+ }
197
+
198
+ set preload(value) {
199
+ this.updateAttr("preload", value);
200
+ }
201
+
202
+ get renderer() {
203
+ const _renderer = this.getAttribute("renderer") === "cef" ? "cef" : "native";
204
+ return _renderer;
205
+ }
206
+
207
+ set renderer(value: 'cef' | 'native') {
208
+ const _renderer = value === "cef" ? "cef" : "native";
209
+ this.updateAttr("renderer", _renderer);
210
+ }
211
+
212
+ // Note: since <electrobun-webview> is an anchor for a native webview
213
+ // on osx even if we hide it, enable mouse passthrough etc. There
214
+ // are still events like drag events which are natively handled deep in the window manager
215
+ // and will be handled incorrectly. To get around this for now we need to
216
+ // move the webview off screen during delegate mode.
217
+ adjustDimensionsForHiddenMirrorMode(rect: DOMRect) {
218
+ if (this.hiddenMirrorMode) {
219
+ rect.x = 0 - rect.width;
220
+ }
221
+
222
+ return rect;
223
+ }
224
+
225
+ // Note: in the brwoser-context we can ride on the dom element's uilt in event emitter for managing custom events
226
+ on(event: WebviewEventTypes, listener: () => {}) {
227
+ this.addEventListener(event, listener);
228
+ }
229
+
230
+ off(event: WebviewEventTypes, listener: () => {}) {
231
+ this.removeEventListener(event, listener);
232
+ }
233
+
234
+ // This is typically called by injected js from bun
235
+ emit(event: WebviewEventTypes, detail: any) {
236
+ this.dispatchEvent(new CustomEvent(event, { detail }));
237
+ }
238
+
239
+ // Call this via document.querySelector('electrobun-webview').syncDimensions();
240
+ // That way the host can trigger an alignment with the nested webview when they
241
+ // know that they're chaning something in order to eliminate the lag that the
242
+ // catch all loop will catch
243
+ syncDimensions(force: boolean = false) {
244
+ if (!this.webviewId || (!force && this.hidden)) {
245
+ return;
246
+ }
247
+
248
+ const rect = this.getBoundingClientRect();
249
+ const { x, y, width, height } =
250
+ this.adjustDimensionsForHiddenMirrorMode(rect);
251
+ const lastRect = this.lastRect;
252
+
253
+ if (width === 0 && height === 0) {
254
+ if (this.wasZeroRect === false) {
255
+ this.wasZeroRect = true;
256
+ this.toggleHidden(true, true);
257
+ }
258
+ return;
259
+ }
260
+
261
+ const masks: Rect[] = [];
262
+ this.maskSelectors.forEach((selector) => {
263
+ const els = document.querySelectorAll(selector);
264
+
265
+ for (let i = 0; i < els.length; i++) {
266
+ const el = els[i];
267
+
268
+ if (el) {
269
+ const maskRect = el.getBoundingClientRect();
270
+
271
+ masks.push({
272
+ // reposition the bounding rect to be relative to the webview rect
273
+ // so objc can apply the mask correctly and handle the actual overlap
274
+ x: maskRect.x - x,
275
+ y: maskRect.y - y,
276
+ width: maskRect.width,
277
+ height: maskRect.height,
278
+ });
279
+ }
280
+ }
281
+ });
282
+
283
+ // store jsonStringified last masks value to compare
284
+ const masksJson = masks.length ? JSON.stringify(masks) : "";
285
+
286
+ if (
287
+ force ||
288
+ lastRect.x !== x ||
289
+ lastRect.y !== y ||
290
+ lastRect.width !== width ||
291
+ lastRect.height !== height ||
292
+ this.lastMasksJSON !== masksJson
293
+ ) {
294
+ // let it know we're still accelerating
295
+ this.setPositionCheckLoop(true);
296
+
297
+ this.lastRect = rect;
298
+ this.lastMasks = masks;
299
+ this.lastMasksJSON = masksJson;
300
+
301
+ this.internalRpc.send.webviewTagResize({
302
+ id: this.webviewId,
303
+ frame: {
304
+ width: width,
305
+ height: height,
306
+ x: x,
307
+ y: y,
308
+ },
309
+ masks: masksJson,
310
+ });
311
+ }
312
+
313
+ if (this.wasZeroRect) {
314
+ this.wasZeroRect = false;
315
+ this.toggleHidden(false, true);
316
+ }
317
+ }
318
+
319
+ boundSyncDimensions = () => this.syncDimensions();
320
+ boundForceSyncDimensions = () => this.syncDimensions(true);
321
+
322
+ setPositionCheckLoop(accelerate = false) {
323
+ if (this.positionCheckLoop) {
324
+ clearInterval(this.positionCheckLoop);
325
+ this.positionCheckLoop = undefined;
326
+ }
327
+
328
+ if (this.positionCheckLoopReset) {
329
+ clearTimeout(this.positionCheckLoopReset);
330
+ this.positionCheckLoopReset = undefined;
331
+ }
332
+
333
+ const delay = accelerate ? 0 : 300;
334
+
335
+ if (accelerate) {
336
+ this.positionCheckLoopReset = setTimeout(() => {
337
+ this.setPositionCheckLoop(false);
338
+ }, 2000);
339
+ }
340
+ // Note: Since there's not catch all way to listen for x/y changes
341
+ // we have a 400ms interval to check
342
+ // on m1 max this 400ms interval for one nested webview
343
+ // only uses around 0.1% cpu
344
+
345
+ // Note: We also listen for resize events and changes to
346
+ // certain properties to get reactive repositioning for
347
+ // many cases.
348
+
349
+ // todo: consider having an option to disable this and let user
350
+ // trigger position sync for high performance cases (like
351
+ // a browser with a hundred tabs)
352
+ this.positionCheckLoop = setInterval(() => this.syncDimensions(), delay);
353
+ }
354
+
355
+ connectedCallback() {
356
+ this.setPositionCheckLoop();
357
+
358
+ this.resizeObserver = new ResizeObserver(() => {
359
+ this.syncDimensions();
360
+ });
361
+ // Note: In objc the webview is positioned in the window from the bottom-left corner
362
+ // the html anchor is positioned in the webview from the top-left corner
363
+ // In those cases the getBoundingClientRect() will return the same value, but
364
+ // we still need to send it to objc to calculate from its bottom left position
365
+ // otherwise it'll move around unexpectedly.
366
+ window.addEventListener("resize", this.boundForceSyncDimensions);
367
+ window.addEventListener("scroll", this.boundSyncDimensions);
368
+
369
+ // todo: For chromium webviews (windows native or chromium bundled)
370
+ // should be able to use performanceObservers on layout-shift to
371
+ // call syncDimensions more reactively
372
+ }
373
+
374
+ disconnectedCallback() {
375
+ // removed from the dom
376
+ clearInterval(this.positionCheckLoop);
377
+
378
+ this.resizeObserver?.disconnect();
379
+ // this.intersectionObserver?.disconnect();
380
+ // this.mutationObserver?.disconnect();
381
+ window.removeEventListener("resize", this.boundForceSyncDimensions);
382
+ window.removeEventListener("scroll", this.boundSyncDimensions);
383
+
384
+ if (this.webviewId) {
385
+ this.internalRpc.send.webviewTagRemove({ id: this.webviewId });
386
+ // Mark webview as removed to prevent further method calls
387
+ this.webviewId = undefined;
388
+ }
389
+ }
390
+
391
+ static get observedAttributes() {
392
+ // TODO: support html, preload, and other stuff here
393
+ return ["src", "html", "preload", "class", "style"];
394
+ }
395
+
396
+ attributeChangedCallback(name, oldValue, newValue) {
397
+ if (name === "src" && oldValue !== newValue) {
398
+ this.updateIFrameSrc(newValue);
399
+ } else if (name === "html" && oldValue !== newValue) {
400
+ this.updateIFrameHtml(newValue);
401
+ } else if (name === "preload" && oldValue !== newValue) {
402
+ this.updateIFramePreload(newValue);
403
+ } else {
404
+ this.syncDimensions();
405
+ }
406
+ }
407
+
408
+ updateIFrameSrc(src: string) {
409
+ if (!this.webviewId) {
410
+ console.warn('updateIFrameSrc called on removed webview');
411
+ return;
412
+ }
413
+ this.internalRpc.send.webviewTagUpdateSrc({
414
+ id: this.webviewId,
415
+ url: src,
416
+ });
417
+ }
418
+
419
+ updateIFrameHtml(html: string) {
420
+ if (!this.webviewId) {
421
+ console.warn('updateIFrameHtml called on removed webview');
422
+ return;
423
+ }
424
+
425
+ this.internalRpc.send.webviewTagUpdateHtml({
426
+ id: this.webviewId,
427
+ html: html,
428
+ });
429
+ }
430
+
431
+ updateIFramePreload(preload: string) {
432
+ if (!this.webviewId) {
433
+ console.warn('updateIFramePreload called on removed webview');
434
+ return;
435
+ }
436
+ this.internalRpc.send.webviewTagUpdatePreload({
437
+ id: this.webviewId,
438
+ preload,
439
+ });
440
+ }
441
+
442
+ goBack() {
443
+ if (!this.webviewId) {
444
+ console.warn('goBack called on removed webview');
445
+ return;
446
+ }
447
+ this.internalRpc.send.webviewTagGoBack({ id: this.webviewId });
448
+ }
449
+
450
+ goForward() {
451
+ if (!this.webviewId) {
452
+ console.warn('goForward called on removed webview');
453
+ return;
454
+ }
455
+ this.internalRpc.send.webviewTagGoForward({ id: this.webviewId });
456
+ }
457
+
458
+ reload() {
459
+ if (!this.webviewId) {
460
+ console.warn('reload called on removed webview');
461
+ return;
462
+ }
463
+ this.internalRpc.send.webviewTagReload({ id: this.webviewId });
464
+ }
465
+ loadURL(url: string) {
466
+ if (!this.webviewId) {
467
+ console.warn('loadURL called on removed webview');
468
+ return;
469
+ }
470
+ this.setAttribute("src", url);
471
+ this.internalRpc.send.webviewTagUpdateSrc({
472
+ id: this.webviewId,
473
+ url,
474
+ });
475
+ }
476
+ loadHTML(html: string) {
477
+ if (!this.webviewId) {
478
+ console.warn('loadHTML called on removed webview');
479
+ return;
480
+ }
481
+ this.setAttribute("html", html);
482
+ this.internalRpc.send.webviewTagUpdateHtml({
483
+ id: this.webviewId,
484
+ html,
485
+ })
486
+ }
487
+
488
+ // This sets the native webview hovering over the dom to be transparent
489
+ toggleTransparent(transparent?: boolean, bypassState?: boolean) {
490
+ if (!this.webviewId) {
491
+ console.warn('toggleTransparent called on removed webview');
492
+ return;
493
+ }
494
+
495
+ if (!bypassState) {
496
+ if (typeof transparent === "undefined") {
497
+ this.transparent = !this.transparent;
498
+ } else {
499
+ this.transparent = transparent;
500
+ }
501
+ }
502
+
503
+ this.internalRpc.send.webviewTagSetTransparent({
504
+ id: this.webviewId,
505
+ transparent: this.transparent || Boolean(transparent),
506
+ });
507
+ }
508
+ togglePassthrough(enablePassthrough?: boolean, bypassState?: boolean) {
509
+ if (!this.webviewId) {
510
+ console.warn('togglePassthrough called on removed webview');
511
+ return;
512
+ }
513
+
514
+ if (!bypassState) {
515
+ if (typeof enablePassthrough === "undefined") {
516
+ this.passthroughEnabled = !this.passthroughEnabled;
517
+ } else {
518
+ this.passthroughEnabled = enablePassthrough;
519
+ }
520
+ }
521
+
522
+ this.internalRpc.send.webviewTagSetPassthrough({
523
+ id: this.webviewId,
524
+ enablePassthrough:
525
+ this.passthroughEnabled || Boolean(enablePassthrough),
526
+ });
527
+ }
528
+
529
+ toggleHidden(hidden?: boolean, bypassState?: boolean) {
530
+ if (!this.webviewId) {
531
+ console.warn('toggleHidden called on removed webview');
532
+ return;
533
+ }
534
+
535
+ if (!bypassState) {
536
+ if (typeof hidden === "undefined") {
537
+ this.hidden = !this.hidden;
538
+ } else {
539
+ this.hidden = hidden;
540
+ }
541
+ }
542
+
543
+ this.internalRpc.send.webviewTagSetHidden({
544
+ id: this.webviewId,
545
+ hidden: this.hidden || Boolean(hidden),
546
+ });
547
+ }
548
+ }
549
+
550
+ customElements.define("electrobun-webview", WebviewTag);
551
+
552
+ insertWebviewTagNormalizationStyles();
553
+ };
554
+
555
+ // Give <electrobun-webview>s some default styles that can
556
+ // be easily overridden in the host document
557
+ const insertWebviewTagNormalizationStyles = () => {
558
+ var style = document.createElement("style");
559
+ style.type = "text/css";
560
+
561
+ var css = `
562
+ electrobun-webview {
563
+ display: block;
564
+ width: 800px;
565
+ height: 300px;
566
+ background: #fff;
567
+ background-repeat: no-repeat!important;
568
+ overflow: hidden;
569
+ }
570
+ `;
571
+
572
+ style.appendChild(document.createTextNode(css));
573
+
574
+ var head = document.getElementsByTagName("head")[0];
575
+ if (!head) {
576
+ return;
577
+ }
578
+
579
+ if (head.firstChild) {
580
+ head.insertBefore(style, head.firstChild);
581
+ } else {
582
+ head.appendChild(style);
583
+ }
584
+ };
585
+
586
+ export { ConfigureWebviewTags };