Halo Esports Wiki
Advertisement

Documentation for this module may be created at Module:TabsDynamic/doc

local util_args = require('Module:ArgsUtil')
local util_table = require('Module:TableUtil')
local util_vars = require('Module:VarsUtil')
local HTML = {
	name = {
		outer_class = 'tabs',
		outer = 'ul',
		inner = 'li'
	},
	content = {
		outer_class = 'tabs-content',
		outer = 'div',
		inner = 'div'
	}
}

local h = {}

local p = {}

function p.main(frame)
	local args = util_args.merge()
	if not next(args) then return end
	return p._main(args)
end

function p.right(frame)
	local args = util_args.merge()
	if not next(args) then return end
	h.convertRightArgs(args)
	return p._main(args)
end

function p._main(args)
	if args[1] == 'tab' then
		return h.tab(args)
	elseif args[1] == 'end' then
		return h.endTable()
	end
	if not args.content1 then
		return h.start(args)
	end
	local data = h.getDataFromArgs(args)
	--if not next(data[1]) then return end
	return p.constructor(data, this)
end

function p.constructor(data, this, right)
	this = tonumber(this or 1)
	if not next(data) then return end
	local output = h.initOutput()
	if util_args.castAsBool(right) then
		util_table.reverseInPlace(data)
	end
	h.printNames(output, data, this, 'name')
	h.printContent(output, data, this, 'content')
	return output
end

function h.convertRightArgs(args)
	local names = util_args.numberedArgsToTable(args, 'name') or {}
	local contents = util_args.numberedArgsToTable(args, 'content') or {}
	h.readdArgListButBackwards(args, names, 'name')
	h.readdArgListButBackwards(args, contents, 'content')
end

function h.readdArgListButBackwards(args, tbl, key)
	util_table.reverseInPlace(tbl)
	for k, v in ipairs(tbl) do
		if v ~= '' then
			args[key .. k] = v
		end
	end
end

function h.convertThis(args, names)
	if args.This then
		args.This = #names + 1 - tonumber(args.This)
	else
		args.This = 1
	end
end

function h.getDataFromArgs(args)
	local ret = {
		name = util_args.numberedArgsToTable(args, 'name') or {},
		content = util_args.numberedArgsToTable(args, 'content') or {},
	}
	return util_table.interlace(ret)
end

function h.start(args)
	-- if the user inputs {{TD|...}} without any |content= args
	this = tonumber(args.This or 1)
	util_vars.setVar('tdthis', this)
	util_vars.resetGlobalIndex('currentTab')
	local output = mw.html.create()
	local data = h.getDataFromArgs(args)
	local ul = h.printInitSection(output, 'name')
	h.printNamesInner(ul, data, this)
	return '<div class="tabs-dynamic">', output, h.contentIntro()
end

function h.tab(frame)
	-- if the user inputs {{TD|tab}}
	return tostring(h.tabClose()) .. tostring(h.tabOpen())
end

function h.tabClose()
	if util_vars.setGlobalIndex('currentTab') > 1 then
		return '</div>'
	end
	return ''
end

function h.tabOpen()
	local current = util_vars.getGlobalIndex('currentTab')
	local this = util_vars.getVar('tdthis')
	return ('<div class="content%s %s">')
		:format(current, h.thisClass(tonumber(current) == tonumber(this)))
end

function h.thisClass(isthis)
	if isthis then
		return 'active'
	end
	return ''
end

function h.endTable()
	-- if the user inputs {{TD|end}}
	return '</div></div></div>'
end

function h.initOutput()
	local output = mw.html.create('div')
		:addClass('tabs-dynamic')
	return output
end

function h.printContent(output, data, this)
	local ul = h.printInitSection(output, 'content')
	h.printContentInner(ul, data, this)
end

function h.printNames(output, data, this)
	local ul = h.printInitSection(output, 'name')
	h.printNamesInner(ul, data, this)
end

function h.printInitSection(output, contentType)
	return output:tag(HTML[contentType].outer)
		:addClass(HTML[contentType].outer_class)
end

function h.printContentInner(ul, data, this)
	for i, row in ipairs(data) do
		local li = ul:tag('div')
			:wikitext('\n', mw.getCurrentFrame():preprocess(row.content or ''), '\n')
			:addClass('content' .. i)
		if i == this then
			li:addClass('active')
		end
	end
end

function h.printNamesInner(ul, data, this)
	for i, row in ipairs(data) do
		local li = ul:tag('li')
			:wikitext(mw.getCurrentFrame():preprocess(row.name or ''))
			:addClass('content' .. i)
		if i == this then
			li:addClass('active')
		end
	end
end

function h.contentIntro()
	return '<div class="tabs-content">'
end

return p
Advertisement