en>Jackmcbarn |
en>Frietjes |
Line 1: |
Line 1: |
| -- This module implements {{pp-meta}} and its daughter templates such as | | -- This implements {{navbox top}} and {{navbox bottom}} |
| -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}.
| | local p = {} |
| | |
| -- Initialise necessary modules.
| |
| require('Module:No globals')
| |
| local class = require('Module:Middleclass').class
| |
| local newFileLink = require('Module:File link').new
| |
| local effectiveProtectionLevel = require('Module:Effective protection level')._main
| |
| local yesno = require('Module:Yesno')
| |
| | |
| -- Lazily initialise modules and objects we don't always need.
| |
| local getArgs, makeMessageBox, lang
| |
| | |
| --------------------------------------------------------------------------------
| |
| -- Helper functions
| |
| --------------------------------------------------------------------------------
| |
| | |
| local function makeCategoryLink(cat)
| |
| if cat then
| |
| return string.format(
| |
| '[[%s:%s]]',
| |
| mw.site.namespaces[14].name,
| |
| cat
| |
| )
| |
| else
| |
| return ''
| |
| end
| |
| end
| |
| | |
| -- Validation function for the expiry and the protection date
| |
| local function validateDate(dateString, dateType)
| |
| lang = lang or mw.language.getContentLanguage()
| |
| local success, result = pcall(lang.formatDate, lang, 'U', dateString)
| |
| if success then
| |
| result = tonumber(result)
| |
| if result then
| |
| return result
| |
| end
| |
| end
| |
| error(string.format(
| |
| 'invalid %s ("%s")',
| |
| dateType,
| |
| tostring(dateString)
| |
| ))
| |
| end
| |
| | |
| --------------------------------------------------------------------------------
| |
| -- Protection class
| |
| --------------------------------------------------------------------------------
| |
| | |
| local Protection = class('Protection') | |
| | |
| Protection.supportedActions = {
| |
| create = true,
| |
| edit = true,
| |
| move = true,
| |
| autoreview = true
| |
| }
| |
| | |
| Protection.bannerConfigFields = {
| |
| 'text',
| |
| 'explanation',
| |
| 'tooltip',
| |
| 'alt',
| |
| 'link',
| |
| 'image'
| |
| } | |
| | |
| 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
| |
| 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
| |
| | |
| -- 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
| |
| | |
| -- 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
| |
| | |
| -- Set reason
| |
| do
| |
| local reason = args.reason or args[1]
| |
| if reason then
| |
| self.reason = reason:lower()
| |
| end
| |
| end
| |
| | |
| -- Set protection date
| |
| self.protectionDate = validateDate(args.date, 'protection date')
| |
|
| |
| -- Set banner config
| |
| do
| |
| self.bannerConfig = {}
| |
| local configTables = {}
| |
| if cfg.banners[self.action] then
| |
| configTables[#configTables + 1] = cfg.banners[self.action][self.reason]
| |
| end
| |
| if cfg.defaultBanners[self.action] then
| |
| configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level]
| |
| configTables[#configTables + 1] = cfg.defaultBanners[self.action].default
| |
| end
| |
| configTables[#configTables + 1] = cfg.masterBanner
| |
| for i, field in ipairs(self.bannerConfigFields) do
| |
| for j, t in ipairs(configTables) do
| |
| if t[field] then
| |
| self.bannerConfig[field] = t[field]
| |
| break
| |
| end
| |
| end
| |
| end
| |
| end
| |
| end
| |
| | |
| function Protection:isProtected()
| |
| return self.level ~= '*'
| |
| end
| |
| | |
| function Protection:makeProtectionCategory()
| |
| local cfg = self._cfg
| |
| local title = self.title
| |
|
| |
| -- Exit if the page is not protected.
| |
| if not self:isProtected() then
| |
| return ''
| |
| end
| |
|
| |
| -- Get the expiry.
| |
| local expiry = self.expiry
| |
| if type(expiry) == 'number' then
| |
| expiry = 'temp'
| |
| elseif expiry ~= 'indef' then
| |
| expiry = nil
| |
| end
| |
| | |
| -- Get the namespace category key.
| |
| 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
| |
| | |
| -- Get the other inputs.
| |
| local reason = self.reason
| |
| local action = self.action
| |
| local level = self.level
| |
|
| |
| --[[
| |
| -- Define the properties table. Each property is a table containing the
| |
| -- canonical order that the property is tested in, the position the
| |
| -- 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.
| |
| --]]
| |
| 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. 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
| |
| do
| |
| local active, inactive = {}, {}
| |
| for i, t in ipairs(configOrder) do
| |
| if t.val then
| |
| active[#active + 1] = t
| |
| else
| |
| inactive[#inactive + 1] = t
| |
| end
| |
| end
| |
| noActive = #active
| |
| attemptOrder = active
| |
| for i, t in ipairs(inactive) do
| |
| attemptOrder[#attemptOrder + 1] = t
| |
| end
| |
| end
| |
|
| |
| --[[
| |
| -- Check increasingly generic key combinations until we find a match.
| |
| -- If a specific category exists for the combination of properties
| |
| -- we are given, that match will be found first. If not, we keep
| |
| -- trying different key combinations until we match using the key
| |
| -- "all-all-all-all-all".
| |
| --
| |
| -- To generate the keys, we index the property subtables using a
| |
| -- 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
| |
| -- i
| |
| -- 1 1 1 1
| |
| -- 2 0 1 1
| |
| -- 3 1 0 1
| |
| -- 4 0 0 1
| |
| -- 5 1 1 0
| |
| -- 6 0 1 0
| |
| -- 7 1 0 0
| |
| -- 8 0 0 0
| |
| --
| |
| -- Values of j higher than the number of active properties are set
| |
| -- to the string "all".
| |
| --
| |
| -- A key for the category table is constructed for each value of i.
| |
| -- The correct position of the value in the key is determined by the
| |
| -- pos field in the property table.
| |
| --]]
| |
| local cats = cfg.protectionCategories
| |
| for i = 1, 2^noActive do
| |
| local key = {}
| |
| for j, t in ipairs(attemptOrder) do
| |
| if j > noActive then
| |
| key[t.order] = 'all'
| |
| else
| |
| local quotient = i / 2 ^ (j - 1)
| |
| quotient = math.ceil(quotient)
| |
| if quotient % 2 == 1 then
| |
| key[t.order] = t.val
| |
| else
| |
| key[t.order] = 'all'
| |
| end
| |
| end
| |
| end
| |
| key = table.concat(key, '-')
| |
| local attempt = cats[key]
| |
| if attempt then
| |
| return makeCategoryLink(attempt)
| |
| end
| |
| end
| |
| end
| |
| | |
| 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 function build_navbox(parentArgs, list) |
| local expiry = self.expiry | | local args = {} |
| if not self:isProtected()
| | for argName, value in pairs(parentArgs) do |
| or type(expiry) == 'number' and expiry < os.time()
| | if value ~= '' then |
| then
| | if type(argName) == 'string' then |
| return makeCategoryLink(self._cfg.msg['tracking-category-incorrect'])
| | -- shift list numbers by 1 |
| end
| | if argName:find('^list[%d]+') then |
| end | | local k = mw.ustring.gsub(argName,'^list([^%d]+)', '%1') |
| | argName = mw.ustring.gsub(argName,'^list[%d]+', 'list' .. (tonumber(k) + 1)) |
| | end |
| | args[argName] = value |
| | end |
| | end |
| | end |
| | args['list1padding'] = '0' |
| | args['list1'] = list |
| | -- Note Navbox.navbox() has a kludge to order the parent frame's args |
| | -- into a specific order. For now, this is omitted from this module. |
|
| |
|
| function Protection:makeTemplateCategory()
| | local Navbox = require('Module:Navbox') |
| local action, namespace = self.action, self.title.namespace | | return Navbox._navbox(args) |
| if self.level == 'templateeditor'
| |
| and (
| |
| (action ~= 'edit' and action ~= 'move')
| |
| or (namespace ~= 10 and namespace ~= 828)
| |
| )
| |
| then
| |
| return makeCategoryLink(self._cfg.msg['tracking-category-template'])
| |
| end
| |
| end | | end |
|
| |
|
| --------------------------------------------------------------------------------
| | function p.top(frame) |
| -- Blurb class
| | local args = frame:getParent().args |
| --------------------------------------------------------------------------------
| | local parts = mw.text.split(build_navbox(args, '<ADD LIST HERE>'), '<ADD LIST HERE>') |
| | | return parts[1] |
| local Blurb = class('Blurb')
| |
| | |
| function Blurb:initialize(protectionObj, args, cfg) | |
| self._cfg = cfg
| |
| self._protectionObj = protectionObj
| |
| self._bannerConfig = protectionObj.bannerConfig
| |
| self._title = protectionObj.title
| |
| self._deletionDiscussionPage = args.xfd
| |
| self._username = args.user
| |
| self._section = args.section
| |
| end
| |
| | |
| -- Static methods --
| |
| | |
| function Blurb.makeFullUrl(page, query, display)
| |
| return string.format(
| |
| '[%s %s]',
| |
| tostring(mw.uri.fullUrl(page, query)),
| |
| display
| |
| )
| |
| end
| |
| | |
| function Blurb.formatDate(num)
| |
| -- Formats a Unix timestamp into dd Month, YYYY format.
| |
| lang = lang or mw.language.getContentLanguage()
| |
| local success, date = pcall( | |
| lang.formatDate,
| |
| lang,
| |
| 'j F Y',
| |
| '@' .. tostring(num)
| |
| )
| |
| if success then
| |
| return date
| |
| end
| |
| end
| |
| | |
| -- Private methods --
| |
| | |
| function Blurb:_getExpandedMessage(msgKey)
| |
| return self:_substituteParameters(self._cfg.msg[msgKey])
| |
| end
| |
| | |
| function Blurb:_substituteParameters(msg)
| |
| if not self._params then
| |
| 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.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter
| |
| parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter
| |
| parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter
| |
| parameterFuncs.EDITREQUEST = self._makeEditRequestParameter
| |
| parameterFuncs.EXPIRY = self._makeExpiryParameter
| |
| parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter
| |
| parameterFuncs.IMAGELINK = self._makeImageLinkParameter
| |
| parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter
| |
| parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter
| |
| parameterFuncs.PAGETYPE = self._makePagetypeParameter
| |
| parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter
| |
| parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter
| |
| parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter
| |
| parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter
| |
| parameterFuncs.RESETBLURB = self._makeResetBlurbParameter
| |
| parameterFuncs.TALKPAGE = self._makeTalkPageParameter
| |
| parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter
| |
| parameterFuncs.VANDAL = self._makeVandalTemplateParameter
| |
|
| |
| self._params = params
| |
| end
| |
|
| |
| msg = msg:gsub('${(%u+)}', self._params)
| |
| return msg
| |
| end
| |
| | |
| function Blurb:_makeCurrentVersionParameter()
| |
| -- A link to the page history or the move log, depending on the kind of
| |
| -- protection.
| |
| local action = self._protectionObj.action | |
| local pagename = self._title.prefixedText
| |
| if action == 'move' then
| |
| -- We need the move log link.
| |
| return self.makeFullUrl(
| |
| 'Special:Log',
| |
| {type = 'move', page = pagename},
| |
| self:_getExpandedMessage('current-version-move-display')
| |
| )
| |
| else
| |
| -- We need the history link.
| |
| return self.makeFullUrl(
| |
| pagename,
| |
| {action = 'history'},
| |
| 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
| |
| | |
| function Blurb:_makeEditRequestParameter()
| |
| local mEditRequest = require('Module:Submit an edit request')
| |
| local action = self._protectionObj.action
| |
| 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.
| |
| local requestType
| |
| if action == 'edit' then
| |
| if level == 'autoconfirmed' then
| |
| requestType = 'semi'
| |
| elseif level == 'templateeditor' then
| |
| requestType = 'template'
| |
| end
| |
| end
| |
| requestType = requestType or 'full'
| |
|
| |
| return mEditRequest.exportLinkToLua{type = requestType, display = display}
| |
| end
| |
| | |
| function Blurb:_makeExpiryParameter()
| |
| local expiry = self._protectionObj.expiry
| |
| if expiry == 'indef' then
| |
| return nil
| |
| elseif type(expiry) == 'number' then
| |
| return Blurb.formatDate(expiry)
| |
| elseif expiry then
| |
| -- Expiry is an error string.
| |
| return expiry
| |
| end
| |
| end
| |
| | |
| function Blurb:_makeExplanationBlurbParameter()
| |
| local action = self._protectionObj.action
| |
| local level = self._protectionObj.level
| |
| 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
| |
| key = 'explanation-blurb-full-subject'
| |
| elseif action == 'move' then
| |
| 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
| |
| key = 'explanation-blurb-default'
| |
| end
| |
| return self:_getExpandedMessage(key)
| |
| end
| |
| | |
| function Blurb:_makeImageLinkParameter()
| |
| local imageLinks = self._cfg.imageLinks
| |
| local action = self._protectionObj.action
| |
| local level = self._protectionObj.level
| |
| local msg
| |
| if imageLinks[action][level] then
| |
| msg = imageLinks[action][level]
| |
| elseif imageLinks[action].default then
| |
| msg = imageLinks[action].default
| |
| else
| |
| msg = imageLinks.edit.default
| |
| end
| |
| return self:_substituteParameters(msg)
| |
| end
| |
| | |
| function Blurb:_makeIntroBlurbParameter()
| |
| local expiry = self._protectionObj.expiry
| |
| if type(expiry) == 'number' then
| |
| return self:_getExpandedMessage('intro-blurb-expiry')
| |
| else
| |
| return self:_getExpandedMessage('intro-blurb-noexpiry')
| |
| end
| |
| end
| |
| | |
| function Blurb:_makeOfficeBlurbParameter()
| |
| local protectionDate = self._protectionObj.protectionDate
| |
| if protectionDate then
| |
| return self:_getExpandedMessage('office-blurb-protectiondate')
| |
| else
| |
| return self:_getExpandedMessage('office-blurb-noprotectiondate')
| |
| end
| |
| end
| |
| | |
| function Blurb:_makePagetypeParameter()
| |
| local pagetypes = self._cfg.pagetypes
| |
| local namespace = self._title.namespace
| |
| return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined')
| |
| end
| |
| | |
| function Blurb:_makeProtectionBlurbParameter()
| |
| local protectionBlurbs = self._cfg.protectionBlurbs
| |
| local action = self._protectionObj.action
| |
| local level = self._protectionObj.level
| |
| local msg
| |
| if protectionBlurbs[action][level] then
| |
| msg = protectionBlurbs[action][level]
| |
| elseif protectionBlurbs[action].default then
| |
| msg = protectionBlurbs[action].default
| |
| elseif protectionBlurbs.edit.default then
| |
| msg = protectionBlurbs.edit.default
| |
| else
| |
| error('no protection blurb defined for protectionBlurbs.edit.default')
| |
| end
| |
| return self:_substituteParameters(msg)
| |
| end
| |
| | |
| function Blurb:_makeProtectionDateParameter()
| |
| local protectionDate = self._protectionObj.protectionDate
| |
| if type(protectionDate) == 'number' then
| |
| return Blurb.formatDate(protectionDate)
| |
| else
| |
| return protectionDate
| |
| end
| |
| end
| |
| | |
| function Blurb:_makeProtectionLevelParameter()
| |
| local protectionLevels = self._cfg.protectionLevels
| |
| local action = self._protectionObj.action
| |
| local level = self._protectionObj.level
| |
| local msg
| |
| if protectionLevels[action][level] then
| |
| msg = protectionLevels[action][level]
| |
| elseif protectionLevels[action].default then
| |
| msg = protectionLevels[action].default
| |
| elseif protectionLevels.edit.default then
| |
| msg = protectionLevels.edit.default
| |
| else
| |
| error('no protection level defined for protectionLevels.edit.default')
| |
| end
| |
| return self:_substituteParameters(msg)
| |
| end
| |
| | |
| function Blurb:_makeProtectionLogParameter()
| |
| local action = self._protectionObj.action
| |
| local pagename = self._title.prefixedText
| |
| if action == 'autoreview' then
| |
| -- We need the pending changes log.
| |
| return self.makeFullUrl(
| |
| 'Special:Log',
| |
| {type = 'stable', page = pagename},
| |
| self:_getExpandedMessage('pc-log-display')
| |
| )
| |
| else
| |
| -- We need the protection log.
| |
| return self.makeFullUrl(
| |
| 'Special:Log',
| |
| {type = 'protect', page = pagename},
| |
| 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
| |
| | |
| function Blurb:_makeTalkPageParameter()
| |
| local section = self._section
| |
| local display = self:_getExpandedMessage('talk-page-link-display')
| |
| return string.format(
| |
| '[[%s:%s#%s|%s]]',
| |
| mw.site.namespaces[self._title.namespace].talk.name,
| |
| self._title.text,
| |
| section or 'top',
| |
| display
| |
| )
| |
| end
| |
| | |
| function Blurb:_makeTooltipBlurbParameter()
| |
| local expiry = self._protectionObj.expiry
| |
| if type(expiry) == 'number' then
| |
| return self:_getExpandedMessage('tooltip-blurb-expiry')
| |
| else
| |
| return self:_getExpandedMessage('tooltip-blurb-noexpiry')
| |
| end
| |
| end
| |
| | |
| function Blurb:_makeVandalTemplateParameter()
| |
| local mVandalM = require('Module:Vandal-m')
| |
| local username = self._username
| |
| username = username or self._title.baseText
| |
| return mVandalM._main{username}
| |
| end
| |
| | |
| -- Public methods --
| |
| | |
| function Blurb:makeReasonText()
| |
| local msg = self._bannerConfig.text
| |
| if msg then
| |
| return self:_substituteParameters(msg)
| |
| 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
| |
| | |
| --------------------------------------------------------------------------------
| |
| -- BannerTemplate class
| |
| --------------------------------------------------------------------------------
| |
| | |
| local BannerTemplate = class('BannerTemplate')
| |
| | |
| function BannerTemplate:initialize(cfg)
| |
| self._cfg = cfg
| |
| end
| |
| | |
| function BannerTemplate:setImageFilename(filename, protectionObj)
| |
| if filename then
| |
| 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
| |
| | |
| return nil
| |
| end
| |
| | |
| function BannerTemplate:setImageWidth(width)
| |
| self._imageWidth = width
| |
| end
| |
| | |
| function BannerTemplate:setImageTooltip(tooltip)
| |
| self._imageCaption = tooltip
| |
| end
| |
| | |
| function BannerTemplate:renderImage()
| |
| local filename = self._imageFilename
| |
| or self._cfg.msg['image-filename-default']
| |
| or 'Transparent.gif'
| |
| return newFileLink(filename)
| |
| :width(self._imageWidth or 20)
| |
| :alt(self._imageAlt)
| |
| :link(self._imageLink)
| |
| :caption(self._imageCaption)
| |
| :render()
| |
| end
| |
| | |
| --------------------------------------------------------------------------------
| |
| -- Banner class
| |
| --------------------------------------------------------------------------------
| |
| | |
| local Banner = BannerTemplate:subclass('Banner')
| |
| | |
| function Banner:initialize(cfg)
| |
| BannerTemplate.initialize(self, cfg)
| |
| self:setImageWidth(40)
| |
| end
| |
| | |
| 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
| |
| | |
| function Banner:__tostring()
| |
| -- Renders the banner.
| |
| makeMessageBox = makeMessageBox or require('Module:Message box').main
| |
| local reasonText = self._reasonText or error('no reason text set')
| |
| local explanationText = self._explanationText
| |
| local mbargs = {
| |
| page = self._page,
| |
| type = 'protection',
| |
| image = self:renderImage(),
| |
| text = string.format(
| |
| "'''%s'''%s",
| |
| reasonText,
| |
| explanationText and '<br />' .. explanationText or ''
| |
| )
| |
| }
| |
| return makeMessageBox('mbox', mbargs) | |
| end
| |
| | |
| --------------------------------------------------------------------------------
| |
| -- Padlock class
| |
| --------------------------------------------------------------------------------
| |
| | |
| local Padlock = BannerTemplate:subclass('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:setRight(px)
| |
| self._right = px
| |
| end
| |
| | |
| function Padlock:__tostring()
| |
| 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
| |
| | |
| --------------------------------------------------------------------------------
| |
| -- Exports
| |
| --------------------------------------------------------------------------------
| |
| | |
| local p = {}
| |
| | |
| function p._exportClasses()
| |
| -- This is used for testing purposes.
| |
| return {
| |
| Protection = Protection,
| |
| Blurb = Blurb,
| |
| BannerTemplate = BannerTemplate,
| |
| Banner = Banner,
| |
| Padlock = Padlock,
| |
| }
| |
| end
| |
| | |
| function p._main(args, cfg)
| |
| if not cfg then
| |
| cfg = mw.loadData('Module:Protection banner/config')
| |
| end
| |
| | |
| -- Initialise protection and blurb objects
| |
| local protectionObj = Protection:new(args, cfg)
| |
| local blurbObj = Blurb:new(protectionObj, args, cfg)
| |
| | |
| 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
| |
| -- Set the image fields
| |
| local bannerConfig = protectionObj.bannerConfig
| |
| bannerObj:setImageFilename(bannerConfig.image, protectionObj)
| |
| | |
| ret[#ret + 1] = tostring(bannerObj)
| |
| end
| |
|
| |
| -- Render the categories
| |
| if yesno(args.category) ~= false then
| |
| ret[#ret + 1] = protectionObj:makeProtectionCategory()
| |
| ret[#ret + 1] = protectionObj:makeExpiryCategory()
| |
| ret[#ret + 1] = protectionObj:makeErrorCategory()
| |
| ret[#ret + 1] = protectionObj:makeTemplateCategory()
| |
| end
| |
|
| |
| return table.concat(ret)
| |
| end | | end |
|
| |
|
| function p.main(frame) | | function p.bottom(frame) |
| if not getArgs then | | local args = frame:getParent().args |
| getArgs = require('Module:Arguments').getArgs
| | local parts = mw.text.split(build_navbox(args, '<ADD LIST HERE>'), '<ADD LIST HERE>') |
| end | | return parts[2] |
| return p._main(getArgs(frame))
| |
| end | | end |
|
| |
|
| return p | | return p |