I am trying to use the html2canvas within a chrome extension I am building.
For my chrome extension I am directly injecting JS so that the user can toggle the extension so it does not go out of focus and closes when the user clicks on the current tab.
<body>
<script src="popup.js"></script>
</body>
I am choosing to dynamically load the html2canvas from a local file where I have copied the JS file.
I am loading it within my content.js file (this file also contains the UI where it is directly injecting into the current tab DOM.
Here is the function where I am calling the html2canvas to load:
async function mouseUpHandler(e) {
if (!isSelecting) return;
isSelecting = false;
// Remove event listeners and overlay
const overlay = document.getElementById("selectionOverlay");
overlay.removeEventListener("mousedown", mouseDownHandler);
overlay.removeEventListener("mousemove", mouseMoveHandler);
overlay.removeEventListener("mouseup", mouseUpHandler);
document.body.removeChild(overlay);
// Get the selected area coordinates
const rect = selectionBox.getBoundingClientRect();
// Remove the selection boxhtm
selectionBox.remove();
console.log("Selected area:", rect);
try {
// Wait for html2canvas to be loaded
await loadHtml2Canvas();
// Ensure window.html2canvas is loaded and then use it
window.html2canvas(document.body, {
x: rect.left + window.scrollX,
y: rect.top + window.scrollY,
width: rect.width,
height: rect.height,
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight,
scale: window.devicePixelRatio // Adjust for high-DPI screens
})
.then((canvas) => {
const dataUrl = canvas.toDataURL("image/png");
console.log("Captured image data URL:", dataUrl);
// Store the captured image data URL
capturedImageDataUrl = dataUrl;
// Display the captured image in the sidebar
displayCapturedImage(dataUrl);
})
.catch((error) => {
console.error('html2canvas error:', error);
});
} catch (error) {
console.error(error.message);
}
}
And here is the loadhtml2canvas:
function loadHtml2Canvas() {
return new Promise((resolve, reject) => {
// Check if html2canvas is already loaded
if (typeof window.html2canvas !== 'undefined') {
console.log('html2canvas is already loaded.');
resolve(); // Resolve immediately if already loaded
return;
}
// Load html2canvas dynamically
let script = document.createElement('script');
const scriptUrl = chrome.runtime.getURL('html2canvas.min.js');
console.log('Loading html2canvas from:', scriptUrl);
script.src = scriptUrl;
script.onload = function() {
console.log('html2canvas loaded dynamically.');
if (typeof window.html2canvas !== 'undefined') {
resolve(); // Resolve the promise if window.html2canvas is defined
} else {
reject(new Error('window.html2canvas is still not defined after loading.'));
}
};
script.onerror = function() {
reject(new Error('Failed to load html2canvas.'));
};
// Append the script to the document head
document.head.appendChild(script);
});
}
What is happening is it looks like it is correctly being loaded from the file but then it turns out to be undefined.
Here is the console.log statements:
Selected area: DOMRect {x: 0, y: 0, width: 0, height: 0, top: 0, …}
content.js:409 Loading html2canvas from: chrome-extension://geekmcfbhphgbnafmfmcmhjeaeoaikod/html2canvas.min.js
content.js:414 html2canvas loaded dynamically.
content.js:482 window.html2canvas is still not defined after loading.
mouseUpHandler @ content.js:482
Any help would be greatly appreciated.
I have tried to load this from the manifest.js like so:
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["html2canvas.min.js", "content.js"]
}
],
"web_accessible_resources": [
{
"resources": ["html2canvas.min.js"],
"matches": ["<all_urls>"]
}
]
I get the same error