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',
|
injector: './src/injector/index.ts',
|
||||||
contentScript: './src/contentScript/index.ts',
|
contentScript: './src/contentScript/index.ts',
|
||||||
panel: './src/panel/index.tsx',
|
panel: './src/panel/index.tsx',
|
||||||
popup: './src/popup/index.ts',
|
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, './build'),
|
path: path.resolve(__dirname, './build'),
|
||||||
|
|
Loading…
Reference in New Issue