User:逆襲的天邪鬼/CheckDiff.js

From TestWiki
Revision as of 15:06, 3 May 2017 by 逆襲的天邪鬼 (talk | contribs) (via Wikiplus)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/*
 * CheckDiff
 *
 * Check diffs in the current page
 *
 * @author 逆襲的天邪鬼
 * @version 0.0.0
 *
 * TODO:
 * 1. 跨日期的編輯記錄
 * 2. 新頁面
 * 3. 在「監視清單」中取消粗體
 * 4. 如果編輯被摺疊……
 * 5. 本頁連結——#
 */

$(function () {

    var $current = null;
    var lock = false;

    function init(position) {
        $current = null;
        lock = false;

        $(position).after('<div id="checkdiff" style="display:none;"></div>');
        $('#checkdiff').append(
            '<div id="checkdiff-toolbar"><ul id="checkdiff-toolbar-ul"></ul></div>',
            '<div id="checkdiff-loading" style="display: none;"></div>',
            '<div id="checkdiff-content"></div>'
        );
        $('#checkdiff-toolbar-ul').append(
            '<li class="checkdiff-toolbar-item"><a href="#" id="checkdiff-refresh">Refresh</a></li>',
            '<li class="checkdiff-toolbar-item"><a href="#" id="checkdiff-up">Up</a></li>',
            '<li class="checkdiff-toolbar-item"><a href="#" id="checkdiff-down">Down</a></li>',
            '<li class="checkdiff-toolbar-item"><a href="#" id="checkdiff-newwindow">New Window</a></li>'
        );
        $('#checkdiff-loading').append(
            '<div class="background"></div>',
            '<div class="icon"><img src="https://upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif" width="32"></div>'
        );
    }

    function bind(diffClass, listClass) {
        $current = null;
        $(diffClass, listClass).click(function (e) {
            e.preventDefault();

            if (lock) {
                return;
            }
            lock = true;

            var $e = $(this);
            var href = $e.attr('href');

            var $li = $e.parent();
            $('#checkdiff-loading').show();
            $('#checkdiff').slideDown();

            $('.checkdiff-current').removeClass('checkdiff-current');
            $li.addClass('checkdiff-current');
            $current = $li;

            var done = function () {
                lock = false;

                $('#checkdiff-loading').hide();
                var offset = $('#checkdiff').offset();
                if (offset) {
                    window.scrollTo(0, offset.top);
                }

                $('#checkdiff-newwindow').attr('href', href);
                $('#checkdiff-newwindow').attr('target', '_blank');
            };

            $.ajax({
                url: href,
                dataType: 'html',
                method: 'GET',
                success: function (data, textStatus, jqXHR) {
                    var $dom = $(data);
                    var $diff = $('#mw-content-text', $dom).attr('id', 'checkdiff-content');

                    // 拒絕修訂滑塊
                    $('.mw-revslider-container', $diff).remove();

                    $('a', $diff).attr('target', '_blank');
                    $('#toc a', $diff).removeAttr('target');
                    $('#checkdiff-content').replaceWith($diff);
                    done();
                },
                error: function (jqXHR, textStatus, errorThown) {
                    $('#checkdiff-content').html('<strong style="color:red;">Error loading page.</strong>');
                    done();
                },
            });
        }).addClass('checklink-diff-link');

        // FIXME: 跨日期
        $('#checkdiff-up').click(function (e) {
            e.preventDefault();
            if (lock) {
                return;
            }

            if (!$current) {
                var $a = $(diffClass, listClass).first();
                if ($a.is('a') && $a.parent().is('li')) {
                    $current = $a.parent();
                }
            } else {
                while ($current.prev().is('li')) {
                    $current = $current.prev();
                    if ($(diffClass, $current).length > 0) {
                        break;
                    }
                }
            }

            if ($current.is('li')) {
                $(diffClass, $current).click();
            } else {
                $current = null;
            }
        });

        // FIXME: 跨日期
        $('#checkdiff-down').click(function (e) {
            e.preventDefault();
            if (lock) {
                return;
            }

            if (!$current) {
                var $a = $(diffClass, listClass).last();
                if ($a.is('a') && $a.parent().is('li')) {
                    $current = $a.parent();
                }
            } else {
                while ($current.next().is('li')) {
                    $current = $current.next();
                    if ($(diffClass, $current).length > 0) {
                        break;
                    }
                }
            }

            if ($current.is('li')) {
                $(diffClass, $current).click();
            } else {
                $current = null;
            }
        });

        $('#checkdiff-refresh').click(function (e) {
            e.preventDefault();
            if (lock) {
                return;
            }

            lock = true;
            $('#checkdiff-loading').show();

            $.ajax({
                url: window.location.href,
                dataType: 'html',
                method: 'GET',
                success: function (data, textStatus, jqXHR) {
                    var $dom = $(data);
                    $('#bodyContent').replaceWith($('#bodyContent', $dom));
                    reset();
                    $('#checkdiff-up').click();
                },
                error: function (jqXHR, textStatus, errorThown) {
                    window.history.go(0);
                },
            });
        });
    }

    function reset() {
        if (mw.config.get('wgCanonicalNamespace') === 'Special') {
            switch (mw.config.get('wgCanonicalSpecialPageName')) {
                case 'Watchlist':
                    init('#mw-watchlist-form');
                    bind('.mw-changeslist-diff', '.mw-changeslist');
                    break;

                case 'Contributions':
                    init('.mw-contributions-form');
                    bind('.mw-changeslist-diff', '.mw-contributions-list');
                    break;

                case 'Recentchanges':
                    init('.rcoptions');
                    bind('.mw-changeslist-diff', '.mw-changeslist');
                    break;
            }
        }
        // TODO 判斷是最近變更、使用者貢獻還是監視列表
    }

    reset();
});