4
4
// links component state tree to library
5
5
// changes the setState method to also update our snapshot
6
6
const Tree = require ( './tree' ) ;
7
+ const astParser = require ( './astParser.js' ) ;
7
8
8
9
module . exports = ( snap , mode ) => {
9
10
let fiberRoot = null ;
11
+ let astHooks ;
10
12
11
13
function sendSnapshot ( ) {
12
14
// don't send messages while jumping or while paused
@@ -20,20 +22,15 @@ module.exports = (snap, mode) => {
20
22
} ) ;
21
23
}
22
24
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
26
25
function changeSetState ( component ) {
27
26
// check that setState hasn't been changed yet
28
27
if ( component . setState . linkFiberChanged ) return ;
29
-
30
28
// make a copy of setState
31
29
const oldSetState = component . setState . bind ( component ) ;
32
-
33
30
// replace component's setState so developer doesn't change syntax
34
31
// component.setState = newSetState.bind(component);
35
- component . setState = ( state , callback = ( ) => { } ) => {
36
- // dont do anything if state is locked
32
+ component . setState = ( state , callback = ( ) => { } ) => {
33
+ // don't do anything if state is locked
37
34
// UNLESS we are currently jumping through time
38
35
if ( mode . locked && ! mode . jumping ) return ;
39
36
// continue normal setState functionality, except add sending message middleware
@@ -46,26 +43,45 @@ module.exports = (snap, mode) => {
46
43
component . setState . linkFiberChanged = true ;
47
44
}
48
45
49
- // Helper function to
46
+ function changeUseState ( component ) {
47
+ if ( component . queue . dispatch . linkFiberChanged ) return ;
48
+ // store the original dispatch function definition
49
+ const oldDispatch = component . queue . dispatch . bind ( component . queue ) ; ;
50
+ // redefine the dispatch function so we can inject our code
51
+ component . queue . dispatch = ( fiber , queue , action ) => {
52
+ // don't do anything if state is locked
53
+ if ( mode . locked && ! mode . jumping ) return ;
54
+ oldDispatch ( fiber , queue , action ) ;
55
+ setTimeout ( ( ) => {
56
+ updateSnapShotTree ( ) ;
57
+ sendSnapshot ( ) ;
58
+ } , 100 ) ;
59
+ } ;
60
+ component . queue . dispatch . linkFiberChanged = true ;
61
+ }
50
62
51
63
// Helper function to traverse through the memoized state
64
+ // TODO: WE NEED TO CLEAN IT UP A BIT
52
65
function traverseHooks ( memoizedState ) {
53
66
// Declare variables and assigned to 0th index and an empty object, respectively
54
- let index = 0 ;
55
- const memoizedObj = { } ;
67
+ const memoized = { } ;
68
+ let index = 0 ;
69
+ astHooks = Object . values ( astHooks ) ;
56
70
// 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 ;
71
+ while ( memoizedState && astHooks ) {
72
+ changeUseState ( memoizedState ) ;
73
+ memoized [ astHooks [ index ] ] = memoizedState . memoizedState ;
60
74
// Reassign memoizedState to its next value
61
75
memoizedState = memoizedState . next ;
76
+ // Increment the index by 2
77
+ index += 2 ;
62
78
}
63
- return memoizedObj ;
79
+ return memoized ;
64
80
}
65
81
66
82
function createTree ( currentFiber , tree = new Tree ( 'root' ) ) {
67
83
if ( ! currentFiber ) return tree ;
68
-
84
+
69
85
const {
70
86
sibling,
71
87
stateNode,
@@ -82,15 +98,12 @@ module.exports = (snap, mode) => {
82
98
changeSetState ( stateNode ) ;
83
99
}
84
100
// 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
101
if ( memoizedState && memoizedState . hasOwnProperty ( 'baseState' ) ) {
88
- // console.log('The memoizedState is: ', memoizedState)
89
-
90
- const traversed = traverseHooks ( memoizedState ) ;
91
- nextTree = tree . appendChild ( traversed ) ;
102
+ // Add a traversed property and initialize to the evaluated result
103
+ // of invoking traverseHooks, and reassign nextTree
104
+ memoizedState . traversed = traverseHooks ( memoizedState ) ;
105
+ nextTree = tree . appendChild ( memoizedState ) ;
92
106
}
93
-
94
107
// iterate through siblings
95
108
createTree ( sibling , tree ) ;
96
109
// iterate through children
@@ -103,67 +116,21 @@ module.exports = (snap, mode) => {
103
116
const { current } = fiberRoot ;
104
117
snap . tree = createTree ( current ) ;
105
118
}
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();
116
119
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
- // };
120
+ return ( container , entryFile ) => {
121
+ const {
122
+ _reactRootContainer : { _internalRoot } ,
123
+ _reactRootContainer,
124
+ } = container ;
125
+ // only assign internal rootp if it actually exists
126
+ fiberRoot = _internalRoot || _reactRootContainer ;
127
+ // If hooks are implemented, traverse through the source code
128
+ if ( entryFile ) astHooks = astParser ( entryFile ) ;
122
129
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
- } ,
168
- } ;
169
- } ;
130
+ updateSnapShotTree ( ) ;
131
+ // send the initial snapshot once the content script has started up
132
+ window . addEventListener ( 'message' , ( { data : { action } } ) => {
133
+ if ( action === 'contentScriptStarted' ) sendSnapshot ( ) ;
134
+ } ) ;
135
+ }
136
+ } ;
0 commit comments