You know how to add pages to your favorites. By clicking the favorite, you will browse to the page, because it is an URL stored in the favorite. If you replace the URL with code, then the code will execute in the context of the current page.
A bookmarklet requires to start with "javascript:" then you just need to have javascript code. A very simple bookmarklet to show an alert will be:
javascript:alert('Hello, World!');
Just create a new favorite, then edit the URL to replace it with the above code and save. Now, when you want to launch this favorite, it will display the alert.
It is that easy! You can imagine a much more complex logic to run, and this is exactly what we will do.
The use case
Because of GDPR and other compliance requirements, websites need to display the capability to chose if you (as a visitor) want to browse the website with or without cookies (or even chosing the cookies).
Most of the time, it is quite long to make the choice, and some malicious websites will discourage you to continue without cookies and without ads. We want to put in place a bookmarklet that will quickly close the popup, remove useless items from the page, and even remove cookies and other items stored by the page.
The code we will build will need to be taylored according to your needs. If you don't want to remove local storage items, or to have your very own whitelist, then update the code according to this.
Simulating the click on the "reject" button
First, the script needs to simulate what a user would do: identifying the small prints telling you how to close the consent form without validating cookies. The hack for this is to identify the technical name of the html item, and try to emulate a click if we have found such element.
We will consider that those DOM elements have a well known class name, such as reject-button or reject-all. If we discover an element with one of this class name, we will submit a click. If there is no DOM element with this class name, we will do nothing and continue with other rules. It's up to you to enrich this list. If you browse a website and have a popup, inspect the dom to identify attributes of the item, and add the class name to the list.
Here is a code for this purpose
To understand what it is doing: for each class name listed in the first Array, we try to find in the DOM a corresponding element, and for each one we simulate the click. If nothing is found, nothing happens.
Removing DOM items
Most of the time, you won't have the right name in your list. You need to identify other attributes of remarkable elements that need to be removed from the page; removing them will remove the popup consent form.
We will remove based on id, on class name, on tag name, and sometimes based on dynamic ids. You can remove the consent form and other items of the page, such as a side bar, social icons, ads, the footer, etc... feel free to customize it beyond the consent form.
Below the corresponding code snippet:
Some consent form remove scroll bars and user interaction with the rest of the page. If you remove the consent form elements, you will not be able to use the page. As most of the websites use the same CMP it is quite always the same logic to run.
We have implemented the removal of classes without removing the element (previous snippet was removing elements), we remove some Style attributes, and we target some elements based on special attributes too. Because some frameworks remove page scrollbars, we enable them back for the html tag.
You now have the toolbox to dynamically alter the page, removing visual elements and some cookie-walls.
Purge of browser storage
Most of the time we are speaking about cookies. But pages can store personal information in other location: local storage, session storage, indexedDB... We need to clear everything.
We have to take into account a whitelist too, because, it could be inconfortable to remove cookies from the websites you are using all day long. Don't forget to update the code to taylor your whitelist.
if(!['jla.ovh','mail.google.com','outlook.live.com','twitter.com'].includes(location.hostname)){
/* remove storage only for non-whitelisted domains */
indexedDB.databases().then(r =>{for(i=0;i < r.length;i++)indexedDB.deleteDatabase(r[i].name)});
/* we don't clear Web SQL as there is no way to enumerate or delete these databases */
localStorage.clear();
sessionStorage.clear();
(function(){
let cookies=document.cookie.split("; ");
for(let c=0;c < cookies.length;c++) {
document.cookie=cookies[c].split("=")[0]+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT ;path=/";
let d=window.location.hostname.split(".");
while(d.length > 0){
let cookieBase=encodeURIComponent(cookies[c].split(";")[0].split("=")[0])
+'=; expires=Thu, 01-Jan-1970 00:00:01 GMT; domain='+d.join('.')+' ;path=';
var p=location.pathname.split('/');
document.cookie=cookieBase+'/';
while(p.length>0){
document.cookie=cookieBase+p.join('/');
p.pop();
};
d.shift();
}
}
})();
}
We have kept the logic inside a function to avoid creating javascript variables that could conflit with the logic of the page. We defined cookies in the past for current domain and subdomains to remove cookies.
Code of the bookmarklet
javascript:/*https://jla.ovh/consent*/
['reject-button','reject-all'].forEach(i=>{[...document.getElementsByClassName(i)].map(e=>e.click())});
['appconsent','catfish','cookies-banner','cookieContainer','cookiePolicyPopupHTML','didomi-host','evidon-amp-consent','ez-cookie-dialog-wrapper'
,'js-message-register','onetrust-consent-sdk','sd-cmp','sharingBlock','slidebox','poool-widget','privacy-overlay','qc-cmp2-container','sas_95_s'
,'share','sticky-ad-header','tc-privacy-wrapper'].forEach(i=>{let e=document.getElementById(i);if(e)e.remove()});
['ad','adsbygoogle','article-share','billboard','bloc_center_full_bottom','byline','cc_banner-wrapper','cmp-ban-nocookie','consent','consent-toast'
,'CookieConsent','cookie-notice-container','dailymotion-cpe','featuredStories','gdpr-glm-standard','gdpr-lmd-standard','js-consent-banner'
,'js-dismissable-hero','js-sharebar','OUTBRAIN','pubbanner','publicite','reg_wall','share','share-bar','sharingtb','social','social-icons','socialMenu'
,'social_sidebar','social-share','teads-inread','zIndex--modal'].forEach(i=>{[...document.getElementsByClassName(i)].map(e=>e.remove())});
['aside','footer','iframe'].forEach(i=>{[...document.getElementsByTagName(i)].map(e=>e.remove())});
document.querySelectorAll("div[id^='sp_message_container_']").forEach(i=>{i.remove()});
['appconsent_noscroll','didomi-popup-open','overflow--hidden','popin-gdpr-no-scroll','qc-cmp-ui-showing'
,'sp-message-open'].forEach(i=>{[...document.getElementsByClassName(i)].map(e=>e.classList.remove(i))});
['jStickySize'].forEach(i=>{let e=document.getElementById(i);if(e)e.style.height=""});
['[data-poool-mode]'].forEach(i=>{[...document.querySelectorAll(i)].map(e=>e.style.height="")});
document.querySelectorAll("[class^='ConsentManager']").forEach(i=>{i.remove()});
['html','body'].forEach(i=>document.getElementsByTagName(i)[0].style.overflow=null);
if(!['jla.ovh','mail.google.com','outlook.live.com','twitter.com'].includes(location.hostname)){
/* remove storage only for non-whitelisted domains */
indexedDB.databases().then(r =>{for(i=0;i < r.length;i++)indexedDB.deleteDatabase(r[i].name)});
/* we don't clear Web SQL as there is no way to enumerate or delete these databases */
localStorage.clear();
sessionStorage.clear();
(function(){
let cookies=document.cookie.split("; ");
for(let c=0;c < cookies.length;c++) {
document.cookie=cookies[c].split('=')[0]+'=;expires=Thu, 01 Jan 1970 00:00:00 GMT ;path=/';
let d=window.location.hostname.split(".");
while(d.length > 0){
let cookieBase=encodeURIComponent(cookies[c].split(";")[0].split("=")[0])
+'=; expires=Thu, 01-Jan-1970 00:00:01 GMT; domain='+d.join('.')+' ;path=';
var p=location.pathname.split('/');
document.cookie=cookieBase+'/';
while(p.length>0){
document.cookie=cookieBase+p.join('/');
p.pop();
};
d.shift();
}
}
})();
}
Now you will have both better privacy and productivity when running this code in 1 click from the favorites toolbar. Feel free to update the bookmarklet to increase the accuracy based on your browsing experience.
Enjoy!