!44 [inula-dev-tools]<feat> 与 chrome 建立消息链接
Merge pull request !44 from 涂旭辉/master
This commit is contained in:
commit
8bb67e9be2
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import { DevToolBackground, DevToolContentScript, DevToolPanel } from '../utils/constants';
|
||||
import { connections } from './index';
|
||||
import { packagePayload } from '../utils/transferUtils';
|
||||
|
||||
// 监听来自 content script 的消息,并将消息发送给对应的 dev tools page
|
||||
const eventsPerTab = {};
|
||||
const storesPerTab = {};
|
||||
const observedComponents = {};
|
||||
const eventPersistencePerTab = {};
|
||||
let idGenerator = 1;
|
||||
|
||||
// 当 tab 重新加载,需要对该 tab 所监听的 stores 进行重置
|
||||
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo) {
|
||||
if (changeInfo.status === 'loading') {
|
||||
if (!eventPersistencePerTab[tabId]) {
|
||||
eventsPerTab[tabId] = [];
|
||||
}
|
||||
storesPerTab[tabId] = [];
|
||||
}
|
||||
});
|
||||
|
||||
function sendTo(connectionId, message) {
|
||||
if (connections[connectionId]) {
|
||||
connections[connectionId].postMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
function requestObservedComponents(tabId) {
|
||||
setTimeout(() => {
|
||||
chrome.tabs.sendMessage(
|
||||
tabId,
|
||||
packagePayload(
|
||||
{
|
||||
type: 'inulax request observed components',
|
||||
data: {}
|
||||
},
|
||||
'dev tool background'
|
||||
)
|
||||
);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
function executeAction(tabId, storeId, action, params) {
|
||||
chrome.tabs.sendMessage(
|
||||
tabId,
|
||||
packagePayload(
|
||||
{
|
||||
type: 'inulax execute action',
|
||||
data: {
|
||||
action,
|
||||
storeId,
|
||||
params,
|
||||
}
|
||||
},
|
||||
'dev tool background'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function queueAction(tabId, storeId, action, params) {
|
||||
chrome.tabs.sendMessage(
|
||||
tabId,
|
||||
packagePayload(
|
||||
{
|
||||
type: 'inulax queue action',
|
||||
data: {
|
||||
action,
|
||||
storeId,
|
||||
params,
|
||||
}
|
||||
},
|
||||
'sev tool background'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getObservedComponents(storeId, tabId) {
|
||||
if (!observedComponents[tabId]) {
|
||||
observedComponents[tabId] = {};
|
||||
}
|
||||
if (!observedComponents[tabId][storeId]) {
|
||||
return [];
|
||||
}
|
||||
return observedComponents[tabId][storeId];
|
||||
}
|
||||
|
||||
// 来自 content script 的消息
|
||||
chrome.runtime.onMessage.addListener(function (message, sender) {
|
||||
if (message.payload.type.startsWith('inulax')) {
|
||||
console.log('inulaXHandler message from content script', {
|
||||
payload: { ...message.payload },
|
||||
});
|
||||
|
||||
if (message.from === DevToolContentScript && sender.tab?.id) {
|
||||
if (message.payload.type === 'inulax observed components') {
|
||||
observedComponents[sender.tab.id] = message.payload.data;
|
||||
|
||||
sendTo(sender.tab.id, {
|
||||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax observed components',
|
||||
data: message.payload.data,
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
return;
|
||||
}
|
||||
requestObservedComponents(sender.tab.id);
|
||||
|
||||
// content script -> inulaXHandler
|
||||
if (!eventsPerTab[sender.tab.id]) {
|
||||
eventsPerTab[sender.tab.id] = [];
|
||||
}
|
||||
eventsPerTab[sender.tab.id].push({
|
||||
id: idGenerator++,
|
||||
timestamp: Date.now(),
|
||||
message: message.payload,
|
||||
});
|
||||
|
||||
sendTo(sender.tab.id, {
|
||||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax events',
|
||||
events: eventsPerTab[sender.tab.id],
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
|
||||
// 如果当前 tab 没有 store data,则初始化
|
||||
if (!storesPerTab[sender.tab.id]) {
|
||||
storesPerTab[sender.tab.id] = [];
|
||||
}
|
||||
|
||||
let found = false;
|
||||
storesPerTab[sender.tab.id]?.some((store, index) => {
|
||||
if (store.id === message.payload.data.store.id) {
|
||||
found = true;
|
||||
storesPerTab[sender.tab!.id!][index] = message.payload.data.store;
|
||||
requestObservedComponents(sender.tab?.id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
const tabId = sender.tab.id;
|
||||
if (!storesPerTab[tabId]) {
|
||||
storesPerTab[tabId] = [];
|
||||
}
|
||||
storesPerTab[tabId].push(message.payload.data.store);
|
||||
sendTo(tabId, {
|
||||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax stores',
|
||||
stores: storesPerTab[tabId]?.map(store => {
|
||||
// 连接被监测的组件
|
||||
requestObservedComponents(tabId);
|
||||
const observedComponents = getObservedComponents(store, tabId);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
newStore: message.payload.data.store.id,
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
sendTo(sender.tab.id, {
|
||||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax stores',
|
||||
stores: storesPerTab[sender.tab.id]?.map(store => {
|
||||
// 连接被监测的组件
|
||||
const observedComponents = getObservedComponents(store, sender.tab?.id);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
updated: message.payload.data.store.id,
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
|
||||
requestObservedComponents(message.payload.tabId);
|
||||
}
|
||||
|
||||
if (message.from === DevToolPanel) {
|
||||
// panel -> inulaXHandler
|
||||
if (message.payload.type === 'inulax run action') {
|
||||
executeAction(
|
||||
message.payload.tabId,
|
||||
message.payload.storeId,
|
||||
message.payload.action,
|
||||
message.payload.args
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inulax change state') {
|
||||
chrome.tabs.sendMessage(
|
||||
message.payload.tabId,
|
||||
packagePayload(message.payload, 'dev tool background')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inulax queue action') {
|
||||
queueAction(
|
||||
message.payload.tabId,
|
||||
message.payload.storeId,
|
||||
message.payload.action,
|
||||
message.payload.args
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inulax resetEvents') {
|
||||
eventsPerTab[message.payload.tabId] = [];
|
||||
sendTo(message.payload.tabId, {
|
||||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax events',
|
||||
events: eventsPerTab[message.payload.tabId],
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inula setPersistent'){
|
||||
const { tabId, persistent } = message.payload;
|
||||
eventPersistencePerTab[tabId] = persistent;
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inulax getPersistence') {
|
||||
sendTo(message.payload.tabId, {
|
||||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax persistence',
|
||||
persistent: !!eventPersistencePerTab[message.payload.tabId],
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inulax getEvents') {
|
||||
if (!eventsPerTab[message.payload.tabId]) {
|
||||
eventsPerTab[message.payload.tabId] = [];
|
||||
}
|
||||
sendTo(message.payload.tabId, {
|
||||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax events',
|
||||
events: eventsPerTab[message.payload.tabId],
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inulax getStores') {
|
||||
sendTo(message.payload.tabId, {
|
||||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax stores',
|
||||
stores: storesPerTab[message.payload.tabId]?.map(store => {
|
||||
requestObservedComponents(message.payload.tabId);
|
||||
const observedComponents = getObservedComponents(
|
||||
store.id,
|
||||
message.payload.tabId
|
||||
);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue