const getInitialTweets = () => [...document.querySelectorAll('.js-stream-item')] const nonchrono = e => { for (typ of ['follower', 'promoted', 'heartBadge']) { if (e.querySelector(`.context .Icon--${typ}`)) { return true; } } return false; } const decorate = e => e.style.border = "10px solid red"; const remove = e => e.remove(); const handler = decorate; const processTweets = tweets => tweets.filter(nonchrono).forEach(handler); const createTweetObserver = () => { return new MutationObserver(mut => processTweets([...mut[0].addedNodes])) } const attachTweetObserver = observer => { const config = { attributes: false, childList: true, subtree: false }; const target = document.querySelector('ol.js-navigable-stream') observer.observe(target, config) } const attachDocObserver = (tweetObserver) => { const config = { attributes: true, childList: false, subtree: false }; const handler = mut => { tweetObserver.disconnect(); if (mut[0].target.classList.contains('route-home')) { processTweets(getInitialTweets()); attachTweetObserver(tweetObserver); } } const observer = new MutationObserver(handler); observer.observe(document.getElementById('doc'), config); } const tweetObserver = createTweetObserver(); processTweets(getInitialTweets()); attachTweetObserver(tweetObserver); attachDocObserver(tweetObserver);