Commit Graph

160 Commits

Author SHA1 Message Date
Justin Halsall
39c8ba1a24 Buffer modifications to virtual stylesheets (#618)
* Fix sheet insertion

Restore skip duration

Use virtualStyleRulesMap to re-populate stylesheet on Flush event

Clear virtualStyleRulesMap after flush applied

* Support rule deletion in virtual processing

* Simply restoreNodeSheet with early aborts

* Encountered a bug where firstFullSnapshot was played twice because timer was immediately started and reached the snapshot before the setTimeout returned

* Ignoring a FullSnapshot needs to be a one-time only thing, as otherwise we'll ignore it after scrubbing (restarting play head at a particular time). This is a problem if mutations have altered the player state, and we try to replay those mutations, so we e.g. try to remove an element that has already been removed because we haven't reset the FullSnapshot state

* Some `npm run typings` related fixups

* add basic html snapshot functionality

* move restoreNodeSheet to it's own module

* Refactor virtual style rules to buffer changes.
Only applies changes on flush.

`virtualStyleRulesMap` now works with strings instead of CSSRules.
CSSRules can only be via made `.insertRule` on CSSStyleSheet in most browsers.
And `new CSSStyleSheet()` only works in Chrome currently.

* remove unused code

* move VirtualStyleRules from CSSRule to string in tests

* correct paths for tests

* naming

* create and restore style snapshots for virtual nodes

* update replayer snapshot

* move storeCSSRules to virtual-styles.ts

* try/catch access to .sheet in case of access errors

* clean up tests

Co-authored-by: Vladimir Milenko <vladimir.milenko@uber.com>
Co-authored-by: Eoghan Murray <eoghan@getthere.ie>
2021-07-08 22:34:02 +08:00
Justin Halsall
7a0e04c574 Add userTriggered (#495)
* add `userTriggered`

* update snapshots to add userTriggered

* add `userTriggered`

* update snapshots to add userTriggered

* update snapshot to include userTrigger

* only set userTriggered on `userTriggeredOnInput: true`

* What is user triggered?

* correct snapshot

* add second radio to demonstrate userTriggered
2021-07-08 22:27:21 +08:00
Eoghan Murray
f99b00eb9d Ignore firstFullSnapshot once only after initial 'poster' build (#608)
* Encountered a bug where firstFullSnapshot was played twice because timer was immediately started and reached the snapshot before the setTimeout returned

* Ignoring a FullSnapshot needs to be a one-time only thing, as otherwise we'll ignore it after scrubbing (restarting play head at a particular time). This is a problem if mutations have altered the player state, and we try to replay those mutations, so we e.g. try to remove an element that has already been removed because we haven't reset the FullSnapshot state

* Some `npm run typings` related fixups
2021-07-06 11:55:52 +08:00
Eoghan Murray
c1158d88df Fix an incorrected finish which halted playback prematurely. The scenario was that there were events being rapidly added to the recording. (#606) 2021-06-30 22:39:00 +08:00
yz-yu
5fc6c193fd plugin API (#598)
* temp: plugin API

* fix a bug in the replay handler and rename some type names.

* update integration test

* improve plugin types and handle legacy log data

* use different naming in record and replay bundles

* delete unreferenced types

Co-authored-by: Lucky Feng <294889365@qq.com>
2021-06-28 00:09:09 +08:00
Yanzhen Yu
4e025c84ce remove unsed variables 2021-06-25 22:44:20 +08:00
bachmanity1
dbaea7a521 implement video seek feature (#593)
* implement video seek feature

* rm attribute from MediaInteractions

* resolve ts warning

* use getEventTarget
2021-06-24 18:28:14 +08:00
yashkumar18
d4d437db37 Handle Drag events in replayer (#587)
* Handle Drag events in replayer

* add touch move source as well

Co-authored-by: Yash Kumar <yashkumar@Yashs-MacBook-Pro-2.local>
2021-06-17 17:21:12 +08:00
Yun Feng
ce74062869 update typings and fix lint errors 2021-06-16 11:40:10 +08:00
Justin Halsall
c59bd710d2 add ability to stop listening 2021-06-16 11:30:16 +08:00
Yakko Majuri
1dd91f0737 Update canvas recording mechanism (#536) 2021-06-10 19:47:19 +08:00
Yanzhen Yu
995d80a26f create mirror during record 2021-05-25 23:37:07 +08:00
Yanzhen Yu
51f64d8fad fix #565 add departed warning 2021-05-25 20:01:31 +08:00
Yanzhen Yu
0f86a72705 fix useless code introduced by resolving conflicts 2021-05-22 18:02:55 +08:00
Ziqiu Zhao
3b4ff0e201 feature: make mirror independent in Replayer (#407)
Co-authored-by: zhaoziqiu <zhaoziqiu@meituan.com>
Co-authored-by: yz-yu <yanzhen@smartx.com>
2021-05-22 18:01:11 +08:00
Lucky Feng
7e46341c18 fix: issue #548 (#550)
1. Do not use virtual parent optimization if the mutation targets have iframe elements as children. This will cause some performance regression but will be easy to add and ship.
2. If an iframe element has already been a child of a virtual parent, add the virtual parent back to the dom.
2021-05-02 21:56:43 +08:00
Yanzhen Yu
df455c483a fix #535 add play-back event to reset mirror and replayer 2021-04-18 21:31:29 +08:00
Yanzhen Yu
cf860278a2 call sort after unpack 2021-04-18 21:10:29 +08:00
Eoghan Murray
af0c0d95bd Sort events upon creation, and keep ordered (#411)
* Sort events at start, as otherwise we risk misidentifying the last event

* Keep inserted events in the correct order, ensuring we don't misidentify the last event

 - e.g. network conditions mean that 'live' events come in non-sequentially
 - or so that adding custom events to an existing event works

* Ensure we maintain original ordering while inserting a new event which has an identical timestamp to an existing event. This came up with a series of mutations which had the same timestamp but needed to be applied in the correct order

* Fast track the common case of a new event being added which occurs after all prior events
2021-04-18 14:21:47 +08:00
Yanzhen Yu
fbfb96297d fix first play check 2021-04-17 16:34:06 +08:00
John Pham
e8925337d9 Don't rebuildFullSnapshot if it's the first run (#532)
* Don't rebuildFullSnapshot if it's the first run

* Fix typo
2021-04-09 13:23:36 +08:00
Yanzhen Yu
df7537b01d impl shadow DOM manager
part of #38
1. observe DOM mutations in shadow DOM
2. rebuild DOM mutations in shadow DOM
2021-03-28 18:16:54 +08:00
Lucky Feng
e3f9a4d205 fix: inaccurate mouse position (#522)
1. Position of mouse was inaccurate when replaying and this PR will fix it.
2. Fix the bug that if one nested iframe has a scale transform and the position of mouse was inaccurate as well.
2021-03-25 10:29:49 +08:00
Lucky Feng
2260806ff3 fix: errors of replaying iframe records (#520)
* fix: errors of replaying iframe records

error1:
HierarchyRequestError: Failed to execute 'appendChild' on 'Node': Nodes of type '#document' may not be inserted inside nodes of type '#document-fragment'.
code: parent.appendChild(target)

error2:
Uncaught DOMException: Failed to execute 'appendChild' on 'Node': Only one element on document allowed.
code: parent.appendChild(target);

* improve the comment for bugfix
2021-03-19 11:48:12 +08:00
Yanzhen Yu
f3e118ef39 add an experiment config to set max speed in fast forward 2021-03-08 14:11:56 +08:00
Yanzhen Yu
34651c40fe fix lint errors 2021-02-27 18:21:54 +08:00
yz-yu
f3d7fa3451 Impl record iframe (#481)
* Impl record iframe

* iframe observe

* temp: add bundle file to git

* update bundle

* update with pick

* update bundle

* fix fragment map remove

* feat: add an option to determine whether to pause CSS animation when playback is paused (#428)

set pauseAnimation to true by default

* fix: elements would lose some states like scroll position because of "virtual parent" optimization (#427)

* fix: elements would lose some state like scroll position because of "virtual parent" optimization

* refactor: the bugfix code

bug: elements would lose some state like scroll position because of "virtual parent" optimization

* fix: an error occured at applyMutation(remove nodes part)

error message:
Uncaught (in promise) DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node

* pick fixes

* revert ignore file

* re-impl iframe record

* re-impl iframe replay

* code housekeeping

* move multi layer dimension calculation to replay side

* update test cases

* teardown test server

* upgrade rrweb-snapshot with iframe load timeout

Co-authored-by: Lucky Feng <yun.feng@smartx.com>
2021-02-10 21:44:25 +08:00
Yanzhen Yu
c712fc77a6 let mouse tail duration respect timer speed 2021-01-12 13:36:03 +08:00
Jarosław Salwa
c4d01e31da Scroll replayer iframe on firstFullsnapshot (#451) 2020-12-30 22:31:29 +08:00
Lucky Feng
f0f32a097a fix: sometimes currentTime is smaller than the totalTime when player is finished (#445)
plus: fix the problem that sometimes return value of getCurrentTime() is negative
2020-12-18 15:32:11 +08:00
Krzysztof Grziwok
714a4fbb73 Catch Security Errors in styleSheet rules (#437) 2020-12-10 22:02:42 +08:00
Lucky Feng
4e7146e72b feat: enable rrweb to record and replay log messages in console (#424)
* wip: working on rrweb logger

* wip: can record and replay some simple log

* wip: can record and replay log's stack

* wip: try to serialize object

* wip: record and replay console logger

hijack all of the console functions.
add listener to thrown errors

* wip: record and replay console logger
add limit to the max number of log records

* feat: enable rrweb to record and replay log messages in console

this is the implementation of new feature request(issue #234)

here are a few points of description.
1. users need to set recordLog option in rrweb.record's parameter to record log messages.  The log recorder is off by default.
2. support recording and replaying all kinds of console functions. But the reliability of them should be tested more
3. the stringify function in  stringify.ts needs improvement. e.g. robustness, handler for cyclical structures and better support for more kinds of object
4. we can replay the log messages in a simulated html console like LogRocket by implementing the interface "ReplayLogger" in the future

* improve: the stringify function

1. handle cyclical structures
2. add stringify option to limit the length of result
3. handle function type

* refactor: simplify the type definition of ReplayLogger
2020-11-29 18:12:03 +08:00
Yanzhen Yu
7d817be155 upgrade to rrweb-snapshot v1.0 2020-11-29 13:54:37 +08:00
Lucky Feng
f9d8fb7844 style: delete a useless constant 2020-11-27 17:52:56 +08:00
Lucky Feng
96e4bfdddd fix: elements would lose some states like scroll position because of "virtual parent" optimization (#427)
* fix: elements would lose some state like scroll position because of "virtual parent" optimization

* refactor: the bugfix code

bug: elements would lose some state like scroll position because of "virtual parent" optimization

* fix: an error occured at applyMutation(remove nodes part)

error message:
Uncaught (in promise) DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node
2020-11-27 17:46:52 +08:00
Lucky Feng
658999c6e0 feat: add an option to determine whether to pause CSS animation when playback is paused (#428)
set pauseAnimation to true by default
2020-11-27 16:16:18 +08:00
Lucky Feng
8f3086c18c fix: applyScroll function doesn't work in sync mode(play at a specific time) (#426)
applyScroll function should be called after all of new nodes mounted on dom
2020-11-26 13:40:57 +08:00
Eoghan Murray
facd6cc121 Ensure animations don't continue playing when we've paused playback (#417) 2020-11-25 23:20:04 +08:00
Eoghan Murray
5c9919e481 Allow .on to be chained directly after the constructor so that event handling for the first full snapshot can be added straight after constructor. See #216 (#416) 2020-11-15 16:37:39 +08:00
踩坑小王子
db5b1fe8ac feat: enable to change the config of mouse tail while playing (#410)
fix a potential bug: handleResize function might change the display style of mouseTail
2020-11-10 10:56:21 +08:00
Yanzhen Yu
6cef61882e optimize the append queue algorithm
Loop the append queue has been proved to be very inefficient, and
some times lead to N^2 time complexity.

Especially when some abnormal data could not be appended into the
real DOM, will make a dead loop.

Previously we use a 5000ms time out to handle this, which is not
user-friendly and not explicitly.

In this patch, we transform the queue into a tree data structure,
which reflects the layout of real DOM. With the tree data structure,
we can find whether there are dangling nodes that need to be dropped.
Also, the iteration will be much more efficient.

There is still a 500ms time out to avoid a dead loop, but should not
be called in expected scenarios.
2020-10-24 15:35:02 +08:00
Justin Halsall
07ff4db2a6 Add support for StylesheetRule in document fragment (#293)
* add failing test

* add stylesheet to dom to manipulate the rules

* cleanup
2020-10-17 16:37:32 +08:00
Yanzhen Yu
c5e8d0bee9 fix queue and use a unsafe but performant checker 2020-09-23 19:15:10 +08:00
Yanzhen Yu
8065415de6 Release 0.9.6 2020-09-21 14:01:56 +08:00
jackycoder
f8e88ced7b compatibility fixes (#358)
* fix polyfill NodeList forEach

* contentDocument.contains for IE

* polyfill DOMTokenList forEach
2020-09-20 18:55:29 +08:00
jackycoder
ef84f844ae fix polyfill NodeList forEach (#357) 2020-09-20 15:25:50 +08:00
Yanzhen Yu
64efb8c242 close #356 improve loop checker 2020-09-20 15:06:30 +08:00
Yanzhen Yu
8d8e70400b make sure rrweb do not use browser API in static stage 2020-09-20 14:15:19 +08:00
Yanzhen Yu
9049f2aef1 close #350 catch error may caused by checkout feature 2020-09-20 12:47:43 +08:00
Yanzhen Yu
2440701926 impl #309 observe font face set changes 2020-09-17 02:11:34 +08:00