Commit Graph

1110 Commits

Author SHA1 Message Date
Justin Halsall
f567393b44 Test: Stylesheet append text node (#886) 2026-04-01 12:00:00 +08:00
Justin Halsall
a5ff2fc77f Record canvas snapshots N times per second (#859)
* Only record canvas when recordCanvas is true

* All should be compiled first

Makes recompiling+debugging a lot faster

* Add support for compiling web workes

Replaces @rollup/plugin-typescript for rollup-plugin-typescript2 as the former is incompatible with rollup-plugin-web-worker-loader

* Update yarn.lock

* Upgrade to typescript 4.5.5

* add support for replay of ImageBitmap in 2d canvas

* Snapshot canvases in a web-worker on FPS basis

* Fix performance of canvas recording and playback

* Wait for all images to be preloaded before checking results

* flatten base64 strings, as encoding isn't consistent

* Cleanup

* Add serializing to 2d canvases as well

* Disable blob serialize test

We don't have any code for it yet

* Upgrade @rollup/plugin-commonjs to 21.0.2

Fixes
https://linguinecode.com/post/import-export-appear-at-the-top-level

* Move canvas recording options to `sampling`

Based on: https://github.com/rrweb-io/rrweb/pull/859#discussion_r846582146
2026-04-01 12:00:00 +08:00
Rahul Lingala
bff6a24ddf Fix mutation edge case when blocked class gets unblocked (#867)
* Fix mutation edge case when blocked class gets unblocked

* Add integration test

* Update isSerialized logic
2026-04-01 12:00:00 +08:00
Justin Halsall
d4f5d8dc48 Remove INode (node.__sn) and use Mirror as source of truth (#868)
* Move ids to weakmap

* Fix typo

* Move from INode to storing serialized data in mirror

* Update packages/rrweb-snapshot/src/rebuild.ts

Co-authored-by: Yun Feng <yun.feng@anu.edu.au>

* Remove unnessisary `as Node` typecastings

Fixes: https://github.com/rrweb-io/rrweb/pull/868#discussion_r842240758

* Remove unnessisary `as unknown as ...`

* Remove unnessisary `as unknown as ...`

* Reset mirror when recording starts

Solves: https://github.com/rrweb-io/rrweb/pull/868#discussion_r842249599

* API has changed for snapshot, change test to reflect that

* Allow for es5 compatibility

* Remove unnessisary as unknown as ... and change test to reflect the API change

* Refactor mirror to remove `nodeIdMap`

Fixes: https://github.com/rrweb-io/rrweb/pull/868#discussion_r842732696

Co-authored-by: Yun Feng <yun.feng@anu.edu.au>
2026-04-01 12:00:00 +08:00
Yanzhen Yu
65237a5ee9 update typings 2026-04-01 12:00:00 +08:00
Yanzhen Yu
d43d9e7edb chore(release): publish new version
- rrdom@0.1.2
 - rrweb@1.1.3
 - rrweb-player@0.7.14
 - rrweb-snapshot@1.1.14
2026-04-01 12:00:00 +08:00
Justin Halsall
ffc9185fa8 Don't serialize all cssRules if multiple text nodes exists (#866) 2026-04-01 12:00:00 +08:00
Justin Halsall
67554c33cc Apply textContent on flush (#865)
* Apply textContent on flush

* fix typo

* Style sheet rules applied after <style>'s textContent override should work
2026-04-01 12:00:00 +08:00
Yanzhen Yu
e0441292a2 fix #864 use for loop instead of forEach 2026-04-01 12:00:00 +08:00
Yun Feng
c67a48df70 add support for nested shadow dom (#834)
* fix: can't record shadow host and shadow dom in incremental mutations

* enable to record newly added shadow dom

* Revert "enable to record newly added shadow dom"

This reverts commit cf7c0ad551ac457f00e3f754702c1464314f6a86.

* Revert "fix: can't record shadow host and shadow dom in incremental mutations"

This reverts commit 8b25cc97f83cbc333702c0ba73684e54eeadaabe.

* fix: can't record shadow host and shadow dom in incremental mutations

* add support for nested shadow root and add integration test

* fix test error

* enable to record shadow-dom in iframes

* add an integration test case for nested iframes and shadow-doms

* use the patch function
2026-04-01 12:00:00 +08:00
Pengsha Ying
39eed78dad docs: text typo (#862) 2026-04-01 12:00:00 +08:00
Justin Halsall
e29bdfda95 Upgrade Typescript to 4.6.2, and bump up other packages (#856) 2026-04-01 12:00:00 +08:00
Yanzhen Yu
e926c82312 chore(release): publish new version
- rrdom@0.1.1
 - rrweb@1.1.2
 - rrweb-player@0.7.13
 - rrweb-snapshot@1.1.13
2026-04-01 12:00:00 +08:00
Cristi Constantin
4c06535309 Decrease embedded img size for inlineImages (#836)
* Decrease embedded img size for inlineImages

* Fix the test

* Use webp for image snapshots

* Implemented optional param dataURLOptions
2026-04-01 12:00:00 +08:00
Yun Feng
24202d2486 fix: can't record SVG element inside iframe properly (#843)
el instanceof SVGElement is false if the svg element is inside iframe so that the isSVG property is missing in the recorded data
2026-04-01 12:00:00 +08:00
Yun Feng
5cd7a0042b fix: Uncaught TypeError: Illegal invocation when recording incremental canvas mutation (#844) 2026-04-01 12:00:00 +08:00
Eoghan Murray
e125c5235d Use the .closest method to transfer recursive parent class checking into the browser engine for an expected performance improvement (#840)
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest available on all modern browsers
2026-04-01 12:00:00 +08:00
Constance Caramanolis
d0eed62b18 Update doc to use yarn to use REPL (#838) 2026-04-01 12:00:00 +08:00
Yun Feng
d4286513fd improve captured message of Error object (#835)
try to fix this problem:
https://github.com/rrweb-io/rrweb/issues/814#issuecomment-1033735775
2026-04-01 12:00:00 +08:00
Yun Feng
80ceb5ba25 console plugin fix (#832)
* fix: empty payload in console-plugin

* update unit test
2026-04-01 12:00:00 +08:00
Justin Halsall
da0a3b8fff Add Twitter badge (#829)
* Add Twitter badge

* Remove extra line break
2026-04-01 12:00:00 +08:00
Alex Dehe Ng
a8cc10e9b8 close all pages to avoid EPERM error on Windows 10 (#830) 2026-04-01 12:00:00 +08:00
Yun Feng
de320fa549 fix: an error when I stop the recording process (#828)
canvas-manager.ts:35 Uncaught TypeError: this.resetObservers is not a function
2026-04-01 12:00:00 +08:00
yz-yu
009ced8480 refactoring observer options (#826) 2026-04-01 12:00:00 +08:00
Cristi Constantin
ac6d9e2f19 Fix inline image issues (#822)
* Fix inline image issues

* Fixed img srcset

Reverted image crossOrigin change

* Tweak rebuilding img srcset
2026-04-01 12:00:00 +08:00
Justin Halsall
6bb4bed2f8 Only record canvas when specified (#825)
* Add very basic webgl support

* document the default

* only capture rr_dataURL in 2d canvas contexts

* rr_dataURL no longer part of webgl snapshot

* ignore __diff_output__ from jest-image-snapshot

* Rename generic "Monorepo" to "RRWeb Monorepo"

* Serialize WebGL variables

* Move rrweb test port number to unique port

rrweb-snapshot uses 3030, rrweb uses 3031

* Prepare for WebGL2

* Split up canvas replay and record webgl vars

* fix typo

* fix typo part 2

* fix typo

* Handle non-variables too

* provide correct context for warning

* (De)Serialize a lot of different objects

* monorepo root should be the first in the list

* Upgrade puppeteer to 11.x

* Correctly de-serialize webgl variables

* Encode arrayBuffers contents to base64

* rename contents to base64

* add webgl2 support and serialize HTMLImageElements

* Support serializing ImageData

* Correctly classify WebGL2 events

* Serialize format changed

* check if canvas has contents before we save the dataURL

* Remove blank dataURL

* reference original file not type defintion file

* update types

* rename code worspace

* update dependencies

* add spector to inspect webgl

* remove live server settings from code workspace

* Save canvas context in the node

Prevents from saving webgl canvases as 2d dataUrls

* remove extra braces

* add ICanvas type

* use ICanvas from rrweb-snapshot in rrweb instead of OgmentedCanvas

* add snapshots and webgl 2 tests

* Upgrade to puppeteer 12.0.1

* Revert back to puppeteer 9.1.1

* Keep index order consistent between replay and record

* keep correct index order in webgl2

* fixed forgotten import

* buffer up pending canvas mutations

* unify the way webgl and webgl2 get patched

* fix parsing error

* Add types for serialize-args

* Add debugging for webgl replay

* Move start-server to utils

* turn off debug mode by default

* Move pendingCanvasMutations to local object and fix if/else statement

* Always save pending mutations

* only use assert snapshot as it's clearer whats going on

* Ugly fix for now

* Making the tests more DRY

* flush at the end of each request animation frame

* Looks like the promise made this test more predictable

* add waitForRAF

* Make nested iframe recording robust no matter the test speed

* mute noisy error in test

* force a requestAnimationFrame

* Bundle events within one frame together as much as possible

WebGL events need to be bundled together as much as possible so they don't accidentally get split over multiple animation frames.

 `newFrame: true` is used to indicate the start of an new animation frame in the recording, and that the event shouldn't be bundled with the previous events.

* Rename RafStamps

* Override event.delay

* cleanup

* Add tests for addDelay

* Add webgl e2e test

* Remove settimeout

* DRY-up test

* Preload images in webgl

* Add e2e test for webgl image preloading

* don't turn on devtools by default!

* Remove spector

* close server after use

* Add imageMap parameter

* Make e2e image test more robust

* document debug mode

* cleanup

* WebGL recording in iframes & Safari 14 support

* fix tests

* don't save null objects as WebGLVar

* group (de)serialized webgl variables by context

* Fix test

* fix tests

* bundle webgl mutations on request animation frame

Instead of fixing it on the replay side we buffer up webgl canvas mutations and wait for a new RAF to flush them. This allows us to remove `newFrame` from the events and simplify things a little

* Add canvas element to mutation observer file

* Add Canvas (Mutation) Manager

Allows you to do `record.freezePage()` and canvas events will get paused.

Based on https://github.com/rrweb-io/rrweb/pull/756#issuecomment-1007566907

* cleanup

* Make sure the correct </body> gets replaced

* Perf: Speed up check to see if canvas is blank

* Access unpatched getImageData

* Use is2DCanvasBlank only for 2d context

* Only record canvas when recordCanvas is true
2026-04-01 12:00:00 +08:00
yz-yu
2b969804a9 impl sequential id plugins (#819)
Also introduce a new kind of plugin: event processor
2026-04-01 12:00:00 +08:00
Justin Halsall
7cd03662a4 Add WebGL support (#756)
* Add very basic webgl support

* document the default

* only capture rr_dataURL in 2d canvas contexts

* rr_dataURL no longer part of webgl snapshot

* ignore __diff_output__ from jest-image-snapshot

* Rename generic "Monorepo" to "RRWeb Monorepo"

* Serialize WebGL variables

* Move rrweb test port number to unique port

rrweb-snapshot uses 3030, rrweb uses 3031

* Prepare for WebGL2

* Split up canvas replay and record webgl vars

* fix typo

* fix typo part 2

* fix typo

* Handle non-variables too

* provide correct context for warning

* (De)Serialize a lot of different objects

* monorepo root should be the first in the list

* Upgrade puppeteer to 11.x

* Correctly de-serialize webgl variables

* Encode arrayBuffers contents to base64

* rename contents to base64

* add webgl2 support and serialize HTMLImageElements

* Support serializing ImageData

* Correctly classify WebGL2 events

* Serialize format changed

* check if canvas has contents before we save the dataURL

* Remove blank dataURL

* reference original file not type defintion file

* update types

* rename code worspace

* update dependencies

* add spector to inspect webgl

* remove live server settings from code workspace

* Save canvas context in the node

Prevents from saving webgl canvases as 2d dataUrls

* remove extra braces

* add ICanvas type

* use ICanvas from rrweb-snapshot in rrweb instead of OgmentedCanvas

* add snapshots and webgl 2 tests

* Upgrade to puppeteer 12.0.1

* Revert back to puppeteer 9.1.1

* Keep index order consistent between replay and record

* keep correct index order in webgl2

* fixed forgotten import

* buffer up pending canvas mutations

* unify the way webgl and webgl2 get patched

* fix parsing error

* Add types for serialize-args

* Add debugging for webgl replay

* Move start-server to utils

* turn off debug mode by default

* Move pendingCanvasMutations to local object and fix if/else statement

* Always save pending mutations

* only use assert snapshot as it's clearer whats going on

* Ugly fix for now

* Making the tests more DRY

* flush at the end of each request animation frame

* Looks like the promise made this test more predictable

* add waitForRAF

* Make nested iframe recording robust no matter the test speed

* mute noisy error in test

* force a requestAnimationFrame

* Bundle events within one frame together as much as possible

WebGL events need to be bundled together as much as possible so they don't accidentally get split over multiple animation frames.

 `newFrame: true` is used to indicate the start of an new animation frame in the recording, and that the event shouldn't be bundled with the previous events.

* Rename RafStamps

* Override event.delay

* cleanup

* Add tests for addDelay

* Add webgl e2e test

* Remove settimeout

* DRY-up test

* Preload images in webgl

* Add e2e test for webgl image preloading

* don't turn on devtools by default!

* Remove spector

* close server after use

* Add imageMap parameter

* Make e2e image test more robust

* document debug mode

* cleanup

* WebGL recording in iframes & Safari 14 support

* fix tests

* don't save null objects as WebGLVar

* group (de)serialized webgl variables by context

* Fix test

* fix tests

* bundle webgl mutations on request animation frame

Instead of fixing it on the replay side we buffer up webgl canvas mutations and wait for a new RAF to flush them. This allows us to remove `newFrame` from the events and simplify things a little

* Add canvas element to mutation observer file

* Add Canvas (Mutation) Manager

Allows you to do `record.freezePage()` and canvas events will get paused.

Based on https://github.com/rrweb-io/rrweb/pull/756#issuecomment-1007566907

* cleanup

* Make sure the correct </body> gets replaced

* Perf: Speed up check to see if canvas is blank

* Access unpatched getImageData

* Use is2DCanvasBlank only for 2d context
2026-04-01 12:00:00 +08:00
Yun Feng
b3fb1f13ba fix: custom style rules don't get inserted into some iframe elements (#823)
* fix: custom style rules don't get inserted into some iframe elements

* code style tweak
2026-04-01 12:00:00 +08:00
Yun Feng
2bca850543 disable smooth scroll behavior in sync mode (#824) 2026-04-01 12:00:00 +08:00
Cristi Constantin
36c746756e Fixes and tweaks (#795)
* Implemented image restore from rr_dataURL

* Implement saving images in the snapshot

* Fixed image saving, added a test

* Rename data-src to data-rrweb-src

* Updated the guide

* Rename recordImages to inlineImages and try catch

* A fix, some tweaks and 2 new log warnings

* Handle CORS errors when reading CSS rules

* Fix after merge

* Improve try catch for the inline image

* PR comments tweaks

* Fix typescript lint

* Small tweaks

* Fix a log warning
2026-04-01 12:00:00 +08:00
Gabriel Stellini
b71eed661f Update css-font-loading-module (#784)
Co-authored-by: Gabriel Stellini <gabriel.stellini@fusonic.net>
2026-04-01 12:00:00 +08:00
Yun Feng
b277b9a7a6 feat: add observer for 'selected' setter of HTMLOptionElement and try to fix issue #746 (#810)
* feat: add observer for 'selected' setter of HTMLOptionElement and try to fix issue #746

* style: add description of mechanism
2026-04-01 12:00:00 +08:00
Yun Feng
0153270680 improve robustness of inlineImages feature (#812)
* fix: add inlineImages option to rrrweb recorder and try to make the code more robust

* Improve robustness
2026-04-01 12:00:00 +08:00
Yanzhen Yu
269b8bb216 chore(release): publish new version
- rrweb@1.1.1
 - rrweb-player@0.7.12
2026-04-01 12:00:00 +08:00
Yanzhen Yu
a7ea00cbec fix #811 expose inlineImages to record 2026-04-01 12:00:00 +08:00
dependabot[bot]
73bfb6a59d Bump node-fetch from 2.6.1 to 2.6.7 (#809)
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-01 12:00:00 +08:00
dependabot[bot]
1b5d08d977 Bump trim-off-newlines from 1.0.1 to 1.0.3 (#808)
Bumps [trim-off-newlines](https://github.com/stevemao/trim-off-newlines) from 1.0.1 to 1.0.3.
- [Release notes](https://github.com/stevemao/trim-off-newlines/releases)
- [Commits](https://github.com/stevemao/trim-off-newlines/compare/v1.0.1...v1.0.3)

---
updated-dependencies:
- dependency-name: trim-off-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-01 12:00:00 +08:00
Yanzhen Yu
8df31a4919 chore(release): publish new version
- rrdom@0.1.0
 - rrweb@1.1.0
 - rrweb-player@0.7.11
 - rrweb-snapshot@1.1.12
2026-04-01 12:00:00 +08:00
Yanzhen Yu
49b7d02e73 make sure emit EventCast after cast fn 2026-04-01 12:00:00 +08:00
Yanzhen Yu
80479d9b9e update plugin docs 2026-04-01 12:00:00 +08:00
yz-yu
9890b8db7c impl #796 observe media volume change (#798) 2026-04-01 12:00:00 +08:00
Cristi Constantin
151debad4a Save images offline, in the snapshot (#770)
* Implemented image restore from rr_dataURL

* Implement saving images in the snapshot

* Fixed image saving, added a test

* Rename data-src to data-rrweb-src

* Updated the guide

* Rename recordImages to inlineImages and try catch
2026-04-01 12:00:00 +08:00
Lucky Feng
dd2cdedcd6 rrdom (#613)
* create rrdom package

* test(rrdom): add unit tests for polyfill.ts

* fix(rrweb snapshot): type check errors

Errors are caused by the declaration similarity of @types/mocha and @types/jest if we install both of them in the whole project.

* Set tagNames to upper case by default

This mirrors the `Element.tagName` implementation:

```
For DOM trees which represent HTML documents, the returned tag name is always in the canonical upper-case form. For example, tagName called on a <div> element returns "DIV".
```
https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName

* Add workspace file

* VSCode settings for rrdom tests

* Add basic test for RRDocument

* Only setup jest tests for rrdom

* mock Node type and Event type for nodejs environment

* test(rrdom): add snapshot for document.test.ts

* fix issue of nwsapi import and add unit tests for rrdom

* fix: querySelectorAll returns nothing when querying elements with ids and classNames

* fix: error of unit test for Event polyfill

Since Event class is built in nodejs after v15.0.0

* add a dummy implementation of canvas

* add style element support

* add unit test for style element

Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
2026-04-01 12:00:00 +08:00
Justin Halsall
044e1c1408 Add option to spoof url in repl (#786)
Really helps when experiencing CORS issues or when loading images in webgl
2026-04-01 12:00:00 +08:00
Yanzhen Yu
44eab895e4 fix lint 2026-04-01 12:00:00 +08:00
Yanzhen Yu
2981181ffd chore(release): publish new version
- rrweb@1.0.8
 - rrweb-player@0.7.10
 - rrweb-snapshot@1.1.11
2026-04-01 12:00:00 +08:00
champ
42326d986d fix #783 (#785) 2026-04-01 12:00:00 +08:00
Yanzhen Yu
e6f4556377 ignore invalid error event 2026-04-01 12:00:00 +08:00
Yanzhen Yu
d8d5d62ef2 update test snapshot 2026-04-01 12:00:00 +08:00