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