Module:PerkSearchResultsView
From Against the Storm Official Wiki
Documentation for this module may be created at Module:PerkSearchResultsView/doc
--- @module PerkSearchResultsView local PerkSearchResultsView = {} local PerksData = require("Module:PerksData") --region Private member variables beginning = "" middle = "" ending = "" local imgS = mw.getCurrentFrame():expandTemplate{ title = "ImgS" } local imgM = mw.getCurrentFrame():expandTemplate{ title = "ImgM" } local imgL = mw.getCurrentFrame():expandTemplate{ title = "ImgL" } local amberIcon = mw.getCurrentFrame():expandTemplate{ title= "Amber" } --endregion --region Private constants local PARAMETER_DISPLAY_OVERRIDE_LIST = "list" -- wikitable classes for tables local CLASS_WIKITABLE_SORTABLE_COLLAPSIBLE = "wikitable sortable mw-collapsible" local CSS_TD_SHRINK_TO_FIT = "max-width: 20em" local CLASS_UNSORTABLE = "unsortable" local RARITY_COLORS = { [PerksData.RARITY_UNCOMMON] = "#15cf00", [PerksData.RARITY_RARE] = "#015db9", [PerksData.RARITY_EPIC] = "#7f27b9", [PerksData.RARITY_LEGENDARY] = "#da6d00", [PerksData.NONE] = "#444444" } local BORDER_SIZES = { [imgS] = "1.5px", [imgM] = "2px", [imgL] = "4px" } -- Shortcut markup that's easier for Lua string concatenations local NBSP = " " local BLANK = "—" --endregion --region Private methods --- --- Formats a standard link to a perk. Does not invoke the template, but it --- could be modified to do so in the future. --- ---@param perkName string the display name of the perk ---@param perkIcon string the filename for the icon ---@param iconSize string representing the desired size of the icon ---@param borderColor string the color of the border to put on the icon ---@return string an assembled link, with icon and text local function perkLink(perkName, perkIcon, iconSize, borderColor) if not perkName or not perkIcon or not iconSize then error("Perk parameters cannot be nil.") end local displayStyle = "display: inline-block;" --- Set absolute height of border span to stop it being bigger than the image if iconSize == imgS then displayStyle = displayStyle .. "height: 18px;" end local startBorderSpan = "<span style=\" " .. displayStyle .. " border: " .. BORDER_SIZES[iconSize] .. " solid " .. borderColor .. "\">" local endBorderSpan = "</span>" --- Hacky fix for weird image offset if iconSize == imgS then --- Add a second containing span to move the image into position startBorderSpan = startBorderSpan .. "<span style=\"display: block; transform: translateY(-4px)\">" endBorderSpan = "</span></span>" end local iconPart = "[[File:" .. perkIcon .. "|" .. iconSize .. "|alt=" .. perkName .. "|link=" .. perkName .. "]]" local linkPart = NBSP .. "[[" .. perkName .. "]]" return startBorderSpan .. iconPart .. endBorderSpan .. linkPart end --- --- Creates a header row under the provided MediaWiki HTML table entity. --- ---@param tableNode table MediaWiki HTML table entity ---@param needsPriceColumn boolean if the table need to include a price column local function makeStandardPerkTableHeaderRow(tableNode, needsPriceColumn) local row = tableNode:tag("tr") row:tag("th"):wikitext("Perk"):done() row:tag("th"):wikitext("Rarity"):done() row:tag("th"):addClass(CLASS_UNSORTABLE):wikitext("Description"):done() row:tag("th"):addClass(CLASS_UNSORTABLE):wikitext("Source(s)"):done() if needsPriceColumn then row:tag("th"):wikitext("Price"):done() end row:done():newline() end --- --- Returns a standard MediaWiki HTML table entity created with standard --- display and interactivity classes. --- ---@return table standard MediaWiki HTML table entity local function startNewWikiTable() return mw.html.create("table"):addClass(CLASS_WIKITABLE_SORTABLE_COLLAPSIBLE):newline() end --- --- Makes the content of the name column under the provided HTML table row --- entity. --- ---@param htmlTableRow table MediaWiki HTML table row entity ---@param perkName string the name of the building ---@param perkIcon string the filename for the icon ---@param borderColor string the color of the border to put on the icon local function makeNameColumn(htmlTableRow, perkName, perkIcon, borderColor) htmlTableRow:tag("td"):wikitext(perkLink(perkName, perkIcon, imgL, borderColor)):done():newline() end --- --- Makes the content of the name column under the provided HTML table row --- entity. --- ---@param htmlTableRow table MediaWiki HTML table row entity ---@param rarity string the rarity of the perk local function makeRarityColumn(htmlTableRow, rarity) htmlTableRow:tag("td"):wikitext(rarity):done():newline() end --- --- Makes the content of the description column under the provided HTML table --- row node. --- ---@param htmlTableRow table MediaWiki HTML table row entity ---@param description string the long description local function makeDescriptionColumn(htmlTableRow, description) htmlTableRow:tag("td"):cssText(CSS_TD_SHRINK_TO_FIT) :wikitext(description):done():newline() end --- --- Builds an unordered bulleted list based on the specified perk's sources. --- ---@param htmlTableRow table the MediaWiki html node we're building on ---@param isFromCornerstone boolean whether the perk is a Cornerstone ---@param isFromEvent boolean whether the perk is a reward from an Event ---@param isFromOrder boolean whether the perk is a reward from an Order ---@param isFromTrader boolean whether the perk is purchasable from a Trader local function makeSourcesColumn(htmlTableRow, isFromCornerstone, isFromEvent, isFromOrder, isFromTrader) local td = htmlTableRow:tag("td") local list = td:tag("ul") if isFromCornerstone then list:tag("li"):wikitext("as a Cornerstone"):done() end if isFromEvent then list:tag("li"):wikitext("from Glade Event rewards"):done() end if isFromOrder then list:tag("li"):wikitext("from Order rewards"):done() end if isFromTrader then list:tag("li"):wikitext("purchased from a Trader"):done() end list:done() td:done() end --- --- Adds a table cell containing the price and the amber icon --- ---@param htmlTableRow table the Mediawiki HTML node we're building on ---@param price number value in amber local function makePriceColumn(htmlTableRow, price) htmlTableRow:tag("td"):wikitext(price .. NBSP .. amberIcon):done() end --endregion --region Public methods --- --- Initializes the table, populates the caption, and writes and header row, --- all appropriate for a table focusing on one perk. --- --- The default is a wikitable output. With the displayOverride flag, this --- method will instead make a list. --- ---@param perkName string the name of the perk this table is built for ---@param displayOverride string a flag for the output type if not the default ---@param needsPriceColumn boolean whether this perk needs a price column function PerkSearchResultsView.startViewForPerk(perkName, displayOverride, needsPriceColumn) -- These should never be nil at runtime. if not perkName then error("Parameter is invalid for perk name.") end local newNode if displayOverride == PARAMETER_DISPLAY_OVERRIDE_LIST then newNode = mw.html.create("ul") else newNode = startNewWikiTable() newNode:tag("caption"):wikitext("Perk: " .. perkName .. "."):done():newline() makeStandardPerkTableHeaderRow(newNode, needsPriceColumn) end beginning = newNode -- Return value is not used by the Controller, but for debugging. return newNode end --- --- Initializes the table, populates the caption, and writes and header row, --- all appropriate for a table focusing on one perk. --- --- The default is a wikitable output. With the displayOverride flag, this --- method will instead make a list. --- ---@param perkName string the name of the perk this table is built for ---@param displayOverride string a flag for the output type if not the default ---@param numPerks number of perks that will be shown ---@param needsPriceColumn boolean whether this perk needs a price column function PerkSearchResultsView.startViewForName(perkName, displayOverride, numPerks, needsPriceColumn) -- These should never be nil at runtime. if not perkName then error("Parameter is invalid for perk name.") end if not numPerks then error("Parameter is invalid for number of perks.") end local number = tonumber(numPerks) if not number then error("Number of perks could not be converted to a number: " .. numPerks) end local newNode if displayOverride == PARAMETER_DISPLAY_OVERRIDE_LIST then newNode = mw.html.create("ul") else newNode = startNewWikiTable() newNode:tag("caption"):wikitext(number .. " perks named " .. perkName .. "."):done():newline() makeStandardPerkTableHeaderRow(newNode, needsPriceColumn) end beginning = newNode -- Return value is not used by the Controller, but for debugging. return newNode end function PerkSearchResultsView.startViewForSearchResults(searchTerm, source, rarity, displayOverride, numPerks, needsPriceColumn) -- These should never be nil at runtime if not searchTerm then error("Parameter is invalid for search term.") end if not numPerks then error("Parameter is invalid for number of perks.") end local number = tonumber(numPerks) if not number then error("Number of perks could not be converted to a number: " .. numPerks) end local newNode if displayOverride == PARAMETER_DISPLAY_OVERRIDE_LIST then newNode = mw.html.create("ul") else local header = number .. NBSP if rarity then header = header .. rarity .. NBSP end header = header .. "Perks mentioning '" .. searchTerm .. "'" if source then header = header .. " from " .. source end header = header .. "." newNode = startNewWikiTable() newNode:tag("caption"):wikitext(header):done():newline() makeStandardPerkTableHeaderRow(newNode, needsPriceColumn) end beginning = newNode -- Return value is not used by the Controller, but for debugging. return newNode end --- --- Adds a new row to the content being built. This is typically called from a --- Controller that knows how many rows to add. PerkSearchResultsView maintains --- the output in-progress while rows are added, so that layout and formatting --- can be owned by this module instead of the Controller. --- ---@param displayOverride string a flag for the output type if not the default ---@param perkName string the name of the perk ---@param description string the flavor text description ---@param iconFilename string the icon of the perk ---@param rarity string the rarity ---@param price number price of the perk at a trader ---@param isFromCornerstone boolean whether this perk is earned as a Cornerstone ---@param isFromEvent boolean whether this perk is rewarded from an event ---@param isFromOrder boolean whether this perk is earned from an Order ---@param isFromTrader boolean whether this perk is purchasable ---@param hasLastColumn boolean whether to render the last column (regardless of isFromTrader) function PerkSearchResultsView.addRowForPerk(displayOverride, perkName, description, iconFilename, rarity, price, isFromCornerstone, isFromEvent, isFromOrder, isFromTrader, hasLastColumn) local newNode if displayOverride == PARAMETER_DISPLAY_OVERRIDE_LIST then -- List version. newNode = mw.html.create("li"):wikitext(perkLink(perkName, iconFilename, imgS, RARITY_COLORS[rarity])) else -- Table version. newNode = mw.html.create("tr"):newline() makeNameColumn(newNode, perkName, iconFilename, RARITY_COLORS[rarity]) makeRarityColumn(newNode, rarity) makeDescriptionColumn(newNode, description) makeSourcesColumn(newNode, isFromCornerstone, isFromEvent, isFromOrder, isFromTrader) if hasLastColumn then if isFromTrader then makePriceColumn(newNode, price) else newNode:tag("td"):wikitext(BLANK):done() end end end newNode:done() middle = middle .. tostring(newNode) return newNode end --- --- Wraps up anything outstanding for the view, then returns the entire --- MediaWiki entity originally started in the respective method. --- ---@return string the HTML markup of the completed view function PerkSearchResultsView.endView() beginning:node(middle) beginning:done() middle = "" return beginning end --endregion return PerkSearchResultsView