Created
August 24, 2022 22:21
-
-
Save ndbeals/81eacd6c561e0bee993ff9a6d59733b6 to your computer and use it in GitHub Desktop.
Facebook Saved Items Bulk Remove
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Facebook Saved Items Bulk Remove | |
// @namespace facebooksaved | |
// @version 0.1 | |
// @description Bulk remove saved items from facebook | |
// @author Nathan Beals | |
// @match https://www.facebook.com/saved/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=facebook.com | |
// @run-at document-start | |
// ==/UserScript== | |
// firefox users: go to about:config and enable 'layout.css.has-selector.enabled' (set to true) | |
(function () { | |
'use strict'; | |
console.log("loaded") | |
// setTimeout(main,5000); | |
window.addEventListener("load", main) | |
// main() | |
})(); | |
function main(params) { | |
console.log("hello facebook") | |
let parentElements = document.querySelectorAll('div[role="main"]> div> div > div[role="main"] > div > div'); | |
let header = parentElements[0]; | |
let itemList = parentElements[1]; | |
let copyEle = header.querySelector('span'); | |
let controlsHeader = copyEle.cloneNode(false); | |
controlsHeader.append(createButton("Select All", (event) => { | |
let checkBoxes = document.querySelectorAll('#selectedItems') | |
for (const checkBox of checkBoxes) { | |
checkBox.checked = true | |
} | |
})) | |
controlsHeader.append(document.createTextNode(" | ")) | |
controlsHeader.append(createButton("UnSelect All", (event) => { | |
let checkBoxes = document.querySelectorAll('#selectedItems') | |
for (const checkBox of checkBoxes) { | |
checkBox.checked = false | |
} | |
})) | |
controlsHeader.append(document.createTextNode(" | ")) | |
controlsHeader.append(createButton("Invert Selection", (event) => { | |
let checkBoxes = document.querySelectorAll('#selectedItems') | |
for (const checkBox of checkBoxes) { | |
checkBox.checked = !checkBox.checked | |
} | |
})) | |
controlsHeader.append(document.createTextNode(" | ")) | |
controlsHeader.append(createButton("Remove All Selected", (event) => { | |
removeAllSaved(itemList, event) | |
})) | |
copyEle.after(controlsHeader) | |
processItems(itemList) | |
} | |
async function removeAllSaved(itemList, event) { | |
let checked = document.querySelectorAll('#selectedItems:checked') | |
for (const checkBox of checked) { | |
checkBox.menuBtn.click() | |
let contextMenu | |
do { | |
await wait(10) | |
contextMenu = document.querySelector('div[role="menuitem"]') | |
} while (contextMenu === null); | |
contextMenu.click() | |
contextMenu = null | |
await wait(10) | |
} | |
} | |
function processItems(itemList) { | |
for (const savedItem of itemList.children) { | |
let parent = savedItem.querySelector(':scope div > div > div'); | |
let menuBtn = parent.querySelector(':scope > div:nth-child(2) > div > div:nth-child(3) > div > div:last-child > div'); | |
let [el, btn] = createCheckBox() | |
btn.menuBtn = menuBtn | |
parent.append(el) | |
} | |
} | |
const wait = (delay) => { | |
return new Promise((resolve) => { | |
setTimeout(resolve, delay); | |
}); | |
}; | |
function createButton(text, onClick) { | |
let btn = document.createElement('button'); | |
btn.innerHTML = text | |
btn.addEventListener("click", onClick) | |
return btn | |
} | |
function createCheckBox(params) { | |
var zNode = document.createElement('div'); | |
zNode.innerHTML = '<input type="checkbox" id="selectedItems">' | |
return [zNode, zNode.firstChild] | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment