置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:Flexinfo

贴贴♀百科,万娘皆可贴的百科全书!转载请标注来源页面的网页链接,并声明引自贴贴百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [查看] [编辑] [历史] [刷新]

该模块服务于{{横排信息}}。

详情请见:Template:横排信息/doc

local p = {}
local getArgs -- 延迟加载
local args -- 传入参数
local format = string.format -- 简写string.format函数

local stylelib = {
	tabs = {
		top = 'border-bottom:2px solid TITLECOLOR; display:flex; align-items:center; margin-bottom:0.5em;',
		top_iconsys = 'margin-bottom:calc(ICONSIZE/2 - 0.8em); margin-top:calc(ICONSIZE/2 - 1.3em);',
		top_iconitem = 'margin-left:calc(ICONSIZE/2);',
		iconmap = 'display:inline-block; height:10px; width:calc(ICONSIZE + 0.15em); position:relative; top:calc(-ICONSIZE/2 + 0.8em); vertical-align:top; margin-left:calc(-ICONSIZE/2 - 0.3em);',
		icon = 'border-radius:calc(ICONSIZE/2); border:2px solid #fff; box-shadow:0 0 3px TITLECOLOR; overflow:hidden; background:#fff; text-align:center; height:calc(ICONSIZE - 4px); width:calc(ICONSIZE - 4px); box-sizing:content-box;',
		title = 'background:TITLECOLOR; color:#fff; border-top-left-radius:6px; border-top-right-radius:6px; display:inline-block; padding:0 0.3em; font-weight:bold; font-size:1.2em; margin-bottom:-2px; white-space:nowrap;',
		alt = 'color:#666; font-size:80%; padding-top:0.2em; padding-left:1em; white-space:nowrap; overflow-x:auto;',
		defaulttitlemargin = '0.3em',
		defaultcolor = '#9ecdd9',
		defaultsize = '48px',
		defaultmargin = '1em'
	},
}

local function itemValue(parameter, itemnum)
	local key
	if itemnum then
		key = format('item%d-', itemnum) .. parameter
	else
		key = parameter
	end
	return args[key]
end

local function findTheme(theme, itemnum)
    local style = {}
    local styleref = {}
    if(stylelib[theme]) then
        styleref = stylelib[theme]
    else
        styleref = stylelib['tabs']
    end
	
	if itemnum then	
		style.top = string.gsub(styleref.top, 'TITLECOLOR', (itemValue('color', itemnum) or args['color'] or styleref.defaultcolor))
		style.top_iconsys = string.gsub(styleref.top_iconsys, 'ICONSIZE', itemValue('iconsize', itemnum) or args['iconsize'] or styleref.defaultsize)
		style.top_iconitem = string.gsub(styleref.top_iconitem, 'ICONSIZE', itemValue('iconsize', itemnum) or args['iconsize'] or styleref.defaultsize)
		style.title = string.gsub(styleref.title, 'TITLECOLOR', (itemValue('color', itemnum) or args['color'] or styleref.defaultcolor))
		style.alt = styleref.alt
		style.iconmap = string.gsub(styleref.iconmap, 'ICONSIZE', itemValue('iconsize', itemnum) or args['iconsize'] or styleref.defaultsize)
		style.icon = string.gsub(styleref.icon, 'TITLECOLOR', (itemValue('color', itemnum) or args['color'] or styleref.defaultcolor))
		style.icon = string.gsub(style.icon, 'ICONSIZE', itemValue('iconsize', itemnum) or args['iconsize'] or styleref.defaultsize)
	end
	
    return style
end

local function renderDummyItem(ctr, dummynum)
	for i = 1, dummynum do
		ctr:tag('div')
			:addClass('flexinfo-itembox')
			:css('flex-basis', args['dummywidth'] or args['width'] or '400px')
			:css('flex-grow', args['grow'] or '1')
			:css('flex-shrink', args['shrink'] or args['grow'] or '1')
	end
end

local function renderNest(ctr, itemnum)
	local style = findTheme(args['theme'], itemnum)

	-- item box
	local itembox = ctr:tag('div')
		:addClass('flexinfo-itembox')
		:css('flex-basis', itemValue('width', itemnum) or args['width'] or '400px')
		:css('flex-grow', itemValue('grow', itemnum) or args['grow'] or '1')
		:css('flex-shrink', itemValue('shrink', itemnum) or args['shrink'] or itemValue('grow', itemnum) or args['grow'] or '1')
		:cssText(args['style-itembox'])
		:cssText(itemValue('style-itembox', itemnum))
		:wikitext(itemValue('nest', itemnum))
end

local function renderItem(ctr, itemnum, hasicon)
	local style = findTheme(args['theme'], itemnum)

	-- item box
	local itembox = ctr:tag('div')
		:addClass('flexinfo-itembox')
		:css('flex-basis', itemValue('width', itemnum) or args['width'] or '400px')
		:css('flex-grow', itemValue('grow', itemnum) or args['grow'] or '1')
		:css('flex-shrink', itemValue('shrink', itemnum) or args['shrink'] or itemValue('grow', itemnum) or args['grow'] or '1')
		:css('margin-top', '1em')
		:cssText(args['style-itembox'])
		:cssText(itemValue('style-itembox', itemnum))
	
	-- item main div
	local item = itembox:tag('div')
		:addClass('flexinfo-item')
		:css('margin-left', args['margin'] or style.defaultmargin or '1em')
		:css('margin-right', args['margin'] or style.defaultmargin or '1em')
		
	-- item top bar
	local itemtop = item:tag('div')
		:addClass('flexinfo-itemtop')
		:cssText(style.top)
	if hasicon == true then	itemtop:cssText(style.top_iconsys) end
		
	-- item title / name
	local itemtitle = itemtop:tag('div')
		:addClass('flexinfo-title')
		:cssText(style.title)
		:cssText(args['style-title'])
		:cssText(itemValue('style-title', itemnum))
		
	-- icon config
	if itemValue('icon', itemnum) then
		itemtop
			:cssText(style.top_iconitem)
		local iconmap = itemtitle:tag('div')
			:addClass('flexinfo-iconmap')
			:cssText(style.iconmap)
			:cssText(args['style-iconmap'])
			:cssText(itemValue('style-iconmap', itemnum))
	
		local icon = iconmap:tag('div')
			:addClass('flexinfo-icon')
			:cssText(style.icon)
			:wikitext(itemValue('icon', itemnum))
			:cssText(args['style-icon'])
			:cssText(itemValue('style-icon', itemnum))
	end
	
	itemtop
		:cssText(args['style-top'])
		:cssText(itemValue('style-top', itemnum))
	itemtitle:wikitext(args[format("item%d", itemnum)])
	
	-- item subhead / alt / cv
	if itemValue('alt', itemnum) then
		local itemcv = itemtop:tag('div')
			:addClass('flexinfo-alt')
			:cssText(style.alt)
			:cssText(args['style-alt'])
			:cssText(itemValue('style-alt', itemnum))
			:wikitext(itemValue('alt', itemnum))
	elseif itemValue('cv', itemnum) then
		local itemcv = itemtop:tag('div')
			:addClass('flexinfo-alt')
			:cssText(style.alt)
			:cssText(args['style-alt'])
			:cssText(itemValue('style-alt', itemnum))
			:wikitext('CV:' .. itemValue('cv', itemnum))
	end
	
	-- item info / text
	local itemtext = item:tag('p')
		:wikitext(itemValue('text', itemnum))
end

function p._flexinfo(infoArgs)
	args = infoArgs
	
	if(args['theme'] == nil) then
		args['theme'] = 'tabs'
	end
	local style = findTheme(args['theme'])
	local itemnums = {}
	local hasicon = false

	for k, _ in pairs(args) do
		if type(k) == 'string' then
			local itemnum = k:match('^item(%d+)$')
			if itemnum then table.insert(itemnums, tonumber(itemnum)) end
			local iconnum = k:match('^item(%d+)-icon')
			if iconnum then hasicon = true end
		end
	end
	table.sort(itemnums)

	local ctr = mw.html.create('div')
		:addClass('infoflex')
		:css('display', 'flex')
		:css('flex-wrap', 'wrap')
		
	local margin = '1em'	
	if(stylelib[theme]) then
		margin = stylelib[theme]['defaultmargin']
	end

	if not args['nest'] then
		ctr
			:css('margin-top', '-0.5em')
			:css('margin-bottom', '0.5em')
			:css('margin-left', ('-' .. margin))
			:css('margin-right', ('-' .. margin))
	end
	
	ctr:cssText(args['containerstyle'])

	local itemnums_size = #itemnums
	for i, itemnum in ipairs(itemnums) do
		if(args[format("item%d-nest", i)]) then
			renderNest(ctr, itemnum)
		else
			renderItem(ctr, itemnum, hasicon)
		end
	end
	
	if(args['dummy']) then
		renderDummyItem(ctr, args['dummy']);
	end

	return ctr
end

function p.flexinfo(frame)
    if not getArgs then
    	getArgs = require('Module:Arguments').getArgs
    end
    args = getArgs(frame)
	
	return p._flexinfo(args)
end

return p