perf(snapshot): avoid costly generation of <a> element on each call to `getHref`, instead cache an anchor element and reuse it's href attributed
---------
Co-authored-by: Eoghan Murray <eoghan@getthere.ie>
* better splitting of selectors - overlapping with #1401
* Add test from example at https://github.com/PostHog/posthog/pull/21427
* ignore brackets inside selector strings
* Add another test as noticed that it's possible to escape strings
* Ensure we are ignoring commas within strings
Co-authored-by: Eoghan Murray <eoghan@getthere.ie>
* Add support for capturing media attributes in rrweb-snapshot
* Add loop to mediaInteractionParam
* Add support for loop in RRMediaElement
* Add support for recording loop attribute on media elements
* Update video playback and fix bugs
* Update cross-origin iframe media attributes and player state
* We weren't recursing into media queries (or @supports etc.) to rewrite hover pseudoclasses
* The early return meant that the stylesWithHoverClass cache wasn't being populated if there were no hover selectors on the stylesheet
- not committing the test, but modifying the existing 'add a hover class to a previously processed css string' as follows shows the problem:
--- a/packages/rrweb-snapshot/test/rebuild.test.ts
+++ b/packages/rrweb-snapshot/test/rebuild.test.ts
@@ -151,6 +185,7 @@ describe('rebuild', function () {
path.resolve(__dirname, './css/benchmark.css'),
'utf8',
);
+ cssText = cssText.replace(/:hover/g, '');
const start = process.hrtime();
addHoverClass(cssText, cache);
* Replace `min-device-width` and similar with `min-width` as the former looks out at the browser viewport whereas we need it to look at the replayer iframe viewport
* Add some tests to show how the hover replacement works against selector lists. I believe these were failing in a previous version of rrweb as I had some local patches that no longer seem to be needed to handle these cases
* Update name of function to reflect that 'addHoverClass' does more than just :hover. I believe this function is only exported for the purposes of use in the tests
* Apply formatting changes
* Create rotten-spies-enjoy.md
* Apply formatting changes
* Add correct typing on `getSelectors`
* Refactor CSS interfaces to include optional rules
* Change `rules` to be non optional
---------
Co-authored-by: eoghanmurray <eoghanmurray@users.noreply.github.com>
Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
* Fix serialization and mutation of <textarea> elements taking account the duality that the value can be set in either the child node, or in the value _parameter_ (not attribute)
* Backwards compatibility: Bug fix and regression test for #112
- this is to fix up 'historical' recordings, as duplicate textarea content should no longer be being created at record time
- new test shows what the snapshot generated by previous versions of rrweb used to look like, hence 'bad'
- original 0efe23f04a fix either didn't work or no longer works due to childNodes being appended subsequent to this part of the code
- during review, we also verified that the `_cssText` case should still be handled okay, as there's currently no scenario where csstext is present with css child nodes of a <style>
* Masking: Fix that textarea values were being missed by the masking system if the value was recorded as a child node
- I didn't notice that form.html was used in other tests, so lucky that I noticed that those tests also should have the 'pre value' masked out
* Simplify by always storing the textarea value in the `.value` attribute (from it's DOM property) and not as a childNode. It should still be rebuilt as a childNode rather than a property
---------
Authored-by: eoghanmurray <eoghan@getthere.ie>
* masking performance: avoid the repeated calls to `closest` when recursing through the DOM
- needsMask===true means that an ancestor has tested positively for masking, and so this node and all descendents should be masked
- needsMask===false means that no ancestors have tested positively for masking, we should check each node encountered
- needsMask===undefined means that we don't know whether ancestors are masked or not (e.g. after a mutation) and should look up the tree
* Add tests including an explicit characterData mutation tests
* Further performance improvement: avoid calls to `el.matches` when on a leaf node, e.g. a `<br/>`
---------
Authored-by: eoghanmurray <eoghan@getthere.ie>
Based on initial PR #1338 by Alexey Babik <alexey.babik@noibu.com>
* Perf: don't run the regex replace unless the selectorText contains a colon (rules generally contain colons)
* Need to check type before querying selectorText property - also good as it means we only try to fix colons at the leaf level
---------
Authored-by: eoghan murray <eoghan@getthere.ie>
* Extend to run fixBrowserCompatibilityIssuesInCSS over styles in inline style sheets
* Apply formatting changes
---------
Co-authored-by: eoghanmurray <eoghanmurray@users.noreply.github.com>
* fix: change default value of input type from null to text
* Apply formatting changes
* add changeset
* add a comment related to the type of input element
* fix: Fix input.type check
Actually I noticed that `el.type` returns `text` when type is not explicitly set, so this is slightly incorrect.
* fix linting
* Apply formatting changes
* feat: Ensure password inputs are masked when switching type
Apply formatting changes
use data- attribute
ref: Ensure type is always lowercased
add changeset
* extract into util
* Apply formatting changes
* feat: Ignore `autoplay` attribute on video/auto elements
This element leads to weird issues when replaying, so it's better to strip this out.
* add changeset
* fix check
fix typo
* Apply formatting changes
---------
Co-authored-by: mydea <mydea@users.noreply.github.com>
* fix: Explicitly handle removed attributes
The attribute `value` can be null when a mutation observer triggers due to a removed attribute. This is currently not reflected by types and code.
* Apply formatting changes
* fix
* add changeset
* Firefox fix: Allow the <head> and <body> to be added in two stages so that (presumably) stylesheet rules are ready to be applied when the body appears
The css which triggered the bug was simply
{
margin-left: 220px;
transition: margin-left .448s;
}
* Add a test case which can only be appreciated if you record against this file://, save the events to a html file, and then open the file in Firefox (without this PR applied)
* Apply formatting changes
* Ensure we don't apply this branch when using rrdom, where it is not necessary
* Apply formatting changes
* Rewrite insertion in order to be compatible with rrdom
Also easier to understand
* Delete transition.html
* Create grumpy-ways-own.md
---------
Co-authored-by: Yun Feng <yun.feng0817@gmail.com>
* fix: Exclude `modulepreload` as well
We were only excluding `<link rel="preload" as="script" />` but we should include `rel="modulepreload"` as well
* Apply formatting changes
* fix: duplicated elements in shadow doms
clean observers before taking new full snapshots
* add checker for replayer to make it stable when data has duplicated nodes
* apply review suggestions
* add change log
* Apply formatting changes
* update prettier to fit the master branch
---------
Co-authored-by: Mark-Fenng <Mark-Fenng@users.noreply.github.com>
* Add `recordCrossOriginIframe` setting
* Set up messaging between iframes
* should emit full snapshot event from iframe as mutation event
* this.mirror was dropped on attachIframe
* should use unique id for child of iframe
* Cross origin iframe recording in `yarn live-stream`
* Root iframe check thats supported by firefox
* Live stream: Inject script in all frames
* Record same origin and cross origin iframes differently
* Should map Input events correctly
* Turn on other tests
* Fix compatibility with newer puppeteer
* puppeteer vs 12 seems stable without to many changes needed
* normalize port numbers in snapshots
* Handle scroll and ViewportResize events in cross origin iframe
* Correctly map cross origin mutations
* Map selection events for cross origin iframes
* Map canvas mutations for cross origin iframes
* Update snapshot to include canvas events
* Skip all meta events
* Support custom events as best we can in cross origin iframes
* Use earliest version of puppeteer that works with cross origin live-stream
* Map mouse/touch interaction events
* Update snapshots for correctly mapped click events
* Tweak tests for new puppeteer version
* Map MediaInteraction correctly for cross origin iframes
* Make tests consistent between high and low dpi devices
* Make test less flaky
* Make test less flaky
* Make test less flaky
* Make test less flaky
* Add support for styles in cross origin iframes
* Map traditional stylesheet mutations on cross origin iframes
* Add todo
* Add iframe mirror
* Get iframe manager to use iframe mirrors internally
* Rename `IframeMirror` to `CrossOriginIframeMirror`
* Setup basic cross origin canvas webrtc streaming
* Clean up removed canvas elements
* reset style mirror on new full snapshot
* Fix cross origin canvas webrtc streaming
* Make emit optional
* Run tests on github actions
* Upload image artifacts from failed tests
* Use newer github actions
* Test: hopefully adding more wait will fix it
* add extra wait
* Fix image snapshot tests
* Make tests run with new puppeteer version
* upgrade eslint-plugin-jest
* Chore: Remove travis ci as ci's running on github actions
* Chore: Support recording cross origin iframe in repl
* Force developers to update the cross origin iframe mapping when adding new events
https://github.com/rrweb-io/rrweb/pull/1035#discussion_r1012516277
* Document cross origin iframe recording
* Docs: cross origin iframes recording methods
* Docs: AI translated, cross origin iframe recording
* rename getParentId to getId
* Migrate to @rrweb/types
* Run on pull request
* doc: improve Chinese doc
* Rename `parentId` to `Id`
Co-authored-by: Mark-Fenng <f18846188605@gmail.com>
* fix: bug when inlined link elements
* test: update snapshot for test cases
* apply Justin's review suggestions
1. make Mirror's replace function act the same with the original one when there's no existed node to get replaced.
2. when replacing with the link/style elements, keep their existing attributes to prevent potential bugs
* test(recording side): add test case for adopted stylesheets in shadow doms and iframe
* add type definition for adopted StyleSheets
* create a StyleSheet Mirror
* enable to record the outermost document's adoptedStyleSheet
* enable to serialize all stylesheets in documents (iframe) and shadow roots
* enable to record adopted stylesheets while building full snapshot
* test: add test case for mutations on adoptedStyleSheets
* defer to record adoptedStyleSheets to avoid create events before full snapshot
* feat: enable to track the mutation of AdoptedStyleSheets
* Merge branch 'fix-shadowdom-record' into construct-style
* fix: incorrect id conditional judgement
* test: add a test case for replaying side
* tweak the style mirror for replayer
* feat: enable to replay adoptedStyleSheet events
* fix: rule index wasn't recorded when serializing the adoptedStyleSheets
* add test case for mutation of stylesheet objects and add support for replace & replaceSync
* refactor: improve the code quality
* feat: monkey patch adoptedStyleSheet API to track its modification
* feat: add support for checkouting fullsnapshot
* CI: fix failed type checks
* test: add test case for nested shadow doms and iframe elements
* feat: add support for adoptedStyleSheets in VirtualDom mode
* style: format files
* test: improve the robustness of the test case
* CI: fix an eslint error
* test: improve the robustness of the test case
* fix: adoptedStyleSheets not applied in fast-forward mode (virtual dom optimization not used)
* refactor the data structure of adoptedStyleSheet event to make it more efficient and robust
* improve the robustness in the live mode
In the live mode where events are transferred over network without strict order guarantee, some newer events are applied before some old events and adopted stylesheets may haven't been created.
Added a retry mechanism to solve this problem.
* apply Yanzhen's review suggestion
* update action name
* test: make the test case more robust for travis CI
* Update packages/rrweb/src/record/constructableStyleSheets.d.ts
Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
* Update packages/rrweb/src/record/constructableStyleSheets.d.ts
Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
* apply Justin's review suggestions
add more browser compatibility checks
* add eslint-plugin-compat and config
* fix record test type errors
* make Mirror's replace function act the same with the original one when there's no existed node to replace
* test: increase the robustness of test cases
* remove eslint disable in favor of feature detection
Early returns aren't supported yet unfortunately, otherwise this code would be cleaner https://github.com/amilajack/eslint-plugin-compat/issues/523
* Remove eslint-disable-next-line compat/compat
* Standardize browserslist and remove lint exceptions (#1010)
* test: revert deleting virtual style tests and rewrite them to fit the current code base
Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
* Sort attributes to make `rr_*` attributes handled last
`rr_dataURL` overwrites `src` attribute, because of this we need to evaluate `rr_dataURL` last so it doesn't accidentally get overwritten again.
* Update packages/rrweb-snapshot/src/rebuild.ts
* Refactor handling of rr_* attributes
Be a little more strict when it comes attribute types
* inline stylesheets when loaded
* set empty link elements to loaded by default
* Clean up stylesheet manager
* Remove attribute mutation code
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/scripts/repl.js
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/src/record/index.ts
* Add todo
* Move require out of time sensitive assert
* Add waitForRAF, its more reliable than waitForTimeout
* Remove flaky tests
* Add recording stylesheets in iframes
* Remove variability from flaky test
* Make test more robust
* Fix naming
* Add test cases for inlineImages
* Add test cases for inlineImages
* Record iframe mutations cross page
* Test: should record images inside iframe with blob url after iframe was reloaded
* Handle negative ids in rrdom correctly
When iframes get inserted they create untracked elements, both on the dom and rrdom side.
Because they are untracked they generate negative numbers when fetching the id from mirror.
This creates a problem when comparing and fetching ids across mirrors.
This commit tries to get away from using negative ids as much as possible in rrdom's comparisons
* Update packages/rrdom/src/diff.ts
Co-authored-by: Yun Feng <yun.feng@anu.edu.au>
* Start unserialized nodes at -2
This way we don't accidentally think of them as mirror misses
* Set unserialized id starting number at -2
* Remove duplication
* Use turbo instead of lerna
* Skip benchmark as it is unreliable when executed in parallel
* Strip port number from serialization, it can vary
* Add settimeout to virtual dom test
* Remove console.log and refactor blob:url serialization
* Include references in tsconfig to indicate which monorepo packages are being used
* Add stream setup
* Migrate project to es module
* Add reference to rrweb from rrdom
* Move jest config to ESM
* Setup basic WebRTC canvas streaming
* Cleanup and refactor WebRTC streaming
* Remove ? which isn't propper javascript
* Yarn lock
* Remove webrtc code from rrweb
* Add plugin hooks
Record/Replay plugins
`.getMirror` exposes the mirror to plugins
Replay plugins
`.onBuild` called whenever a node was added to the dom
* Expose plugins with server
* Use unminified version for tests
* Don't include simple-peer in rrweb main project
* Add canvas webrtc plugin
Streams contents of canvas via webrtc
* ignore tsconfig.tsbuildinfo
* Cleanup unused code
* type definition files are no longer committed
* Devtools off by default
* Extract .css into its own file
* Refactor plugin apis and fix multi canvas streaming support
* Add readme to rrweb canvas webrtc plugin
* Reference canvas-webrtc plugin in documentation
* Forbidden non-null assertion
* Remove linting of each project, yarn lint:report will do this
* Remove test code
* Cut down line length
* fix CI failure and improve the zh_CN doc
* Update packages/rrweb/src/plugins/canvas-webrtc/replay/index.ts
Co-authored-by: Yun Feng <yun.feng@anu.edu.au>
* Cleaner styling of replay
Co-authored-by: Yun Feng <yun.feng@anu.edu.au>
* Clean up stream.js based on @Mark-Fenng's feedback
* Remove duplicate send
Co-authored-by: Yun Feng <yun.feng@anu.edu.au>
Co-authored-by: Yun Feng <yun.feng0817@gmail.com>
* inline stylesheets when loaded
* set empty link elements to loaded by default
* Clean up stylesheet manager
* Remove attribute mutation code
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/scripts/repl.js
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/src/record/index.ts
* Add todo
* Move require out of time sensitive assert
* Add waitForRAF, its more reliable than waitForTimeout
* Remove flaky tests
* Add recording stylesheets in iframes
* Remove variability from flaky test
* Make test more robust
* Fix naming
* Add test cases for inlineImages
* Add test cases for inlineImages
* Record iframe mutations cross page
* Test: should record images inside iframe with blob url after iframe was reloaded
* Handle negative ids in rrdom correctly
When iframes get inserted they create untracked elements, both on the dom and rrdom side.
Because they are untracked they generate negative numbers when fetching the id from mirror.
This creates a problem when comparing and fetching ids across mirrors.
This commit tries to get away from using negative ids as much as possible in rrdom's comparisons
* Update packages/rrdom/src/diff.ts
Co-authored-by: Yun Feng <yun.feng@anu.edu.au>
* Start unserialized nodes at -2
This way we don't accidentally think of them as mirror misses
* Set unserialized id starting number at -2
* Remove duplication
Co-authored-by: Yun Feng <yun.feng@anu.edu.au>
* fix: style not applied to polyfillled shadow dom
* test: add integration test for shadydom and @lwc/synthetic-shadow
* improve the implementation of function isNativeShadowDom
* apply lele0108's review suggestion
* refactor: eliminate eslint errors as many as I can
* refactor: fix more eslint errors in the record module
* LINT: fix @typescript-eslint/unbound-method
* LINT: fix all eslint errors in source code
* LINT: fix as many eslint warnings as possible
Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
* inline stylesheets when loaded
* set empty link elements to loaded by default
* Clean up stylesheet manager
* Remove attribute mutation code
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/scripts/repl.js
* Update packages/rrweb/test/record.test.ts
* Update packages/rrweb/src/record/index.ts
* Add todo
* Move require out of time sensitive assert
* Add waitForRAF, its more reliable than waitForTimeout
* Remove flaky tests
* Add recording stylesheets in iframes
* Remove variability from flaky test
* Make test more robust
* Fix naming
* Speed up snapshotting of many new dom nodes
By avoiding reflow we shave about 15-25% off our snapshotting time
* Improve newlyAddedElement docs
* Optimize needMaskingText by using el.closest and less recursion
* Serve all rrweb dist files
* Split serializeNode into smaller functions
Makes it easier to profile
* Slow down cpu enhance tracing on fast machines
* Increase timeout
* Perf: only loop through ancestors when they have something to compare to
* Perf: `hasNode` is cheaper than `getMeta`
* Perf: If parents where already checked, no need to do it again
* Perf: reverse for loops are faster
Because they only do the .lenght check once. In this case I don't think we'll see much performance gains if any
* Clean up code
* Perf: check ancestors once with isBlocked
* guessing this might fixes canvas test
* Update packages/rrweb/src/record/observers/canvas/webgl.ts
Co-authored-by: yz-yu <yanzhen@smartx.com>
* Fix#904 (#906)
Properly remove crossorigin attribute
* Bump minimist from 1.2.5 to 1.2.6 (#902)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)
---
updated-dependencies:
- dependency-name: minimist
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: yz-yu <yanzhen@smartx.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>