Home
Random
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/DrMeepster/C yes yes
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local p = {} -------------------------------- -----Code from other people----- -------------------------------- TableTools = require("Module:TableTools") --https://stackoverflow.com/a/1283608 --All stack overflow code is CC BY-SA 3.0 local function tableMerge(t1, t2) for k,v in pairs(t2) do if type(v) == "table" then if type(t1[k] or false) == "table" then _tableMerge(t1[k] or {}, t2[k] or {}) else t1[k] = v end else t1[k] = v end end return t1 end --This function is public domain. See http://lua-users.org/wiki/OrderedTable --Modified to be able to accept args local function Ordered(t) --nextkey and firstkey are used as markers; nextkey[firstkey] is --the first key in the table, and nextkey[nextkey] is the last key. --nextkey[nextkey[nextkey]] should always be nil. local key2val, nextkey, firstkey = {}, {}, {} nextkey[nextkey] = firstkey local function onext(self, key) while key ~= nil do key = nextkey[key] local val = self[key] if val ~= nil then return key, val end end end -- To save on tables, we use firstkey for the (customised) -- metatable; this line is just for documentation local selfmeta = firstkey -- record the nextkey table, for routines lacking the closure selfmeta.__nextkey = nextkey -- setting a new key (might) require adding the key to the chain function selfmeta:__newindex(key, val) rawset(self, key, val) if nextkey[key] == nil then -- adding a new key nextkey[nextkey[nextkey]] = key nextkey[nextkey] = key end end out = setmetatable(key2val, selfmeta) if t then tableMerge(out, t) end return out end p.Ordered = Ordered -------------------------------- ----------Code from me---------- -------------------------------- --metatable of mw.html p.htmlMeta = getmetatable(mw.html.create()) p.orderedMeta = getmetatable(p.Ordered()) function p.filter(tabl, typ) local typeCheck = (type(typ) == "string" and type) or (type(typ) == "table" and getmetatable) or error("Invalid type!") local out = {} for k,v in pairs(tabl) do if typeCheck(v) == typ then out[k] = v end end return out end -------------------------------- --an HTML Element local Element = {parent=nil, id = nil} Element.__index = Element --Create a new Element function Element.new(type) o = setmetatable({}, Element) o.type = type o.children = {} o.style = Ordered() o.classes = {} return o end --Add Element or mw.html as child function Element:add(child) if getmetatable(child) == Element then child.parent = self elseif getmetatable(child) ~= htmlMeta then error("Inavlid child!") end table.insert(self.children, child) return child end --Add string as child function Element:wikitext(child) if type(child) ~= "string" then error("Inavlid child!") end table.insert(self.children, child) return self end --create a new Element then add it function Element:tag(name) elem = Element.new(name) return self:add(elem) end --add a newline (br) function Element:newline() self:tag("br") return self end --add a css property function Element:css(k, v) if type(k) == "table" then for _,kv in ipairs(k) do self:css(kv[1], kv[2]) end elseif type(k) == "string" and type(v) == "string" then self.style[k] = v else error("CSS keys and values should be string!") end return self end --add classes function Element:class(class) if type(class) == "table" then tableMerge(self.classes, class) elseif type(class) == "string" then table.insert(self.classes, class) else error("Invalid class type!") end return self end --set the id function Element:setId(id) if type(id) ~= "string" then error("Id must be string!") end self.id = id return self end --returns parent. used for function chaining function Element:done() return self.parent or self end --returns the root Element function Element:allDone() local parent = self.parent if parent == nil then return self end while parent.parent do parent = parent.parent end return parent end --turn this Element into an mw.html object function Element:bake() local root = mw.html.create(self.type):css(self.style) for _,class in ipairs(self.classes) do root:addClass(class) end for _, child in ipairs(self.children) do if getmetatable(child) == Element then --must bake Element root:node(child:bake()) elseif getmetatable(child) == htmlMeta then --do not need to bake mw.html root:node(child) elseif type(child) == "string" then --if string add as wikitext root:wikitext(child) else error("Unknown child of element!") end end return root end --bakes the root Element function Element:bakeAll() return self:allDone():bake() end --wip dont use function Element:stylesheet(css) for _,c in ipairs(css) do for _,s in ipairs(c.selectors) do if s:check(self) then self:css(c.properties) break end end end for _,child in pairs(p.filter(self.children, Element)) do child:stylesheet(css) end return self end -------------------------------- local Selector = { yes = false, id = nil, type = nil, class = {}, directParent = nil, parent = nil, next = nil } --[[ selections ordered roughly by price, cheapest to most expensive --basic selections-- yes - Makes the selector always be true (*) id - Element must have this id (#id) type - Element must be of this type (type) class - Element must have all these classes (.class1.class2 etc) --combinator selections-- directParent- Element must have its parent element match this selector (parentElement > element) parent - Element must be inside an element matching this selector (parentElement element) ]] Selector.__index = Selector function Selector.new(s) s = s or {} if type(s.class) == "string" then s.class = {s.class} elseif type(s.class) ~= "table" then s.class = {} end return setmetatable(s, Selector) end function Selector:check(e) if getmetatable(e) ~= Element then return false end -- all selector if self.yes then return true end -- id selector if self.id and e.id ~= self.id then return false end -- type selector if self.type and e.type ~= self.type then return false end -- class selector if #self.class > 0 then local class = true for _,v in pairs(self.class) do if not TableTools.inArray(e.classes, v) then class = false break end end if not class then return false end end -- direct parent check if self.directParent and not self.directParent:check(e.parent) then return false end -- parent check if self.parent then local nextParent = e.parent while true do if nextParent == nil then return false end if self.parent:check(nextParent) then break end nextParent = nextParent.parent end end -- all selectors passed return true end -------------------------------- p.Element = Element p.Selector = Selector return p
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:Sandbox/DrMeepster/C yes yes/doc
(
edit
)