Protected page

Module:Simple navbox

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

local p = {}
local getArgs = require('Module:Arguments').getArgs

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

local function hasBackground(s)
	return type(s) == 'string' and (
		s:find('background', 1, true) or
		s:find('background%-color', 1, true)
	)
end

local function hasColor(s)
	if type(s) ~= 'string' then return false end
	s = s:lower()
	return s:match('^%s*color%s*:') or s:match('[;%s]color%s*:')
end

-- Main entry point
function p.main(frame)
	local args = getArgs(frame)  -- Uses Module:Arguments, trims, handles aliases
	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 args.templatestyles then
		table.insert(out, frame:extensionTag{ name = 'templatestyles', args = { src = args.templatestyles } })
	end

	-- Collapse logic
	local collapse = lc(args.collapse or args.collapsible or '')
	local state = lc(args.state or '')

	local collapsible = state ~= 'plain' and collapse ~= 'no'
	local allowOuterImages = not collapsible
	local userSetOuterImage = args['image-outer'] or args.imageouter or args.imageouterleft or args['image-outer-right'] or args.imageouterright or args.imageouter2
	if userSetOuterImage and collapsible then
		mw.addWarning("<code>imageouter</code> type images will not be shown unless <code>|state = plain</code> or <code>|collapse = no</code>.")
	end
	
	-- Outer image args
	local imageOuterLeft = allowOuterImages and (args['image-outer'] or args.imageouter or args.imageouterleft)
	local imageOuterRight = allowOuterImages and (args['image-outer-right'] or args.imageouterright or args.imageouter2)
	local hasOuterImages = imageOuterLeft or imageOuterRight

	-- Inner images
	local imageLeftArg = args.image2 or args.imageleft
	local hasInnerImages = args.image or imageLeftArg
	if hasOuterImages and hasInnerImages then
		mw.addWarning("When <code>|state = plain</code> or <code>|collapse = no</code>, <code>image</code> ''or'' <code>imageouter</code> type images can be used, but ''not'' both.")
	end

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

	if collapsible then
		table.insert(classes, 'NavFrame')
		if state == 'collapsed' or state == 'closed' then
			table.insert(classes, 'NavClosed')
		elseif state == 'expanded' or state == 'uncollapsed' or state == 'open' then
			table.insert(classes, 'NavOpen')
		end
	elseif hasOuterImages then
		table.insert(classes, 'simple-outer')
	end

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

	-- Outer left image
	if imageOuterLeft then
		table.insert(out, string.format('<div class="simple-outer-image">%s</div>', imageOuterLeft))
	end

	-- Header
	local headerstyle = args.headerstyle or args.titlestyle or ''
	local headerClass = 'simple-header NavHead'
	if headerstyle ~= '' and hasColor(headerstyle) then
		headerClass = headerClass .. ' simple-header-modified'
	end

	local header = {}
	if 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 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 = lc(args['image-align'] or args.imagealign or '')
	local flex = 'display:flex; flex-flow:row;'
	if 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 inner image
	local imageLeft = args.image2 or args.imageleft
	local imageValign = args['image-valign'] or args.imagevalign or 'center'
	if not hasOuterImages and 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 args.group1 then
		local oddGStyle = (args.groupstyle or '') .. (args.oddgroupstyle and ';' .. args.oddgroupstyle or '')
		local evenGStyle = (args.groupstyle or '') .. (args.evengroupstyle and ';' .. args.evengroupstyle or '')
		local oddLStyle = (args.liststyle or '') .. (args.oddliststyle and ';' .. args.oddliststyle or '')
		local evenLStyle = (args.liststyle or '') .. (args.evenliststyle and ';' .. args.evenliststyle or '')

		local tableClass = 'simple-group-container' ..
			((hasBackground(args.groupstyle) or hasBackground(args.oddgroupstyle) or hasBackground(args.evengroupstyle)) and ' simple-group-modified' or '') ..
			((hasBackground(args.liststyle) or hasBackground(args.oddliststyle) or hasBackground(args.evenliststyle)) and ' simple-list-modified' or '')
		if hasColor(oddGStyle) or hasColor(evenGStyle) then
			tableClass = tableClass .. ' simple-group-inherit'
		end

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

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

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

		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) .. ';' .. (args['group' .. i .. 'style'] or '')
			local lstyle = (odd and oddLStyle or evenLStyle) .. ';' .. (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
		local list = args.list or args.list1 or 'Error: <code>list</code> is empty!'
		if 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 inner image
	if not hasOuterImages and 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 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>') -- close simple-navcontent

	-- Outer right image
	if imageOuterRight then
		table.insert(out, string.format('<div class="simple-outer-imageright">%s</div>', imageOuterRight))
	end

	table.insert(out, '</div>') -- close outer simple-navbox

	return table.concat(out)
end

return p