MediaWiki:ComparisonPage-TranslatedJapaneseGames.js

//// MediaWiki:ComparisonPage-TranslatedJapaneseGames.js //// A script file that contains all the HTML and Javascript to add to the page Comparison_of_translated_Japanese_femdom_games in order to implement useful table organization functions. //// Called by MediaWiki:Common.js only if the current page is Comparison_of_translated_Japanese_femdom_games.

var e, s; // Variables to store e (div element of each Template) and s (scripts stored within div elements). Also, confirm that e is null (that the Template is placed on the page) before modifying it.

// Fill out the div of Template:List1ColumnCheckboxes to contain the HTML for the column checkboxes & select/unselect all button e = document.getElementById('fdw-list1-column-checkboxes'); if (e != null) { e.innerHTML = '' + 'Column Display: ' + 'Select All / Unselect All  ' + 'Cover   |   ' + 'Translated Title   |   ' + 'Romanized Title   |   ' + 'Kanji Title   |   ' + 'Developer   |   ' + 'Original Release Date   |   ' + 'Translator   |   ' + 'Translation Date   |   ' + 'Genres   |   ' + 'Engine   |   ' + 'Estimated Play Length   |   ' + 'Developer Type   |   ' + 'Art Style   |   ' + 'Resolution   |   ' + 'Themes   |   ' + 'Fetishes <input type="checkbox" id="fdw-list1-columnFetishes-checkbox" checked="true">  |   ' + 'Notes <input type="checkbox" id="fdw-list1-columnNotes-checkbox">  |   ' + 'Screenshots <input type="checkbox" id="fdw-list1-columnScreenshots-checkbox" checked="true">  |   ' + 'External Links <input type="checkbox" id="fdw-list1-columnLinks-checkbox" checked="true">'; } // Fill out the div of Template:List1ColumnCheckboxesLogic to contain the JavaScript logic related to the column checkboxes e = document.getElementById('fdw-list1-column-checkboxes-logic'); if (e != null) { s = document.createElement("script"); // TODO Fix the fact that if Template:List1ColumnCheckboxesLogic loads before Template:List1ColumnCheckboxes, the initial row un-displaying fails to happen due to getElementById returning a null value. // TODO Dynamically clicking the button close to page load is an awkward solution. Make column undisplay happen elsewhere. s.text = '' + 'var columnCheckboxArray = [];' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnCover-checkbox"), 1]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnTranslated-checkbox"), 2]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnRomanized-checkbox"), 3]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnKanji-checkbox"), 4]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnDeveloper-checkbox"), 5]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnDate-checkbox"), 6]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnTL-checkbox"), 7]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnTLDate-checkbox"), 8]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnGenres-checkbox"), 9]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnEngine-checkbox"), 10]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnPlayLength-checkbox"), 11]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnDevType-checkbox"), 12]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnArtStyle-checkbox"), 13]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnResolution-checkbox"), 14]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnSetting-checkbox"), 15]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnFetishes-checkbox"), 16]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnNotes-checkbox"), 17]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnScreenshots-checkbox"), 18]);' + '\n' + 'columnCheckboxArray.push([document.getElementById("fdw-list1-columnLinks-checkbox"), 19]);' + '\n' + '// Perform an initial un-display of columns based on initial state of checkboxes (this code is pasted from the redisplay button code)' + '\n' + 'var elem;' + '\n' + 'var elems;' + '\n' + 'var offset;' + '\n' + // 'columnCheckboxArray.forEach(function(item) {' + '\n' + //  '  checkbox = item[0];' + '\n' + //  '  offset = item[1];' + '\n' + //  '  // Evaluate every cell from top to bottom that is the nth-child column based on offset, which is within the tr of the body (not the header/first row)' + '\n' + //  '  elems = document.querySelectorAll("tbody>tr>:nth-child(" + offset + ")");' + '\n' + //  '  for (var i = 0; i < elems.length; i++) {' + '\n' + //  '    if (checkbox.checked == true) {' + '\n' + //  '      elems[i].style.display = "";' + '\n' + //  '    } else {' + '\n' + //  '      elems[i].style.display = "none";' + '\n' + //  '  }}' + '\n' + //  '  // Evaluate every cell from top to bottom that is the nth-child column based on offset, which is within the tr of the header' + '\n' + //  '  elem = document.querySelector("thead>tr>:nth-child(" + offset + ")");' + '\n' + //  '  if (checkbox.checked == true) {' + '\n' + // '    elem.style.display = "";' + '\n' + // '  } else {' + '\n' + // '    elem.style.display = "none";' + '\n' + // '  }' + '\n' + // '});' + '\n' +  '// Define the function that is run upon clicking Select All/Unselected All' + '\n' +  'function fdw_list1_checkall {' + '\n' +  '  setting = true; // Default to checking all checkboxes' + '\n' +  '  var checkboxes = document.querySelectorAll("input[type=checkbox][id^=fdw-list1-column]");' + '\n' +  '  var checkedCheckboxes = document.querySelectorAll("input:checked[id^=fdw-list1-column]");' + '\n' +  '  if (checkedCheckboxes.length == checkboxes.length) {' + '\n' +  '    setting = false; // All checked already, so uncheck all' + '\n' +  '  }' + '\n' +  '  checkboxes.forEach(function(checkbox) {' + '\n' + '   checkbox.checked = setting;' + '\n' + ' });' + '\n' +  '}' + '\n' +  ''; e.appendChild(s); }

// Fill out the div of Template:List1CoverDisplay to contain the JavaScript that turns the column 1 covers into pairs of thumbnails and hover-able full size versions e = document.getElementById('fdw-list1-cover-display'); if (e != null) { s = document.createElement("script"); s.text = '' + 'var coverColumnImages = document.querySelectorAll("table tr td:nth-child(1) img");' + '\n' + 'coverColumnImages.forEach(function(coverImage) {' + '\n' + '  console.log(coverImage.getAttribute("src"));' + '\n' +  '  var coverImageFullSize = coverImage.cloneNode(true);' + '\n' +  '  var coverImageFullSizeDiv;' + '\n' +  '  var newURL;' + '\n' +  '  newURL = coverImageFullSize.src.replace("/thumb/", "/");' + '\n' +  '  newURL= newURL.substr(0, newURL.lastIndexOf("/"));' + '\n' +  '  coverImageFullSize.src = newURL;' + '\n' +  '  console.log(newURL);' + '\n' +  '  coverImageFullSize.style.display = "block";' + '\n' +  '  coverImageFullSize.style.position = "absolute";' + '\n' +  '  coverImageFullSize.style.padding = "10px";' + '\n' +  '  coverImageFullSize.style.maxWidth = "100%";' + '\n' +  '  coverImageFullSize.style.maxHeight = "100%";' + '\n' +  '  coverImageFullSize.style.auto = "100%";' + '\n' +  '  coverImageFullSize.style.width = "auto";' + '\n' +  '  coverImageFullSize.style.height = "auto";' + '\n' + ' coverImageFullSizeDiv = document.createElement("div");' + '\n' + ' coverImageFullSizeDiv.appendChild(coverImageFullSize);' + '\n' + ' coverImageFullSizeDiv.style.marginLeft = "100px";' + '\n' + '// coverImageFullSizeDiv.style.marginTop = (-1 * coverImageFullSize.naturalHeight) + "px";' + '\n' + ' console.log(coverImageFullSize.naturalHeight);' + '\n' + ' coverImage.addEventListener("mouseenter", (event) => { ' + '\n' +  '    coverImage.after(coverImageFullSizeDiv);' + '\n' +  '  });' + '\n' + ' coverImage.addEventListener("mouseleave", (event) => { ' + '\n' +  '    coverImageFullSizeDiv.remove;' + '\n' +  '  });' + '\n' + '});' + '\n' + ''; e.appendChild(s); }

// Fill out the div of Template:List1FilterSection to contain the buttons used to create theme and fetish filters e = document.getElementById('fdw-list1-filter-section'); if (e != null) { e.innerHTML = '' + 'Filters: ' + '\n' + '<button id="fdw-list1-filter-theme-button" onClick="fdw_list1_add_theme_filter">Add a Theme Filter ' + '\n' + '<button id="fdw-list1-filter-fetish-button" onClick="fdw_list1_add_fetish_filter">Add a Fetish Filter  ' + '\n' + ''; } // Fill out the div of Template:List1FilterSectionLogic to contain the JavaScript that allows dynamic creation and deletion of theme and fetish filters e = document.getElementById('fdw-list1-filter-section-logic'); if (e != null) { s = document.createElement("script"); s.text = '' + 'function fdw_list1_add_theme_filter {' + '\n' + ' var newFilter = document.createElement("div");' + '\n' + ' newFilter.innerHTML = "Theme: ";' + '\n' + ' var newFilterText = document.createElement("input");' + '\n' + ' var newFilterButton = document.createElement("button");' + '\n' + ' newFilter.appendChild(newFilterText);' + '\n' + ' newFilter.appendChild(newFilterButton);' + '\n' + ' newFilterText.classList.add("theme-filter-text");' + '\n' + ' newFilterButton.innerHTML = "⊗";' + '\n' + ' newFilterButton.onclick = function { newFilter.remove; }' + '\n' + ' var filterArea = document.getElementById("fdw-list1-filter-section");' + '\n' + ' filterArea.appendChild(newFilter); // Hopefully this will not persistently affect fdw-list1-filter-section upon reload' + '\n' + '}' + '\n' + 'function fdw_list1_add_fetish_filter {' + '\n' + // Same as previous function but change theme-filter-text to fetish-filter-text and Theme: to Fetish: ' var newFilter = document.createElement("div");' + '\n' + ' newFilter.innerHTML = "Fetish: ";' + '\n' + ' var newFilterText = document.createElement("input");' + '\n' + ' var newFilterButton = document.createElement("button");' + '\n' + ' newFilter.appendChild(newFilterText);' + '\n' + ' newFilter.appendChild(newFilterButton);' + '\n' + ' newFilterText.classList.add("fetish-filter-text");' + '\n' + ' newFilterButton.innerHTML = "⊗";' + '\n' + ' newFilterButton.onclick = function { newFilter.remove; }' + '\n' + ' var filterArea = document.getElementById("fdw-list1-filter-section");' + '\n' + ' filterArea.appendChild(newFilter);' + '\n' + '}' + '\n' + ''; e.appendChild(s); }

// Fill out the div of Template:List1RedisplayButton to contain the button used to redisplay the table e = document.getElementById('fdw-list1-redisplay-button'); if (e != null) { e.innerHTML = '<button id="fdw-list1-column-button" onClick="fdw_list1_column_toggle">Redisplay Table  '; } // Fill out the div of Template:List1RedisplayButtonLogic to contain the logic used to redisplay the table e = document.getElementById('fdw-list1-redisplay-button-logic'); if (e != null) { s = document.createElement("script"); s.text = 'function fdw_list1_column_toggle {' + '\n' + '// Handle checkboxes' + '\n' + 'var elem;' + '\n' + 'var elems;' + '\n' + 'var offset;' + '\n' + 'columnCheckboxArray.forEach(function(item) {' + '\n' + '  checkbox = item[0];' + '\n' +  '  offset = item[1];' + '\n' +  '  // Evaluate every cell from top to bottom that is the nth-child column based on offset, which is within the tr of the body (not the header/first row)' + '\n' +  '  elems = document.querySelectorAll("tbody>tr>:nth-child(" + offset + ")");' + '\n' +  '  for (var i = 0; i < elems.length; i++) {' + '\n' +  '    if (checkbox.checked == true) {' + '\n' +  '      elems[i].style.display = "";' + '\n' +  '    } else {' + '\n' +  '      elems[i].style.display = "none";' + '\n' +  '  }}' + '\n' +  '  // Evaluate every cell from top to bottom that is the nth-child column based on offset, which is within the tr of the header' + '\n' +  '  elem = document.querySelector("thead>tr>:nth-child(" + offset + ")");' + '\n' +  '  if (checkbox.checked == true) {' + '\n' +  '    elem.style.display = "";' + '\n' + ' } else {' + '\n' + '   elem.style.display = "none";' + '\n' + ' }' + '\n' + '});' + '\n' + '// Handle filters' + '\n' +  'var table = document.querySelector("table");' + '\n' +  '// Get all text box HTML elements, then use map to obtain an array of their .value properties, then remove elements which are pure whitespace' + '\n' +  'var theme_includes = Array.from(document.getElementsByClassName("theme-filter-text")).map(e => e.value).filter(function(v) { return v.trim.length > 0; });' + '\n' +  'var fetish_includes = Array.from(document.getElementsByClassName("fetish-filter-text")).map(e => e.value).filter(function(v) { return v.trim.length > 0; });' + '\n' +  'var filtersExist = (theme_includes.join != "" || fetish_includes.join != "");' + '\n' +  '// Iterate through all table rows. Start at 1 to skip the table header' + '\n' +  'for (var i=1; i < table.rows.length; i++) {' + '\n' +  '  // If there are no filters, set each row to display properly. Otherwise, set each row to not display and only redisplay if it matches all filters.' + '\n' + ' if (!filtersExist) {' + '\n' + '   table.rows[i].style.display = "";' + '\n' + ' } else {' + '\n' + '   table.rows[i].style.display = "none";' + '\n' + '   var displayRow = true; // Change to false if it fails any filter tests. We know at least 1 exists' + '\n' + '   // Process theme filters' + '\n' + '   for (var j = 0; j < theme_includes.length; j++) {' + '\n' + '     // If the include string contains a comma, check if at least comma-split term matches; if not, set displayRow to false' + '\n' + '     // If the include string does NOT contain a comma, just set displayRow to false if it does not match' + '\n' + '     if (theme_includes[j].includes(",")) {' + '\n' + '       var atLeastOneMatches = false;' + '\n' + '       var validTerms = theme_includes[j].split(",").filter(function(v) { return v.trim.length > 0; });' + '\n' + '       validTerms.forEach(function (term) {' + '\n' +  '          if (table.rows[i].cells[14].innerHTML.toLowerCase.includes(term.toLowerCase)) {' + '\n' +  '            atLeastOneMatches = true;' + '\n' +  '          }' + '\n' +  '        });' + '\n' + '       if (atLeastOneMatches == false) {' + '\n' + '         displayRow = false;' + '\n' + '       }' + '\n' + '     } else if (!(table.rows[i].cells[14].innerHTML.toLowerCase.includes(theme_includes[j].trim.toLowerCase))) {' + '\n' + '       displayRow = false;' + '\n' + '     }' + '\n' + '   }' + '\n' + '   // Now for fetish filters (largely redundant)' + '\n' + '   for (var j = 0; j < fetish_includes.length; j++) {' + '\n' + '     // If the include string contains a comma, check if at least comma-split term matches; if not, set displayRow to false' + '\n' + '     // If the include string does NOT contain a comma, just set displayRow to false if it does not match' + '\n' + '     if (fetish_includes[j].includes(",")) {' + '\n' + '       var atLeastOneMatches = false;' + '\n' + '       var validTerms = fetish_includes[j].split(",").filter(function(v) { return v.trim.length > 0; });' + '\n' + '       validTerms.forEach(function (term) {' + '\n' +  '          if (table.rows[i].cells[15].innerHTML.toLowerCase.includes(term.trim.toLowerCase)) {' + '\n' +  '            atLeastOneMatches = true;' + '\n' +  '          }' + '\n' +  '        });' + '\n' + '       if (atLeastOneMatches == false) {' + '\n' + '         displayRow = false;' + '\n' + '       }' + '\n' + '     } else if (!(table.rows[i].cells[15].innerHTML.toLowerCase.includes(fetish_includes[j].trim.toLowerCase))) {' + '\n' + '       displayRow = false;' + '\n' + '     }' + '\n' + '   }' + '\n' + '   // If displayRow was never switched to false, it is safe to display the row' + '\n' + '   if (displayRow == true) {' + '\n' + '     table.rows[i].style.display = "";' + '\n' + '   }' + '\n' + ' }' + '\n' + '}' + '\n' + '}' + '\n'; // Close the onclick function e.appendChild(s); }

// Fill out the div of Template:List1FavoritesButtons to contain the buttons to save and reset favorites e = document.getElementById('fdw-list1-favorites-buttons'); if (e != null) { e.innerHTML = '' + 'Favorites: <button onClick="fdw_list1_favorites_save">Save Favorites & Columns to URL Bar to Share ' + '\n' + '<button onClick="fdw_list1_favorites_reset">Reset Favorites  ' + '\n' + ''; } // Fill out the div of Template:List1FavoritesButtonsLogic to load favorites checkboxes and contain favorites buttons logic. Also column logic e = document.getElementById('fdw-list1-favorites-buttons-logic'); if (e != null) { s = document.createElement("script"); s.text = '' + 'var favoritesCheckboxesArray = [];' + '\n' + 'var table = document.querySelector("table");' + '\n' + 'for (var i=1; i < table.rows.length; i++) { // Start on second row (past header)' + '\n' + ' var newCheckbox = document.createElement("input");' + '\n' + ' newCheckbox.type = "checkbox";' + '\n' + ' newCheckbox.style.msTransform = "scale(2)"; // IE' + '\n' + ' newCheckbox.style.MozTransform = "scale(2)"; // FF' + '\n' + ' newCheckbox.style.WebkitTransform = "scale(2)"; // Safari and Chrome' + '\n' + ' newCheckbox.style.OTransform = "scale(2)"; // Opera' + '\n' + ' newCheckbox.style.transform = "scale(2)";' + '\n' + ' newCheckbox.onclick =  function  {' + '\n' + '   if (this.parentNode.parentNode.style.backgroundColor == "") {' + '\n' + '     this.parentNode.parentNode.style.backgroundColor = "#90ee90";' + '\n' + '     this.parentNode.setAttribute("data-sort-value", "Selected");' + '\n' + '   } else if (this.parentNode.parentNode.style.backgroundColor != "") {' + '\n' + '     this.parentNode.parentNode.style.backgroundColor = "";' + '\n' + '     this.parentNode.setAttribute("data-sort-value", "Unselected");' + '\n' + '   }' + '\n' + ' };' + '\n' + ' favoritesCheckboxesArray.push(newCheckbox);' + '\n' + ' table.rows[i].cells[19].appendChild(newCheckbox);' + '\n' + ' table.rows[i].cells[19].setAttribute("data-sort-value", "Unselected");' + '\n' + '}' + '\n' + '// Load initial favorites based on URL parameter' + '\n' + 'var params = new URLSearchParams(window.location.search);' + '\n' + 'var checkedArray = JSON.parse(params.get("favs"));' + '\n' + 'console.log(checkedArray);' + '\n' + 'if (checkedArray) { ' + '\n' + ' for (i=0; i < checkedArray.length; i++) {' + '\n' + '   table.rows[checkedArray[i]+1].cells[19].childNodes[1].checked = "checked";' + '\n' + '   table.rows[checkedArray[i]+1].style.backgroundColor = "#90ee90";' + '\n' + '   table.rows[checkedArray[i]+1].cells[19].setAttribute("data-sort-value", "Selected");' + '\n' + ' }' + '\n' + '}' + '\n' + '// Load states into columns checkboxes based on URL parameter' + '\n' + '// TODO makes less horribly inefficient and rename arrays' + '\n' + '// check all to start' + '\n' + 'columnCheckboxArray.forEach(function(item) {' + '\n' + '  item[0].checked = "checked";' + '\n' +  '});' + '\n' + 'var checkedArray2 = JSON.parse(params.get("hcols"));' + '\n' + 'if (checkedArray2) { ' + '\n' + ' for (var i=0; i < checkedArray2.length; i++) {' + '\n' + '   columnCheckboxArray.forEach(function(item) {' + '\n' +  '      var checkbox = item[0];' + '\n' +  '      var offset = item[1];' + '\n' +  '      if (checkedArray2[i] == offset) {' + '\n' +  '        checkbox.checked = "";' + '\n' +  '      }' + '\n' +  '    });' + '\n' + ' }' + '\n' + '}' + '\n' + '// Undisplay columns based on column checkbox states. Again, this code is just pasted from elsewhere in this JS file' + '\n' + '// TODO Refactor this code so that instead of referencing the column checkboxes, it directly references hcols, to avoid the DOM for the checkboxes loading after causing it to not work' + '\n' + 'var elem;' + '\n' + 'var elems;' + '\n' + 'var offset;' + '\n' + 'columnCheckboxArray.forEach(function(item) {' + '\n' + '  checkbox = item[0];' + '\n' +  '  offset = item[1];' + '\n' +  '  // Evaluate every cell from top to bottom that is the nth-child column based on offset, which is within the tr of the body (not the header/first row)' + '\n' +  '  elems = document.querySelectorAll("tbody>tr>:nth-child(" + offset + ")");' + '\n' +  '  for (var i = 0; i < elems.length; i++) {' + '\n' +  '    if (checkbox.checked == true) {' + '\n' +  '      elems[i].style.display = "";' + '\n' +  '    } else {' + '\n' +  '      elems[i].style.display = "none";' + '\n' +  '  }}' + '\n' +  '  // Evaluate every cell from top to bottom that is the nth-child column based on offset, which is within the tr of the header' + '\n' +  '  elem = document.querySelector("thead>tr>:nth-child(" + offset + ")");' + '\n' +  '  if (checkbox.checked == true) {' + '\n' +  '    elem.style.display = "";' + '\n' + ' } else {' + '\n' + '   elem.style.display = "none";' + '\n' + ' }' + '\n' + '});' + '\n' + '// Button click functions' + '\n' +  'function fdw_list1_favorites_save {' + '\n' +  '  // Favorites' + '\n' +  '  var checkedRows = [];' + '\n' +  '  for (i=0; i < favoritesCheckboxesArray.length; i++) {' + '\n' +  '    if (favoritesCheckboxesArray[i].checked)  {' + '\n' +  '      checkedRows.push(i);' + '\n' +  '    }' + '\n' +  '  }' + '\n' +  '  console.log(checkedRows);' + '\n' +  '  var params = new URLSearchParams;' + '\n' +  '  params.append("favs", JSON.stringify(checkedRows));' + '\n' +  '  // Columns' + '\n' +  '  var uncheckedColumns = [];' + '\n' +  '  for (i=0; i < columnCheckboxArray.length; i++) {' + '\n' +  '    if (columnCheckboxArray[i][0].checked == "")  {' + '\n' +  '      uncheckedColumns.push(columnCheckboxArray[i][1]);' + '\n' +  '    }' + '\n' +  '  }' + '\n' +  '  params.append("hcols", JSON.stringify(uncheckedColumns));' + '\n' +  '  window.history.pushState("object or string", "Title", "Comparison_of_translated_Japanese_femdom_games?" + params.toString);' + '\n' + '}' + '\n' +  'function fdw_list1_favorites_reset {' + '\n' +  '  favoritesCheckboxesArray.forEach(function(checkbox) {' + '\n' + '   checkbox.checked = "";' + '\n' + '   checkbox.parentNode.parentNode.style.backgroundColor = "";' + '\n' + '   checkbox.parentNode.setAttribute("data-sort-value", "Unselected");' + '\n' + ' });' + '\n' +  '}' + '\n'; // Close the onclick function e.appendChild(s); }