Match-id-6411a05fa00c9702c38999dd426b0cd28346f65a
This commit is contained in:
parent
59e00b336a
commit
548c3b6172
|
@ -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;
|
||||
});
|
|
@ -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}, '*');
|
||||
}
|
||||
}
|
||||
);
|
|
@ -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();
|
|
@ -0,0 +1,7 @@
|
|||
chrome.devtools.panels.create('Horizon',
|
||||
'',
|
||||
'panel.html',
|
||||
function(panel) {
|
||||
|
||||
}
|
||||
);
|
|
@ -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>
|
|
@ -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": []
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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'),
|
||||
|
|
Loading…
Reference in New Issue