Module:Infobox: Difference between revisions
fix phantom reference bug
m>Mr. Stradivarius m (Protected Module:Infobox: High-risk Lua module ([Edit=Block all non-admin users] (indefinite) [Move=Block all non-admin users] (indefinite))) |
m>Mr. Stradivarius (fix phantom reference bug) |
||
Line 7: | Line 7: | ||
local HtmlBuilder = require('Module:HtmlBuilder') | local HtmlBuilder = require('Module:HtmlBuilder') | ||
local args | local args = {} | ||
local origArgs | |||
local root | local root | ||
Line 263: | Line 264: | ||
end | end | ||
local function | local function preprocessSingleArg(argName) | ||
-- | -- If the argument exists and isn't blank, add it to the argument table. | ||
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions. | |||
-- | if origArgs[argName] and origArgs[argName] ~= '' then | ||
if | args[argName] = origArgs[argName] | ||
end | end | ||
if | end | ||
error(" | |||
local function preprocessArgs(prefixTable, step) | |||
-- Assign the parameters with the given prefixes to the args table, in order, in batches | |||
-- of the step size specified. This is to prevent references etc. from appearing in the | |||
-- wrong order. The prefixTable should be an array containing tables, each of which has | |||
-- two possible fields, a "prefix" string and a "depend" table. The function always parses | |||
-- parameters containing the "prefix" string, but only parses parameters in the "depend" | |||
-- table if the prefix parameter is present and non-blank. | |||
if type(prefixTable) ~= 'table' then | |||
error("Non-table value detected for the prefix table", 2) | |||
end | |||
if type(step) ~= 'number' then | |||
error("Invalid step value detected", 2) | |||
end | end | ||
-- Get arguments without a number suffix, and check for bad input. | |||
for i,v in ipairs(prefixTable) do | |||
if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then | |||
error('Invalid input detected to preprocessArgs prefix table', 2) | |||
end | |||
preprocessSingleArg(v.prefix) | |||
-- Only parse the depend parameter if the prefix parameter is present and not blank. | |||
if args[v.prefix] and v.depend then | |||
for j, dependValue in ipairs(v.depend) do | |||
if type(dependValue) ~= 'string' then | |||
error('Invalid "depend" parameter value detected in preprocessArgs') | |||
end | |||
preprocessSingleArg(dependValue) | |||
end | |||
end | |||
end | |||
-- Get arguments with number suffixes. | |||
local a = 1 -- Counter variable. | local a = 1 -- Counter variable. | ||
local moreArgumentsExist = true | local moreArgumentsExist = true | ||
while moreArgumentsExist == true do | while moreArgumentsExist == true do | ||
moreArgumentsExist = false | moreArgumentsExist = false | ||
for i = a, a + step - 1 do | for i = a, a + step - 1 do | ||
for j,v in ipairs(prefixTable) do | for j,v in ipairs(prefixTable) do | ||
local prefixArgName = v.prefix .. tostring(i) | |||
if | if origArgs[prefixArgName] then | ||
moreArgumentsExist = true | moreArgumentsExist = true -- Do another loop if any arguments are found, even blank ones. | ||
preprocessSingleArg(prefixArgName) | |||
end | |||
-- Process the depend table if the prefix argument is present and not blank, or | |||
-- we are processing "prefix1" and "prefix" is present and not blank, and | |||
-- if the depend table is present. | |||
if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then | |||
for j,dependValue in ipairs(v.depend) do | |||
local dependArgName = dependValue .. tostring(i) | |||
preprocessSingleArg(dependArgName) | |||
end | |||
end | end | ||
end | end | ||
Line 299: | Line 331: | ||
function p.infobox(frame) | function p.infobox(frame) | ||
-- If called via #invoke, use the args passed into the invoking template. | -- If called via #invoke, use the args passed into the invoking template. | ||
-- Otherwise, for testing purposes, assume args are being passed directly in. | -- Otherwise, for testing purposes, assume args are being passed directly in. | ||
Line 309: | Line 340: | ||
-- Parse the data parameters in the same order that the old {{infobox}} did, so that | -- Parse the data parameters in the same order that the old {{infobox}} did, so that | ||
-- references etc. will display in the expected places. | -- references etc. will display in the expected places. Parameters that depend on | ||
-- another parameter are only processed if that parameter is present, to avoid | |||
-- phantom references appearing in article reference lists. | |||
preprocessSingleArg('child') | |||
preprocessSingleArg('bodyclass') | |||
preprocessSingleArg('subbox') | |||
preprocessSingleArg('bodystyle') | |||
preprocessSingleArg('title') | |||
preprocessSingleArg('titleclass') | |||
preprocessSingleArg('titlestyle') | |||
preprocessSingleArg('above') | |||
preprocessSingleArg('aboveclass') | |||
preprocessSingleArg('abovestyle') | |||
preprocessArgs({ | |||
{prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}} | |||
}, 10) | |||
preprocessSingleArg('subheaderstyle') | |||
preprocessSingleArg('subheaderclass') | |||
preprocessArgs({ | |||
{prefix = 'image', depend = {'caption', 'imagerowclass'}} | |||
}, 10) | |||
preprocessSingleArg('captionstyle') | |||
preprocessSingleArg('imagestyle') | |||
preprocessSingleArg('imageclass') | |||
preprocessArgs({ | |||
{prefix = 'header'}, | |||
{prefix = 'data', depend = {'label', 'rowclass'}}, | |||
{prefix = 'class'} | |||
}, 50) | |||
preprocessSingleArg('headerstyle') | |||
preprocessSingleArg('labelstyle') | |||
preprocessSingleArg('datastyle') | |||
preprocessSingleArg('below') | |||
preprocessSingleArg('belowclass') | |||
preprocessSingleArg('belowstyle') | |||
preprocessSingleArg('name') | |||
args['italic title'] = origArgs['italic title'] -- different behaviour if blank or absent | |||
preprocessSingleArg('decat') | |||
return _infobox() | return _infobox() |