xkcd Tweaks

Some tweaks to xkcd.com and what-if.xkcd.com

目前为 2016-08-10 提交的版本。查看 最新版本

// ==UserScript==
// @name          xkcd Tweaks
// @description   Some tweaks to xkcd.com and what-if.xkcd.com
// @include       /^(https?:)?(\/\/)?(www\.)?(what-?if\.)?xkcd\.com/
// @icon          data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABX0lEQVRYhcWVMZIEIQhFOYrhHM8baGjoEbyRYYcehY2cchXwt7O9Q1VXzQDKAxSJiPjLH/G3xARwzi20zrnnAaTAT4GIAGjvJAkhLH4hBBxgzl5ZIFbBqpxWsQXAyk4CQYJbEH8GcNo2EQAVC2CU1to9gE8rIJW6t2gLoDlKC8dAyPWEAOZslAWLDYWGAE5ONBFxa00N3s8BBGCBbO6z2f/bAPPmiM/H11AjtzL03sMA3nsM4M5YfQRgLJn2WxK09CZAz75nOm4y206rpgJIAeYsJJ9T6AVAGzKW7hR6AZDKNZZV0xsb/9IZoPIB211DLbgGPdpEgFlmoN2JZmautS7QtVbVfzsHXq/XorNevJQSExGXUriUwkTEKaX7AJ3+ui5Rv9mQY4wcYzybA1YgFGD+r7UBGkSorWecc37rcs5mG0SAu1nO+nHej+/EvwGgehFgvD47AHQdYMOe0qe+Hzm8hknb8QYpAAAAAElFTkSuQmCC
// @namespace     https://greasyfork.org/en/users/59570-mital-ashok
// @license       http://creativecommons.org/licenses/by-sa/4.0/
// @version       1.0.0
// @grant         none
// @noframes
// ==/UserScript==


(function() {
    var border = true,
        hr = true,
        titleText = true,
        snap = false;
    
    
    function repeat(interval, func, onCompletion) {
        if (typeof onCompletion === 'undefined') {
            onCompletion = function() {};
        }
        if (func()) {
            onCompletion();
            return;
        }
        var intervalId = setInterval(function() {if (func()) { clearInterval(intervalId); onCompletion(); }}, interval);
    }

    function disable(nodeList) {
        return function disable() {
            Array.prototype.forEach.call(nodeList, function(currentValue) {
                currentValue.style.visibility = 'hidden';
                currentValue.removeAttribute('href');
                currentValue.style.cursor = 'default';
                currentValue.parentElement.style.MozUserSelect = 'none';
                currentValue.parentElement.style.webkitUserSelect = 'none';
                currentValue.parentElement.style.userSelect = 'none';
            });
            return Array.prototype.every.call(nodeList, function(currentValue) {
                return currentValue.style.visibility === 'hidden' &&
                       !currentValue.hasAttribute('href') &&
                       currentValue.style.cursor === 'default';
            });
        };
    }

    if (/^(https?:)?(\/\/)?(www\.)?whatif/i.test(window.location.href)) {
        window.location.href = window.location.href.replace(/^((https?:)?(\/\/)?(www\.)?what)(if)/i, '$1-$5');
    }
    
    var isWhatIf = /^(https?:)?(\/\/)?(www\.)?what-if/i.test(window.location.href),
        blackList = {
            'xkcd': [],
            'whatIf': []
        },
        number, first, last, random, 
        left = 37, right = 39, n = 78, p = 80, r = 82;

    if (isWhatIf) {
        last = false;
        var setRandom = function(create) {
            if (typeof random === 'undefined') {
                random = Math.floor(Math.random() * (lastNumber - 1)) + 1;
            }
            if (random === number) {
                random++;
            }
            if (create) {
                var addRandom = function(ulTag) {
                    var liTag = document.createElement('li'),
                        aTag = document.createElement('a');
                    aTag.href = '/' + random + '/';
                    aTag.appendChild(document.createTextNode('Random'));
                    liTag.appendChild(aTag);
                    if (last) {
                        ulTag.insertBefore(liTag, ulTag.lastChild);
                    } else {
                        ulTag.insertBefore(liTag, ulTag.lastChild.previousSibling);
                    }
                    if (first) {
                        liTag.style.marginLeft = '8.57552em';
                    }
                };
                navs = document.getElementsByClassName('main-nav');
                addRandom(navs[0].firstElementChild);
                addRandom(navs[1].firstElementChild);
            } else {
                window.location.pathname = '/' + random + '/';
            }
        },
        lastNumber, navs, addButtons, xhttp;
        
        xhttp = new XMLHttpRequest();
        xhttp.open('get', '/', false);
        xhttp.send();
        lastNumber = +xhttp.response.match(/<a href="\/\/what-if.xkcd.com\/(\d+)\/"><h1>/)[1];

        document.addEventListener('keydown', function(event) {
            var keyCode = event.keyCode;
            if ((keyCode === right || keyCode === n) && !last) {
                Array.prototype.forEach.call(document.getElementsByTagName('a'), function(currentValue) {
                    if (currentValue.firstChild !== null) {
                        if (currentValue.firstChild.textContent === 'Next') {
                            currentValue.click();
                        }
                    }
                });
            } else if ((keyCode === left || keyCode === p) && !first) {
                Array.prototype.forEach.call(document.getElementsByTagName('a'), function(currentValue) {
                    if (currentValue.firstChild !== null) {
                        if (currentValue.firstChild.textContent === 'Prev') {
                            currentValue.click();
                        }
                    }
                });
            } else if (keyCode === r) {
                setRandom();
            }
        });

        var headATag = document.getElementsByTagName('h1')[0].parentElement;
        number = +headATag.getAttribute('href').slice(19, -1);
        if (number === 0) {
            number = lastNumber;
        }
        first = number === 1;
        last = number === lastNumber;
        if (/^(https?:)?(\/\/)?(www\.)?what-if.xkcd.com\/\d+/i.test(window.location.href)) {
            repeat(100, function() {
                headATag.removeAttribute('href');
                headATag.style.textDecoration = 'underline';
                return !headATag.hasAttribute('href') && headATag.style.textDecoration === 'underline';
            });
        }
        setRandom(true);

        addButtons = function(navTag) {
            var ulTag = navTag.firstElementChild,
                aTag;
            navTag.style.width = '23.5em';
            if (!first) {
                var firstTag = document.createElement('li');
                aTag = document.createElement('a');
                aTag.appendChild(document.createTextNode('First'));
                aTag.href = '/1/';
                firstTag.appendChild(aTag);
                firstTag.className = 'nav-prev';
                ulTag.insertBefore(firstTag, ulTag.firstChild);
            }
            if (!last) {
                var lastTag = document.createElement('li');
                aTag = document.createElement('a');
                aTag.appendChild(document.createTextNode('Last'));
                aTag.href = '/';
                lastTag.appendChild(aTag);
                lastTag.className = 'nav-next';
                ulTag.insertBefore(lastTag, ulTag.lastElementChild);
            }
            Array.prototype.forEach.call(ulTag.children, function(currentValue) {
                if (currentValue.firstChild.firstChild.textContent !== 'Last') {
                    currentValue.style.marginRight = '0.5em';
                }                    
            });
        };
        navs = document.getElementsByClassName('main-nav');
        addButtons(navs[0]);
        addButtons(navs[1]);
        

        Array.prototype.forEach.call(document.getElementsByTagName('img'), function(currentValue) {
            if (currentValue.hasAttribute('title')) {
                if (border) {
                    currentValue.style.border = '2px solid rgba(127, 127, 127, 0.22)';
                }
                if (titleText) {
                    currentValue.style.marginTop = currentValue.style.paddingTop;
                    currentValue.style.marginBottom = 0;
                    var oldPadding = currentValue.style.paddingBottom;
                    currentValue.style.paddingTop = 0;
                    currentValue.style.paddingBottom = 0;
                    var title = document.createElement('p');
                    title.appendChild(document.createTextNode(currentValue.title));
                    title.style.textAlign = 'center';
                    title.style.paddingLeft = '5em';
                    title.style.paddingRight = '5em';
                    title.style.paddingTop = 0;
                    title.style.paddingBottom = oldPadding;
                    title.style.fontSize = '85%';
                    currentValue.parentElement.insertBefore(title, currentValue.nextSibling);
                    currentValue.removeAttribute('title');
                }
            }
        });
    } else {
        var comic = document.getElementById('comic'),
            title = document.createElement('p'),
            previousButtons, nextButtons, intervalId, top;


        repeat(1000, function() {
            if (comic.firstElementChild.tagName.toLowerCase() === 'script') {
                return false;
            }
            try {
                if (hr) {
                    comic.parentElement.insertBefore(document.createElement('hr'), comic.nextSibling);
                    comic.parentElement.insertBefore(document.createElement('hr'), comic);
                }
                if (titleText) {
                    title.appendChild(document.createTextNode(comic.firstElementChild.title));
                    title.style.fontVariant = 'normal';
                    title.style.paddingLeft = '80px';
                    title.style.paddingRight = '80px';
                    title.style.fontSize = '20px';
                    comic.parentElement.insertBefore(title, comic.nextSibling);
                    comic.firstElementChild.removeAttribute('title');
                    return true;
                }
            } catch (e) {
                return true;
            }
        });
        
        if (snap) {
            top = document.getElementById('middleContainer').offsetTop + 6;
            window.scrollTo(0, top);
            window.addEventListener('scroll', function() {
                scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
                if (scrollPosition > top - 145 && top + 10 > scrollPosition) {
                    if (intervalId === false && scrollPosition !== top) {
                        intervalId = setInterval(function() {
                            if (scrollPosition > top - 145 && top + 10 > scrollPosition) {
                                window.scrollTo(0, top);
                            }
                            clearInterval(intervalId);
                            intervalId = false;
                        }, 500);
                    }
                } else {
                    clearInterval(intervalId);
                    intervalId = false;
                }
            });
        }

        first = last = false;
        repeat(100, function() {
            nextButtons = Array.prototype.slice.call(document.querySelectorAll('[accesskey="n"], [href="/"]'), 1);
            previousButtons = document.querySelectorAll('[accesskey="p"], [href="/1/"]');
            return nextButtons.length === 4 && previousButtons.length === 4;
        }, function() {
            if (previousButtons[1].getAttribute('href') === '#') {
                number = 1;
                first = true;
                repeat(100, disable(previousButtons));
            } else {
                number = +previousButtons[1].href.slice(1, -1);
                if (nextButtons[0].getAttribute('href') === '#') {
                    last = true;
                    repeat(100, disable(nextButtons));
                }
            }
            if (blackList.xkcd.indexOf(number) !== -1) {
                return false;
            }
            
            document.addEventListener('keydown', function(event) {
                var keyCode = event.keyCode;
                if ((keyCode === right || keyCode === n) && !last) {
                    nextButtons[0].click();
                } else if ((keyCode === left || keyCode === p) && !first) {
                    previousButtons[1].click();
                } else if (keyCode === r) {
                    document.querySelector('[href="//c.xkcd.com/random/comic/"]').click();
                }
            });
        });
    }
})();