From d69a08f2e20c9a9eb05983cb5106b8d5be8e60d5 Mon Sep 17 00:00:00 2001 From: Lam Tang Date: Thu, 7 Jul 2022 00:16:27 +0800 Subject: [PATCH 1/2] capture messages from @opensumi/ide-connection and show them in a demo --- src/capturer/index.js | 54 ++++++++++++++++++++++++++++ src/pages/Devtools/index.js | 15 -------- src/pages/Panel/Panel.jsx | 71 +++++++++++++++++++++++++++++++++++++ src/pages/Panel/Panel.tsx | 14 -------- src/utils/eval.js | 41 +++++++++++++++++++++ 5 files changed, 166 insertions(+), 29 deletions(-) create mode 100644 src/capturer/index.js create mode 100644 src/pages/Panel/Panel.jsx delete mode 100644 src/pages/Panel/Panel.tsx create mode 100644 src/utils/eval.js diff --git a/src/capturer/index.js b/src/capturer/index.js new file mode 100644 index 0000000..fb22b1c --- /dev/null +++ b/src/capturer/index.js @@ -0,0 +1,54 @@ +import evalInWindow from '../utils/eval'; + +const startCapturing = () => { + return evalInWindow(() => { + // Return if messages are already being listened to prevent duplicates + // when reloading the extension + if (window.__opensumi_devtools.messages != null) { + window.__opensumi_devtools.messages = []; + return; + } + + window.__opensumi_devtools.messages = []; + + window.__opensumi_devtools.capture = (msg) => { + if (window.__opensumi_devtools.evaling) return; + + try { + msg = JSON.stringify(msg); + } catch (error) { + msg = `Failed to serialize args to JSON: ${error.message || error}`; + } + + window.__opensumi_devtools.messages.push({ + time: new Date().toLocaleString(), + msg: msg, + }); + }; + }); +}; + +const stopCapturing = () => { + return evalInWindow(() => { + if (window.__opensumi_devtools.messages) + delete window.__opensumi_devtools.messages; + if (window.__opensumi_devtools.capture) + delete window.__opensumi_devtools.capture; + }); +}; + +const getMessages = () => { + return evalInWindow(() => { + const messages = window.__opensumi_devtools.messages; + if (messages) window.__opensumi_devtools.messages = []; + return messages; + }).then((messages) => { + if (messages) return messages; + + // Start listening for messages if array is missing meaning + // the window was reloaded + return startCapturing().then(() => []); + }); +}; + +export { startCapturing, stopCapturing, getMessages }; diff --git a/src/pages/Devtools/index.js b/src/pages/Devtools/index.js index 2a251ee..05061e8 100644 --- a/src/pages/Devtools/index.js +++ b/src/pages/Devtools/index.js @@ -1,18 +1,3 @@ -chrome.devtools.inspectedWindow.eval(`console.log('你好牛你好牛')`); - -chrome.devtools.inspectedWindow - .eval(`window.__OPENSUMI_DEVTOOL_EVENT_SOURCE_TOKEN__ = { - traffic: { - send: (msg) => { - console.log('[send] ', msg) - }, - receive: (msg) => { - console.log('[receive] ', msg) - }, - }, - }; -`); - chrome.devtools.panels.create( 'OpenSumi DevTools', 'logo.png', diff --git a/src/pages/Panel/Panel.jsx b/src/pages/Panel/Panel.jsx new file mode 100644 index 0000000..67acb16 --- /dev/null +++ b/src/pages/Panel/Panel.jsx @@ -0,0 +1,71 @@ +import React, { useState, useEffect } from 'react'; +import './Panel.css'; +import { startCapturing, stopCapturing, getMessages } from '../../capturer'; + +const INTERVAL = 333; + +const Panel = () => { + const [capturing, setCapturing] = useState(false); + const [messages, setMessages] = useState([]); + const [timer, setTimer] = useState(null); + + const addMessages = () => { + getMessages() + .then((messages) => { + setMessages((oldMessages) => [...oldMessages, ...messages]); + }) + .catch((error) => { + console.error('Getting messages failed!'); + console.error(error.stack || error); + }); + }; + + const start = () => { + startCapturing() + .then(() => { + setCapturing(true); + setTimer(setInterval(() => addMessages(), INTERVAL)); + }) + .catch((error) => { + console.error('Starting capturing failed!'); + console.error(error.stack || error); + }); + }; + + const stop = () => { + stopCapturing() + .then(() => { + setCapturing(false); + clearInterval(timer); + setTimer(null); + }) + .catch((error) => { + console.error('Stoping capturing failed!'); + console.error(error.stack || error); + }); + }; + + return ( +
+ + +

{capturing ? 'capturing' : 'not capturing'}

+ + + + {messages.map((msg, index) => { + return ( + + + + + + ); + })} + +
{index}{msg.time}{msg.msg}
+
+ ); +}; + +export default Panel; diff --git a/src/pages/Panel/Panel.tsx b/src/pages/Panel/Panel.tsx deleted file mode 100644 index 74da7e9..0000000 --- a/src/pages/Panel/Panel.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import './Panel.css'; -import Line from './line/line'; - -const Panel: React.FC = () => { - return ( -
-

OpenSumi DevTools

- -
- ); -}; - -export default Panel; diff --git a/src/utils/eval.js b/src/utils/eval.js new file mode 100644 index 0000000..c946b2c --- /dev/null +++ b/src/utils/eval.js @@ -0,0 +1,41 @@ +const evalInWindow = (expression, ...rest) => { + if (typeof expression === 'function') { + expression = `(${expression})`; + if (rest.length > 0) { + let expressionArgs = JSON.stringify(rest); + expression += `.apply(this, ${expressionArgs})`; + } else { + expression += '()'; + } + } + + expression = ` + (function () { + window.__opensumi_devtools = window.__opensumi_devtools || {} + window.__opensumi_devtools.evaling = true + + try { + return ${expression} + } finally { + window.__opensumi_devtools.evaling = false + } + })() + `; + + return new Promise((resolve, reject) => { + window.chrome.devtools.inspectedWindow.eval(expression, (result, error) => { + if (error) { + if (error.isException && error.value) { + let stack = error.value; + error = new Error(stack.split('\n')[0]); + error.stack = stack; + } + reject(error); + } else { + resolve(result); + } + }); + }); +}; + +export default evalInWindow; From 3719cc78eace3570b516af2fc891f575d52c7156 Mon Sep 17 00:00:00 2001 From: Lam Tang Date: Thu, 7 Jul 2022 10:11:10 +0800 Subject: [PATCH 2/2] useEffect not used, remvoe it --- src/pages/Panel/Panel.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Panel/Panel.jsx b/src/pages/Panel/Panel.jsx index 67acb16..6ae786c 100644 --- a/src/pages/Panel/Panel.jsx +++ b/src/pages/Panel/Panel.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import './Panel.css'; import { startCapturing, stopCapturing, getMessages } from '../../capturer';