refactor: clipper screenshot (#2325)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { runtime, action, browserAction, windows, storage } from 'webextension-polyfill'
|
||||
import { runtime, action, browserAction, windows, storage, tabs } from 'webextension-polyfill'
|
||||
import { ClipPayload, RuntimeMessage, RuntimeMessageTypes } from '../types/message'
|
||||
|
||||
const isFirefox = navigator.userAgent.indexOf('Firefox/') !== -1
|
||||
@@ -22,11 +22,15 @@ const openPopupAndClipSelection = async (payload: ClipPayload) => {
|
||||
void openPopup()
|
||||
}
|
||||
|
||||
runtime.onMessage.addListener((message: RuntimeMessage) => {
|
||||
runtime.onMessage.addListener(async (message: RuntimeMessage) => {
|
||||
if (message.type === RuntimeMessageTypes.OpenPopupWithSelection) {
|
||||
if (!message.payload) {
|
||||
return
|
||||
}
|
||||
void openPopupAndClipSelection(message.payload)
|
||||
} else if (message.type === RuntimeMessageTypes.CaptureVisibleTab) {
|
||||
return await tabs.captureVisibleTab(undefined, {
|
||||
format: 'png',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { runtime } from 'webextension-polyfill'
|
||||
import { Readability } from '@mozilla/readability'
|
||||
import { RuntimeMessage, RuntimeMessageTypes } from '../types/message'
|
||||
import { toPng } from 'html-to-image'
|
||||
|
||||
let isSelectingNodeForClipping = false
|
||||
let isScreenshotMode = false
|
||||
@@ -47,7 +46,9 @@ runtime.onMessage.addListener(async (message: RuntimeMessage) => {
|
||||
}
|
||||
case RuntimeMessageTypes.GetFullPage: {
|
||||
if (isScreenshotMode) {
|
||||
const content = await toPng(document.body)
|
||||
const content = await runtime.sendMessage({
|
||||
type: RuntimeMessageTypes.CaptureVisibleTab,
|
||||
})
|
||||
return { title: document.title, content: content, url: window.location.href, isScreenshot: true }
|
||||
}
|
||||
|
||||
@@ -101,6 +102,55 @@ const disableNodeSelection = () => {
|
||||
nodeOverlayElement.style.visibility = 'hidden'
|
||||
}
|
||||
|
||||
const imageFromBase64 = (base64: string) => {
|
||||
return new Promise<HTMLImageElement>((resolve, reject) => {
|
||||
const image = new Image()
|
||||
image.onload = () => {
|
||||
resolve(image)
|
||||
}
|
||||
image.onerror = reject
|
||||
image.src = base64
|
||||
})
|
||||
}
|
||||
|
||||
const toPng = async (element: HTMLElement) => {
|
||||
const visibleTab: string = await runtime.sendMessage({
|
||||
type: RuntimeMessageTypes.CaptureVisibleTab,
|
||||
})
|
||||
|
||||
const image = await imageFromBase64(visibleTab)
|
||||
|
||||
const canvas = document.createElement('canvas')
|
||||
|
||||
canvas.width = image.width
|
||||
canvas.height = image.height
|
||||
|
||||
const context = canvas.getContext('2d')
|
||||
|
||||
if (!context) {
|
||||
throw new Error('Could not get canvas context')
|
||||
}
|
||||
|
||||
context.drawImage(image, 0, 0)
|
||||
|
||||
const elementRect = element.getBoundingClientRect()
|
||||
|
||||
const x = elementRect.x
|
||||
const y = elementRect.y
|
||||
|
||||
const width = elementRect.width
|
||||
const height = elementRect.height
|
||||
|
||||
const imageData = context.getImageData(x, y, width, height)
|
||||
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
|
||||
context.putImageData(imageData, 0, 0)
|
||||
|
||||
return canvas.toDataURL('image/png')
|
||||
}
|
||||
|
||||
window.addEventListener('click', async (event) => {
|
||||
if (!isSelectingNodeForClipping) {
|
||||
return
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 2,
|
||||
"name": "Standard Notes Clipper",
|
||||
"description": "Web clipper for Standard Notes",
|
||||
"permissions": ["activeTab", "storage"],
|
||||
"permissions": ["activeTab", "storage", "<all_urls>"],
|
||||
"browser_action": {
|
||||
"default_popup": "popup/index.html?route=extension"
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@ export const RuntimeMessageTypes = {
|
||||
OpenPopupWithSelection: 'open-popup-with-selection',
|
||||
StartNodeSelection: 'start-node-selection',
|
||||
ToggleScreenshotMode: 'toggle-screenshot-mode',
|
||||
CaptureVisibleTab: 'capture-visible-tab',
|
||||
} as const
|
||||
|
||||
export type RuntimeMessageType = typeof RuntimeMessageTypes[keyof typeof RuntimeMessageTypes]
|
||||
@@ -24,6 +25,7 @@ export type RuntimeMessageReturnTypes = {
|
||||
[RuntimeMessageTypes.GetSelection]: ClipPayload
|
||||
[RuntimeMessageTypes.HasSelection]: boolean
|
||||
[RuntimeMessageTypes.GetFullPage]: ClipPayload
|
||||
[RuntimeMessageTypes.CaptureVisibleTab]: string
|
||||
[RuntimeMessageTypes.OpenPopupWithSelection]: void
|
||||
[RuntimeMessageTypes.StartNodeSelection]: void
|
||||
[RuntimeMessageTypes.ToggleScreenshotMode]: void
|
||||
|
||||
Reference in New Issue
Block a user