2026-01-27 17:21:32 +08:00
|
|
|
/**
|
|
|
|
|
* content script for RemotePageController
|
|
|
|
|
*/
|
|
|
|
|
import { PageController } from '@page-agent/page-controller'
|
|
|
|
|
|
|
|
|
|
export function initPageController() {
|
|
|
|
|
let pageController: PageController | null = null
|
|
|
|
|
let intervalID: number | null = null
|
|
|
|
|
|
|
|
|
|
const myTabIdPromise = chrome.runtime
|
|
|
|
|
.sendMessage({ type: 'PAGE_CONTROL', action: 'get_my_tab_id' })
|
|
|
|
|
.then((response) => {
|
|
|
|
|
return (response as { tabId: number | null }).tabId
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function getPC(): PageController {
|
|
|
|
|
if (!pageController) {
|
2026-01-28 17:16:39 +08:00
|
|
|
pageController = new PageController({ enableMask: false })
|
2026-01-27 17:21:32 +08:00
|
|
|
}
|
|
|
|
|
return pageController
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
intervalID = window.setInterval(async () => {
|
|
|
|
|
const isAgentRunning = (await chrome.storage.local.get('isAgentRunning')).isAgentRunning
|
|
|
|
|
const currentTabId = (await chrome.storage.local.get('currentTabId')).currentTabId
|
|
|
|
|
|
|
|
|
|
const shouldShowMask = isAgentRunning && currentTabId === (await myTabIdPromise)
|
|
|
|
|
|
|
|
|
|
// console.log('[RemotePageController] polling:', {
|
|
|
|
|
// isAgentRunning,
|
|
|
|
|
// currentTabId,
|
|
|
|
|
// myTabId: await myTabIdPromise,
|
|
|
|
|
// shouldShowMask,
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
if (shouldShowMask) {
|
2026-01-28 17:16:39 +08:00
|
|
|
const pc = getPC()
|
|
|
|
|
pc.initMask()
|
|
|
|
|
await pc.showMask()
|
2026-01-27 17:21:32 +08:00
|
|
|
} else {
|
|
|
|
|
// await getPC().hideMask()
|
|
|
|
|
if (pageController) {
|
|
|
|
|
pageController.hideMask()
|
2026-01-28 20:19:16 +08:00
|
|
|
pageController.cleanUpHighlights()
|
2026-01-27 17:21:32 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isAgentRunning) {
|
|
|
|
|
if (pageController) {
|
2026-01-28 20:19:16 +08:00
|
|
|
pageController.dispose()
|
2026-01-27 17:21:32 +08:00
|
|
|
pageController = null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, 1_000)
|
|
|
|
|
|
2026-01-29 18:37:42 +08:00
|
|
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse): true | undefined => {
|
2026-01-27 17:21:32 +08:00
|
|
|
if (message.type !== 'PAGE_CONTROL') {
|
2026-01-29 18:37:42 +08:00
|
|
|
// sendResponse({
|
|
|
|
|
// success: false,
|
|
|
|
|
// error: `[RemotePageController.ContentScript]: Invalid message type: ${message.type}`,
|
|
|
|
|
// })
|
2026-01-27 17:21:32 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { action, payload } = message
|
|
|
|
|
const methodName = getMethodName(action)
|
|
|
|
|
|
|
|
|
|
const pc = getPC() as any
|
|
|
|
|
|
|
|
|
|
switch (action) {
|
|
|
|
|
case 'get_last_update_time':
|
|
|
|
|
case 'get_browser_state':
|
|
|
|
|
case 'update_tree':
|
|
|
|
|
case 'clean_up_highlights':
|
|
|
|
|
case 'click_element':
|
|
|
|
|
case 'input_text':
|
|
|
|
|
case 'select_option':
|
|
|
|
|
case 'scroll':
|
|
|
|
|
case 'scroll_horizontally':
|
|
|
|
|
case 'execute_javascript':
|
|
|
|
|
pc[methodName](...(payload || []))
|
|
|
|
|
.then((result: any) => sendResponse(result))
|
|
|
|
|
.catch((error: any) =>
|
|
|
|
|
sendResponse({
|
|
|
|
|
success: false,
|
|
|
|
|
error: error instanceof Error ? error.message : String(error),
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
sendResponse({
|
|
|
|
|
success: false,
|
|
|
|
|
error: `Unknown PAGE_CONTROL action: ${action}`,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getMethodName(action: string): string {
|
|
|
|
|
switch (action) {
|
|
|
|
|
case 'get_last_update_time':
|
|
|
|
|
return 'getLastUpdateTime' as const
|
|
|
|
|
case 'get_browser_state':
|
|
|
|
|
return 'getBrowserState' as const
|
|
|
|
|
case 'update_tree':
|
|
|
|
|
return 'updateTree' as const
|
|
|
|
|
case 'clean_up_highlights':
|
|
|
|
|
return 'cleanUpHighlights' as const
|
|
|
|
|
|
|
|
|
|
// DOM actions
|
|
|
|
|
|
|
|
|
|
case 'click_element':
|
|
|
|
|
return 'clickElement' as const
|
|
|
|
|
case 'input_text':
|
|
|
|
|
return 'inputText' as const
|
|
|
|
|
case 'select_option':
|
|
|
|
|
return 'selectOption' as const
|
|
|
|
|
case 'scroll':
|
|
|
|
|
return 'scroll' as const
|
|
|
|
|
case 'scroll_horizontally':
|
|
|
|
|
return 'scrollHorizontally' as const
|
|
|
|
|
case 'execute_javascript':
|
|
|
|
|
return 'executeJavascript' as const
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return action
|
|
|
|
|
}
|
|
|
|
|
}
|