|
/* |
|
* Use-case: you have hundreds of old shared Dropbox links and |
|
* you want to un-share them. |
|
* |
|
* Go to https://www.dropbox.com/share/links and let it load, |
|
* scroll to the bottom of the list, open browser's dev console |
|
* (tested in Chrome & Firefox) and paste this file's whole contents |
|
* into console's input field. |
|
* |
|
* Call `getCount()` to check if script detects links correctly. |
|
* Call `loop(50)` to delete last 50 links from the list. |
|
* To cancel the loop just run `cancel = true`. |
|
* If it crashes due to error, just run loop again. |
|
* |
|
* Script was confirmed working as of 2023-03-14. |
|
* |
|
*/ |
|
|
|
|
|
// helpers |
|
|
|
function getElemsWithText(tagName, text) { |
|
return new Array(...document.getElementsByTagName(tagName)) |
|
.filter(function(el) { return el.textContent == text; }); |
|
} |
|
|
|
function getElemWithTextPromise(tagName, text) { |
|
return new Promise(function(resolve, reject) { |
|
var elems = getElemsWithText(tagName, text); |
|
if (elems && elems.length) { |
|
resolve(elems[elems.length - 1]); // returning last because "Delete link" matches 8 nested divs, clicking first doesn't work |
|
} |
|
else { |
|
console.error("Elems is", elems); |
|
reject(); |
|
} |
|
}); |
|
} |
|
|
|
function getElemsWithInnerHtml(tagName, textInInnerHtml) { |
|
return new Array(...document.getElementsByTagName(tagName)) |
|
.filter(function(el) { return el.innerHTML.indexOf(textInInnerHtml) != -1; }); |
|
} |
|
|
|
function getLastMenuButtonPromise() { |
|
return new Promise(function(resolve, reject) { |
|
var tagName = "button"; |
|
var textInInnerHtml |
|
var elems = getElemsWithInnerHtml("button", "<svg"); // this is supposed to find buttons with three dots "..." icon |
|
|
|
if (elems && elems.length) { |
|
resolve(elems[elems.length - 1]); // this assumes that last found button is a menu button |
|
} |
|
else { |
|
console.error("Elems is", elems); |
|
reject(); |
|
} |
|
}); |
|
} |
|
|
|
|
|
function getDeleteLinkSpanPromise() { |
|
return getElemWithTextPromise("div", "Delete link"); |
|
} |
|
|
|
function getDeleteConfirmationButtonPromise() { |
|
return getElemWithTextPromise("button", "Delete link"); |
|
} |
|
|
|
function delayPromise(t) { |
|
return new Promise(function(resolve) { |
|
setTimeout(resolve, t); |
|
}); |
|
} |
|
|
|
function click(elem) { |
|
elem.click(); |
|
} |
|
|
|
function wait() { |
|
return delayPromise(110); |
|
} |
|
|
|
function deleteFirstLinkPromise() { |
|
return getLastMenuButtonPromise() |
|
.then(click) |
|
.then(wait) |
|
.then(getDeleteLinkSpanPromise) |
|
.then(click) |
|
.then(wait) |
|
.then(getDeleteConfirmationButtonPromise) |
|
.then(click); |
|
} |
|
|
|
|
|
// for use |
|
|
|
function getCount() { |
|
return getElemsWithInnerHtml("button", "<svg").length; |
|
} |
|
|
|
var cancel = false; |
|
|
|
function loop(times) { |
|
if (cancel || times == 0) { |
|
cancel = false; |
|
console.log("Finished!"); |
|
return; |
|
} |
|
|
|
console.log("Deleting, " + times + " left..."); |
|
|
|
deleteFirstLinkPromise().then( |
|
function() { |
|
setTimeout(function() { loop(times - 1); }, 700); |
|
}, |
|
function(err) { |
|
console.log("Nope"); |
|
console.error(err); |
|
} |
|
); |
|
} |