MediaWiki:Common.js: Difference between revisions

From Geometry Dash Wiki
Jump to navigation Jump to search
Add e!Wiki footer attribution, licensing information, independence note, and contact link
Use Geometry Dash Wiki Expanded as the public name instead of internal e!Wiki shorthand
 
Line 489: Line 489:
});
});


/* e!Wiki footer: source attribution, licensing, and local contact. */
/* Geometry Dash Wiki Expanded footer: source attribution, licensing, and local contact. */
mw.loader.using('mediawiki.util').then(function () {
mw.loader.using('mediawiki.util').then(function () {
$(function () {
$(function () {
Line 517: Line 517:
     var independent = document.createElement('li');
     var independent = document.createElement('li');
     independent.id = 'footer-info-ewiki-independent';
     independent.id = 'footer-info-ewiki-independent';
     independent.textContent = 'e!Wiki is an independent community wiki and is not affiliated with wiki.gg or RobTop Games.';
     independent.textContent = 'Geometry Dash Wiki Expanded is an independent community wiki and is not affiliated with wiki.gg or RobTop Games.';
     information.append(sources, license, independent);
     information.append(sources, license, independent);
     var places = document.querySelector('#footer-places');
     var places = document.querySelector('#footer-places');
Line 523: Line 523:
         var contact = document.createElement('li');
         var contact = document.createElement('li');
         contact.id = 'footer-places-ewiki-contact';
         contact.id = 'footer-places-ewiki-contact';
         contact.appendChild(link('Contact e!Wiki', mw.util.getUrl('User talk:Josh994')));
         contact.appendChild(link('Contact Geometry Dash Wiki Expanded', mw.util.getUrl('User talk:Josh994')));
         places.appendChild(contact);
         places.appendChild(contact);
     }
     }

Latest revision as of 01:56, 10 October 2026

/* Any JavaScript here will be loaded for all users on every page load. */

/***************************/
/* Interface Modification **/
/***************************/

/* [[MediaWiki:Custom-Category:Games]] */
$(function () {
    var config = {
        targetCategory: 'Games (base content)',
        sourceContent: 'MediaWiki:Custom-Category:Games',
        insertionPoint: '#mw-normal-catlinks'
    };

    // Initial checks: Run only on page views (not edit mode) and for existing pages
    if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;

    // Category check: Verify if the article belongs to the target category
    var categories = mw.config.get('wgCategories');
    if (categories.indexOf(config.targetCategory) === -1) return;

    // Load and inject content
    var api = new mw.Api();
    api.get({
        action: 'parse',
        page: config.sourceContent,
        prop: 'text',
        disablelimitreport: true,
        disableeditsection: true
    }).done(function (data) {
        if (data && data.parse && data.parse.text) {
            var insertHtml = data.parse.text['*'];
            // Wrap in a div for styling and append
            $(config.insertionPoint).append(
                $('<div id="custom-category-page-list" style="font-weight:normal;">')
                .html(insertHtml)
            );
        }
    }).fail(function () {
        console.error('Failed to load the content list from ' + config.sourceContent);
    });
});

/***************************/

/* [[MediaWiki:Custom-Category:Gameplay]] */
$(function () {
    var config = {
        targetCategory: 'Gameplay (base content)',
        sourceContent: 'MediaWiki:Custom-Category:Gameplay',
        insertionPoint: '#mw-normal-catlinks'
    };

    // Initial checks: Run only on page views (not edit mode) and for existing pages
    if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;

    // Category check: Verify if the article belongs to the target category
    var categories = mw.config.get('wgCategories');
    if (categories.indexOf(config.targetCategory) === -1) return;

    // Load and inject content
    var api = new mw.Api();
    api.get({
        action: 'parse',
        page: config.sourceContent,
        prop: 'text',
        disablelimitreport: true,
        disableeditsection: true
    }).done(function (data) {
        if (data && data.parse && data.parse.text) {
            var insertHtml = data.parse.text['*'];
            // Wrap in a div for styling and append
            $(config.insertionPoint).append(
                $('<div id="custom-category-page-list" style="font-weight:normal;">')
                .html(insertHtml)
            );
        }
    }).fail(function () {
        console.error('Failed to load the content list from ' + config.sourceContent);
    });
});

/***************************/

/* [[MediaWiki:Custom-Category:Rewards]] */
$(function () {
    var config = {
        targetCategory: 'Rewards (base content)',
        sourceContent: 'MediaWiki:Custom-Category:Rewards',
        insertionPoint: '#mw-normal-catlinks'
    };

    // Initial checks: Run only on page views (not edit mode) and for existing pages
    if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;

    // Category check: Verify if the article belongs to the target category
    var categories = mw.config.get('wgCategories');
    if (categories.indexOf(config.targetCategory) === -1) return;

    // Load and inject content
    var api = new mw.Api();
    api.get({
        action: 'parse',
        page: config.sourceContent,
        prop: 'text',
        disablelimitreport: true,
        disableeditsection: true
    }).done(function (data) {
        if (data && data.parse && data.parse.text) {
            var insertHtml = data.parse.text['*'];
            // Wrap in a div for styling and append
            $(config.insertionPoint).append(
                $('<div id="custom-category-page-list" style="font-weight:normal;">')
                .html(insertHtml)
            );
        }
    }).fail(function () {
        console.error('Failed to load the content list from ' + config.sourceContent);
    });
});

/***************************/

/* [[MediaWiki:Custom-Category:Rooms]] */
$(function () {
    var config = {
        targetCategory: 'Rooms (base content)',
        sourceContent: 'MediaWiki:Custom-Category:Rooms',
        insertionPoint: '#mw-normal-catlinks'
    };

    // Initial checks: Run only on page views (not edit mode) and for existing pages
    if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;

    // Category check: Verify if the article belongs to the target category
    var categories = mw.config.get('wgCategories');
    if (categories.indexOf(config.targetCategory) === -1) return;

    // Load and inject content
    var api = new mw.Api();
    api.get({
        action: 'parse',
        page: config.sourceContent,
        prop: 'text',
        disablelimitreport: true,
        disableeditsection: true
    }).done(function (data) {
        if (data && data.parse && data.parse.text) {
            var insertHtml = data.parse.text['*'];
            // Wrap in a div for styling and append
            $(config.insertionPoint).append(
                $('<div id="custom-category-page-list" style="font-weight:normal;">')
                .html(insertHtml)
            );
        }
    }).fail(function () {
        console.error('Failed to load the content list from ' + config.sourceContent);
    });
});

/***************************/

/* [[MediaWiki:Custom-Category:LevelEditing]] */
$(function () {
    var config = {
        targetCategory: 'Level editing (base content)',
        sourceContent: 'MediaWiki:Custom-Category:LevelEditing',
        insertionPoint: '#mw-normal-catlinks'
    };

    // Initial checks: Run only on page views (not edit mode) and for existing pages
    if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;

    // Category check: Verify if the article belongs to the target category
    var categories = mw.config.get('wgCategories');
    if (categories.indexOf(config.targetCategory) === -1) return;

    // Load and inject content
    var api = new mw.Api();
    api.get({
        action: 'parse',
        page: config.sourceContent,
        prop: 'text',
        disablelimitreport: true,
        disableeditsection: true
    }).done(function (data) {
        if (data && data.parse && data.parse.text) {
            var insertHtml = data.parse.text['*'];
            // Wrap in a div for styling and append
            $(config.insertionPoint).append(
                $('<div id="custom-category-page-list" style="font-weight:normal;">')
                .html(insertHtml)
            );
        }
    }).fail(function () {
        console.error('Failed to load the content list from ' + config.sourceContent);
    });
});

/***************************/

/* [[MediaWiki:Custom-Category:AccountFeatures]] */
$(function () {
    var config = {
        targetCategory: 'Account features (base content)',
        sourceContent: 'MediaWiki:Custom-Category:AccountFeatures',
        insertionPoint: '#mw-normal-catlinks'
    };

    // Initial checks: Run only on page views (not edit mode) and for existing pages
    if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;

    // Category check: Verify if the article belongs to the target category
    var categories = mw.config.get('wgCategories');
    if (categories.indexOf(config.targetCategory) === -1) return;

    // Load and inject content
    var api = new mw.Api();
    api.get({
        action: 'parse',
        page: config.sourceContent,
        prop: 'text',
        disablelimitreport: true,
        disableeditsection: true
    }).done(function (data) {
        if (data && data.parse && data.parse.text) {
            var insertHtml = data.parse.text['*'];
            // Wrap in a div for styling and append
            $(config.insertionPoint).append(
                $('<div id="custom-category-page-list" style="font-weight:normal;">')
                .html(insertHtml)
            );
        }
    }).fail(function () {
        console.error('Failed to load the content list from ' + config.sourceContent);
    });
});

/***************************/

/* [[MediaWiki:Custom-Category:Updates]] */
$(function () {
    var config = {
        targetCategory: 'Updates (base content)',
        sourceContent: 'MediaWiki:Custom-Category:Updates',
        insertionPoint: '#mw-normal-catlinks'
    };

    // Initial checks: Run only on page views (not edit mode) and for existing pages
    if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;

    // Category check: Verify if the article belongs to the target category
    var categories = mw.config.get('wgCategories');
    if (categories.indexOf(config.targetCategory) === -1) return;

    // Load and inject content
    var api = new mw.Api();
    api.get({
        action: 'parse',
        page: config.sourceContent,
        prop: 'text',
        disablelimitreport: true,
        disableeditsection: true
    }).done(function (data) {
        if (data && data.parse && data.parse.text) {
            var insertHtml = data.parse.text['*'];
            // Wrap in a div for styling and append
            $(config.insertionPoint).append(
                $('<div id="custom-category-page-list" style="font-weight:normal;">')
                .html(insertHtml)
            );
        }
    }).fail(function () {
        console.error('Failed to load the page list from ' + config.sourceContent);
    });
});

/***************************/

/* [[MediaWiki:Custom-MainLevels]] */
$(function () {
    var config = {
        targetCategory: 'Main levels (base content)',
        sourceContent: 'MediaWiki:Custom-MainLevels',
        insertionPoint: '#mw-content-text'
    };

    // Initial checks: Run only on page views (not edit mode) and for existing pages
    if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;

    // Category check: Verify if the article belongs to the target category
    var categories = mw.config.get('wgCategories');
    if (categories.indexOf(config.targetCategory) === -1) return;

    // Load and inject content
    var api = new mw.Api();
    api.get({
        action: 'parse',
        page: config.sourceContent,
        prop: 'text',
        disablelimitreport: true,
        disableeditsection: true
    }).done(function (data) {
        if (data && data.parse && data.parse.text) {
            var insertHtml = data.parse.text['*'];
            // Wrap in a div for styling and append
            $(config.insertionPoint).append(
                $('<div id="custom-category-footer">')
                .html(insertHtml)
            );
        }
    }).fail(function () {
        console.error('Failed to load the footer from ' + config.sourceContent);
    });
});

/***************************/

/* [[Template:USERNAME]] */
$(function () { 
	mw.config.get('wgUserName');
	if (mw.config.get('wgUserName') !== null) ('span.username-insert').text(mw.config.get('wgUserName'));
});

/***************************/

/* [[Template:Discord]] (DiscordCompact.js v0.0.2 - https://support.wiki.gg/wiki/DiscordCompact) */
$(function () {
	var widget = $("#content #discord-compact-widget");
    // Cancel when no widget detected
    if (!widget.length) return;
    // Ensure that ID is not blank
	var id = widget.attr("data-id");
	if (id === "") throw new Error("DiscordCompact has a blank server id!");
	// Ensure that ID consists only of numbers with 17 character minimum
	if (!new RegExp("^[0-9]{17}[0-9]+$").test(id)) throw new Error("DiscordCompact has an invalid server id!");
	var apiBase = "https://discord.com/api/guilds/" + id;
	// Get information about the server, such as online member count and invite url, as well as limits of the server existing at all or having widgets disabled
	$.ajax(apiBase + "/widget.json").fail(function(req) {
        if (!req.responseJSON) throw new Error("DiscordCompact encountered an unknown error whilst fetching widget.json (status: " + req.status);
		switch (req.responseJSON.code) {
            case 10004:
                throw new Error("DiscordCompact has a valid server id, but no such server exists!");
            case 50004:
                throw new Error("DiscordCompact has a valid server id, but that server has widgets disabled!");
            default:
                throw new Error("DiscordCompact encountered an unknown error whilst fetching widget.json (status: " + req.status + "; code: " + req.responseJSON.code + ")");
        }
	}).done(function(res) {
		const inviteURL = res.instant_invite;
        // Warn when unable to retrieve invite URL
        if (inviteURL == null) console.warn("DiscordCompact cannot get an invite URL; does this server have an invite channel set in Widget settings?");
        // Generate widget image
        $.ajax({url: apiBase + "/widget.png?style=banner2", xhrFields: {responseType: "blob"}}).fail(function(req) {
            if (!req.responseJSON) throw new Error("DiscordCompact encountered an unknown error whilst fetching widget.png! (status: " + req.status);
            throw new Error("DiscordCompact encountered an unknown error whilst fetching widget.png! (status: " + req.status + "; code: " + req.responseJSON.code + ")");
        }).done(function(blob) {
            // Convert the image data into base64, preventing having to make the client request it a second time
            const imageReader = new FileReader();
            imageReader.readAsDataURL(blob);
            imageReader.onloadend = function() {
                const b64Data = imageReader.result;
                // Convert the widget into a selectable link
                widget.replaceWith(function() {
                    return $("<a>", {
                        id: widget.attr("id"),
                        class: widget.attr("class"),
                        style: widget.attr("style"),
                        alt: "Discord server widget",
                        href: inviteURL
                    });
                });
                // Select the widget
                widget = $("#discord-compact-widget");
                // CSS
                widget.css("display", "block");
                widget.css("max-height", "76px");
                widget.css("max-width", "320px");
                // Create image
                const widgetImage = document.createElement("img");
                widgetImage.src = b64Data;
                widgetImage.style.width = "100%";
                widgetImage.style.height = "100%";
                widgetImage.style.borderRadius = "4px";
                widget.append(widgetImage);
                // Prevent image dragging
                widget.on("dragstart", function(e) {e.preventDefault();});
                // Console message
                console.log("DiscordCompact loaded successfully!");
            };
        });
	});
});

/***************************/

/* [[Template:Discord]] (DiscordWidget.js - https://support.wiki.gg/wiki/DiscordWidget) */
$(function () {
	'use strict';
	var mconfig = mw.config.get([
		'wgContentLanguage',
		'wgUserLanguage',
		'wgUserName'
	]);
	if (window.DiscordIntegratorLoaded) {
		return;
	}
	window.DiscordIntegratorLoaded = true;
	// Main object, @static
	var DiscordIntegrator = {
		// Initialising
		init: function() {
			mw.hook('wikipage.content').add($.proxy(this.insertToContent, this));
		},
		//Finding the designated places in content in which to place the widget and placing it
		insertToContent: function($content) {
			$content.find('.DiscordIntegrator:not(.loaded)').each($.proxy(function(cabbage, el) {
				el = $(el);
				el.html(this.generateContent(el.data())).addClass('loaded');
			}, this));
		},
		// Determines the theme of the widget, @param {string} config Configured theme, @return {string} 'light' or 'dark' depending on the wiki theme and configuration
		determineTheme: function(config) {
			// If explicitly configured to light or dark
			if (config === 'dark') {
				return 'dark';
			}
			if (config === 'light') {
				return 'light';
			}
			// If not configured, try to determine based on wiki theme (set by themeToggle):
			return $(':root').hasClass('view-dark') ? 'dark' : 'light';
		},
		// Generate widget content from an object, @return {string} content of the widget
		generateContent: function(config) {
			if (!config.id || !String(config.id).match(/\d{17,19}/)) {
				return "Error: ID of the widget is malformed or not supplied, please see <a href='https://support.wiki.gg/wiki/DiscordWidget' title='the instructions'>the instructions</a> for how to find your server's ID. Please make sure you are not inserting <strong>the DiscordIntegrator template</strong> when asked for <strong>your widget ID</strong>.";
			}
			if (
				(
					config.loggedIn === true ||
					Boolean(config['logged-in']) === true &&
					config['logged-in'] !== 'false' &&
					config['logged-in'] !== '{{{loggedIn}}}'
				) && !mconfig.wgUserName
			) {
				return "Please <a href='/Special:UserLogin' title='log in'>log in</a> to see this widget.";
			}
			var username = config.username === '@disabled' ?
				'' :
				config.username === '@function' &&
				typeof window.DiscordIntegratorGetUsername === 'function' ?
					window.DiscordIntegratorGetUsername() :
					config.username || mconfig.wgUserName;
			return mw.html.element('iframe', {
				src: 'https://discord.com/widget?id=' + config.id +
					'&theme=' + this.determineTheme(config.theme) +
					'&username=' + encodeURIComponent(username),
				width: config.width || '100%',
				height: config.height || '400px',
				style: 'max-width:100%;',
				allowtransparency: 'true',
				frameborder: '0',
				title: "Discord server widget"
			});
		}
	};
	DiscordIntegrator.init();
});

/***************************/

/* CSS classes for daytime periods */
$(function() {
    'use strict';
    var currentTime = new Date().getHours();
	if (0 <= currentTime && currentTime < 6) {
		if (document.body) {document.body.classList.add('night');}
	}
	else if (6 <= currentTime && currentTime < 12) {
		if (document.body) {document.body.classList.add('morning');}
	}
	else if (12 <= currentTime && currentTime < 18) {
		if (document.body) {document.body.classList.add('afternoon');}
	}
	else {
		if (document.body) {document.body.classList.add('evening');}
	}
});

/* Geometry Dash Wiki Expanded footer: source attribution, licensing, and local contact. */
mw.loader.using('mediawiki.util').then(function () {
$(function () {
    var footer = document.querySelector('#footer');
    var information = document.querySelector('#footer-info');
    if (!footer || !information || document.getElementById('footer-info-ewiki-sources')) return;
    function link(text, href) {
        var element = document.createElement('a');
        element.textContent = text;
        element.href = href;
        return element;
    }
    var sources = document.createElement('li');
    sources.id = 'footer-info-ewiki-sources';
    sources.append('Imported material is adapted from the ',
        link('Geometry Dash Wiki', 'https://geometrydash.wiki.gg/'),
        ' and, where applicable, the ',
        link('Geometry Dash Fandom', 'https://geometry-dash.fandom.com/'),
        ' and ', link('Geometry Dash Fan Fandom', 'https://geometry-dash-fan.fandom.com/'),
        ' wikis. Source and contributor links are recorded in import edit summaries.');
    var license = document.createElement('li');
    license.id = 'footer-info-ewiki-license';
    license.append('Imported wiki text retains its original licensing, including ',
        link('Creative Commons Attribution-ShareAlike 4.0', 'https://creativecommons.org/licenses/by-sa/4.0/'),
        '. Images and separately licensed code may have different terms. ',
        link('Sources and licensing', mw.util.getUrl('Geometry Dash Wiki:Copyrights')), '.');
    var independent = document.createElement('li');
    independent.id = 'footer-info-ewiki-independent';
    independent.textContent = 'Geometry Dash Wiki Expanded is an independent community wiki and is not affiliated with wiki.gg or RobTop Games.';
    information.append(sources, license, independent);
    var places = document.querySelector('#footer-places');
    if (places && !document.getElementById('footer-places-ewiki-contact')) {
        var contact = document.createElement('li');
        contact.id = 'footer-places-ewiki-contact';
        contact.appendChild(link('Contact Geometry Dash Wiki Expanded', mw.util.getUrl('User talk:Josh994')));
        places.appendChild(contact);
    }
});

});