Commit ac39b82b authored by Domi's avatar Domi

fix: offscreen service

parent 7f03fb1b
...@@ -5,7 +5,11 @@ import { ...@@ -5,7 +5,11 @@ import {
ContentScriptId, ContentScriptId,
} from "@/types" } from "@/types"
import { waitMessage, tabUpdated, getLocal, getPipWindow } from "@/utils/ext" import { waitMessage, tabUpdated, getLocal, getPipWindow } from "@/utils/ext"
import { setupOffscreenDocument, offscreenHtmlPath } from "./offscreen" import {
createOffscreenDocument,
offscreenHtmlPath,
setupOffscreen,
} from "./offscreen"
import { import {
registerContentSidebar, registerContentSidebar,
unregisterContentSidebar, unregisterContentSidebar,
...@@ -14,7 +18,7 @@ import { ...@@ -14,7 +18,7 @@ import {
import config from "@/assets/config.json" import config from "@/assets/config.json"
import { allFrameScript, contentMainScript } from "@/manifest" import { allFrameScript, contentMainScript } from "@/manifest"
import { getIsEdge } from "@/utils/ext" import { getIsEdge } from "@/utils/ext"
import { contentInvoke } from "@/utils/invoke" import { messageInvoke } from "@/utils/invoke"
type Config = typeof config type Config = typeof config
...@@ -81,10 +85,8 @@ async function updateWindow({ windowId, windowInfo }: UpdatePipWinOption) { ...@@ -81,10 +85,8 @@ async function updateWindow({ windowId, windowInfo }: UpdatePipWinOption) {
let currentSender: chrome.runtime.MessageSender | null = null let currentSender: chrome.runtime.MessageSender | null = null
contentInvoke messageInvoke
.register(ServiceFunc.setupOffscreen, () => .register(ServiceFunc.setupOffscreen, () => setupOffscreen())
setupOffscreenDocument(offscreenHtmlPath)
)
.register(ServiceFunc.getAllCommands, () => chrome.commands.getAll()) .register(ServiceFunc.getAllCommands, () => chrome.commands.getAll())
.register(ServiceFunc.createTab, (p: chrome.tabs.CreateProperties) => .register(ServiceFunc.createTab, (p: chrome.tabs.CreateProperties) =>
chrome.tabs.create(p) chrome.tabs.create(p)
...@@ -99,7 +101,7 @@ async function handleInvokeRequest( ...@@ -99,7 +101,7 @@ async function handleInvokeRequest(
sender: chrome.runtime.MessageSender sender: chrome.runtime.MessageSender
) { ) {
currentSender = sender currentSender = sender
let result = await contentInvoke.handleReqMsg(message) let result = await messageInvoke.handleReqMsg(message)
if (!sender.tab?.id) { if (!sender.tab?.id) {
console.error("sender tab id is undefined", sender) console.error("sender tab id is undefined", sender)
...@@ -134,6 +136,9 @@ function handleMessage(message: any, sender: chrome.runtime.MessageSender) { ...@@ -134,6 +136,9 @@ function handleMessage(message: any, sender: chrome.runtime.MessageSender) {
case MessageType.invokeRequest: case MessageType.invokeRequest:
handleInvokeRequest(message, sender) handleInvokeRequest(message, sender)
break break
case MessageType.invokeResponse:
messageInvoke.handleResMsg(message)
break
case MessageType.contentMounted: case MessageType.contentMounted:
handleContentMounted(sender.tab!.id!) handleContentMounted(sender.tab!.id!)
break break
...@@ -154,7 +159,7 @@ async function handleToggleMinimize() { ...@@ -154,7 +159,7 @@ async function handleToggleMinimize() {
const tabId = pipWindow.tabId const tabId = pipWindow.tabId
contentInvoke.invoke({ messageInvoke.invoke({
tabId, tabId,
func: ServiceFunc.toggleMinimize, func: ServiceFunc.toggleMinimize,
args: [], args: [],
......
import { ServiceFunc } from "@/types"
import { messageInvoke } from "@/utils/invoke"
let creating: Promise<void> | null // A global promise to avoid concurrency issues let creating: Promise<void> | null // A global promise to avoid concurrency issues
export async function setupOffscreenDocument(path: string) { export async function createOffscreenDocument(path: string) {
// Check all windows controlled by the service worker to see if one // Check all windows controlled by the service worker to see if one
// of them is the offscreen document with the given path // of them is the offscreen document with the given path
const offscreenUrl = chrome.runtime.getURL(path) const offscreenUrl = chrome.runtime.getURL(path)
...@@ -34,3 +37,12 @@ export async function setupOffscreenDocument(path: string) { ...@@ -34,3 +37,12 @@ export async function setupOffscreenDocument(path: string) {
} }
export const offscreenHtmlPath = "/offscreen.html" export const offscreenHtmlPath = "/offscreen.html"
export async function setupOffscreen() {
await createOffscreenDocument(offscreenHtmlPath)
await messageInvoke.invoke({
key: ServiceFunc.waitOffscreen,
func: ServiceFunc.waitOffscreen,
args: [],
})
}
...@@ -12,7 +12,7 @@ import { useI18n } from "@/utils/i18n" ...@@ -12,7 +12,7 @@ import { useI18n } from "@/utils/i18n"
import IconHide from "./icons/IconHide.vue" import IconHide from "./icons/IconHide.vue"
import { pip } from "@/content/pip" import { pip } from "@/content/pip"
import { getPageIcon } from "@/utils/dom" import { getPageIcon } from "@/utils/dom"
import { contentInvoke } from "@/utils/invoke" import { messageInvoke } from "@/utils/invoke"
import IconKeyboard from "@/components/icons/IconKeyboard.vue" import IconKeyboard from "@/components/icons/IconKeyboard.vue"
import IconEdit from "@/components/icons/IconEdit.vue" import IconEdit from "@/components/icons/IconEdit.vue"
...@@ -68,7 +68,7 @@ watch(isMinimized, (value) => { ...@@ -68,7 +68,7 @@ watch(isMinimized, (value) => {
} }
sheet.disabled = !value sheet.disabled = !value
contentInvoke.getAllCommands().then((commands) => { messageInvoke.getAllCommands().then((commands) => {
const command = commands.find((c) => c.name == "toggleMinimize") const command = commands.find((c) => c.name == "toggleMinimize")
if (command) { if (command) {
toggleMinimizeCommand.value = command toggleMinimizeCommand.value = command
...@@ -83,7 +83,7 @@ onMounted(() => { ...@@ -83,7 +83,7 @@ onMounted(() => {
pipWindow.window?.addEventListener("resize", updateWindowInfo) pipWindow.window?.addEventListener("resize", updateWindowInfo)
updateWindowInfo() updateWindowInfo()
contentInvoke.register(ServiceFunc.toggleMinimize, () => { messageInvoke.register(ServiceFunc.toggleMinimize, () => {
console.log("invoke toggleMinimize") console.log("invoke toggleMinimize")
toggleMinimize() toggleMinimize()
}) })
...@@ -254,7 +254,7 @@ const handleEditCommand = (e: MouseEvent) => { ...@@ -254,7 +254,7 @@ const handleEditCommand = (e: MouseEvent) => {
e.stopPropagation() e.stopPropagation()
const desc = chrome.i18n.getMessage("toggle_minimize_desc") const desc = chrome.i18n.getMessage("toggle_minimize_desc")
const text = encodeURIComponent(desc) const text = encodeURIComponent(desc)
contentInvoke.createTab({ messageInvoke.createTab({
url: `chrome://extensions/shortcuts#:~:text=${text}`, url: `chrome://extensions/shortcuts#:~:text=${text}`,
}) })
} }
......
<script setup lang="ts"> <script setup lang="ts">
import { watch, computed, reactive, ref, onMounted, watchEffect } from "vue" import { watch, computed, reactive, ref, onMounted, watchEffect } from "vue"
import { chatDocsPanel } from "@/store/content" import { chatDocsPanel } from "@/store/content"
import { contentInvoke } from "@/utils/invoke" import { messageInvoke } from "@/utils/invoke"
import { convertBlobToBase64, semanticClip } from "@/utils/utils" import { convertBlobToBase64, semanticClip } from "@/utils/utils"
import ScrollView from "@/components/ScrollView.vue" import ScrollView from "@/components/ScrollView.vue"
import IconArrowBack from "@/components/icons/IconArrowBack.vue" import IconArrowBack from "@/components/icons/IconArrowBack.vue"
...@@ -126,8 +126,8 @@ watch( ...@@ -126,8 +126,8 @@ watch(
if (maxInputType !== "token") return if (maxInputType !== "token") return
if (!message) return if (!message) return
await contentInvoke.setupOffscreen() await messageInvoke.setupOffscreen()
const tokenLength = await contentInvoke.calcTokens(message) const tokenLength = await messageInvoke.calcTokens(message)
const rate = (message.length / tokenLength) * 0.95 const rate = (message.length / tokenLength) * 0.95
const exceedMaxInput = tokenLength > maxInput const exceedMaxInput = tokenLength > maxInput
if (exceedMaxInput) { if (exceedMaxInput) {
...@@ -173,8 +173,8 @@ watch( ...@@ -173,8 +173,8 @@ watch(
if (item.kind == "file" && typeof item.data != "string") { if (item.kind == "file" && typeof item.data != "string") {
const url = await convertBlobToBase64(item.data) const url = await convertBlobToBase64(item.data)
await contentInvoke.setupOffscreen() await messageInvoke.setupOffscreen()
const results = await contentInvoke.parseDoc({ const results = await messageInvoke.parseDoc({
key: item.key, key: item.key,
type: item.type, type: item.type,
size: item.data.size, size: item.data.size,
......
...@@ -6,7 +6,7 @@ import IconArrowCircleRight from "@/components/icons/IconArrowCircleRight.vue" ...@@ -6,7 +6,7 @@ import IconArrowCircleRight from "@/components/icons/IconArrowCircleRight.vue"
import IconClose from "@/components/icons/IconClose.vue" import IconClose from "@/components/icons/IconClose.vue"
import { MessageType, ServiceFunc } from "@/types" import { MessageType, ServiceFunc } from "@/types"
import { computed } from "vue" import { computed } from "vue"
import { contentInvoke } from "@/utils/invoke" import { messageInvoke } from "@/utils/invoke"
import { handleImgError } from "@/utils/dom" import { handleImgError } from "@/utils/dom"
const globeImg = chrome.runtime.getURL("img/globe.svg") const globeImg = chrome.runtime.getURL("img/globe.svg")
...@@ -20,7 +20,7 @@ const isMinimized = computed(() => { ...@@ -20,7 +20,7 @@ const isMinimized = computed(() => {
}) })
async function toggleMinimize() { async function toggleMinimize() {
await contentInvoke.invoke({ await messageInvoke.invoke({
tabId: pipWindow.tabId, tabId: pipWindow.tabId,
func: ServiceFunc.toggleMinimize, func: ServiceFunc.toggleMinimize,
args: [], args: [],
......
...@@ -20,7 +20,7 @@ import { ...@@ -20,7 +20,7 @@ import {
addContentEventListener, addContentEventListener,
removeContentEventListener, removeContentEventListener,
} from "@/content/event" } from "@/content/event"
import { contentInvoke } from "@/utils/invoke" import { messageInvoke } from "@/utils/invoke"
import { getPageIcon } from "@/utils/dom" import { getPageIcon } from "@/utils/dom"
// import { PipEventName } from "@/types/pip" // import { PipEventName } from "@/types/pip"
...@@ -47,7 +47,7 @@ function handleMessage( ...@@ -47,7 +47,7 @@ function handleMessage(
sendResponse({ type: MessageType.contentHere }) sendResponse({ type: MessageType.contentHere })
break break
case MessageType.invokeResponse: case MessageType.invokeResponse:
contentInvoke.handleResMsg(message) messageInvoke.handleResMsg(message)
break break
case MessageType.showChatDocs: case MessageType.showChatDocs:
chatDocsPanel.visible = true chatDocsPanel.visible = true
...@@ -58,7 +58,7 @@ function handleMessage( ...@@ -58,7 +58,7 @@ function handleMessage(
sidebarAddon.url = message.url sidebarAddon.url = message.url
break break
case MessageType.invokeRequest: case MessageType.invokeRequest:
contentInvoke.handleReqMsg(message).then((result) => { messageInvoke.handleReqMsg(message).then((result) => {
if (result) { if (result) {
chrome.runtime.sendMessage({ chrome.runtime.sendMessage({
type: MessageType.invokeResponse, type: MessageType.invokeResponse,
...@@ -95,7 +95,7 @@ async function handlePipEvent(event: any) { ...@@ -95,7 +95,7 @@ async function handlePipEvent(event: any) {
addContentEventListener(ContentEventType.pipLoaded, handlePipLoaded) addContentEventListener(ContentEventType.pipLoaded, handlePipLoaded)
}) })
const window = await contentInvoke.invoke({ const window = await messageInvoke.invoke({
func: ServiceFunc.getPipWindow, func: ServiceFunc.getPipWindow,
args: [ args: [
{ {
...@@ -105,7 +105,7 @@ async function handlePipEvent(event: any) { ...@@ -105,7 +105,7 @@ async function handlePipEvent(event: any) {
], ],
}) })
const tab = await contentInvoke.invoke({ const tab = await messageInvoke.invoke({
func: ServiceFunc.getMyTab, func: ServiceFunc.getMyTab,
args: [], args: [],
}) })
......
...@@ -6,7 +6,7 @@ import TurndownService from "turndown" ...@@ -6,7 +6,7 @@ import TurndownService from "turndown"
import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types" import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types"
import { Tiktoken } from "tiktoken/lite" import { Tiktoken } from "tiktoken/lite"
import cl100k_base from "tiktoken/encoders/cl100k_base.json" import cl100k_base from "tiktoken/encoders/cl100k_base.json"
import { contentInvoke } from "@/utils/invoke" import { messageInvoke } from "@/utils/invoke"
pdfjs.GlobalWorkerOptions.workerSrc = "/js/pdf.worker.js" pdfjs.GlobalWorkerOptions.workerSrc = "/js/pdf.worker.js"
...@@ -104,8 +104,11 @@ async function handleMessage( ...@@ -104,8 +104,11 @@ async function handleMessage(
) { ) {
console.log("offscreen message: ", message, sender) console.log("offscreen message: ", message, sender)
if (message?.type === MessageType.invokeRequest) { if (message?.type === MessageType.invokeRequest) {
const result = await contentInvoke.handleReqMsg(message) const result = await messageInvoke.handleReqMsg(message)
if (result) { if (!result) {
return
}
if (sender.tab?.id) {
chrome.runtime.sendMessage({ chrome.runtime.sendMessage({
type: MessageType.forwardToTab, type: MessageType.forwardToTab,
tabId: sender.tab?.id, tabId: sender.tab?.id,
...@@ -114,17 +117,30 @@ async function handleMessage( ...@@ -114,17 +117,30 @@ async function handleMessage(
...result, ...result,
}, },
}) })
} else {
chrome.runtime.sendMessage({
type: MessageType.invokeResponse,
...result,
})
} }
} }
} }
contentInvoke messageInvoke
.register(ServiceFunc.parseDoc, parseDoc) .register(ServiceFunc.parseDoc, parseDoc)
.register(ServiceFunc.calcTokens, calcTokens) .register(ServiceFunc.calcTokens, calcTokens)
.register(ServiceFunc.tokenSlice, tokenSlice) .register(ServiceFunc.tokenSlice, tokenSlice)
.register(ServiceFunc.waitOffscreen, () => Promise.resolve())
chrome.runtime.onMessage.addListener(handleMessage) chrome.runtime.onMessage.addListener(handleMessage)
chrome.runtime.sendMessage({
type: MessageType.invokeResponse,
key: ServiceFunc.waitOffscreen,
success: true,
value: null,
})
// for testing purposes // for testing purposes
document.onclick = () => { document.onclick = () => {
console.log("CLICK") console.log("CLICK")
......
...@@ -4,7 +4,7 @@ import { createApp } from "vue" ...@@ -4,7 +4,7 @@ import { createApp } from "vue"
import Popup from "./Popup.vue" import Popup from "./Popup.vue"
import { i18n } from "@/utils/i18n" import { i18n } from "@/utils/i18n"
import { MessageType } from "@/types" import { MessageType } from "@/types"
import { contentInvoke } from "@/utils/invoke" import { messageInvoke } from "@/utils/invoke"
const app = createApp(Popup) const app = createApp(Popup)
...@@ -14,7 +14,7 @@ app.mount("#app") ...@@ -14,7 +14,7 @@ app.mount("#app")
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
switch (message.type) { switch (message.type) {
case MessageType.invokeResponse: case MessageType.invokeResponse:
contentInvoke.handleResMsg(message) messageInvoke.handleResMsg(message)
break break
} }
}) })
...@@ -32,6 +32,7 @@ export enum ServiceFunc { ...@@ -32,6 +32,7 @@ export enum ServiceFunc {
toggleMinimize = "toggle-minimize", toggleMinimize = "toggle-minimize",
getPipWindow = "get-pip-window", getPipWindow = "get-pip-window",
getMyTab = "get-my-tab", getMyTab = "get-my-tab",
waitOffscreen = "wait-offscreen",
} }
export type ParseDocOptions = { export type ParseDocOptions = {
......
import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types" import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types"
import Invoke, { type InvokeReq } from "./Invoke" import Invoke, { type InvokeReq } from "./Invoke"
class ContentInvoke extends Invoke { class MessageInvoke extends Invoke {
public async send(req: InvokeReq & { tabId?: number }) { public async send(req: InvokeReq & { tabId?: number }) {
const key = this.key const key = req.key || this.key
if (req.tabId) { if (req.tabId) {
chrome.tabs.sendMessage(req.tabId, { chrome.tabs.sendMessage(req.tabId, {
...@@ -74,6 +74,6 @@ class ContentInvoke extends Invoke { ...@@ -74,6 +74,6 @@ class ContentInvoke extends Invoke {
} }
} }
const contentInvoke = new ContentInvoke("content") const messageInvoke = new MessageInvoke("content")
export { ContentInvoke, contentInvoke } export { MessageInvoke, messageInvoke }
export { Invoke } from "./Invoke" export { Invoke } from "./Invoke"
export { ContentInvoke, contentInvoke } from "./ContentInvoke" export { MessageInvoke, messageInvoke } from "./MessageInvoke"
export { WebviewInvoke } from "./WebviewInvoke" export { WebviewInvoke } from "./WebviewInvoke"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment