Protected page

Module:Simple navbox

From Uncyclopedia, the content-free encyclopedia
Jump to navigation Jump to search

local p = {}

-- Utilities
local function isNotEmpty(v)
	return v ~= nil and v ~= ''
end

local function lc(v)
	return type(v) == 'string' and mw.ustring.lower(v) or v
end

local function getArg(args, ...)
	for i = 1, select('#', ...) do
		local k = select(i, ...)
		if isNotEmpty(args[k]) then
			return args[k]
		end
	end
	return nil
end

-- Main entry point
function p.main(frame)
	local args = frame:getParent().args
	local out = {}

	-- Stylesheets
	table.insert(out, frame:extensionTag{ name = 'templatestyles', args = { src = 'Simple navbox/styles.css' } })
	table.insert(out, frame:extensionTag{ name = 'templatestyles', args = { src = 'Hlist/styles.css' } })

	if isNotEmpty(args.templatestyles) then
		table.insert(out, frame:extensionTag{ name = 'templatestyles', args = { src = args.templatestyles } })
	end

	-- Collapse logic
	local collapse = getArg(args, 'collapse', 'collapsible')
	local collapsible = not (lc(collapse) == 'no')
	local state = lc(args.state)

	-- Outer image
	local imageOuter = getArg(args, 'image-outer', 'imageouter')

	-- Classes
	local bodyclass = getArg(args, 'bodyclass', 'class') or ''
	local classes = { 'simple-navbox', bodyclass, 'noprint' }

	if collapsible then
		table.insert(classes, 'NavFrame')
		if state == 'collapsed' then
			table.insert(classes, 'NavClosed')
		end
	else
		if isNotEmpty(imageOuter) then
			table.insert(classes, 'simple-outer')
		end
	end

	-- Body style
	local bodystyle = args.bodystyle or ''

	table.insert(out, string.format(
		'<div class="%s" style="%s">',
		table.concat(classes, ' '), bodystyle
	))

	-- Outer image rendering (non-collapsible only)
	if not collapsible and isNotEmpty(imageOuter) then
		table.insert(out, string.format('<div class="simple-outer-image">%s</div>', imageOuter))
	end

	-- Header
	local headerstyle = getArg(args, 'headerstyle', 'titlestyle') or ''
	local headerClass = 'simple-header NavHead'
	if isNotEmpty(headerstyle) then
		headerClass = headerClass .. ' simple-header-modified'
	end

	local header = {}
	if isNotEmpty(args.name) then
		table.insert(header, frame:expandTemplate{ title = 'simple navbar', args = { args.name } })
	end
	table.insert(header, args.title or 'Default title: add a value for <code>title</code> in the template.')

	table.insert(out, string.format(
		'<div class="%s" style="%s">%s</div>',
		headerClass, headerstyle, table.concat(header)
	))

	-- Nav content wrapper
	table.insert(out, string.format(
		'<div class="simple-navcontent NavContent" style="%s">',
		args.navcontentstyle or ''
	))

	-- Above block
	if isNotEmpty(args.above) then
		table.insert(out, string.format(
			'<div class="simple-group-above" style="%s">\n%s\n</div>',
			args.abovestyle or '',
			frame:preprocess(args.above)
		))
	end

	-- Flex container
	local imageAlign = getArg(args, 'image-align', 'imagealign')
	local flex = 'display:flex; flex-flow:row;'
	if lc(imageAlign) == 'left' then
		flex = 'display:flex; flex-flow:row-reverse; justify-content:flex-end;'
	end

	table.insert(out, string.format(
		'<div class="simple-content-container" style="%s %s">',
		flex, args.containerstyle or ''
	))

	-- Left image
	local imageLeft = getArg(args, 'image2', 'imageleft')
	local imageValign = getArg(args, 'image-valign', 'imagevalign') or 'center'
	if not isNotEmpty(imageOuter) and isNotEmpty(imageLeft) then
		table.insert(out, string.format(
			'<div class="simple-image" style="align-self:%s">%s</div>',
			imageValign, imageLeft
		))
	end

	-- Content
	table.insert(out, string.format(
		'<div class="simple-content %s" style="%s">',
		args.listclass or '', args.contentstyle or ''
	))

	-- Grouped mode
	if isNotEmpty(args.group1) then
		local modified = isNotEmpty(args.groupstyle) or isNotEmpty(args.oddgroupstyle) or isNotEmpty(args.evengroupstyle)
		local tableClass = 'simple-group-container'
		if modified then
			tableClass = tableClass .. ' simple-group-modified'
		end

		table.insert(out, string.format(
			'<table class="%s" style="%s">',
			tableClass, args.tablestyle or ''
		))

		-- Precompute odd/even styles to avoid repeated concatenation
		local oddGStyle = (args.groupstyle or '') .. (isNotEmpty(args.oddgroupstyle) and ';' .. args.oddgroupstyle or '')
		local evenGStyle = (args.groupstyle or '') .. (isNotEmpty(args.evengroupstyle) and ';' .. args.evengroupstyle or '')
		local oddLStyle = (args.liststyle or '') .. (isNotEmpty(args.oddliststyle) and ';' .. args.oddliststyle or '')
		local evenLStyle = (args.liststyle or '') .. (isNotEmpty(args.evenliststyle) and ';' .. args.evenliststyle or '')

		-- Collect non-empty lists for batch preprocessing
		local batchLists = {}
		local groupIndices = {}

		for i = 1, 50 do
			local group = args['group' .. i]
			local listContent = args['list' .. i] or ''
			if isNotEmpty(group) then
				table.insert(batchLists, listContent)
				table.insert(groupIndices, i)
			end
		end

		-- Batch preprocess
		local preprocessedLists = {}
		if #batchLists > 0 then
			-- Concatenate with unique separator
			local sep = '@@SIMPLE_SEPARATOR@@'
			local concatenated = table.concat(batchLists, sep)
			local processed = frame:preprocess(concatenated)
			-- Split back
			for part in mw.ustring.gmatch(processed, '(.-)' .. sep) do
				table.insert(preprocessedLists, part)
			end
			-- Handle last item
			if #preprocessedLists < #batchLists then
				table.insert(preprocessedLists, mw.ustring.match(processed, '.*' .. sep .. '(.*)') or batchLists[#batchLists])
			end
		end

		-- Output rows
		for idx, i in ipairs(groupIndices) do
			local group = args['group' .. i]
			local listContent = preprocessedLists[idx] or ''
			local odd = (i % 2 == 1)

			local gstyle = odd and oddGStyle or evenGStyle
			gstyle = gstyle .. ';' .. (args['group' .. i .. 'style'] or '')

			local lstyle = odd and oddLStyle or evenLStyle
			lstyle = lstyle .. ';' .. (args['list' .. i .. 'style'] or '')

			table.insert(out, string.format(
				'<tr class="simple-group-row" style="%s">' ..
				'<td class="simple-group" style="%s">%s</td>' ..
				'<td class="simple-list" style="%s">\n%s\n</td>' ..
				'</tr>',
				args.rowstyle or '',
				gstyle,
				group,
				lstyle,
				listContent
			))
		end

		table.insert(out, '</table>')
	else
		-- List-only mode
		local list = args.list or args.list1 or 'Error: <code>list</code> is empty!'
		if isNotEmpty(list) then
			list = frame:preprocess(list)
		end
		table.insert(out, string.format(
			'<div class="simple-list simple-list-only" style="%s">\n%s\n</div>',
			args.liststyle or '',
			list
		))
	end

	table.insert(out, '</div>') -- simple-content

	-- Right image
	if not isNotEmpty(imageOuter) and isNotEmpty(args.image) then
		table.insert(out, string.format(
			'<div class="simple-image" style="align-self:%s">%s</div>',
			imageValign, args.image
		))
	end

	table.insert(out, '</div>') -- container

	-- Below block
	if isNotEmpty(args.below) then
		table.insert(out, string.format(
			'<div class="simple-group-above simple-group-below" style="%s">\n%s\n</div>',
			args.belowstyle or args.abovestyle or '',
			frame:preprocess(args.below)
		))
	end

	table.insert(out, '</div></div>')

	return table.concat(out)
end

return p