1
+ /* eslint-disable func-names */
1
2
/* eslint-disable no-use-before-define */
2
3
/* eslint-disable no-param-reassign */
3
4
// links component state tree to library
@@ -9,14 +10,19 @@ module.exports = (snap, mode) => {
9
10
10
11
function sendSnapshot ( ) {
11
12
// don't send messages while jumping or while paused
13
+ // DEV: So that when we are jumping to an old snapshot it wouldn't think we want to create new snapshots
12
14
if ( mode . jumping || mode . paused ) return ;
13
15
const payload = snap . tree . getCopy ( ) ;
16
+ // console.log('payload', payload);
14
17
window . postMessage ( {
15
18
action : 'recordSnap' ,
16
19
payload,
17
20
} ) ;
18
21
}
19
22
23
+ // DEV: This is how we know when a change has happened
24
+ // (by injecting an event listener to every component's setState functionality).
25
+ // Will need to create a separate one for useState components
20
26
function changeSetState ( component ) {
21
27
// check that setState hasn't been changed yet
22
28
if ( component . setState . linkFiberChanged ) return ;
@@ -40,11 +46,32 @@ module.exports = (snap, mode) => {
40
46
component . setState . linkFiberChanged = true ;
41
47
}
42
48
49
+ // Helper function to
50
+
51
+ // Helper function to traverse through the memoized state
52
+ function traverseHooks ( memoizedState ) {
53
+ // Declare variables and assigned to 0th index and an empty object, respectively
54
+ let index = 0 ;
55
+ const memoizedObj = { } ;
56
+ // while memoizedState is truthy, save the value to the object
57
+ while ( memoizedState ) {
58
+ // Increment the index by 1
59
+ memoizedObj [ `state${ index += 1 } ` ] = memoizedState . memoizedState ;
60
+ // Reassign memoizedState to its next value
61
+ memoizedState = memoizedState . next ;
62
+ }
63
+ return memoizedObj ;
64
+ }
65
+
43
66
function createTree ( currentFiber , tree = new Tree ( 'root' ) ) {
44
67
if ( ! currentFiber ) return tree ;
45
- // We have to figure out which properties to destructure from currentFiber
46
- // To support hooks and Context API
47
- const { sibling, stateNode, child } = currentFiber ;
68
+
69
+ const {
70
+ sibling,
71
+ stateNode,
72
+ child,
73
+ memoizedState,
74
+ } = currentFiber ;
48
75
49
76
let nextTree = tree ;
50
77
// check if stateful component
@@ -54,8 +81,16 @@ module.exports = (snap, mode) => {
54
81
// change setState functionality
55
82
changeSetState ( stateNode ) ;
56
83
}
57
- // Need to check if functional component AND uses hooks
58
-
84
+ // Check if the component uses hooks
85
+ // TODO: Refactor the conditionals - think about the edge case where a stateful
86
+ // component might have a key called 'baseState' in the state
87
+ if ( memoizedState && memoizedState . hasOwnProperty ( 'baseState' ) ) {
88
+ // console.log('The memoizedState is: ', memoizedState)
89
+
90
+ const traversed = traverseHooks ( memoizedState ) ;
91
+ nextTree = tree . appendChild ( traversed ) ;
92
+ }
93
+
59
94
// iterate through siblings
60
95
createTree ( sibling , tree ) ;
61
96
// iterate through children
@@ -68,19 +103,67 @@ module.exports = (snap, mode) => {
68
103
const { current } = fiberRoot ;
69
104
snap . tree = createTree ( current ) ;
70
105
}
106
+ // return container => {
107
+ // console.log('this is the container', container)
108
+ // const {
109
+ // _reactRootContainer: { _internalRoot },
110
+ // _reactRootContainer,
111
+ // } = container;
112
+ // // only assign internal root if it actually exists
113
+ // fiberRoot = _internalRoot || _reactRootContainer;
114
+ // console.log('fiberRoot', fiberRoot);
115
+ // updateSnapShotTree();
71
116
72
- return container => {
73
- const {
74
- _reactRootContainer : { _internalRoot } ,
75
- _reactRootContainer,
76
- } = container ;
77
- // only assign internal root if it actually exists
78
- fiberRoot = _internalRoot || _reactRootContainer ;
79
- updateSnapShotTree ( ) ;
117
+ // // send the initial snapshot once the content script has started up
118
+ // window.addEventListener('message', ({ data: { action } }) => {
119
+ // if (action === 'contentScriptStarted') sendSnapshot();
120
+ // });
121
+ // };
80
122
81
- // send the initial snapshot once the content script has started up
82
- window . addEventListener ( 'message' , ( { data : { action } } ) => {
83
- if ( action === 'contentScriptStarted' ) sendSnapshot ( ) ;
84
- } ) ;
123
+ return {
124
+ _ ( container ) {
125
+ const {
126
+ _reactRootContainer : { _internalRoot } ,
127
+ _reactRootContainer,
128
+ } = container ;
129
+ // only assign internal root if it actually exists
130
+ fiberRoot = _internalRoot || _reactRootContainer ;
131
+ updateSnapShotTree ( ) ;
132
+ // send the initial snapshot once the content script has started up
133
+ window . addEventListener ( 'message' , ( { data : { action } } ) => {
134
+ if ( action === 'contentScriptStarted' ) sendSnapshot ( ) ;
135
+ } ) ;
136
+ } ,
137
+ testUseState ( useState ) {
138
+ return function ( initial ) {
139
+ // running the original useState and storing its result (state and dispatch function)
140
+ const toReturn = useState ( initial ) ;
141
+ // storing the original dispatch function definition somewhere
142
+ const oldDispatch = toReturn [ 1 ] ;
143
+ // redefining the dispatch function so we can inject our code
144
+ toReturn [ 1 ] = function ( newVal ) {
145
+ oldDispatch ( newVal ) ;
146
+ updateSnapShotTree ( ) ;
147
+ sendSnapshot ( ) ;
148
+ } ;
149
+ return toReturn ;
150
+ } ;
151
+ } ,
152
+ testUseReducer ( useReducer ) {
153
+ return function ( reducer , initialState , init ) {
154
+ // Declare a constant and initialize to the built-in useReducer method
155
+ // Which returns an array with the state and dispatch
156
+ const reduced = useReducer ( reducer , initialState , init ) ;
157
+ // Save the dispatch method
158
+ const oldDispatch = reduced [ 1 ] ;
159
+ // reassign the dispatch method with the additional methods
160
+ reduced [ 1 ] = function ( type ) {
161
+ oldDispatch ( type ) ;
162
+ updateSnapShotTree ( ) ;
163
+ sendSnapshot ( ) ;
164
+ }
165
+ return reduced ;
166
+ }
167
+ } ,
85
168
} ;
86
- } ;
169
+ } ;
0 commit comments