Canva
Canva is a popular website for creating multiple documents such as slides, resumes, simple text documents, etc. βοΈ
This page mostly contains some hacky solutions in JavaScript to automate painful and tiring tasks.
β οΈ Use at your own risk. Written for developers.
Canva: select all of your images
Usage
- Go to
https://www.canva.com/projects
> images - Enjoy
About
This JavaScript code selects all images that you have on Canva.
- Step 1: switch to list view (if needed)
- Step 2: scroll to the bottom of the page
- Step 3: find a way to get the checkbox for one image
- Step 4: click on every checkbox
The script can be modified, for instance, to only select some images based on their name...
// Step 1: Use list view (if not already using list view)
document.querySelector('path[d~="5.25h7.5a.75.75"')?.parentNode.parentNode.parentNode.parentNode.click()
// Step 2
const scrollToTheBottomOfElement = async (e) => {
let previous = e.scrollHeight;
while (1) {
e.scrollTo(0, e.scrollHeight);
await new Promise(resolve => setTimeout(resolve, 400));
if (e.scrollHeight === previous) break;
previous = e.scrollHeight;
}
}
scrollToTheBottomOfElement(document.querySelector('main > div > div'))
.then((x) => {
// Step 3: select the "class" shared by every button
const className = document.querySelectorAll("*[d~='1.06L9.53']")[4]
?.parentNode?.parentNode?.parentNode?.parentNode?.firstChild?.classList[0]
// not found, damn, they changed something
if (className === undefined) {
console.log("Error: can't find className")
} else {
// Step 4: we select every unselected images
for (i of document.querySelectorAll('.'+className))
if (!i.checked) i.click()
}
})
Canva: remove paid templates
setInterval(() => {
Array.from(document.querySelectorAll('span[class]')).filter(span => span.innerHTML === 'β¬').map(span => span.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode).forEach(x => x.parentNode.removeChild(x))
Array.from(document.querySelectorAll("*[d~='M7.51']")).map(p => p.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode).filter(p => !p.id).forEach(x => x.parentNode?.removeChild(x))}
, 2000)
This script will remove from the currently displayed entries:
- templates with the "paid" icon
- templates with the "premium" icon
Called every 2 seconds (e.g. continue to delete as you scroll).
Canva: delete all images in the trash automatically
There is this video Canva - How to delete ALL images from trash folder automatically which uses an auto-clicker, but
- π« You can't use your computer while deleting stuff
- π£ There is a need for additional software (and the suggested download link is from a dangerous website with cracked software...)
- π€― Elements aren't always at the same location
So, I made some complex JavaScript, because their code is complex.
β οΈβ οΈ
You're responsible for any problems. Use it at your own risk.
β οΈβ οΈ
Explanations
You must run the script on the page: https://canva.com/folder/trash
.
-
The script will select the tab "images" and navigate to it (
images
). -
The script will swap the list view (see
layout
) -
Then, we will start the main job (see
await doJob()
)
For the main job, what I do is
-
Fetching the first delete icon (see
popup
) -
It will open a popup to restore/delete permanently the associated element. The script waits for 0.8s for the popup to open, then clicks on delete permanently (see
deleteNode
) -
The script will wait for 0.8s for the big popup with the last confirmation to open. Then, it will check the checkbox saying that it may break your designs (see
checkbox
) -
The script will wait for 0.1s, and then press the confirmation button (see
confirmation
) -
Finally, the script will wait for 0.4s, and start again
It's worth noting that the script won't work if the page has changed. It was still working in December 2022.
πͺ² Bugs πͺ²
Sometimes an image was deleted, but it's still here in the list, so the script will try to delete it again. It won't have any negative impact, it's just that the script will run a second time for nothing.
// https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function doJob() {
await sleep(3000)
while (true) {
// goal: open on restore/delete popup
const popup = document.querySelectorAll("*[d~='14a2']")[1]?.parentNode.parentNode.parentNode.parentNode
if (popup === undefined) {
console.log("Cannot fetch element")
break
}
popup.click()
await sleep(800)
// goal: open confirmation popup
const deleteNode = document.querySelectorAll("*[d~=M8]")[0]?.parentNode.parentNode.parentNode.parentNode.parentNode
if (deleteNode === undefined) {
console.log("Cannot fetch 'delete'")
break
}
deleteNode.click()
await sleep(800)
// goal: check the checkbox (if needed)
const checkbox = document.querySelector('label > div > input')
if (checkbox === undefined) {
console.log("Checkbox not found, stopping just in case.")
break
}
checkbox.click()
await sleep(100)
// goal: close the deal
const confirmation = document.querySelector('body > div:nth-child(2) > div > div > div > div > div > div > div > div > div > div > div > button > span')?.parentNode
if (confirmation === undefined) {
console.log("confirmation not found")
break
}
confirmation.click()
await sleep(400)
console.log("Removed")
}
}
const images = document.querySelector('button[role="tab"][id][tabindex="-1"][aria-controls][aria-selected="false"][class]')
if (images) {
images.click()
const layout = document.querySelector("*[d~=M5]")?.parentNode.parentNode.parentNode.parentNode
if (!layout) {
console.log("Cannot swap layout")
} else {
layout.click()
await doJob()
}
} else {
console.log("Cannot open image tab")
}