Skip to content

Commit

Permalink
fix: shortcuts now send messages to all frames
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackGlory committed May 4, 2024
1 parent b05f751 commit 607ae4a
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { createTabClient } from '@delight-rpc/webextension'
import { IFrameAPI } from '@src/contract.js'
import { CommandHandler } from './types.js'
import { concatPlainText } from '@utils/concat-plain-text.js'
import { assert, isntNull } from '@blackglory/prelude'

export const commandSelectionAsConcatenatedPlainText: CommandHandler = async (info, tab) => {
if (tab.id) {
const tabClient = createTabClient<IFrameAPI>({
tabId: tab.id
, frameId: info.frameId
})

const text = await tabClient.getSelectionText()
assert(isntNull(text))

return plainText(concatPlainText(text))
}
Expand Down
3 changes: 3 additions & 0 deletions src/background/handlers/selection-as-markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CommandHandler } from './types.js'
import { getConfig } from '@background/storage.js'
import { pipeAsync } from 'extra-utils'
import { offscreen } from '@background/offscreen-client.js'
import { assert, isntNull } from '@blackglory/prelude'

export const commandSelectionAsMarkdown: CommandHandler = async (info, tab) => {
if (tab.id) {
Expand All @@ -16,7 +17,9 @@ export const commandSelectionAsMarkdown: CommandHandler = async (info, tab) => {
tabId: tab.id
, frameId: info.frameId
})

const html = await client.getSelectionHTML()
assert(isntNull(html))

return plainText(
await pipeAsync(
Expand Down
3 changes: 3 additions & 0 deletions src/background/handlers/selection-as-plain-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import { plainText } from './utils.js'
import { createTabClient } from '@delight-rpc/webextension'
import { IFrameAPI } from '@src/contract.js'
import { CommandHandler } from './types.js'
import { assert, isntNull } from '@blackglory/prelude'

export const commandSelectionAsPlainText: CommandHandler = async (info, tab) => {
if (tab.id) {
const tabClient = createTabClient<IFrameAPI>({
tabId: tab.id
, frameId: info.frameId
})

const text = await tabClient.getSelectionText()
assert(isntNull(text))

return plainText(text)
}
Expand Down
7 changes: 6 additions & 1 deletion src/background/handlers/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { assert, isntNull } from '@blackglory/prelude'
import { CommandResultType, CommandResult } from './types.js'
import { createTabClient } from '@delight-rpc/webextension'
import { IFrameAPI } from '@src/contract.js'
Expand All @@ -21,5 +22,9 @@ export async function getActiveElementTextContent(
, frameId?: number
): Promise<string> {
const tabClient = createTabClient<IFrameAPI>({ tabId, frameId })
return await tabClient.getActiveElementTextContent()

const text = await tabClient.getActiveElementTextContent()
assert(isntNull(text))

return text
}
29 changes: 23 additions & 6 deletions src/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { IBackgroundAPI } from '@src/contract.js'
import { ImplementationOf } from 'delight-rpc'
import { createServer } from '@delight-rpc/webextension'
import { updateMenu } from './menu.js'
import { isDev } from '@utils/is-dev.js'
import { assert, isntUndefined } from '@blackglory/prelude'

const launched = new Deferred<void>()

Expand Down Expand Up @@ -72,14 +74,29 @@ chrome.contextMenus.onClicked.addListener(async (info, tab) => {
})

chrome.commands.onCommand.addListener(async (command, tab) => {
const result = await commandHandlers[command](
{}
, tab ?? await getActiveTab()
tab = tab ?? await getActiveTab()

const tabId = tab.id
assert(isntUndefined(tabId))

const frames = await chrome.webNavigation.getAllFrames({ tabId }) ?? []

const result = await Promise.any(
frames.map(async frame => {
const result = await commandHandlers[command](
{
frameUrl: frame.url
, frameId: frame.frameId
}
, tab
)
assert(isntUndefined(result))

return result
})
)

if (result) {
await handleCommandResult(result)
}
await handleCommandResult(result)
})

async function ensureOffscreenDocument(): Promise<void> {
Expand Down
17 changes: 7 additions & 10 deletions src/content-script.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createServer } from '@delight-rpc/webextension'
import { IFrameAPI } from '@src/contract.js'
import { isDev } from '@utils/is-dev.js'

if (isDev()) {
console.info(`[${chrome.runtime.getManifest().name}] The content script is injected`)
Expand All @@ -12,7 +13,7 @@ createServer<IFrameAPI>({
, getSelectionText
})

function getSelectionHTML(): string {
function getSelectionHTML(): string | null {
const userSelection = window.getSelection()
if (userSelection && userSelection.rangeCount) {
const range = userSelection.getRangeAt(0)
Expand All @@ -21,22 +22,18 @@ function getSelectionHTML(): string {
div.appendChild(clonedSelection)
return div.innerHTML
} else {
return ''
return null
}
}

function getSelectionText(): string {
return window.getSelection()?.toString() ?? ''
function getSelectionText(): string | null {
return window.getSelection()?.toString() ?? null
}

function getActiveElementTextContent(): string {
return document.activeElement?.textContent ?? ''
function getActiveElementTextContent(): string | null {
return document.activeElement?.textContent ?? null
}

function getDocumentTitle(): string {
return document.title
}

function isDev(): boolean {
return process.env.NODE_ENV === 'development'
}
6 changes: 3 additions & 3 deletions src/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ export interface IHTMLCleanerAllowlistItem {
}

export interface IFrameAPI {
getSelectionHTML(): string
getSelectionText(): string
getActiveElementTextContent(): string
getSelectionHTML(): string | null
getSelectionText(): string | null
getActiveElementTextContent(): string | null
getDocumentTitle(): string
}

Expand Down
1 change: 1 addition & 0 deletions src/manifest.dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
, "clipboardWrite"
, "offscreen"
, "storage"
, "webNavigation"
]
, "host_permissions": [
"<all_urls>"
Expand Down
1 change: 1 addition & 0 deletions src/manifest.prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
, "clipboardWrite"
, "offscreen"
, "storage"
, "webNavigation"
]
, "host_permissions": [
"<all_urls>"
Expand Down
3 changes: 3 additions & 0 deletions src/utils/is-dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isDev(): boolean {
return process.env.NODE_ENV === 'development'
}

0 comments on commit 607ae4a

Please sign in to comment.