Open main menu
Home
Random
Donate
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:URLutil
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 URLutil = { suite = "URLutil", serial = "2022-04-05", item = 10859193 } --[=[ Utilities for URL etc. on www. * decode() * encode() * getAuthority() * getFragment() * getHost() * getLocation() * getNormalized() * getPath() * getPort() * getQuery() * getQueryTable() * getRelativePath() * getScheme() * getSortkey() * getTLD() * getTop2domain() * getTop3domain() * isAuthority() * isDomain() * isDomainExample() * isDomainInt() * isHost() * isHostPathResource() * isIP() * isIPlocal() * isIPv4() * isIPv6() * isMailAddress() * isMailLink() * isProtocolDialog() * isProtocolWiki() * isResourceURL() * isSuspiciousURL() * isUnescapedURL() * isWebURL() * wikiEscapeURL() * failsafe() Only [[dotted decimal]] notation for IPv4 expected. Does not support dotted hexadecimal, dotted octal, or single-number formats. IPv6 URL (bracketed) not yet implemented; might need Wikintax escaping anyway. ]=] local Failsafe = URLutil local decodeComponentProtect = { F = "\"#%<>[\]^`{|}", P = "\"#%<>[\]^`{|}/?", Q = "\"#%<>[\]^`{|}&=+;,", X = "\"#%<>[\]^`{|}&=+;,/?" } local decodeComponentEscape = function ( averse, adapt ) return adapt == 20 or adapt == 127 or decodeComponentProtect[ averse ]:find( string.char( adapt ), 1, true ) end -- decodeComponentEscape() local decodeComponentML = function ( ask ) local i = 1 local j, n, s while ( i ) do i = ask:find( "&#[xX]%x%x+;", i ) if i then j = ask:find( ";", i + 3, true ) s = ask:sub( i + 2, j - 1 ):upper() n = s:byte( 1, 1 ) if n == 88 then n = tonumber( s:sub( 2 ), 16 ) elseif s:match( "^%d+$" ) then n = tonumber( s ) else n = false end if n then if n >= 128 then s = string.format( "&#%d;", n ) elseif decodeComponentEscape( "X", n ) then s = string.format( "%%%02X", n ) else s = string.format( "%c", n ) end j = j + 1 if i == 1 then ask = s .. ask:sub( j ) else ask = string.format( "%s%s%s", ask:sub( 1, i - 1 ), s, ask:sub( j ) ) end end i = i + 1 end end -- while i return ask end -- decodeComponentML() local decodeComponentPercent = function ( ask, averse ) local i = 1 local j, k, m, n while ( i ) do i = ask:find( "%%[2-7]%x", i ) if i then j = i + 1 k = j + 1 n = ask:byte( k, k ) k = k + 1 m = ( n > 96 ) if m then n = n - 32 m = n end if n > 57 then n = n - 55 else n = n - 48 end n = ( ask:byte( j, j ) - 48 ) * 16 + n if n == 39 and ask:sub( i + 3, i + 5 ) == "%27" then j = i + 6 while ( ask:sub( j, j + 2 ) == "%27" ) do j = j + 3 end -- while "%27" elseif decodeComponentEscape( averse, n ) then if m then ask = string.format( "%s%c%s", ask:sub( 1, j ), m, ask:sub( k ) ) end elseif i == 1 then ask = string.format( "%c%s", n, ask:sub( k ) ) else ask = string.format( "%s%c%s", ask:sub( 1, i - 1 ), n, ask:sub( k ) ) end i = j end end -- while i return ask end -- decodeComponentPercent() local getTopDomain = function ( url, mode ) local r = URLutil.getHost( url ) if r then local pattern = "[%w%%%-]+%.%a[%w%-]*%a)$" if mode == 3 then pattern = "[%w%%%-]+%." .. pattern end r = mw.ustring.match( "." .. r, "%.(" .. pattern ) if not r then r = false end else r = false end return r end -- getTopDomain() local getHash = function ( url ) local r = url:find( "#", 1, true ) if r then local i = url:find( "&#", 1, true ) if i then local s while ( i ) do s = url:sub( i + 2 ) if s:match( "^%d+;" ) or s:match( "^x%x+;" ) then r = url:find( "#", i + 4, true ) if r then i = url:find( "&#", i + 4, true ) else i = false end else r = i + 1 i = false end end -- while i end end return r end -- getHash() URLutil.decode = function ( url, enctype ) local r, s if type( enctype ) == "string" then s = mw.text.trim( enctype ) if s == "" then s = false else s = s:upper() end end r = mw.text.encode( mw.uri.decode( url, s ) ) if r:find( "[%[|%]]" ) then local k r, k = r:gsub( "%[", "[" ) :gsub( "|", "|" ) :gsub( "%]", "]" ) end return r end -- URLutil.decode() URLutil.encode = function ( url, enctype ) local k, r, s if type( enctype ) == "string" then s = mw.text.trim( enctype ) if s == "" then s = false else s = s:upper() end end r = mw.uri.encode( url, s ) k = r:byte( 1, 1 ) if -- k == 35 or -- # k == 42 or -- * k == 58 or -- : k == 59 then -- ; r = string.format( "%%%X%s", k, r:sub( 2 ) ) end if r:find( "[%[|%]]" ) then r, k = r:gsub( "%[", "%5B" ) :gsub( "|", "%7C" ) :gsub( "%]", "%5D" ) end return r end -- URLutil.encode() URLutil.getAuthority = function ( url ) local r if type( url ) == "string" then local colon, host, port local pattern = "^%s*%w*:?//([%w%.%%_-]+)(:?)([%d]*)/" local s = mw.text.decode( url ) local i = s:find( "#", 6, true ) if i then s = s:sub( 1, i - 1 ) .. "/" else s = s .. "/" end host, colon, port = mw.ustring.match( s, pattern ) if URLutil.isHost( host ) then host = mw.ustring.lower( host ) if colon == ":" then if port:find( "^[1-9]" ) then r = ( host .. ":" .. port ) end elseif #port == 0 then r = host end end else r = false end return r end -- URLutil.getAuthority() URLutil.getFragment = function ( url, decode ) local r if type( url ) == "string" then local i = getHash( url ) if i then r = mw.text.trim( url:sub( i ) ):sub( 2 ) if type( decode ) == "string" then local encoding = mw.text.trim( decode ) local launch if encoding == "%" then launch = true elseif encoding == "WIKI" then r = r:gsub( "%.(%x%x)", "%%%1" ) :gsub( "_", " " ) launch = true end if launch then r = mw.uri.decode( r, "PATH" ) end end else r = false end else r = nil end return r end -- URLutil.getFragment() URLutil.getHost = function ( url ) local r = URLutil.getAuthority( url ) if r then r = mw.ustring.match( r, "^([%w%.%%_%-]+):?[%d]*$" ) end return r end -- URLutil.getHost() URLutil.getLocation = function ( url ) local r if type( url ) == "string" then r = mw.text.trim( url ) if r == "" then r = false else local i i = getHash( r ) if i then if i == 1 then r = false else r = r:sub( 1, i - 1 ) end end end else r = nil end return r end -- URLutil.getLocation() URLutil.getNormalized = function ( url ) local r if type( url ) == "string" then r = mw.text.trim( url ) if r == "" then r = false else r = decodeComponentML( r ) end else r = false end if r then local k = r:find( "//", 1, true ) if k then local j = r:find( "/", k + 2, true ) local sF, sP, sQ if r:find( "%%[2-7]%x" ) then local i = getHash( r ) if i then sF = r:sub( i + 1 ) r = r:sub( 1, i - 1 ) if sF == "" then sF = false else sF = decodeComponentPercent( sF, "F" ) end end i = r:find( "?", 1, true ) if i then sQ = r:sub( i ) r = r:sub( 1, i - 1 ) sQ = decodeComponentPercent( sQ, "Q" ) end if j then if #r > j then sP = r:sub( j + 1 ) sP = decodeComponentPercent( sP, "P" ) end r = r:sub( 1, j - 1 ) end elseif j then local n = #r if r:byte( n, n ) == 35 then -- '#' n = n - 1 r = r:sub( 1, n ) end if n > j then sP = r:sub( j + 1 ) end r = r:sub( 1, j - 1 ) end r = mw.ustring.lower( r ) .. "/" if sP then r = r .. sP end if sQ then r = r .. sQ end if sF then r = string.format( "%s#%s", r, sF ) end end r = r:gsub( " ", "%%20" ) :gsub( "%[", "%%5B" ) :gsub( "|", "%%7C" ) :gsub( "%]", "%%5D" ) :gsub( "%<", "%%3C" ) :gsub( "%>", "%%3E" ) end return r end -- URLutil.getNormalized() URLutil.getPath = function ( url ) local r = URLutil.getRelativePath( url ) if r then local s = r:match( "^([^%?]*)%?" ) if s then r = s end s = r:match( "^([^#]*)#" ) if s then r = s end end return r end -- URLutil.getPath() URLutil.getPort = function ( url ) local r = URLutil.getAuthority( url ) if r then r = r:match( ":([1-9][0-9]*)$" ) if r then r = tonumber( r ) else r = false end end return r end -- URLutil.getPort() URLutil.getQuery = function ( url, key, separator ) local r = URLutil.getLocation( url ) if r then r = r:match( "^[^%?]*%?(.+)$" ) if r then if type( key ) == "string" then local single = mw.text.trim( key ) local sep = "&" local s, scan if type( separator ) == "string" then s = mw.text.trim( separator ) if s:match( "^[&;,/]$" ) then sep = s end end s = string.format( "%s%s%s", sep, r, sep ) scan = string.format( "%s%s=([^%s]*)%s", sep, key, sep, sep ) r = s:match( scan ) end end if not r then r = false end end return r end -- URLutil.getQuery() URLutil.getQueryTable = function ( url, separator ) local r = URLutil.getQuery( url ) if r then local sep = "&" local n, pairs, s, set if type( separator ) == "string" then s = mw.text.trim( separator ) if s:match( "^[&;,/]$" ) then sep = s end end pairs = mw.text.split( r, sep, true ) n = #pairs r = { } for i = 1, n do s = pairs[ i ] if s:find( "=", 2, true ) then s, set = s:match( "^([^=]+)=(.*)$" ) if s then r[ s ] = set end else r[ s ] = false end end -- for i end return r end -- URLutil.getQueryTable() URLutil.getRelativePath = function ( url ) local r if type( url ) == "string" then local s = url:match( "^%s*[a-zA-Z]*://(.*)$" ) if s then s = s:match( "[^/]+(/.*)$" ) else local x x, s = url:match( "^%s*(/?)(/.*)$" ) if x == "/" then s = s:match( "/[^/]+(/.*)$" ) end end if s then r = mw.text.trim( s ) elseif URLutil.isResourceURL( url ) then r = "/" else r = false end else r = nil end return r end -- URLutil.getRelativePath() URLutil.getScheme = function ( url ) local r if type( url ) == "string" then local pattern = "^%s*([a-zA-Z]*)(:?)(//)" local prot, colon, slashes = url:match( pattern ) r = false if slashes == "//" then if colon == ":" then if #prot > 2 then r = prot:lower() .. "://" end elseif #prot == 0 then r = "//" end end else r = nil end return r end -- URLutil.getScheme() URLutil.getSortkey = function ( url ) local r = url if type( url ) == "string" then local i = url:find( "//" ) if i then local scheme if i == 0 then scheme = "" else scheme = url:match( "^%s*([a-zA-Z]*)://" ) end if scheme then local s = url:sub( i + 2 ) local comps, site, m, suffix scheme = scheme:lower() i = s:find( "/" ) if i and i > 1 then suffix = s:sub( i + 1 ) -- mw.uri.encode() s = s:sub( 1, i - 1 ) suffix = suffix:gsub( "#", " " ) else suffix = "" end site, m = s:match( "^(.+)(:%d+)$" ) if not m then site = s m = 0 end comps = mw.text.split( site:lower(), ".", true ) r = "///" for i = #comps, 2, -1 do r = string.format( "%s%s.", r, comps[ i ] ) end -- for --i r = string.format( "%s%s %d %s: %s", r, comps[ 1 ], m, scheme, suffix ) end end end return r end -- URLutil.getSortkey() URLutil.getTLD = function ( url ) local r = URLutil.getHost( url ) if r then r = mw.ustring.match( r, "%w+%.(%a[%w%-]*%a)$" ) if not r then r = false end end return r end -- URLutil.getTLD() URLutil.getTop2domain = function ( url ) return getTopDomain( url, 2 ) end -- URLutil.getTop2domain() URLutil.getTop3domain = function ( url ) return getTopDomain( url, 3 ) end -- URLutil.getTop3domain() URLutil.isAuthority = function ( s ) local r if type( s ) == "string" then local pattern = "^%s*([%w%.%%_-]+)(:?)(%d*)%s*$" local host, colon, port = mw.ustring.match( s, pattern ) if colon == ":" then port = port:match( "^[1-9][0-9]*$" ) if type( port ) ~= "string" then r = false end elseif port ~= "" then r = false end r = URLutil.isHost( host ) else r = nil end return r end -- URLutil.isAuthority() URLutil.isDomain = function ( s ) local r if type( s ) == "string" then local scan = "^%s*([%w%.%%_-]*%w)%.(%a[%w-]*%a)%s*$" local scope s, scope = mw.ustring.match( s, scan ) if type( s ) == "string" then if mw.ustring.find( s, "^%w" ) then if mw.ustring.find( s, "..", 1, true ) then r = false else r = true end end end else r = nil end return r end -- URLutil.isDomain() URLutil.isDomainExample = function ( url ) -- RFC 2606: example.com example.net example.org example.edu local r = getTopDomain( url, 2 ) if r then local s = r:lower():match( "^example%.([a-z][a-z][a-z])$" ) if s then r = ( s == "com" or s == "edu" or s == "net" or s == "org" ) else r = false end end return r end -- URLutil.isDomainExample() URLutil.isDomainInt = function ( url ) -- Internationalized Domain Name (Punycode) local r = URLutil.getHost( url ) if r then if r:match( "^[!-~]+$" ) then local s = "." .. r if s:find( ".xn--", 1, true ) then r = true else r = false end else r = true end end return r end -- URLutil.isDomainInt() URLutil.isHost = function ( s ) return URLutil.isDomain( s ) or URLutil.isIP( s ) end -- URLutil.isHost() URLutil.isHostPathResource = function ( s ) local r = URLutil.isResourceURL( s ) if not r and s then r = URLutil.isResourceURL( "//" .. mw.text.trim( s ) ) end return r end -- URLutil.isHostPathResource() URLutil.isIP = function ( s ) return URLutil.isIPv4( s ) and 4 or URLutil.isIPv6( s ) and 6 end -- URLutil.isIP() URLutil.isIPlocal = function ( s ) -- IPv4 according to RFC 1918, RFC 1122; even any 0.0.0.0 (RFC 5735) local r = false local num = s:match( "^ *([01][0-9]*)%." ) if num then num = tonumber( num ) if num == 0 then r = s:match( "^ *0+%.[0-9]+%.[0-9]+%.[0-9]+ *$" ) elseif num == 10 or num == 127 then -- loopback; private/local host: 127.0.0.1 r = URLutil.isIPv4( s ) elseif num == 169 then -- 169.254.*.* elseif num == 172 then -- 172.(16...31).*.* num = s:match( "^ *0*172%.([0-9]+)%." ) if num then num = tonumber( num ) if num >= 16 and num <= 31 then r = URLutil.isIPv4( s ) end end elseif beg == 192 then -- 192.168.*.* num = s:match( "^ *0*192%.([0-9]+)%." ) if num then num = tonumber( num ) if num == 168 then r = URLutil.isIPv4( s ) end end end end if r then r = true end return r end -- URLutil.isIPlocal() URLutil.isIPv4 = function ( s ) local function legal( n ) return ( tonumber( n ) < 256 ) end local r = false if type( s ) == "string" then local p1, p2, p3, p4 = s:match( "^%s*([1-9][0-9]?[0-9]?)%.([12]?[0-9]?[0-9])%.([12]?[0-9]?[0-9])%.([12]?[0-9]?[0-9])%s*$" ) if p1 and p2 and p3 and p4 then r = legal( p1 ) and legal( p2 ) and legal( p3 ) and legal( p4 ) end end return r end -- URLutil.isIPv4() URLutil.isIPv6 = function ( s ) local dcolon, groups if type( s ) ~= "string" or s:len() == 0 or s:find( "[^:%x]" ) -- only colon and hex digits are legal chars or s:find( "^:[^:]" ) -- can begin or end with :: but not with single : or s:find( "[^:]:$" ) or s:find( ":::" ) then return false end s = mw.text.trim( s ) s, dcolon = s:gsub( "::", ":" ) if dcolon > 1 then return false end -- at most one :: s = s:gsub( "^:?", ":" ) -- prepend : if needed, upper s, groups = s:gsub( ":%x%x?%x?%x?", "" ) -- remove valid groups, and count them return ( ( dcolon == 1 and groups < 8 ) or ( dcolon == 0 and groups == 8 ) ) and ( s:len() == 0 or ( dcolon == 1 and s == ":" ) ) -- might be one dangling : if original ended with :: end -- URLutil.isIPv6() URLutil.isMailAddress = function ( s ) if type( s ) == "string" then s = mw.ustring.match( s, "^%s*[%w%.%%_-]+@([%w%.%%-]+)%s*$" ) return URLutil.isDomain( s ) end return false end -- URLutil.isMailAddress() URLutil.isMailLink = function ( s ) if type( s ) == "string" then local addr s, addr = mw.ustring.match( s, "^%s*([Mm][Aa][Ii][Ll][Tt][Oo]):(%S[%w%.%%_-]*@[%w%.%%-]+)%s*$" ) if type( s ) == "string" then if s:lower() == "mailto" then return URLutil.isMailAddress( addr ) end end end return false end -- URLutil.isMailLink() local function isProtocolAccepted( prot, supplied ) if type( prot ) == "string" then local scheme, colon, slashes = mw.ustring.match( prot, "^%s*([a-zA-Z]*)(:?)(/?/?)%s*$" ) if slashes ~= "/" then if scheme == "" then if colon ~= ":" and slashes == "//" then return true end elseif colon == ":" or slashes == "" then local s = supplied:match( " " .. scheme:lower() .. " " ) if type( s ) == "string" then return true end end end end return false end -- isProtocolAccepted() URLutil.isProtocolDialog = function ( prot ) return isProtocolAccepted( prot, " mailto irc ircs ssh telnet " ) end -- URLutil.isProtocolDialog() URLutil.isProtocolWiki = function ( prot ) return isProtocolAccepted( prot, " ftp ftps git http https nntp sftp svn worldwind " ) end -- URLutil.isProtocolWiki() URLutil.isResourceURL = function ( url ) local scheme = URLutil.getScheme( url ) if scheme then local s = " // http:// https:// ftp:// sftp:// " s = s:find( string.format( " %s ", scheme ) ) if s then if URLutil.getAuthority( url ) then if not url:match( "%S%s+%S" ) then local s1, s2 = url:match( "^([^#]+)(#.*)$" ) if s2 then if url:match( "^%s*[a-zA-Z]*:?//(.+)/" ) then return true end else return true end end end end end return false end -- URLutil.isResourceURL() URLutil.isSuspiciousURL = function ( url ) if URLutil.isResourceURL( url ) then local s = URLutil.getAuthority( url ) local pat = "[%[|%]" .. mw.ustring.char( 34, 8201, 45, 8207, 8234, 45, 8239, 8288 ) .. "]" if s:find( "@" ) or url:find( "''" ) or url:find( pat ) or url:find( "[%.,]$" ) then return true end -- TODO zero width character ?? return false end return true end -- URLutil.isSuspiciousURL() URLutil.isUnescapedURL = function ( url, trailing ) if type( trailing ) ~= "string" then if URLutil.isWebURL( url ) then if url:match( "[%[|%]]" ) then return true end end end return false end -- URLutil.isUnescapedURL() URLutil.isWebURL = function ( url ) if URLutil.getScheme( url ) and URLutil.getAuthority( url ) then if not url:find( "%S%s+%S" ) and not url:find( "''", 1, true ) then return true end end return false end -- URLutil.isWebURL() URLutil.wikiEscapeURL = function ( url ) if url:find( "[%[|%]]" ) then local n url, n = url:gsub( "%[", "[" ) :gsub( "|", "|" ) :gsub( "%]", "]" ) end return url end -- URLutil.wikiEscapeURL() Failsafe.failsafe = function ( atleast ) -- Retrieve versioning and check for compliance -- Precondition: -- atleast -- string, with required version -- or wikidata|item|~|@ or false -- Postcondition: -- Returns string -- with queried version/item, also if problem -- false -- if appropriate -- 2020-08-17 local since = atleast local last = ( since == "~" ) local linked = ( since == "@" ) local link = ( since == "item" ) local r if last or link or linked or since == "wikidata" then local item = Failsafe.item since = false if type( item ) == "number" and item > 0 then local suited = string.format( "Q%d", item ) if link then r = suited else local entity = mw.wikibase.getEntity( suited ) if type( entity ) == "table" then local seek = Failsafe.serialProperty or "P348" local vsn = entity:formatPropertyValues( seek ) if type( vsn ) == "table" and type( vsn.value ) == "string" and vsn.value ~= "" then if last and vsn.value == Failsafe.serial then r = false elseif linked then if mw.title.getCurrentTitle().prefixedText == mw.wikibase.getSitelink( suited ) then r = false else r = suited end else r = vsn.value end end end end end end if type( r ) == "nil" then if not since or since <= Failsafe.serial then r = Failsafe.serial else r = false end end return r end -- Failsafe.failsafe() local function Template( frame, action, amount ) -- Run actual code from template transclusion -- Precondition: -- frame -- object -- action -- string, with function name -- amount -- number, of args if > 1 -- Postcondition: -- Return string or not local n = amount or 1 local v = { } local r, s for i = 1, n do s = frame.args[ i ] if s then s = mw.text.trim( s ) if s ~= "" then v[ i ] = s end end end -- for i if v[ 1 ] then r = URLutil[ action ]( v[ 1 ], v[ 2 ], v[ 3 ] ) end return r end -- Template() local p = {} function p.decode( frame ) return Template( frame, "decode", 2 ) or "" end function p.encode( frame ) return Template( frame, "encode", 2 ) or "" end function p.getAuthority( frame ) return Template( frame, "getAuthority" ) or "" end function p.getFragment( frame ) local r = Template( frame, "getFragment", 2 ) if r then r = "#" .. r else r = "" end return r end function p.getHost( frame ) return Template( frame, "getHost" ) or "" end function p.getLocation( frame ) return Template( frame, "getLocation" ) or "" end function p.getNormalized( frame ) return Template( frame, "getNormalized" ) or "" end function p.getPath( frame ) return Template( frame, "getPath" ) or "" end function p.getPort( frame ) return Template( frame, "getPort" ) or "" end function p.getQuery( frame ) local r = Template( frame, "getQuery", 3 ) if r then local key = frame.args[ 2 ] if key then key = mw.text.trim( key ) if key == "" then key = nil end end if not key then r = "?" .. r end else r = "" end return r end function p.getRelativePath( frame ) return Template( frame, "getRelativePath" ) or "" end function p.getScheme( frame ) return Template( frame, "getScheme" ) or "" end function p.getSortkey( frame ) return Template( frame, "getSortkey" ) or "" end function p.getTLD( frame ) return Template( frame, "getTLD" ) or "" end function p.getTop2domain( frame ) return Template( frame, "getTop2domain" ) or "" end function p.getTop3domain( frame ) return Template( frame, "getTop3domain" ) or "" end function p.isAuthority( frame ) return Template( frame, "isAuthority" ) and "1" or "" end function p.isDomain( frame ) return Template( frame, "isDomain" ) and "1" or "" end function p.isDomainExample( frame ) return Template( frame, "isDomainExample" ) and "1" or "" end function p.isDomainInt( frame ) return Template( frame, "isDomainInt" ) and "1" or "" end function p.isHost( frame ) return Template( frame, "isHost" ) and "1" or "" end function p.isHostPathResource( frame ) return Template( frame, "isHostPathResource" ) and "1" or "" end function p.isIP( frame ) return Template( frame, "isIP" ) or "" end function p.isIPlocal( frame ) return Template( frame, "isIPlocal" ) and "1" or "" end function p.isIPv4( frame ) return Template( frame, "isIPv4" ) and "1" or "" end function p.isIPv6( frame ) return Template( frame, "isIPv6" ) and "1" or "" end function p.isMailAddress( frame ) return Template( frame, "isMailAddress" ) and "1" or "" end function p.isMailLink( frame ) return Template( frame, "isMailLink" ) and "1" or "" end function p.isProtocolDialog( frame ) return Template( frame, "isProtocolDialog" ) and "1" or "" end function p.isProtocolWiki( frame ) return Template( frame, "isProtocolWiki" ) and "1" or "" end function p.isResourceURL( frame ) return Template( frame, "isResourceURL" ) and "1" or "" end function p.isSuspiciousURL( frame ) return Template( frame, "isSuspiciousURL" ) and "1" or "" end function p.isUnescapedURL( frame ) return Template( frame, "isUnescapedURL", 2 ) and "1" or "" end function p.isWebURL( frame ) return Template( frame, "isWebURL" ) and "1" or "" end function p.wikiEscapeURL( frame ) return Template( frame, "wikiEscapeURL" ) end p.failsafe = function ( frame ) local s = type( frame ) local since if s == "table" then since = frame.args[ 1 ] elseif s == "string" then since = frame end if since then since = mw.text.trim( since ) if since == "" then since = false end end return Failsafe.failsafe( since ) or "" end function p.URLutil() return URLutil 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:URLutil/doc
(
edit
)