Module:FrameTools/sandbox

--

-- This module contains helper functions for dealing with frame objects.

local p = {}

-- Frame methods are protected by a `checkSelf` function, which makes them more -- difficult to copy.

function p.copy(frame) local copy = mw.clone(frame)

-- Point methods on `copy` to their `frame` counterparts for methodName, method in pairs(frame) do       if type(method) == "function" and methodName ~= "getParent" then copy[methodName] = function (copy, ...) return method(frame, ...) end end end

-- This method needs special treatment function copy:getParent local parent = frame:getParent

if parent then return p.copy(parent) end end

return copy end

-- Creates a pseudo frame with some useful functions -- available in mw:Extension:Scribunto, e.g. newChild

function p.makePseudoFrame(frame,parentArgs,childArgs) if type(frame) ~= "table" then error("frame must be a table") end local libraryUtil = require( 'libraryUtil' ) local pseudoFrame = {parent = {}} local checkSelf = libraryUtil.makeCheckSelfFunction( 'pseudoFrame', 'obj', pseudoFrame, 'PseudoFrame object' ) local parent = pseudoFrame.parent for name in pairs(frame) do       pseudoFrame[name] = function (pseudoFrame, ...) return frame[name](frame, unpack(arg)) end parent[name] = function (parent,...) return pseudoFrame[name](pseudoFrame, unpack(arg)) end end

local pArgs if frame and frame:getParent then pArgs = frame:getParent.args end pseudoFrame.parent.args = mw.clone( parentArgs or pArgs) pseudoFrame.args = mw.clone( childArgs or frame.args or {}) pseudoFrame.title = tostring(mw.title.getCurrentTitle) function pseudoFrame:getTitle checkSelf(self,"getTitle") return self.title end function pseudoFrame:getParent checkSelf(self,"getParent") function pseudoFrame.parent:getTitle -- checkSelf(self.parent,"getTitle") return self.title end return self.parent end function copyMembers(tmpTable,self) for name in pairs(self) do           if name ~="parent" then tmpTable[name] = function (tmpTable, ...) return self[name](self, unpack(arg)) end end if name =="parent" then tmpTable.name = self.name end end end

function pseudoFrame:newChild(...) checkSelf(self,"newChild") local params = unpack(arg) local tmpTable = p.makePseudoFrame(frame,self.args,params.args) tmpTable.parent.title = mw.clone(self.title) tmpTable.title = mw.clone(params.title) return tmpTable end return pseudoFrame end

-- Returns a frame-like object with the given arguments removed.

function p.removeArgs(frame, ...) local pseudoFrame = p.copy(frame) local args = pseudoFrame.args local metatable = getmetatable(args)

-- disable arg caching metatable.__index = nil metatable.__pairs = nil

-- remove args for _, arg in ipairs{...} do       args[arg] = nil end

return pseudoFrame end

return p

-- -- (Add categories here.)