Twitter Show Sensitive Content

No more extra click to show a stupid tweets!

目前為 2021-12-27 提交的版本,檢視 最新版本

//* eslint-env browser, es6, greasemonkey */
// ==UserScript==
// @name         Twitter Show Sensitive Content
// @namespace    kTu*Kzukf&5p#85%xas!fBH4#GT@FQ7@
// @version      0.1
// @description  No more extra click to show a stupid tweets!
// @author       _SUDO
// @match        https://twitter.com/*
// @icon         https://www.google.com/s2/favicons?domain=twitter.com
// @license      GPL
// @grant        window.onurlchange
// ==/UserScript==

const maxCheckDeepness = 30
let observer = null

function findParent(elem) {
    let tries = maxCheckDeepness
    let currentNode = elem
    let parent = currentNode.parentElement

    while (parent.childElementCount === 1) {
        if (tries <= 0) break;
        tries--
        currentNode = parent
        parent = parent.parentElement
    }

    return parent
}

function findChild(elem) {
    let tries = maxCheckDeepness
    let currentNode = elem
    let child = currentNode.children

    while (child.length === 1) {
        if (tries <= 0) break;
        tries--
        currentNode = child
        child = child[0].children
    }

    return child
}

function unHideTweet(tweetElement) {
    const hidden = tweetElement

    console.log('[M] Hidden container found!', hidden)
    // Now filter until we end up without singles divs and two elements
    let tweet = findChild(hidden) // second element
    console.log('[M] CHILDS:', tweet)
    if (tweet.length === 1) {
        console.log('[M] Only one child found!', tweet[0])
        tweet = tweet[0]
    } else {
        console.log('[M] AAAAAA')
        let running = true
        while (running) {
            console.log('[M] Multiple childs found, filtering one more time...', tweet)
            if (tweet.length === 2 && tweet[0].childElementCount === 0)
                tweet = findChild(tweet[1])
            else {
                tweet = tweet[1]
                running = false
            }
        }
    }

    try {
        // This should click the button instead of the actual container
        // if the container is clicked, the page will be redirected
        tweet.children[0].click()
    } catch (err) {
        // No page interaction, we scheduble click action
        console.error('[M] NO PAGE INTERACTION!', err)
    }
}

function watcher(disconnect = false) {
    if (disconnect && observer) {
        observer.disconnect()
        return
    }

    // Twitter uses articles for every tweet.
    // To use the observer we need to find all tweets parent element
    const target = findParent(document.querySelector('article'))
    const sensitiveContentElement = `div[role="presentation"] > div`

    console.log('Target:', target)

    // Show all elements loaded before the observer registration
    const staticTweets = document.querySelectorAll(sensitiveContentElement)
    if (staticTweets) staticTweets.forEach((e) => unHideTweet(e))

    observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            // Well now we can filter elements
            if (mutation.type === 'childList' && mutation.addedNodes.length) {
                // console.log('[M]', mutation, mutation.type, mutation.type.attributes)
                // console.log('[M]', mutation.addedNodes[0])

                const hidden = mutation.addedNodes[0].querySelector(sensitiveContentElement)
                if (hidden) {
                    unHideTweet(hidden)
                }
            }
        })
    })



    observer.observe(target, {
        childList: true,
        subtree: false,
        characterData: false,
    })
}

function runOnURLChange() {
        if (window.onurlchange === null) {
            window.addEventListener('urlchange', (info) => {
                init()
            })
        } else {
            console.error('window.onurlchange not supported')
        }
    }

async function init() {
    let tries = 30
    while(!document.querySelector('article')) {
        if (tries <= 0) {
            console.error('Max tries excedeed, perhaps the element have changed?')
            break;
        }
        tries--
        await new Promise(r => setTimeout(r, 500));
    }
    // Not elements are loaded :)
    watcher()
}

if (document.readyState === 'complete') init()
else {
    document.addEventListener('readystatechange', (evt) => {
        if (document.readyState === 'complete') init()
    }, {once: true})
}
runOnURLChange()

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址