Files
chrome-extensions-samples/api-samples/cookies/cookie-clearer/popup.js
Sebastian Benz dc2174377a Add prettier and eslint (#831)
* Ignores archived samples
* Uses eslint/recommended rules
* Runs prettier and eslint (including --fix) pre-commit via husky
* Adds new npm scripts: 'lint', 'lint:fix' and 'prettier'
* Does not lint inline js code
* Fix all prettier and eslint errors
* Add custom prettier rules
* Apply custom prettier rules
* Update readme to explain how to setup the repo
* addressed comments
2023-02-22 13:25:39 +01:00

109 lines
2.9 KiB
JavaScript

const form = document.getElementById('control-row');
const go = document.getElementById('go');
const input = document.getElementById('input');
const message = document.getElementById('message');
// The async IIFE is necessary because Chrome <89 does not support top level await.
(async function initPopupWindow() {
let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
if (tab?.url) {
try {
let url = new URL(tab.url);
input.value = url.hostname;
} catch {
// ignore
}
}
input.focus();
})();
form.addEventListener('submit', handleFormSubmit);
async function handleFormSubmit(event) {
event.preventDefault();
clearMessage();
let url = stringToUrl(input.value);
if (!url) {
setMessage('Invalid URL');
return;
}
let message = await deleteDomainCookies(url.hostname);
setMessage(message);
}
function stringToUrl(input) {
// Start with treating the provided value as a URL
try {
return new URL(input);
} catch {
// ignore
}
// If that fails, try assuming the provided input is an HTTP host
try {
return new URL('http://' + input);
} catch {
// ignore
}
// If that fails ¯\_(ツ)_/¯
return null;
}
async function deleteDomainCookies(domain) {
let cookiesDeleted = 0;
try {
const cookies = await chrome.cookies.getAll({ domain });
if (cookies.length === 0) {
return 'No cookies found';
}
let pending = cookies.map(deleteCookie);
await Promise.all(pending);
cookiesDeleted = pending.length;
} catch (error) {
return `Unexpected error: ${error.message}`;
}
return `Deleted ${cookiesDeleted} cookie(s).`;
}
function deleteCookie(cookie) {
// Cookie deletion is largely modeled off of how deleting cookies works when using HTTP headers.
// Specific flags on the cookie object like `secure` or `hostOnly` are not exposed for deletion
// purposes. Instead, cookies are deleted by URL, name, and storeId. Unlike HTTP headers, though,
// we don't have to delete cookies by setting Max-Age=0; we have a method for that ;)
//
// To remove cookies set with a Secure attribute, we must provide the correct protocol in the
// details object's `url` property.
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Secure
const protocol = cookie.secure ? 'https:' : 'http:';
// Note that the final URL may not be valid. The domain value for a standard cookie is prefixed
// with a period (invalid) while cookies that are set to `cookie.hostOnly == true` do not have
// this prefix (valid).
// https://developer.chrome.com/docs/extensions/reference/cookies/#type-Cookie
const cookieUrl = `${protocol}//${cookie.domain}${cookie.path}`;
return chrome.cookies.remove({
url: cookieUrl,
name: cookie.name,
storeId: cookie.storeId
});
}
function setMessage(str) {
message.textContent = str;
message.hidden = false;
}
function clearMessage() {
message.hidden = true;
message.textContent = '';
}