MediaWiki:Common.js: Difference between revisions

From Makerpedia

Winhallk (talk | contribs)
update code for new tools page
No edit summary
 
(27 intermediate revisions by 4 users not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */


if (document) window.µ = function (id, elem) {
window.µ = function (id, elem) {
   var ret;
   var ret;
   var root = ((elem) ? elem : document);
   var root = ((elem) ? elem : document);
Line 23: Line 23:
};
};


/* add additional edit button in bottom right corner -- styled in Common.css */
window.pageParams = {};
/* Takes them to visual editor if available/logged in; if not, takes them to normal edit mode; if they are not logged in at all, takes them to login page */
const urlParams = new URLSearchParams(window.location.search);
let editLinkQuery = document.querySelector("#ca-ve-edit a") ? "#ca-ve-edit a" : (document.querySelector("#ca-edit a") ? "#ca-edit a" : "#pt-login a");
for (const [key, value] of urlParams.entries()) {
document.getElementById("content").innerHTML += '<a href='+document.querySelector(editLinkQuery).href+'><button class="big-edit-button"><p>EDIT</p></button></a>';
  window.pageParams[key] = value;
 
/* looks at current url parameters of the form '?param1=value1&param2=value2...' and returns a dictionary of the form {param1: value1, param2: value2, ...} */
function parseUrlParameters() {
    let queryStr = window.location.search.substring(1).replaceAll("%20", " "); // start string after the question mark and replace '%20' with spaces
    let queryDict = {};
    queryStr.split("&").forEach(function(query) {
        let pair = query.split("=");
        queryDict[pair[0]] = pair[1];
    })
    return queryDict;
}
}


// Project Tutorials Gallery
window.makers = {};
mw.loader.using(['mediawiki.api', 'jquery'], function () {
    $(document).ready(function () {
        if (mw.config.get('wgPageName') !== 'GALLERY') return; // Ensure script runs only on the Gallery page


        // get url parameters and automatically select filter to value of 'filter' parameter in url (eg www.wikititle/pagetitle?filter=Textiles)
window.makerSkills = [
        let queryDict = parseUrlParameters();
  {name: "3D Printing", image:"images/badges/3dprinting.png", super: "Digital Fab"},
        var category = queryDict['filter'] ? queryDict['filter'] : "Projects"; // If no filter query in url, use default category Projects
  {name: "Airbrushing", image:"images/badges/airbrushing.png", super: "Crafts"},
        var galleryContainer = $('#project-gallery');
  {name: "Button Making", image:"images/badges/button.png", super: "Crafts"},
  {name: "Music and Sound", image:"images/badges/cassette.png", super: "Crafts"},
  {name: "Crafting", image:"images/badges/crafting.png", super: "Crafts"},
  {name: "Handsewing", image:"images/badges/handsewing.png", super: "Textiles"},
  {name: "Graphic Design", image:"images/badges/graphic.png", super: "Software"},
  {name: "Laser Cutting", image:"images/badges/laser.png", super: "Digital Fab"},
  {name: "Machining", image:"images/badges/machining.png", super: "Fabrication"},
  {name: "3D Modeling", image:"images/badges/modeling.png", super: "Software"},
  {name: "Programming", image:"images/badges/programming.png", super: "Electronics"},
  {name: "Soldering", image:"images/badges/soldering.png", super: "Electronics"},
  {name: "Technical Design", image:"images/badges/technical.png", super: "Software"},
  {name: "Textiles", image:"images/badges/textile.png", super: "Textiles"},
  {name: "Welding", image:"images/badges/welding.png", super: "Fabrication"},
  {name: "Woodworking", image:"images/badges/woodworking.png", super: "Fabrication"},
];


        /* add buttons to filter by category on Project Tutorials page
//Knitting, crocheting, weaving, detail painting, miniatures, wood carving, resin and mold making, plaster, clay and ceramics, printmaking, milling, turning, cnc milling, cnc plasma cutting
          html text displayed can be anything, but value of data-filter should be the same format as value passed in url parameters and entry in categories
          dictionary in loadGallery() function */
        galleryContainer.before('<div id="category-filter">' +
        '<button id="all-filter-btn" class="filter-btn" data-filter="Projects">Show All</button>' +
        '<button id="crafts-filter-btn" class="filter-btn" data-filter="Crafts">Crafts</button>' +
        '<button id="design-filter-btn" class="filter-btn" data-filter="Design">Design</button>' +
        '<button id="fabrication-filter-btn" class="filter-btn" data-filter="Fabrication">Fabrication</button>' +
        '<button id="cnc-laser-filter-btn" class="filter-btn" data-filter="CNC-Laser">Laser & CNC</button>' +
        '<button id="metalworking-filter-btn" class="filter-btn" data-filter="Metalworking">Metalworking</button>' +
        '<button id="textiles-filter-btn" class="filter-btn" data-filter="Textiles">Textiles</button>' +
        '</div>');


        // use insertImage function to query api and insert given image at given id, with given style (adds icons to Project Tutorials filter buttons)
window.makerTools = [
        insertImage("File:Airbrushing_icon_color.png", "#fabrication-filter-btn", style="height:1.5em;padding-left:.4em");
  {name: "Makerspace Tools", super: "Makerspace Tools"},
        insertImage("File:Button_icon_color.png", "#crafts-filter-btn", style="height:1.5em;padding-left:.4em");
  {name: "Machine Shop Tools", super: "Machine Shop Tools"},
        insertImage("File:Cassette_icon_color.png", "#crafts-filter-btn", style="height:1.5em;padding-left:.4em");
  {name: "Wood Shop Tools", super: "Wood Shop Tools"},
        insertImage("File:Crafting_icon_color.png", "#crafts-filter-btn", style="height:1.5em;padding-left:.4em");
  {name: "Instrument Shop Tools", super: "Instrument Shop Tools"},
        insertImage("File:Graphic_icon_color.png", "#design-filter-btn", style="height:1.5em;padding-left:.4em");
];
        insertImage("File:Handsewing_icon_color.png", "#textiles-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Laser_icon_color.png", "#cnc-laser-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Machining_icon_color.png", "#cnc-laser-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Modeling_icon_color.png", "#design-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Printing_icon_color.png", "#fabrication-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Programming_icon_color.png", "#design-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Soldering_icon_color.png", "#metalworking-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Technical_icon_color.png", "#design-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Textile_icon_color.png", "#textiles-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Welding_icon_color.png", "#metalworking-filter-btn", style="height:1.5em;padding-left:.4em");
        insertImage("File:Woodworking_icon_color.png", "#fabrication-filter-btn", style="height:1.5em;padding-left:.4em");


        // load gallery based on category
        function loadGallery(category) {
            galleryContainer.html('<div class="gallery-container"></div>'); 


            let pageTitles = [];
window.toolCats = [
  {name: "Horizontal Bandsaws", super: "Bandsaws"},
  {name: "Vertical Bandsaws", super: "Bandsaws"},
  {name: "Vertical Knee Mills", super: "Mills"},
  {name: "Vertical Bed Mills", super: "Mills"},
  {name: "Drill Presses", super: "Drill Presses"},
  {name: "SLS 3D Printers", super: "3D Printers"},
  {name: "SLA 3D Printers", super: "3D Printers"},
  {name: "FDM 3D Printers", super: "3D Printers"},
  {name: "Toolroom Lathe", super: "Lathes"},
  {name: "Drills", super: "Power Hand Tools"},
  {name: "Drivers", super: "Power Hand Tools"},
  {name: "Portabands", super: "Power Hand Tools, Bandsaws"},
  {name: "Hand Sanders", super: "Power Hand Tools, Sanders"}
];


            // map larger umbrella categories to the skill badge categories they include
//makers.categories = Array.from(new Set(makers.skills.map(x=>x.super)));
            let categories = {
//console.log(makers.categories);
                "Projects" : ["Projects"],
                "Design" : ["Graphic Design", "3D Modeling", "Technical Design", "Programming"],
                "Textiles" : ["Textiles", "Hand Sewing"],
                "Crafts" : ["Crafting", "Button Pressing", "Cassette Making"],
                "Fabrication" : ["Airbrushing", "3D Printing", "Woodworking"],
                "CNC-Laser" : ["Laser Cutting", "Machining"],
                "Metalworking" : ["Soldering", "Welding"]
            };


            // insert projects corresponding to each skill under broader category filter selected
console.log('starting widgets');
            categories[category].forEach(function(cat) {
                new mw.Api().get({
                    action: 'query',
                    list: 'categorymembers',
                    cmtitle: 'Category:' + cat,
                    cmlimit: 50, 
                    format: 'json'
                }).done(function (data) {
                    var pages = data.query.categorymembers;
                    var galleryHtml = '';
                    var requests = pages.map(function (page) {
                        return new mw.Api().get({
                            action: 'query',
                            prop: 'revisions',
                            rvprop: 'content',
                            titles: page.title,
                            format: 'json'
                        }).then(function (pageData) {
                            var pageId = Object.keys(pageData.query.pages)[0];
                            var content = pageData.query.pages[pageId].revisions[0]['*'];
                            var pageUrl = mw.util.getUrl(page.title);
                            var imgUrl = '';


                            // Try to find a direct image URL (img1=https://...)
mw.loader.using(['mediawiki.api', 'jquery']).then(()=>{
                            var directMatch = content.match(/img1=(https:\/\/[^\s|}%]+)/);
  if(window.widgets){
                            if (directMatch) {
    for(let i=0; i<window.widgets.length; i++){
                                imgUrl = directMatch[1];
      window.widgets[i]();
                            }
    }
 
  }
                            // If no direct URL, try to find a [[File:...]] entry
                            var fileMatch = content.match(/\[\[File:([^|\]]+)/);
                            if (!imgUrl && fileMatch) {
                                var fileName = fileMatch[1].trim();
 
                                // Fetch full image URL from MediaWiki API
                                return new mw.Api().get({
                                    action: 'query',
                                    titles: 'File:' + fileName,
                                    prop: 'imageinfo',
                                    iiprop: 'url',
                                    format: 'json'
                                }).then(function (imageData) {
                                    var imagePageId = Object.keys(imageData.query.pages)[0];
                                    if (imageData.query.pages[imagePageId].imageinfo) {
                                        imgUrl = imageData.query.pages[imagePageId].imageinfo[0].url;
                                    }
 
                               
                                    galleryHtml += generateGalleryItem(pageUrl, page.title, imgUrl, category);
                                });
                            } else {
                                // Add the gallery item if the image was found and is not already being shown
                                  if(!pageTitles.includes(page.title)) {
                                    galleryHtml += generateGalleryItem(pageUrl, page.title, imgUrl, category);
                                    pageTitles.push(page.title);
                                  }
                            }
                        });
                    });
 
                Promise.all(requests).then(function () {
                    $('.gallery-container').append(galleryHtml);
                });
                });
            });
        }
 
        // generate a gallery
        function generateGalleryItem(pageUrl, title, imgUrl, category) {
            return `
                <div class="gallery-item ${category}">
                    <a href="${pageUrl}">
                        ${imgUrl ? `<img src="${imgUrl}" alt="${title}">` : `<img src="https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg" alt="No Image Available">`}
 
                    </a>
                    <div class="gallery-caption">
                        <a href="${pageUrl}">${title}</a>
                    </div>
                </div>
            `;
        }
 
        loadGallery(category);
 
        // find filter button corresponding to selected category and add css class 'selected-filter'
        $(".filter-btn").each(function () { $(this).data("filter") === category ? $(this).addClass('selected-filter') : null});
 
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button
        $(".filter-btn").click(function () {
            var selectedCategory = $(this).data("filter");
            loadGallery(selectedCategory);
            $('.filter-btn.selected-filter').each((i, elem) => $(elem).removeClass('selected-filter'));
            $(this).addClass('selected-filter');
        });
    });
});
});


// Tools Gallery
/* add additional edit button in bottom right corner -- styled in Common.css */  
mw.loader.using(['mediawiki.api', 'jquery'], function () {
/* Takes them to visual editor if available/logged in; if not, takes them to normal edit mode; if they are not logged in at all, takes them to login page */
    $(document).ready(function () {
let editLinkQuery = document.querySelector("#ca-ve-edit a") ? "#ca-ve-edit a" : (document.querySelector("#ca-edit a") ? "#ca-edit a" : "#pt-login a");
        if (mw.config.get('wgPageName') !== 'Tools') return;  // Ensure script runs only on the Tools page
document.getElementById("content").innerHTML += '<a href='+document.querySelector(editLinkQuery).href+'><button class="big-edit-button"><p>EDIT</p></button></a>';
 
        // get url parameters and automatically select appropriate filter
        let queryDict = parseUrlParameters();
        var category = queryDict['filter'] ? queryDict['filter'] : "Tools"; // If no filter query in url, use default category
        var galleryContainer = $('#tools-gallery'); 
 
        // Add filter buttons before the gallery
        galleryContainer.before('<div id="category-filter">' +
            '<button class="filter-btn" data-filter="Tools">Show All</button>' + 
            '<button class="filter-btn" data-filter="Makerspace Tools">Makerspace Tools</button>' +
            '<button class="filter-btn" data-filter="Machine Shop Tools">Machine Shop Tools</button>' +
            '<button class="filter-btn" data-filter="Wood Shop Tools">Wood Shop Tools</button>' +
            '<button class="filter-btn" data-filter="Instrument Shop Tools">Instrument Shop Tools</button>' +
            '<button class="filter-btn" data-filter="Repair Lair Tools">Repair Lair Tools</button>' +
        '</div>');
 
        function loadGallery(category) {
            galleryContainer.html('<div class="gallery-container">Loading gallery...</div>'); 
 
            new mw.Api().get({
                action: 'query',
                list: 'categorymembers',
                cmtitle: 'Category:' + category,
                cmlimit: 50, 
                format: 'json'
            }).done(function (data) {
                var pages = data.query.categorymembers;
                var galleryHtml = '';
 
                var requests = pages.map(function (page) {
                    return new mw.Api().get({
                        action: 'query',
                        prop: 'revisions',
                        rvprop: 'content',
                        titles: page.title,
                        format: 'json'
                    }).then(function (pageData) {
                        var pageId = Object.keys(pageData.query.pages)[0];
                        var content = pageData.query.pages[pageId].revisions[0]['*'];
                        var pageUrl = mw.util.getUrl(page.title);
                        var imgUrl = '';
 
                        // Try to find a [[File:...]] entry
                        var fileMatch = content.match(/\[\[File:([^|\]]+)/);
                        if (fileMatch) {
                            var fileName = fileMatch[1].trim();
 
                            // Fetch full image URL from MediaWiki API
                            return new mw.Api().get({
                                action: 'query',
                                titles: 'File:' + fileName,
                                prop: 'imageinfo',
                                iiprop: 'url',
                                format: 'json'
                            }).then(function (imageData) {
                                var imagePageId = Object.keys(imageData.query.pages)[0];
                                if (imageData.query.pages[imagePageId].imageinfo) {
                                    imgUrl = imageData.query.pages[imagePageId].imageinfo[0].url;
                                }
 
                                // Add the gallery item
                                galleryHtml += generateGalleryItem(pageUrl, page.title, imgUrl, category);
                            });
                        } else {
                            // If no image is found, still display the title
                            galleryHtml += generateGalleryItem(pageUrl, page.title, imgUrl, category);
                        }
                    });
                });
 
                Promise.all(requests).then(function () {
                    // Append gallery items after loading them
                    galleryContainer.html('<div class="gallery-container">' + galleryHtml + '</div>');
                });
            });
        }
 
        function generateGalleryItem(pageUrl, title, imgUrl, category) {
            return `
                <div class="gallery-item ${category}">
                    <a href="${pageUrl}">
                        ${imgUrl ? `<img src="${imgUrl}" alt="${title}">` : `<img src="https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg" alt="No Image Available">`}
 
                    </a>
                    <div class="gallery-caption">
                        <a href="${pageUrl}">${title}</a>
                    </div>
                </div>
            `;
        }
 
        loadGallery(category);
 
        // find filter button corresponding to preselected category and add css class 'selected-filter'
        $(".filter-btn").each(function () { $(this).data("filter") === category ? $(this).addClass('selected-filter') : null});
 
        // when filter button is clicked, load tools for that category, deselect current filtered button, and select newly clicked filter button
        $(".filter-btn").click(function () {
            var selectedCategory = $(this).data("filter");
            loadGallery(selectedCategory); 
            $('.filter-btn.selected-filter').each((i, elem) => $(elem).removeClass('selected-filter'));
            $(this).addClass('selected-filter');
        });
    });
});
 
 
//CAROUSEL
function loadCarouselData() {
    // Make the API query to fetch pages for carousel
    var category = "SimpleProjects";
    var carouselData = [];
 
    new mw.Api().get({
        action: 'query',
        list: 'categorymembers',
        cmtitle: 'Category:' + category,
        cmlimit: 50,
        format: 'json'
    }).done(function (data) {
        var pages = data.query.categorymembers;
 
        var requests = pages.map(function (page) {
            return new mw.Api().get({
                action: 'query',
                prop: 'revisions',
                rvprop: 'content',
                titles: page.title,
                format: 'json'
            }).then(function (pageData) {
                var pageId = Object.keys(pageData.query.pages)[0];
                var content = pageData.query.pages[pageId].revisions[0]['*'];
                var pageUrl = mw.util.getUrl(page.title);
                var imgUrl = '';
 
                // Try to find a direct image URL (img1=https://...)
                var directMatch = content.match(/img1=(https:\/\/[^\s|}%]+)/);
                if (directMatch) {
                    imgUrl = directMatch[1];
                }
 
                // If no direct URL, try to find a [[File:...]] entry
                var fileMatch = content.match(/\[\[File:([^|\]]+)/);
                if (!imgUrl && fileMatch) {
                    var fileName = fileMatch[1].trim();
 
                    // Fetch full image URL from MediaWiki API
                    return new mw.Api().get({
                        action: 'query',
                        titles: 'File:' + fileName,
                        prop: 'imageinfo',
                        iiprop: 'url',
                        format: 'json'
                    }).then(function (imageData) {
                        var imagePageId = Object.keys(imageData.query.pages)[0];
                        if (imageData.query.pages[imagePageId].imageinfo) {
                            imgUrl = imageData.query.pages[imagePageId].imageinfo[0].url;
                        }
 
                        // Store carousel item data
                        if (imgUrl) {
                            carouselData.push({ pageUrl: pageUrl, imgUrl: imgUrl, title: page.title });
                        }
                    });
                } else {
                    // Store carousel item data
                    if (imgUrl) {
                        carouselData.push({ pageUrl: pageUrl, imgUrl: imgUrl, title: page.title });
                    }
                }
            });
        });
 
        Promise.all(requests).then(function () {
            // Call the function to display carousel
            displayCarousel(carouselData);
        });
    });
}
 
 
function displayCarousel(carouselData) {
    var carouselHtml = '';
 
    carouselData.forEach(function (item) {
        carouselHtml += `
            <div class="carousel-item">
                <a href="${item.pageUrl}">
                    <img src="${item.imgUrl}" alt="Carousel Image">
                </a>
              <div class="carousel-title">${item.title}</div>
            </div>
        `;
    });
 
    // Inject the HTML into the carousel container
    var carouselContainer = $('.carousel-container');
    carouselContainer.html(carouselHtml);
 
    // Initialize the carousel behavior
    initializeCarousel();
}
 
function initializeCarousel() {
    let currentIndex = 0;
    let $carouselItems = $(".carousel-item");
    let totalItems = $carouselItems.length;
   
    $carouselItems.hide().eq(currentIndex).show();
 
    let $prevButton = $('<button class="carousel-prev"> &#128896; </button>');
    let $nextButton = $('<button class="carousel-next"> &#128898; </button>');
    $('.carousel-container').append($prevButton, $nextButton);
   
    function nextSlide() {
        currentIndex = (currentIndex + 1) % totalItems;
        updateCarousel();
    }
 
    let autoSlide = setInterval(nextSlide, 10000); //auto slide every 10 seconds
    function resetInterval() {
        clearInterval(autoSlide);
        autoSlide = setInterval(nextSlide, 10000);
    }
 
    $nextButton.click(function () {
        nextSlide();
        resetInterval();
    });
 
    $prevButton.click(function () {
        currentIndex = (currentIndex - 1 + totalItems) % totalItems;
        updateCarousel();
        resetInterval();
    });
 
    function updateCarousel () {
      $carouselItems.hide().eq(currentIndex).show();
    }
}
 
$(document).ready(function () {
    loadCarouselData(); // Load the carousel data on page load
});  




Line 520: Line 170:
             let urlSub = url.substring(url.indexOf("/")); // get just later part of url as link to image (after first slash)
             let urlSub = url.substring(url.indexOf("/")); // get just later part of url as link to image (after first slash)
             if(asLinkedSkillBadge) { // insert as linked skill badge (image wrapped in <a> with link to prefiltered Project Tutorials page)
             if(asLinkedSkillBadge) { // insert as linked skill badge (image wrapped in <a> with link to prefiltered Project Tutorials page)
                 document.querySelector(selector).innerHTML += '<a href="./GALLERY?title=GALLERY&filter='+linkFilter+'" title="'+tooltip+'"><img class="skill-badge-img" src="'+urlSub+'" alt="'+alt+'" style="'+style+'"></a>';
                 document.querySelector(selector).innerHTML += '<a href="./Project_Tutorials?title=Project_Tutorials&filter='+linkFilter+'" title="'+tooltip+'"><img class="skill-badge-img" src="'+urlSub+'" alt="'+alt+'" style="'+style+'"></a>';
             }
             }
             else { // insert as regular image
             else { // insert as regular image
Line 531: Line 181:
/* like button. Only appears on "Main" Namespace pages that aren't sidebar pages (should be restricted to content pages like articles).*/
/* like button. Only appears on "Main" Namespace pages that aren't sidebar pages (should be restricted to content pages like articles).*/
/* Styled in common.css*/
/* Styled in common.css*/
if (mw.config.get('wgNamespaceNumber') == 0 && mw.config.get('wgPageName') !== 'GALLERY' && mw.config.get('wgPageName') !== 'Tools' && mw.config.get('wgPageName') !== 'Spaces_New' && mw.config.get('wgPageName') !== 'Home_New') {
if (mw.config.get('wgNamespaceNumber') == 0 && mw.config.get('wgPageName') !== 'Project_Tutorials' && mw.config.get('wgPageName') !== 'Tools' && mw.config.get('wgPageName') !== 'Spaces' && mw.config.get('wgPageName') !== 'Home') {
     // if page is favorited we should show unfavorite button instead. Direct to login if not logged in.
     // if page is favorited we should show unfavorite button instead. Direct to login if not logged in.
     if (document.querySelector("#ca-favorite")) {
     if (document.querySelector("#ca-favorite")) {

Latest revision as of 21:51, 30 March 2025

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

window.µ = function (id, elem) {
  var ret;
  var root = ((elem) ? elem : document);
  switch (id.charAt(0)) {
    case '|':
      ret = root;
      break;
    case '+':
      ret = document.createElement(id.substring(1));
      if (elem) elem.appendChild(ret);
      break;
    case '#':
      ret = root.querySelector(id);
      break;
    default:
      ret = Array.prototype.slice.call(root.querySelectorAll(id));
      break;
  }

  return ret;
};

window.pageParams = {};
const urlParams = new URLSearchParams(window.location.search);
for (const [key, value] of urlParams.entries()) {
  window.pageParams[key] = value;
}

window.makers = {};

window.makerSkills = [
   {name: "3D Printing", image:"images/badges/3dprinting.png", super: "Digital Fab"},
   {name: "Airbrushing", image:"images/badges/airbrushing.png", super: "Crafts"},
   {name: "Button Making", image:"images/badges/button.png", super: "Crafts"},
   {name: "Music and Sound", image:"images/badges/cassette.png", super: "Crafts"},
   {name: "Crafting", image:"images/badges/crafting.png", super: "Crafts"},
   {name: "Handsewing", image:"images/badges/handsewing.png", super: "Textiles"},
   {name: "Graphic Design", image:"images/badges/graphic.png", super: "Software"},
   {name: "Laser Cutting", image:"images/badges/laser.png", super: "Digital Fab"},
   {name: "Machining", image:"images/badges/machining.png", super: "Fabrication"},
   {name: "3D Modeling", image:"images/badges/modeling.png", super: "Software"},
   {name: "Programming", image:"images/badges/programming.png", super: "Electronics"},
   {name: "Soldering", image:"images/badges/soldering.png", super: "Electronics"},
   {name: "Technical Design", image:"images/badges/technical.png", super: "Software"},
   {name: "Textiles", image:"images/badges/textile.png", super: "Textiles"},
   {name: "Welding", image:"images/badges/welding.png", super: "Fabrication"},
   {name: "Woodworking", image:"images/badges/woodworking.png", super: "Fabrication"},
];

//Knitting, crocheting, weaving, detail painting, miniatures, wood carving, resin and mold making, plaster, clay and ceramics, printmaking, milling, turning, cnc milling, cnc plasma cutting

window.makerTools = [
   {name: "Makerspace Tools", super: "Makerspace Tools"},
   {name: "Machine Shop Tools", super: "Machine Shop Tools"},
   {name: "Wood Shop Tools", super: "Wood Shop Tools"},
   {name: "Instrument Shop Tools", super: "Instrument Shop Tools"},
];


window.toolCats = [
   {name: "Horizontal Bandsaws", super: "Bandsaws"},
   {name: "Vertical Bandsaws", super: "Bandsaws"},
   {name: "Vertical Knee Mills", super: "Mills"},
   {name: "Vertical Bed Mills", super: "Mills"},
   {name: "Drill Presses", super: "Drill Presses"},
   {name: "SLS 3D Printers", super: "3D Printers"},
   {name: "SLA 3D Printers", super: "3D Printers"},
   {name: "FDM 3D Printers", super: "3D Printers"},
   {name: "Toolroom Lathe", super: "Lathes"},
   {name: "Drills", super: "Power Hand Tools"},
   {name: "Drivers", super: "Power Hand Tools"},
   {name: "Portabands", super: "Power Hand Tools, Bandsaws"},
   {name: "Hand Sanders", super: "Power Hand Tools, Sanders"}
];

//makers.categories = Array.from(new Set(makers.skills.map(x=>x.super)));
//console.log(makers.categories);

console.log('starting widgets');

mw.loader.using(['mediawiki.api', 'jquery']).then(()=>{
  if(window.widgets){
    for(let i=0; i<window.widgets.length; i++){
      window.widgets[i]();
    }
  }
});

/* add additional edit button in bottom right corner -- styled in Common.css */ 
/* Takes them to visual editor if available/logged in; if not, takes them to normal edit mode; if they are not logged in at all, takes them to login page */
let editLinkQuery = document.querySelector("#ca-ve-edit a") ? "#ca-ve-edit a" : (document.querySelector("#ca-edit a") ? "#ca-edit a" : "#pt-login a");
document.getElementById("content").innerHTML += '<a href='+document.querySelector(editLinkQuery).href+'><button class="big-edit-button"><p>EDIT</p></button></a>';



// Individual Project pages (and potentially tools): if page is part of a category, insert any corresponding skill badges at top of page
if(document.getElementById("catlinks") != null) {
    document.querySelectorAll("#catlinks li a").forEach((cat) => {
        let query = "#firstHeading";
        if(cat.title.includes("Category:Airbrushing")) {
            insertImage('File:Airbrushing_badge_small.png', query, "padding-left:.3em;", "Fabrication", true, "Airbrushing");
        }
        if(cat.title.includes("Category:Button Pressing")) {
            insertImage('File:Button_badge_small.png', query, "padding-left:.3em;", "Crafts", true, "Button Pressing");
        } 
        if(cat.title.includes("Category:Cassette Making")) {
            insertImage('File:Cassette_badge_small.png', query, "padding-left:.3em;", "Crafts", true, "Cassette Making");
        } 
        if(cat.title.includes("Category:Crafting")) {
            insertImage('File:Crafting_badge_small.png', query, "padding-left:.3em;", "Crafts", true, "Crafting");
        }
        if(cat.title.includes("Category:Graphic Design")) {
            insertImage('File:Graphic_badge_small.png', query, "padding-left:.3em;", "Design", true, "Graphic Design");
        } 
        if(cat.title.includes("Category:Hand Sewing")) {
            insertImage('File:Handsewing_badge_small.png', query, "padding-left:.3em;", "Textiles", true, "Hand Sewing");
        } 
        if(cat.title.includes("Category:Laser Cutting")) {
            insertImage('File:Laser_badge_small.png', query, "padding-left:.3em;", "CNC-Laser", true, "Laser Cutting");
        } 
        if(cat.title.includes("Category:Machining")) {
            insertImage('File:Machining_badge_small.png', query, "padding-left:.3em;", "CNC-Laser", true, "Machining");
        } 
        if(cat.title.includes("Category:3D Modeling")) {
            insertImage('File:Modeling_badge_small.png', query, "padding-left:.3em;", "Design", true, "3D Modeling");
        } 
        if(cat.title.includes("Category:3D Printing")) {
            insertImage('File:Printing_badge_small.png', query, "padding-left:.3em;", "Fabrication", true, "3D Printing");
        } 
        if(cat.title.includes("Category:Programming")) {
            insertImage('File:Programming_badge_small.png', query, "padding-left:.3em;", "Design", true, "Programming");
        } 
        if(cat.title.includes("Category:Soldering")) {
            insertImage('File:Soldering_badge_small.png', query, "padding-left:.3em;", "Metalworking", true, "Soldering");
        } 
        if(cat.title.includes("Category:Technical Design")) {
            insertImage('File:Technical_badge_small.png', query, "padding-left:.3em;", "Design", true, "Technical Design");
        } 
        if(cat.title.includes("Category:Textiles")) {
            insertImage('File:Textile_badge_small.png', query, "padding-left:.3em;", "Textiles", true, "Textiles");
        } 
        if(cat.title.includes("Category:Welding")) {
            insertImage('File:Welding_badge_small.png', query, "padding-left:.3em;", "Metalworking", true, "Welding");
        } 
        if(cat.title.includes("Category:Woodworking")) {
            insertImage('File:Woodworking_badge_small.png', query, "padding-left:.3em;", "Fabrication", true, "Woodworking");
        } 
    })
}

// uses api to insert image at given selector element in html, using image in mediawiki format (eg [[File:filename...]])
// optional style parameter gets applied
// if asLinkedSkillBadge is true, styles as skill badge (image wrapped in <a> link)
function insertImage(image, selector, style="", linkFilter="", asLinkedSkillBadge=false, tooltip=image) {
    $.getJSON(
        mw.util.wikiScript( 'api' ), {
            format: 'json',
            action: 'query',
            titles: image,
            prop: 'imageinfo',
            iiprop: 'url'
        },
        function( obj ) {
            let pages = obj.query.pages;
            let result1 = pages[Object.keys(pages)[0]];
            let url = result1.imageinfo[0].url;
            let alt = result1.title; // set alt text to image title
            let urlSub = url.substring(url.indexOf("/")); // get just later part of url as link to image (after first slash)
            if(asLinkedSkillBadge) { // insert as linked skill badge (image wrapped in <a> with link to prefiltered Project Tutorials page)
                document.querySelector(selector).innerHTML += '<a href="./Project_Tutorials?title=Project_Tutorials&filter='+linkFilter+'" title="'+tooltip+'"><img class="skill-badge-img" src="'+urlSub+'" alt="'+alt+'" style="'+style+'"></a>';
            }
            else { // insert as regular image
                document.querySelector(selector).innerHTML += '<img src="'+urlSub+'" alt="'+alt+'" style="'+style+'">';
            }
        }
    );
}

/* like button. Only appears on "Main" Namespace pages that aren't sidebar pages (should be restricted to content pages like articles).*/
/* Styled in common.css*/
if (mw.config.get('wgNamespaceNumber') == 0 && mw.config.get('wgPageName') !== 'Project_Tutorials' && mw.config.get('wgPageName') !== 'Tools' && mw.config.get('wgPageName') !== 'Spaces' && mw.config.get('wgPageName') !== 'Home') {
    // if page is favorited we should show unfavorite button instead. Direct to login if not logged in.
    if (document.querySelector("#ca-favorite")) {
        document.getElementById("firstHeading").innerHTML += '<a href=/wiki/index.php?title='+mw.config.get('wgPageName')+'&action=favorite&returnto='+mw.config.get('wgPageName')+'><button class="favorite"></button></a>';
    } else if (document.querySelector("#ca-unfavorite")) {
        document.getElementById("firstHeading").innerHTML += '<a href=/wiki/index.php?title='+mw.config.get('wgPageName')+'&action=unfavorite&returnto='+mw.config.get('wgPageName')+'><button class="unfavorite"></button></a>';
    // occurs if the user is not logged in:
    } else {
        document.getElementById("firstHeading").innerHTML += '<a href='+document.querySelector("#pt-login a").href+'><button class="favorite"></button></a>';
    };
};

// open any <a> wrapped in <u class="plainlinks"> in same tab (generally internal links that must be treated as external links in order to give url parameters)
$('u.plainlinks a').each(function() { $(this).attr('target', "_self")});