Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

MediaWiki:Common.js

MediaWiki interface page

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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
(function () {
    var pageName = mw.config.get("wgPageName");
    var skin = mw.config.get("skin");
    var isMainPage = mw.config.get("wgIsMainPage");

    function onMainPage() {
        var searchTrigger = document.getElementById(
            "tg-mainpage-search-trigger"
        );
        var searchInput = document.getElementById("searchInput");
        var searchToggle;

        function onSearchTriggerClick() {
            if (skin === "citizen") {
                // HACK: Force sticky header to be visible
                var isSearchHidden =
                    document.body.classList.contains("citizen-scroll--down") &&
                    window.matchMedia("(max-width: 1119px)");
                if (isSearchHidden) {
                    document.body.classList.remove("citizen-scroll--down");
                    document.body.classList.add("citizen-scroll--up");
                }
                // Citizen does not have a visible search bar, you need to expand the search card first
                // And Citizen will focus the input automatically
                searchToggle.open = true;
            } else {
                // This should work for all skins that has visible search bar
                searchInput.focus();
            }
        }

        // Attach click event listener to search button on the main page
        if (searchTrigger && searchInput) {
            if (skin === "citizen") {
                searchToggle = document.getElementById("citizen-search-details");
            }
            searchTrigger.addEventListener("click", onSearchTriggerClick);
        }
    }

    function initSauronEye(container) {
        var Eye = {
            size: 250,
            point: 15,
            speed: 100,
            pupil: { x: 6, y: 36 },
            eye: { x: 100, y: 65 },
            data: [],

            Add: function (val) {
                return val + Eye.size / 2;
            },

            Interval: function (color, distance, value) {
                var s = Math.abs(
                    (color.a - color.b) / (distance.b - distance.a)
                );
                var v = value - distance.a;
                var c = color.a > color.b ? color.a - v * s : color.a + v * s;
                return Math.round(c);
            },

            Color: function (percent) {
                if (percent < 5)
                    return Eye.Interval(
                        { a: 255, b: 180 },
                        { a: 0, b: 2 },
                        percent
                    );
                else if (percent < 10)
                    return Eye.Interval(
                        { a: 180, b: 100 },
                        { a: 2, b: 5 },
                        percent
                    );
                else if (percent < 40)
                    return Eye.Interval(
                        { a: 100, b: 0 },
                        { a: 5, b: 30 },
                        percent
                    );
                else if (percent < 70)
                    return Eye.Interval(
                        { a: 0, b: 100 },
                        { a: 30, b: 70 },
                        percent
                    );
                else if (percent < 75)
                    return Eye.Interval(
                        { a: 100, b: 180 },
                        { a: 70, b: 80 },
                        percent
                    );
                else
                    return Eye.Interval(
                        { a: 180, b: 255 },
                        { a: 80, b: 100 },
                        percent
                    );
            },

            Pifagor: function (x, y) {
                return Math.sqrt(x * x + y * y);
            },

            Remove: function (radius, max, i) {
                if (radius > max) {
                    Eye.data.splice(i, 1);
                }
            },

            Write: function (x, y, color, opacity) {
                Eye.ctx.fillStyle = "rgba(255," + color + ",0," + opacity + ")";
                Eye.ctx.fillRect(Eye.Add(x), Eye.Add(y), 1, 1);
            },

            Style: function (point, i) {
                var radius = Eye.Pifagor(point.x, point.y);
                var percent =
                    ((radius - point.min) / (point.max - point.min)) * 100;
                var color = Eye.Color(percent);
                var opacity = percent > 70 ? 1 - (percent - 70) / 30 : 1;

                Eye.Write(point.x, point.y, color, opacity);
                Eye.Remove(radius, point.max, i);
            },

            Move: function (i) {
                var point = Eye.data[i];
                point.x += point.X;
                point.y += point.Y;
                Eye.Style(point, i);
            },

            Update: function () {
                Eye.Fill(0.02);
                for (var i = 0; i < Eye.point; i++) {
                    Eye.Point();
                }
                for (var j = 0; j < Eye.data.length; j++) {
                    Eye.Move(j);
                }
            },

            Draw: function () {
                Eye.Update();
                requestAnimationFrame(Eye.Draw, Eye.canvas);
            },

            Noise: function (value) {
                return Math.random() * value - value / 2;
            },

            Radius: function (start, end) {
                return {
                    max: Eye.Pifagor(end.x, end.y),
                    min: Eye.Pifagor(start.x, start.y),
                };
            },

            Step: function (start, end) {
                return {
                    x: (end.x - start.x) / Eye.speed,
                    y: (end.y - start.y) / Eye.speed,
                };
            },

            Position: function (type, angel, noise) {
                return {
                    x: Eye[type].x * Math.cos(angel) + Eye.Noise(noise),
                    y: Eye[type].y * Math.sin(angel) + Eye.Noise(noise),
                };
            },

            Point: function () {
                var angel = Math.random() * 2 * Math.PI;
                var start = Eye.Position("pupil", angel, 5);
                var end = Eye.Position("eye", angel, 25);
                var radius = Eye.Radius(start, end);
                var step = Eye.Step(start, end);

                Eye.data.push({
                    x: start.x,
                    y: start.y,
                    X: step.x,
                    Y: step.y,
                    min: radius.min,
                    max: radius.max,
                });
            },

            Fill: function (a) {
                Eye.ctx.fillStyle = "rgba(0,0,0," + a + ")";
                Eye.ctx.fillRect(0, 0, Eye.size, Eye.size);
            },

            Init: function () {
                Eye.Fill(1);
                for (var i = 0; i < Eye.point; i++) {
                    Eye.Point();
                }
                Eye.Draw();
            },

            Watch: function () {
                Eye.canvas = document.getElementById("tg-sauroneye");
                Eye.canvas.width = Eye.size;
                Eye.canvas.height = Eye.size;
                Eye.ctx = Eye.canvas.getContext("2d");
                Eye.Init();
            },
        };

        var canvas = document.createElement("canvas");
        canvas.id = "tg-sauroneye";
        container.append(canvas);
        Eye.Watch();
    }

    function init() {
        // Wait for page content to be fully loaded
        mw.hook("wikipage.content").add(function () {
            if (isMainPage) {
                onMainPage();
            }

            var eyeContainer = document.getElementById(
                "tg-sauroneye-container"
            );
            if (eyeContainer) {
                initSauronEye(eyeContainer);
            }
        });
    }

    init();
})();
/* Any JavaScript here will be loaded for all users on every page load. */
(function () {
    var pageName = mw.config.get("wgPageName");
    var skin = mw.config.get("skin");
    var isMainPage = mw.config.get("wgIsMainPage");

    function onMainPage() {
        var searchTrigger = document.getElementById(
            "tg-mainpage-search-trigger"
        );
        var searchInput = document.getElementById("searchInput");
        var searchToggle;

        function onSearchTriggerClick() {
            if (skin === "citizen") {
                // HACK: Force sticky header to be visible
                var isSearchHidden =
                    document.body.classList.contains("citizen-scroll--down") &&
                    window.matchMedia("(max-width: 1119px)");
                if (isSearchHidden) {
                    document.body.classList.remove("citizen-scroll--down");
                    document.body.classList.add("citizen-scroll--up");
                }
                // Citizen does not have a visible search bar, you need to expand the search card first
                // And Citizen will focus the input automatically
                searchToggle.open = true;
            } else {
                // This should work for all skins that has visible search bar
                searchInput.focus();
            }
        }

        // Attach click event listener to search button on the main page
        if (searchTrigger && searchInput) {
            if (skin === "citizen") {
                searchToggle = document.getElementById("citizen-search-details");
            }
            searchTrigger.addEventListener("click", onSearchTriggerClick);
        }
    }

    function initSauronEye(container) {
        var Eye = {
            size: 250,
            point: 15,
            speed: 100,
            pupil: { x: 6, y: 36 },
            eye: { x: 100, y: 65 },
            data: [],

            Add: function (val) {
                return val + Eye.size / 2;
            },

            Interval: function (color, distance, value) {
                var s = Math.abs(
                    (color.a - color.b) / (distance.b - distance.a)
                );
                var v = value - distance.a;
                var c = color.a > color.b ? color.a - v * s : color.a + v * s;
                return Math.round(c);
            },

            Color: function (percent) {
                if (percent < 5)
                    return Eye.Interval(
                        { a: 255, b: 180 },
                        { a: 0, b: 2 },
                        percent
                    );
                else if (percent < 10)
                    return Eye.Interval(
                        { a: 180, b: 100 },
                        { a: 2, b: 5 },
                        percent
                    );
                else if (percent < 40)
                    return Eye.Interval(
                        { a: 100, b: 0 },
                        { a: 5, b: 30 },
                        percent
                    );
                else if (percent < 70)
                    return Eye.Interval(
                        { a: 0, b: 100 },
                        { a: 30, b: 70 },
                        percent
                    );
                else if (percent < 75)
                    return Eye.Interval(
                        { a: 100, b: 180 },
                        { a: 70, b: 80 },
                        percent
                    );
                else
                    return Eye.Interval(
                        { a: 180, b: 255 },
                        { a: 80, b: 100 },
                        percent
                    );
            },

            Pifagor: function (x, y) {
                return Math.sqrt(x * x + y * y);
            },

            Remove: function (radius, max, i) {
                if (radius > max) {
                    Eye.data.splice(i, 1);
                }
            },

            Write: function (x, y, color, opacity) {
                Eye.ctx.fillStyle = "rgba(255," + color + ",0," + opacity + ")";
                Eye.ctx.fillRect(Eye.Add(x), Eye.Add(y), 1, 1);
            },

            Style: function (point, i) {
                var radius = Eye.Pifagor(point.x, point.y);
                var percent =
                    ((radius - point.min) / (point.max - point.min)) * 100;
                var color = Eye.Color(percent);
                var opacity = percent > 70 ? 1 - (percent - 70) / 30 : 1;

                Eye.Write(point.x, point.y, color, opacity);
                Eye.Remove(radius, point.max, i);
            },

            Move: function (i) {
                var point = Eye.data[i];
                point.x += point.X;
                point.y += point.Y;
                Eye.Style(point, i);
            },

            Update: function () {
                Eye.Fill(0.02);
                for (var i = 0; i < Eye.point; i++) {
                    Eye.Point();
                }
                for (var j = 0; j < Eye.data.length; j++) {
                    Eye.Move(j);
                }
            },

            Draw: function () {
                Eye.Update();
                requestAnimationFrame(Eye.Draw, Eye.canvas);
            },

            Noise: function (value) {
                return Math.random() * value - value / 2;
            },

            Radius: function (start, end) {
                return {
                    max: Eye.Pifagor(end.x, end.y),
                    min: Eye.Pifagor(start.x, start.y),
                };
            },

            Step: function (start, end) {
                return {
                    x: (end.x - start.x) / Eye.speed,
                    y: (end.y - start.y) / Eye.speed,
                };
            },

            Position: function (type, angel, noise) {
                return {
                    x: Eye[type].x * Math.cos(angel) + Eye.Noise(noise),
                    y: Eye[type].y * Math.sin(angel) + Eye.Noise(noise),
                };
            },

            Point: function () {
                var angel = Math.random() * 2 * Math.PI;
                var start = Eye.Position("pupil", angel, 5);
                var end = Eye.Position("eye", angel, 25);
                var radius = Eye.Radius(start, end);
                var step = Eye.Step(start, end);

                Eye.data.push({
                    x: start.x,
                    y: start.y,
                    X: step.x,
                    Y: step.y,
                    min: radius.min,
                    max: radius.max,
                });
            },

            Fill: function (a) {
                Eye.ctx.fillStyle = "rgba(0,0,0," + a + ")";
                Eye.ctx.fillRect(0, 0, Eye.size, Eye.size);
            },

            Init: function () {
                Eye.Fill(1);
                for (var i = 0; i < Eye.point; i++) {
                    Eye.Point();
                }
                Eye.Draw();
            },

            Watch: function () {
                Eye.canvas = document.getElementById("tg-sauroneye");
                Eye.canvas.width = Eye.size;
                Eye.canvas.height = Eye.size;
                Eye.ctx = Eye.canvas.getContext("2d");
                Eye.Init();
            },
        };

        var canvas = document.createElement("canvas");
        canvas.id = "tg-sauroneye";
        container.append(canvas);
        Eye.Watch();
    }

    function init() {
        // Wait for page content to be fully loaded
        mw.hook("wikipage.content").add(function () {
            if (isMainPage) {
                onMainPage();
            }

            var eyeContainer = document.getElementById(
                "tg-sauroneye-container"
            );
            if (eyeContainer) {
                initSauronEye(eyeContainer);
            }
        });
    }

    init();
})();