Skip to content

Instantly share code, notes, and snippets.

@jhancock532
Created October 18, 2020 16:26
Show Gist options
  • Save jhancock532/64b15a90a82ba184ec9c47f6db4ecf84 to your computer and use it in GitHub Desktop.
Save jhancock532/64b15a90a82ba184ec9c47f6db4ecf84 to your computer and use it in GitHub Desktop.
Mozilla Firefox extension that visualises the ghost of the tweets we've scrolled past.
//Don't use HTML2Canvas as part of a browser extension. Just don't. Trust me.
//For more information, see the bottom of the FAQ's at http://html2canvas.hertzen.com/faq
setTimeout(function tick() {
let timelineContainers = document.querySelectorAll('[aria-label="Timeline: Your Home Timeline"]');
let tweets = timelineContainers[0].children[0].children;
let timeline = timelineContainers[0].children[0];
for (let i = 0; i < tweets.length; i++){
tweets[i].setAttribute('scrolledpast','false');
console.log(tweets[i]);
}
// From https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
// Options for the observer (which mutations to observe)
const config = { childList: true, subtree: false };
// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
tweets = timelineContainers[0].children[0].children;
for (let i = 0; i < tweets.length; i++){
if (tweets[i].hasAttribute("scrolledpast") == false) {
tweets[i].setAttribute("scrolledpast", "false");
}
}
}
}
}
window.addEventListener('scroll', function(){
lastYScrollPosition = window.scrollY;
for (let i = 0; i < tweets.length; i++){
if (tweets[i].getAttribute("scrolledpast") == "false"){
let yPosition = getTranslatedYPosition(tweets[i]);
if (yPosition < lastYScrollPosition) {
let clonedTweet = tweets[i].cloneNode(true);
let leftPosition = Math.random() * window.innerWidth;
let topPosition = Math.random() * window.innerHeight / 1.5;
if (leftPosition > window.innerWidth - 500){
leftPosition -= 500;
}
clonedTweet.style.left = leftPosition.toString() + "px";
clonedTweet.style.zIndex = "100";
clonedTweet.style.position = "fixed";
clonedTweet.style.transform = "";
clonedTweet.style.top = topPosition.toString() + "px"; //Set this to "0" to replicate the first experiment.
clonedTweet.style.width = "500px";
clonedTweet.style.background = "black";
clonedTweet.style.opacity = "1"; //Set this to "0.1" to replicate the ghost experiments.
clonedTweet.style.pointerEvents = "none";
document.body.appendChild(clonedTweet);
tweets[i].setAttribute("scrolledpast", "true");
tweets[i].style.display = none;
}
}
}
}, true);
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(timeline, config);
}, 3000); //Wait a couple seconds for the tweet container to load in.
//Code speaks its own language of control and structure.
//Words can be intrepreted within an infinite number of contexts,
//but for many programs, there is only one interpretation that matters.
/**
* Code from https://zellwk.com/blog/css-translate-values-in-javascript/
* Gets computed translate values
* @param {HTMLElement} element
* @returns {Object}
*/
function getTranslatedYPosition (element) {
const style = window.getComputedStyle(element)
const matrix = style['transform'] || style.webkitTransform || style.mozTransform
// No transform property. Simply return 0 values.
if (matrix === 'none') {
return 0;
}
// Can either be 2d or 3d transform
const matrixType = matrix.includes('3d') ? '3d' : '2d'
const matrixValues = matrix.match(/matrix.*\((.+)\)/)[1].split(', ')
// 2d matrices have 6 values
// Last 2 values are X and Y.
// 2d matrices does not have Z value.
if (matrixType === '2d') {
return matrixValues[5];
}
// 3d matrices have 16 values
// The 13th, 14th, and 15th values are X, Y, and Z
if (matrixType === '3d') {
return matrixValues[13];
}
}
{
"manifest_version": 2,
"name": "Content Aggregation",
"version": "1.0",
"description": "Performs content aggregation of Twitter tweets, visualising the traces they leave behind in our minds and how that can obscure our perception.",
"icons": {
"48": "icons/icon-48.png",
"96": "icons/icon-96.png"
},
"content_scripts": [
{
"matches": ["*://twitter.com/*"],
"js": ["content-aggregation.js"]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment