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