Quick filter for M&B wiki operations

Add a small input box to look-up, find and filter specific Mount&Blade 1.011 and Warband module system operations.

Od 21.07.2025.. Pogledajte najnovija verzija.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        Quick filter for M&B wiki operations
// @description Add a small input box to look-up, find and filter specific Mount&Blade 1.011 and Warband module system operations.
// @namespace   https://greasyfork.org/users/4813
// @match       https://mbcommands.fandom.com/wiki/Operations*
// @match       https://antifandom.com/mbcommands/wiki/Operations*
// @icon        https://static.wikia.nocookie.net/mount26blade20mooders20reference/images/4/4a/Site-favicon.ico/revision/latest
// @version     2025.07.21
// @author      Swyter
// @license     GNU GPLv3
// @grant       none
// ==/UserScript==

/* swy: append our new filter input box HTML element into the page */
search=document.createElement("input")
search.setAttribute("id", "opfilter")
search.setAttribute("type", "text")
search.setAttribute("placeholder", "Filter operations...")
document.body.appendChild(search)

/* swy: append a new inline CSS stylesheet for our stuff into the page */
style=document.createElement("style")
style.textContent = `
.operation[hidden],
.operation[hidden] + dl,
body[opfilter] .mw-parser-output p:not(.operation),
body[opfilter] .mw-parser-output pre,
body[opfilter] .mw-parser-output ol,
body[opfilter] .mw-parser-output ul,
body[opfilter] .mw-parser-output *:not(.operation) + dl,
body[opfilter] .mw-parser-output div
{
  display: none; /* swy: hide all the flowing text, explanations and tables while in filter mode */
}

input#opfilter
{
  position: fixed;
  width: calc(100% - (20% + 20%)); /* swy: center it leaving 20% of page width at either side */
  left: calc(20%);
  bottom: 20px;
  box-shadow: 0 0 56px #000;
  opacity: .8;
}

input#opfilter:not(:focus)
{
  opacity: .35; /* swy: fade it out when the input box is not focused */
}

* { scroll-margin-top: 100px; } /* swy: fix scrolling to an element but getting hidden by the top bar: https://stackoverflow.com/a/59253905/674685 */
`
document.body.appendChild(style)

/* swy: on every new typed input do this */
search.oninput=function(e)
{
  /* swy: hide all the non-operation stuff (text, explanations, ...) when using the search box; make it clean */
  document.body.setAttribute("opfilter", "true")

  /* swy: get a list of every operation, get the search text the user typed, split into words */
  operations  = document.querySelectorAll(".operation");
  search_text = e.target.value

  search_elems = search_text.toLowerCase().split(/\s+/)

  /* swy: go across every operation in the page and show it, if it contains
          *every* word in the filter, or just hide it otherwise */
  for (var op of operations)
  {
    matches_all = true

    for (var el of search_elems)
      if (!op.id.includes(el))
        matches_all = false

    if (matches_all)
      op.removeAttribute("hidden")
    else
      op.setAttribute("hidden", "true")
  }

  /* swy: scroll into the first (visible) operation that matches our search, if any */
  if (first_visible_op = document.querySelector('.operation:not([hidden])'))
      first_visible_op.scrollIntoView();

// wiki_content = document.querySelector(".mw-parser-output")
// cur_wiki_content_elem = wiki_content.lastElementChild
// any_visible_since_last_header = []
// any_visible_since_last_header[1] = false
// any_visible_since_last_header[2] = false
// any_visible_since_last_header[3] = false
// any_visible_since_last_header[4] = false
// any_visible_since_last_header[5] = false
// do
// {
//   cur_is_hidden = !!!cur_wiki_content_elem.offsetParent /* swy: https://stackoverflow.com/a/21696585/674685 */

//   if (cur_wiki_content_elem.nodeName == "H5" ||
//       cur_wiki_content_elem.nodeName == "H4" ||
//       cur_wiki_content_elem.nodeName == "H3" ||
//       cur_wiki_content_elem.nodeName == "H2" ||
//       cur_wiki_content_elem.nodeName == "H1")
//   {
//     h_number = +temp0.tagName[1] /* swy: 'h3' -> 3 */

//     cur_wiki_content_elem.setAttribute("hidden", "true") : op.removeAttribute("hidden")

//     for (var i=h_number; i <= any_visible_since_last_header.length; i++)
//       any_visible_since_last_header[i] = false
//   }
//   else
//   {
//     any_visible_since_last_header[1] = !cur_is_hidden
//   }
//   //any_visible_since_last_header

//   console.log(cur_wiki_content_elem, cur_is_hidden)
// } while (cur_wiki_content_elem = cur_wiki_content_elem.previousElementSibling)

}