element-hq / element-web

A glossy Matrix collaboration client for the web.
https://element.io
GNU Affero General Public License v3.0
11.19k stars 2k forks source link

Anonymized screenshots - Lorem Ipsemifier - dummy text #9615

Open lampholder opened 5 years ago

lampholder commented 5 years ago

A devtools tool to temporarily switch all message text with lorem ipsum (plus generated avatars and display names) so that people can submit anonymised screen captures that don't look like a blurry disaster.

MadLittleMods commented 2 years ago

To add some keywords:

Screenshot mockup:

https://codepen.io/MadLittleMods/pen/VwyJEOE

You can also see a video demo of this in action: https://youtu.be/n78tHoCx1es?t=252

JavaScript to create screenshot mockup ```js // Wraps every text node with `span.anonymous-text-block` which can // be styled to make all text into color blocks to anonymize it. function anonymizeContentInNode(node) { // This is just nested here to make it easy to copy-paste a single function const template = document.createElement('template'); function createNodesFromHtml(html) { template.innerHTML = html; return template.content.childNodes; } // Loop through each child in the given node let nextSibling; for (node = node.firstChild; node; node = nextSibling) { // Record this before we potentially replace the node below and it will lose its siblings // and seems to freeze the browser. nextSibling = node.nextSibling; // Don't mangle styles and scripts if (node.tagName && ['style', 'script'].includes(node.tagName.toLowerCase())) { continue; } // Don't anonymize twice if this function is run more than once (while testing). // This is not related to the recursive nature of this function. if (node.classList && node.classList.contains('anonymous-text-block')) { continue; } // Only text nodes if (node.nodeType === 3) { const newNodes = []; // Split the text by whitespace [...node.textContent.matchAll(/(\s*)(\S*)(\s*)/g)].forEach(([_, padStart, text, padEnd]) => { // Ensure the white-space is maintained newNodes.push(...createNodesFromHtml(padStart)); // No need to touch empty nodes if (text.length !== 0) { const html = `${text}`; newNodes.push(...createNodesFromHtml(html)); } // Ensure the white-space is maintained newNodes.push(...createNodesFromHtml(padEnd)); }); // Replace the text node with our wrapped text that we can style with CSS node.replaceWith(...newNodes); } else { // Recursively call for each element anonymizeContentInNode(node); } } } anonymizeContentInNode(document.querySelector('body')); // Add some CSS styles document.body.insertAdjacentHTML('beforeend', ` `); document.body.classList.add('should-anonymize'); ```

Right now it’s a general script that runs on any page and replaces all text nodes on the page. But we don’t need to replace all text nodes. The normal strings in the UI aren’t sensitive. We only need to apply this to user-generated content that is sensitive like messages, room names, and things like IP’s and keys in the settings, etc. So this could benefit from some deeper integration in Element itself.


Probably related to the skeleton UI (placeholder content before a SPA hydrates with real content) styles we already have in place:

Another example is the code syntax minimap styles you would see in a code editor (VSCode, Atom, Sublime):


When in this mode, it would also be interesting to add some event_id labels in the corner of each messages for better debugging. Possibly room_id's as well for the room list. That way you can easily correlate the logs to the screenshot.

JokerGermany commented 2 years ago

Only the profile pictures of the member list of the room is blurred, not the names.

JokerGermany commented 2 years ago

And which command is needed to unblur?

JokerGermany commented 2 years ago

And the rooms aren't blurred, too grafik

MadLittleMods commented 2 years ago

@JokerGermany This is very noisy and this issue is not really the place to nitpick the proof of concept (obviously not perfect and just made to craft a screenshot to show what's possible). Probably best to chat in https://matrix.to/#/#element-web:matrix.org and you can also see people sharing concerns when I first posted it in the TWIM room.

The JavaScript snippet, simply color blocks all text currently on the page. If the page updates in any way, that text won't also be obscured. Details on the design can change in any way when we actually implement something (it's not even designed atm, just me as a developer).

To unblur stuff, you will need to refresh the page.