Greasy Fork

Kickass Torrents Enhancements with Ad Remover

Enhances KickassTorrents (KAT) by forcing HTTPS, using a max-width layout, enabling navigation in search results using the arrow keys and removing ads.

目前为 2015-01-04 提交的版本。查看 最新版本

// ==UserScript==
// @name        Kickass Torrents Enhancements with Ad Remover
// @id          kickass-enhancements
// @namespace   urn:uuid:53d8a5b1-8677-481a-8096-939db3c8d0b3
// @version     1.1.3
// @description Enhances KickassTorrents (KAT) by forcing HTTPS, using a max-width layout, enabling navigation in search results using the arrow keys and removing ads.
// @license     MIT; http://opensource.org/licenses/MIT
// @match       http://kickass.so/*
// @match       https://kickass.so/*
// @grant       unsafeWindow
// @run-at      document-start
// ==/UserScript==

"use strict";

(function (unsafeWindow) {

    // Force HTTPS
    if (/^http:\/\//.test(window.location.href)) {
        window.location.replace(window.location.href.replace(/^http:\/\//, "https://"));
        return;
    }

    // Disable pop-up windows
    (function () {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.textContent = "window.open = function open() { return null; };";

        // Run script before any other script is run
        (document.documentElement || document).appendChild(script);
        script.parentNode.removeChild(script);
    })();

    // Continue when DOM is available
    document.addEventListener("DOMContentLoaded", onContentLoaded, true);

    var contentContainer;
    var sidebar;
    var prevPageHref;
    var nextPageHref;
    var sidebarToggled;

    function closeSidebarSections() {
        // Avoid closing sidebar sections after user interaction
        if (sidebarToggled)
            return;

        var sections = sidebar.querySelectorAll(".sliderbox");
        var i = sections.length - 1;

        // Close sidebar sections while the viewport is shorter than the document and sidebar is higher than content
        while (i >= 0 && window.innerWidth > document.documentElement.clientWidth && sidebar.offsetTop + sidebar.offsetHeight > contentContainer.offsetTop + contentContainer.offsetHeight) {
            var section = sections[i--];
            var foldClose = section.querySelector(".foldClose");
            var block = section.querySelector(".showBlockJS");

            if (foldClose && block) {
                foldClose.classList.add("ka-180");
                block.classList.remove("showBlockJS");
                block.classList.add("hideBlockJS");
            }
        }
    }

    function onContentLoaded() {
        document.removeEventListener("DOMContentLoaded", onContentLoaded, true);

        // Force HTTPS for KickassTorrents and Torcache links
        var items = document.querySelectorAll("a[href^=\"http://kickass.so/\"], link[href^=\"http://kickass.so/\"], a[href^=\"http://torcache.net/\"]");
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            item.href = item.href.replace(/^http:\/\//, "https://")
        }

        // Inline referrer anonymizer (for IMDb links)
        var items = document.querySelectorAll("a[href^=\"http://anonym.to/?http\"]");
        for (var i = 0; i < items.length; i++) {
            var a = items[i];
            var match = a.href.match(/^http:\/\/anonym\.to\/\?(https?:\/\/.*)$/);
            if (!match)
                return;

            var encodedURL = match[1].replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

            var html = "<!DOCTYPE html>" +
                "<html>" +
                "<head>" +
                "<meta http-equiv=\"refresh\" content=\"0;url=" + encodedURL + "\">" +
                "</head>" +
                "</html>";

            a.href = "data:text/html;charset=utf-8," + encodeURIComponent(html);
        }

        // Apply style sheet to support the max-width layout and hide advertisements
        var style = document.createElement("style");
        style.type = "text/css";
        style.textContent = "body { min-width: 0; }" +
            "footer { width: auto; }" +
            ".tabs { overflow: visible; }" +
            "ul.tabNavigation li a span { padding-left: 7px; padding-right: 7px; }" +
            ".pages a:not(.blank) { min-width: 15px; padding-left: 7px; padding-right: 7px; }" +
            ".advertising, .partner1Button { display: none; }";
        document.head.appendChild(style);

        // Select original content container
        var mainContent = document.querySelector(".mainpart .doublecelltable td");
        sidebar = document.getElementById("sidebar");
        if (!mainContent && !sidebar)
            mainContent = document.querySelector(".mainpart");

        // Create max-width content container
        if (mainContent) {
            contentContainer = document.createElement("div");
            contentContainer.style.margin = "15px auto 0";
            contentContainer.style.maxWidth = "900px";

            while (mainContent.firstChild)
                contentContainer.appendChild(mainContent.firstChild);

            // Include float elements in parent height
            var clearDiv = document.createElement("div");
            clearDiv.style.clear = "both";
            contentContainer.appendChild(clearDiv);

            mainContent.appendChild(contentContainer);

            // Remove width from original content container
            var items = contentContainer.querySelectorAll(":scope > div.margauto");
            for (var i = 0; i < items.length; i++) {
                var item = items[i];
                if (/(^|\s)width[0-9]+px($|\s)/.test(item.className))
                    item.style.setProperty("width", "auto", "important");
            }
        }

        // Hide advertisements
        var items = document.evaluate("//div[starts-with(@id, '_') and string-length(@id) = 33 and not(parent::*[@id = 'sidebar'])]", document, null, 6 /*UNORDERED_NODE_SNAPSHOT_TYPE*/, null);
        for (var i = 0; i < items.snapshotLength; i++)
            items.snapshotItem(i).style.display = "none";

        // Hide single tabs with no content (Sponsored Links)
        var items = document.querySelectorAll(".tabs");
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            if (!item.querySelector(":scope > :not(.tabNavigation):not(.tabsSeparator)") && document.evaluate("not(descendant::li[2])", item, null, 3 /*BOOLEAN_TYPE*/, null).booleanValue)
                item.style.display = "none";
        }

        // Hide line breaks after hidden elements
        var items = document.querySelectorAll("* + br");
        for (var i = 0; i < items.length; i++) {
            var br = items[i];

            // Ignore line breaks after visible elements
            if (window.getComputedStyle(br.previousElementSibling, null).display != "none")
                continue;

            for (var prevNode = br.previousSibling; prevNode; prevNode = prevNode.previousSibling) {
                switch (prevNode.nodeType) {
                    case 1 /*ELEMENT_NODE*/:
                        // Found previous hidden element
                        br.style.display = "none";
                        break;
                    case 3 /*TEXT_NODE*/:
                        // Ignore white space
                        if (!/\S/.test(prevNode.textContent))
                            continue;
                        break;
                    default:
                        // Ignore comments
                        continue;
                }

                // Found text between the line break and the previous element
                break;
            }
        }

        // Enhance navigation
        var activePages = document.querySelectorAll(".pages a.active");
        for (var i = 0; i < activePages.length; i++) {
            var activePage = activePages[i];
            var parent = activePage.parentNode;

            // Add Prev button
            var prevPage = document.evaluate("preceding-sibling::a[1]", activePage, null, 8 /*ANY_UNORDERED_NODE_TYPE*/, null).singleNodeValue;
            if (prevPage) {
                if (i == 0)
                    prevPageHref = prevPage.href;

                prevPage = prevPage.cloneNode(false);
                prevPage.textContent = "< Prev";
                parent.insertBefore(prevPage, parent.firstElementChild);
            }

            // Add Next button
            var nextPage = document.evaluate("following-sibling::a[1]", activePage, null, 8 /*ANY_UNORDERED_NODE_TYPE*/, null).singleNodeValue;
            if (nextPage) {
                if (i == 0)
                    nextPageHref = nextPage.href;

                nextPage = nextPage.cloneNode(false);
                nextPage.textContent = "Next >";
                parent.insertBefore(nextPage, parent.lastElementChild.nextSibling);
            }
        }

        // Navigate using arrow keys
        if (prevPageHref || nextPageHref)
            window.addEventListener("keypress", onKeyPress, false);

        if (sidebar && contentContainer) {
            // Detect sidebar user interaction
            var items = sidebar.querySelectorAll(".sliderbox .foldClose");
            for (var i = 0; i < items.length; i++)
                items[i].addEventListener("click", onFoldCloseClick, false);

            closeSidebarSections();

            // Close sidebar sections again after images are loaded
            window.addEventListener("load", closeSidebarSections, false);

            // Close sidebar sections when window is resized
            window.addEventListener("resize", closeSidebarSections, false);
        }
    }

    function onKeyPress(event) {
        switch (event.key) {
            case "Left":
                if (prevPageHref)
                    window.location.assign(prevPageHref);
                break;
            case "Right":
                if (nextPageHref)
                    window.location.assign(nextPageHref);
                break;
            default:
                return;
        }

        event.preventDefault();
    }

    function onFoldCloseClick() {
        sidebarToggled = true;
    }

})(void(0));