Home
Random
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Mock title
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local checkType = require('libraryUtil').checkType local mRepr = require('Module:Repr') local p = {} local mockTitleRegistry = {} --[[ -- Capitalize a string. --]] local function capitalize(s) return s:sub(1, 1):upper() .. s:sub(2, -1) end --[[ -- Check that a named argument is one of multiple types. --]] local function checkTypeForNamedArgMulti(name, argName, arg, expectTypes) local argType = type(arg) for _, expectedType in ipairs(expectTypes) do if argType == expectedType then return end end error( string.format( "bad named argument %s to '%s' (%s expected, got %s)", argName, name, mw.text.listToText(expectTypes, ", ", " or "), argType ), 3 ) end --[[ -- Set a property on an object to the given value, if that value is not nil. --]] local function maybeSetProperty(object, property, value) if value ~= nil then rawset(object, property, value) end end --[[ -- Construct a mock title from a string, an ID or an options table. If we were -- passed a mock title object to start with, return it as-is. --]] local function constructMockTitle(titleOrOptions) if titleOrOptions == nil then return nil end local titleOrOptionsType = type(titleOrOptions) if titleOrOptionsType == "string" or titleOrOptionsType == "number" then return p.MockTitle{page = titleOrOptions} elseif titleOrOptionsType == "table" then if type(titleOrOptions.getContent) == "function" then return titleOrOptions else return p.MockTitle(titleOrOptions) end else error( string.format( "Invalid type specified to constructMockTitle (expected string, number, table or nil; received %s)", titleOrOptionsType ), 2 ) end end --[[ -- Get a table of protection levels with the levels set by the user. The -- makeOptionsKey is a function that takes a protection action as an input and -- gives the option table key for that action. The function returns two values: -- the table of protection levels (as used by the protectionLevels and -- cascadingProtection title object properties), and a boolean flag indicating -- whether any protection levels were set. --]] local function getProtectionLevels(options, makeOptionsKey) local levels = { edit = {}, move = {}, create = {}, upload = {}, } local isSet = false for action in pairs(levels) do local level = options[makeOptionsKey(action)] if level then levels[action][1] = level isSet = true end end return levels, isSet end --[[ -- Set protection levels --]] local function setProtectionLevels(title, options) local protectionLevels, isProtectionSet = getProtectionLevels( options, function (action) return action .. "Protection" end ) if isProtectionSet then rawset(title, "protectionLevels", protectionLevels) end end --[[ -- Set cascading protection --]] local function setCascadingProtection(title, options) local cascadingProtectionLevels, isCascadingProtectionSet = getProtectionLevels( options, function (action) return string.format("cascading%sProtection", capitalize(action)) end ) local cascadingSourcesExist = options.cascadingProtectionSources and #options.cascadingProtectionSources >= 1 if isCascadingProtectionSet and cascadingSourcesExist then rawset( title, "cascadingProtection", { restrictions = cascadingProtectionLevels, sources = options.cascadingProtectionSources, } ) elseif isCascadingProtectionSet then error("a cascading protection argument was given but the cascadingProtectionSources argument was missing or empty", 2) elseif cascadingSourcesExist then error("the cascadingProtectionSources argument was given, but no cascading protection argument was given", 2) end end --[[ -- Set page content, if specified --]] local function maybeSetContent(titleObject, content) if content then rawset(titleObject, "getContent", function () return content end) end end --[[ -- Set properties in the file table, as well as the fileExists property --]] local function setFileProperties(title, options) if title.file then for _, property in ipairs{"exists", "width", "height", "pages", "size", "mimeType", "length"} do local optionName = "file" .. capitalize(property) maybeSetProperty(title.file, property, options[optionName]) end end end --[[ -- Patch an existing title object with the given options. --]] function p.patchTitleObject(title, options) -- Set simple properties for _, property in ipairs{"id", "isRedirect", "exists", "contentModel"} do maybeSetProperty(title, property, options[property]) end -- Set redirect title maybeSetProperty(title, "redirectTarget", constructMockTitle(options.redirectTarget)) -- Set complex properties setProtectionLevels(title, options) setCascadingProtection(title, options) maybeSetContent(title, options.content) setFileProperties(title, options) return title end --[[ -- Construct a new mock title. --]] function p.MockTitle(options) checkType("MockTitle", 1, options, "table") checkTypeForNamedArgMulti("MockTitle", "page", options.page, {"string", "number"}) local title = mw.title.new(options.page) return p.patchTitleObject(title, options) end --[[ -- Register a mock title. -- This can be a string, a mock title object or a table of options for -- MockTitle. --]] function p.registerMockTitle(titleOrOptions) checkType("registerMockTitle", 1, titleOrOptions, "table") title = constructMockTitle(titleOrOptions) mockTitleRegistry[title.prefixedText] = title end --[[ -- Remove a title from the mock title registry. -- Returns the title that was removed. --]] function p.deregisterMockTitle(titleOrOptions) checkType("deregisterMockTitle", 1, title, "table") title = constructMockTitle(titleOrOptions) registeredTitle = mockTitleRegistry[title.prefixedText] mockTitleRegistry[title.prefixedText] = nil return registeredTitle end --[[ -- Register multiple mock titles. --]] function p.registerMockTitles(...) checkType("registerMockTitles", 1, titleData, "table") for _, titleOrOptions in ipairs{...} do p.registerMockTitle(titleOrOptions) end end --[[ -- Deregister multiple mock titles. -- Returns a sequence of titles that were removed. --]] function p.deregisterMockTitles(...) checkType("deregisterMockTitles", 1, titleData, "table") local removedTitles = {} for _, titleOrOptions in ipairs{...} do table.insert(removedTitles, p.deregisterMockTitle(titleOrOptions)) end return removedTitles end --[[ -- Clear the mock title registry. --]] function p.clearMockTitleRegistry() mockTitleRegistry = {} end --[[ -- Patch the given title function. -- This replaces the title function with a function that looks in the title -- registry for the given title. --]] local function patchTitleFunc(funcName) local oldFunc = mw.title[funcName] mw.title[funcName] = function(...) local title = oldFunc(...) if not title then error( string.format( "Could not make title object from invocation %s", mRepr.invocationRepr{ funcName = "mw.title." .. funcName, args = {...} } ), 2 ) end local mockTitle = mockTitleRegistry[title.prefixedText] if mockTitle then return mockTitle else return title end end return oldTitleNew end --[[ -- Patch mw.title.new. -- The original mw.title.new is restored after running the given function. --]] function p.patchTitleNew(func, ...) local oldTitleNew = patchTitleFunc("new") func(...) mw.title.new = oldTitleNew end --[[ -- Patch mw.title.makeTitle. -- The original mw.title.makeTitle is restored after running the given function. --]] function p.patchMakeTitle(func, ...) local oldMakeTitle = patchTitleFunc("makeTitle") func(...) mw.title.makeTitle = oldMakeTitle end --[[ -- Patch mw.title.new and mw.title.makeTitle. -- The original title functions are restored after running the given function. --]] function p.patchTitleConstructors(func, ...) local oldTitleNew = patchTitleFunc("new") local oldMakeTitle = patchTitleFunc("makeTitle") func(...) mw.title.new = oldTitleNew mw.title.makeTitle = oldMakeTitle end return p
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:Mock title/doc
(
edit
)