diff --git a/.yarn/cache/html-to-image-npm-1.11.11-faab8eba97-b453beca72.zip b/.yarn/cache/html-to-image-npm-1.11.11-faab8eba97-b453beca72.zip
deleted file mode 100644
index 133b21fcb..000000000
Binary files a/.yarn/cache/html-to-image-npm-1.11.11-faab8eba97-b453beca72.zip and /dev/null differ
diff --git a/packages/clipper/package.json b/packages/clipper/package.json
index 7f69243af..3f890a650 100644
--- a/packages/clipper/package.json
+++ b/packages/clipper/package.json
@@ -32,7 +32,6 @@
"webpack": "*"
},
"dependencies": {
- "@mozilla/readability": "^0.4.2",
- "html-to-image": "^1.11.11"
+ "@mozilla/readability": "^0.4.2"
}
}
diff --git a/packages/clipper/src/background/background.ts b/packages/clipper/src/background/background.ts
index c4a969e1c..8f381ff77 100644
--- a/packages/clipper/src/background/background.ts
+++ b/packages/clipper/src/background/background.ts
@@ -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',
+ })
}
})
diff --git a/packages/clipper/src/content/content.ts b/packages/clipper/src/content/content.ts
index 376faf33c..6f5d55e3f 100644
--- a/packages/clipper/src/content/content.ts
+++ b/packages/clipper/src/content/content.ts
@@ -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((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
diff --git a/packages/clipper/src/manifest.v2.json b/packages/clipper/src/manifest.v2.json
index 61c929017..555b7e3e9 100644
--- a/packages/clipper/src/manifest.v2.json
+++ b/packages/clipper/src/manifest.v2.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Standard Notes Clipper",
"description": "Web clipper for Standard Notes",
- "permissions": ["activeTab", "storage"],
+ "permissions": ["activeTab", "storage", ""],
"browser_action": {
"default_popup": "popup/index.html?route=extension"
},
diff --git a/packages/clipper/src/types/message.ts b/packages/clipper/src/types/message.ts
index c6303d5c5..60da6a8f6 100644
--- a/packages/clipper/src/types/message.ts
+++ b/packages/clipper/src/types/message.ts
@@ -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
diff --git a/packages/web/src/javascripts/Components/ClipperView/ClipperView.tsx b/packages/web/src/javascripts/Components/ClipperView/ClipperView.tsx
index 512e06f14..b6a5f7724 100644
--- a/packages/web/src/javascripts/Components/ClipperView/ClipperView.tsx
+++ b/packages/web/src/javascripts/Components/ClipperView/ClipperView.tsx
@@ -340,15 +340,9 @@ const ClipperView = ({
return
}
setClipPayload(payload)
- if (isScreenshotMode) {
- addToast({
- type: ToastType.Regular,
- message: 'Capturing full page...',
- })
- }
}}
>
- Clip full page
+ {isScreenshotMode ? 'Capture visible' : 'Clip full page'}
-
Default tag:
+
Default tag
{defaultTag && (