diff --git a/libs/extension/src/background/index.ts b/libs/extension/src/background/index.ts new file mode 100644 index 00000000..2745c61a --- /dev/null +++ b/libs/extension/src/background/index.ts @@ -0,0 +1,58 @@ +// 多个页面、tab页共享一个 background,需要建立连接池,给每个tab建立连接 +const connections = {}; + +// panel 代码中调用 let backgroundPageConnection = chrome.runtime.connect({...}) 会触发回调函数 +chrome.runtime.onConnect.addListener(function (port) { + + // The original connection event doesn't include the tab ID of the + // DevTools page, so we need to send it explicitly. + function extensionListener(message, sender, sendResponse) { + // 在backgroundPageConnection创建后会发送初始化请求,这样就可以获取tabId,给连接编号 + if (message.name === 'init') { + // 获取 panel 所在 tab 页的tabId + connections[message.tabId] = port; + chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { + chrome.tabs.sendMessage(tabs[0].id, {tag: 'init horizon info'}, function(response) { + console.log(response.farewell); + }); + }); + return; + } + + if (message.name === 'update') { + return; + } + // other message handling + } + + // Listen to messages sent from the DevTools page + port.onMessage.addListener(extensionListener); + + port.onDisconnect.addListener(function (port) { + port.onMessage.removeListener(extensionListener); + + const tabs = Object.keys(connections); + for (let i = 0, len = tabs.length; i < len; i++) { + if (connections[tabs[i]] == port) { + delete connections[tabs[i]]; + break; + } + } + }); +}); + +// 监听来自 content script 的消息,并将消息发送给对应的 devTools page,也就是 panel +chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { + // Messages from content scripts should have sender.tab set + if (sender.tab) { + const tabId = sender.tab.id; + if (tabId in connections) { + connections[tabId].postMessage(request); + } else { + console.log('Tab not found in connection list.'); + } + } else { + console.log('sender.tab not defined.'); + } + return true; +}); diff --git a/libs/extension/src/contentScript/index.ts b/libs/extension/src/contentScript/index.ts new file mode 100644 index 00000000..2236496a --- /dev/null +++ b/libs/extension/src/contentScript/index.ts @@ -0,0 +1,36 @@ +import { injectCode } from '../utils/injectUtils'; + +// 页面的window对象不能直接通过 contentScript 代码修改,只能通过添加 js 代码往页面 window 注入hook +injectCode(chrome.runtime.getURL('/injector.js')); + +// 监听来自页面的信息 +window.addEventListener('message', event => { + // 只监听来自本页面的消息 + if (event.source !== window) { + return; + } + + if (event.data.type && (event.data.type === 'HORIZON_DEV_TOOLS')) { + console.log('Content script received: ' + JSON.stringify(event.data.vNode)); + // 传递给background + chrome.runtime.sendMessage(event.data.vNode, function (response) { + console.log(response); + }); + } +}, false); + + + +// 监听来自background的消息 +chrome.runtime.onMessage.addListener( + function (request, sender, sendResponse) { + console.log(sender.tab ? + 'from a content script:' + sender.tab.url : + 'from the extension'); + if (request.tag === 'init horizon info') { + // 传递消息给页面 + console.log('start pass info to webpage'); + window.postMessage({type: 'HORIZON_DEV_TOOLS', id: 1}, '*'); + } + } +); diff --git a/libs/extension/src/injector/index.ts b/libs/extension/src/injector/index.ts new file mode 100644 index 00000000..178cf608 --- /dev/null +++ b/libs/extension/src/injector/index.ts @@ -0,0 +1,32 @@ +import parseTreeRoot from "../parser/parseVNode"; + +function injectHook() { + if (window.__HORIZON_DEV_HOOK__) { + return; + } + Object.defineProperty(window, '__HORIZON_DEV_HOOK__', { + enumerable: false, + value: { + roots: [], + send: function (vNode: any) { + const result = parseTreeRoot(vNode); + window.postMessage({ + type: 'HORIZON_DEV_TOOLS', vNode: result + }, '*'); + }, + listen: function (id: number) { + window.addEventListener('message', function(event) { + // We only accept messages from ourselves + if (event.source !== window) { + return; + } + + if (event.data.type && (event.data.type === 'HORIZON_DEV_TOOLS') && event.data.id === id) { + console.log('todo'); + } + }); + } + }, + }); +} +injectHook(); diff --git a/libs/extension/src/main/index.ts b/libs/extension/src/main/index.ts new file mode 100644 index 00000000..b81f544c --- /dev/null +++ b/libs/extension/src/main/index.ts @@ -0,0 +1,7 @@ +chrome.devtools.panels.create('Horizon', + '', + 'panel.html', + function(panel) { + + } +); \ No newline at end of file diff --git a/libs/extension/src/main/main.html b/libs/extension/src/main/main.html new file mode 100644 index 00000000..540f18ae --- /dev/null +++ b/libs/extension/src/main/main.html @@ -0,0 +1,12 @@ + + +
+ + + +Horizon dev tools!
+