편집을 취소할 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 게시해주세요.
최신판 | 당신의 편집 | ||
4번째 줄: | 4번째 줄: | ||
-- Initialise necessary modules. | -- Initialise necessary modules. | ||
require('Module:No globals') | require('Module:No globals') | ||
local | local class = require('Module:Middleclass').class | ||
local newFileLink = require('Module:File link').new | |||
local effectiveProtectionLevel = require('Module:Effective protection level')._main | local effectiveProtectionLevel = require('Module:Effective protection level')._main | ||
local yesno = require('Module:Yesno') | local yesno = require('Module:Yesno') | ||
-- Lazily initialise modules and objects we don't always need. | -- Lazily initialise modules and objects we don't always need. | ||
local getArgs, makeMessageBox, lang | local getArgs, makeMessageBox, lang | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
19번째 줄: | 16번째 줄: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local function makeCategoryLink(cat | local function makeCategoryLink(cat) | ||
if cat then | if cat then | ||
return string.format( | return string.format( | ||
'[[%s: | '[[%s:%s]]', | ||
mw.site.namespaces[14].name, | mw.site.namespaces[14].name, | ||
cat | cat | ||
) | ) | ||
else | |||
return '' | |||
end | end | ||
end | end | ||
32번째 줄: | 30번째 줄: | ||
-- 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 = lang or mw.language.getContentLanguage() | |||
local success, result = pcall(lang.formatDate, lang, 'U', dateString) | local success, result = pcall(lang.formatDate, lang, 'U', dateString) | ||
if success then | if success then | ||
43번째 줄: | 39번째 줄: | ||
end | end | ||
error(string.format( | error(string.format( | ||
'invalid %s | 'invalid %s ("%s")', | ||
dateType, | dateType, | ||
tostring(dateString) | tostring(dateString) | ||
) | )) | ||
end | end | ||
82번째 줄: | 49번째 줄: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local Protection = | local Protection = class('Protection') | ||
Protection.supportedActions = { | Protection.supportedActions = { | ||
create = true, | |||
edit = true, | edit = true, | ||
move = true, | move = true, | ||
autoreview | autoreview = true | ||
} | } | ||
101번째 줄: | 67번째 줄: | ||
} | } | ||
function Protection | function Protection:initialize(args, cfg) | ||
self._cfg = cfg | |||
if args.title then | |||
self.title = mw.title.new(args.title) | |||
if not self.title then | |||
error('Invalid title "' .. args.title .. '"', 2) | |||
end | |||
else | |||
self.title = mw.title.getCurrentTitle() | |||
end | |||
-- Set action | -- Set action | ||
if not args.action then | do | ||
if not args.action then | |||
self.action = 'edit' | |||
elseif self.supportedActions[args.action] then | |||
self.action = args.action | |||
else | |||
error('Unsupported action ' .. args.action, 2) | |||
end | |||
end | end | ||
-- Set level | -- Set level | ||
do | |||
self.level = effectiveProtectionLevel(self.action, self.title) | |||
if self.level == 'accountcreator' then | |||
-- Lump titleblacklisted pages in with template-protected pages, | |||
-- since templateeditors can do both. | |||
self.level = 'templateeditor' | |||
elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then | |||
-- Users need to be autoconfirmed to move pages anyway, so treat | |||
-- semi-move-protected pages as unprotected. | |||
self.level = '*' | |||
end | |||
end | end | ||
-- Set expiry | -- Set expiry | ||
if args.expiry then | |||
if cfg.indefStrings[args.expiry] then | |||
self.expiry = 'indef' | |||
elseif type(args.expiry) == 'number' then | |||
self.expiry = args.expiry | |||
else | |||
self.expiry = validateDate(args.expiry, 'expiry date') | |||
end | |||
end | end | ||
-- Set reason | -- Set reason | ||
do | |||
local reason = args.reason or args[1] | |||
if | if reason then | ||
self.reason = reason:lower() | |||
end | end | ||
end | end | ||
-- Set protection date | -- Set protection date | ||
self.protectionDate = validateDate(args.date, 'protection date') | |||
-- Set banner config | -- Set banner config | ||
do | do | ||
self.bannerConfig = {} | |||
local configTables = {} | local configTables = {} | ||
if cfg.banners[ | if cfg.banners[self.action] then | ||
configTables[#configTables + 1] = cfg.banners[ | configTables[#configTables + 1] = cfg.banners[self.action][self.reason] | ||
end | end | ||
if cfg.defaultBanners[ | if cfg.defaultBanners[self.action] then | ||
configTables[#configTables + 1] = cfg.defaultBanners[ | configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] | ||
configTables[#configTables + 1] = cfg.defaultBanners[ | configTables[#configTables + 1] = cfg.defaultBanners[self.action].default | ||
end | end | ||
configTables[#configTables + 1] = cfg.masterBanner | configTables[#configTables + 1] = cfg.masterBanner | ||
for i, field in ipairs( | for i, field in ipairs(self.bannerConfigFields) do | ||
for j, t in ipairs(configTables) do | for j, t in ipairs(configTables) do | ||
if t[field] then | if t[field] then | ||
self.bannerConfig[field] = t[field] | |||
break | break | ||
end | end | ||
168번째 줄: | 146번째 줄: | ||
end | end | ||
end | end | ||
end | end | ||
function Protection:isProtected() | function Protection:isProtected() | ||
return self.level ~= '*' | return self.level ~= '*' | ||
end | end | ||
function Protection:makeProtectionCategory() | function Protection:makeProtectionCategory() | ||
if not self: | local cfg = self._cfg | ||
local title = self.title | |||
-- Exit if the page is not protected. | |||
if not self:isProtected() then | |||
return '' | return '' | ||
end | end | ||
-- Get the expiry | -- Get the expiry. | ||
local | local expiry = self.expiry | ||
if | if type(expiry) == 'number' then | ||
expiry = 'temp' | |||
elseif | elseif expiry ~= 'indef' then | ||
expiry = nil | |||
end | end | ||
-- Get the namespace key | -- Get the namespace category key. | ||
local | local nskey | ||
do | |||
local namespace = title.namespace | |||
local categoryNamespaces = cfg.categoryNamespaceKeys | |||
nskey = categoryNamespaces[namespace] | |||
if not nskey and namespace % 2 == 1 then | |||
nskey = 'talk' | |||
end | |||
end | end | ||
-- Define the | -- Get the other inputs. | ||
-- | local reason = self.reason | ||
-- | local action = self.action | ||
local | local level = self.level | ||
{ | |||
{ | --[[ | ||
{val = | -- Define the properties table. Each property is a table containing the | ||
{val = | -- canonical order that the property is tested in, the position the | ||
{val = | -- property has in the category key strings, and the property value itself. | ||
--]] | |||
local properties = { | |||
expiry = {order = 1, val = expiry}, | |||
namespace = {order = 2, val = nskey}, | |||
reason = {order = 3, val = reason}, | |||
level = {order = 4, val = level}, | |||
action = {order = 5, val = action} | |||
} | } | ||
--[[ | --[[ | ||
-- | -- Apply the category order configuration, if any. The configuration value | ||
-- | -- will be a property string, e.g. 'reason', 'namespace', etc. The property | ||
-- corresponding to that string is tested last (i.e. it is the most | |||
-- | -- important, because it keeps its specified value the longest) and the | ||
-- | -- other properties are tested in the canonical order. If no configuration | ||
-- value is specified then the canonical order is used. | |||
-- the | |||
-- | |||
--]] | --]] | ||
local configOrder = {} | |||
do | |||
local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority | |||
local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false | |||
for propertiesKey, t in pairs(properties) do | |||
configOrder[t.order] = t | |||
end | |||
if namespaceFirst then | |||
-- Swap namespace and reason around. | |||
local namespaceTable = table.remove(configOrder, 2) | |||
table.insert(configOrder, 3, namespaceTable) | |||
end | |||
end | |||
--[[ | --[[ | ||
-- Define the attempt order. | -- Define the attempt order. Properties with no value defined are moved | ||
-- | -- to the end, where they will later be given the value "all". This is | ||
-- to cut down on the number of table lookups in the cats table, which | |||
-- | -- grows exponentially with the number of properties with valid values. | ||
-- | -- We keep track of the number of active properties with the noActive | ||
-- | -- parameter. | ||
--]] | --]] | ||
local noActive, attemptOrder | local noActive, attemptOrder | ||
do | do | ||
local active, inactive = {}, {} | local active, inactive = {}, {} | ||
for i, t in ipairs( | for i, t in ipairs(configOrder) do | ||
if t.val then | if t.val then | ||
active[#active + 1] = t | active[#active + 1] = t | ||
267번째 줄: | 246번째 줄: | ||
--[[ | --[[ | ||
-- Check increasingly generic key combinations until we find a match. | -- Check increasingly generic key combinations until we find a match. | ||
-- specific category exists for the combination of | -- If a specific category exists for the combination of properties | ||
-- given, that match will be found first. If not, we keep | -- we are given, that match will be found first. If not, we keep | ||
-- key | -- trying different key combinations until we match using the key | ||
-- "all-all-all-all-all". | -- "all-all-all-all-all". | ||
-- | -- | ||
-- To generate the keys, we index the | -- To generate the keys, we index the property subtables using a | ||
-- with indexes i and j. j is only calculated up to the number of active | -- binary matrix with indexes i and j. j is only calculated up to | ||
-- the number of active properties. For example, if there were three | |||
-- active properties, the matrix would look like this, with 0 | |||
-- | -- corresponding to the string "all", and 1 corresponding to the | ||
-- val field in the property table: | |||
-- | -- | ||
-- j 1 2 3 | -- j 1 2 3 | ||
290번째 줄: | 270번째 줄: | ||
-- 8 0 0 0 | -- 8 0 0 0 | ||
-- | -- | ||
-- Values of j higher than the number of active | -- Values of j higher than the number of active properties are set | ||
-- to the string "all". | -- to the string "all". | ||
-- | -- | ||
-- A key for | -- A key for the category table is constructed for each value of i. | ||
-- The position of the value in the key is determined by the | -- The correct position of the value in the key is determined by the | ||
-- | -- pos field in the property table. | ||
--]] | --]] | ||
local cats = cfg.protectionCategories | local cats = cfg.protectionCategories | ||
302번째 줄: | 282번째 줄: | ||
for j, t in ipairs(attemptOrder) do | for j, t in ipairs(attemptOrder) do | ||
if j > noActive then | if j > noActive then | ||
key[t. | key[t.order] = 'all' | ||
else | else | ||
local quotient = i / 2 ^ (j - 1) | local quotient = i / 2 ^ (j - 1) | ||
quotient = math.ceil(quotient) | quotient = math.ceil(quotient) | ||
if quotient % 2 == 1 then | if quotient % 2 == 1 then | ||
key[t. | key[t.order] = t.val | ||
else | else | ||
key[t. | key[t.order] = 'all' | ||
end | end | ||
end | end | ||
end | end | ||
key = table.concat(key, ' | key = table.concat(key, '-') | ||
local attempt = cats[key] | local attempt = cats[key] | ||
if attempt then | if attempt then | ||
return makeCategoryLink(attempt | return makeCategoryLink(attempt) | ||
end | end | ||
end | end | ||
end | end | ||
function Protection: | function Protection:makeExpiryCategory() | ||
local cfg = self._cfg | |||
if not self.expiry | |||
and cfg.expiryCheckActions[self.action] | |||
and self.reason -- the old {{pp-protected}} didn't check for expiry | |||
and not cfg.reasonsWithoutExpiryCheck[self.reason] | |||
then | |||
return makeCategoryLink(self._cfg.msg['tracking-category-expiry']) | |||
end | |||
end | |||
function Protection:makeErrorCategory() | |||
local expiry = self.expiry | local expiry = self.expiry | ||
if not self:isProtected() | |||
or type(expiry) == 'number' and expiry < os.time() | or type(expiry) == 'number' and expiry < os.time() | ||
then | |||
return makeCategoryLink(self._cfg.msg['tracking-category-incorrect']) | |||
end | |||
end | end | ||
function Protection: | function Protection:makeTemplateCategory() | ||
local action, namespace = self.action, self.title.namespace | local action, namespace = self.action, self.title.namespace | ||
if self.level == 'templateeditor' | |||
and ( | and ( | ||
(action ~= 'edit' and action ~= 'move') | (action ~= 'edit' and action ~= 'move') | ||
or (namespace ~= 10 and namespace ~= 828) | or (namespace ~= 10 and namespace ~= 828) | ||
) | ) | ||
then | |||
return makeCategoryLink(self._cfg.msg['tracking-category-template']) | |||
end | end | ||
end | end | ||
359번째 줄: | 337번째 줄: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local Blurb = | local Blurb = class('Blurb') | ||
Blurb. | function Blurb:initialize(protectionObj, cfg) | ||
self._cfg = cfg | |||
self._protectionObj = protectionObj | |||
self._bannerConfig = protectionObj.bannerConfig | |||
self._title = protectionObj.title | |||
end | |||
-- Static methods -- | |||
function Blurb. | function Blurb.makeFullUrl(page, query, display) | ||
return | return string.format( | ||
'[%s %s]', | |||
tostring(mw.uri.fullUrl(page, query)), | |||
display | |||
) | |||
end | end | ||
function Blurb.formatDate(num) | |||
function Blurb | |||
-- 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.language.getContentLanguage() | ||
386번째 줄: | 362번째 줄: | ||
lang.formatDate, | lang.formatDate, | ||
lang, | lang, | ||
'j F Y', | |||
'@' .. tostring(num) | '@' .. tostring(num) | ||
) | ) | ||
393번째 줄: | 369번째 줄: | ||
end | end | ||
end | end | ||
-- Private methods -- | |||
function Blurb:_getExpandedMessage(msgKey) | function Blurb:_getExpandedMessage(msgKey) | ||
400번째 줄: | 378번째 줄: | ||
function Blurb:_substituteParameters(msg) | function Blurb:_substituteParameters(msg) | ||
if not self._params then | if not self._params then | ||
local parameterFuncs = {} | local params, parameterFuncs = {}, {} | ||
setmetatable(params, { | |||
__index = function (t, k) | |||
local param | |||
if parameterFuncs[k] then | |||
param = parameterFuncs[k](self) | |||
end | |||
param = param or '' | |||
params[k] = param | |||
return param | |||
end | |||
}) | |||
parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter | parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter | ||
parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter | |||
parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter | |||
parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter | |||
parameterFuncs.EDITREQUEST = self._makeEditRequestParameter | parameterFuncs.EDITREQUEST = self._makeEditRequestParameter | ||
parameterFuncs.EXPIRY = self._makeExpiryParameter | parameterFuncs.EXPIRY = self._makeExpiryParameter | ||
408번째 줄: | 400번째 줄: | ||
parameterFuncs.IMAGELINK = self._makeImageLinkParameter | parameterFuncs.IMAGELINK = self._makeImageLinkParameter | ||
parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter | parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter | ||
parameterFuncs. | parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter | ||
parameterFuncs.PAGETYPE = self._makePagetypeParameter | parameterFuncs.PAGETYPE = self._makePagetypeParameter | ||
parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter | parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter | ||
414번째 줄: | 406번째 줄: | ||
parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter | parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter | ||
parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter | parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter | ||
parameterFuncs.RESETBLURB = self._makeResetBlurbParameter | |||
parameterFuncs.TALKPAGE = self._makeTalkPageParameter | parameterFuncs.TALKPAGE = self._makeTalkPageParameter | ||
parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter | parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter | ||
parameterFuncs.VANDAL = self._makeVandalTemplateParameter | parameterFuncs.VANDAL = self._makeVandalTemplateParameter | ||
self._params = | self._params = params | ||
end | end | ||
439번째 줄: | 421번째 줄: | ||
-- A link to the page history or the move log, depending on the kind of | -- A link to the page history or the move log, depending on the kind of | ||
-- protection. | -- protection. | ||
local | local action = self._protectionObj.action | ||
if | local pagename = self._title.prefixedText | ||
if action == 'move' then | |||
-- We need the move log link. | -- We need the move log link. | ||
return makeFullUrl( | return self.makeFullUrl( | ||
'Special:Log', | 'Special:Log', | ||
{type = 'move', page = pagename}, | {type = 'move', page = pagename}, | ||
449번째 줄: | 432번째 줄: | ||
else | else | ||
-- We need the history link. | -- We need the history link. | ||
return makeFullUrl( | return self.makeFullUrl( | ||
pagename, | pagename, | ||
{action = 'history'}, | {action = 'history'}, | ||
self:_getExpandedMessage('current-version-edit-display') | self:_getExpandedMessage('current-version-edit-display') | ||
) | ) | ||
end | |||
end | |||
function Blurb:_makeDeletionDiscussionLinkParameter() | |||
local deletionDiscussionPage = self._deletionDiscussionPage | |||
if deletionDiscussionPage then | |||
local display = self:_getExpandedMessage('deletion-discussion-link-display') | |||
return string.format('[[%s|%s]]', deletionDiscussionPage, display) | |||
end | |||
end | |||
function Blurb:_makeDisputeBlurbParameter() | |||
local expiry = self._protectionObj.expiry | |||
if type(expiry) == 'number' then | |||
return self:_getExpandedMessage('dispute-blurb-expiry') | |||
else | |||
return self:_getExpandedMessage('dispute-blurb-noexpiry') | |||
end | |||
end | |||
function Blurb:_makeDisputeSectionParameter() | |||
-- "disputes", with or without a section link | |||
local section = self._section | |||
local disputes = self:_getExpandedMessage('dispute-section-link-display') | |||
if section then | |||
return string.format( | |||
'[[%s:%s#%s|%s]]', | |||
mw.site.namespaces[self._title.namespace].talk.name, | |||
self._title.text, | |||
section, | |||
disputes | |||
) | |||
else | |||
return disputes | |||
end | end | ||
end | end | ||
461번째 줄: | 478번째 줄: | ||
local action = self._protectionObj.action | local action = self._protectionObj.action | ||
local level = self._protectionObj.level | local level = self._protectionObj.level | ||
-- Get the display message key. | |||
local key | |||
if action == 'edit' and level == 'autoconfirmed' then | |||
key = 'edit-request-semi-display' | |||
else | |||
key = 'edit-request-full-display' | |||
end | |||
local display = self:_getExpandedMessage(key) | |||
-- Get the edit request type. | -- Get the edit request type. | ||
467번째 줄: | 493번째 줄: | ||
if level == 'autoconfirmed' then | if level == 'autoconfirmed' then | ||
requestType = 'semi' | requestType = 'semi' | ||
elseif level == 'templateeditor' then | elseif level == 'templateeditor' then | ||
requestType = 'template' | requestType = 'template' | ||
475번째 줄: | 499번째 줄: | ||
requestType = requestType or 'full' | requestType = requestType or 'full' | ||
return mEditRequest.exportLinkToLua{type = requestType, display = display} | |||
return mEditRequest. | |||
end | end | ||
function Blurb:_makeExpiryParameter() | function Blurb:_makeExpiryParameter() | ||
local expiry = self._protectionObj.expiry | local expiry = self._protectionObj.expiry | ||
if type(expiry) == 'number' then | if expiry == 'indef' then | ||
return | return nil | ||
elseif type(expiry) == 'number' then | |||
return Blurb.formatDate(expiry) | |||
elseif expiry then | |||
-- Expiry is an error string. | |||
return expiry | return expiry | ||
end | end | ||
491번째 줄: | 515번째 줄: | ||
function Blurb:_makeExplanationBlurbParameter() | function Blurb:_makeExplanationBlurbParameter() | ||
local action = self._protectionObj.action | local action = self._protectionObj.action | ||
local level = self._protectionObj.level | local level = self._protectionObj.level | ||
local | local namespace = self._title.namespace | ||
local isTalk = self._title.isTalkPage | |||
-- | -- @TODO: add semi-protection and pending changes blurbs | ||
-- | local key | ||
if namespace == 8 then | |||
-- MediaWiki namespace | |||
key = 'explanation-blurb-full-nounprotect' | |||
elseif action == 'edit' and level == 'sysop' and not isTalk then | |||
elseif | key = 'explanation-blurb-full-subject' | ||
elseif action == 'move' then | |||
elseif | if isTalk then | ||
key = 'explanation-blurb-move-talk' | |||
else | |||
key = 'explanation-blurb-move-subject' | |||
end | |||
elseif action == 'create' then | |||
local xfd = self._deletionDiscussion | |||
if xfd then | |||
key = 'explanation-blurb-create-xfd' | |||
else | |||
key = 'explanation-blurb-create-noxfd' | |||
end | |||
else | else | ||
key = 'explanation-blurb-default' | |||
end | end | ||
return self: | return self:_getExpandedMessage(key) | ||
end | end | ||
541번째 줄: | 562번째 줄: | ||
function Blurb:_makeIntroBlurbParameter() | function Blurb:_makeIntroBlurbParameter() | ||
local expiry = self._protectionObj.expiry | |||
if type(expiry) == 'number' then | |||
return self:_getExpandedMessage('intro-blurb-expiry') | return self:_getExpandedMessage('intro-blurb-expiry') | ||
else | else | ||
548번째 줄: | 570번째 줄: | ||
end | end | ||
function Blurb: | function Blurb:_makeOfficeBlurbParameter() | ||
local protectionDate = self._protectionObj.protectionDate | |||
return self:_getExpandedMessage(' | if protectionDate then | ||
return self:_getExpandedMessage('office-blurb-protectiondate') | |||
else | else | ||
return self:_getExpandedMessage(' | return self:_getExpandedMessage('office-blurb-noprotectiondate') | ||
end | end | ||
end | end | ||
558번째 줄: | 581번째 줄: | ||
function Blurb:_makePagetypeParameter() | function Blurb:_makePagetypeParameter() | ||
local pagetypes = self._cfg.pagetypes | local pagetypes = self._cfg.pagetypes | ||
return pagetypes[ | local namespace = self._title.namespace | ||
return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') | |||
end | end | ||
575번째 줄: | 597번째 줄: | ||
msg = protectionBlurbs.edit.default | msg = protectionBlurbs.edit.default | ||
else | else | ||
error('no protection blurb defined for protectionBlurbs.edit.default' | error('no protection blurb defined for protectionBlurbs.edit.default') | ||
end | end | ||
return self:_substituteParameters(msg) | return self:_substituteParameters(msg) | ||
583번째 줄: | 605번째 줄: | ||
local protectionDate = self._protectionObj.protectionDate | local protectionDate = self._protectionObj.protectionDate | ||
if type(protectionDate) == 'number' then | if type(protectionDate) == 'number' then | ||
return | return Blurb.formatDate(protectionDate) | ||
else | else | ||
return protectionDate | return protectionDate | ||
601번째 줄: | 623번째 줄: | ||
msg = protectionLevels.edit.default | msg = protectionLevels.edit.default | ||
else | else | ||
error('no protection level defined for protectionLevels.edit.default' | error('no protection level defined for protectionLevels.edit.default') | ||
end | end | ||
return self:_substituteParameters(msg) | return self:_substituteParameters(msg) | ||
607번째 줄: | 629번째 줄: | ||
function Blurb:_makeProtectionLogParameter() | function Blurb:_makeProtectionLogParameter() | ||
local | local action = self._protectionObj.action | ||
if | local pagename = self._title.prefixedText | ||
if action == 'autoreview' then | |||
-- We need the pending changes log. | -- We need the pending changes log. | ||
return makeFullUrl( | return self.makeFullUrl( | ||
'Special:Log', | 'Special:Log', | ||
{type = 'stable', page = pagename}, | {type = 'stable', page = pagename}, | ||
617번째 줄: | 640번째 줄: | ||
else | else | ||
-- We need the protection log. | -- We need the protection log. | ||
return makeFullUrl( | return self.makeFullUrl( | ||
'Special:Log', | 'Special:Log', | ||
{type = 'protect', page = pagename}, | {type = 'protect', page = pagename}, | ||
self:_getExpandedMessage('protection-log-display') | self:_getExpandedMessage('protection-log-display') | ||
) | ) | ||
end | |||
end | |||
function Blurb:_makeResetBlurbParameter() | |||
local protectionDate = self._protectionObj.protectionDate | |||
if protectionDate then | |||
return self:_getExpandedMessage('reset-blurb-protectiondate') | |||
else | |||
return self:_getExpandedMessage('reset-blurb-noprotectiondate') | |||
end | end | ||
end | end | ||
function Blurb:_makeTalkPageParameter() | function Blurb:_makeTalkPageParameter() | ||
local section = self._section | |||
local display = self:_getExpandedMessage('talk-page-link-display') | |||
return string.format( | return string.format( | ||
'[[%s:%s#%s|%s]]', | '[[%s:%s#%s|%s]]', | ||
mw.site.namespaces[self. | mw.site.namespaces[self._title.namespace].talk.name, | ||
self. | self._title.text, | ||
section or 'top', | |||
display | |||
) | ) | ||
end | end | ||
function Blurb:_makeTooltipBlurbParameter() | function Blurb:_makeTooltipBlurbParameter() | ||
local expiry = self._protectionObj.expiry | |||
if type(expiry) == 'number' then | |||
return self:_getExpandedMessage('tooltip-blurb-expiry') | return self:_getExpandedMessage('tooltip-blurb-expiry') | ||
else | else | ||
643번째 줄: | 678번째 줄: | ||
end | end | ||
function Blurb: | function Blurb:_makeVandalTemplateParameter() | ||
local mVandalM = require('Module:Vandal-m') | |||
local username = self._username | |||
username = username or self._title.baseText | |||
return mVandalM._main{username} | |||
end | end | ||
function Blurb: | -- Public methods -- | ||
function Blurb:setDeletionDiscussionPage(page) | |||
self._deletionDiscussionPage = page | |||
end | end | ||
function Blurb:setUsername(username) | |||
self._username = username | |||
end | |||
function Blurb: | function Blurb:setSection(section) | ||
self._section = section | |||
end | |||
function Blurb:makeReasonText() | |||
local msg = self._bannerConfig.text | |||
if msg then | |||
return self:_substituteParameters(msg) | return self:_substituteParameters(msg) | ||
end | end | ||
end | |||
function Blurb:makeExplanationText() | |||
local msg = self._bannerConfig.explanation | |||
return self:_substituteParameters(msg) | |||
end | |||
function Blurb:makeTooltipText() | |||
local msg = self._bannerConfig.tooltip | |||
return self:_substituteParameters(msg) | |||
end | |||
function Blurb:makeAltText() | |||
local msg = self._bannerConfig.alt | |||
return self:_substituteParameters(msg) | |||
end | |||
function Blurb:makeLinkText() | |||
local msg = self._bannerConfig.link | |||
return self:_substituteParameters(msg) | |||
end | end | ||
691번째 줄: | 730번째 줄: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local BannerTemplate = | local BannerTemplate = class('BannerTemplate') | ||
function BannerTemplate | function BannerTemplate:initialize(cfg) | ||
self._cfg = cfg | |||
end | |||
function BannerTemplate:setImageFilename(filename, protectionObj) | |||
if filename then | |||
if | self._imageFilename = filename | ||
return nil | |||
end | |||
local action = protectionObj.action | |||
local level = protectionObj.level | |||
local expiry = protectionObj.expiry | |||
local namespace = protectionObj.title.namespace | |||
-- Deal with special cases first. | |||
if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? | |||
and action == 'edit' | |||
and level == 'sysop' | |||
and not expiry | |||
then | |||
-- Fully protected modules and templates get the special red "indef" | |||
-- padlock. | |||
self._imageFilename = self._cfg.msg['image-filename-indef'] | |||
return nil | |||
end | |||
-- Deal with regular protection types. | |||
local images = self._cfg.images | |||
if images[action] then | |||
if images[action][level] then | |||
self._imageFilename = images[action][level] | |||
return nil | |||
elseif images[action].default then | |||
self._imageFilename = images[action].default | |||
return nil | |||
end | end | ||
end | end | ||
return | |||
return nil | |||
end | |||
function BannerTemplate:setImageWidth(width) | |||
self._imageWidth = width | |||
end | |||
function BannerTemplate:setImageTooltip(tooltip) | |||
self._imageCaption = tooltip | |||
end | end | ||
742번째 줄: | 786번째 줄: | ||
or self._cfg.msg['image-filename-default'] | or self._cfg.msg['image-filename-default'] | ||
or 'Transparent.gif' | or 'Transparent.gif' | ||
return | return newFileLink(filename) | ||
:width(self._imageWidth or 20) | |||
:alt(self._imageAlt) | |||
alt | :link(self._imageLink) | ||
link | :caption(self._imageCaption) | ||
caption | :render() | ||
end | end | ||
755번째 줄: | 798번째 줄: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local Banner = | local Banner = BannerTemplate:subclass('Banner') | ||
Banner. | |||
function Banner:initialize(cfg) | |||
BannerTemplate.initialize(self, cfg) | |||
self:setImageWidth(40) | |||
end | |||
function Banner | function Banner:setReasonText(s) | ||
self._reasonText = s | |||
end | |||
function Banner:setExplanationText(s) | |||
self._explanationText = s | |||
end | |||
function Banner:setPage(s) | |||
-- This specifies the page to generate the banner for. This only affects | |||
-- Module:Message box if the page specified is not the current page. | |||
self._page = s | |||
end | end | ||
771번째 줄: | 822번째 줄: | ||
-- 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('no reason text set' | local reasonText = self._reasonText or error('no reason text set') | ||
local explanationText = self._explanationText | local explanationText = self._explanationText | ||
local mbargs = { | local mbargs = { | ||
790번째 줄: | 841번째 줄: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local Padlock = | local Padlock = BannerTemplate:subclass('Padlock') | ||
Padlock. | |||
function Padlock:initialize(cfg) | |||
BannerTemplate.initialize(self, cfg) | |||
self:setImageWidth(20) | |||
end | |||
function Padlock:setImageAlt(alt) | |||
self._imageAlt = alt | |||
end | |||
function Padlock:setImageLink(link) | |||
self._imageLink = link | |||
end | |||
function Padlock | function Padlock:setRight(px) | ||
self._right = px | |||
end | end | ||
function Padlock:__tostring() | function Padlock:__tostring() | ||
local | local root = mw.html.create('div') | ||
root | |||
:addClass('metadata topicon nopopups') | |||
:attr('id', 'protected-icon') | |||
:css{display = 'none', right = self._right or '55px'} | |||
:wikitext(self:renderImage()) | |||
return tostring(root) | |||
end | end | ||
832번째 줄: | 887번째 줄: | ||
end | end | ||
function p._main(args, cfg | function p._main(args, cfg) | ||
if not cfg then | |||
cfg = mw.loadData('Module:Protection banner/config') | |||
end | |||
local protectionObj = Protection | -- Initialise protection and blurb objects | ||
local protectionObj = Protection:new(args, cfg) | |||
local blurbObj = Blurb:new(protectionObj, cfg) | |||
blurbObj:setDeletionDiscussionPage(args.xfd) | |||
blurbObj:setUsername(args.user) | |||
blurbObj:setSection(args.section) | |||
local ret = {} | local ret = {} | ||
-- | -- Render the banner | ||
if protectionObj:isProtected() then | |||
-- Get the banner object | |||
local bannerObj | |||
if yesno(args.small) then | |||
bannerObj = Padlock:new(cfg) | |||
bannerObj:setImageTooltip(blurbObj:makeTooltipText()) | |||
bannerObj:setImageAlt(blurbObj:makeAltText()) | |||
bannerObj:setImageLink(blurbObj:makeLinkText()) | |||
else | |||
bannerObj = Banner:new(cfg) | |||
-- Large banners use the alt text for the tooltip. | |||
bannerObj:setImageTooltip(blurbObj:makeAltText()) | |||
-- Set the text fields and the page name. | |||
bannerObj:setReasonText(blurbObj:makeReasonText()) | |||
bannerObj:setExplanationText(blurbObj:makeExplanationText()) | |||
bannerObj:setPage(protectionObj.title.prefixedText) | |||
) | |||
end | end | ||
-- Set the image fields | |||
local bannerConfig = protectionObj.bannerConfig | |||
bannerObj:setImageFilename(bannerConfig.image, protectionObj) | |||
ret[#ret + 1] = tostring(bannerObj) | |||
end | end | ||
-- Render the categories | -- Render the categories | ||
if yesno(args.category) ~= false then | if yesno(args.category) ~= false then | ||
ret[#ret + 1] = protectionObj: | ret[#ret + 1] = protectionObj:makeProtectionCategory() | ||
ret[#ret + 1] = protectionObj:makeExpiryCategory() | |||
ret[#ret + 1] = protectionObj:makeErrorCategory() | |||
ret[#ret + 1] = protectionObj:makeTemplateCategory() | |||
end | end | ||
870번째 줄: | 937번째 줄: | ||
end | end | ||
function p.main(frame | function p.main(frame) | ||
if not getArgs then | |||
getArgs = require('Module:Arguments').getArgs | |||
end | end | ||
return p._main( | return p._main(getArgs(frame)) | ||
end | end | ||
return p | return p |