Module:NavboxMobile: Difference between revisions
EnWikiAdmin (talk | contribs) No edit summary |
EnWikiAdmin (talk | contribs) No edit summary |
||
(77 intermediate revisions by the same user not shown) | |||
Line 50: | Line 50: | ||
local function add_list_styles() | local function add_list_styles() | ||
local frame = mw.getCurrentFrame() | |||
local function add_list_templatestyles(htmlclass, templatestyles) | |||
if has_list_class(htmlclass) then | |||
return frame:extensionTag{ | |||
name = 'templatestyles', args = { src = templatestyles } | |||
} | |||
else | |||
return '' | |||
end | |||
end | |||
local hlist_styles = add_list_templatestyles('hlist', cfg.hlist_templatestyles) | |||
local plainlist_styles = add_list_templatestyles('plainlist', cfg.plainlist_templatestyles) | |||
-- a second workaround for [[phab:T303378]] | |||
-- when that issue is fixed, we can actually use has_navbar not to emit the | |||
-- tag here if we want | |||
if has_navbar() and hlist_styles == '' then | |||
hlist_styles = frame:extensionTag{ | |||
name = 'templatestyles', args = { src = cfg.hlist_templatestyles } | |||
} | |||
end | |||
-- hlist -> plainlist is best-effort to preserve old Common.css ordering. | |||
-- this ordering is not a guarantee because most navboxes will emit only | |||
-- one of these classes [hlist_note] | |||
return hlist_styles .. plainlist_styles | |||
end | end | ||
Line 95: | Line 95: | ||
-- Combine list styles with base and user styles | -- Combine list styles with base and user styles | ||
local list_styles = add_list_styles() | local list_styles = add_list_styles() | ||
local base_templatestyles = cfg.templatestyles | local base_templatestyles = cfg.templatestyles | ||
local templatestyles = add_user_styles(args[cfg.arg.templatestyles]) | local templatestyles = add_user_styles(args[cfg.arg.templatestyles]) | ||
Line 146: | Line 146: | ||
if not item then | if not item then | ||
return '' -- Prevent nil errors | return '' -- Prevent nil errors | ||
end | end | ||
if item:sub(1, 2) == '{|' then | if item:sub(1, 2) == '{|' then | ||
-- Applying nowrap to lines in a table does not make sense. | -- Applying nowrap to lines in a table does not make sense. | ||
-- Add newlines to compensate for trim of x in |parm=x in a template. | -- Add newlines to compensate for trim of x in |parm=x in a template. | ||
item = item:gsub('|%s*width%s*=%s*"[%d%w]+"', '| width="100%"') | |||
return '\n' .. item .. '\n' | return '\n' .. item .. '\n' | ||
end | end | ||
if nowrapitems == cfg.keyword.nowrapitems_yes then | if nowrapitems == cfg.keyword.nowrapitems_yes or true then | ||
local lines = {} | local lines = {} | ||
for line in (item .. '\n'):gmatch('([^\n]*)\n') do | for line in (item .. '\n'):gmatch('([^\n]*)\n') do | ||
Line 169: | Line 167: | ||
return '\n' .. item .. '\n' | return '\n' .. item .. '\n' | ||
end | end | ||
-- Ensure no excessive whitespace | |||
item = mw.ustring.gsub(item, "%s+", " ") | |||
return item | return item | ||
end | end | ||
Line 198: | Line 196: | ||
return tbl:tag('tr') | return tbl:tag('tr') | ||
end | end | ||
-- Function to render the navigation bar | -- Function to render the navigation bar | ||
local function renderNavBar( | local function renderNavBar(cell) | ||
if args.navbar == 'off' then | if args.navbar == 'off' then | ||
return -- Don't render anything if Navbar is off | |||
end | end | ||
-- Render the Navbar | |||
cell:wikitext(navbar{ | |||
args.name, | |||
mini = 1, | |||
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;' | |||
}) | |||
end | end | ||
-- | -- | ||
Line 235: | Line 219: | ||
local titleRow = addTableRow(tbl) | local titleRow = addTableRow(tbl) | ||
local titleCell = titleRow:tag('th'):attr('scope', 'col') | local titleCell = titleRow:tag('th'):attr('scope', 'col') | ||
:addClass('navboxMobile-title') | :addClass('navboxMobile-title') | ||
:addClass(cfg.class.navbox_list) | :addClass(cfg.class.navbox_list) | ||
:addClass(args[cfg.arg.titleclass]) - | :addClass(args[cfg.arg.titleclass]) | ||
:attr('colspan', | :attr('data-level', 1) | ||
:attr('colspan', 2) | |||
:cssText(args.basestyle) | :cssText(args.basestyle) | ||
:cssText(args.titlestyle) | :cssText(args.titlestyle) | ||
:css('position', 'relative') -- Ensure relative positioning for absolute children | |||
-- Add the title content, centered across the full width | |||
titleCell | titleCell | ||
:tag('div') | :tag('div') | ||
:css(' | :css('margin', '0 auto') | ||
:css(' | :css('text-align', 'center') | ||
:wikitext(addNewline(args.title)) | :wikitext(addNewline(args.title)) | ||
-- Add the navbar, positioned absolutely in the top-right corner | |||
if has_navbar() then | |||
titleCell | |||
:tag('div') | |||
:addClass('navboxMobile-navbar') | |||
:css('position', 'absolute') | |||
:css('top', '0') | |||
:css('right', '0') | |||
:css('padding', '0.2em') -- Optional: Adjust padding for alignment | |||
:wikitext(navbar{ | |||
args.name, | |||
mini = 1, | |||
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;' | |||
}) | |||
end | |||
end | end | ||
-- | -- | ||
Line 301: | Line 276: | ||
:wikitext(addNewline(args.above)) | :wikitext(addNewline(args.above)) | ||
end | end | ||
Line 321: | Line 297: | ||
local function renderListRow(tbl, path, parentLevel) | |||
-- Initialize path and parentLevel | |||
path = path or "" | |||
parentLevel = parentLevel or 2 -- Start at level 2 for child groups | |||
-- Keep track of rendered children to avoid duplicates | |||
local renderedChildren = {} | |||
for i = 1, 10 do | |||
local groupKey = (path ~= "" and "child" .. path .. "_" or "") .. "group" .. i | |||
local listKey = (path ~= "" and "child" .. path .. "_" or "") .. "list" .. i | |||
-- Skip if this group has already been rendered | |||
if not renderedChildren[listKey] and args[listKey] then | |||
renderedChildren[listKey] = true -- Track rendered lists | |||
-- Render the group (heading) | |||
local groupRow = addTableRow(tbl) | |||
local groupCell = groupRow:tag('th') | |||
:attr('scope', 'row') | |||
:addClass('navboxMobile-group-content') | |||
:addClass('navboxMobile-group-level' .. parentLevel) -- Correct level | |||
:attr('data-level', parentLevel) -- Optional attribute for CSS targeting | |||
:wikitext(processItem(args[groupKey])) | |||
-- Check if the list is non-empty before rendering content | |||
if args[listKey] and args[listKey] ~= "" then | |||
if args[listKey] == "child" then | |||
-- Check if the child contains valid groups or lists | |||
local childHasContent = false | |||
for j = 1, 10 do | |||
local childGroupKey = "child" .. (path ~= "" and path .. "_" or "") .. i .. "_group" .. j | |||
local childListKey = "child" .. (path ~= "" and path .. "_" or "") .. i .. "_list" .. j | |||
if args[childGroupKey] or args[childListKey] then | |||
childHasContent = true | |||
break | |||
end | |||
end | |||
if childHasContent then | |||
-- Recursively render child lists | |||
local newPath = (path ~= "" and path .. "_" or "") .. i | |||
renderListRow(tbl, tostring(newPath), parentLevel + 1) | |||
end | |||
else | else | ||
-- Render | -- Render flat lists | ||
local listRow = addTableRow(tbl) | |||
:addClass(' | local listCell = listRow:tag('td') | ||
: | :attr('colspan', 2) | ||
:addClass('navboxMobile-list-content') -- Base content class | |||
:addClass('navboxMobile-list-level' .. parentLevel) -- Correct level | |||
:addClass((i % 2 == 1) and 'navboxMobile-odd' or 'navboxMobile-even') -- Odd/even class | |||
:addClass(args.listclass or '') -- Apply `listclass` if defined in the template | |||
:wikitext(processItem(args[listKey], args.nowrapitems)) | |||
end | end | ||
end | end | ||
end | end | ||
end | end | ||
end | end | ||
Line 499: | Line 424: | ||
local tbl = mw.html.create('table') | local tbl = mw.html.create('table') | ||
:addClass('nowraplinks') | :addClass('nowraplinks') | ||
:addClass(cfg.class. | :addClass(cfg.class.navbox) | ||
:addClass(args.bodyclass) | :addClass(args.bodyclass) | ||
:addClass(args.listclass or '') -- Apply the `listclass` argument globally if applicable | |||
:cssText(args.bodystyle) | :cssText(args.bodystyle) | ||
:cssText(args.style) | :cssText(args.style) | ||
Line 506: | Line 432: | ||
:css('margin-bottom', '0') | :css('margin-bottom', '0') | ||
-- Add the title row | |||
renderTitleRow(tbl) | |||
tbl | -- Add the above row | ||
renderAboveRow(tbl) | |||
-- Render all group and list rows | |||
for _, listnum in ipairs(listnums) do | for _, listnum in ipairs(listnums) do | ||
renderListRow(tbl, listnum) | local listKey = "list" .. listnum | ||
local groupKey = "group" .. listnum | |||
if args[listKey] then | |||
-- Render group row | |||
local groupRow = addTableRow(tbl) | |||
local groupCell = groupRow:tag('th') | |||
:attr('scope', 'row') | |||
:addClass('navboxMobile-group-content') | |||
:addClass('navboxMobile-group-level1') | |||
:addClass(args.listclass or '') -- Apply `listclass` for group rows | |||
:wikitext(processItem(args[groupKey])) | |||
-- Render list row | |||
if args[listKey] == 'child' then | |||
renderListRow(tbl, tostring(listnum), 2) | |||
else | |||
local listRow = addTableRow(tbl) | |||
listRow:tag('td') | |||
:attr('colspan', 2) | |||
:addClass('navboxMobile-list-content') | |||
:addClass((listnum % 2 == 1) and 'navboxMobile-odd' or 'navboxMobile-even') | |||
:addClass(args.listclass or '') -- Apply `listclass` to flat rows | |||
:wikitext(processItem(args[listKey])) | |||
end | |||
end | |||
end | end | ||
-- Add the below row | |||
renderBelowRow(tbl) | renderBelowRow(tbl) | ||
Line 532: | Line 475: | ||
-- | |||
-- Main NavboxMobile Function | |||
-- | |||
-- In the main navboxMobile function | |||
function p._navboxMobile(navboxMobileArgs) | function p._navboxMobile(navboxMobileArgs) | ||
args = navboxMobileArgs | args = navboxMobileArgs | ||
Line 542: | Line 490: | ||
local hiding_templatestyles = move_hiding_templatestyles(args) | local hiding_templatestyles = move_hiding_templatestyles(args) | ||
-- Collect list numbers | -- Collect top-level list numbers (list1, list2, etc.) | ||
for k, v in pairs(args) do | for k, v in pairs(args) do | ||
if type(k) == 'string' then | if type(k) == 'string' then | ||
Line 561: | Line 509: | ||
-- Create the final HTML with styles | -- Create the final HTML with styles | ||
local res = mw.html.create() | local res = mw.html.create() | ||
res:node(add_navbox_mobile_styles(hiding_templatestyles)) | res:node(add_navbox_mobile_styles(hiding_templatestyles)) | ||
res:node(tbl) | |||
return tostring(res) | return tostring(res) | ||
end | end | ||
-- | |||
-- Main NavboxMobile Function | |||
-- | |||
function p.navboxMobile(frame) | function p.navboxMobile(frame) | ||
if not getArgs then | if not getArgs then | ||
Line 633: | Line 537: | ||
return p._navboxMobile(args) | return p._navboxMobile(args) | ||
end | end | ||
return p | return p |