2023年政策修订增补工作正在进行中,欢迎参与!
Module:菜单栏
跳转到导航
跳转到搜索
local menuBar = {}
local getArgs = require('Module:Arguments').getArgs
local toolStripItem={}
local toolStripContainer={
}
function toolStripContainer.base(args)
return setmetatable(args or {},toolStripContainer)
end
toolStripContainer.__index=toolStripContainer
function toolStripContainer.create()
return toolStripContainer.base({items={}})
end
function toolStripContainer:addItem(item_name)
local item=toolStripItem.create(item_name)
table.insert(self.items,item)
return item
end
toolStripContainer._collapseToggle=require('Module:折叠标签')._toggle
function toolStripContainer._collapse(name,text_off,text_on)
local node =toolStripContainer._collapseToggle(name,text_off or name,text_on or text_off or name)
:css("min-width","100%")
return node
end
function toolStripContainer.analysisItemSp(text)
local value=text:match("^%b[]",2)
if not value then
return text
end
local strs=mw.text.split(value:sub(2,#value-1),"|")
local node=toolStripContainer._collapse(unpack(strs))
return tostring(node)
end
function toolStripContainer:addItemSp(item_name)--解释折叠
local node=mw.html.create()
local str = item_name:gsub('%b[]',toolStripContainer.analysisItemSp)
return self:addItem(str)
end
function toolStripContainer:_node()
local node =mw.html.create("div")
:addClass("template_menu_container")
local context=node:tag("div")
:css("background-color",self.back_color)
:css("border-width",self.border_width)
:css("border-color",self.border_color)
:css("border-style","solid")
return node,context
end
function toolStripContainer:_hr()
local node =mw.html.create("hr")
:css("margin","0")
:css("background-color",self.border_color)
:css("border-color",self.border_color)
:css("color",self.border_color);
return node
end
function toolStripContainer:_nodeItem(node,item)
node:node(item:toNode())
end
function toolStripContainer:_nodeGroup(node)
for index=1,#self.items-1 do
self:_nodeItem(node,self.items[index])
if self.split then
node:node(self:_hr())
end
end
self:_nodeItem(node,self.items[#self.items])
end
function toolStripContainer:toNode()
if #self.items==0 then return end
local node,context=self:_node()
self:_nodeGroup(context)
return node
end
local toolStripGroup=toolStripContainer.base()
toolStripGroup.__index=toolStripGroup
function toolStripGroup.create()
return setmetatable({items={}},toolStripGroup)
end
function toolStripGroup:_node()
local node =mw.html.create("div")
:addClass("template_menu_container")
local context=node:tag("div")
context :css("display","flex")
:css("flex-direction",self.flex_direction)
context =context:tag("div")
context :css("background-color",self.back_color)
:css("border-width",self.border_width)
:css("border-color",self.border_color)
:css("border-style","solid")
node :css("text-align",self.text_align)
:css("position","relative")
context :css("position","absolute")
:css("min-width","100%")
return node,context
end
function toolStripGroup:_hr()
local node =toolStripContainer._hr(self)
return node
end
function toolStripGroup:_split()
local node =mw.html.create("hr")
:css("padding","2px")
:css("background-color",self.back_color)
node :tag("hr")
:css("margin","2px")
:css("border-color",self.border_color)
return node
end
function toolStripGroup:_nodeItem(node,item)
if item.context=="-" then
node:node(toolStripGroup:_split())
else
node:node(item:toNode())
end
end
function toolStripItem.base(args)
local item=args or {}
return setmetatable(item,toolStripItem)
end
function toolStripItem.create(context,group)
local item={
context=context,
group=group or toolStripGroup.create(),
}
return setmetatable(item,toolStripItem)
end
toolStripItem.__index=toolStripItem
function toolStripItem:addItem(item_name)
return self.group:addItem(item_name)
end
function toolStripItem:addItemSp(item_name)
return self.group:addItemSp(item_name)
end
function toolStripItem:_title(args)
local node =mw.html.create("div")
if self.select_border_width=="0" then
node :css("background-color",self.cover_color)
:css("flex","auto")
:node(self.context)
return node
end
node :css("border-color",self.cover_color)
:css("border-width",self.select_border_width)
:css("border-style","solid")
:css("flex","auto")
local main =node :tag("div")
:css("background-color",self.cover_color)
:node(self.context)
return node,main
end
function toolStripItem:_node()
local node =mw.html.create("div")
:addClass("template_menu_item")
:css("min-width",self.min_width)
node :node(self:_title())
return node
end
function toolStripItem:toNode()
local node=self:_node()
local childs=self.group:toNode()
if childs then
node:css("display","flex")
:css("align-items",self.align_items)
:node(childs)
end
return node
end
local menuItem=toolStripItem.base()
function menuItem.create(context,group)
return setmetatable(toolStripItem.create(context,group),menuItem)
end
menuItem.__index=menuItem
function menuItem:_node()
local node =toolStripItem._node(self)
:css("flex",self.flex)
:css("display","flex")
:css("flex-direction",self.flex_direction)
return node
end
function menuItem:toNode()
local node=self:_node()
node:node(self.group:toNode())
return node
end
local menuBar=toolStripContainer.base()
function menuBar.create()
return setmetatable({items={}},menuBar)
end
menuBar.__index=menuBar
function menuBar:addItem(item_name)
local result=menuItem.create(item_name)
table.insert(self.items,result)
return result
end
function menuBar:_hr()
local node =toolStripContainer._hr(self)
if self.flex_direction=="column-reverse" or self.flex_direction=="column" then
node :css("width","auto")
:css("height",self.border_width);
else
node :css("height","auto")
:css("width",self.border_width);
end
return node
end
function menuBar:_node()
local node,context=toolStripContainer._node(self)
context :css("display","flex")
:css("white-space","nowrap")
:css("border-left-width",self.left_width)
:css("width",self.width)
:css("flex-direction",self.flex_direction)
:css("text-align",self.text_align)
return node,context
end
function menuBar:toNode()
if #self.items==0 then return end
local node,context=self:_node()
self:_nodeGroup(context)
if menuItem.flex~="auto" and self.width~="min-context" then--追加覆盖
if self.split then
context:node(self:_hr())
end
context :tag("div")
:css("flex","auto")
:css("background-color",menuItem.cover_color)
end
return node
end
function menuBar.argsSet(args)
local tab={
left ="row-reverse",
right ="row",
up ="column-reverse",
down ="column",
}
local tab2={
left ="flex-end",
right ="flex-start",
up ="flex-end",
down ="flex-start",
}
local expend_direction=args["flex-direction"] or args["菜单项排列方向"] or "rigth"
local pop_direction=args["pop-direction"] or args["菜单弹出方向"] or "down"
local child_pop_direction=args["chlid-pop-direction"] or args["子菜单弹出方向"] or "right"
local child_expend_direction=args["chlid-flex-direction"] or args["子菜单展开方向"] or pop_direction
--menuBar
menuBar.flex_direction=tab[expend_direction]
menuBar.width=args["width"] or args["菜单宽度"] or "auto"--min-content
menuBar.back_color=args["back-color"] or args["菜单背景色"] or "white"
menuBar.border_width=args["border-width"] or args["菜单框架宽度"] or "1px"
menuBar.border_color=args["border-color"] or args["菜单框架色"] or "green"
menuBar.left_width=args["left-width"] or args["菜单开端宽度"] or "15px"
menuBar.text_align=args["text-align"] or args["菜单文字位置"] or "center"
menuBar.split=((args["item-split"] or args["菜单项分割线"]~="false"))
--menuItem
menuItem.flex_direction=tab[pop_direction]
menuItem.flex=args["flex"] or args["排列"] or "auto"--
menuItem.min_width=args["item-min-width"] or args["菜单项最小宽度"] or "50px"
menuItem.select_color=args["select-color"] or args["菜单项选择色"] or menuBar.border_color
menuItem.select_border_width=args["select-border-width"] or args["菜单项选择框架宽度"] or "0"
--menuItem.select_border_color=args["select-border-color"]--选择框架颜色
--toolStripGroup
toolStripGroup.flex_direction=tab[child_expend_direction]
toolStripGroup.up=((args["child-direct"] or args["子菜单弹出方向"])=="up")--
toolStripGroup.back_color=args["child-back-color"] or args["子菜单背景色"] or menuBar.back_color
toolStripGroup.border_width=args["child-border-width"] or args["子菜单框架宽度"] or menuBar.border_width
toolStripGroup.border_color=args["child-border-color"] or args["子菜单框架色"] or menuBar.border_color
toolStripGroup.text_align=args["child-text-align"] or args["子菜单文字位置"] or menuBar.text_align
toolStripGroup.split=((args["child-item-split"] or args["子菜单项分割线"]~="false"))
--toolStripItem
toolStripItem.flex_direction=tab[child_pop_direction]
toolStripItem.select_color=args["child-select-color"] or args["子菜单项选择色"] or toolStripGroup.border_color
toolStripItem.min_width=args["child-item-min-width"] or args["子菜单项最小宽度"]
toolStripItem.select_border_width=args["child-select-back-color"] or args["子菜单项选择框架宽度"] or "3px"
toolStripItem.align_items=tab2[child_expend_direction]
--toolStripItem.select_border_color=args["child-select-border-color"] or toolStripGroup.back_color--子菜单项选择框架颜色
--由于实际上选择时进行的是透明化处理,因此参数调整
menuItem.cover_color=menuBar.back_color--未选择时用背景色遮盖
menuBar.back_color=menuItem.select_color--选择时透出背景色遮盖
toolStripItem.cover_color=toolStripGroup.back_color--未选择时用背景色遮盖
toolStripGroup.back_color=toolStripItem.select_color--选择时透出背景色遮盖
end
function menuBar.analysisItem(text)
local s,s2,v,v2
local b,e=text:find("^%*+")
local level,sp
if not b then
b,e=text:find("^#+")
sp=true
if not b then
return nil
end
end
level=e+1-b
return text:sub(e+1),level,sp
end
function menuBar._main(args)--主函数
menuBar.argsSet(args)
local texts=mw.text.split(args[1],"\n")
local main=menuBar.create()
local stack = {[0]=main}
local currectLevel=1
local arg,level
for _,text in pairs(texts) do
str,level,sp=menuBar.analysisItem(text)
if str then
while level-1>currectLevel do
stack[currectLevel+1]=stack[currectLevel]:addItem("")
currectLevel=currectLevel+1
end
if sp then
stack[level]=stack[level-1]:addItemSp(str)
else
stack[level]=stack[level-1]:addItem(str)
end
currectLevel=level
end
end
return main:toNode():done()
end
function menuBar.main(frame)--主函数
local args = getArgs(frame)
return menuBar._main(args)
end
return menuBar