در حال ویرایش پودمان:HtmlBuilder
این ویرایش را میتوان خنثی کرد. لطفاً تفاوت زیر را بررسی کنید تا تأیید کنید که این چیزی است که میخواهید انجام دهید، سپس تغییرات زیر را ذخیره کنید تا خنثیسازی ویرایش را به پایان ببرید.
نسخهٔ فعلی | متن شما | ||
خط ۱: | خط ۱: | ||
-- 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 |