جز
بدون خلاصۀ ویرایش
Hasaninasab (بحث | مشارکتها) (صفحهای تازه حاوی «error('Please use mw.html instead of Module:HtmlBuilder', 3)» ایجاد کرد) |
Hasaninasab (بحث | مشارکتها) جزبدون خلاصۀ ویرایش |
||
خط ۱: | خط ۱: | ||
-- Module for building complex HTML (e.g. infoboxes, navboxes) using a fluent interface. | |||
local HtmlBuilder = {} | |||
local metatable = {} | |||
metatable.__index = function(t, key) | |||
local ret = rawget(t, key) | |||
if ret then | |||
return ret | |||
end | |||
ret = metatable[key] | |||
if type(ret) == 'function' then | |||
return function(...) | |||
return ret(t, ...) | |||
end | |||
else | |||
return ret | |||
end | |||
end | |||
metatable.__tostring = function(t) | |||
local ret = {} | |||
t._build(ret) | |||
return table.concat(ret) | |||
end | |||
metatable._build = function(t, ret) | |||
if t.tagName then | |||
table.insert(ret, '<' .. t.tagName) | |||
for i, attr in ipairs(t.attributes) do | |||
table.insert(ret, ' ' .. attr.name .. '="' .. attr.val .. '"') | |||
end | |||
if #t.styles > 0 then | |||
table.insert(ret, ' style="') | |||
for i, prop in ipairs(t.styles) do | |||
if type(prop) == 'string' then -- added with cssText() | |||
table.insert(ret, prop .. ';') | |||
else -- added with css() | |||
table.insert(ret, prop.name .. ':' .. prop.val .. ';') | |||
end | |||
end | |||
table.insert(ret, '"') | |||
end | |||
if t.selfClosing then | |||
table.insert(ret, ' /') | |||
end | |||
table.insert(ret, '>') | |||
end | |||
for i, node in ipairs(t.nodes) do | |||
if node then | |||
if type(node) == 'table' then | |||
node._build(ret) | |||
else | |||
table.insert(ret, tostring(node)) | |||
end | |||
end | |||
end | |||
if t.tagName and not t.unclosed and not t.selfClosing then | |||
table.insert(ret, '</' .. t.tagName .. '>') | |||
end | |||
end | |||
metatable.node = function(t, builder) | |||
if builder then | |||
table.insert(t.nodes, builder) | |||
end | |||
return t | |||
end | |||
metatable.wikitext = function(t, ...) | |||
local vals = {...} | |||
for i = 1, #vals do | |||
if vals[i] then | |||
table.insert(t.nodes, vals[i]) | |||
end | |||
end | |||
return t | |||
end | |||
metatable.newline = function(t) | |||
table.insert(t.nodes, '\n') | |||
return t | |||
end | |||
metatable.tag = function(t, tagName, args) | |||
args = args or {} | |||
args.parent = t | |||
local builder = HtmlBuilder.create(tagName, args) | |||
table.insert(t.nodes, builder) | |||
return builder | |||
end | |||
local function getAttr(t, name) | |||
for i, attr in ipairs(t.attributes) do | |||
if attr.name == name then | |||
return attr | |||
end | |||
end | |||
end | |||
metatable.attr = function(t, name, val) | |||
if type(val) == 'string' or type(val) == 'number' then | |||
-- if caller sets the style attribute explicitly, then replace all styles previously added with css() and cssText() | |||
if name == 'style' then | |||
t.styles = {val} | |||
return t | |||
end | |||
local attr = getAttr(t, name) | |||
if attr then | |||
attr.val = val | |||
else | |||
table.insert(t.attributes, {name = name, val = val}) | |||
end | |||
end | |||
return t | |||
end | |||
metatable.addClass = function(t, class) | |||
if class then | |||
local attr = getAttr(t, 'class') | |||
if attr then | |||
attr.val = attr.val .. ' ' .. class | |||
else | |||
t.attr('class', class) | |||
end | |||
end | |||
return t | |||
end | |||
metatable.css = function(t, name, val) | |||
if type(val) == 'string' or type(val) == 'number' then | |||
for i, prop in ipairs(t.styles) do | |||
if prop.name == name then | |||
prop.val = val | |||
return t | |||
end | |||
end | |||
table.insert(t.styles, {name = name, val = val}) | |||
end | |||
return t | |||
end | |||
metatable.cssText = function(t, css) | |||
if css then | |||
table.insert(t.styles, css) | |||
end | |||
return t | |||
end | |||
metatable.done = function(t) | |||
return t.parent or t | |||
end | |||
metatable.allDone = function(t) | |||
while t.parent do | |||
t = t.parent | |||
end | |||
return t | |||
end | |||
function HtmlBuilder.create(tagName, args) | |||
args = args or {} | |||
local builder = {} | |||
setmetatable(builder, metatable) | |||
builder.nodes = {} | |||
builder.attributes = {} | |||
builder.styles = {} | |||
builder.tagName = tagName | |||
builder.parent = args.parent | |||
builder.unclosed = args.unclosed or false | |||
builder.selfClosing = args.selfClosing or false | |||
return builder | |||
end | |||
return HtmlBuilder |