MediaWiki:Common.js: Difference between revisions

From Makerpedia

EvaC (talk | contribs)
No edit summary
No edit summary
 
(185 intermediate revisions by 6 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 (prioritize 'Edit' over 'Edit Source' when available) -- styled in Medik.css */
window.pageParams = {};
if(document.getElementById("ca-edit") != null || document.getElementById("ca-ve-edit") != null) {
const urlParams = new URLSearchParams(window.location.search);
    let link = document.getElementById("ca-ve-edit") != null ? document.querySelector("#ca-ve-edit a").href : document.querySelector("#ca-edit a").href;
for (const [key, value] of urlParams.entries()) {
    document.getElementById("content").innerHTML += '<a href='+link+'><button class="big-edit-button"><p>EDIT</p></button></a>';
  window.pageParams[key] = value;
}
}


$(document).ready(function () {
window.makers = {};
    // Add the category filter buttons before the gallery
    $("#tool-gallery").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="Wood Shop Tools">Wood Shop Tools</button>' +
        '<button class="filter-btn" data-filter="Machine Shop Tools">Machine Shop Tools</button>' +
    '</div>');


    // Initially, show all galleries
window.makerSkills = [
    $("#tool-gallery, #makerspace-gallery, #machineshop-gallery, #woodshop-gallery").show();
  {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"},
];


    // Filter logic when a button is clicked
//Knitting, crocheting, weaving, detail painting, miniatures, wood carving, resin and mold making, plaster, clay and ceramics, printmaking, milling, turning, cnc milling, cnc plasma cutting
    $(".filter-btn").click(function () {
        var selectedCategory = $(this).data("filter");


        // Hide all galleries first
window.makerTools = [
        $("#tool-gallery, #makerspace-gallery, #machineshop-gallery, #woodshop-gallery").hide();
  {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"},
];


        // Show the appropriate gallery based on the selected category
        if (selectedCategory === "Tools") {
            // Show all galleries when "Show All" is clicked
            $("#tool-gallery, #makerspace-gallery, #machineshop-gallery, #woodshop-gallery").show();
        } else if (selectedCategory === "Machine Shop Tools") {
            // Show only Machine Shop Tools gallery
            $("#machineshop-gallery").show();
        } else if (selectedCategory === "Makerspace Tools") {
            // Show only Makerspace Tools gallery
            $("#makerspace-gallery").show();
        } else if (selectedCategory === "Wood Shop Tools") {
            // Show only Wood Shop Tools gallery
            $("#woodshop-gallery").show();
        }
    });
});


$(document).ready(function () {
window.toolCats = [
    let currentIndex = 0;
  {name: "Horizontal Bandsaws", super: "Bandsaws"},
    let $carouselItems = $(".carousel-item");
  {name: "Vertical Bandsaws", super: "Bandsaws"},
    let totalItems = $carouselItems.length;
  {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');


    $(".carousel-count").text(`Total Images: ${totalItems}`);
mw.loader.using(['mediawiki.api', 'jquery']).then(()=>{
     // Hide all items and show the first one by default
  if(window.widgets){
    $carouselItems.hide();
     for(let i=0; i<window.widgets.length; i++){
     $carouselItems.eq(currentIndex).show();
      window.widgets[i]();
     }
  }
});


    // Create the Next and Previous buttons
/* add additional edit button in bottom right corner -- styled in Common.css */
    let $prevButton = $('<button class="carousel-prev"> ◀ </button>');
/* 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 $nextButton = $('<button class="carousel-next"> </button>');
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>';


    // add buttons to the carousel container
    $(".carousel-container").append($prevButton, $nextButton);




     $nextButton.click(function () {
// Individual Project pages (and potentially tools): if page is part of a category, insert any corresponding skill badges at top of page
         if (currentIndex < totalItems - 1) {
if(document.getElementById("catlinks") != null) {
             currentIndex++;
     document.querySelectorAll("#catlinks li a").forEach((cat) => {
        } else {
        let query = "#firstHeading";
            currentIndex = 0; // Loop back to the first item
         if(cat.title.includes("Category:Airbrushing")) {
             insertImage('File:Airbrushing_badge_small.png', query, "padding-left:.3em;", "Fabrication", true, "Airbrushing");
         }
         }
         updateCarousel();
         if(cat.title.includes("Category:Button Pressing")) {
    });
            insertImage('File:Button_badge_small.png', query, "padding-left:.3em;", "Crafts", true, "Button Pressing");
 
        }
    // Previous button click
        if(cat.title.includes("Category:Cassette Making")) {
    $prevButton.click(function () {
             insertImage('File:Cassette_badge_small.png', query, "padding-left:.3em;", "Crafts", true, "Cassette Making");
        if (currentIndex > 0) {
         }  
             currentIndex--;
        if(cat.title.includes("Category:Crafting")) {
         } else {
             insertImage('File:Crafting_badge_small.png', query, "padding-left:.3em;", "Crafts", true, "Crafting");
             currentIndex = totalItems - 1; // Loop back to the last item
         }
         }
         updateCarousel();
         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");
        }
     })
}


    // Function to update the carousel view
// uses api to insert image at given selector element in html, using image in mediawiki format (eg [[File:filename...]])
    function updateCarousel() {
// optional style parameter gets applied
        $carouselItems.hide(); // Hide all items
// if asLinkedSkillBadge is true, styles as skill badge (image wrapped in <a> link)
        $carouselItems.eq(currentIndex).show(); // Show the active one
function insertImage(image, selector, style="", linkFilter="", asLinkedSkillBadge=false, tooltip=image) {
    }
     $.getJSON(
});
         mw.util.wikiScript( 'api' ), {
 
            format: 'json',
 
// Gallery
mw.loader.using(['mediawiki.api', 'jquery'], function () {
     $(document).ready(function () {
         if (mw.config.get('wgPageName') !== 'Gallery') return;  // Run only on the Gallery page
       
        var category = "Projects";  // The category to scan
        var galleryContainer = $('#project-gallery').empty(); // Target the div
 
        new mw.Api().get({
             action: 'query',
             action: 'query',
             list: 'categorymembers',
             titles: image,
             cmtitle: 'Category:' + category,
             prop: 'imageinfo',
             cmlimit: 50,  // Adjust if needed
             iiprop: 'url'
            format: 'json'
         },
         }).done(function (data) {
        function( obj ) {
             var pages = data.query.categorymembers;
             let pages = obj.query.pages;
             var galleryHtml = '<div class="gallery-container">';
             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+'">';
            }
        }
    );
}


            var requests = pages.map(function (page) {
/* like button. Only appears on "Main" Namespace pages that aren't sidebar pages (should be restricted to content pages like articles).*/
                return new mw.Api().get({
/* Styled in common.css*/
                    action: 'query',
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') {
                    prop: 'revisions',
    // if page is favorited we should show unfavorite button instead. Direct to login if not logged in.
                    rvprop: 'content',
    if (document.querySelector("#ca-favorite")) {
                    titles: page.title,
        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>';
                    format: 'json'
    } else if (document.querySelector("#ca-unfavorite")) {
                }).then(function (pageData) {
        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>';
                    var pageId = Object.keys(pageData.query.pages)[0];
    // occurs if the user is not logged in:
                    var content = pageData.query.pages[pageId].revisions[0]['*'];
    } else {
                    var match = content.match(/img1=(https:\/\/[^\n|}%s]+)/);
        document.getElementById("firstHeading").innerHTML += '<a href='+document.querySelector("#pt-login a").href+'><button class="favorite"></button></a>';
                   
    };
                    if (match) {
};
                        var imgUrl = match[1];
                        var pageUrl = mw.util.getUrl(page.title);
 
                        galleryHtml += `
                            <div class="gallery-item">
                                <a href="${pageUrl}">
                                    <img src="${imgUrl}" style="width: 200px;">
                                </a>
                                <div class="gallery-caption">
                                    <a href="${pageUrl}">${page.title}</a>
                                </div>
                            </div>
                        `;
                    }
                });
            });


            Promise.all(requests).then(function () {
// 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)
                galleryHtml += '</div>';
$('u.plainlinks a').each(function() { $(this).attr('target', "_self")});
                galleryContainer.html(galleryHtml);
            });
        });
    });
});

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")});