Editing Module:Protection banner
From Guild of Archivists
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 20: | Line 20: | ||
local function makeCategoryLink(cat, sort) | local function makeCategoryLink(cat, sort) | ||
if cat then | |||
if cat | |||
return string.format( | return string.format( | ||
'[[%s:%s|%s]]', | '[[%s:%s|%s]]', | ||
mw.site.namespaces[14].name, | |||
cat, | cat, | ||
sort | sort | ||
) | ) | ||
end | end | ||
end | end | ||
Line 41: | Line 32: | ||
-- Validation function for the expiry and the protection date | -- Validation function for the expiry and the protection date | ||
local function validateDate(dateString, dateType) | local function validateDate(dateString, dateType) | ||
lang = | if not lang then | ||
lang = mw.language.getContentLanguage() | |||
end | |||
local success, result = pcall(lang.formatDate, lang, 'U', dateString) | local success, result = pcall(lang.formatDate, lang, 'U', dateString) | ||
if success then | if success then | ||
Line 50: | Line 43: | ||
end | end | ||
error(string.format( | error(string.format( | ||
'invalid %s | 'invalid %s: %s', | ||
dateType, | dateType, | ||
tostring(dateString) | tostring(dateString) | ||
Line 64: | Line 57: | ||
end | end | ||
-- Given a directed graph formatted as node -> table of direct successors, | |||
-- get a table of all nodes reachable from a given node (though always | |||
-- including the given node). | |||
local function getReachableNodes(graph, start) | |||
local function | |||
local toWalk, retval = {[start] = true}, {} | local toWalk, retval = {[start] = true}, {} | ||
while true do | while true do | ||
-- Can't use pairs() since we're adding and removing things as we're iterating | -- Can't use pairs() since we're adding and removing things as we're iterating | ||
local k = next(toWalk) | local k = next(toWalk) -- This always gets the "first" key | ||
if k == nil then | if k == nil then | ||
return retval | |||
end | |||
toWalk[k] = nil | toWalk[k] = nil | ||
retval[k] = true | retval[k] = true | ||
for _,v in ipairs( | for _,v in ipairs(graph[k]) do | ||
if not retval[v] then | if not retval[v] then | ||
toWalk[v] = true | toWalk[v] = true | ||
Line 84: | Line 76: | ||
end | end | ||
end | end | ||
end | end | ||
Line 97: | Line 88: | ||
edit = true, | edit = true, | ||
move = true, | move = true, | ||
autoreview = true | autoreview = true, | ||
upload = true | |||
} | } | ||
Line 121: | Line 113: | ||
else | else | ||
error(string.format( | error(string.format( | ||
'invalid action | 'invalid action: %s', | ||
tostring(args.action) | tostring(args.action) | ||
), 3) | ), 3) | ||
Line 140: | Line 132: | ||
elseif effectiveExpiry ~= 'unknown' then | elseif effectiveExpiry ~= 'unknown' then | ||
obj.expiry = validateDate(effectiveExpiry, 'expiry date') | obj.expiry = validateDate(effectiveExpiry, 'expiry date') | ||
end | end | ||
Line 213: | Line 197: | ||
-- Get the namespace key fragment. | -- Get the namespace key fragment. | ||
local | local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] | ||
if not namespaceFragment and title.namespace % 2 == 1 then | |||
namespaceFragment = 'talk' | |||
end | end | ||
Line 243: | Line 224: | ||
-- instead. | -- instead. | ||
--]] | --]] | ||
table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) | |||
--[[ | --[[ | ||
Line 329: | Line 305: | ||
end | end | ||
return '' | return '' | ||
end | end | ||
Line 361: | Line 325: | ||
local msg = self._cfg.msg | local msg = self._cfg.msg | ||
local ret = { self:makeProtectionCategory() } | local ret = { self:makeProtectionCategory() } | ||
if self:isIncorrect() then | if self:isIncorrect() then | ||
ret[#ret + 1] = makeCategoryLink( | ret[#ret + 1] = makeCategoryLink( | ||
Line 494: | Line 452: | ||
if level == 'autoconfirmed' then | if level == 'autoconfirmed' then | ||
requestType = 'semi' | requestType = 'semi' | ||
elseif level == 'extendedconfirmed' then | |||
requestType = 'extended' | |||
elseif level == 'templateeditor' then | elseif level == 'templateeditor' then | ||
requestType = 'template' | requestType = 'template' | ||
Line 760: | Line 720: | ||
end | end | ||
return setmetatable(obj, BannerTemplate) | return setmetatable(obj, BannerTemplate) | ||
end | end | ||
Line 776: | Line 728: | ||
return makeFileLink{ | return makeFileLink{ | ||
file = filename, | file = filename, | ||
size = (self. | size = (self.imageWidth or 20) .. 'px', | ||
alt = self._imageAlt, | alt = self._imageAlt, | ||
link = self._imageLink, | link = self._imageLink, | ||
caption = self. | caption = self.imageCaption | ||
} | } | ||
end | end | ||
Line 792: | Line 744: | ||
function Banner.new(protectionObj, blurbObj, cfg) | function Banner.new(protectionObj, blurbObj, cfg) | ||
local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. | local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. | ||
obj | obj.imageWidth = 40 | ||
obj | obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. | ||
obj._reasonText = blurbObj:makeBannerText('text') | obj._reasonText = blurbObj:makeBannerText('text') | ||
obj._explanationText = blurbObj:makeBannerText('explanation') | obj._explanationText = blurbObj:makeBannerText('explanation') | ||
Line 808: | Line 760: | ||
page = self._page, | page = self._page, | ||
type = 'protection', | type = 'protection', | ||
image = | image = self:renderImage(), | ||
text = string.format( | text = string.format( | ||
"'''%s'''%s", | "'''%s'''%s", | ||
Line 827: | Line 779: | ||
function Padlock.new(protectionObj, blurbObj, cfg) | function Padlock.new(protectionObj, blurbObj, cfg) | ||
local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. | local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. | ||
obj | obj.imageWidth = 20 | ||
obj | obj.imageCaption = blurbObj:makeBannerText('tooltip') | ||
obj._imageAlt = blurbObj:makeBannerText('alt') | obj._imageAlt = blurbObj:makeBannerText('alt') | ||
obj._imageLink = blurbObj:makeBannerText('link') | obj._imageLink = blurbObj:makeBannerText('link') | ||
Line 840: | Line 792: | ||
local frame = mw.getCurrentFrame() | local frame = mw.getCurrentFrame() | ||
-- The nowiki tag helps prevent whitespace at the top of articles. | -- The nowiki tag helps prevent whitespace at the top of articles. | ||
return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ | |||
name = 'indicator', | name = 'indicator', | ||
args = {name = self._indicatorName}, | args = {name = self._indicatorName}, | ||
content = self:renderImage() | content = self:renderImage() | ||
} | } | ||
end | end | ||
Line 874: | Line 824: | ||
local ret = {} | local ret = {} | ||
-- If a page's edit protection is equally or more restrictive than its protection from some other action, | -- If a page's edit protection is equally or more restrictive than its | ||
-- protection from some other action, then don't bother displaying anything | |||
if protectionObj.action == 'edit' or args.demolevel or not | -- for the other action (except categories). | ||
if protectionObj.action == 'edit' or | |||
args.demolevel or | |||
not getReachableNodes( | |||
cfg.hierarchy, | |||
protectionObj.level | |||
)[effectiveProtectionLevel('edit', protectionObj.title)] | |||
then | |||
-- Initialise the blurb object | -- Initialise the blurb object | ||
local blurbObj = Blurb.new(protectionObj, args, cfg) | local blurbObj = Blurb.new(protectionObj, args, cfg) |