mirror of
https://github.com/chenasraf/copy-tab-url.git
synced 2026-05-17 17:38:15 +00:00
refactor: clean up content script loading
This commit is contained in:
103
src/contentScripts/content_script.tsx
Normal file
103
src/contentScripts/content_script.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import logger from '@/common/logger'
|
||||
import { onMessage } from 'webext-bridge/content-script'
|
||||
|
||||
let toastTimeout1: NodeJS.Timeout, toastTimeout2: NodeJS.Timeout
|
||||
|
||||
export function contentScriptMain() {
|
||||
logger.info('[vite-react-webext] Hello world from content script')
|
||||
|
||||
injectCSS()
|
||||
|
||||
onMessage('copy-tab-url', (payload) => {
|
||||
logger.debug('copy-text', payload)
|
||||
setTimeout(async () => {
|
||||
logger.debug('Copying text', payload.data)
|
||||
navigator.clipboard.writeText(payload.data as string)
|
||||
toast('URL Copied to Clipboard')
|
||||
}, 0)
|
||||
})
|
||||
onMessage('copy-tab-markdown', (payload) => {
|
||||
logger.debug('copy-text', payload)
|
||||
setTimeout(async () => {
|
||||
logger.debug('Copying text', payload.data)
|
||||
navigator.clipboard.writeText(payload.data as string)
|
||||
toast('Markdown Copied to Clipboard')
|
||||
}, 0)
|
||||
})
|
||||
}
|
||||
|
||||
async function toast(text: string) {
|
||||
await dismissToast()
|
||||
const container = document.createElement('div')
|
||||
container.style.position = 'fixed'
|
||||
container.style.top = '10px'
|
||||
container.style.right = '10px'
|
||||
container.style.zIndex = '999999'
|
||||
container.style.perspective = '100px'
|
||||
|
||||
const toast = document.createElement('div')
|
||||
toast.dataset.taburlToast = 'taburl-toast'
|
||||
|
||||
toast.innerText = text
|
||||
|
||||
container.appendChild(toast)
|
||||
document.body.appendChild(container)
|
||||
|
||||
logger.debug('Toast injected')
|
||||
|
||||
clearTimeout(toastTimeout1)
|
||||
clearTimeout(toastTimeout2)
|
||||
|
||||
return new Promise((resolve) => {
|
||||
toastTimeout1 = setTimeout(() => {
|
||||
toast.classList.add('show')
|
||||
toastTimeout2 = setTimeout(() => {
|
||||
dismissToast()
|
||||
}, 3000)
|
||||
resolve(undefined)
|
||||
}, 10)
|
||||
})
|
||||
}
|
||||
|
||||
async function dismissToast() {
|
||||
const toast = document.querySelector('[data-taburl-toast]') as HTMLDivElement
|
||||
const container = toast?.parentElement
|
||||
clearTimeout(toastTimeout1)
|
||||
clearTimeout(toastTimeout2)
|
||||
|
||||
if (!toast || !container) return
|
||||
logger.debug('Dismissing toast')
|
||||
toast.classList.remove('show')
|
||||
return new Promise((resolve) => {
|
||||
toastTimeout1 = setTimeout(() => {
|
||||
container.remove()
|
||||
logger.debug('Toast dismissed')
|
||||
resolve(undefined)
|
||||
}, 150)
|
||||
})
|
||||
}
|
||||
|
||||
function injectCSS() {
|
||||
if (document.getElementById('taburl-toast-style')) return
|
||||
const style = document.createElement('style')
|
||||
style.id = 'taburl-toast-style'
|
||||
style.innerHTML = `
|
||||
[data-taburl-toast] {
|
||||
background: rgb(24, 24, 24);
|
||||
color: rgb(255, 255, 255);
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
padding: 12px;
|
||||
border-radius: 1em;
|
||||
transition: all 150ms ease-in-out;
|
||||
opacity: 0;
|
||||
transform: rotate3d(0, 3, 1, 10deg) translateY(-10px);
|
||||
}
|
||||
|
||||
[data-taburl-toast].show {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
`
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
@@ -1,95 +1,8 @@
|
||||
import logger from '@/common/logger'
|
||||
import { onMessage } from 'webext-bridge/content-script'
|
||||
import { contentScriptMain } from './content_script'
|
||||
|
||||
// NOTE Firefox `browser.tabs.executeScript()` requires scripts return a primitive value,
|
||||
// so we wrap the content script in an IIFE
|
||||
// prettier doesn't like this.
|
||||
; (() => {
|
||||
let toastTimeout1: NodeJS.Timeout, toastTimeout2: NodeJS.Timeout
|
||||
logger.info('[vite-react-webext] Hello world from content script')
|
||||
|
||||
injectCSS()
|
||||
|
||||
onMessage('copy-text', (payload) => {
|
||||
logger.debug('copy-text', payload)
|
||||
setTimeout(async () => {
|
||||
logger.debug('Copying text', payload.data)
|
||||
navigator.clipboard.writeText(payload.data as string)
|
||||
injectToast()
|
||||
}, 10)
|
||||
})
|
||||
|
||||
async function injectToast() {
|
||||
if (document.querySelector('[data-taburl-toast]')) {
|
||||
dismissToast()
|
||||
await new Promise((resolve) => setTimeout(resolve, 160))
|
||||
}
|
||||
const container = document.createElement('div')
|
||||
container.style.position = 'fixed'
|
||||
container.style.top = '10px'
|
||||
container.style.right = '10px'
|
||||
container.style.zIndex = '999999'
|
||||
container.style.perspective = '100px'
|
||||
|
||||
const toast = document.createElement('div')
|
||||
toast.dataset.taburlToast = 'taburl-toast'
|
||||
|
||||
toast.innerText = 'URL Copied to Clipboard'
|
||||
|
||||
container.appendChild(toast)
|
||||
document.body.appendChild(container)
|
||||
|
||||
logger.debug('Toast injected')
|
||||
|
||||
clearTimeout(toastTimeout1)
|
||||
clearTimeout(toastTimeout2)
|
||||
|
||||
toastTimeout1 = setTimeout(() => {
|
||||
toast.classList.add('show')
|
||||
|
||||
toastTimeout2 = setTimeout(() => {
|
||||
dismissToast()
|
||||
}, 3000)
|
||||
}, 10)
|
||||
}
|
||||
|
||||
function dismissToast() {
|
||||
const toast = document.querySelector('[data-taburl-toast]') as HTMLDivElement
|
||||
const container = toast?.parentElement
|
||||
clearTimeout(toastTimeout1)
|
||||
clearTimeout(toastTimeout2)
|
||||
|
||||
if (!toast || !container) return
|
||||
logger.debug('Dismissing toast')
|
||||
toast.classList.remove('show')
|
||||
toastTimeout1 = setTimeout(() => {
|
||||
container.remove()
|
||||
logger.debug('Toast dismissed')
|
||||
}, 150)
|
||||
}
|
||||
|
||||
function injectCSS() {
|
||||
if (document.getElementById('taburl-toast-style')) return
|
||||
const style = document.createElement('style')
|
||||
style.id = 'taburl-toast-style'
|
||||
style.innerHTML = `
|
||||
[data-taburl-toast] {
|
||||
background: rgb(24, 24, 24);
|
||||
color: rgb(255, 255, 255);
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
padding: 12px;
|
||||
border-radius: 1em;
|
||||
transition: all 150ms ease-in-out;
|
||||
opacity: 0;
|
||||
transform: rotate3d(0, 3, 1, 10deg) translateY(-10px);
|
||||
}
|
||||
|
||||
[data-taburl-toast].show {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
`
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
contentScriptMain()
|
||||
})()
|
||||
|
||||
Reference in New Issue
Block a user