nicolaslegland / mute

// ==UserScript==
// @author      Nicolas Le Gland
// @copyright   2018, nicolaslegland (https://openuserjs.org/users/nicolaslegland)
// @description Mute promoted tweets.
// @downloadURL https://openuserjs.org/src/scripts/nicolaslegland/mute.user.js
// @exclude     https://twitter.com/i/*
// @grant       none
// @homepageURL https://openuserjs.org/scripts/nicolaslegland/mute
// @icon        https://twitter.com/favicon.ico
// @include     https://twitter.com/*
// @installURL  https://openuserjs.org/src/scripts/nicolaslegland/mute.user.js
// @license     GPL-3.0-or-later
// @name        mute
// @run-at      document-end
// @supportURL  https://openuserjs.org/scripts/nicolaslegland/mute/issues
// @updateURL   https://openuserjs.org/src/scripts/nicolaslegland/mute.user.js
// @version     12
// ==/UserScript==

// Find and remove promoted tweets
function gFind()
{
    // Suspend observer
    g_oObserver.disconnect();
    window.clearTimeout(g_oTimer);

    // Loop through Tweet list
	var l_oList = document.getElementsByClassName('tweet'),
        l_iCount = l_oList.length,
        l_iIndex = 0;
    while (l_iIndex !== l_iCount)
    {
        // Look for promoted icon
        var l_oTweet = l_oList[l_iIndex];
        if (1 === l_oTweet.getElementsByClassName('Icon--promoted').length)
        {
            // Look for link to tweet
            var l_oLink = l_oTweet.getElementsByClassName('tweet-timestamp');
            if (1 === l_oLink.length)
            {
                // Log call
                var l_oDate = new Date(),
                    l_sMonth = '0' + (l_oDate.getMonth() + 1),
                    l_sDay = '0' + (l_oDate.getDate() + 1),
                    l_sHour = '0' + l_oDate.getHours(),
                    l_sMinute = '0' + l_oDate.getMinutes(),
                    l_sSecond = '0' + l_oDate.getSeconds(),
                    l_sMillisecond = '00' + l_oDate.getMilliseconds();
                console.log(
                    l_oDate.getFullYear() + '-' + l_sMonth.substr(l_sMonth.length - 2, 2) + '-' + l_sDay.substr(l_sDay.length - 2, 2) + ' ' +
                    l_sHour.substr(l_sHour.length - 2, 2) + ':' + l_sMinute.substr(l_sMinute.length - 2, 2) + ':' + l_sSecond.substr(l_sSecond.length - 2, 2) + '.' + l_sMillisecond.substr(l_sMillisecond.length - 3, 3) + ' ' +
                    GM_info.script.homepage + ' ' + l_oLink[0].href);

                // Hide the promoted tweet
                l_oTweet.parentNode.style.display = 'none';

                // Replace it with a hidden iframe to the promoted account
                l_oTweet.innerHTML = '<iframe src="' + l_oLink[0].href + '" width="100%"></iframe>';

                // Observe iframe loading
                l_oTweet.getElementsByTagName('iframe')[0].addEventListener('load', function()
                                                                            {
                    // Click the Mute button
                    this.contentDocument.getElementsByClassName('mute-user-item')[0].click();
                });
            }
        }
        ++l_iIndex;
    }

    // Restart observer
    g_oObserver.observe(document.body,
    {
        childList: true,
        subtree: true,
    });
}

// Obverse additions of nodes
var g_oObserver = new MutationObserver(function ()
{
    // Rearm delayed process
    window.clearTimeout(g_oTimer);
    g_oTimer = window.setTimeout(gFind, 1000);
}),

// Delay process
g_oTimer = window.setTimeout(gFind, 1000);