From 5a9d7d9e624261dca9123165f5f43ede18081750 Mon Sep 17 00:00:00 2001 From: Victor Varaschin Date: Wed, 13 Mar 2019 10:56:04 -0400 Subject: [PATCH 1/8] Fixed bug that made devtool refresh when we started recording. --- src/app/components/App.jsx | 13 ++++++-- src/browser/chrome/background.js | 54 +++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/app/components/App.jsx b/src/app/components/App.jsx index 8c5f8a9..f73e090 100644 --- a/src/app/components/App.jsx +++ b/src/app/components/App.jsx @@ -48,6 +48,7 @@ class App extends Component { }; this.portToExtension = null; + this.justStartedRecording = false; this.addActionToView = this.addActionToView.bind(this); this.toTheFuture = this.toTheFuture.bind(this); @@ -108,9 +109,11 @@ class App extends Component { } } - // functionality to change 'record' button to 'pause' setIsRecording() { - console.log('setIsRecording:', this.state.isRecording) + // This variable will prevent the app from refreshing when we refresh + // the userpage. + this.justStartedRecording = true; + this.setState(state => ({ isRecording: !state.isRecording, })); @@ -213,6 +216,12 @@ class App extends Component { } resetApp() { + if (this.justStartedRecording) { + console.log('not reseting...'); + this.justStartedRecording = false; + return; + } + console.log('reseting...'); this.setState({ data: [], searchField: '', diff --git a/src/browser/chrome/background.js b/src/browser/chrome/background.js index 9b2024d..7d810c6 100644 --- a/src/browser/chrome/background.js +++ b/src/browser/chrome/background.js @@ -25,7 +25,6 @@ function handleRequest(request) { // TODO: filter the request from the webRequest call. if (!interceptedUrl.startsWith(request.initiator)) return { cancel: false }; - console.log('intercepting... ', request); if (request.type === 'script' && !request.url.startsWith('chrome') && request.frameId === 0) { // TODO: adjust comment @@ -72,6 +71,59 @@ function addScriptInterception() { { urls: [''] }, ['blocking'], ); + + // chrome.webRequest.onBeforeSendHeaders.addListener( + // (request) => { + // if (!interceptedUrl.startsWith(request.initiator)) return { cancel: false }; + + // if (request.type !== 'script' || request.url.startsWith('chrome') + // || request.frameId !== 0) return; + + // request.requestHeaders.push({ + // name: 'Access-Control-Allow-Credentials', + // value: '*', + // }); + + // request.requestHeaders.push({ + // name: 'Accept', + // value: 'application/javascript', + // }); + + // request.requestHeaders.push({ + // name: 'ABC', + // value: 'abc', + // }); + + // for (let i = 0; i < request.requestHeaders.length; i++) { + // const header = request.requestHeaders[i]; + // if (header.name === 'Origin') { + // console.log('found one'); + // delete request.requestHeaders[i]; + // } + // } + + // console.log('intercepting fom beforesendheaders: ', request); + // }, + // { urls: [''] }, + // ['blocking', 'requestHeaders'], + // ); + + // chrome.webRequest.onHeadersReceived.addListener((request) => { + // if (!interceptedUrl.startsWith(request.initiator)) return { cancel: false }; + + // if (request.type !== 'script' || request.url.startsWith('chrome') + // || request.frameId !== 0) return; + + // const syncRequest = new XMLHttpRequest(); + // syncRequest.open('GET', request.url, false); + // syncRequest.send(null); + + // console.log('Got req onHeadersReceived!!!! ', request); + + // return { redirectUrl: 'data:application/javascript; charset=utf-8,'.concat(syncRequest.responseText) }; + // }, + // { urls: [''] }, + // ['blocking', 'responseHeaders']); } let reqIndex = 0; From fbe7e53e6f1c527ccc2c9af8ab77766c12a40855 Mon Sep 17 00:00:00 2001 From: Victor Varaschin Date: Wed, 13 Mar 2019 11:04:30 -0400 Subject: [PATCH 2/8] added react-json-view to package-lock --- src/app/package-lock.json | 41 ++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/app/package-lock.json b/src/app/package-lock.json index 4a00f84..5fe1308 100644 --- a/src/app/package-lock.json +++ b/src/app/package-lock.json @@ -3010,7 +3010,8 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true }, "aproba": { "version": "1.2.0", @@ -3031,12 +3032,14 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "optional": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3051,17 +3054,20 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "optional": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3178,7 +3184,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "optional": true }, "ini": { "version": "1.3.5", @@ -3190,6 +3197,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3204,6 +3212,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3211,12 +3220,14 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "optional": true }, "minipass": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3235,6 +3246,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3315,7 +3327,8 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3327,6 +3340,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "optional": true, "requires": { "wrappy": "1" } @@ -3412,7 +3426,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3448,6 +3463,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3467,6 +3483,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3510,12 +3527,14 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "optional": true }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "optional": true } } }, From 4f15e5ac4acc072d9c3b635a50f38a9b23a06bb0 Mon Sep 17 00:00:00 2001 From: Victor Varaschin Date: Wed, 13 Mar 2019 11:17:17 -0400 Subject: [PATCH 3/8] Data stays filtered after new actions get posted --- src/app/components/App.jsx | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/app/components/App.jsx b/src/app/components/App.jsx index 5db5d93..1fd481a 100644 --- a/src/app/components/App.jsx +++ b/src/app/components/App.jsx @@ -65,21 +65,31 @@ class App extends Component { // adds listener to the effects that are gonna be sent from // our edited useReducer from the 'react' library. chrome.runtime.onConnect.addListener((port) => { - if (port.name === 'injected-app') { - this.portToExtension = port; - - port.onMessage.addListener((msg) => { - const newData = { - action: msg.action, - state: msg.state, - id: this.state.data.length, - }; - this.setState((state) => ({ + if (port.name !== 'injected-app') return; + + this.portToExtension = port; + + port.onMessage.addListener((msg) => { + const newData = { + action: msg.action, + state: msg.state, + id: this.state.data.length, + }; + + const { searchField } = this.state; + const newDataActionType = newData.action.type.toLowerCase(); + + if (newDataActionType.includes(searchField.toLowerCase())) { + this.setState(state => ({ data: [...state.data, newData], filteredData: [...state.data, newData], })); - }); - } + } else { + this.setState(state => ({ + data: [...state.data, newData], + })); + } + }); }); // We listen to the message from devtools.js (sent originally from @@ -94,8 +104,6 @@ class App extends Component { }); } - - // functionality to change 'play' button to 'stop' setIsPlaying() { if (this.state.isPlayingIndex > this.state.data.length - 1) { From 66820b185724449fc62c47af421656704ed4fcb5 Mon Sep 17 00:00:00 2001 From: Victor Varaschin Date: Wed, 13 Mar 2019 11:49:58 -0400 Subject: [PATCH 4/8] fixed time travel forward when already at tail of linked list. --- src/app/components/App.jsx | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/app/components/App.jsx b/src/app/components/App.jsx index 1fd481a..1bc14b4 100644 --- a/src/app/components/App.jsx +++ b/src/app/components/App.jsx @@ -217,6 +217,9 @@ class App extends Component { // function to travel to the FUTURE toTheFuture() { + const { data, isPlayingIndex } = this.state; + if (isPlayingIndex === data.length - 1) return; + if (!this.portToExtension) return console.error('No connection on stored port.'); this.portToExtension.postMessage({ type: 'TIMETRAVEL', @@ -225,7 +228,6 @@ class App extends Component { // if (isPlayingIndex >= this.state.data.length - 1) isPlayingIndex = 0; - const { data, isPlayingIndex } = this.state; const { id, action, state } = data[isPlayingIndex + 1]; this.setState(prev => ({ ...prev, @@ -240,26 +242,23 @@ class App extends Component { // function to travel to the PAST toThePast() { + const { data, isPlayingIndex } = this.state; + if (isPlayingIndex === 0) return; + if (!this.portToExtension) return console.error('No connection on stored port.'); this.portToExtension.postMessage({ type: 'TIMETRAVEL', direction: 'backwards', }); - const { data, isPlayingIndex } = this.state; - - if (isPlayingIndex === 0) { - console.log('is playingIdx in toThePast is 0'); - } else { - const { id, action, state } = data[isPlayingIndex - 1]; - this.setState(prev => ({ - ...prev, - id, - action, - state, - isPlayingIndex: isPlayingIndex - 1, - })); - } + const { id, action, state } = data[isPlayingIndex - 1]; + this.setState(prev => ({ + ...prev, + id, + action, + state, + isPlayingIndex: isPlayingIndex - 1, + })); } resetApp() { From e121ee2d6f3a2afefeec2445232409904983ce7f Mon Sep 17 00:00:00 2001 From: Victor Varaschin Date: Wed, 13 Mar 2019 17:04:44 -0400 Subject: [PATCH 5/8] Fixed time-slider play functionality. --- src/app/components/App.jsx | 25 +++++++++------------ src/app/components/EventCards/FilterBar.jsx | 1 + src/app/container/Events.jsx | 3 ++- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/app/components/App.jsx b/src/app/components/App.jsx index 1bc14b4..4bb7ad8 100644 --- a/src/app/components/App.jsx +++ b/src/app/components/App.jsx @@ -82,11 +82,13 @@ class App extends Component { if (newDataActionType.includes(searchField.toLowerCase())) { this.setState(state => ({ data: [...state.data, newData], - filteredData: [...state.data, newData], + isPlayingIndex: state.data.length, + filteredData: [...state.filteredData, newData], })); } else { this.setState(state => ({ data: [...state.data, newData], + isPlayingIndex: state.data.length, })); } }); @@ -106,8 +108,8 @@ class App extends Component { // functionality to change 'play' button to 'stop' setIsPlaying() { - if (this.state.isPlayingIndex > this.state.data.length - 1) { - this.setState({ isPlayingIndex: 0 }); + if (this.state.isPlayingIndex >= this.state.data.length - 1) { + return; } let { isPlaying } = this.state; @@ -142,20 +144,11 @@ class App extends Component { } actionInPlay() { - let { isPlayingIndex } = this.state; - const { isPlaying, data } = this.state; - - if (isPlayingIndex >= data.length - 1) isPlayingIndex = 0; - - this.setState({ isPlayingIndex: isPlayingIndex + 1 }); - const { id, action, state } = data[isPlayingIndex + 1]; - this.toTheFuture(); + const { data, isPlayingIndex } = this.state; setTimeout(() => { - this.setState((prev, props) => { - return { ...prev, id, action, state }; - }); - if (isPlaying && isPlayingIndex + 1 < data.length - 1) { + this.toTheFuture(); + if (this.state.isPlaying && isPlayingIndex + 1 < data.length - 1) { this.actionInPlay(); } else { this.setState({ isPlaying: false }); @@ -289,6 +282,7 @@ class App extends Component { setIsRecording, isRecording, filteredData, + searchField, } = this.state; return ( @@ -304,6 +298,7 @@ class App extends Component { activeEventId={id} searchChange={this.searchChange} filteredData={filteredData} + searchField={searchField} /> )} right={ diff --git a/src/app/components/EventCards/FilterBar.jsx b/src/app/components/EventCards/FilterBar.jsx index e620832..1b78b0d 100644 --- a/src/app/components/EventCards/FilterBar.jsx +++ b/src/app/components/EventCards/FilterBar.jsx @@ -16,6 +16,7 @@ export default function FilterBar(props) { type="text" placeholder="filter actions by name..." onChange={searchChange} + value={props.searchField} /> diff --git a/src/app/container/Events.jsx b/src/app/container/Events.jsx index 0fd20d3..4593489 100644 --- a/src/app/container/Events.jsx +++ b/src/app/container/Events.jsx @@ -18,11 +18,12 @@ class Events extends Component { data, searchChange, filteredData, + searchField, } = this.props; return ( <> - + Date: Tue, 19 Mar 2019 21:23:32 -0400 Subject: [PATCH 6/8] Delete closed ports from array --- package-lock.json | 46 ++++++++++---- package.json | 3 +- src/app/components/App.jsx | 17 +++--- src/browser/chrome/background.js | 102 +++++++++++++++++-------------- 4 files changed, 103 insertions(+), 65 deletions(-) diff --git a/package-lock.json b/package-lock.json index 128e079..ab38a6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1807,7 +1807,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1828,12 +1829,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1848,17 +1851,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1975,7 +1981,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1987,6 +1994,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2001,6 +2009,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2008,12 +2017,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -2032,6 +2043,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2112,7 +2124,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2124,6 +2137,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2209,7 +2223,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2245,6 +2260,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2264,6 +2280,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2307,12 +2324,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -2928,6 +2947,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", diff --git a/package.json b/package.json index 2c787c9..b102d20 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "eslint-plugin-jsx-a11y": "^6.2.1", "esprima": "^4.0.1", "estraverse": "^4.2.0", - "lodash": "^4.17.11" + "lodash": "^4.17.11", + "lodash.clonedeep": "^4.5.0" } } diff --git a/src/app/components/App.jsx b/src/app/components/App.jsx index 4bb7ad8..de22f8f 100644 --- a/src/app/components/App.jsx +++ b/src/app/components/App.jsx @@ -45,6 +45,9 @@ class App extends Component { isPlaying: false, isRecording: false, isPlayingIndex: 0, + id: 0, + action: {}, + state: {}, }; this.portToExtension = null; @@ -123,7 +126,7 @@ class App extends Component { setIsRecording() { // This variable will prevent the app from refreshing when we refresh - // the userpage. + // the userpage. this.justStartedRecording = true; this.setState(state => ({ @@ -219,8 +222,6 @@ class App extends Component { direction: 'forward', }); - // if (isPlayingIndex >= this.state.data.length - 1) isPlayingIndex = 0; - const { id, action, state } = data[isPlayingIndex + 1]; this.setState(prev => ({ ...prev, @@ -268,6 +269,9 @@ class App extends Component { isPlaying: false, isRecording: false, isPlayingIndex: 0, + id: 0, + action: {}, + state: {}, }); } @@ -277,12 +281,11 @@ class App extends Component { id, state, data, - setIsPlaying, isPlaying, - setIsRecording, isRecording, filteredData, searchField, + isPlayingIndex, } = this.state; return ( @@ -315,7 +318,7 @@ class App extends Component { toTheFuture={this.toTheFuture} toThePast={this.toThePast} isPlaying={isPlaying} - isPlayingIndex={this.state.isPlayingIndex} + isPlayingIndex={isPlayingIndex} isRecording={isRecording} setIsPlaying={this.setIsPlaying} setIsRecording={this.setIsRecording} @@ -327,4 +330,4 @@ class App extends Component { } } -export default App; \ No newline at end of file +export default App; diff --git a/src/browser/chrome/background.js b/src/browser/chrome/background.js index 7d810c6..a049fe6 100644 --- a/src/browser/chrome/background.js +++ b/src/browser/chrome/background.js @@ -1,5 +1,6 @@ -const parseAndGenerate = require('./scripts/parser'); -const ports = []; +const parseAndGenerate = require('./scripts/parser2'); + +let ports = []; chrome.tabs.onUpdated.addListener((id, info, tab) => { if (tab.status !== 'complete' || tab.url.startsWith('chrome')) return; @@ -12,6 +13,7 @@ chrome.tabs.onUpdated.addListener((id, info, tab) => { }); chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + interceptedUrl = ''; notifyPorts( { action: 'refresh_devtool', tabId: tabs[0].id }, 'devtools', @@ -26,7 +28,9 @@ function handleRequest(request) { if (!interceptedUrl.startsWith(request.initiator)) return { cancel: false }; if (request.type === 'script' && !request.url.startsWith('chrome') - && request.frameId === 0) { + && request.frameId === 0 && ((request.url.slice(-3) === '.js') + || (request.url.slice(-4) === '.jsx'))) { + console.log('Got one: ', request.url, request); // TODO: adjust comment // Else we need to check wether or not this contains the react // library. If it does, we need to send the edit javascript to @@ -40,6 +44,9 @@ function handleRequest(request) { sendMessageToContent(parseAndGenerate(syncRequest.responseText)); + // const code = encodeURIComponent(parseAndGenerate(syncRequest.responseText)); + // console.log('CODE - LENGTH: ', code.length); + // return { redirectUrl: 'data:application/javascript; charset=utf-8,'.concat(code) }; return { redirectUrl: 'javascript:' }; } } @@ -78,52 +85,50 @@ function addScriptInterception() { // if (request.type !== 'script' || request.url.startsWith('chrome') // || request.frameId !== 0) return; - - // request.requestHeaders.push({ - // name: 'Access-Control-Allow-Credentials', - // value: '*', - // }); - - // request.requestHeaders.push({ - // name: 'Accept', - // value: 'application/javascript', - // }); - - // request.requestHeaders.push({ - // name: 'ABC', - // value: 'abc', - // }); - + // console.log('onBeforeHeaders = ', request.url); + // // request.requestHeaders.push({ + // // name: 'Access-Control-Allow-Credentials', + // // value: '*', + // // }); + + // // request.requestHeaders.push({ + // // name: 'Accept', + // // value: 'application/javascript', + // // }); + + // // request.requestHeaders.push({ + // // name: 'ABC', + // // value: 'abc', + // // }); + // const filteredHeaders = [{name: 'TTT', value: 'OK'}]; // for (let i = 0; i < request.requestHeaders.length; i++) { // const header = request.requestHeaders[i]; - // if (header.name === 'Origin') { - // console.log('found one'); - // delete request.requestHeaders[i]; + // if (header.name !== 'Origin') { + // filteredHeaders.push({ + // name: header.name, + // value: header.value, + // }); // } // } - - // console.log('intercepting fom beforesendheaders: ', request); + // return { requestHeaders: filteredHeaders }; // }, // { urls: [''] }, // ['blocking', 'requestHeaders'], // ); - // chrome.webRequest.onHeadersReceived.addListener((request) => { - // if (!interceptedUrl.startsWith(request.initiator)) return { cancel: false }; - - // if (request.type !== 'script' || request.url.startsWith('chrome') - // || request.frameId !== 0) return; - - // const syncRequest = new XMLHttpRequest(); - // syncRequest.open('GET', request.url, false); - // syncRequest.send(null); - - // console.log('Got req onHeadersReceived!!!! ', request); + // chrome.webRequest.onSendHeaders.addListener( + // (request) => { + // console.log('onSendHeaders: ', request); + // }, + // { urls: [''] }, + // ['requestHeaders'], + // ); - // return { redirectUrl: 'data:application/javascript; charset=utf-8,'.concat(syncRequest.responseText) }; - // }, - // { urls: [''] }, - // ['blocking', 'responseHeaders']); + // chrome.webRequest.onHeadersReceived.addListener( + // handleRequest, + // { urls: [''] }, + // ['blocking', 'responseHeaders'], + // ); } let reqIndex = 0; @@ -135,12 +140,17 @@ function sendMessageToContent(codeString) { } function notifyPorts(msg, portName) { - ports.forEach((port) => { - if (portName && (port.name !== portName)) return; - try { - port.postMessage(msg); - } catch { - console.log('notifyPorts has found some closed conections.'); + let index = 0; + while (index < ports.length) { + if (portName && (ports[index].name !== portName)) index++; + else { + try { + ports[index].postMessage(msg); + index++; + } catch { + // remove closed port from array + ports = [...ports.slice(0, index), ...ports.slice(index + 1)]; + } } - }); + } } From 2f960bf345bdb98ad3f9bbc96ba3e30cfcaa18b0 Mon Sep 17 00:00:00 2001 From: Victor Varaschin Date: Wed, 20 Mar 2019 14:27:47 -0400 Subject: [PATCH 7/8] State diff, pause button, injecting scripts only while recording --- src/app/components/App.jsx | 41 +- .../DetailCards/Effects/EffectsDisplay.jsx | 10 +- src/app/components/stateDifference.jsx | 62 +- src/app/container/Details.jsx | 4 +- src/browser/chrome/background.js | 81 +- src/browser/chrome/manifest.json | 6 +- src/browser/chrome/scripts/inject_bundle.js | 907 ++++++++++++++++++ .../chrome/scripts/inject_script_tags.js | 108 ++- src/browser/chrome/scripts/parser.js | 4 +- src/browser/chrome/scripts/time_travel.js | 33 - 10 files changed, 1055 insertions(+), 201 deletions(-) create mode 100644 src/browser/chrome/scripts/inject_bundle.js diff --git a/src/app/components/App.jsx b/src/app/components/App.jsx index de22f8f..da979b2 100644 --- a/src/app/components/App.jsx +++ b/src/app/components/App.jsx @@ -48,10 +48,12 @@ class App extends Component { id: 0, action: {}, state: {}, + prevState: {} }; this.portToExtension = null; this.justStartedRecording = false; + this.hasInjectedScript = false; this.addActionToView = this.addActionToView.bind(this); this.toTheFuture = this.toTheFuture.bind(this); @@ -73,9 +75,14 @@ class App extends Component { this.portToExtension = port; port.onMessage.addListener((msg) => { + // If the user paused the recording session, we return + const { isRecording } = this.state; + if (!isRecording) return; + const newData = { action: msg.action, state: msg.state, + prevState: msg.prevState, id: this.state.data.length, }; @@ -111,7 +118,8 @@ class App extends Component { // functionality to change 'play' button to 'stop' setIsPlaying() { - if (this.state.isPlayingIndex >= this.state.data.length - 1) { + const { isPlayingIndex, data } = this.state; + if (isPlayingIndex >= data.length - 1) { return; } @@ -128,17 +136,22 @@ class App extends Component { // This variable will prevent the app from refreshing when we refresh // the userpage. this.justStartedRecording = true; - + const { isRecording, hasInjectedScript } = this.state; this.setState(state => ({ isRecording: !state.isRecording, })); + // if we are hitting the pause or re-starting the record session + if (isRecording || hasInjectedScript) return; + + this.setState({ hasInjectedScript: true }); + // we query the active window so we can send it to the background script // so it knows on which URL to run our devtool. chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { const { url } = tabs[0]; - // backgroundPort is a variable made avaiable by the devtools.js + // backgroundPort is a variable made avaiable by the devtools.js backgroundPort.postMessage({ turnOnDevtool: true, url, @@ -147,11 +160,11 @@ class App extends Component { } actionInPlay() { - const { data, isPlayingIndex } = this.state; + const { data, isPlayingIndex, isPlaying } = this.state; setTimeout(() => { this.toTheFuture(); - if (this.state.isPlaying && isPlayingIndex + 1 < data.length - 1) { + if (isPlaying && isPlayingIndex + 1 < data.length - 1) { this.actionInPlay(); } else { this.setState({ isPlaying: false }); @@ -165,10 +178,10 @@ class App extends Component { const { data } = this.state; const actionToView = data.filter(action => e.target.id === String(action.id)); const { - action, id, state, + action, id, state, prevState, } = actionToView[0]; this.setState({ - action, id, state, + action, id, state, prevState, }); } @@ -193,7 +206,7 @@ class App extends Component { // time travel bar change handleBarChange(e) { const { data, isPlayingIndex } = this.state; - const { id, action, state } = data[e.target.value]; + const { id, action, state, prevState } = data[e.target.value]; // forward or past const currentIsPlayingIndex = e.target.value; const forward = currentIsPlayingIndex > isPlayingIndex; @@ -201,6 +214,7 @@ class App extends Component { id, action, state, + prevState, isPlayingIndex: parseInt(currentIsPlayingIndex), }); // Displays to screen @@ -222,16 +236,15 @@ class App extends Component { direction: 'forward', }); - const { id, action, state } = data[isPlayingIndex + 1]; + const { id, action, state, prevState } = data[isPlayingIndex + 1]; this.setState(prev => ({ ...prev, id, action, state, + prevState, isPlayingIndex: isPlayingIndex + 1, })); - - console.log('isPlayingIndex', this.state.isPlayingIndex); } // function to travel to the PAST @@ -245,12 +258,13 @@ class App extends Component { direction: 'backwards', }); - const { id, action, state } = data[isPlayingIndex - 1]; + const { id, action, state, prevState } = data[isPlayingIndex - 1]; this.setState(prev => ({ ...prev, id, action, state, + prevState, isPlayingIndex: isPlayingIndex - 1, })); } @@ -272,6 +286,7 @@ class App extends Component { id: 0, action: {}, state: {}, + prevState: {}, }); } @@ -286,6 +301,7 @@ class App extends Component { filteredData, searchField, isPlayingIndex, + prevState, } = this.state; return ( @@ -310,6 +326,7 @@ class App extends Component { action={action} id={id} actionState={state} + prevState={prevState} /> )} /> diff --git a/src/app/components/DetailCards/Effects/EffectsDisplay.jsx b/src/app/components/DetailCards/Effects/EffectsDisplay.jsx index 8869fa7..5c29195 100644 --- a/src/app/components/DetailCards/Effects/EffectsDisplay.jsx +++ b/src/app/components/DetailCards/Effects/EffectsDisplay.jsx @@ -1,23 +1,23 @@ import React from 'react'; -import { DetailsWrapper } from '../../../styles/Details.jsx'; import ReactJson from 'react-json-view'; +import { DetailsWrapper } from '../../../styles/Details.jsx'; // functionality // gets difference from previous state to new state import stateDifference from '../../stateDifference.jsx'; export default function Effects(props) { - console.log('state differnce in effects display IMPORT', stateDifference); - const differenceOfPrevAndNextState = stateDifference([1,2,3], [2,4, 9, 11, {'wow': 1}]) + const { prevState, actionState } = props; + const differenceOfPrevAndNextState = stateDifference(prevState, actionState); + return ( - ); } diff --git a/src/app/components/stateDifference.jsx b/src/app/components/stateDifference.jsx index b0af52c..b2df9ec 100644 --- a/src/app/components/stateDifference.jsx +++ b/src/app/components/stateDifference.jsx @@ -1,39 +1,39 @@ function stateDifference(old, curr) { - - if(typeof(old) === "string" && typeof(curr) === "string") { - if(old === curr) return false; - return curr; - } - else if(typeof(old) === "number" && typeof(curr) === "number") { - if( old === curr) return false; - return curr; - } - else if(typeof(old) !== typeof(curr)) { + + if(typeof(old) === "string" && typeof(curr) === "string") { + if(old === curr) return false; + return curr; + } + else if(typeof(old) === "number" && typeof(curr) === "number") { + if( old === curr) return false; return curr; - } - else if(Array.isArray(old) && Array.isArray(curr)) { - let newArr = []; - for ( let i = 0; i < curr.length; i++){ - if(!old.includes(curr[i])){ - let result = stateDifference(old[i], curr[i]) - if (result) { - newArr.push(result) - } - } - } - return newArr.length > 0 ? newArr : false; - } - else if(typeof(old) === "object" && typeof(curr) === "object") { - let newObj = {} - for ( let prop in curr) { - result = stateDifference(old[prop], curr[prop]) - if (result){ - newObj[prop] = result + } + else if(typeof(old) !== typeof(curr)) { + return curr; + } + else if(Array.isArray(old) && Array.isArray(curr)) { + let newArr = []; + for ( let i = 0; i < curr.length; i++){ + if(!old.includes(curr[i])){ + let result = stateDifference(old[i], curr[i]) + if (result) { + newArr.push(result) } } - return Object.keys(newObj).length === 0 ? false : newObj + } + return newArr.length > 0 ? newArr : false; + } + else if(typeof(old) === "object" && typeof(curr) === "object") { + let newObj = {} + for ( let prop in curr) { + let result = stateDifference(old[prop], curr[prop]) + if (result) { + newObj[prop] = result + } } + return Object.keys(newObj).length === 0 ? false : newObj } +} - export default stateDifference; \ No newline at end of file +export default stateDifference; \ No newline at end of file diff --git a/src/app/container/Details.jsx b/src/app/container/Details.jsx index e1e731d..c005f2f 100644 --- a/src/app/container/Details.jsx +++ b/src/app/container/Details.jsx @@ -18,7 +18,7 @@ export default function Details(props) { // destructuring required info that's being passed down from App.jsx // passing these props onto children const { - action, id, actionState, + action, prevState, actionState, } = props; @@ -34,7 +34,7 @@ export default function Details(props) { /> } + render={props => } /> { if (tab.status !== 'complete' || tab.url.startsWith('chrome')) return; @@ -14,6 +17,7 @@ chrome.tabs.onUpdated.addListener((id, info, tab) => { chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { interceptedUrl = ''; + reqIndex = 0; notifyPorts( { action: 'refresh_devtool', tabId: tabs[0].id }, 'devtools', @@ -21,8 +25,6 @@ chrome.tabs.onUpdated.addListener((id, info, tab) => { }); }); - -let interceptedUrl = ''; function handleRequest(request) { // TODO: filter the request from the webRequest call. if (!interceptedUrl.startsWith(request.initiator)) return { cancel: false }; @@ -30,23 +32,21 @@ function handleRequest(request) { if (request.type === 'script' && !request.url.startsWith('chrome') && request.frameId === 0 && ((request.url.slice(-3) === '.js') || (request.url.slice(-4) === '.jsx'))) { - console.log('Got one: ', request.url, request); - // TODO: adjust comment - // Else we need to check wether or not this contains the react - // library. If it does, we need to send the edit javascript to - // out content script, so it can inject into the page. If it doesnt, - // we need to send the url to our content script so that it can - // add it to the page