Skip to content

Instantly share code, notes, and snippets.

@IceCreamYou
Last active March 5, 2024 11:18
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IceCreamYou/4f085b180a1608b99cb2 to your computer and use it in GitHub Desktop.
Save IceCreamYou/4f085b180a1608b99cb2 to your computer and use it in GitHub Desktop.
Blurs Google Calendar event names to make it easier to share screenshots of your availability.

Sometimes for scheduling purposes it would be nice to be able to take a screenshot of your calendar and send it to someone, but you may not want to show that someone the names of every event on your calendar. This code and bookmarklet solves that problem by blurring out event names on your calendar.

Here is the code:

var style = document.getElementById('--style') || document.createElement('style'), // <style> element holding blur/hide rules
    spans = document.querySelectorAll('[data-eventchip] span'); // This worked as of May 3, 2023 but it may change.

// Add the styles
style.id = '--style';
style.innerHTML = trustedTypes.createPolicy('forceInner', { createHTML: (t) => t }).createHTML(`
    .--blur { -webkit-filter: blur(4px); filter: blur(4px); }
    .rsvp-no-chip.--hide, .rsvp-no-bg.--hide { opacity: 0; }
`);
document.head.appendChild(style);

// Blur active event titles
for (var i = 0, l = spans.length; i < l; i++) {
    spans[i].classList.toggle('--blur');
}

Run it once (e.g. in the browser console) to blur, then run it again to un-blur.

And here is that code as a bookmarklet:

javascript:void%20function(){var%20a=document.getElementById(%22--style%22)||document.createElement(%22style%22),b=document.querySelectorAll(%22[data-eventchip]%20span%22);a.id=%22--style%22,a.innerHTML=trustedTypes.createPolicy(%22forceInner%22,{createHTML:a=%3Ea}).createHTML(`
%20%20%20%20.--blur%20{%20-webkit-filter:%20blur(4px);%20filter:%20blur(4px);%20}
%20%20%20%20.rsvp-no-chip.--hide,%20.rsvp-no-bg.--hide%20{%20opacity:%200;%20}
`),document.head.appendChild(a);for(var%20c=0,d=b.length;c%3Cd;c++)b[c].classList.toggle(%22--blur%22)}();

This page doesn't allow linking bookmarklets, so you'll need to add the bookmarklet manually.

@kovasap
Copy link

kovasap commented Aug 3, 2021

For someone else coming across this in the future, the class names have indeed changed and are random character strings that change every page load (AFAIK) :(. This alternative code will blur all spans on the page, which has a similar effect:

// These class names were recorded on February 8, 2016 and may change.
var style = document.getElementById('--style') || document.createElement('style'), // <style> element holding blur/hide rules
    spans = document.getElementsByTagName('span');

// Add the styles
style.id = '--style';
style.innerHTML = '.--blur { -webkit-filter: blur(4px); filter: blur(4px); }\
                   .rsvp-no-chip.--hide, .rsvp-no-bg.--hide { opacity: 0; }';
document.head.appendChild(style);

// Blur active event titles
for (var i = 0, l = spans.length; i < l; i++) {
    spans[i].classList.toggle('--blur');
}

@swbrattain
Copy link

swbrattain commented Jul 28, 2022

The second one that pulls elements by span tag is nice, but it also blurs out the times on the side of the calendar which then essentially renders this unusable for the intended purpose. Anyone have ideas how to fix this?

Update:
This works for Chrome current as of today:

var style = document.getElementById('--style') || document.createElement('style'), // <style> element holding blur/hide rules
spans = document.getElementsByTagName('span');

// Add the styles
style.id = '--style';
style.innerHTML = '.--blur { -webkit-filter: blur(4px); filter: blur(4px); }
.rsvp-no-chip.--hide, .rsvp-no-bg.--hide { opacity: 0; }';
document.head.appendChild(style);

// Blur active event titles
for (var i = 0, l = spans.length; i < l; i++) {
if (spans[i].classList.contains('FAxxKc')){
spans[i].classList.toggle('--blur');
}
}

@IceCreamYou
Copy link
Author

I updated the original post. At least for now, the selector [data-eventchip] span (as opposed to just span) will select only calendar events. This works for full-day events too.

@c-harding
Copy link

What does the .rsvp-no-chip.--hide selector apply to?

@c-harding
Copy link

This is my own version, which blurs all entries (unblurs on second run), and displays calendar times too, as these were being blurred out.

// These selectors were recorded on 2023-02-03 and may change.
{
    let style;
    if ((style = document.getElementById('--style'))) style.remove();
    else {
        style = document.createElement('style'); // <style> element holding blur/hide rules
    
        // Add the styles
        style.id = '--style';
        style.innerHTML = `
            [data-eventchip]::after {
                content: attr(data-time) !important;
                position: absolute;
                z-index: 2;
                color: black;
                left: 4px;
                font-size: 11px;
                text-shadow: 0 0 3px white;
            }
            [data-eventchip] div {
                -webkit-filter: blur(4px);
                filter: blur(4px);
            }
        `;
        document.head.appendChild(style);
    }
    [...document.querySelectorAll('[data-eventchip]')].forEach(chip => {
        chip.dataset.time = (chip.textContent.match(/\d\d?:\d\d – \d\d?:\d\d/) ?? chip.textContent.match(/\d\d?:\d\d?/))?.[0]??''
    })
}
javascript:(function(){let style;if((style=document.getElementById('--style')))style.remove();else{style=document.createElement('style');style.id='--style';style.innerHTML='[data-eventchip]::after{content:attr(data-time)!important;position:absolute;z-index:2;left:4px;font-size:11px;text-shadow:0 0 3px white;}[data-eventchip] div{-webkit-filter:blur(4px);filter:blur(4px)}';document.head.appendChild(style);}const timeRegex=/^\d\d?:\d\d( – \d\d?:\d\d)?/;[...document.querySelectorAll('[data-eventchip]')].forEach(chip=>chip.dataset.time=(chip.textContent.match(/\d\d?:\d\d – \d\d?:\d\d/)??chip.textContent.match(/\d\d?:\d\d?/))?.[0]??'')})()

@swbrattain
Copy link

Is it possible to blur the locations too?

@c-harding
Copy link

@swbrattain the version I posted does blur the locations

@aurelijusrozenas
Copy link

aurelijusrozenas commented May 3, 2023

Is it just me, or it stopped working? I was really fond of it 😊
Oh I see, there is an error This document requires 'TrustedHTML' assignment..

@swbrattain
Copy link

@IceCreamYou
Copy link
Author

I just updated the original post with a fix.

@aurelijusrozenas
Copy link

aurelijusrozenas commented May 4, 2023

EDIT: haha, @IceCreamYou beat me to it :)

Updated @c-harding variant:

{
    escapeHTMLPolicy = trustedTypes.createPolicy("forceInner", {
        createHTML: (to_escape) => to_escape
    });
    let style;
    if ((style = document.getElementById('--style'))) style.remove();
    else {
        style = document.createElement('style'); // <style> element holding blur/hide rules

        // Add the styles
        style.id = '--style';
        style.innerHTML = escapeHTMLPolicy.createHTML(`
            [data-eventchip]::after {
                content: attr(data-time) !important;
                position: absolute;
                z-index: 2;
                color: black;
                left: 4px;
                font-size: 11px;
                text-shadow: 0 0 3px white;
            }
            [data-eventchip] div {
                -webkit-filter: blur(4px);
                filter: blur(4px);
            }
        `);
        document.head.appendChild(style);
    }
    [...document.querySelectorAll('[data-eventchip]')].forEach(chip => {
        chip.dataset.time = (chip.textContent.match(/\d\d?:\d\d – \d\d?:\d\d/) ?? chip.textContent.match(/\d\d?:\d\d?/))?.[0]??''
    })
}
javascript:(function()%7B%7Blet%20escapeHTMLPolicy%20%3D%20trustedTypes.createPolicy(%22forceInner%22%2C%20%7BcreateHTML%3A%20(to_escape)%20%3D%3E%20to_escape%7D)%3Blet%20style%3Bif%20((style%20%3D%20document.getElementById('--style')))%20%7Bstyle.remove()%3B%7D%20else%20%7Bstyle%20%3D%20document.createElement('style')%3Bstyle.id%20%3D%20'--style'%3Bstyle.innerHTML%20%3D%20escapeHTMLPolicy.createHTML(%60%5Bdata-eventchip%5D%3A%3Aafter%20%7Bcontent%3A%20attr(data-time)%20!important%3Bposition%3A%20absolute%3Bz-index%3A%202%3Bcolor%3A%20black%3Bleft%3A%204px%3Bfont-size%3A%2011px%3Btext-shadow%3A%200%200%203px%20white%3B%7D%5Bdata-eventchip%5D%20div%20%7B-webkit-filter%3A%20blur(4px)%3Bfilter%3A%20blur(4px)%3B%7D%60)%3Bdocument.head.appendChild(style)%3B%7D%5B...document.querySelectorAll('%5Bdata-eventchip%5D')%5D.forEach(chip%20%3D%3E%20%7Bchip.dataset.time%20%3D%20(chip.textContent.match(%2F%5Cd%5Cd%3F%3A%5Cd%5Cd%20%E2%80%93%20%5Cd%5Cd%3F%3A%5Cd%5Cd%2F)%20%3F%3F%20chip.textContent.match(%2F%5Cd%5Cd%3F%3A%5Cd%5Cd%3F%2F))%3F.%5B0%5D%20%3F%3F%20''%7D)%7D%7D)()

@CM217217
Copy link

CM217217 commented Jan 5, 2024

I stumbled across this but am not familiar with or comfortable using this method. However, I did stumble across a Chrome Extension called Obfuscate-calendar that does exactly this. Just thought I would share in case others that are not comfortable with this method also stumble across this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment