Greasy Fork

来自缓存

KAT Enhancements

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

目前为 2014-12-30 提交的版本。查看 最新版本

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

(function (window, document) {
    "use strict";

    // Force https
    if (window.location.protocol == "http:") {
        window.location.replace("https" + window.location.href.substring(4));
        return;
    }

    // Disable pop-up windows
    window.open = function open() {
        return null;
    }

    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.className = (foldClose.className + " ka-180").trim();
                block.className = (block.className + " hideBlockJS").replace(/(^|\s+)showBlockJS($|\s+)/g, " ").trim();
            }
        }
    }

    function onContentLoaded(event) {
        // Apply style sheet to support the max-width layout and hide advertisements
        var head = document.querySelector("head");
        if (head) {
            var style = document.createElement("style");
            style.type = "text/css";
            style.innerHTML = "body { min-width: 0; }" +
                "footer { width: auto; }" +
                ".width900px { width: auto !important; }" +
                ".tabs { overflow: visible; }" +
                ".pages a:not(.blank) { min-width: 15px; padding-left: 7px; padding-right: 7px; }" +
                ".advertising, .partner1Button { display: none; }";

            head.appendChild(style);
        }

        // Max-width 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);
        }

        // 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;
    }

    window.addEventListener("DOMContentLoaded", onContentLoaded, false);

})(window, document);