Module:Protection banner: Difference between revisions
add catonly param which hides both the banner and padlock if set to yes. all testcases pass. tested in sandbox.
(add catonly param which hides both the banner and padlock if set to yes. all testcases pass. tested in sandbox.) |
|||
Line 1: | Line 1: | ||
-- This module implements {{pp-meta}} and its daughter templates such as | -- This module implements {{pp-meta}} and its daughter templates such as | ||
-- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. | -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. | ||
-- Initialise necessary modules. | -- Initialise necessary modules. | ||
require('Module:No globals') | require('Module:No globals') | ||
local makeFileLink = require('Module:File link')._main | local makeFileLink = require('Module:File link')._main | ||
local effectiveProtectionLevel = require('Module:Effective protection level')._main | local effectiveProtectionLevel = require('Module:Effective protection level')._main | ||
Line 20: | Line 18: | ||
-- Helper functions | -- Helper functions | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local function makeCategoryLink(cat, sort) | local function makeCategoryLink(cat, sort) | ||
Line 59: | Line 33: | ||
local function validateDate(dateString, dateType) | local function validateDate(dateString, dateType) | ||
if not lang then | if not lang then | ||
lang = mw.language.getContentLanguage() | |||
end | end | ||
local success, result = pcall(lang.formatDate, lang, 'U | local success, result = pcall(lang.formatDate, lang, 'U', dateString) | ||
if success then | if success then | ||
result = tonumber(result) | result = tonumber(result) | ||
Line 70: | Line 43: | ||
end | end | ||
error(string.format( | error(string.format( | ||
'%s | 'invalid %s: %s', | ||
dateType, | dateType, | ||
tostring(dateString) | tostring(dateString) | ||
Line 140: | Line 113: | ||
else | else | ||
error(string.format( | error(string.format( | ||
' | 'invalid action: %s', | ||
tostring(args.action) | tostring(args.action) | ||
), 3) | ), 3) | ||
Line 158: | Line 131: | ||
obj.expiry = 'indef' | obj.expiry = 'indef' | ||
elseif effectiveExpiry ~= 'unknown' then | elseif effectiveExpiry ~= 'unknown' then | ||
obj.expiry = validateDate(effectiveExpiry, ' | obj.expiry = validateDate(effectiveExpiry, 'expiry date') | ||
end | end | ||
Line 165: | Line 138: | ||
obj.reason = mw.ustring.lower(args[1]) | obj.reason = mw.ustring.lower(args[1]) | ||
if obj.reason:find('|') then | if obj.reason:find('|') then | ||
error(' | error('reasons cannot contain the pipe character ("|")', 3) | ||
end | end | ||
end | end | ||
Line 171: | Line 144: | ||
-- Set protection date | -- Set protection date | ||
if args.date then | if args.date then | ||
obj.protectionDate = validateDate(args.date, ' | obj.protectionDate = validateDate(args.date, 'protection date') | ||
end | end | ||
Line 196: | Line 169: | ||
end | end | ||
return setmetatable(obj, Protection) | return setmetatable(obj, Protection) | ||
end | |||
function Protection:isUserScript() | |||
-- Whether the page is a user JavaScript or CSS page. | |||
local title = self.title | |||
return title.namespace == 2 and ( | |||
title.contentModel == 'javascript' or title.contentModel == 'css' | |||
) | |||
end | end | ||
Line 201: | Line 182: | ||
return self.level ~= '*' | return self.level ~= '*' | ||
end | end | ||
function Protection:shouldShowLock() | |||
-- Whether we should output a banner/padlock | |||
return self:isProtected() and not self:isUserScript() | |||
end | |||
-- Whether this page needs a protection category. | |||
Protection.shouldHaveProtectionCategory = Protection.shouldShowLock | |||
function Protection:isTemporary() | function Protection:isTemporary() | ||
Line 207: | Line 196: | ||
function Protection:makeProtectionCategory() | function Protection:makeProtectionCategory() | ||
if not self:shouldHaveProtectionCategory() then | |||
return '' | |||
end | |||
local cfg = self._cfg | local cfg = self._cfg | ||
local title = self.title | local title = self.title | ||
-- Get the expiry key fragment. | -- Get the expiry key fragment. | ||
Line 228: | Line 216: | ||
namespaceFragment = 'talk' | namespaceFragment = 'talk' | ||
end | end | ||
-- Define the order that key fragments are tested in. This is done with an | -- Define the order that key fragments are tested in. This is done with an | ||
-- array of tables containing the value to be tested, along with its | -- array of tables containing the value to be tested, along with its | ||
Line 336: | Line 324: | ||
function Protection:isIncorrect() | function Protection:isIncorrect() | ||
local expiry = self.expiry | local expiry = self.expiry | ||
return not self: | return not self:shouldHaveProtectionCategory() | ||
or type(expiry) == 'number' and expiry < os.time() | or type(expiry) == 'number' and expiry < os.time() | ||
end | end | ||
Line 351: | Line 339: | ||
function Protection:makeCategoryLinks() | function Protection:makeCategoryLinks() | ||
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 394: | Line 382: | ||
function Blurb:_formatDate(num) | function Blurb:_formatDate(num) | ||
-- Formats a Unix timestamp into dd Month, YYYY format. | -- Formats a Unix timestamp into dd Month, YYYY format. | ||
lang = lang or mw.language.getContentLanguage() | |||
lang = lang or mw. | |||
local success, date = pcall( | local success, date = pcall( | ||
lang.formatDate, | lang.formatDate, | ||
lang, | lang, | ||
self._cfg.msg['expiry-date-format'] or ' | self._cfg.msg['expiry-date-format'] or 'j F Y', | ||
'@' .. | '@' .. tostring(num) | ||
) | ) | ||
if success then | if success then | ||
Line 456: | Line 443: | ||
-- We need the move log link. | -- We need the move log link. | ||
return makeFullUrl( | return makeFullUrl( | ||
' | 'Special:Log', | ||
{type = 'move', page = pagename}, | {type = 'move', page = pagename}, | ||
self:_getExpandedMessage('current-version-move-display') | self:_getExpandedMessage('current-version-move-display') | ||
Line 529: | Line 516: | ||
else | else | ||
error(string.format( | error(string.format( | ||
' | 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', | ||
action, | action, | ||
level, | level, | ||
Line 555: | Line 542: | ||
function Blurb:_makeIntroBlurbParameter() | function Blurb:_makeIntroBlurbParameter() | ||
if self._protectionObj:isTemporary() then | if self._protectionObj:isTemporary() then | ||
return | return self:_getExpandedMessage('intro-blurb-expiry') | ||
else | else | ||
return self:_getExpandedMessage('intro-blurb-noexpiry') | return self:_getExpandedMessage('intro-blurb-noexpiry') | ||
Line 563: | Line 550: | ||
function Blurb:_makeIntroFragmentParameter() | function Blurb:_makeIntroFragmentParameter() | ||
if self._protectionObj:isTemporary() then | if self._protectionObj:isTemporary() then | ||
return | return self:_getExpandedMessage('intro-fragment-expiry') | ||
else | else | ||
return self:_getExpandedMessage('intro-fragment-noexpiry') | return self:_getExpandedMessage('intro-fragment-noexpiry') | ||
Line 573: | Line 560: | ||
return pagetypes[self._protectionObj.title.namespace] | return pagetypes[self._protectionObj.title.namespace] | ||
or pagetypes.default | or pagetypes.default | ||
or error(' | or error('no default pagetype defined', 8) | ||
end | end | ||
Line 588: | Line 575: | ||
msg = protectionBlurbs.edit.default | msg = protectionBlurbs.edit.default | ||
else | else | ||
error(' | error('no protection blurb defined for protectionBlurbs.edit.default', 8) | ||
end | end | ||
return self:_substituteParameters(msg) | return self:_substituteParameters(msg) | ||
Line 614: | Line 601: | ||
msg = protectionLevels.edit.default | msg = protectionLevels.edit.default | ||
else | else | ||
error(' | error('no protection level defined for protectionLevels.edit.default', 8) | ||
end | end | ||
return self:_substituteParameters(msg) | return self:_substituteParameters(msg) | ||
Line 624: | Line 611: | ||
-- We need the pending changes log. | -- We need the pending changes log. | ||
return makeFullUrl( | return makeFullUrl( | ||
' | 'Special:Log', | ||
{type = 'stable', page = pagename}, | {type = 'stable', page = pagename}, | ||
self:_getExpandedMessage('pc-log-display') | self:_getExpandedMessage('pc-log-display') | ||
Line 631: | Line 618: | ||
-- We need the protection log. | -- We need the protection log. | ||
return makeFullUrl( | return makeFullUrl( | ||
' | 'Special:Log', | ||
{type = 'protect', page = pagename}, | {type = 'protect', page = pagename}, | ||
self:_getExpandedMessage('protection-log-display') | self:_getExpandedMessage('protection-log-display') | ||
Line 650: | Line 637: | ||
function Blurb:_makeTooltipBlurbParameter() | function Blurb:_makeTooltipBlurbParameter() | ||
if self._protectionObj:isTemporary() then | if self._protectionObj:isTemporary() then | ||
return | return self:_getExpandedMessage('tooltip-blurb-expiry') | ||
else | else | ||
return self:_getExpandedMessage('tooltip-blurb-noexpiry') | return self:_getExpandedMessage('tooltip-blurb-noexpiry') | ||
Line 658: | Line 645: | ||
function Blurb:_makeTooltipFragmentParameter() | function Blurb:_makeTooltipFragmentParameter() | ||
if self._protectionObj:isTemporary() then | if self._protectionObj:isTemporary() then | ||
return | return self:_getExpandedMessage('tooltip-fragment-expiry') | ||
else | else | ||
return self:_getExpandedMessage('tooltip-fragment-noexpiry') | return self:_getExpandedMessage('tooltip-fragment-noexpiry') | ||
Line 665: | Line 652: | ||
function Blurb:_makeVandalTemplateParameter() | function Blurb:_makeVandalTemplateParameter() | ||
return | return mw.getCurrentFrame():expandTemplate{ | ||
self._args.user or self._protectionObj.title.baseText | title="vandal-m", | ||
args={self._args.user or self._protectionObj.title.baseText} | |||
} | } | ||
end | end | ||
Line 676: | Line 664: | ||
if not key or not Blurb.bannerTextFields[key] then | if not key or not Blurb.bannerTextFields[key] then | ||
error(string.format( | error(string.format( | ||
' | '"%s" is not a valid banner config field', | ||
tostring(key) | tostring(key) | ||
), 2) | ), 2) | ||
Line 689: | Line 677: | ||
if type(msg) ~= 'string' then | if type(msg) ~= 'string' then | ||
error(string.format( | error(string.format( | ||
' | 'bad output from banner config function with key "%s"' | ||
.. ' ( | .. ' (expected string, got %s)', | ||
tostring(key), | tostring(key), | ||
type(msg) | type(msg) | ||
Line 783: | Line 771: | ||
-- Renders the banner. | -- Renders the banner. | ||
makeMessageBox = makeMessageBox or require('Module:Message box').main | makeMessageBox = makeMessageBox or require('Module:Message box').main | ||
local reasonText = self._reasonText or error(' | local reasonText = self._reasonText or error('no reason text set', 2) | ||
local explanationText = self._explanationText | local explanationText = self._explanationText | ||
local mbargs = { | local mbargs = { | ||
Line 855: | Line 843: | ||
-- protection from some other action, then don't bother displaying anything | -- protection from some other action, then don't bother displaying anything | ||
-- for the other action (except categories). | -- for the other action (except categories). | ||
if protectionObj.action == 'edit' or | if not yesno(args.catonly) and (protectionObj.action == 'edit' or | ||
args.demolevel or | args.demolevel or | ||
not getReachableNodes( | not getReachableNodes( | ||
cfg.hierarchy, | cfg.hierarchy, | ||
protectionObj.level | protectionObj.level | ||
)[effectiveProtectionLevel('edit', protectionObj.title)] | )[effectiveProtectionLevel('edit', protectionObj.title)]) | ||
then | then | ||
-- Initialise the blurb object | -- Initialise the blurb object | ||
Line 866: | Line 854: | ||
-- Render the banner | -- Render the banner | ||
if protectionObj: | if protectionObj:shouldShowLock() then | ||
ret[#ret + 1] = tostring( | ret[#ret + 1] = tostring( | ||
(yesno(args.small) and Padlock or Banner) | (yesno(args.small) and Padlock or Banner) | ||
Line 887: | Line 875: | ||
-- Find default args, if any. | -- Find default args, if any. | ||
local parent = frame.getParent and frame:getParent() | local parent = frame.getParent and frame:getParent() | ||
local defaultArgs = parent and cfg.wrappers[ | local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] | ||
-- Find user args, and use the parent frame if we are being called from a | -- Find user args, and use the parent frame if we are being called from a |