You've already forked bilibili-subtitle
优化
This commit is contained in:
@@ -2,6 +2,7 @@ import {v4} from 'uuid'
|
||||
import {handleTask, initTaskService, tasksMap} from './taskService'
|
||||
import {MESSAGE_TARGET_INJECT, MESSAGE_TO_EXTENSION_ADD_TASK, MESSAGE_TO_EXTENSION_CLOSE_SIDE_PANEL, MESSAGE_TO_EXTENSION_GET_TASK, MESSAGE_TO_EXTENSION_SHOW_FLAG, MESSAGE_TO_INJECT_TOGGLE_DISPLAY, STORAGE_ENV} from '@/consts/const'
|
||||
import ExtensionMessage from '@/messaging/ExtensionMessage'
|
||||
import { TAG_TARGET_INJECT } from '@/messaging/const'
|
||||
|
||||
const setBadgeOk = async (tabId: number, ok: boolean) => {
|
||||
await chrome.action.setBadgeText({
|
||||
@@ -114,7 +115,7 @@ chrome.action.onClicked.addListener(async (tab) => {
|
||||
})
|
||||
} else {
|
||||
closeSidePanel()
|
||||
extensionMessage.broadcastMessageExact([tab.id!], MESSAGE_TARGET_INJECT, MESSAGE_TO_INJECT_TOGGLE_DISPLAY).catch(console.error)
|
||||
extensionMessage.broadcastMessageExact([tab.id!], [TAG_TARGET_INJECT], MESSAGE_TO_INJECT_TOGGLE_DISPLAY).catch(console.error)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import { MESSAGE_TARGET_INJECT } from '@/consts/const'
|
||||
import Layer1Protocol from './Layer1Protocol'
|
||||
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_ROUTE_MSG } from './const'
|
||||
|
||||
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_HANDSHAKE, MESSAGE_TO_EXTENSION_ROUTE_MSG } from './const'
|
||||
|
||||
export type PortContext = {
|
||||
id: string
|
||||
@@ -10,68 +9,28 @@ export type PortContext = {
|
||||
portMessageHandler: Layer1Protocol
|
||||
ready: boolean
|
||||
|
||||
tabId?: number
|
||||
type?: 'inject' | 'app'
|
||||
tabId?: number // 所属tab
|
||||
tags?: string[] // 标签,用来筛选消息发送目标
|
||||
}
|
||||
|
||||
export type L2MethodHandler = (params: any, context: MethodContext, portContext: PortContext) => Promise<any>
|
||||
export type L2MethodHandlers = {
|
||||
[key: string]: L2MethodHandler
|
||||
}
|
||||
|
||||
class ExtensionMessage {
|
||||
portIdToPort: Map<string, PortContext> = new Map()
|
||||
methods?: {
|
||||
[key: string]: (params: any, context: MethodContext) => Promise<any>
|
||||
}
|
||||
methods?: L2MethodHandlers
|
||||
|
||||
debug = (...args: any[]) => {
|
||||
console.debug('[Extension Messaging]', ...args)
|
||||
}
|
||||
|
||||
init = (methods: {
|
||||
[key: string]: (params: any, context: MethodContext) => Promise<any>
|
||||
}) => {
|
||||
const innerMethods = {
|
||||
[MESSAGE_TO_EXTENSION_ROUTE_MSG]: (params: any, context: MethodContext) => {
|
||||
return this.broadcastMessageExact([context.tabId!], params.target, params.method, params.params)
|
||||
}
|
||||
}
|
||||
|
||||
this.methods = {...innerMethods, ...methods}
|
||||
|
||||
const handler = async (req: L2ReqMsg, portContext: PortContext): Promise<L2ResMsg> => {
|
||||
const { tabId } = portContext
|
||||
const method = this.methods?.[req.method]
|
||||
if (method != null) {
|
||||
return method(req.params, {
|
||||
from: req.from,
|
||||
event: req,
|
||||
tabId,
|
||||
// sender: portContext.port.sender,
|
||||
}).then(data => ({
|
||||
code: 200,
|
||||
data,
|
||||
})).catch(err => {
|
||||
console.error(err)
|
||||
return {
|
||||
code: 500,
|
||||
message: err.message,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return {
|
||||
code: 501,
|
||||
message: 'Unknown method: ' + req.method,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chrome.runtime.onConnect.addListener((port: chrome.runtime.Port) => {
|
||||
this.debug('onConnect', port)
|
||||
|
||||
const id = crypto.randomUUID()
|
||||
const name = port.name
|
||||
const portMessageHandler = new Layer1Protocol<L2ReqMsg, L2ResMsg>(async (req: L2ReqMsg) => {
|
||||
// 初始化消息
|
||||
if (req.method === '_init') {
|
||||
const type = req.params.type
|
||||
let tabId = req.params.tabId
|
||||
init = (methods: L2MethodHandlers) => {
|
||||
const innerMethods: L2MethodHandlers = {
|
||||
[MESSAGE_TO_EXTENSION_HANDSHAKE]: async (params: any, context: MethodContext, portContext: PortContext) => {
|
||||
const tags = params.tags
|
||||
let tabId = params.tabId
|
||||
|
||||
//get current tabId
|
||||
if (tabId == null) {
|
||||
@@ -83,18 +42,50 @@ class ExtensionMessage {
|
||||
}
|
||||
|
||||
portContext.tabId = tabId
|
||||
portContext.type = type
|
||||
portContext.tags = tags
|
||||
portContext.ready = true
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
} as L2ResMsg
|
||||
},
|
||||
[MESSAGE_TO_EXTENSION_ROUTE_MSG]: async (params: any, context: MethodContext) => {
|
||||
return this.broadcastMessageExact([context.tabId!], params.tags, params.method, params.params)
|
||||
},
|
||||
}
|
||||
|
||||
// 处理消息
|
||||
return handler(req, portContext)
|
||||
this.methods = { ...innerMethods, ...methods }
|
||||
|
||||
chrome.runtime.onConnect.addListener((port: chrome.runtime.Port) => {
|
||||
this.debug('onConnect', port)
|
||||
|
||||
const id = crypto.randomUUID()
|
||||
const name = port.name
|
||||
// 创建消息处理器
|
||||
const portMessageHandler = new Layer1Protocol<L2ReqMsg, L2ResMsg>(async (req: L2ReqMsg) => {
|
||||
const { tabId } = portContext
|
||||
const method = this.methods?.[req.method]
|
||||
if (method != null) {
|
||||
return method(req.params, {
|
||||
from: req.from,
|
||||
event: req,
|
||||
tabId,
|
||||
// sender: portContext.port.sender,
|
||||
}, portContext).then(data => ({
|
||||
code: 200,
|
||||
data,
|
||||
})).catch(err => {
|
||||
console.error(err)
|
||||
return {
|
||||
code: 500,
|
||||
msg: err.message,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return {
|
||||
code: 501,
|
||||
msg: 'Unknown method: ' + req.method,
|
||||
}
|
||||
}
|
||||
}, port)
|
||||
const portContext: PortContext = {id, name, port, portMessageHandler, ready: false}
|
||||
// 创建portContext
|
||||
const portContext: PortContext = { id, name, port, portMessageHandler, ready: false }
|
||||
this.portIdToPort.set(id, portContext)
|
||||
|
||||
// 监听断开连接
|
||||
@@ -105,15 +96,22 @@ class ExtensionMessage {
|
||||
})
|
||||
}
|
||||
|
||||
//tags 如果为null,则不检查tags,如果为空数组,则不会发送消息
|
||||
//返回:最后一个响应(因此如果只发送给一个tab,则返回的是该tab的响应)
|
||||
broadcastMessageExact = async (tabIds: number[], target: string, method: string, params?: any) => {
|
||||
const targetType = target === MESSAGE_TARGET_INJECT ? 'inject' : 'app'
|
||||
broadcastMessageExact = async (tabIds: number[], tags: string[] | null, method: string, params?: any) => {
|
||||
// 如果tags为空数组,则不会发送消息
|
||||
if (tags != null && tags.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
let res: L2ResMsg | undefined
|
||||
for (const portContext of this.portIdToPort.values()) {
|
||||
//check tabId
|
||||
if (tabIds.includes(portContext.tabId!)) {
|
||||
if (targetType === portContext.type) {
|
||||
//check tags
|
||||
if (tags == null || tags.some(tag => portContext.tags?.includes(tag))) {
|
||||
try {
|
||||
const req: L2ReqMsg = {target, method, params, from: 'extension'}
|
||||
const req: L2ReqMsg = { method, params, from: 'extension' }
|
||||
res = await portContext.portMessageHandler.sendMessage(req)
|
||||
} catch (e) {
|
||||
console.error('send message to port error', portContext.id, e)
|
||||
@@ -124,13 +122,13 @@ class ExtensionMessage {
|
||||
return res?.data
|
||||
}
|
||||
|
||||
broadcastMessage = async (ignoreTabIds: number[] | undefined | null, target: string, method: string, params?: any) => {
|
||||
broadcastMessage = async (ignoreTabIds: number[] | undefined | null, tags: string[], method: string, params?: any) => {
|
||||
const tabs = await chrome.tabs.query({
|
||||
discarded: false,
|
||||
})
|
||||
const tabIds: number[] = tabs.map(tab => tab.id).filter(tabId => tabId != null) as number[]
|
||||
const filteredTabIds: number[] = tabIds.filter(tabId => !ignoreTabIds?.includes(tabId))
|
||||
await this.broadcastMessageExact(filteredTabIds, target, method, params)
|
||||
await this.broadcastMessageExact(filteredTabIds, tags, method, params)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { MESSAGE_TARGET_APP, MESSAGE_TARGET_EXTENSION, MESSAGE_TARGET_INJECT } from '@/consts/const'
|
||||
import Layer1Protocol from './Layer1Protocol'
|
||||
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_ROUTE_MSG } from './const'
|
||||
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_HANDSHAKE, MESSAGE_TO_EXTENSION_ROUTE_MSG, TAG_TARGET_APP, TAG_TARGET_INJECT } from './const'
|
||||
|
||||
class InjectMessage {
|
||||
port?: chrome.runtime.Port
|
||||
@@ -18,11 +18,11 @@ class InjectMessage {
|
||||
this.debug(`${req.from} => `, JSON.stringify(req))
|
||||
|
||||
// check event target
|
||||
if (req.target !== MESSAGE_TARGET_INJECT) return Promise.resolve({
|
||||
success: false,
|
||||
code: 501,
|
||||
message: 'Target Error: ' + req.target,
|
||||
})
|
||||
// if (req.target !== MESSAGE_TARGET_INJECT) return Promise.resolve({
|
||||
// success: false,
|
||||
// code: 501,
|
||||
// message: 'Target Error: ' + req.target,
|
||||
// })
|
||||
|
||||
const method = this.methods?.[req.method]
|
||||
if (method != null) {
|
||||
@@ -38,23 +38,23 @@ class InjectMessage {
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error(err)
|
||||
let message
|
||||
let msg
|
||||
if (err instanceof Error) {
|
||||
message = err.message
|
||||
msg = err.message
|
||||
} else if (typeof err === 'string') {
|
||||
message = err
|
||||
msg = err
|
||||
} else {
|
||||
message = 'error: ' + JSON.stringify(err)
|
||||
msg = 'error: ' + JSON.stringify(err)
|
||||
}
|
||||
return {
|
||||
code: 500,
|
||||
message,
|
||||
msg,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return {
|
||||
code: 501,
|
||||
message: 'Unknown method: ' + req.method,
|
||||
msg: 'Unknown method: ' + req.method,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,26 +69,24 @@ class InjectMessage {
|
||||
this.portMessageHandler = new Layer1Protocol<L2ReqMsg, L2ResMsg>(this.messageHandler, this.port)
|
||||
this.portMessageHandler.sendMessage({
|
||||
from: 'inject',
|
||||
target: MESSAGE_TARGET_EXTENSION,
|
||||
method: '_init',
|
||||
method: MESSAGE_TO_EXTENSION_HANDSHAKE,
|
||||
params: {
|
||||
type: 'inject',
|
||||
tags: [TAG_TARGET_INJECT],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
sendExtension = async <T = any>(method: string, params?: any): Promise<T> => {
|
||||
const req: L2ReqMsg = {
|
||||
return await this.portMessageHandler!.sendMessage({
|
||||
from: 'inject',
|
||||
target: MESSAGE_TARGET_EXTENSION,
|
||||
method,
|
||||
params: params ?? {},
|
||||
}
|
||||
return await this.portMessageHandler!.sendMessage(req).then((res) => {
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
return res.data as T
|
||||
} else {
|
||||
throw new Error(res.message)
|
||||
throw new Error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -98,7 +96,7 @@ class InjectMessage {
|
||||
console.log('sendApp>>>', method, params)
|
||||
}
|
||||
return this.sendExtension(MESSAGE_TO_EXTENSION_ROUTE_MSG, {
|
||||
target: MESSAGE_TARGET_APP,
|
||||
tags: [TAG_TARGET_APP],
|
||||
method,
|
||||
params,
|
||||
})
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// 请求信息
|
||||
export type L2ReqMsg = {
|
||||
from: 'extension' | 'inject' | 'app'
|
||||
target: string
|
||||
// target: string
|
||||
method: string
|
||||
params?: any
|
||||
// [key: string]: any
|
||||
@@ -10,8 +10,12 @@ export type L2ReqMsg = {
|
||||
// 响应信息
|
||||
export type L2ResMsg<L2Res = any> = {
|
||||
code: number
|
||||
message?: string
|
||||
msg?: string
|
||||
data?: L2Res
|
||||
}
|
||||
|
||||
export const MESSAGE_TO_EXTENSION_HANDSHAKE = 'handshake'
|
||||
export const MESSAGE_TO_EXTENSION_ROUTE_MSG = 'routeMsg'
|
||||
|
||||
export const TAG_TARGET_INJECT = 'target:inject'
|
||||
export const TAG_TARGET_APP = 'target:app'
|
||||
|
@@ -2,7 +2,7 @@ import { MESSAGE_TARGET_EXTENSION, MESSAGE_TARGET_INJECT } from '@/consts/const'
|
||||
import { injectWaiter } from './useMessageService'
|
||||
import { useCallback } from 'react'
|
||||
import Layer1Protocol from './Layer1Protocol'
|
||||
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_ROUTE_MSG } from './const'
|
||||
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_ROUTE_MSG, TAG_TARGET_INJECT } from './const'
|
||||
|
||||
const useMessage = () => {
|
||||
const sendExtension = useCallback(async <T = any>(method: string, params?: any) => {
|
||||
@@ -11,20 +11,19 @@ const useMessage = () => {
|
||||
// send message
|
||||
const res = await pmh.sendMessage({
|
||||
from: 'app',
|
||||
target: MESSAGE_TARGET_EXTENSION,
|
||||
method,
|
||||
params: params ?? {},
|
||||
})
|
||||
if (res.code === 200) {
|
||||
return res.data as T
|
||||
} else {
|
||||
throw new Error(res.message)
|
||||
throw new Error(res.msg)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const sendInject = useCallback(async <T = any>(method: string, params?: any): Promise<T> => {
|
||||
return await sendExtension(MESSAGE_TO_EXTENSION_ROUTE_MSG, {
|
||||
target: MESSAGE_TARGET_INJECT,
|
||||
tags: [TAG_TARGET_INJECT],
|
||||
method,
|
||||
params: params ?? {},
|
||||
})
|
||||
|
@@ -4,7 +4,7 @@ import {
|
||||
} from '@/consts/const'
|
||||
import { Waiter } from '@kky002/kky-util'
|
||||
import Layer1Protocol from './Layer1Protocol'
|
||||
import { L2ReqMsg, L2ResMsg } from './const'
|
||||
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_HANDSHAKE, TAG_TARGET_APP } from './const'
|
||||
|
||||
const debug = (...args: any[]) => {
|
||||
console.debug('[App Messaging]', ...args)
|
||||
@@ -25,11 +25,11 @@ const useMessageService = (methods?: {
|
||||
const messageHandler = useCallback(async (req: L2ReqMsg): Promise<L2ResMsg> => {
|
||||
debug(`${req.from} => `, JSON.stringify(req))
|
||||
|
||||
// check event target
|
||||
if (req.target !== MESSAGE_TARGET_APP) return {
|
||||
code: 501,
|
||||
message: 'Target Error: ' + req.target,
|
||||
}
|
||||
// // check event target
|
||||
// if (req.target !== MESSAGE_TARGET_APP) return {
|
||||
// code: 501,
|
||||
// msg: 'Target Error: ' + req.target,
|
||||
// }
|
||||
|
||||
const method = methods?.[req.method]
|
||||
if (method != null) {
|
||||
@@ -44,23 +44,23 @@ const useMessageService = (methods?: {
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error(err)
|
||||
let message
|
||||
let msg
|
||||
if (err instanceof Error) {
|
||||
message = err.message
|
||||
msg = err.message
|
||||
} else if (typeof err === 'string') {
|
||||
message = err
|
||||
msg = err
|
||||
} else {
|
||||
message = 'error: ' + JSON.stringify(err)
|
||||
msg = 'error: ' + JSON.stringify(err)
|
||||
}
|
||||
return {
|
||||
code: 500,
|
||||
message,
|
||||
msg,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return {
|
||||
code: 501,
|
||||
message: 'Unknown method: ' + req.method,
|
||||
msg: 'Unknown method: ' + req.method,
|
||||
}
|
||||
}
|
||||
}, [methods])
|
||||
@@ -79,12 +79,13 @@ const useMessageService = (methods?: {
|
||||
let tabId = tabIdStr ? parseInt(tabIdStr) : undefined
|
||||
// 初始化
|
||||
pmh.sendMessage({
|
||||
method: '_init',
|
||||
from: 'app',
|
||||
method: MESSAGE_TO_EXTENSION_HANDSHAKE,
|
||||
params: {
|
||||
type: 'app',
|
||||
tabId,
|
||||
tags: [TAG_TARGET_APP],
|
||||
},
|
||||
} as L2ReqMsg)
|
||||
})
|
||||
portMessageHandlerInit = true
|
||||
|
||||
return pmh
|
||||
|
Reference in New Issue
Block a user