Module:ToggleUtil

local util_vars = require('Module:VarsUtil') local i18n = require('Module:I18nUtil')

local h = {}

function h.getShowData(data, isSection) local default_text = isSection and 'Show All' or 'show' local new_data = mw.clone(data) new_data.text = data.show_text or default_text new_data.verb = 'show' new_data.id = data.show_id return new_data end

function h.getHideData(data, isSection) local default_text = isSection and 'Hide All' or 'hide' local new_data = mw.clone(data) new_data.text = data.hide_text or default_text new_data.verb = 'hide' new_data.show_attr = data.hide_attr new_data.hide_attr = data.show_attr new_data.hide_class = data.show_class new_data.initshown = not data.initshown new_data.id = data.hide_id return new_data end

function h.addButton(div, data, addSectionClass) local span = div:tag('span') :addClass('sections-toggler') :attr('data-toggler-hiddenclass', data.hiddenclass) :attr('data-toggler-show', data.show_attr) :attr('data-toggler-hide', data.hide_attr) :attr('id', data.id) :addClass(data.hide_class or data.hide_attr) -- hide yourself, and get shown by other :wikitext(data.text) if data.initshown then span:addClass(data.hiddenclass or 'toggle-section-hidden') end if addSectionClass then span:addClass('toggler-section-' .. data.verb) -- purely for style end end

local p = {}

-- for individual show/hides that need a single show-hide all function p.prepDataByWeek(data, i)	-- to be used by a parent function before sending stuff here -- replaces instances in classes as needed with the current week data.show_attr = data.show_attr:format(i) data.hide_attr = data.hide_attr:format(i) data.show_class = data.show_class:format(i) data.hide_class = data.hide_class:format(i) end

function p.prepDataByWeekAndGame(data, i, j)	data.show_attr = data.show_attr:format(i, j)	data.hide_attr = data.hide_attr:format(i, j)	data.show_class = data.show_class:format(i, i, j)	data.hide_class = data.hide_class:format(i, i, j) end

-- to be called directly from a parent function function p.printToggleHeader(tbl, colspan, display, data) local th = tbl:tag('tr') :tag('th') :attr('colspan',colspan or 1) local div = th:tag('div') :cssText('position:relative;') :tag('div') :addClass('table-header-showhide') p.printToggleButton(div, data) th:wikitext(display) end

-- in theory could be called directly but mostly should be called from above function p.printToggleButton(div, data) if not data then data = h.makeDefaultSectionToggleData('set') end div:wikitext('[') h.addButton(div, h.getShowData(data)) h.addButton(div, h.getHideData(data)) div:wikitext(']') end

-- intended to be called externally, makes a section Show All button function p.printSectionToggler(tbl, data) if not tbl then tbl = mw.html.create end local div = tbl:tag('div'):addClass('expand-contract-button'):addClass(data.cssclass) local showData = h.getShowData(data, true) local hideData= h.getHideData(data, true) h.addButton(div, showData, true) h.addButton(div, hideData, true) return tbl end -- end tab/all toggles

--- -- simple toggle -- uses section javascript --

function p.printSimpleToggleButton(div, isHidden) local data = h.makeDefaultSectionToggleData('set', isHidden) div:wikitext('[') h.addButton(div, h.getShowData(data)) h.addButton(div, h.getHideData(data)) div:wikitext(']') end

function p.tagSimpleToggledContent(div, isHidden) local data = h.makeDefaultSectionToggleData('get', isHidden) div:addClass(data.contentClass) if isHidden then div:addClass('toggle-section-hidden') end end

function h.makeDefaultSectionToggleData(verb, isHidden) local index = util_vars[verb .. 'GlobalIndex']('TOGGLE_SECTION_INDEX') local contentClass = 'default-content-toggle-' .. index local buttonClass = 'default-button-toggle-' .. index local ret = { contentClass = contentClass, show_attr = isHidden and contentClass or buttonClass, hide_attr = isHidden and buttonClass or contentClass, }	return ret end

-- separate from the above -- this assumes a simple single class & single attr function p.initSectionToggler util_vars.setGlobalIndex('SECTION_TOGGLE_SHOW') util_vars.setGlobalIndex('SECTION_TOGGLE_HIDE') end

function p.tagSectionToggler(tbl, isReversed, hiddenclass) local show = 'SECTION_SHOW' .. util_vars.getGlobalIndex('SECTION_TOGGLE_SHOW') local hide = 'SECTION_HIDE' .. util_vars.getGlobalIndex('SECTION_TOGGLE_HIDE') local showNew = isReversed and hide or show local hideNew = isReversed and show or hide tbl:addClass('sections-toggler') :attr('data-toggler-hiddenclass', hiddenclass) :attr('data-toggler-show', showNew) :attr('data-toggler-hide', hideNew) p.tagSectionToggle(tbl, isReversed, hiddenClass) end

function p.tagSectionToggle(tbl, isReversed, hiddenclass) if isReversed then tbl:addClass(hiddenclass or 'toggle-section-hidden') tbl:addClass('SECTION_SHOW' .. util_vars.getGlobalIndex('SECTION_TOGGLE_SHOW')) else tbl:addClass('SECTION_HIDE' .. util_vars.getGlobalIndex('SECTION_TOGGLE_HIDE')) end end -- end simple section toggler

-- option from list stuff -- call printOptionFromListTogglers to make the toggles, and oflCellClasses to make the toggled data -- if the toggled data is physically above the togglers, then call oflInit before doing anything else function p.oflInit(data) -- only run this one time if data._INITIALIZED then return end local n = util_vars.setGlobalIndex('OFLToggler') h.oflInitClasses(data, n)	data.all = data.all or ('ofl-toggler-%s-all'):format(n) data.section = data.section or ('ofl-toggler-%s-section'):format(n) data.init = data.init or data.order[1] -- make sure this doesn't run again data._INITIALIZED = true -- allow this to be called by string if desired h.recordDataByKey(data) end

function p.printOptionFromListTogglers(tbl, data) -- @param tbl: HTML object -- @param data: table of toggle data, requires key order = array of classes to provide ordering -- print the togglers at the start of a section -- then call oflCellClasses on each of the things we want to show data = h.findData(data) -- guarantee pass a table to oflInit, which will do nothing if it's been run for this object before p.oflInit(data) if not tbl then tbl = mw.html.create end if not data.displays then data.displays = {} end local len = #data.order for i, val in ipairs(data.order) do		local span = h.oflPrintOneToggler(tbl, data, val) h.oflTogglersAttrs(span, data.attrs, val) if i < len then tbl:wikitext(data.sep or '|') end end return tbl end

function p.oflCellClasses(tbl, data, this) -- @param tbl: HTML object -- @param data: data object from printOptionFromListTogglers, or string key to look up via findData -- @param this: one of the classes from data.order data = h.findData(data) tbl:addClass(data.classes[this]) :addClass(data.all) if data.showall then tbl:addClass(data.classes[data.showall]) end if h.oflDoWeAddHiddenclass(data, this) then tbl:addClass(data.hiddenclass or 'toggle-section-hidden') end return tbl end

function h.recordDataByKey(data) -- singleton object to record all active toggles by key -- currently only supports same-Lua-session toggles, no variable support if not data.key then return end if not TOGGLE_DATA_LOOKUPS then TOGGLE_DATA_LOOKUPS = {} end TOGGLE_DATA_LOOKUPS[data.key] = data end

function h.findData(data) if type(data) == 'table' then return data end if not TOGGLE_DATA_LOOKUPS[data] then error(("Trying to look up a key (%s) that doesn't exist"):format(data)) end return TOGGLE_DATA_LOOKUPS[data] end

function h.oflInitClasses(data, n)	if data.classes then return end data.classes = {} for k, v in ipairs(data.order) do		data.classes[v] = ('ofl-toggle-%s-%s'):format(n, k)	end end

function h.oflPrintOneToggler(tbl, data, val, text, isActive) if not tbl then tbl = mw.html.create end local span = tbl:tag('span') :addClass('optionfromlist-toggler') :addClass(data.section) :attr('data-toggle-section', data.section) :attr('data-toggler-show', data.classes[val]) :attr('data-toggler-hide', data.all) :wikitext(h.getDisplay(data, val)) if (data.init or data.order[1]) == val then span:addClass('active') end if data.hiddenclass then span:attr('data-toggler-hiddenclass', data.hiddenclass) end return span end

function h.getDisplay(data, val) local output if i18n.exists then output = i18n.print(val .. 'Toggle') end if not output then output = data.displays[val] or val end return output end

function h.oflTogglersAttrs(span, attrs, val) if not attrs then return end for attr, data in pairs(attrs) do		span:attr(attr, data[val]) end end

function h.oflDoWeAddHiddenclass(data, this) if data.showall == data.init then return false end return this ~= data.init end

-- always active stuff

function p.printSepToggler(tbl, data, isHideButton) local suffix = '_opposite' local class = isHideButton and (data.class .. suffix) or data.class local otherClass = isHideButton and data.class or (data.class .. suffix) local showText = data.show_text or 'show' local hideText = data.hide_text or 'hide' local text = isHideButton and hideText or showText local span = tbl:tag('span') :addClass('sections-toggler') :wikitext(i18n.print(text .. 'Toggle') or text) :attr('data-toggler-show', class) :attr('data-toggler-hide', otherClass) end

function p.sepCellClasses(tbl, data, isActive) local class = isActive and (data.class .. '_opposite') or data.class tbl:addClass(class) if not isActive then tbl:addClass(data.hiddenclass or 'toggle-section-hidden') end end

-- popup button -- all popup buttons are pretty, but we have the choice of what actions to additionally bind -- by optionally calling the default popupButton or popupButtonLazy function p.popupButton(tbl, class) -- default popup button local popup = p.popupButtonPretty(tbl, class) popup.button:addClass('popup-button-action') return popup end

function p.popupButtonLazy(tbl, class, parse) -- content inside will be computed lazily -- the js adds –  for you, so only provide the part inside that local button = p.popupButton(tbl, class) button.button:addClass('popup-button-lazy') :attr('data-parse-text', parse) return button end

function p.popupButtonPretty(tbl, class) -- does NOT add a button action, can be called directly or via p.popupButton -- p.popupButton fetches this then adds the button action and returns -- class can be specified to add custom popup-content, popup-button, and popup-wrapper class names if not tbl then tbl = mw.html.create end if not settings then settings = {} end local span = tbl:tag('span') local button = span:tag('div') :addClass('popup-button-pretty') :wikitext('') local wrapper = button:tag('div') :addClass('popup-content-wrapper-pretty') :addClass('popup-content-wrapper-action') :addClass('popup-content-hidden') local inner = wrapper:tag('div') :addClass('popup-content-inner-pretty') :addClass('popup-content-inner-action') if class then inner:addClass('popup-content-' .. class) button:addClass('popup-button-' .. class) wrapper:addClass('popup-wrapper-' .. class) end return { tbl = tbl, span = span, button = button, wrapper = wrapper, inner = inner } end

function p.allToggleAll(tbl, key) if not tbl then tbl = mw.html.create('') end local button = tbl:tag('div') :addClass('all-toggle-all-toggler') :addClass('active') :attr('data-all-toggle-key', key) local button2 = tbl:tag('div') :addClass('all-toggle-all-toggler') :addClass('toggle-section-hidden') :attr('data-all-toggle-key', key) local content = tbl:tag('div') :addClass('toggle-section-hidden') :addClass('all-toggle-all-toggle') :attr('data-all-toggle-key', key) return { tbl = tbl, button = button, button2 = button2, content = content, } end return p