Disney Magic Kingdoms Wiki

The Sword in the Stone Part 3 Update has arrived! ✨
Visit this page to learn all about what's coming up in Disney Magic Kingdoms!

READ MORE

Disney Magic Kingdoms Wiki
No edit summary
No edit summary
Line 351: Line 351:
 
local data = args['list'..num]
 
local data = args['list'..num]
   
local srchpat = args['stripend' .. num] or args.stripend
+
local srchpat = args['stripbegin' .. num] or args.stripbegin
  +
  +
if srchpat and srchpat ~= "" then
  +
srchpat = string.gsub(srchpat, "([%^%$%(%)%.%+%-%?])", "%%%1")
  +
data = string.gsub(data, "%[%[(" .. srchpat .. "%s*)([^%]|]-)%]%]", "[[%1%2|%2]]")
  +
data = string.gsub(data, "%[%[([^%]]-|)(" .. srchpat .. "%s*)([^%]|]-)%]%]", "[[%1%3]]")
  +
end
  +
  +
srchpat = args['stripend' .. num] or args.stripend
   
 
if srchpat and srchpat ~= "" then
 
if srchpat and srchpat ~= "" then

Revision as of 00:38, 9 February 2020

Description

This module is the Lua back-end for {{Navbox}}.

Usage

{{#invoke:Navbox|main|<parameter list>}}

For parameter details see Template:Navbox/doc


--------------------------------------------------------------------
--<pre> Navbox Module
--
-- * Fully CSS styled (inline styles possible but not default)
-- * Supports unlimited rows
-- * Supports collapsible groups (just set parameter withcollapsiblegroups)
--
-- By User:Effan_R from disneymagickingdomswiki.fandom.com
-- Adapted from Navbox Module by User:Tjcool007 from layton.wikia.com
--------------------------------------------------------------------

local p = {}

local args = {} -- Arguments passed to template
local navbox -- Actual navbox

local rownums = {}
local hasrows, alt, altg, isChild = false, false, false, false
local cimage, cimageleft
local colspan, rowspan
local spacer = false

------------------------------------------------
-- Title
------------------------------------------------

--- Processes the VDE links in the title
--
-- @param titlecell The table cell of the title
local function processVde( titlecell )
	if not args.name then return end

	titlecell:wikitext(mw.getCurrentFrame():expandTemplate({
			title = 'Navbar',
			args = { args.name,
					['fontstyle'] = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';border:none;',
					['mini'] = 1
					}
		}))
end

--- Processes the main title row
local function processTitle()
	-- Nothing to do if no title --
	if not args.title then return end

	local titleRow = navbox:tag('tr')

	if args.titlegroup then
		titleRow:tag('td')
				:addClass('navbox-group')
				:wikitext(args.titlegroup)
		if args.titlegroupstyle then titlerow:cssText(args.titlegroupstyle) end
	end

	local titleCell = titleRow:tag('th')

	if args.titlegroup then
		titleCell:css('border-left', '2px solid #fdfdfd')
				:css('width', '100%')
	end

	titleCell:addClass('navbox-title')
			:attr('colspan', colspan)

	if args.basestyle then titleCell:cssText(args.basestyle) end
	if args.titlestyle then titleCell:cssText(args.titlestyle) end

	local titlebar = titleCell:tag('div')
	titlebar:css('width', '6em')

	if not args.name and isChild or args.navbar == 'plain' or args.navbar == 'off' then
		if args.navbar == 'off' then
			if args.state == 'plain' then
				titlebar:css('float', 'right')
						:wikitext('&nbsp;')
			end
		else
			if args.state ~= 'plain' then
				titlebar:css('float', 'left')
						:css('text-align', 'left')
						:wikitext('&nbsp;')
			end
		end
	else
		titlebar:css('float', 'left')
			:css('text-align', 'left')
		processVde(titlebar)
	end

	titleCell
		:tag('span')
			:addClass(args.titleclass)
			:css('font-size', (isChild and '100%' or '110%'))
			:wikitext(args.title)

	spacer = true
end

--- Processes the group title row
local function processGroupTitle(parent, num)
	-- Nothing to do if no group #	--
	if not args['group' .. num] then return end

	local titleRow = parent:tag('tr')

	local titleCell = titleRow:tag('th')

	titleCell:addClass('navbox-title')
			:attr('colspan', colspan)

	if args.basestyle then titleCell:cssText(args.basestyle) end
	if args.groupstyle then titleCell:cssText(args.groupstyle) end
	if args['group' .. num .. 'style'] then
		titleCell:cssText(args['group' .. num .. 'style'])
	end

	local titlebar = titleCell:tag('div')
	titlebar:css('width', '6em')
		:css('float', 'left')
		:css('text-align', 'left')
		:wikitext('&nbsp;')

	titleCell
		:tag('span')
			:css('font-size', '100%')
			:wikitext(args['group' .. num])

	spacer = true
end

------------------------------------------------
-- Gutter
------------------------------------------------

--- Add gutter between rows
--
-- @param parent node, inRowspan to increment image rowspan
local function _addGutter( parent, incRowspan )
	if spacer then
		local gutterCell = parent:tag('tr'):css('height', '2px')
		gutterCell:tag('td')
	end

	if incRowspan then
		rowspan = rowspan + 1
	end
	spacer = false
end

------------------------------------------------
-- Above/Below
------------------------------------------------

--- Processes the above and below rows
--
-- @param rowtype Either 'above' or 'below'
local function processAboveBelow( rowtype )
	if not args[rowtype] then return end

	local abrow = mw.html.create('tr')
	local abcell = mw.html.create('td')

	abcell:addClass('navbox-abovebelow')
		:attr('colspan', colspan)

	if args[rowtype .. 'class'] then abcell:addClass(args[rowtype .. 'class']) end
	if args.basestyle then abcell:cssText(args.basestyle) end
	if args[rowtype .. 'style'] then abcell:cssText(args[rowtype .. 'style']) end

	abcell:tag('div')
		:wikitext(args[rowtype])

	abrow:node(abcell)
	_addGutter( navbox )
	navbox:node( abrow )

	spacer = true
end

------------------------------------------------
-- Main Rows
------------------------------------------------

--- Processes the images
local function _processImage(row, imgtype)
	if not args[imgtype] then return end

	local imagecell = row:tag('td')
						:addClass('navbox-image')

	imagecell:css('width', '0%')
			:css('padding', '0px 0px 0px 2px')

	if args.imageclass then imagecell:addClass(args.imageclass) end
	if args.imagestyle then imagecell:cssText(args.imagestyle) end

	local imagediv = imagecell:tag('div')
							:wikitext(args[imgtype])

	if imgtype == 'image' then
		cimage = imagecell
	else
		cimageleft = imagecell
	end
end

--- Handles Odd Even Groups
--
-- @return Alternatingly returns true (odd) or false (even). Returns fixed value of
--	       true (odd) or false (even) if specified by args.evenodd
local function _evenoddGroup()
	if args.evenodd == 'even' then return false end
	if args.evenodd == 'odd' then return true end

	altg = not altg

	return altg
end

--- Handles Odd Even rows
--
-- @return Alternatingly returns true (odd) or false (even). Returns fixed value of
--	       true (odd) or false (even) if specified by args.evenodd
local function _evenoddRow()
	if args.evenodd == 'even' then return false end
	if args.evenodd == 'odd' then return true end

	alt = not alt

	return alt
end

--- Processes a single list row
--
-- @param num Number of the row to be processed
local function processList(num)
	if not args['list'..num] then return end

	local row = mw.html.create('tr')
	local listrow = row

	if not hasrows then
		_processImage(row, 'imageleft')
	end

	local listpadding = args['list' .. num .. 'padding'] or args.listpadding or '0em 0.25em'

	if args['group'..num] then
		if args.withcollapsiblegroups then
			-- convert Group to collapsible title row --
			_addGutter(navbox)

			local altGroup = _evenoddGroup()

			local headercell = row:tag('td')
								:addClass('navbox-list')
								:attr('colspan', 2)
								:css('padding', '0px')

			if altGroup then
				headercell:addClass('navbox-odd')
				if args.oddstyle then headercell:cssText(args.oddstyle) end
			else
				headercell:addClass('navbox-even')
				if args.evenstyle then headercell:cssText(args.evenstyle) end
			end

			if args.listclass then headercell:addClass(args.listclass) end
			if args.liststyle then headercell:cssText(args.liststyle) end
			if args['list' .. num .. 'style'] then headercell:cssText(args['list' .. num .. 'style']) end
			if not args.groupwidth then headercell:css('width', '100%') end

			headercell:tag('div')
						:css('padding', listpadding)

			local headertable = headercell:tag('table')
			headertable:addClass('navbox-subgroup')
			if args.bodystyle then headertable:cssText(args.bodystyle) end
			if args.style then headertable:cssText(args.style) end

			headertable:addClass('nowraplinks')
				:addClass('mw-collapsible')
				:attr('cellspacing', '0')
				:attr('data-expandtext', 'show')
				:attr('data-collapsetext', 'hide')
				:css('border-spacing', 0)

			if args.bodyclass then headertable:addClass(args.bodyclass) end
			if args.innerstyle then headertable:cssText(args.innerstyle) end

			if args.selected ~= args['abbr' .. num] then
				if args['state' .. num] then
					headertable:addClass(args['state' .. num])
				else
					headertable:addClass('mw-collapsed')
				end
			end

			processGroupTitle(headertable, num)
			_addGutter(headertable)

			alt =  (args.evenodd == 'swap')

			listrow = headertable:tag('tr')
		else
			local groupcell = row:tag('th')
								:addClass('navbox-group')
								:attr('scope','row')
								:wikitext( args['group'..num] )

			if args.groupclass then groupcell:addClass( args.groupclass ) end
			if args.groupstyle then groupcell:cssText( args.groupstyle ) end
			if args.basestyle then groupcell:cssText( args.basestyle ) end
			if args['group' .. num .. 'style'] then groupcell:cssText(args['group' .. num .. 'style'])	end
			if args.groupwidth then groupcell:css('width', args.groupwidth) end
		end
	end

	local altRow = _evenoddRow()

	local listcell = listrow:tag('td')
						:addClass('navbox-list')
						:css('padding', '0px')

	if altRow then
		listcell:addClass('navbox-odd')
		if args.oddstyle then listcell:cssText(args.oddstyle) end
	else
		listcell:addClass('navbox-even')
		if args.evenstyle then listcell:cssText(args.evenstyle) end
	end

	if not args.withcollapsiblegroups and args.listclass then listcell:addClass(args.listclass) end
	if args.liststyle then listcell:cssText(args.liststyle) end
	if args['list' .. num .. 'style'] then listcell:cssText(args['list' .. num .. 'style']) end
	if not args.groupwidth then listcell:css('width', '100%') end

	if not args.withcollapsiblegroups and args['group'..num] then
		listcell:css('text-align', 'left')
			:css('border-left-width', '2px')
			:css('border-left-style', 'solid')
	else
		listcell:attr('colspan',2)
	end


	local hlistcell = listcell:tag('div')
				:css('padding', listpadding)

	local data = args['list'..num]

	local srchpat = args['stripbegin' .. num] or args.stripbegin

	if srchpat and srchpat ~= "" then
		srchpat = string.gsub(srchpat, "([%^%$%(%)%.%+%-%?])", "%%%1")
		data = string.gsub(data, "%[%[(" .. srchpat .. "%s*)([^%]|]-)%]%]", "[[%1%2|%2]]")
		data = string.gsub(data, "%[%[([^%]]-|)(" .. srchpat .. "%s*)([^%]|]-)%]%]", "[[%1%3]]")
	end

	srchpat = args['stripend' .. num] or args.stripend

	if srchpat and srchpat ~= "" then
		srchpat = string.gsub(srchpat, "([%^%$%(%)%.%+%-%?])", "%%%1")
		data = string.gsub(data, "%[%[([^%]]-|[^%]]-)(%s*" .. srchpat .. ")%]%]", "[[%1]]")
		data = string.gsub(data, "%[%[([^%]%|]-)(%s*" .. srchpat .. ")%]%]", "[[%1%2|%1]]")
	end

	if data:match('^[*:;#]') then
		-- Add newlines to support lists properly
		hlistcell
			:newline()
			:wikitext( data )
			:newline()
	else
		hlistcell:wikitext( data )
	end

	local firstRow = false
	if not hasrows then
		firstRow = true
		hasrows = true
		_processImage(row, 'image')
	end

	_addGutter(navbox,not firstRow)
	navbox:node( row )
	rowspan = rowspan + 1
	spacer = true
end

--- Processes all rows
local function processRows()
	for i=1,#rownums do
		processList(rownums[i])
	end

	if cimageleft then
		cimageleft:attr('rowspan',rowspan)
	end
	if cimage then
		cimage:attr('rowspan',rowspan)
	end
end

------------------------------------------------
-- ARGUMENTS PREPROCESSOR
-- * Extracts arguments from frame and stores them in args table
-- * At the same time, checks for valid row numbers
------------------------------------------------

--- Preprocessor for the arguments.
-- Will fill up the args table with the parameters from the frame grouped by their type.
--
-- @param frame The frame passed to the Module.
local function preProcessArgs(frame)
	local tmp = {}

	if frame == mw.getCurrentFrame() then
		tmp = frame:getParent().args
	else
		tmp = frame
	end

	-- Storage tables
	local nums = {}

	-- Loop over all the args
	for k,v in pairs(tmp) do
		-- Skip empty args, which are useless
		if v ~= '' then
			local cat,num = tostring(k):match('^(%a+)([1-9]%d*)$')

			if cat == 'list' then
				nums[num] = true
			end

			args[k] = v -- Simple copy
		end
	end

	colspan = args.image and 3 or 2
	if args.imageleft then colspan = colspan + 1 end
	if args.titlegroup then colspan = colspan - 1 end

	rowspan = 0

	alt =  (args.evenodd == 'swap')
	altg = alt

	for k, v in pairs(nums) do
		rownums[#rownums+1] = tonumber(k)
	end

	table.sort(rownums)
end

------------------------------------------------
-- MAIN FUNCTIONS
------------------------------------------------

--- Processes the arguments to create the navbox.
--
-- @return A string with HTML that is the navbox.
local function _navbox()
	-- Create the root HTML element
	local trim = function(s)
		return s and mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1") or ''
	end
	local border = args.border or trim(args[1])  or ''
	isChild = (border == 'child' or border == 'subgroup' or border == 'none')

	if isChild then
		navbox = mw.html.create('table')
		navbox:addClass('navbox-subgroup')
		if args.bodystyle then navbox:cssText(args.bodystyle) end
		if args.style then navbox:cssText(args.style) end
	else
		navbox = mw.html.create('table')
		navbox:addClass('navbox-inner')
			:css('background', 'transparent')
			:css('color', 'inherit')
	end

	navbox:addClass('nowraplinks')
		:addClass(args.bodyclass)
		:attr('cellspacing', '0')
		:attr('data-expandtext', 'show')
		:attr('data-collapsetext', 'hide')
		:css('border-spacing', 0)
		:cssText(args.innerstyle)

	if args.title then
		if args.state ~= 'plain' and args.stat ~= 'off' then
			navbox:addClass('mw-collapsible')
			if args.state then	navbox:addClass(args.state) end
		end
	end

	-- Process...
	spacer = false

	processTitle()
	processAboveBelow('above')
	processRows()
	processAboveBelow('below')

	-- Wrapper Table --
	if not isChild then
		local wrapper = mw.html.create('table')
		wrapper:addClass('navbox')
				:attr('cellspacing', '0')
				:css('border-spacing', 0)
		if args.bodystyle then wrapper:cssText(args.bodystyle) end
		if args.style then wrapper:cssText(args.style) end
		local wrapperrow = wrapper:tag('tr')
		wrapperrow:tag('td')
				:css('padding', '2px')
				:node(navbox)
		return tostring(wrapper)
	else
		local wrapper = mw.html.create('')
		wrapper:wikitext('</div>')
		wrapper:node(navbox)
		wrapper:wikitext('<div>')
		return tostring(wrapper)
	end
end

--- Main module entry point.
-- To be called with {{#invoke:navbox|main}} or directly from another module.
--
-- @param frame The frame passed to the module via the #invoke. If called from another
--              module directly, this should be a table with the parameter definition.
function p.main(frame)
	-- Save the arguments in a local variable so other functions can use them.
	preProcessArgs(frame)

	return _navbox()
end

return p