Created
October 18, 2020 16:26
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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