Greasy Fork

Greasy Fork is available in English.

oneClickDeleteInstagramPost 一键删除 Instagram 帖子

在 Instagram 的个人页面的图片上添加 [Delete] 按钮,点击直接删除图片,不再有确认提示框

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name                oneClickDeleteInstagramPost
// @name:en             oneClickDeleteInstagramPost
// @name:ja             oneClickDeleteInstagramPost ワンクリックで削除 Post
// @name:zh-CN          oneClickDeleteInstagramPost 一键删除 Instagram 帖子
// @name:zh-TW          oneClickDeleteInstagramPost 一鍵刪除 Instagram 帖子
// @namespace           https://github.com/catscarlet/oneClickDeleteInstagramPost
// @description         Add [Delete] button on the post in Personal Page on Instagram. Directly delete post without confirm.
// @description:en      Add a [Delete] button to the Personal Page on Instagram. Directly delete post without confirm.
// @description:ja      Instagramの個人ページの投稿に[削除]ボタンを追加してください。 確認なしで投稿を直接削除します。
// @description:zh-CN   在 Instagram 的个人页面的图片上添加 [Delete] 按钮,点击直接删除图片,不再有确认提示框
// @description:zh-TW   在 Instagram 的個人頁面的圖片上添加 [Delete] 按鈕,點擊直接刪除图片,不再有確認提示框
// @version             1.1.1
// @author              catscarlet
// @license             MIT License
// @match               *://www.instagram.com/*
// @require             https://cdn.jsdelivr.net/npm/[email protected]/bignumber.min.js
// @run-at              document-end
// @grant               none
// ==/UserScript==

(function() {
    'use strict';

    let safe_lock = 1; //Set this to 0 to unlock the 'Delete this' button.
    let show_alt = 0; //Hide alt by default. Set this to 1 to show alt of images.

    const InstagramConvert = {
        charset: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
        decode: url => {
            let result = BigInt(0);
            let power = BigInt(1);

            for (let i = url.length - 1; i >= 0; i--) {
                const char = url[i];
                const index = InstagramConvert.charset.indexOf(char);
                result += BigInt(index) * power;
                power *= BigInt(64);
            }
            return result.toString();
        },
    };

    let old_path = '';
    let new_path = '';
    let temp_lock = 0;

    historyPushStateMonitor(window.history);
    historyOnpushstate();

    history.onpushstate = function(e) {
        goPendingUrl();
    };

    window.onpopstate = function(event) {
        goPendingUrl();
    };

    function historyPushStateMonitor(history) {
        let pushState = history.pushState;
        history.pushState = function(state) {
            old_path = location.pathname.toString();

            if (typeof history.onpushstate == 'function') {
                history.onpushstate({state: state});
            }

            return pushState.apply(history, arguments);
        };
    }

    function goPendingUrl() {
        new_path = location.pathname.toString();

        if (old_path == new_path) {
            setTimeout(goPendingUrl, 1000);
        } else {
            historyOnpushstate();
        }
    }

    function historyOnpushstate() {
        pending();
    }

    function pending() {
        let article = document.querySelectorAll('.xg7h5cd.x1n2onr6');
        if (!article.length) {
            setTimeout(pending, 500);
        } else {
            ob();
            getPost();
        }
    }

    function ob() {
        let articles = document.querySelector('.xg7h5cd.x1n2onr6').children[0].children[0];

        let observerOptions = {
            childList: true,
            attributes: false,
            subtree: true,
        };

        let observer = new MutationObserver(getPost);

        observer.observe(articles, observerOptions);
    }

    function getPost() {
        let articles = document.querySelector('.xg7h5cd.x1n2onr6').children[0].children[0];
        let own_it = pageOwnerCheck();

        for (let articlesline of articles.children) {
            for (let post of articlesline.children) {
                let link = post.children[0];
                if (!link) {
                    return false;
                }
                if (link.hasAttribute('alte')) {
                    continue;
                }

                let url = link.href;
                let urlSegment = GetUrlSegmentByUrl(url);
                if (!urlSegment) {
                    continue;
                }
                let block = link.children[0];
                let img = block.children[0].children[0];
                let alt = img.alt;

                let btn_div = document.createElement('div');
                btn_div.style.height  = '2rem';
                let media_id = getMediaIdByUrlSegment(urlSegment);

                let btn = document.createElement('button');
                btn.innerHTML = 'delete this: ' + media_id;
                btn.style.backgroundColor  = 'darksalmon';
                btn.onclick = function() {
                    deleteByMediaId(media_id, btn, post);
                };

                post.classList.add('oneClickDeleteInstagramPost_post');

                btn_div.className = 'btn_div';

                if (own_it) {
                    if (safe_lock) {
                        btn.disabled = true;
                        btn.title = 'Safe_lock is ON! You need to edit the script and change the "safe_lock" to 0 in order to delete your post without confirm.';
                    }
                    btn_div.appendChild(btn);
                    post.appendChild(btn_div);
                }

                let alt_div = document.createElement('div');
                alt_div.className = 'alt_div';
                alt_div.style.height  = '1rem';
                let alt_div_style = 'word-break: break-word;';
                if (!show_alt) {
                    alt_div_style += 'display: none;';
                }
                alt_div.innerHTML = '<span style="' + alt_div_style + '">' + alt + '</span>';
                post.appendChild(alt_div);

                let post_style = 'height: calc(' + post.offsetHeight + 'px - 3rem); margin-bottom: 3rem;';
                post.style = post_style;

                link.setAttribute('alte', 1);
            }
        }
    };

    function GetUrlSegmentByUrl(url) {
        let regexp = /https:\/\/www.instagram.com\/(\S+)\/p\/(\?taken-by=\S+)?/;
        let result = url.match(regexp);
        if (result) {
            return result[1];
        } else {
            return false;
        }
    }

    function getMediaIdByUrlSegment(urlSegment) {
        let id = InstagramConvert.decode(urlSegment);

        return id;
    }

    function deleteByMediaId(media_id, btn, post) {
        btn.innerHTML = 'deleting';
        btn.style.backgroundColor  = 'yellow';
        btn.onclick = false;
        btn.disabled = true;

        let url = 'https://www.instagram.com/api/v1/web/create/' + media_id + '/delete/';

        let xmlhttp = new XMLHttpRequest();
        xmlhttp.open('POST', url, true);
        xmlhttp.setRequestHeader('X-CSRFToken', window._sharedData.config.csrf_token);
        xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlhttp.send(null);

        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {
                if (xmlhttp.status == 200) {
                    let rst = JSON.parse(xmlhttp.response);
                    if (rst.did_delete) {
                        post.style.visibility = 'hidden';
                    } else {
                        btn.innerHTML = 'Failed';
                    }
                } else {
                    btn.innerHTML = 'Failed';
                }
            }
        };
    }

    function pageOwnerCheck() {
        let not_own_it = 0;
        let match_regex = /https:\/\/www.instagram.com\/([^\/]+)\/$/;
        let href = location.href;

        let array1 = match_regex.exec(href);
        if (array1 !== null) {
            if (array1[1] == 'explore') {
                not_own_it++;
            }
        }

        if (document.getElementsByClassName('fx7hk').length && document.getElementsByClassName('fx7hk')[0].childElementCount == 2) {
            not_own_it += 2;
        }

        return !not_own_it;
    };
})();