Skip to content

Instantly share code, notes, and snippets.

@ndbeals
Created August 24, 2022 22:21
Show Gist options
  • Save ndbeals/81eacd6c561e0bee993ff9a6d59733b6 to your computer and use it in GitHub Desktop.
Save ndbeals/81eacd6c561e0bee993ff9a6d59733b6 to your computer and use it in GitHub Desktop.
Facebook Saved Items Bulk Remove
// ==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