Módulo:Droflax
Ir para navegação
Ir para pesquisar
A documentação para este módulo pode ser criada em Módulo:Droflax/doc
local p = {}
function p.render(frame)
local args = frame:getParent().args
local mwHtml = require('mw.html')
local util = require('libraryUtil')
-- Validación básica
if not args.nome or args.nome == '' then
return '<div class="error">Falta el nombre del personaje</div>'
end
-- Construir estructura de datos optimizada
local data = {
nome = args.nome,
tier = args.tier or '',
classe = args.classe or '',
image = args.image or '',
habilidades = {},
skins = {}
}
-- Procesar habilidades (1-15) con validación
for i = 1, 15 do
if args['hab'..i..'-nome'] and args['hab'..i..'-nome'] ~= '' then
table.insert(data.habilidades, {
nome = args['hab'..i..'-nome'],
icon = args['hab'..i..'-icon'] or '',
level = tonumber(args['hab'..i..'-level']) or 0,
desc = args['hab'..i..'-desc'] or '',
atr = args['hab'..i..'-atr'] or '',
video = args['hab'..i..'-video'] or ''
})
end
end
-- Procesar skins (1-5) con validación
for i = 1, 5 do
if args['skin'..i..'-image'] and args['skin'..i..'-image'] ~= '' then
table.insert(data.skins, {
image = args['skin'..i..'-image'],
tooltip = (args['skin'..i..'-tooltip'] or ''):gsub('\n', '<br>')
})
end
end
-- Construir HTML optimizado
local html = mwHtml.create('div')
:addClass('personaje-box')
:addClass('tier-' .. (data.tier:lower() or ''))
:attr('data-loaded', 'false') -- Para que JS detecte cuando puede actuar
-- Cabecera optimizada
local header = html:tag('div')
:addClass('personaje-header')
header:tag('div')
:addClass('personaje-topbar')
:wikitext(string.format([[
<div class="personaje-nome-box">
<img src="/images/6/63/Franky_ts_medal.png" class="topbar-icon" loading="lazy" width="40" height="40">
<div class="personaje-nome-category">
<div class="nome">%s</div>
<div class="classes">%s</div>
</div>
</div>
<div class="topbar-description">%s é um personagem do tier %s.</div>
]], data.nome, data.classe, data.nome, data.tier))
-- Tabs con accesibilidad mejorada
header:tag('div')
:addClass('personaje-tabs')
:attr('role', 'tablist')
:wikitext([[
<button class="tab-btn" data-tab="arma" role="tab" aria-selected="false">Arma</button>
<button class="tab-btn active" data-tab="habilidades" role="tab" aria-selected="true">Habilidades</button>
<button class="tab-btn" data-tab="skins" role="tab" aria-selected="false">Skins</button>
]])
-- Imagen principal con optimización
if data.image ~= '' then
html:tag('link')
:attr('rel', 'preload')
:attr('href', data.image)
:attr('as', 'image')
:attr('fetchpriority', 'high')
:done()
html:tag('img')
:addClass('art-personaje')
:attr('src', data.image)
:attr('alt', data.nome)
:attr('loading', 'eager')
:attr('width', '300')
:attr('height', '300')
:attr('decoding', 'async')
end
-- Precarga de recursos importantes con priorización
if #data.habilidades > 0 then
-- Precargar primeros 3 iconos de habilidades
for i = 1, math.min(3, #data.habilidades) do
if data.habilidades[i].icon ~= '' then
html:tag('link')
:attr('rel', 'preload')
:attr('href', data.habilidades[i].icon)
:attr('as', 'image')
:attr('fetchpriority', 'low')
:done()
end
end
end
-- Contenedor de habilidades optimizado
local habilidadesContainer = html:tag('div')
:addClass('tab-content')
:addClass('active')
:attr('id', 'habilidades')
:attr('role', 'tabpanel')
local cuadrosContainer = habilidadesContainer:tag('div')
:addClass('cuadros-container')
for i, hab in ipairs(data.habilidades) do
local cuadro = cuadrosContainer:tag('div')
:addClass('cuadro')
:attr('data-index', i)
:attr('title', hab.nome)
:attr('aria-label', hab.nome)
if hab.icon ~= '' then
cuadro:tag('img')
:attr('src', hab.icon)
:attr('alt', hab.nome)
:attr('loading', 'lazy')
:attr('width', '40')
:attr('height', '40')
:attr('decoding', 'async')
else
cuadro:wikitext('<div class="icon-placeholder"></div>')
end
end
-- Contenedor de detalles de habilidades
habilidadesContainer:tag('div')
:addClass('habilidades-container')
:wikitext([[
<div class="habilidades-details">
<div class="descripcion-container"></div>
</div>
<div class="video-container"></div>
]])
-- Contenedor de skins optimizado
local skinsContainer = html:tag('div')
:addClass('tab-content')
:attr('id', 'skins')
:attr('role', 'tabpanel')
if #data.skins > 0 then
skinsContainer:wikitext([[
<div class="card-skins">
<span class="card-skins-title">SKINS & SPOTLIGHTS</span>
<div class="skins-carousel-wrapper">
<button class="skins-arrow left" aria-label="Anterior skin">«</button>
<div class="skins-carousel">
]])
for _, skin in ipairs(data.skins) do
skinsContainer:wikitext(string.format([[
<div class="skin-card" title="%s" aria-label="%s">
<img class="skins--imageBanner" src="/images/default-skin-banner.jpg" loading="lazy" width="200" height="80">
<img class="skins--imageSkin" src="%s" loading="lazy" width="150" height="150">
</div>
]], skin.tooltip, skin.tooltip, skin.image))
end
skinsContainer:wikitext([[
</div>
<button class="skins-arrow right" aria-label="Siguiente skin">»</button>
</div>
</div>
]])
end
-- Incluir datos para JS de forma segura
html:tag('script')
:attr('type', 'application/ld+json')
:attr('id', 'personaje-data-json')
:wikitext(mw.text.jsonEncode(data))
return tostring(html)
end
return p