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

MediaWiki:Mobile.js: Difference between revisions

MediaWiki interface page
m (try hiding unselected elements instead)
Tags: mobile edit mobile web edit
(Removal of Ko-Fi)
 
(17 intermediate revisions by one other user not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for users using the mobile site */
/* Any JavaScript here will be loaded for users using the mobile site */


// For filtering items
/* Adds links to the sidebar menu
var elementsToFilter = {};
* A workaround for MobileFrontend not supporting customization yet
* Ref: https://www.mediawiki.org/wiki/Topic:Vqy1kx6q4e0bzvyb
*/
var timer = setInterval(function() {
  if ($('.menu ul:first').length) {
    console.log("mobile menu exists");
    clearInterval(timer);
    $('.menu ul:first').after(
        '<ul> \
            <li><a href="#"> \
                <span>Navigation</span> \
              </a> \
            </li> \
            <li><a href="/wiki/BlazBlue_(Franchise)" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>About BlazBlue</span></a> \
            </li> \
            <li><a href="/wiki/Characters" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Characters</span></a> \
            </li> \
            <li><a href="/wiki/Locations" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Locations</span></a> \
            </li> \
            <li><a href="/wiki/Lore" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Lore</span></a> \
            </li> \
            <li><a href="/wiki/Category:Items" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Items</span></a> \
            </li> \
            <li><a href="/wiki/Category:Events" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Events</span></a> \
            </li> \
            <li><a href="/wiki/Category:Species" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Species</span></a> \
            </li> \
            <li><a href="/wiki/Category:Organizations" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Organizations</span></a> \
            </li> \
            <li><a href="/wiki/Merchandise" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Merchandise</span></a> \
            </li> \
        </ul> \
        <ul> \
        <li><a href="#"> \
                <span>BBDW</span> \
              </a> \
            </li> \
            <li><a href="/wiki/BlazBlue_Alternative:_Dark_War" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>About BBDW</span></a> \
            </li> \
            <li><a href="/wiki/Characters_(BBDW)" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Characters</span></a> \
            </li> \
            <li><a href="/wiki/Grimoires_(BBDW)" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Grimoires</span></a> \
            </li> \
            <li><a href="/wiki/Items_(BBDW)" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Items</span></a> \
            </li> \
            <li><a href="/wiki/BlazBlue_Alternative:_Dark_War/Guides/System" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>System</span></a> \
            </li> \
            <li><a href="/wiki/BlazBlue_Alternative:_Dark_War/Guides" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Guides</span></a> \
            </li> \
        </ul> \
        <ul class="level1"> \
            <li><a href="#"> \
                <span>Community</span></a> \
            </li> \
            <ul class ="level2"> \
                <li><a href="/wiki/Help:Manual_of_Style" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>Manual of Style</span></a> \
                </li> \
                <li><a href="/wiki/Help:ToDo" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>To Do List</span></a> \
                </li> \
                <li><a href="https://discord.gg/7TnmT7X" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>Discord</span></a> \
                </li> \
                <li><a href="https://www.facebook.com/TheBlazBlueWiki" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>Facebook</span></a> \
                </li> \
                <li><a href="https://twitter.com/BlazBlue_Wiki" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>Twitter</span></a> \
                </li> \
            </ul> \
        </ul>'
    );
    $(".menu").find(".level2").hide(); // hide level2 until level1 is clicked
    $(".level1").click(function(event){
        $(this).find(".level2").slideToggle(500);
    }); // if level1 is clicked, dropdown level2
  }
}, 100); // check every 100ms


var gameSelectOptions = '{ \
/*
  "name":"gameSelect",\
* see also MediaWiki:Gadget-DropdownFilter.js
  "attribute":"data-game",\
*/
  "options":[ \
  var elementsToFilter = {}; /* for createDropdownSelects() */
        ["Game", ""],\
        ["BBCT", ""],\
        ["BBCS", ""],\
        ["BBCSEX", ""],\
        ["BBCP", ""],\
        ["BBCPEX", ""],\
        ["BBCF", ""],\
        ["BBTAG", ""]\
    ]\
}';
 
$(document).ready(function() {
    // For filtering items
    elementsToFilter = document.getElementsByClassName("filter-element");


  $(document).ready(function() {
     createDropdownSelects();
     createDropdownSelects();
});
    createCollapsibleTables();
 
  });
function createDropdownSelects() {
 
/* For filtering items with Template:DropdownFilter */
  function createDropdownSelects() {
    var selectionParameters = document.getElementById("selectionOptions");
     var selectRowElement = document.getElementById("selectRow");
     var selectRowElement = document.getElementById("selectRow");
     if (!selectRowElement) {
     if (!selectRowElement || !selectionParameters) {
         return;
         return;
     }
     }
     selectRowElement.setAttribute("style", "padding: 6px;");
     selectRowElement.setAttribute("style", "padding: 6px;");
   
    var gameSelect = document.getElementById('gameSelectDiv');
    createDropdownSelect(gameSelect, gameSelectOptions);
}


function createDropdownSelect(dropdownDiv, optionList) {
    var dropdownSelectionOptions = selectionParameters.innerHTML;
    createDropdownSelect(dropdownSelectionOptions);
  }
 
  function createDropdownSelect(optionList) {
     var i = 0;
     var i = 0;
     var dropdown = JSON.parse(optionList);
     var dropdown = JSON.parse(optionList);
    /* read options from the JSON */
    var dropdownDiv = document.getElementById(dropdown.divID);
    elementsToFilter = document.getElementsByClassName(dropdown.applyToElementsWithThisClass);
    /* create the options to populate the dropdown with */
     var html = "<select id=\"" + dropdown.name + "\" name=\"" + dropdown.name + "\" class=\"form-control\" onchange=\"filter('" + dropdown.name + "','" + dropdown.attribute + "'" + ")\">";
     var html = "<select id=\"" + dropdown.name + "\" name=\"" + dropdown.name + "\" class=\"form-control\" onchange=\"filter('" + dropdown.name + "','" + dropdown.attribute + "'" + ")\">";


Line 54: Line 163:
     }
     }


    /* populate the dropdown */
     dropdownDiv.innerHTML += html;
     dropdownDiv.innerHTML += html;
}
  }
 
  /*
  * Called from the onChange() event of a select element.
  * Checks each row or element to see if its attribute contains at least one match with the selected value of the dropdown
  * Filters only one dropdown
  */
  function filter(filterDiv, attribute) { 
    resetFiltersApplied();
 
    var filterValue = document.getElementById(filterDiv).value;
 
    if (!filterValue) /* selected option is undefined, so do nothing (rather than hiding everything) */ return;


// Check each row to see if it is in the filter
     // Go through all of the items to filter through
// Filters only one dropdown
function filter(filterDiv, attribute) { 
  resetFiltersApplied();
 
  var filterValue = document.getElementById(filterDiv).value;
 
     // Go through all the hero grid icons
     for (var i = 0; i < elementsToFilter.length; i++) {
     for (var i = 0; i < elementsToFilter.length; i++) {
       var data = elementsToFilter[i].getAttribute(attribute);
       var data = elementsToFilter[i].getAttribute(attribute);
Line 71: Line 186:
       var showRow = false;
       var showRow = false;
       for (var w in words) {
       for (var w in words) {
      showRow = showRow || (words[w] == filterValue);
        showRow = showRow || (words[w] == filterValue);
         // console.log(filterValue + " " + words[w] + " " + showRow);
         // console.log(filterValue + " " + words[w] + " " + showRow);
       }
       }
Line 78: Line 193:
       applyFilterAction(elementsToFilter[i], showRow);
       applyFilterAction(elementsToFilter[i], showRow);
     }
     }
}
  }


// This method handlecs the CSS changes if an icon/row matches the filter
  // This method handlecs the CSS changes if a div matches the filter
function applyFilterAction(element, applyFilter) {
  function applyFilterAction(element, applyFilter) {
     if (element.nodeName == "DIV") {
     if (element.nodeName == "DIV") {
         if (!applyFilter) {
         if (!applyFilter) {
            element.style.display = "none";
          element.style.display = "none";
         } else {
         } else {
           element.style.display = "inline-block";
           element.style.display = "inline-block";
         }
         }
     }
     }
}
  }


// Reset any filters applied to elements.
  // Reset any filters applied to elements.
function resetFiltersApplied() {
  function resetFiltersApplied() {
     for (var i = 0; i < elementsToFilter.length; i++) {
     for (var i = 0; i < elementsToFilter.length; i++) {
        if (elementsToFilter[i].nodeName == "DIV") {
      if (elementsToFilter[i].nodeName == "DIV") {
            elementsToFilter[i].style.opacity = "inline-block";
        elementsToFilter[i].style.display = "inline-block";
        }
      }
     }
     }
  }
 
/* Manually rewrite mw-collapsible functionality */
/*
* find mw-collapsible and if mw-collapsible-collapsed then collapse the table
*/
function createCollapsibleTables() {
 
  var $tables = [];
  var $tables = $('.mw-collapsible');
 
  if ($tables.length === 0) return;
 
  $tables.each(function() {
    // Find first row
    var $rows = $(this).find('tr');
    if ($rows.length === 0) return;
   
    var $header = $rows[0].firstChild; //the first th or tr
   
    // insert Expand/Collapse button
    $('<span class="mw-collapsible-toggle mw-collapsible-toggle-default" role="button" tabindex="0"><a class="mw-collapsible-text"></a></span>').prependTo($header);
   
    // if the table is collapsed, then we want it to start out collapsed
    var showTable = $(this).hasClass('mw-collapsed');
    toggleCollapsibleTable($(this), !showTable);
    var $toggleSpan = $header.firstChild;
    $($toggleSpan).click(function() {
      var $parent = $(this).parents('.mw-collapsible');
      var showTable = $parent.hasClass('mw-collapsed');
      toggleCollapsibleTable($parent, showTable);
    });
   
  });
}
function toggleCollapsibleTable($table, showTable) {
  // hide or show contents based on presence of mw-collapsed
  var $toggle = $table.find('.mw-collapsible-toggle');
  var $text = $table.find('.mw-collapsible-text');
  var innerText = '';
 
  if (!showTable) { // hide contents
    $table.find('tr').not(':first-of-type').fadeTo("slow",0, function() {
      $(this).css('display','none');
    });
    innerText = 'Expand';
    $toggle.addClass('mw-collapsible-toggle-collapsed');
    $toggle.removeClass('mw-collapsible-toggle-expanded');
    $table.addClass('mw-collapsed');
  } else { // show contents
    $table.find('tr').not(':first-of-type').css('display','');
    $table.find('tr').not(':first-of-type').css('opacity','');
    innerText = 'Collapse';
    $toggle.addClass('mw-collapsible-toggle-expanded');
    $toggle.removeClass('mw-collapsible-toggle-collapsed');
    $table.removeClass('mw-collapsed');
  }
  $text[0].innerHTML = innerText;
}
}

Latest revision as of 17:03, 27 June 2023

/* Any JavaScript here will be loaded for users using the mobile site */

/* Adds links to the sidebar menu
 * A workaround for MobileFrontend not supporting customization yet
 * Ref: https://www.mediawiki.org/wiki/Topic:Vqy1kx6q4e0bzvyb
*/
var timer = setInterval(function() {
  if ($('.menu ul:first').length) {
    console.log("mobile menu exists");
    clearInterval(timer);
    $('.menu ul:first').after(
        '<ul> \
            <li><a href="#"> \
                <span>Navigation</span> \
              </a> \
            </li> \
            <li><a href="/wiki/BlazBlue_(Franchise)" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>About BlazBlue</span></a> \
            </li> \
            <li><a href="/wiki/Characters" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Characters</span></a> \
            </li> \
            <li><a href="/wiki/Locations" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Locations</span></a> \
            </li> \
            <li><a href="/wiki/Lore" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Lore</span></a> \
            </li> \
            <li><a href="/wiki/Category:Items" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Items</span></a> \
            </li> \
            <li><a href="/wiki/Category:Events" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Events</span></a> \
            </li> \
            <li><a href="/wiki/Category:Species" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Species</span></a> \
            </li> \
            <li><a href="/wiki/Category:Organizations" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Organizations</span></a> \
            </li> \
            <li><a href="/wiki/Merchandise" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Merchandise</span></a> \
            </li> \
        </ul> \
        <ul> \
        	<li><a href="#"> \
                <span>BBDW</span> \
              </a> \
            </li> \
            <li><a href="/wiki/BlazBlue_Alternative:_Dark_War" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>About BBDW</span></a> \
            </li> \
            <li><a href="/wiki/Characters_(BBDW)" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Characters</span></a> \
            </li> \
            <li><a href="/wiki/Grimoires_(BBDW)" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Grimoires</span></a> \
            </li> \
            <li><a href="/wiki/Items_(BBDW)" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Items</span></a> \
            </li> \
            <li><a href="/wiki/BlazBlue_Alternative:_Dark_War/Guides/System" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>System</span></a> \
            </li> \
            <li><a href="/wiki/BlazBlue_Alternative:_Dark_War/Guides" \
                class="mw-ui-icon mw-ui-icon-before"> \
                <span>Guides</span></a> \
            </li> \
        </ul> \
        <ul class="level1"> \
            <li><a href="#"> \
                <span>Community</span></a> \
            </li> \
            <ul class ="level2"> \
                <li><a href="/wiki/Help:Manual_of_Style" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>Manual of Style</span></a> \
                </li> \
                <li><a href="/wiki/Help:ToDo" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>To Do List</span></a> \
                </li> \
                <li><a href="https://discord.gg/7TnmT7X" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>Discord</span></a> \
                </li> \
                <li><a href="https://www.facebook.com/TheBlazBlueWiki" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>Facebook</span></a> \
                </li> \
                <li><a href="https://twitter.com/BlazBlue_Wiki" \
                    class="mw-ui-icon mw-ui-icon-before"> \
                    <span>Twitter</span></a> \
                </li> \
            </ul> \
        </ul>'
    );
    $(".menu").find(".level2").hide(); // hide level2 until level1 is clicked
    $(".level1").click(function(event){ 
         $(this).find(".level2").slideToggle(500);
    }); // if level1 is clicked, dropdown level2
  }
}, 100); // check every 100ms

/*
* see also MediaWiki:Gadget-DropdownFilter.js
*/
  var elementsToFilter = {}; /* for createDropdownSelects() */

  $(document).ready(function() {
    createDropdownSelects();
    createCollapsibleTables();
  });
  
/* For filtering items with Template:DropdownFilter */
  function createDropdownSelects() {
    var selectionParameters = document.getElementById("selectionOptions");
    var selectRowElement = document.getElementById("selectRow");
    if (!selectRowElement || !selectionParameters) {
        return;
    }
    selectRowElement.setAttribute("style", "padding: 6px;");

    var dropdownSelectionOptions = selectionParameters.innerHTML;
    createDropdownSelect(dropdownSelectionOptions);
  }

  function createDropdownSelect(optionList) {
    var i = 0;
    var dropdown = JSON.parse(optionList);

    /* read options from the JSON */
    var dropdownDiv = document.getElementById(dropdown.divID);
    elementsToFilter = document.getElementsByClassName(dropdown.applyToElementsWithThisClass);

    /* create the options to populate the dropdown with */
    var html = "<select id=\"" + dropdown.name + "\" name=\"" + dropdown.name + "\" class=\"form-control\" onchange=\"filter('" + dropdown.name + "','" + dropdown.attribute + "'" + ")\">";

    for (i; i < dropdown.options.length; i++) {
        html += "<option ";
        if (i === 0) {
            html += "selected=\"selected\"";
        }
        if (dropdown.options[i][1] !== "") {
          html +=  "disabled=\"" + dropdown.options[i][1] + "\"";
        }
        html += "value=\"" + dropdown.options[i][0] + "\">" 
             + dropdown.options[i][0] + "</option>";
    }

    /* populate the dropdown */
    dropdownDiv.innerHTML += html;
  }

  /* 
   * Called from the onChange() event of a select element.
   * Checks each row or element to see if its attribute contains at least one match with the selected value of the dropdown
   * Filters only one dropdown
   */
  function filter(filterDiv, attribute) {  
    resetFiltersApplied();

    var filterValue = document.getElementById(filterDiv).value;

    if (!filterValue) /* selected option is undefined, so do nothing (rather than hiding everything) */ return;

    // Go through all of the items to filter through
    for (var i = 0; i < elementsToFilter.length; i++) {
      var data = elementsToFilter[i].getAttribute(attribute);
      var words = data.split(' ');
      
      var showRow = false;
      for (var w in words) {
        showRow = showRow || (words[w] == filterValue);
        // console.log(filterValue + " " + words[w] + " " + showRow);
      }
        
      // Apply the filter
      applyFilterAction(elementsToFilter[i], showRow);
    }
  }

  // This method handlecs the CSS changes if a div matches the filter
  function applyFilterAction(element, applyFilter) {
    if (element.nodeName == "DIV") {
        if (!applyFilter) {
          element.style.display = "none";
        } else {
          element.style.display = "inline-block";
        }
    }
  }

  // Reset any filters applied to elements.
  function resetFiltersApplied() {
    for (var i = 0; i < elementsToFilter.length; i++) {
      if (elementsToFilter[i].nodeName == "DIV") {
        elementsToFilter[i].style.display = "inline-block";
      }
    }
  }
  
/* Manually rewrite mw-collapsible functionality */

/* 
 * find mw-collapsible and if mw-collapsible-collapsed then collapse the table 
 */
function createCollapsibleTables() {
  
  var $tables = [];
  var $tables = $('.mw-collapsible');
  
  if ($tables.length === 0) return;
  
  $tables.each(function() {
    // Find first row
    var $rows = $(this).find('tr');
    if ($rows.length === 0) return;
    
    var $header = $rows[0].firstChild; //the first th or tr
    
    // insert Expand/Collapse button
    $('<span class="mw-collapsible-toggle mw-collapsible-toggle-default" role="button" tabindex="0"><a class="mw-collapsible-text"></a></span>').prependTo($header);
    
    // if the table is collapsed, then we want it to start out collapsed
    var showTable = $(this).hasClass('mw-collapsed');
    toggleCollapsibleTable($(this), !showTable); 

    var $toggleSpan = $header.firstChild;
    $($toggleSpan).click(function() {
      var $parent = $(this).parents('.mw-collapsible');
      var showTable = $parent.hasClass('mw-collapsed');
      toggleCollapsibleTable($parent, showTable);
    });
    
  });
}

function toggleCollapsibleTable($table, showTable) {
  // hide or show contents based on presence of mw-collapsed
  var $toggle = $table.find('.mw-collapsible-toggle');
  var $text = $table.find('.mw-collapsible-text');
  var innerText = '';
  
  if (!showTable) { // hide contents
    $table.find('tr').not(':first-of-type').fadeTo("slow",0, function() {
      $(this).css('display','none');
    });
    innerText = 'Expand';
    $toggle.addClass('mw-collapsible-toggle-collapsed');
    $toggle.removeClass('mw-collapsible-toggle-expanded');
    $table.addClass('mw-collapsed');
  } else { // show contents
    $table.find('tr').not(':first-of-type').css('display','');
    $table.find('tr').not(':first-of-type').css('opacity','');
    innerText = 'Collapse';
    $toggle.addClass('mw-collapsible-toggle-expanded');
    $toggle.removeClass('mw-collapsible-toggle-collapsed');
    $table.removeClass('mw-collapsed');
  }
  $text[0].innerHTML = innerText;
}