Match-id-6411a05fa00c9702c38999dd426b0cd28346f65a

This commit is contained in:
* 2022-04-15 17:52:55 +08:00 committed by *
parent 59e00b336a
commit 548c3b6172
9 changed files with 186 additions and 1 deletions

View File

@ -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;
});

View File

@ -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}, '*');
}
}
);

View File

@ -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();

View File

@ -0,0 +1,7 @@
chrome.devtools.panels.create('Horizon',
'',
'panel.html',
function(panel) {
}
);

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</div>
<div>
<p>Horizon dev tools!</p>
</div>
</body>
<script src="main.js"></script>
</html>

View File

@ -0,0 +1,22 @@
{
"name": "Horizon dev tool",
"description": "Horizon chrome dev extension",
"version": "1.0",
"minimum_chrome_version": "10.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"permissions": ["storage", "activeTab", "scripting"],
"devtools_page": "main.html",
"action": {},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["contentScript.js"],
"run_at": "document_start"
}
],
"web_accessible_resources": []
}

View File

@ -0,0 +1,19 @@
function ifNullThrows(v) {
if (v === null) {
throw new Error('received a null');
}
return v;
}
// 用于向页面注入脚本
export function injectCode(src) {
const script = document.createElement('script');
script.src = src;
script.onload = function () {
// 加载完毕后需要移除
script.remove();
};
ifNullThrows(document.head || document.documentElement).appendChild(script);
}

View File

@ -7,7 +7,6 @@ const config = {
injector: './src/injector/index.ts',
contentScript: './src/contentScript/index.ts',
panel: './src/panel/index.tsx',
popup: './src/popup/index.ts',
},
output: {
path: path.resolve(__dirname, './build'),