MediaWiki:Common.js

From Little-Known Galaxy Wiki
Jump to navigation Jump to search

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.
/* Any JavaScript here will be loaded for all users on every page load. */


/* DRUID */
$(function () {
  $(".druid-main-images-label").off("click");
  $(".druid-main-images-label").click(function () {
    var $parent = $(this).closest(".druid-container");
    $parent.find(".druid-toggleable").removeClass("focused");
    var i = $(this).attr("data-druid");
    $parent.find(".druid-toggleable[data-druid=" + i + "]").addClass("focused");
  });

  $(".druid-collapsible").off("click");
  $(".druid-collapsible").click(function () {
    var kind = $(this).attr("data-druid-section");
    $(this).toggleClass("druid-collapsible-collapsed");
    $(this)
      .closest(".druid-container")
      .find("[data-druid-section-row=" + kind + "]")
      .toggleClass("druid-collapsed");
  });
});
/* End DRUID */

/* [[Template:Spoiler]] */
$(function () {
	$('.spoiler-content')
	.off('click') // in case this code is loaded twice
	.on('click', function(e){
		$(this).toggleClass('show');
	}).find('a').on('click', function(e){
		e.stopPropagation();
	});

});
/* End Template:Spoiler */


/* Link to imported modules from Lua code */
$(function() {
    var config = mw.config.get([
        'wgCanonicalNamespace',
        'wgFormattedNamespaces'
    ]);
    if (config.wgCanonicalNamespace !== 'Module') {
        return;
    }
    var localizedNamespace = config.wgFormattedNamespaces[828];
    $('.s1, .s2, .s').each(function() {
        var $this = $(this);
        var html = $this.html();
        var quote = html[0];
        var isLongStringQuote = quote === '[';
        var quoteRE = new RegExp('^\\' + quote + '|\\' + quote + '$', 'g');
        if (isLongStringQuote) {
            quoteRE = /^\[\[|\]\]$/g;
        }
        var name = html.replace(quoteRE, '');
        var isEnglishPrefix = name.startsWith('Module:');
        var isLocalizedPrefix = name.startsWith(localizedNamespace + ':');
        var isDevPrefix = name.startsWith('Dev:');
        if (isEnglishPrefix || isLocalizedPrefix || isDevPrefix) {
            var attrs = {
                href: mw.util.getUrl(name)
            };
            if (isDevPrefix) {
                attrs.href = 'https://commons.wiki.gg/wiki/Module:' + mw.util.wikiUrlencode(name.replace('Dev:', ''));
                attrs.target = '_blank';
                attrs.rel = 'noopener';
            }
            var link = mw.html.element('a', attrs, name);
            var str = quote + link + quote;
            if (isLongStringQuote) {
                str = '[[' + link + ']]';
            }
            $this.html(str);
        }
    });
});

	/*
	* Checklist tables *
	*******************/
	/* Special thanks to the Palia wiki for helping us with this! */
	$.when(
		mw.loader.using([ 'mediawiki.storage' ]),
		$.ready
	).then(function () {
        var loadTableData = function () {
            var checklists = [];
            // if table has "data-checklist=Some_Bundle", add it to the list
            $.each($("tr"), function (index) {
                if ($(this).data("checklist") !== undefined) {
                    checklists.push($(this).data("checklist").replace("'", ""));
                }
            })

            // Load data for the checklists
            for (var i = 0; i < checklists.length; i++) {
                var serialized = mw.storage.get('mwchecklist-' + checklists[i].replace("'", ""));

                if (serialized === null) continue;
                
                var items = serialized.split(';');
                // Restore saved items
                for (var itemIndex = 0; itemIndex < items.length; itemIndex++) {
                    try {
                        // Update the checkbox to the saved value
                        $("*[data-item='" + items[itemIndex].replace("'", "") + "']")
                            .find('input[type=checkbox]')
                            .prop("checked", true)
                            .trigger("change");
                    } catch (error) {
                        console.log("Error trying to check", items[itemIndex], ". Resetting it.", error)
                        mw.storage.set('mwchecklist-' + checklists[i], "");
                    }
                }
            }
        };
        
        var storeItem = function (tableId, item) {
            var saved = mw.storage.get('mwchecklist-' + tableId);
            if (saved === undefined || saved === null) {
                mw.storage.set(
                    'mwchecklist-' + tableId,
                    item
                );
            } else {
                var items = saved.split(';');
                // Check we aren't adding duplicates (edge case)
                if (!items.includes(item)) {
                    items.push(item);
                    mw.storage.set(
                        'mwchecklist-' + tableId,
                        items.join(';')
                    );
                }
            }
        };

        var removeItem = function (tableId, item) {
            var saved = mw.storage.get('mwchecklist-' + tableId);
            // Only remove if there are existing items
            if (saved !== undefined && saved !== null) {
                var items = saved.split(';')
                mw.storage.set(
                    'mwchecklist-' + tableId,
                    items.filter(function (x) { return x !== item }).join(';')
                );
            }
        }
    
        // Add checkboxes to all icons in required column
        $.each($(".collection-requires"), function (index) {
            // Important to try/catch here so the rest of the javascript still executes
            // if something funky happened.
            try {
                // Get all the icons and check they have data-items
                var $icons = $(this).find(".custom-icon").filter(function (index) {
                    return $(this).data("item") !== undefined;
                });

                // Prepend checkboxes to elements and handle hover & click
                $.each($icons, function (index) {
                    // When hovering over an item, indicate that it is actionable
                    // by applying the dropdown background
                    $(this)
                        .css("border-radius", "6px")
                        .css("padding", "2px")
                        .hover(
                            function() { $(this).css("background-color", "var(--theme-dropdown-hover)") },
                            function() { $(this).css("background-color", "var(--theme-table-td-background)") }
                        )
                        .prepend('<input type="checkbox" style="margin-right: 4px;"/>')
                        .on("click", function(event) {
                            // If this isn't the checkbox or link, click the item
                            // This allows clicking the area around instead of just the checkbox itself
                            if (event.target.localName !== "input" && event.target.localName !== "a") {
                                var isChecked = $(this).find('input[type=checkbox]').prop('checked');
                                $(this).find('input[type=checkbox]')
                                    .prop("checked", !isChecked)
                                    .trigger("change");
                            }
                        });
                });

                // When a checkbox is clicked, strikethru text and make it less visible
                $.each($(this).find('input[type=checkbox]'), function(index) {
                    var itemId = $(this).parent().data("item");
                    
                   $(this).on("change", function() {
                        if (this.checked) {
                            // Item is complete - Make less visible
                            // note: "transition" applies a smooth opacity shift instead of
                            //       instantly changing it. 
                            $(this).siblings()
                                .css("transition", "opacity")
                                .css("opacity", ".5")
                                .css("text-decoration-line", "line-through");

                            storeItem(
                            	$(this).closest('tr').data("checklist").replace("'", ""),
                            	itemId.replace("'", "")
                        	);
                        } else {
                            // Marked incomplete - Return to normal
                            $(this).siblings()
                                .css("transition", "opacity")
                                .css("opacity", "1")
                                .css("text-decoration-line", "none");
                            
                            removeItem(
                            	$(this).closest('tr').data("checklist").replace("'", ""),
                            	itemId.replace("'", "")
                        	);
                        }
                    });
                });

                // Check all checkboxes that were previously isChecked
                loadTableData();
            } catch (error) {
                console.log("Couldn't enable museum checkboxes -", error)
            }
        });
	});



/* CHECKLIST FOR MODULE:Icon list */	
$.when(
    mw.loader.using(['mediawiki.storage']),
    $.ready
).then(function () {
    var loadNewCheckboxData = function () {
        var checklists = [];

        // Collect identifiers for new functionality
        $("div.icon-list-checklist").each(function () {
            var checklistId = $(this).data("checklist");
            checklists.push(checklistId);
        });

        // Load data for the checklists
        for (var i = 0; i < checklists.length; i++) {
            var serialized = mw.storage.get('mwchecklist-' + checklists[i]);
            if (serialized === null) continue;

            var items = serialized.split(';');
            // Restore saved items
            for (var itemIndex = 0; itemIndex < items.length; itemIndex++) {
                try {
                    // Update the checkbox to the saved value
                    $("div.icon-list-checklist span[data-item='" + items[itemIndex] + "']")
                        .find('input[type=checkbox]')
                        .prop("checked", true)
                        .trigger("change");
                } catch (error) {
                    console.log("Error trying to check", items[itemIndex], ". Resetting it.", error);
                    mw.storage.set('mwchecklist-' + checklists[i], "");
                }
            }
        }
    };

    var storeNewItem = function (checklistId, item) {
        var saved = mw.storage.get('mwchecklist-' + checklistId);
        if (saved === undefined || saved === null) {
            mw.storage.set('mwchecklist-' + checklistId, item);
        } else {
            var items = saved.split(';');
            // Check we aren't adding duplicates (edge case)
            if (!items.includes(item)) {
                items.push(item);
                mw.storage.set('mwchecklist-' + checklistId, items.join(';'));
            }
        }
    };

    var removeNewItem = function (checklistId, item) {
        var saved = mw.storage.get('mwchecklist-' + checklistId);
        // Only remove if there are existing items
        if (saved !== undefined && saved !== null) {
            var items = saved.split(';');
            mw.storage.set(
                'mwchecklist-' + checklistId,
                items.filter(function (x) { return x !== item }).join(';')
            );
        }
    };

    var initializeIconListChecklist = function () {
        $("div.icon-list-checklist").find('span[data-item]').each(function () {
            // Important to try/catch here so the rest of the javascript still executes
            // if something funky happened.
            try {
                var $this = $(this);
                var checklistId = $this.closest('div.icon-list-checklist').data("checklist");
                var itemId = $this.data("item");

                // Log item for debugging
                console.log("Initializing item:", itemId);

                // Add a checkbox before the icon text if not already present
                if ($this.find('input[type=checkbox]').length === 0) {
                    console.log("Adding checkbox for item:", itemId);
                    var $checkbox = $('<input type="checkbox" style="margin-right: 4px;">');
                    $this.prepend($checkbox);

                    // When a checkbox is clicked, strikethru text and make it less visible
                    $checkbox.on("change", function () {
                        if (this.checked) {
                            console.log("Checked item:", itemId);
                            // Item is complete - Make less visible
                            // note: "transition" applies a smooth opacity shift instead of
                            //       instantly changing it.
                            $this.css("transition", "opacity")
                                .css("opacity", ".5")
                                .css("text-decoration-line", "line-through");

                            storeNewItem(checklistId, itemId);
                        } else {
                            console.log("Unchecked item:", itemId);
                            // Marked incomplete - Return to normal
                            $this.css("transition", "opacity")
                                .css("opacity", "1")
                                .css("text-decoration-line", "none");

                            removeNewItem(checklistId, itemId);
                        }
                    });
                }

                // When hovering over an item, indicate that it is actionable
                // by applying the dropdown background
                $this.hover(
                    function () { $(this).css("background-color", "var(--theme-dropdown-hover)") },
                    function () { $(this).css("background-color", "var(--theme-table-td-background)") }
                );
            } catch (error) {
                console.log("Couldn't enable checkboxes -", error);
            }
        });
    };

    initializeIconListChecklist();
    loadNewCheckboxData(); // Make sure to load data after initializing
});