MediaWiki:Gadget-site.js

来自Minecraft基岩版开发Wiki

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Internet Explorer或Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
  • Opera:Ctrl-F5
/**
 * Scripts placed here are loaded on both desktop and mobile views.
 * 
 * Desktop-only scripts should go in [[MediaWiki:Common.js]]
 * Mobile-only scripts should go in [[MediaWiki:Mobile.js]].
 */

/* 复制提醒 */
mw.loader.load(mw.config.get('wgScriptPath') + '/index.php?title=MediaWiki:CopyNotice.js&action=raw&ctype=text/javascript');

/* 首页 */
$(".page-Minecraft基岩版开发Wiki #siteSub").remove();
$(".page-Minecraft基岩版开发Wiki #ca-nstab-main").remove();


(function () {
    'use strict';

    /* Variables for interface text used throughout the script, for ease of translating */
    var i18n = {
        // Collapsible elements and page loader
        hideText: wgULS('隐藏', '隱藏'),
        showText: wgULS('显示', '顯示'),
        loadErrorTitle: wgULS('加载内容时出错。', '載入內容時出錯。')
    };

    /* Fired whenever wiki content is added. (#mw-content-text, live preview, load page, etc.) */
    mw.hook('wikipage.content').add(function ($wikipageContent) {


        /**
         * Collapsible elements
         *
         * Add the "collapsible" class to an element and the child element with class "collapsible-content"
         * (or everything but the header row if a table) will be hidden when the element is collapsed.
         *
         * * Add the class "collapsed" to the element to make it start out collapsed.
         * * Add either "collapsetoggle-left" or "collapsetoggle-inline" to the element to choose the collapse
         *   toggle alignment (defaults to right).
         * * Add an ID in the format of "collapsible-<x>" to the element to make any element with the class
         *  "collapsetoggle-custom" and a matching class in the format of "collapsible-<x>-toggle" control
         *   the collapsing instead of the standard button.
         *   If the custom toggle contains an element with the "jslink" class, only that will be clickable.
         */
        (function () {
            var $collapsibles = $wikipageContent.find('.collapsible');
            if (!$collapsibles.length) {
                return;
            }

            var $toggleTemplate = $('<span>').addClass('collapsetoggle').append(
                '[', $('<span>').addClass('jslink'), ']'
            );
            $collapsibles.each(function () {
                var $collapsible = $(this);
                if ($collapsible.data('made-collapsible')) {
                    return true;
                }

                var $children = $collapsible.children();
                var showText = $collapsible.data('expandtext') || i18n.showText;
                var hideText = $collapsible.data('collapsetext') || i18n.hideText;

                // If there is no content area, add it
                if (!$collapsible.is('table') && !$children.filter('.collapsible-content').length) {
                    if ($collapsible.is('tr')) {
                        $children.addClass('collapsible-content');
                    } else {
                        $collapsible.wrapInner('<div class="collapsible-content">');
                        $children = $collapsible.children();
                    }
                }

                var $toggle;
                var id = $collapsible.attr('id');
                if (id && id.match(/^collapsible-./)) {
                    $toggle = $($wikipageContent[0].getElementsByClassName(id + '-toggle'))
                        .filter('.collapsetoggle-custom').css('visibility', 'visible');
                }

                // Create and insert the toggle button if there is no custom one
                if (!$toggle || !$toggle.length) {
                    var $toggleContainer;
                    if ($collapsible.is('table')) {
                        var $rows = $children.filter('thead').children();
                        if (!$rows.length) {
                            $rows = $children.filter('tbody').first().children();
                            if (!$rows.length) {
                                $rows = $children.filter('tr');
                            }
                        }
                        $toggleContainer = $rows.first().children().last();
                    } else {
                        $toggleContainer = $children.first();
                        if ($toggleContainer.hasClass('collapsible-content')) {
                            $toggleContainer = $collapsible;
                        }
                    }

                    $toggle = $toggleTemplate.clone();
                    if (
                        $toggleContainer !== $collapsible && (
                            $collapsible.hasClass('collapsetoggle-inline') ||
                            $collapsible.hasClass('collapse-button-none')
                        )) {
                        $toggleContainer.append($toggle);
                    } else {
                        $toggleContainer.prepend($toggle);
                    }
                }

                var $toggleLink = $toggle.find('.jslink');
                if (!$toggleLink.length) {
                    $toggleLink = $toggle;
                }
                $toggleLink.attr('tabindex', 0).text(hideText);

                // Find max toggle size, and set its min-width to it
                var hideWidth = $toggle.width();
                $toggleLink.text(showText);
                var showWidth = $toggle.width();
                if (hideWidth !== showWidth) {
                    $toggle.css('min-width', hideWidth > showWidth ? hideWidth : showWidth);
                }

                // Set the text back to hide if it's not collapsed to begin with
                if (!$collapsible.hasClass('collapsed')) {
                    $toggleLink.text(hideText);
                }

                $toggleLink.on('click keydown', function (e) {
                    // Only trigger on enter press
                    if (e.keyCode && e.keyCode !== 13) {
                        return;
                    }

                    // Don't toggle when clicking buttons or links inside the toggle
                    var $target = $(e.target);
                    if ($target.is('button') || $target.is('a')) {
                        return;
                    }

                    $collapsible.toggleClass('collapsed');
                    if ($collapsible.hasClass('collapsed')) {
                        $toggleLink.text(showText);
                    } else {
                        $toggleLink.text(hideText);
                    }

                    // Stop table sorting activating when clicking the link
                    e.stopPropagation();
                });

                $collapsible.data('made-collapsible', true);
            });
        }());

        /**
         * Page loader
         *
         * Allows a page to be downloaded and displayed on demand.
         * Use with [[Template:LoadPage]] and [[Template:LoadBox]]
         */
        (function () {
            var $loadPage = $wikipageContent.find('.load-page');
            if (!$loadPage.length) {
                return;
            }

            // We need the spinner to show loading is happening, but we don't want
            // to have a delay while the module downloads, so we'll load this now,
            // regardless of if something is clicked
            mw.loader.load('jquery.spinner');

            // Create button starting with hide text
            // Will be changed to the show text while calculating the maximum button size
            var $buttonTemplate = $('<span>').addClass('mw-editsection-like load-page-button')
                .append('[', $('<span>').addClass('jslink').text(i18n.hideText), ']');

            var extractList = function ($contentContainer, listClass) {
                var $content = $contentContainer.find('.mw-parser-output > ul > li > ul').children();
                if (listClass) {
                    $content.addClass(listClass);
                }

                return $content;
            };

            $loadPage.each(function () {
                var $body = $(this);
                var page = $body.data('page');
                if (!page) {
                    return;
                }

                var template = $body.data('template');
                var treeview = $body.data('treeview');
                var treeviewClass = $body.data('treeviewclass');
                var $heading;
                var $contentContainer;
                var $content;
                var $button = $buttonTemplate.clone();
                var $buttonLink = $button.find('.jslink');
                if (treeview) {
                    $heading = $body;
                    $contentContainer = $('<div>');
                } else {
                    $heading = $body.children().first();
                    $contentContainer = $body.find('.load-page-content');
                }

                // Add the button
                $heading.append($button);

                // Move the edit button to the right spot
                $contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter($button);

                // Find max button width, and set its min-width to it
                var hideWidth = $button.width();
                $buttonLink.text(i18n.showText);
                var showWidth = $button.width();

                if (hideWidth !== showWidth) {
                    $button.css('min-width', hideWidth > showWidth ? hideWidth : showWidth);
                }

                $buttonLink.click(function () {
                    if ($body.hasClass('pageloader-contentloaded')) {
                        if ($buttonLink.text() === i18n.showText) {
                            if (treeview) {
                                $content.insertAfter($body);
                            } else {
                                $contentContainer.show();
                            }
                            $buttonLink.text(i18n.hideText);
                        } else {
                            if (treeview) {
                                $content.children(".load-page-button").children(".jslink").each(function () {
                                    if ($(this).text() === i18n.hideText) this.click();
                                });
                                $content.detach();
                            } else {
                                $contentContainer.hide();
                            }
                            $buttonLink.text(i18n.showText);
                        }
                        return;
                    }

                    // See if this was loaded elsewhere before making a request
                    var gotContent;
                    $('.pageloader-contentloaded').each(function () {
                        var $fLoader = $(this);
                        if ($fLoader.data('page') === page && $fLoader.data('pageloader-content')) {
                            $contentContainer.html($fLoader.data('pageloader-content')).removeClass('noscript');
                            mw.hook('wikipage.content').fire($contentContainer);

                            if (treeview) {
                                $body.find('.noscript').remove();
                                $content = extractList($contentContainer, treeviewClass);
                                $content.insertAfter($body);
                            }

                            $buttonLink.text(i18n.hideText);
                            $body.addClass('pageloader-contentloaded');
                            gotContent = true;
                            return false;
                        }
                    });
                    if (gotContent) {
                        return;
                    }

                    // Just in-case the spinner module is still not ready yet
                    var $spinner = $();
                    mw.loader.using('jquery.spinner', function () {
                        // $spinner will be false if the content somehow loaded before the module did
                        if ($spinner) {
                            $spinner = $.createSpinner().addClass('mw-editsection-like')
                                .css('min-width', $button.css('min-width'));
                            $button.hide().after($spinner);
                        }
                    });

                    var requestData = {
                        action: 'parse',
                        prop: 'text|modules|jsconfigvars'
                    };
                    if (template) {
                        requestData.page = page;
                    } else {
                        requestData.title = mw.config.get('wgPageName');
                        requestData.text = '{' + '{:' + page + '}}';
                    }
                    new mw.Api().get(requestData).done(function (data) {
                        // Add config and modules
                        if (data.parse.jsconfigvars) {
                            mw.config.set(data.parse.jsconfigvars);
                        }
                        if (data.parse.modules) {
                            mw.loader.load(data.parse.modules.concat(
                                data.parse.modulescripts,
                                data.parse.modulestyles
                            ));
                        }

                        var html = data.parse.text['*'];
                        $contentContainer.html(html).removeClass('noscript');

                        // Resolve self-links
                        if (template) {
                            var curPage = '/' + mw.config.get('wgPageName');
                            $contentContainer.find('a').each(function () {
                                var $link = $(this);
                                if ($link.attr('href') === encodeURI(curPage)) {
                                    $link.replaceWith($('<strong>').addClass('selflink').append($link.contents()));
                                }
                            });
                            html = $contentContainer.html();
                        }

                        $body.data('pageloader-content', html);

                        // Fire content hook on the new content, running all this stuff again and more :)
                        mw.hook('wikipage.content').fire($contentContainer);

                        if (treeview) {
                            $body.find('.noscript').remove();
                            $content = extractList($contentContainer, treeviewClass);
                            $content.insertAfter($body);
                        }

                        $spinner.remove();
                        $spinner = false;
                        $buttonLink.text(i18n.hideText);
                        $button.show();
                        $body.addClass('pageloader-contentloaded');
                    }).fail(function (_, error) {
                        $spinner.remove();
                        $spinner = false;
                        $button.show();

                        var errorText = '';
                        if (error.textStatus) {
                            errorText = error.textStatus;
                        } else if (error.error) {
                            errorText = error.error.info;
                        }

                        mw.notify(errorText, {
                            title: i18n.loadErrorTitle,
                            autoHide: false
                        });
                    });
                });
            });
        }());

        /**
         * Set minimum height for animations to prevent moving the page if the frames
         * differ in height
         */
        (function () {
            // Set frames to be visible for measuring height
            var $animated = $wikipageContent.find('.animated').addClass('animated-visible');

            // Group frames per animation
            var animateds = [];
            $animated.each(function () {
                animateds.push({
                    $: $(this).find('> .animated-subframe').addBack()
                        .find('> *:not(.animated-subframe)'),
                });
            });

            // Get highest frame for each animation (if heights differ)
            $.each(animateds, function () {
                var minHeight = 0,
                    differentHeights;
                this.$.each(function () {
                    var height = this.offsetHeight;
                    differentHeights = differentHeights || minHeight && height !== minHeight;
                    minHeight = Math.max(height, minHeight);
                });

                if (differentHeights) {
                    this.height = minHeight;
                }
            });

            // Set animation to be at least as tall as the tallest frame,
            // and set the non-active frames to be hidden again
            $animated.each(function (i) {
                $(this).css('min-height', animateds[i].height);
            }).removeClass('animated-visible');
        }());

    });
    /* End wiki content hook */


    /* Fires when DOM is ready */
    $(function () {


        /**
         * Element animator
         *
         * Cycles through a set of elements (or "frames") on a 2 second timer per frame
         * Add the "animated" class to the frame containing the elements to animate.
         * Optionally, add the "animated-active" class to the frame to display first.
         * Optionally, add the "animated-subframe" class to a frame, and the
         * "animated-active" class to a subframe within, in order to designate a set of
         * subframes which will only be cycled every time the parent frame is displayed.
         * Animations with the "animated-paused" class will be skipped each interval.
         *
         * Requires some styling from [[MediaWiki:Gadget-site-styles.css]].
         */
        (function () {
            var $content = $('#mw-content-text');
            var advanceFrame = function (parentElem, parentSelector) {
                var curFrame = parentElem.querySelector(parentSelector + ' > .animated-active');
                $(curFrame).removeClass('animated-active');
                var $nextFrame = $(curFrame && curFrame.nextElementSibling || parentElem.firstElementChild);
                return $nextFrame.addClass('animated-active');
            };

            // Set the name of the hidden property
            var hidden;
            if (typeof document.hidden !== 'undefined') {
                hidden = 'hidden';
            } else if (typeof document.msHidden !== 'undefined') {
                hidden = 'msHidden';
            } else if (typeof document.webkitHidden !== 'undefined') {
                hidden = 'webkitHidden';
            }

            setInterval(function () {
                if (hidden && document[hidden]) {
                    return;
                }
                $content.find('.animated').each(function () {
                    if ($(this).hasClass('animated-paused')) {
                        return;
                    }

                    var $nextFrame = advanceFrame(this, '.animated');
                    if ($nextFrame.hasClass('animated-subframe')) {
                        advanceFrame($nextFrame[0], '.animated-subframe');
                    }
                });
            }, 2000);
        }());


    });
    /* End DOM ready */


}());