diff --git a/src/background/index.mjs b/src/background/index.mjs
index 8e245b2..b767c40 100644
--- a/src/background/index.mjs
+++ b/src/background/index.mjs
@@ -16,7 +16,7 @@ import {
gptApiModelKeys,
} from '../config/index.mjs'
import { isSafari } from '../utils/is-safari'
-import { isFirefox } from '../utils/is-firefox'
+import { config as menuConfig } from '../content-script/menu-tools'
const KEY_ACCESS_TOKEN = 'accessToken'
const cache = new ExpiryMap(10 * 1000)
@@ -107,41 +107,58 @@ Browser.runtime.onMessage.addListener(async (message) => {
}
})
-Browser.contextMenus.removeAll().then(() => {
- const menuId = 'ChatGPTBox-Menu'
- Browser.contextMenus.create({
- id: menuId,
- title: 'ChatGPTBox',
- contexts: ['all'],
- })
-
- Browser.contextMenus.create({
- id: menuId + 'new',
- parentId: menuId,
- title: 'New Chat',
- contexts: [isFirefox() ? 'all' : 'selection'],
- })
- for (const index in defaultConfig.selectionTools) {
- const key = defaultConfig.selectionTools[index]
- const desc = defaultConfig.selectionToolsDesc[index]
+function refreshMenu() {
+ Browser.contextMenus.removeAll().then(() => {
+ const menuId = 'ChatGPTBox-Menu'
Browser.contextMenus.create({
- id: menuId + key,
- parentId: menuId,
- title: desc,
- contexts: ['selection'],
+ id: menuId,
+ title: 'ChatGPTBox',
+ contexts: ['all'],
})
- }
- Browser.contextMenus.onClicked.addListener((info, tab) => {
- const itemId = info.menuItemId === menuId ? 'new' : info.menuItemId.replace(menuId, '')
- const message = {
- itemId: itemId,
- selectionText: info.selectionText,
+ for (const [k, v] of Object.entries(menuConfig)) {
+ Browser.contextMenus.create({
+ id: menuId + k,
+ parentId: menuId,
+ title: v.label,
+ contexts: ['all'],
+ })
}
- console.debug('menu clicked', message)
- Browser.tabs.sendMessage(tab.id, {
- type: 'MENU',
- data: message,
+ Browser.contextMenus.create({
+ id: menuId + 'separator1',
+ parentId: menuId,
+ contexts: ['selection'],
+ type: 'separator',
+ })
+ for (const index in defaultConfig.selectionTools) {
+ const key = defaultConfig.selectionTools[index]
+ const desc = defaultConfig.selectionToolsDesc[index]
+ Browser.contextMenus.create({
+ id: menuId + key,
+ parentId: menuId,
+ title: desc,
+ contexts: ['selection'],
+ })
+ }
+
+ Browser.contextMenus.onClicked.addListener((info, tab) => {
+ const message = {
+ itemId: info.menuItemId.replace(menuId, ''),
+ selectionText: info.selectionText,
+ }
+ console.debug('menu clicked', message)
+ Browser.tabs.sendMessage(tab.id, {
+ type: 'CREATE_MENU',
+ data: message,
+ })
})
})
+}
+
+Browser.runtime.onMessage.addListener(async (message) => {
+ if (message.type === 'REFRESH_MENU') {
+ refreshMenu()
+ }
})
+
+refreshMenu()
diff --git a/src/content-script/index.jsx b/src/content-script/index.jsx
index 32f64ac..6161654 100644
--- a/src/content-script/index.jsx
+++ b/src/content-script/index.jsx
@@ -4,9 +4,11 @@ import { render } from 'preact'
import DecisionCard from '../components/DecisionCard'
import { config as siteConfig } from './site-adapters'
import { config as toolsConfig } from './selection-tools'
+import { config as menuConfig } from './menu-tools'
import { clearOldAccessToken, getUserConfig, setAccessToken } from '../config/index.mjs'
import {
createElementAtPosition,
+ cropText,
getClientPosition,
getPossibleElementByQuerySelector,
initSession,
@@ -210,38 +212,31 @@ async function prepareForRightClickMenu() {
})
Browser.runtime.onMessage.addListener(async (message) => {
- if (message.type === 'MENU') {
+ if (message.type === 'CREATE_MENU') {
const data = message.data
- if (data.itemId === 'new') {
- const position = { x: menuX, y: menuY }
- const container = createElementAtPosition(position.x, position.y)
- container.className = 'chatgptbox-toolbar-container-not-queryable'
- render(
- ,
- container,
+ let prompt = ''
+ if (data.itemId in toolsConfig)
+ prompt = await toolsConfig[data.itemId].genPrompt(data.selectionText)
+ else if (data.itemId in menuConfig)
+ prompt = cropText(
+ `Reply in ${await getPreferredLanguage()}.\n` +
+ (await menuConfig[data.itemId].genPrompt()),
)
- } else {
- const position = { x: menuX, y: menuY }
- const container = createElementAtPosition(position.x, position.y)
- container.className = 'chatgptbox-toolbar-container-not-queryable'
- render(
- ,
- container,
- )
- }
+
+ const position = { x: menuX, y: menuY }
+ const container = createElementAtPosition(position.x, position.y)
+ container.className = 'chatgptbox-toolbar-container-not-queryable'
+ render(
+ ,
+ container,
+ )
}
})
}
diff --git a/src/content-script/menu-tools/index.mjs b/src/content-script/menu-tools/index.mjs
new file mode 100644
index 0000000..0ee810a
--- /dev/null
+++ b/src/content-script/menu-tools/index.mjs
@@ -0,0 +1,16 @@
+import { getCoreContentText } from '../../utils/get-core-content-text'
+
+export const config = {
+ newChat: {
+ label: 'New Chat',
+ genPrompt: async () => {
+ return ''
+ },
+ },
+ summarizePage: {
+ label: 'Summarize Page',
+ genPrompt: async () => {
+ return `The following is the text content of a web page, analyze the core content and summarize:\n${getCoreContentText()}`
+ },
+ },
+}
diff --git a/src/utils/get-core-content-text.mjs b/src/utils/get-core-content-text.mjs
index 9f1af09..5f618a1 100644
--- a/src/utils/get-core-content-text.mjs
+++ b/src/utils/get-core-content-text.mjs
@@ -35,10 +35,10 @@ export function getCoreContentText() {
let ret
if (secondLargestElement && getArea(secondLargestElement) > 0.5 * getArea(largestElement)) {
- ret = secondLargestElement.textContent
+ ret = secondLargestElement.innerText || secondLargestElement.textContent
console.log('use second')
} else {
- ret = largestElement.textContent
+ ret = largestElement.innerText || largestElement.textContent
console.log('use first')
}
return ret.trim().replaceAll(' ', '').replaceAll('\n\n', '').replaceAll(',,', '')