buninu-browser 0.2.1 → 0.2.3

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 (90) hide show
  1. package/AGENTS.md +4 -0
  2. package/README.md +74 -9
  3. package/ai-debug.log +5537 -0
  4. package/bunfig.toml +1 -0
  5. package/buninu-browser.js +4 -0
  6. package/index.js +5 -0
  7. package/lib/audio/piano.js +24 -1
  8. package/lib/audio/playback-buffer.js +27 -0
  9. package/lib/audio/pulse-client.js +137 -19
  10. package/lib/cdp-server.js +22 -11
  11. package/lib/happy-dom/parser.js +29 -4
  12. package/lib/happy-dom/selector-pseudo-adapter.js +14 -0
  13. package/lib/headless-shell.js +69 -19
  14. package/lib/input/hit-test.js +25 -7
  15. package/lib/layout/text-layout.js +268 -85
  16. package/lib/log.js +5 -2
  17. package/lib/media/byte-pipe.js +82 -0
  18. package/lib/media/position-audio.js +42 -0
  19. package/lib/media/video-keyframe.js +29 -0
  20. package/lib/network/network-service.js +161 -14
  21. package/lib/paint/display-list.js +316 -15
  22. package/lib/paint/gradient.js +11 -5
  23. package/lib/render-tree/index.js +19 -2
  24. package/lib/render-tree/svg.js +2 -1
  25. package/lib/renderer/bindings.js +995 -69
  26. package/lib/renderer/canvas-2d.js +92 -0
  27. package/lib/renderer/compositor.js +16 -1
  28. package/lib/renderer/custom-element-reactions.js +18 -0
  29. package/lib/renderer/history.js +42 -0
  30. package/lib/renderer/host.js +166 -9
  31. package/lib/renderer/image-loading.js +27 -0
  32. package/lib/renderer/interfaces.js +215 -0
  33. package/lib/renderer/keyboard-input.js +12 -0
  34. package/lib/renderer/main.js +162 -12
  35. package/lib/renderer/media-playback-events.js +13 -0
  36. package/lib/renderer/media-source.js +819 -0
  37. package/lib/renderer/messaging.js +411 -0
  38. package/lib/renderer/native-functions.js +113 -0
  39. package/lib/renderer/page-realm.js +1408 -242
  40. package/lib/renderer/page-renderer.js +1893 -223
  41. package/lib/renderer/piano-input.js +22 -0
  42. package/lib/renderer/pointer-move.js +29 -0
  43. package/lib/renderer/rejections.js +31 -0
  44. package/lib/renderer/rewrite-worker.js +22 -0
  45. package/lib/renderer/script-rewrite.js +805 -57
  46. package/lib/renderer/trusted-types.js +129 -0
  47. package/lib/renderer/video-presentation.js +126 -0
  48. package/lib/renderer/workers.js +327 -0
  49. package/lib/screenshot-cli.js +2 -0
  50. package/lib/style/computed-style.js +186 -29
  51. package/lib/user-agent.js +14 -2
  52. package/package.json +4 -1
  53. package/patches/happy-dom/0002-use-bun-platform-adapters.patch +139 -19
  54. package/patches/happy-dom/0006-parse-css-escapes-in-selectors.patch +115 -0
  55. package/patches/happy-dom/README.md +26 -0
  56. package/patches/ses/0002-embedder-native-functions-source-text-sloppy-code.patch +106 -0
  57. package/patches/ses/0003-cache-sloppy-evaluators.patch +47 -0
  58. package/patches/ses/README.md +4 -0
  59. package/test/canvas-2d.test.js +55 -0
  60. package/test/compositor.test.js +41 -1
  61. package/test/computed-style.test.js +59 -1
  62. package/test/display-list.test.js +88 -1
  63. package/test/download.test.js +43 -0
  64. package/test/fixtures/long-video.mp4 +0 -0
  65. package/test/fixtures/media-sync.js +57 -0
  66. package/test/happy-dom-platform-adapters.test.js +25 -0
  67. package/test/headless-shell.test.js +23 -1
  68. package/test/hit-test.test.js +25 -1
  69. package/test/media-playback-events.test.js +22 -0
  70. package/test/media-source.test.js +156 -0
  71. package/test/media-sync.test.js +12 -0
  72. package/test/mobile.test.js +2 -2
  73. package/test/navigation.test.js +61 -0
  74. package/test/network-service.test.js +14 -0
  75. package/test/page-scripts.test.js +1203 -7
  76. package/test/piano-input.test.js +44 -0
  77. package/test/playback-buffer.test.js +31 -0
  78. package/test/position-audio.test.js +67 -0
  79. package/test/positioning.test.js +95 -1
  80. package/test/pulse-client.test.js +84 -0
  81. package/test/renderer-host.test.js +5 -2
  82. package/test/screenshot-cli.test.js +25 -1
  83. package/test/script-rewrite.test.js +111 -6
  84. package/test/setup.js +5 -0
  85. package/test/text-layout.test.js +62 -0
  86. package/test/user-agent.test.js +60 -4
  87. package/test/video-presentation.test.js +67 -0
  88. package/vendor/happy-dom/packages/happy-dom/src/nodes/html-image-element/HTMLImageElement.ts +52 -22
  89. package/vendor/happy-dom/packages/happy-dom/src/query-selector/SelectorParser.ts +18 -17
  90. package/vendor/ses/dist/ses.mjs +52 -6
package/AGENTS.md CHANGED
@@ -5,7 +5,11 @@
5
5
  - Native bindings are generally not allowed in the headless shell itself
6
6
  * In the future when it is wrapped into a full browser on each platform, the frontend should stay as thin wrappers just enough to draw rendered content from the headlesss shell
7
7
  * Specifically, able to work with ../casty through CDP is an important goal
8
+ - Working with casty requires setting the env CASTY_BROWSER to the absolute path of buninu-browser.js
9
+ * Then start casty by `bun ../casty/index.js [URL]`. If no URL is specified it starts casty's homepage.
10
+ - Enable logs by BUNINU_LOG
8
11
  - Only use Bun FFI to dlopen libc when other methods are clearly not enough
12
+ - Read README.md and `bun index.js --help` for a general understanding
9
13
 
10
14
  ## Implementing the browser
11
15
  - Do not treat any website specially when refining browser features like layout css js. Fix the actual problem that all websites can benefit from.
package/README.md CHANGED
@@ -24,6 +24,12 @@ npx buninu-browser
24
24
  # Open a URL
25
25
  npx buninu-browser buninu.org
26
26
 
27
+ # WebKit/Safari compatibility identity is the default
28
+ npx buninu-browser https://youtu.be/jf-pn0a-Twk
29
+
30
+ # Switch back to the Chromium compatibility identity
31
+ npx buninu-browser buninu.org -- --chromium
32
+
27
33
  # Arguments after -- go to the
28
34
  # browser engine; --mobile presents
29
35
  # it as a phone (mobile user agent,
@@ -60,6 +66,17 @@ this package's `buninu-browser.js`
60
66
  and starts casty with `npx` when npx
61
67
  and Bun are both installed, otherwise
62
68
  with `bunx`, or `bun x`.
69
+ No adjacent casty checkout is needed. From a local Buninu Browser checkout,
70
+ `bun index.js [URL] [-- BROWSER_FLAGS...]` uses the same package-based launcher.
71
+
72
+ The engine defaults to a WebKit/Safari compatibility identity in casty,
73
+ headless, and screenshot modes. `--webkit` explicitly selects this default;
74
+ `--chromium` selects the previous desktop Chromium identity. Pass these flags
75
+ after `--` through casty, or directly after `--headless`. If both desktop flags
76
+ are supplied, the last one wins. `--mobile` takes priority over either desktop
77
+ identity and retains the Android phone profile. These flags select browser
78
+ identities, not native WebKit or Chromium engines. API callers can use
79
+ `createBrowser({ webkit: false })` to select the Chromium identity.
63
80
 
64
81
  The first argument picks a frontend;
65
82
  the rest is passed on:
@@ -147,11 +164,11 @@ Compatibility with casty is therefore part of the initial vertical slice
147
164
  rather than a later layer: CDP discovery, target lifecycle, navigation,
148
165
  screenshots and screencast, viewport, and input. Early development and every
149
166
  screen test so far have been done in casty itself. casty launches the
150
- browser named by `CASTY_BROWSER` before looking for Chromium, so a checkout
151
- of this repository runs next to a casty checkout with:
167
+ browser named by `CASTY_BROWSER` before looking for Chromium. The package
168
+ launcher sets this automatically and obtains casty through the package runner:
152
169
 
153
170
  ```sh
154
- CASTY_BROWSER="$PWD/buninu-browser.js" bun ../casty/bin/casty.js buninu.org
171
+ npx buninu-browser buninu.org
155
172
  ```
156
173
 
157
174
  ## Design
@@ -247,7 +264,7 @@ pushes a screencast frame.
247
264
  ### Mobile presentation
248
265
 
249
266
  Pages see a desktop browser unless `--mobile` is given. With it, requests
250
- and `navigator.userAgent` use an Android 16 WebView user agent, and the
267
+ and `navigator.userAgent` use an Android 16 Chrome user agent, and the
251
268
  `hover`/`pointer` media features report a touch screen (`hover: none`,
252
269
  `pointer: coarse`). User agent overrides sent over CDP are ignored so the
253
270
  flag stays in effect under clients that set a desktop user agent, such as
@@ -257,11 +274,29 @@ asked for; input coordinates are scaled back, and pages see the factor as
257
274
  `visualViewport.scale`.
258
275
 
259
276
  ```sh
260
- CASTY_BROWSER="$PWD/buninu-browser.js" bun ../casty/bin/casty.js github.com -- --mobile
277
+ npx buninu-browser github.com -- --mobile
261
278
  ```
262
279
 
263
280
  ### Video and audio
264
281
 
282
+ The default desktop WebKit/Safari compatibility identity (also selectable with
283
+ `--webkit`) matches Bun's JavaScriptCore more closely than the optional
284
+ `--chromium` identity. It presents macOS Safari even on other operating systems, sets the
285
+ matching navigator vendor/platform, and omits Chromium User-Agent Client Hints.
286
+ This can help pages that compare their declared browser with JavaScript engine
287
+ behavior. The flag applies to every site and keeps the page sandbox enabled.
288
+
289
+ ```sh
290
+ npx buninu-browser https://youtu.be/jf-pn0a-Twk -- --webkit
291
+ ```
292
+
293
+ The casty package version must support non-Chromium CDP backends without
294
+ replacing their advertised identity or applying Chrome-specific page patches.
295
+ The default and explicit
296
+ `--webkit` profiles ignore CDP user-agent overrides. The same flag works with
297
+ `--headless` and screenshot mode. This is a compatibility workaround, not a
298
+ guarantee that a service will accept every session.
299
+
265
300
  `<video>` and `<audio>` share one pipeline; an `<audio controls>` is a
266
301
  300x32 control bar with no picture. Clicking plays or pauses, clicking the
267
302
  progress track seeks, and page script has `play()`, `pause()`,
@@ -271,9 +306,39 @@ MPEG-4, Theora, MPEG-1/2; MP3, AAC, FLAC, Vorbis, Opus, WAV).
271
306
 
272
307
  Sound, a video's included, plays through a PulseAudio native-protocol server
273
308
  on `127.0.0.1:4713`, such as [jspulse](https://github.com/jjtseng93/jspulse)
274
- (`npx @drxiaozhi/jspulse`); without one, video plays silently. The controller
275
- holds the connection, since renderers cannot open sockets, and paces the
276
- stream to real time, so pausing stops the sound within half a second.
309
+ or PulseAudio itself; without one, video plays silently. Start jspulse with
310
+ the backend appropriate for your platform:
311
+
312
+ ```sh
313
+ npx @drxiaozhi/jspulse --sles # Android OpenSL ES
314
+ npx @drxiaozhi/jspulse --alsa # Linux ALSA
315
+ npx @drxiaozhi/jspulse --win32 # Windows waveform audio
316
+ ```
317
+
318
+ Keep the server on its default port, `4713`, when using Buninu Browser.
319
+ Although jspulse supports `-p` / `--port`, the browser currently connects to
320
+ `127.0.0.1:4713` and does not read `PULSE_SERVER`.
321
+
322
+ The controller
323
+ holds the connection, since renderers cannot open sockets. For media playback
324
+ it polls the server's playback cursor and measured sink latency; video follows
325
+ the reported audio progress, not the amount of PCM submitted or elapsed wall
326
+ time. Missing timing feedback holds the clock and is logged, rather than being
327
+ replaced by a fixed A/V delay. Audio queued ahead is bounded, including across
328
+ network stalls and decoder reopens.
329
+
330
+ Synchronization requires the standard PulseAudio timing query and an output
331
+ backend that reports its measured queue latency. jspulse provides a common
332
+ timing interface across ALSA, Windows, and OpenSL ES: ALSA uses hardware delay
333
+ and software queue measurements; Windows and OpenSL ES track buffer completion.
334
+ The shared Windows/ALSA mixer accounts for each stream separately.
335
+ Use a jspulse version that includes this timing support; older OpenSL ES
336
+ backends lack it. A server reporting zero latency while retaining an
337
+ unreported device queue cannot provide accurate synchronization.
338
+ Buffer-completion timing has buffer-sized resolution and does not measure
339
+ additional unreported downstream latency, such as Bluetooth output latency.
340
+ With `BUNINU_LOG`, `media sync` records reported audio progress, the latest
341
+ rendered video position, and the output queue/latency for diagnosis.
277
342
 
278
343
  ### Diagnostics
279
344
 
@@ -289,7 +354,7 @@ Renderers cannot open files under seccomp, so the controller collects their
289
354
  output and writes the log.
290
355
 
291
356
  ```sh
292
- BUNINU_LOG=1 CASTY_BROWSER="$PWD/buninu-browser.js" bun ../casty/bin/casty.js github.com
357
+ BUNINU_LOG=1 npx buninu-browser github.com
293
358
  ```
294
359
 
295
360
  ## Open-source components