پودمان:Protection banner: تفاوت میان نسخه‌ها

۸۹۰ بایت اضافه‌شده ،  ‏۲۷ نوامبر ۲۰۱۸
جز
۱ نسخه واردشده
بدون خلاصۀ ویرایش
جز (۱ نسخه واردشده)
خط ۵: خط ۵:
-- Initialise necessary modules.
-- Initialise necessary modules.
require('Module:No globals')
require('Module:No globals')
local converter = require("Module:Numeral converter").convert
local convertString = require("Module:Numeral_converter").convert
local makeFileLink = require('Module:File link')._main
local newFileLink = require('Module:File link').new
local effectiveProtectionLevel = require('Module:Effective protection level')._main
local effectiveProtectionLevel = require('Module:Effective protection level')._main
local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main
local yesno = require('Module:Yesno')
local yesno = require('Module:Yesno')


خط ۱۷: خط ۱۶:
local CONFIG_MODULE = 'Module:Protection banner/config'
local CONFIG_MODULE = 'Module:Protection banner/config'


--------------------------------------------------------------------------------
-- خط زیر از پایین صفحه به بالا آورده شده‌است بخاطر تابع p.replacePersianGreMonthName()
-- Helper functions
local p = {}
--------------------------------------------------------------------------------


-- چون ممکنه نام ماه میلادی رو به فارسی کاربران بنویسند من این تابع رو تعریف کردم که به انگلیسی برگرداند تا خطای تاریخ نامعتبر ندهد.
-- چون ممکنه نام ماه میلادی رو به فارسی کاربران بنویسند من این تابع رو تعریف کردم که به انگلیسی برگرداند تا خطای تاریخ نامعتبر ندهد.
local function replacePersianGreMonthName(frame)
function p.replacePersianGreMonthName(frame)
getArgs = require('Module:Arguments').getArgs
getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame)
local args = getArgs(frame)
خط ۳۰: خط ۲۸:
args[1] = mw.ustring.gsub(args[1], v, greMonth[k])
args[1] = mw.ustring.gsub(args[1], v, greMonth[k])
end
end
return converter("en", args[1])
return convertString("en", args[1])
end
end
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------


-- از آنجا که تاریخ‌ها به صورت انگلیسی به پودمان داده می‌شوند، از mw.getLanguage('en') استفاده شده‌است
-- از آنجا که تاریخ‌ها به صورت انگلیسی به پودمان داده می‌شوند، از mw.getLanguage('en') استفاده شده‌است
خط ۴۶: خط ۴۸:


local function makeCategoryLink(cat, sort)
local function makeCategoryLink(cat, sort)
if cat then
local nsText = mw.site.namespaces[14].name
if cat and sort then
return string.format(
return string.format(
'[[%s:%s|%s]]',
'[[%s:%s|%s]]',
mw.site.namespaces[14].name,
nsText,
cat,
cat,
sort
sort
)
)
elseif cat then
return string.format(
'[[%s:%s]]',
nsText,
cat
)
else
return ''
end
end
end
end
خط ۵۸: خط ۶۹:
-- 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)
if not lang then
-- در خط زیر جای mw.language.getContentLanguage() از mw.getLanguage('en') استفاده کردم.
-- در خط زیر جای mw.language.getContentLanguage() از mw.getLanguage('en') استفاده کردم.
lang = lang or mw.getLanguage('en')
lang = mw.getLanguage('en')
local success, result = pcall(lang.formatDate, lang, 'U', p.replacePersianGreMonthName{convertString('en', dateString)})
end
local success, result = pcall(lang.formatDate, lang, 'U', converter('en', dateString))
if success then
if success then
result = tonumber(result)
result = tonumber(result)
خط ۷۰: خط ۷۹:
end
end
error(string.format(
error(string.format(
'%s نامعتبر: %s',
'%s ("%s") نامعتبر است',
dateType,
dateType,
tostring(dateString)
tostring(dateString)
خط ۸۴: خط ۹۳:
end
end


-- Given a directed graph formatted as node -> table of direct successors,
local function toTableEnd(t, pos)
-- get a table of all nodes reachable from a given node (though always
-- Sends the value at position pos to the end of array t, and shifts the
-- including the given node).
-- other items down accordingly.
local function getReachableNodes(graph, start)
return table.insert(t, table.remove(t, pos))
end
 
local function walkHierarchy(hierarchy, start)
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) -- This always gets the "first" key
local k = next(toWalk)
if k == nil then
if k == nil then break end
return retval
end
toWalk[k] = nil
toWalk[k] = nil
retval[k] = true
retval[k] = true
for _,v in ipairs(graph[k]) do
for _,v in ipairs(hierarchy[k]) do
if not retval[v] then
if not retval[v] then
toWalk[v] = true
toWalk[v] = true
خط ۱۰۳: خط ۱۱۳:
end
end
end
end
return retval
end
end


خط ۱۱۵: خط ۱۲۶:
edit = true,
edit = true,
move = true,
move = true,
autoreview = true,
autoreview = true
upload = true
}
}


خط ۱۴۰: خط ۱۵۰:
else
else
error(string.format(
error(string.format(
'اقدام نامعتبر: %s',
'عمل ("%s") نامعتبر است',
tostring(args.action)
tostring(args.action)
), 3)
), 3)
خط ۱۴۷: خط ۱۵۷:
-- Set level
-- Set level
obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title)
obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title)
if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then
if obj.level == 'accountcreator' then
-- Lump titleblacklisted pages in with template-protected pages,
-- since templateeditors can do both.
obj.level = 'templateeditor'
elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then
-- Users need to be autoconfirmed to move pages anyway, so treat
-- Users need to be autoconfirmed to move pages anyway, so treat
-- semi-move-protected pages as unprotected.
-- semi-move-protected pages as unprotected.
خط ۱۵۴: خط ۱۶۸:


-- Set expiry
-- Set expiry
local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title)
if args.expiry then
if effectiveExpiry == 'infinity' then
if cfg.indefStrings[args.expiry] then
obj.expiry = 'indef'
obj.expiry = 'indef'
elseif effectiveExpiry ~= 'unknown' then
elseif type(args.expiry) == 'number' then
obj.expiry = validateDate(effectiveExpiry, 'تاریخ انقضا')
obj.expiry = args.expiry
else
obj.expiry = validateDate(args.expiry, 'expiry date')
end
end
end


خط ۱۶۵: خط ۱۸۲:
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('دلایل نمی‌تواند شامل نویسه خط عمودی («|») باشد', 3)
error('دلایل نمی‌تواند شامل نویسه خط عمودی ("|") شود', 3)
end
end
end
end
خط ۱۷۱: خط ۱۸۸:
-- 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
خط ۲۲۴: خط ۲۴۱:


-- Get the namespace key fragment.
-- Get the namespace key fragment.
local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace]
local namespaceFragment
if not namespaceFragment and title.namespace % 2 == 1 then
do
namespaceFragment = 'talk'
namespaceFragment = cfg.categoryNamespaceKeys[title.namespace]
if not namespaceFragment and title.namespace % 2 == 1 then
namespaceFragment = 'talk'
end
end
end
   
   
خط ۲۵۱: خط ۲۷۱:
-- instead.
-- instead.
--]]
--]]
table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3))
if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then
-- table.insert(order, 3, table.remove(order, 2))
toTableEnd(order, 2)
else
toTableEnd(order, 3)
end
   
   
--[[
--[[
خط ۳۳۲: خط ۳۵۷:
end
end
return ''
return ''
end
function Protection:needsExpiry()
local cfg = self._cfg
local actionNeedsCheck = cfg.expiryCheckActions[self.action]
return not self.expiry and (
actionNeedsCheck or (
actionNeedsCheck == nil
and self.reason -- the old {{pp-protected}} didn't check for expiry
and not cfg.reasonsWithoutExpiryCheck[self.reason]
)
)
end
end


خط ۳۵۲: خط ۳۸۹:
local msg = self._cfg.msg
local msg = self._cfg.msg
local ret = { self:makeProtectionCategory() }
local ret = { self:makeProtectionCategory() }
if self:needsExpiry() then
ret[#ret + 1] = makeCategoryLink(
msg['tracking-category-expiry'],
self.title.text
)
end
if self:isIncorrect() then
if self:isIncorrect() then
ret[#ret + 1] = makeCategoryLink(
ret[#ret + 1] = makeCategoryLink(
خط ۴۰۰: خط ۴۴۳:
lang,
lang,
self._cfg.msg['expiry-date-format'] or 'xij xiF xiY', -- The 'xi' prefix is the prefix for displaying Iranian time
self._cfg.msg['expiry-date-format'] or 'xij xiF xiY', -- The 'xi' prefix is the prefix for displaying Iranian time
'@' .. replacePersianGreMonthName{converter('en', tostring(num))}
'@' .. p.replacePersianGreMonthName{convertString('en', tostring(num))}
)
)
if success then
if success then
خط ۴۸۰: خط ۵۲۳:
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'
خط ۵۲۹: خط ۵۷۰:
else
else
error(string.format(
error(string.format(
'نمی‌توان explanation blurb را برای عمل «%s»، سطح «%و کلید بحث «%پیدا کرد',
'نمی‌توان explanation blurb را برای عمل "%s"، سطح "%s" و کلید بحث "%s" پیدا کرد',
action,
action,
level,
level,
خط ۵۵۵: خط ۵۹۶:
function Blurb:_makeIntroBlurbParameter()
function Blurb:_makeIntroBlurbParameter()
if self._protectionObj:isTemporary() then
if self._protectionObj:isTemporary() then
return converter('fa', replacePersianMonthName(self:_getExpandedMessage('intro-blurb-expiry')))
return convertString('fa', replacePersianMonthName(self:_getExpandedMessage('intro-blurb-expiry')))
else
else
return self:_getExpandedMessage('intro-blurb-noexpiry')
return self:_getExpandedMessage('intro-blurb-noexpiry')
خط ۵۶۳: خط ۶۰۴:
function Blurb:_makeIntroFragmentParameter()
function Blurb:_makeIntroFragmentParameter()
if self._protectionObj:isTemporary() then
if self._protectionObj:isTemporary() then
return converter('fa', replacePersianMonthName(self:_getExpandedMessage('intro-fragment-expiry')))
return convertString('fa', replacePersianMonthName(self:_getExpandedMessage('intro-fragment-expiry')))
else
else
return self:_getExpandedMessage('intro-fragment-noexpiry')
return self:_getExpandedMessage('intro-fragment-noexpiry')
خط ۶۵۰: خط ۶۹۱:
function Blurb:_makeTooltipBlurbParameter()
function Blurb:_makeTooltipBlurbParameter()
if self._protectionObj:isTemporary() then
if self._protectionObj:isTemporary() then
return converter('fa', replacePersianMonthName(self:_getExpandedMessage('tooltip-blurb-expiry')))
return convertString('fa', replacePersianMonthName(self:_getExpandedMessage('tooltip-blurb-expiry')))
else
else
return self:_getExpandedMessage('tooltip-blurb-noexpiry')
return self:_getExpandedMessage('tooltip-blurb-noexpiry')
خط ۶۵۸: خط ۶۹۹:
function Blurb:_makeTooltipFragmentParameter()
function Blurb:_makeTooltipFragmentParameter()
if self._protectionObj:isTemporary() then
if self._protectionObj:isTemporary() then
return converter('fa', replacePersianMonthName(self:_getExpandedMessage('tooltip-fragment-expiry')))
return convertString('fa', replacePersianMonthName(self:_getExpandedMessage('tooltip-fragment-expiry')))
else
else
return self:_getExpandedMessage('tooltip-fragment-noexpiry')
return self:_getExpandedMessage('tooltip-fragment-noexpiry')
خط ۶۷۶: خط ۷۱۷:
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" زمینه پیکربندی بنر معتبری نیست',
tostring(key)
tostring(key)
), 2)
), 2)
خط ۷۴۸: خط ۷۸۹:
end
end
return setmetatable(obj, BannerTemplate)
return setmetatable(obj, BannerTemplate)
end
function BannerTemplate:setImageWidth(width)
self._imageWidth = width
end
function BannerTemplate:setImageTooltip(tooltip)
self._imageCaption = tooltip
end
end


خط ۷۵۴: خط ۸۰۳:
or self._cfg.msg['image-filename-default']
or self._cfg.msg['image-filename-default']
or 'Transparent.gif'
or 'Transparent.gif'
return makeFileLink{
return newFileLink(filename)
file = filename,
:width(self._imageWidth or 20)
size = (self.imageWidth or 20) .. 'px',
:alt(self._imageAlt)
alt = self._imageAlt,
:link(self._imageLink)
link = self._imageLink,
:caption(self._imageCaption)
caption = self.imageCaption
:render()
}
end
end


خط ۷۷۲: خط ۸۲۰:
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.imageWidth = 40
obj:setImageWidth(40)
obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip.
obj:setImageTooltip(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')
خط ۸۰۷: خط ۸۵۵:
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.imageWidth = 20
obj:setImageWidth(20)
obj.imageCaption = blurbObj:makeBannerText('tooltip')
obj:setImageTooltip(blurbObj:makeBannerText('tooltip'))
obj._imageAlt = blurbObj:makeBannerText('alt')
obj._imageAlt = blurbObj:makeBannerText('alt')
obj._imageLink = blurbObj:makeBannerText('link')
obj._imageLink = blurbObj:makeBannerText('link')
obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action]
obj._left = cfg.padlockPositions[protectionObj.action]
or cfg.padlockIndicatorNames.default
or cfg.padlockPositions.default
or 'pp-default'
or '55px'
return setmetatable(obj, Padlock)
return setmetatable(obj, Padlock)
end
end


function Padlock:__tostring()
function Padlock:__tostring()
local frame = mw.getCurrentFrame()
local root = mw.html.create('div')
-- The nowiki tag helps prevent whitespace at the top of articles.
root
return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{
:addClass('metadata topicon nopopups')
name = 'indicator',
:attr('id', 'protected-icon')
args = {name = self._indicatorName},
:css{display = 'none', left = self._left}
content = self:renderImage()
:wikitext(self:renderImage())
}
return tostring(root)
end
end


خط ۸۳۰: خط ۸۷۸:
-- Exports
-- Exports
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
local p = {}


function p._exportClasses()
function p._exportClasses()
خط ۸۵۲: خط ۸۹۸:
local ret = {}
local ret = {}


-- If a page's edit protection is equally or more restrictive than its
-- If a page's edit protection is equally or more restrictive than its protection from some other action,
-- protection from some other action, then don't bother displaying anything
-- then don't bother displaying anything for the other action (except categories).
-- for the other action (except categories).
if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then
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)