@zenbu-labs/pixel 0.0.0 → 0.0.13

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 (153) hide show
  1. package/dist/bin.d.ts +2 -0
  2. package/dist/bin.js +161 -0
  3. package/dist/bootstrap.d.ts +1 -0
  4. package/dist/bootstrap.js +75 -0
  5. package/dist/context-menu.d.ts +20 -0
  6. package/dist/context-menu.js +57 -0
  7. package/dist/debug.d.ts +1 -0
  8. package/dist/debug.js +9 -0
  9. package/dist/devtools-layout.d.ts +21 -0
  10. package/dist/devtools-layout.js +45 -0
  11. package/dist/devtools.d.ts +33 -0
  12. package/dist/devtools.js +125 -0
  13. package/dist/electron/index.d.ts +3 -0
  14. package/dist/electron/index.js +4 -0
  15. package/dist/host/guest.d.ts +5 -0
  16. package/dist/host/guest.js +178 -0
  17. package/dist/host/server.d.ts +91 -0
  18. package/dist/host/server.js +296 -0
  19. package/dist/host/shell.d.ts +35 -0
  20. package/dist/host/shell.js +113 -0
  21. package/dist/host/strip.d.ts +6 -0
  22. package/dist/host/strip.js +63 -0
  23. package/dist/icons.d.ts +30 -0
  24. package/dist/icons.js +58 -0
  25. package/dist/index.d.ts +17 -0
  26. package/dist/index.js +39 -0
  27. package/dist/instances.d.ts +30 -0
  28. package/dist/instances.js +177 -0
  29. package/dist/layout.d.ts +5 -0
  30. package/dist/layout.js +34 -0
  31. package/dist/popup.d.ts +21 -0
  32. package/dist/popup.js +47 -0
  33. package/dist/preload/index.d.ts +15 -0
  34. package/dist/preload/index.js +3 -0
  35. package/dist/react/colors.d.ts +3 -0
  36. package/dist/react/colors.js +25 -0
  37. package/dist/react/components.d.ts +21 -0
  38. package/dist/react/components.js +45 -0
  39. package/dist/react/devtools/app.d.ts +3 -0
  40. package/dist/react/devtools/app.js +89 -0
  41. package/dist/react/devtools/console-capture.d.ts +1 -0
  42. package/dist/react/devtools/console-capture.js +41 -0
  43. package/dist/react/devtools/controller.d.ts +45 -0
  44. package/dist/react/devtools/controller.js +252 -0
  45. package/dist/react/devtools/elements.d.ts +4 -0
  46. package/dist/react/devtools/elements.js +152 -0
  47. package/dist/react/devtools/export-profile.d.ts +2 -0
  48. package/dist/react/devtools/export-profile.js +225 -0
  49. package/dist/react/devtools/fiber-hook.d.ts +1 -0
  50. package/dist/react/devtools/fiber-hook.js +89 -0
  51. package/dist/react/devtools/log-panel.d.ts +4 -0
  52. package/dist/react/devtools/log-panel.js +113 -0
  53. package/dist/react/devtools/profiler.d.ts +11 -0
  54. package/dist/react/devtools/profiler.js +374 -0
  55. package/dist/react/devtools/store.d.ts +27 -0
  56. package/dist/react/devtools/store.js +61 -0
  57. package/dist/react/devtools/stores.d.ts +92 -0
  58. package/dist/react/devtools/stores.js +41 -0
  59. package/dist/react/devtools/theme.d.ts +35 -0
  60. package/dist/react/devtools/theme.js +77 -0
  61. package/dist/react/devtools/ui.d.ts +24 -0
  62. package/dist/react/devtools/ui.js +59 -0
  63. package/dist/react/index.d.ts +110 -0
  64. package/dist/react/index.js +538 -0
  65. package/dist/react/markdown.d.ts +25 -0
  66. package/dist/react/markdown.js +270 -0
  67. package/dist/react/native.d.ts +116 -0
  68. package/dist/react/native.js +56 -0
  69. package/dist/react/reconciler-config.d.ts +241 -0
  70. package/dist/react/reconciler-config.js +412 -0
  71. package/dist/react/styles.d.ts +88 -0
  72. package/dist/react/styles.js +85 -0
  73. package/dist/react/surface.d.ts +55 -0
  74. package/dist/react/surface.js +74 -0
  75. package/dist/registry.d.ts +53 -0
  76. package/dist/registry.js +193 -0
  77. package/dist/root.d.ts +19 -0
  78. package/dist/root.js +342 -0
  79. package/dist/sandbox.d.ts +4 -0
  80. package/dist/sandbox.js +84 -0
  81. package/dist/scale.d.ts +7 -0
  82. package/dist/scale.js +31 -0
  83. package/dist/ssh/index.d.ts +58 -0
  84. package/dist/ssh/index.js +445 -0
  85. package/dist/terminal/applescript.d.ts +2 -0
  86. package/dist/terminal/applescript.js +20 -0
  87. package/dist/terminal/detect.d.ts +10 -0
  88. package/dist/terminal/detect.js +34 -0
  89. package/dist/terminal/graphics.d.ts +9 -0
  90. package/dist/terminal/graphics.js +142 -0
  91. package/dist/terminal/index.d.ts +12 -0
  92. package/dist/terminal/index.js +23 -0
  93. package/dist/terminal/run.d.ts +2 -0
  94. package/dist/terminal/run.js +15 -0
  95. package/dist/terminal/shared.d.ts +20 -0
  96. package/dist/terminal/shared.js +88 -0
  97. package/dist/terminal/terminal.d.ts +66 -0
  98. package/dist/terminal/terminal.js +6 -0
  99. package/dist/terminal/terminals/cmux.d.ts +2 -0
  100. package/dist/terminal/terminals/cmux.js +98 -0
  101. package/dist/terminal/terminals/ghostty-script.d.ts +1 -0
  102. package/dist/terminal/terminals/ghostty-script.js +179 -0
  103. package/dist/terminal/terminals/ghostty.d.ts +2 -0
  104. package/dist/terminal/terminals/ghostty.js +336 -0
  105. package/dist/terminal/terminals/herdr.d.ts +2 -0
  106. package/dist/terminal/terminals/herdr.js +141 -0
  107. package/dist/terminal/terminals/index.d.ts +5 -0
  108. package/dist/terminal/terminals/index.js +26 -0
  109. package/dist/terminal/terminals/kitty.d.ts +2 -0
  110. package/dist/terminal/terminals/kitty.js +209 -0
  111. package/dist/terminal/terminals/supacode.d.ts +2 -0
  112. package/dist/terminal/terminals/supacode.js +79 -0
  113. package/dist/terminal/terminals/tmux.d.ts +2 -0
  114. package/dist/terminal/terminals/tmux.js +132 -0
  115. package/dist/terminal/terminals/tty7.d.ts +2 -0
  116. package/dist/terminal/terminals/tty7.js +58 -0
  117. package/dist/terminal/terminals/vscode.d.ts +2 -0
  118. package/dist/terminal/terminals/vscode.js +13 -0
  119. package/dist/terminal/terminals/wezterm.d.ts +2 -0
  120. package/dist/terminal/terminals/wezterm.js +59 -0
  121. package/dist/theme.d.ts +22 -0
  122. package/dist/theme.js +40 -0
  123. package/dist/web/browser-session.d.ts +13 -0
  124. package/dist/web/browser-session.js +186 -0
  125. package/dist/web/cursor.d.ts +1 -0
  126. package/dist/web/cursor.js +24 -0
  127. package/dist/web/devtools.d.ts +39 -0
  128. package/dist/web/devtools.js +300 -0
  129. package/dist/web/favicon.d.ts +7 -0
  130. package/dist/web/favicon.js +73 -0
  131. package/dist/web/frame-rate.d.ts +1 -0
  132. package/dist/web/frame-rate.js +12 -0
  133. package/dist/web/host.d.ts +123 -0
  134. package/dist/web/host.js +573 -0
  135. package/dist/web/input.d.ts +49 -0
  136. package/dist/web/input.js +468 -0
  137. package/dist/web/offscreen.d.ts +2 -0
  138. package/dist/web/offscreen.js +23 -0
  139. package/dist/web/paint.d.ts +11 -0
  140. package/dist/web/paint.js +128 -0
  141. package/dist/web/popup.d.ts +40 -0
  142. package/dist/web/popup.js +144 -0
  143. package/dist/web/session.d.ts +20 -0
  144. package/dist/web/session.js +110 -0
  145. package/dist/web/types.d.ts +38 -0
  146. package/dist/web/types.js +39 -0
  147. package/dist/web/zoom.d.ts +5 -0
  148. package/dist/web/zoom.js +36 -0
  149. package/dist/webview.d.ts +55 -0
  150. package/dist/webview.js +481 -0
  151. package/package.json +69 -3
  152. package/scripts/apparmor.sh +71 -0
  153. package/scripts/postinstall.mjs +150 -0
@@ -0,0 +1,40 @@
1
+ import type { BrowserWindow } from "electron";
2
+ import type { Surface } from "../react";
3
+ import { PageInput } from "./input";
4
+ import type { ZoomDirection } from "./zoom";
5
+ export interface PopupState {
6
+ url: string;
7
+ title: string;
8
+ loading: boolean;
9
+ width: number;
10
+ height: number;
11
+ }
12
+ export declare class PopupWindow {
13
+ readonly input: PageInput;
14
+ cursorShape: string;
15
+ onCursorChange: (() => void) | null;
16
+ private readonly window;
17
+ private readonly surface;
18
+ private readonly onChange;
19
+ private readonly renderScale;
20
+ private stateValue;
21
+ private visible;
22
+ private focused;
23
+ private cdpAttached;
24
+ private destroyed;
25
+ constructor(window: BrowserWindow, surface: Surface, size: {
26
+ width: number;
27
+ height: number;
28
+ }, renderScale: number, scale: () => number, onChange: () => void, onClosed: () => void, openWindow?: (details: Electron.HandlerDetails) => Electron.WindowOpenHandlerResponse);
29
+ get state(): PopupState;
30
+ close(): void;
31
+ zoom(direction: ZoomDirection): number;
32
+ scaleZoom(ratio: number): number;
33
+ setVisible(visible: boolean): void;
34
+ private screencastParams;
35
+ private startStreaming;
36
+ private focus;
37
+ private attachCdp;
38
+ private cdp;
39
+ private update;
40
+ }
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PopupWindow = void 0;
4
+ const electron_1 = require("electron");
5
+ const cursor_1 = require("./cursor");
6
+ const input_1 = require("./input");
7
+ const zoom_1 = require("./zoom");
8
+ class PopupWindow {
9
+ input;
10
+ cursorShape = "default";
11
+ onCursorChange = null;
12
+ window;
13
+ surface;
14
+ onChange;
15
+ renderScale;
16
+ stateValue;
17
+ visible = true;
18
+ focused = false;
19
+ cdpAttached = false;
20
+ destroyed = false;
21
+ constructor(window, surface, size, renderScale, scale, onChange, onClosed, openWindow) {
22
+ this.window = window;
23
+ this.surface = surface;
24
+ this.onChange = onChange;
25
+ this.renderScale = renderScale;
26
+ this.stateValue = {
27
+ url: window.webContents.getURL(),
28
+ title: "",
29
+ loading: true,
30
+ width: size.width,
31
+ height: size.height,
32
+ };
33
+ this.input = new input_1.PageInput({
34
+ contents: () => this.window.webContents,
35
+ scale,
36
+ focus: () => this.focus(),
37
+ cdp: (method, params) => this.cdp(method, params),
38
+ });
39
+ const contents = window.webContents;
40
+ contents.on("page-title-updated", (_event, title) => this.update({ title }));
41
+ contents.on("did-navigate", (_event, url) => this.update({ url }));
42
+ contents.on("did-navigate-in-page", (_event, url, mainFrame) => {
43
+ if (mainFrame)
44
+ this.update({ url });
45
+ });
46
+ contents.on("did-start-loading", () => this.update({ loading: true }));
47
+ contents.on("did-stop-loading", () => this.update({ loading: false }));
48
+ contents.on("cursor-changed", (_event, type) => {
49
+ const shape = (0, cursor_1.cursorShapeFor)(type);
50
+ if (shape === this.cursorShape)
51
+ return;
52
+ this.cursorShape = shape;
53
+ this.onCursorChange?.();
54
+ });
55
+ contents.setWindowOpenHandler(openWindow ??
56
+ (({ url }) => {
57
+ void contents.loadURL(url);
58
+ return { action: "deny" };
59
+ }));
60
+ window.on("closed", () => {
61
+ this.destroyed = true;
62
+ this.surface.clear();
63
+ onClosed();
64
+ });
65
+ void this.startStreaming(size, renderScale).catch(() => { });
66
+ this.focus();
67
+ }
68
+ get state() {
69
+ return this.stateValue;
70
+ }
71
+ close() {
72
+ if (!this.destroyed)
73
+ this.window.destroy();
74
+ }
75
+ zoom(direction) {
76
+ return (0, zoom_1.stepZoom)(this.window.webContents, direction);
77
+ }
78
+ scaleZoom(ratio) {
79
+ return (0, zoom_1.scaleZoom)(this.window.webContents, ratio);
80
+ }
81
+ setVisible(visible) {
82
+ if (this.visible === visible || this.destroyed)
83
+ return;
84
+ this.visible = visible;
85
+ void this.cdp(visible ? "Page.startScreencast" : "Page.stopScreencast", {
86
+ ...(visible ? this.screencastParams() : {}),
87
+ }).catch(() => { });
88
+ }
89
+ screencastParams() {
90
+ return {
91
+ format: "png",
92
+ everyNthFrame: 1,
93
+ maxWidth: Math.ceil(this.stateValue.width * this.renderScale),
94
+ maxHeight: Math.ceil(this.stateValue.height * this.renderScale),
95
+ };
96
+ }
97
+ async startStreaming(size, renderScale) {
98
+ await this.attachCdp();
99
+ this.window.webContents.debugger.on("message", (_event, method, params) => {
100
+ if (method !== "Page.screencastFrame")
101
+ return;
102
+ const frame = params;
103
+ void this.cdp("Page.screencastFrameAck", { sessionId: frame.sessionId }).catch(() => { });
104
+ if (!this.visible || this.destroyed)
105
+ return;
106
+ const image = electron_1.nativeImage.createFromBuffer(Buffer.from(frame.data, "base64"));
107
+ if (image.isEmpty())
108
+ return;
109
+ const dims = image.getSize();
110
+ this.surface.present({ bgra: image.toBitmap(), width: dims.width, height: dims.height });
111
+ });
112
+ await this.cdp("Page.enable");
113
+ await this.cdp("Emulation.setDeviceMetricsOverride", {
114
+ width: size.width,
115
+ height: size.height,
116
+ deviceScaleFactor: renderScale,
117
+ mobile: false,
118
+ });
119
+ await this.cdp("Page.startScreencast", this.screencastParams());
120
+ }
121
+ focus() {
122
+ if (this.focused || this.destroyed)
123
+ return;
124
+ this.focused = true;
125
+ this.window.focus();
126
+ this.window.webContents.focus();
127
+ return this.cdp("Emulation.setFocusEmulationEnabled", { enabled: true }).then(() => undefined, () => undefined);
128
+ }
129
+ async attachCdp() {
130
+ if (this.cdpAttached)
131
+ return;
132
+ this.window.webContents.debugger.attach("1.3");
133
+ this.cdpAttached = true;
134
+ }
135
+ async cdp(method, params) {
136
+ await this.attachCdp();
137
+ return this.window.webContents.debugger.sendCommand(method, params);
138
+ }
139
+ update(change) {
140
+ this.stateValue = { ...this.stateValue, ...change };
141
+ this.onChange();
142
+ }
143
+ }
144
+ exports.PopupWindow = PopupWindow;
@@ -0,0 +1,20 @@
1
+ import type { Session } from "electron";
2
+ import type { PageHost } from "./host";
3
+ export interface TerminalTheme {
4
+ background: number[];
5
+ foreground: number[];
6
+ ansi: (number[] | null)[];
7
+ }
8
+ export declare const THEME_CHANNEL = "pixel:theme";
9
+ export declare const THEME_REQUEST_CHANNEL = "pixel:theme-request";
10
+ export declare const QUIT_CHANNEL = "pixel:quit";
11
+ export declare function prepareSession(ses: Session): void;
12
+ export declare function flushSessions(): void;
13
+ export interface EmbedderHost {
14
+ hosts(): Iterable<PageHost>;
15
+ theme(): TerminalTheme | null;
16
+ quit(host: PageHost): void;
17
+ }
18
+ export declare function installEmbedderApi(target: EmbedderHost): void;
19
+ export declare function uninstallEmbedderApi(target: EmbedderHost): void;
20
+ export declare function broadcastTheme(target: EmbedderHost, theme: TerminalTheme | null): void;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.QUIT_CHANNEL = exports.THEME_REQUEST_CHANNEL = exports.THEME_CHANNEL = void 0;
7
+ exports.prepareSession = prepareSession;
8
+ exports.flushSessions = flushSessions;
9
+ exports.installEmbedderApi = installEmbedderApi;
10
+ exports.uninstallEmbedderApi = uninstallEmbedderApi;
11
+ exports.broadcastTheme = broadcastTheme;
12
+ const node_fs_1 = __importDefault(require("node:fs"));
13
+ const node_path_1 = __importDefault(require("node:path"));
14
+ const electron_1 = require("electron");
15
+ const browser_session_1 = require("./browser-session");
16
+ exports.THEME_CHANNEL = "pixel:theme";
17
+ exports.THEME_REQUEST_CHANNEL = "pixel:theme-request";
18
+ exports.QUIT_CHANNEL = "pixel:quit";
19
+ // library into an app keeps working.
20
+ const API_PRELOAD_SOURCE = `if (process.isMainFrame) {
21
+ const { ipcRenderer } = require("electron");
22
+ let current = null;
23
+ const subscribers = new Set();
24
+ ipcRenderer.on("pixel:theme", (_event, theme) => {
25
+ current = theme;
26
+ for (const subscriber of subscribers) {
27
+ try { subscriber(theme); } catch {}
28
+ }
29
+ });
30
+ ipcRenderer.send("pixel:theme-request");
31
+ globalThis.pixel = {
32
+ theme: () => current,
33
+ onTheme(subscriber) {
34
+ subscribers.add(subscriber);
35
+ if (current) { try { subscriber(current); } catch {} }
36
+ return () => subscribers.delete(subscriber);
37
+ },
38
+ quit: () => ipcRenderer.send("pixel:quit"),
39
+ };
40
+ }
41
+ `;
42
+ let apiPreloadFile = null;
43
+ function apiPreloadPath() {
44
+ if (!apiPreloadFile) {
45
+ apiPreloadFile = node_path_1.default.join(electron_1.app.getPath("userData"), "pixel-api-preload.js");
46
+ node_fs_1.default.writeFileSync(apiPreloadFile, API_PRELOAD_SOURCE);
47
+ }
48
+ return apiPreloadFile;
49
+ }
50
+ const prepared = new Set();
51
+ function prepareSession(ses) {
52
+ if (prepared.has(ses))
53
+ return;
54
+ prepared.add(ses);
55
+ (0, browser_session_1.configureBrowserSession)(ses);
56
+ ses.registerPreloadScript({ type: "frame", filePath: apiPreloadPath() });
57
+ }
58
+ function flushSessions() {
59
+ for (const ses of prepared) {
60
+ try {
61
+ ses.flushStorageData();
62
+ }
63
+ catch { }
64
+ }
65
+ }
66
+ const embedders = new Set();
67
+ function ownerOf(event) {
68
+ if (event.senderFrame !== event.sender.mainFrame)
69
+ return null;
70
+ for (const embedder of embedders) {
71
+ for (const host of embedder.hosts()) {
72
+ if (host.hasContents(event.sender.id))
73
+ return { embedder, host };
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+ function onThemeRequest(event) {
79
+ const owner = ownerOf(event);
80
+ if (!owner)
81
+ return;
82
+ const payload = owner.embedder.theme();
83
+ if (payload)
84
+ event.sender.send(exports.THEME_CHANNEL, payload);
85
+ }
86
+ function onQuitRequest(event) {
87
+ const owner = ownerOf(event);
88
+ if (owner)
89
+ owner.embedder.quit(owner.host);
90
+ }
91
+ function installEmbedderApi(target) {
92
+ if (embedders.size === 0) {
93
+ electron_1.ipcMain.on(exports.THEME_REQUEST_CHANNEL, onThemeRequest);
94
+ electron_1.ipcMain.on(exports.QUIT_CHANNEL, onQuitRequest);
95
+ }
96
+ embedders.add(target);
97
+ }
98
+ function uninstallEmbedderApi(target) {
99
+ embedders.delete(target);
100
+ if (embedders.size === 0) {
101
+ electron_1.ipcMain.removeListener(exports.THEME_REQUEST_CHANNEL, onThemeRequest);
102
+ electron_1.ipcMain.removeListener(exports.QUIT_CHANNEL, onQuitRequest);
103
+ }
104
+ }
105
+ function broadcastTheme(target, theme) {
106
+ if (!theme)
107
+ return;
108
+ for (const host of target.hosts())
109
+ host.sendToPage(exports.THEME_CHANNEL, theme);
110
+ }
@@ -0,0 +1,38 @@
1
+ import type { TextureInfo } from "electron";
2
+ export type DevtoolsDock = "bottom" | "right";
3
+ export interface WebViewState {
4
+ url: string;
5
+ title: string;
6
+ loading: boolean;
7
+ canGoBack: boolean;
8
+ canGoForward: boolean;
9
+ findMatches: {
10
+ active: number;
11
+ total: number;
12
+ } | null;
13
+ zoom: number;
14
+ favicon: string | null;
15
+ }
16
+ export declare function initialWebViewState(url: string): WebViewState;
17
+ export interface SurfaceLayout {
18
+ x: number;
19
+ y: number;
20
+ width: number;
21
+ height: number;
22
+ scale: number;
23
+ }
24
+ export declare function cssSize(width: number, height: number, scale: number): {
25
+ width: number;
26
+ height: number;
27
+ };
28
+ export declare function snapToCssGrid(width: number, height: number, scale: number): {
29
+ width: number;
30
+ height: number;
31
+ };
32
+ export declare function damageOf(info: TextureInfo): {
33
+ x: number;
34
+ y: number;
35
+ width: number;
36
+ height: number;
37
+ } | undefined;
38
+ export declare function paintedNothing(info: TextureInfo): boolean;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initialWebViewState = initialWebViewState;
4
+ exports.cssSize = cssSize;
5
+ exports.snapToCssGrid = snapToCssGrid;
6
+ exports.damageOf = damageOf;
7
+ exports.paintedNothing = paintedNothing;
8
+ function initialWebViewState(url) {
9
+ return {
10
+ url,
11
+ title: "",
12
+ loading: true,
13
+ canGoBack: false,
14
+ canGoForward: false,
15
+ findMatches: null,
16
+ zoom: 1,
17
+ favicon: null,
18
+ };
19
+ }
20
+ function cssSize(width, height, scale) {
21
+ return {
22
+ width: Math.max(1, Math.floor(width / scale)),
23
+ height: Math.max(1, Math.floor(height / scale)),
24
+ };
25
+ }
26
+ function snapToCssGrid(width, height, scale) {
27
+ const css = cssSize(width, height, scale);
28
+ return { width: Math.round(css.width * scale), height: Math.round(css.height * scale) };
29
+ }
30
+ function damageOf(info) {
31
+ const rect = info.metadata?.captureUpdateRect;
32
+ if (!rect || rect.width <= 0 || rect.height <= 0)
33
+ return undefined;
34
+ return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
35
+ }
36
+ function paintedNothing(info) {
37
+ const rect = info.metadata?.captureUpdateRect;
38
+ return !!rect && (rect.width <= 0 || rect.height <= 0);
39
+ }
@@ -0,0 +1,5 @@
1
+ import type { WebContents } from "electron";
2
+ export type ZoomDirection = 1 | -1 | 0;
3
+ export declare function stepZoom(contents: WebContents, direction: ZoomDirection): number;
4
+ export declare function scaleZoom(contents: WebContents, ratio: number): number;
5
+ export declare function zoomDirection(key: string): ZoomDirection | null;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stepZoom = stepZoom;
4
+ exports.scaleZoom = scaleZoom;
5
+ exports.zoomDirection = zoomDirection;
6
+ const ZOOM_PRESETS = [
7
+ 0.25, 0.33, 0.5, 0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5,
8
+ ];
9
+ function stepZoom(contents, direction) {
10
+ const current = contents.getZoomFactor();
11
+ const factor = direction === 0
12
+ ? 1
13
+ : direction === 1
14
+ ? (ZOOM_PRESETS.find((preset) => preset > current * 1.001) ?? ZOOM_PRESETS.at(-1))
15
+ : ([...ZOOM_PRESETS].reverse().find((preset) => preset < current * 0.999) ??
16
+ ZOOM_PRESETS[0]);
17
+ contents.setZoomFactor(factor);
18
+ return factor;
19
+ }
20
+ function scaleZoom(contents, ratio) {
21
+ const floor = ZOOM_PRESETS[0];
22
+ const ceiling = ZOOM_PRESETS.at(-1);
23
+ const exact = contents.getZoomFactor() * ratio;
24
+ const factor = Math.min(ceiling, Math.max(floor, Math.round(exact * 1000) / 1000));
25
+ contents.setZoomFactor(factor);
26
+ return factor;
27
+ }
28
+ function zoomDirection(key) {
29
+ if (key === "=" || key === "+")
30
+ return 1;
31
+ if (key === "-" || key === "_")
32
+ return -1;
33
+ if (key === "0")
34
+ return 0;
35
+ return null;
36
+ }
@@ -0,0 +1,55 @@
1
+ import type { PointerEvent, Style, SurfaceCapture } from "./react";
2
+ import type { DownloadProgress } from "./web/browser-session";
3
+ import type { BrowserWindowOptions, OpenWindowDecision, OpenWindowPolicy } from "./web/host";
4
+ import type { DevtoolsDock, WebViewState } from "./web/types";
5
+ import type { ZoomDirection } from "./web/zoom";
6
+ export type { BrowserWindowOptions, DownloadProgress, OpenWindowDecision, OpenWindowPolicy, WebViewState };
7
+ export interface WebViewProps {
8
+ src: string;
9
+ style?: Style;
10
+ preload?: string;
11
+ partition?: string;
12
+ clipboardRead?: boolean;
13
+ proxy?: string;
14
+ browserWindowOptions?: BrowserWindowOptions;
15
+ autoFocus?: boolean;
16
+ devtools?: boolean | DevtoolsDock;
17
+ hidden?: boolean;
18
+ keepFrame?: boolean;
19
+ onChange?(state: WebViewState): void;
20
+ onPointer?(event: PointerEvent): void;
21
+ onContextMenu?(params: Electron.ContextMenuParams): void;
22
+ onOpenWindow?: OpenWindowPolicy;
23
+ onDownload?(progress: DownloadProgress): void;
24
+ }
25
+ export interface WebViewHandle {
26
+ readonly webContents: Electron.WebContents;
27
+ readonly state: WebViewState;
28
+ onChange(listener: (state: WebViewState) => void): () => void;
29
+ loadURL(url: string): void;
30
+ focus(): void;
31
+ blur(): void;
32
+ back(): void;
33
+ forward(): void;
34
+ reload(): void;
35
+ zoom(direction: ZoomDirection): number;
36
+ find(text: string): void;
37
+ findNext(forward: boolean): void;
38
+ stopFind(): void;
39
+ cdp(method: string, params?: Record<string, unknown>): Promise<Record<string, unknown>>;
40
+ openDevtools(): void;
41
+ closeDevtools(): void;
42
+ closePopup(): void;
43
+ readonly recording: WebViewRecording;
44
+ }
45
+ export interface WebViewRecording {
46
+ start(dir: string): SurfaceCapture;
47
+ onFrame(listener: () => void): () => void;
48
+ frameSize(): {
49
+ width: number;
50
+ height: number;
51
+ } | null;
52
+ pinFrameRate(pinned: boolean): void;
53
+ invalidate(): void;
54
+ }
55
+ export declare const WebView: import("react").ForwardRefExoticComponent<WebViewProps & import("react").RefAttributes<WebViewHandle>>;