mirror of
https://github.com/openwrt/luci.git
synced 2026-04-15 19:01:56 +00:00
treewide: move server side CBI support to luci-compat
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
1977
modules/luci-compat/luasrc/cbi.lua
Normal file
1977
modules/luci-compat/luasrc/cbi.lua
Normal file
File diff suppressed because it is too large
Load Diff
470
modules/luci-compat/luasrc/cbi/datatypes.lua
Normal file
470
modules/luci-compat/luasrc/cbi/datatypes.lua
Normal file
@@ -0,0 +1,470 @@
|
||||
-- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Copyright 2017 Dan Luedtke <mail@danrl.com>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local ip = require "luci.ip"
|
||||
local math = require "math"
|
||||
local util = require "luci.util"
|
||||
local tonumber, tostring, type, unpack, select = tonumber, tostring, type, unpack, select
|
||||
|
||||
|
||||
module "luci.cbi.datatypes"
|
||||
|
||||
|
||||
_M['or'] = function(v, ...)
|
||||
local i
|
||||
for i = 1, select('#', ...), 2 do
|
||||
local f = select(i, ...)
|
||||
local a = select(i+1, ...)
|
||||
if type(f) ~= "function" then
|
||||
if f == v then
|
||||
return true
|
||||
end
|
||||
i = i - 1
|
||||
elseif f(v, unpack(a)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
_M['and'] = function(v, ...)
|
||||
local i
|
||||
for i = 1, select('#', ...), 2 do
|
||||
local f = select(i, ...)
|
||||
local a = select(i+1, ...)
|
||||
if type(f) ~= "function" then
|
||||
if f ~= v then
|
||||
return false
|
||||
end
|
||||
i = i - 1
|
||||
elseif not f(v, unpack(a)) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function neg(v, ...)
|
||||
return _M['or'](v:gsub("^%s*!%s*", ""), ...)
|
||||
end
|
||||
|
||||
function list(v, subvalidator, subargs)
|
||||
if type(subvalidator) ~= "function" then
|
||||
return false
|
||||
end
|
||||
local token
|
||||
for token in v:gmatch("%S+") do
|
||||
if not subvalidator(token, unpack(subargs)) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function bool(val)
|
||||
if val == "1" or val == "yes" or val == "on" or val == "true" then
|
||||
return true
|
||||
elseif val == "0" or val == "no" or val == "off" or val == "false" then
|
||||
return true
|
||||
elseif val == "" or val == nil then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function uinteger(val)
|
||||
local n = tonumber(val)
|
||||
if n ~= nil and math.floor(n) == n and n >= 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function integer(val)
|
||||
local n = tonumber(val)
|
||||
if n ~= nil and math.floor(n) == n then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function ufloat(val)
|
||||
local n = tonumber(val)
|
||||
return ( n ~= nil and n >= 0 )
|
||||
end
|
||||
|
||||
function float(val)
|
||||
return ( tonumber(val) ~= nil )
|
||||
end
|
||||
|
||||
function ipaddr(val)
|
||||
return ip4addr(val) or ip6addr(val)
|
||||
end
|
||||
|
||||
function ip4addr(val)
|
||||
if val then
|
||||
return ip.IPv4(val) and true or false
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function ip4prefix(val)
|
||||
val = tonumber(val)
|
||||
return ( val and val >= 0 and val <= 32 )
|
||||
end
|
||||
|
||||
function ip6addr(val)
|
||||
if val then
|
||||
return ip.IPv6(val) and true or false
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function ip6prefix(val)
|
||||
val = tonumber(val)
|
||||
return ( val and val >= 0 and val <= 128 )
|
||||
end
|
||||
|
||||
function cidr(val)
|
||||
return cidr4(val) or cidr6(val)
|
||||
end
|
||||
|
||||
function cidr4(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
|
||||
return ip4addr(ip) and ip4prefix(mask)
|
||||
end
|
||||
|
||||
function cidr6(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
|
||||
return ip6addr(ip) and ip6prefix(mask)
|
||||
end
|
||||
|
||||
function ipnet4(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
|
||||
return ip4addr(ip) and ip4addr(mask)
|
||||
end
|
||||
|
||||
function ipnet6(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
|
||||
return ip6addr(ip) and ip6addr(mask)
|
||||
end
|
||||
|
||||
function ipmask(val)
|
||||
return ipmask4(val) or ipmask6(val)
|
||||
end
|
||||
|
||||
function ipmask4(val)
|
||||
return cidr4(val) or ipnet4(val) or ip4addr(val)
|
||||
end
|
||||
|
||||
function ipmask6(val)
|
||||
return cidr6(val) or ipnet6(val) or ip6addr(val)
|
||||
end
|
||||
|
||||
function ip6hostid(val)
|
||||
if val == "eui64" or val == "random" then
|
||||
return true
|
||||
else
|
||||
local addr = ip.IPv6(val)
|
||||
if addr and addr:prefix() == 128 and addr:lower("::1:0:0:0:0") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function port(val)
|
||||
val = tonumber(val)
|
||||
return ( val and val >= 0 and val <= 65535 )
|
||||
end
|
||||
|
||||
function portrange(val)
|
||||
local p1, p2 = val:match("^(%d+)%-(%d+)$")
|
||||
if p1 and p2 and port(p1) and port(p2) then
|
||||
return true
|
||||
else
|
||||
return port(val)
|
||||
end
|
||||
end
|
||||
|
||||
function macaddr(val)
|
||||
return ip.checkmac(val) and true or false
|
||||
end
|
||||
|
||||
function hostname(val, strict)
|
||||
if val and (#val < 254) and (
|
||||
val:match("^[a-zA-Z_]+$") or
|
||||
(val:match("^[a-zA-Z0-9_][a-zA-Z0-9_%-%.]*[a-zA-Z0-9]$") and
|
||||
val:match("[^0-9%.]"))
|
||||
) then
|
||||
return (not strict or not val:match("^_"))
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function host(val, ipv4only)
|
||||
return hostname(val) or ((ipv4only == 1) and ip4addr(val)) or ((not (ipv4only == 1)) and ipaddr(val))
|
||||
end
|
||||
|
||||
function network(val)
|
||||
return uciname(val) or host(val)
|
||||
end
|
||||
|
||||
function hostport(val, ipv4only)
|
||||
local h, p = val:match("^([^:]+):([^:]+)$")
|
||||
return not not (h and p and host(h, ipv4only) and port(p))
|
||||
end
|
||||
|
||||
function ip4addrport(val, bracket)
|
||||
local h, p = val:match("^([^:]+):([^:]+)$")
|
||||
return (h and p and ip4addr(h) and port(p))
|
||||
end
|
||||
|
||||
function ip4addrport(val)
|
||||
local h, p = val:match("^([^:]+):([^:]+)$")
|
||||
return (h and p and ip4addr(h) and port(p))
|
||||
end
|
||||
|
||||
function ipaddrport(val, bracket)
|
||||
local h, p = val:match("^([^%[%]:]+):([^:]+)$")
|
||||
if (h and p and ip4addr(h) and port(p)) then
|
||||
return true
|
||||
elseif (bracket == 1) then
|
||||
h, p = val:match("^%[(.+)%]:([^:]+)$")
|
||||
if (h and p and ip6addr(h) and port(p)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
h, p = val:match("^([^%[%]]+):([^:]+)$")
|
||||
return (h and p and ip6addr(h) and port(p))
|
||||
end
|
||||
|
||||
function wpakey(val)
|
||||
if #val == 64 then
|
||||
return (val:match("^[a-fA-F0-9]+$") ~= nil)
|
||||
else
|
||||
return (#val >= 8) and (#val <= 63)
|
||||
end
|
||||
end
|
||||
|
||||
function wepkey(val)
|
||||
if val:sub(1, 2) == "s:" then
|
||||
val = val:sub(3)
|
||||
end
|
||||
|
||||
if (#val == 10) or (#val == 26) then
|
||||
return (val:match("^[a-fA-F0-9]+$") ~= nil)
|
||||
else
|
||||
return (#val == 5) or (#val == 13)
|
||||
end
|
||||
end
|
||||
|
||||
function hexstring(val)
|
||||
if val then
|
||||
return (val:match("^[a-fA-F0-9]+$") ~= nil)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function hex(val, maxbytes)
|
||||
maxbytes = tonumber(maxbytes)
|
||||
if val and maxbytes ~= nil then
|
||||
return ((val:match("^0x[a-fA-F0-9]+$") ~= nil) and (#val <= 2 + maxbytes * 2))
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function base64(val)
|
||||
if val then
|
||||
return (val:match("^[a-zA-Z0-9/+]+=?=?$") ~= nil) and (math.fmod(#val, 4) == 0)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function string(val)
|
||||
return true -- Everything qualifies as valid string
|
||||
end
|
||||
|
||||
function directory(val, seen)
|
||||
local s = fs.stat(val)
|
||||
seen = seen or { }
|
||||
|
||||
if s and not seen[s.ino] then
|
||||
seen[s.ino] = true
|
||||
if s.type == "dir" then
|
||||
return true
|
||||
elseif s.type == "lnk" then
|
||||
return directory( fs.readlink(val), seen )
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function file(val, seen)
|
||||
local s = fs.stat(val)
|
||||
seen = seen or { }
|
||||
|
||||
if s and not seen[s.ino] then
|
||||
seen[s.ino] = true
|
||||
if s.type == "reg" then
|
||||
return true
|
||||
elseif s.type == "lnk" then
|
||||
return file( fs.readlink(val), seen )
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function device(val, seen)
|
||||
local s = fs.stat(val)
|
||||
seen = seen or { }
|
||||
|
||||
if s and not seen[s.ino] then
|
||||
seen[s.ino] = true
|
||||
if s.type == "chr" or s.type == "blk" then
|
||||
return true
|
||||
elseif s.type == "lnk" then
|
||||
return device( fs.readlink(val), seen )
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function uciname(val)
|
||||
return (val:match("^[a-zA-Z0-9_]+$") ~= nil)
|
||||
end
|
||||
|
||||
function range(val, min, max)
|
||||
val = tonumber(val)
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
|
||||
if val ~= nil and min ~= nil and max ~= nil then
|
||||
return ((val >= min) and (val <= max))
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function min(val, min)
|
||||
val = tonumber(val)
|
||||
min = tonumber(min)
|
||||
|
||||
if val ~= nil and min ~= nil then
|
||||
return (val >= min)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function max(val, max)
|
||||
val = tonumber(val)
|
||||
max = tonumber(max)
|
||||
|
||||
if val ~= nil and max ~= nil then
|
||||
return (val <= max)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function rangelength(val, min, max)
|
||||
val = tostring(val)
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
|
||||
if val ~= nil and min ~= nil and max ~= nil then
|
||||
return ((#val >= min) and (#val <= max))
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function minlength(val, min)
|
||||
val = tostring(val)
|
||||
min = tonumber(min)
|
||||
|
||||
if val ~= nil and min ~= nil then
|
||||
return (#val >= min)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function maxlength(val, max)
|
||||
val = tostring(val)
|
||||
max = tonumber(max)
|
||||
|
||||
if val ~= nil and max ~= nil then
|
||||
return (#val <= max)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function phonedigit(val)
|
||||
return (val:match("^[0-9%*#!%.]+$") ~= nil)
|
||||
end
|
||||
|
||||
function timehhmmss(val)
|
||||
return (val:match("^[0-6][0-9]:[0-6][0-9]:[0-6][0-9]$") ~= nil)
|
||||
end
|
||||
|
||||
function dateyyyymmdd(val)
|
||||
if val ~= nil then
|
||||
yearstr, monthstr, daystr = val:match("^(%d%d%d%d)-(%d%d)-(%d%d)$")
|
||||
if (yearstr == nil) or (monthstr == nil) or (daystr == nil) then
|
||||
return false;
|
||||
end
|
||||
year = tonumber(yearstr)
|
||||
month = tonumber(monthstr)
|
||||
day = tonumber(daystr)
|
||||
if (year == nil) or (month == nil) or (day == nil) then
|
||||
return false;
|
||||
end
|
||||
|
||||
local days_in_month = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||
|
||||
local function is_leap_year(year)
|
||||
return (year % 4 == 0) and ((year % 100 ~= 0) or (year % 400 == 0))
|
||||
end
|
||||
|
||||
function get_days_in_month(month, year)
|
||||
if (month == 2) and is_leap_year(year) then
|
||||
return 29
|
||||
else
|
||||
return days_in_month[month]
|
||||
end
|
||||
end
|
||||
if (year < 2015) then
|
||||
return false
|
||||
end
|
||||
if ((month == 0) or (month > 12)) then
|
||||
return false
|
||||
end
|
||||
if ((day == 0) or (day > get_days_in_month(month, year))) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function unique(val)
|
||||
return true
|
||||
end
|
||||
568
modules/luci-compat/luasrc/model/firewall.lua
Normal file
568
modules/luci-compat/luasrc/model/firewall.lua
Normal file
@@ -0,0 +1,568 @@
|
||||
-- Copyright 2009 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local type, pairs, ipairs, table, luci, math
|
||||
= type, pairs, ipairs, table, luci, math
|
||||
|
||||
local tpl = require "luci.template.parser"
|
||||
local utl = require "luci.util"
|
||||
local uci = require "luci.model.uci"
|
||||
|
||||
module "luci.model.firewall"
|
||||
|
||||
|
||||
local uci_r, uci_s
|
||||
|
||||
function _valid_id(x)
|
||||
return (x and #x > 0 and x:match("^[a-zA-Z0-9_]+$"))
|
||||
end
|
||||
|
||||
function _get(c, s, o)
|
||||
return uci_r:get(c, s, o)
|
||||
end
|
||||
|
||||
function _set(c, s, o, v)
|
||||
if v ~= nil then
|
||||
if type(v) == "boolean" then v = v and "1" or "0" end
|
||||
return uci_r:set(c, s, o, v)
|
||||
else
|
||||
return uci_r:delete(c, s, o)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function init(cursor)
|
||||
uci_r = cursor or uci_r or uci.cursor()
|
||||
uci_s = uci_r:substate()
|
||||
|
||||
return _M
|
||||
end
|
||||
|
||||
function save(self, ...)
|
||||
uci_r:save(...)
|
||||
uci_r:load(...)
|
||||
end
|
||||
|
||||
function commit(self, ...)
|
||||
uci_r:commit(...)
|
||||
uci_r:load(...)
|
||||
end
|
||||
|
||||
function get_defaults()
|
||||
return defaults()
|
||||
end
|
||||
|
||||
function new_zone(self)
|
||||
local name = "newzone"
|
||||
local count = 1
|
||||
|
||||
while self:get_zone(name) do
|
||||
count = count + 1
|
||||
name = "newzone%d" % count
|
||||
end
|
||||
|
||||
return self:add_zone(name)
|
||||
end
|
||||
|
||||
function add_zone(self, n)
|
||||
if _valid_id(n) and not self:get_zone(n) then
|
||||
local d = defaults()
|
||||
local z = uci_r:section("firewall", "zone", nil, {
|
||||
name = n,
|
||||
network = " ",
|
||||
input = d:input() or "DROP",
|
||||
forward = d:forward() or "DROP",
|
||||
output = d:output() or "DROP"
|
||||
})
|
||||
|
||||
return z and zone(z)
|
||||
end
|
||||
end
|
||||
|
||||
function get_zone(self, n)
|
||||
if uci_r:get("firewall", n) == "zone" then
|
||||
return zone(n)
|
||||
else
|
||||
local z
|
||||
uci_r:foreach("firewall", "zone",
|
||||
function(s)
|
||||
if n and s.name == n then
|
||||
z = s['.name']
|
||||
return false
|
||||
end
|
||||
end)
|
||||
return z and zone(z)
|
||||
end
|
||||
end
|
||||
|
||||
function get_zones(self)
|
||||
local zones = { }
|
||||
local znl = { }
|
||||
|
||||
uci_r:foreach("firewall", "zone",
|
||||
function(s)
|
||||
if s.name then
|
||||
znl[s.name] = zone(s['.name'])
|
||||
end
|
||||
end)
|
||||
|
||||
local z
|
||||
for z in utl.kspairs(znl) do
|
||||
zones[#zones+1] = znl[z]
|
||||
end
|
||||
|
||||
return zones
|
||||
end
|
||||
|
||||
function get_zone_by_network(self, net)
|
||||
local z
|
||||
|
||||
uci_r:foreach("firewall", "zone",
|
||||
function(s)
|
||||
if s.name and net then
|
||||
local n
|
||||
for n in utl.imatch(s.network or s.name) do
|
||||
if n == net then
|
||||
z = s['.name']
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return z and zone(z)
|
||||
end
|
||||
|
||||
function del_zone(self, n)
|
||||
local r = false
|
||||
|
||||
if uci_r:get("firewall", n) == "zone" then
|
||||
local z = uci_r:get("firewall", n, "name")
|
||||
r = uci_r:delete("firewall", n)
|
||||
n = z
|
||||
else
|
||||
uci_r:foreach("firewall", "zone",
|
||||
function(s)
|
||||
if n and s.name == n then
|
||||
r = uci_r:delete("firewall", s['.name'])
|
||||
return false
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if r then
|
||||
uci_r:foreach("firewall", "rule",
|
||||
function(s)
|
||||
if s.src == n or s.dest == n then
|
||||
uci_r:delete("firewall", s['.name'])
|
||||
end
|
||||
end)
|
||||
|
||||
uci_r:foreach("firewall", "redirect",
|
||||
function(s)
|
||||
if s.src == n or s.dest == n then
|
||||
uci_r:delete("firewall", s['.name'])
|
||||
end
|
||||
end)
|
||||
|
||||
uci_r:foreach("firewall", "forwarding",
|
||||
function(s)
|
||||
if s.src == n or s.dest == n then
|
||||
uci_r:delete("firewall", s['.name'])
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
return r
|
||||
end
|
||||
|
||||
function rename_zone(self, old, new)
|
||||
local r = false
|
||||
|
||||
if _valid_id(new) and not self:get_zone(new) then
|
||||
uci_r:foreach("firewall", "zone",
|
||||
function(s)
|
||||
if old and s.name == old then
|
||||
if not s.network then
|
||||
uci_r:set("firewall", s['.name'], "network", old)
|
||||
end
|
||||
uci_r:set("firewall", s['.name'], "name", new)
|
||||
r = true
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
if r then
|
||||
uci_r:foreach("firewall", "rule",
|
||||
function(s)
|
||||
if s.src == old then
|
||||
uci_r:set("firewall", s['.name'], "src", new)
|
||||
end
|
||||
if s.dest == old then
|
||||
uci_r:set("firewall", s['.name'], "dest", new)
|
||||
end
|
||||
end)
|
||||
|
||||
uci_r:foreach("firewall", "redirect",
|
||||
function(s)
|
||||
if s.src == old then
|
||||
uci_r:set("firewall", s['.name'], "src", new)
|
||||
end
|
||||
if s.dest == old then
|
||||
uci_r:set("firewall", s['.name'], "dest", new)
|
||||
end
|
||||
end)
|
||||
|
||||
uci_r:foreach("firewall", "forwarding",
|
||||
function(s)
|
||||
if s.src == old then
|
||||
uci_r:set("firewall", s['.name'], "src", new)
|
||||
end
|
||||
if s.dest == old then
|
||||
uci_r:set("firewall", s['.name'], "dest", new)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
return r
|
||||
end
|
||||
|
||||
function del_network(self, net)
|
||||
local z
|
||||
if net then
|
||||
for _, z in ipairs(self:get_zones()) do
|
||||
z:del_network(net)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
defaults = utl.class()
|
||||
function defaults.__init__(self)
|
||||
uci_r:foreach("firewall", "defaults",
|
||||
function(s)
|
||||
self.sid = s['.name']
|
||||
return false
|
||||
end)
|
||||
|
||||
self.sid = self.sid or uci_r:section("firewall", "defaults", nil, { })
|
||||
end
|
||||
|
||||
function defaults.get(self, opt)
|
||||
return _get("firewall", self.sid, opt)
|
||||
end
|
||||
|
||||
function defaults.set(self, opt, val)
|
||||
return _set("firewall", self.sid, opt, val)
|
||||
end
|
||||
|
||||
function defaults.syn_flood(self)
|
||||
return (self:get("syn_flood") == "1")
|
||||
end
|
||||
|
||||
function defaults.drop_invalid(self)
|
||||
return (self:get("drop_invalid") == "1")
|
||||
end
|
||||
|
||||
function defaults.input(self)
|
||||
return self:get("input") or "DROP"
|
||||
end
|
||||
|
||||
function defaults.forward(self)
|
||||
return self:get("forward") or "DROP"
|
||||
end
|
||||
|
||||
function defaults.output(self)
|
||||
return self:get("output") or "DROP"
|
||||
end
|
||||
|
||||
|
||||
zone = utl.class()
|
||||
function zone.__init__(self, z)
|
||||
if uci_r:get("firewall", z) == "zone" then
|
||||
self.sid = z
|
||||
self.data = uci_r:get_all("firewall", z)
|
||||
else
|
||||
uci_r:foreach("firewall", "zone",
|
||||
function(s)
|
||||
if s.name == z then
|
||||
self.sid = s['.name']
|
||||
self.data = s
|
||||
return false
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function zone.get(self, opt)
|
||||
return _get("firewall", self.sid, opt)
|
||||
end
|
||||
|
||||
function zone.set(self, opt, val)
|
||||
return _set("firewall", self.sid, opt, val)
|
||||
end
|
||||
|
||||
function zone.masq(self)
|
||||
return (self:get("masq") == "1")
|
||||
end
|
||||
|
||||
function zone.name(self)
|
||||
return self:get("name")
|
||||
end
|
||||
|
||||
function zone.network(self)
|
||||
return self:get("network")
|
||||
end
|
||||
|
||||
function zone.input(self)
|
||||
return self:get("input") or defaults():input() or "DROP"
|
||||
end
|
||||
|
||||
function zone.forward(self)
|
||||
return self:get("forward") or defaults():forward() or "DROP"
|
||||
end
|
||||
|
||||
function zone.output(self)
|
||||
return self:get("output") or defaults():output() or "DROP"
|
||||
end
|
||||
|
||||
function zone.add_network(self, net)
|
||||
if uci_r:get("network", net) == "interface" then
|
||||
local nets = { }
|
||||
|
||||
local n
|
||||
for n in utl.imatch(self:get("network") or self:get("name")) do
|
||||
if n ~= net then
|
||||
nets[#nets+1] = n
|
||||
end
|
||||
end
|
||||
|
||||
nets[#nets+1] = net
|
||||
|
||||
_M:del_network(net)
|
||||
self:set("network", table.concat(nets, " "))
|
||||
end
|
||||
end
|
||||
|
||||
function zone.del_network(self, net)
|
||||
local nets = { }
|
||||
|
||||
local n
|
||||
for n in utl.imatch(self:get("network") or self:get("name")) do
|
||||
if n ~= net then
|
||||
nets[#nets+1] = n
|
||||
end
|
||||
end
|
||||
|
||||
if #nets > 0 then
|
||||
self:set("network", table.concat(nets, " "))
|
||||
else
|
||||
self:set("network", " ")
|
||||
end
|
||||
end
|
||||
|
||||
function zone.get_networks(self)
|
||||
local nets = { }
|
||||
|
||||
local n
|
||||
for n in utl.imatch(self:get("network") or self:get("name")) do
|
||||
nets[#nets+1] = n
|
||||
end
|
||||
|
||||
return nets
|
||||
end
|
||||
|
||||
function zone.clear_networks(self)
|
||||
self:set("network", " ")
|
||||
end
|
||||
|
||||
function zone.get_forwardings_by(self, what)
|
||||
local name = self:name()
|
||||
local forwards = { }
|
||||
|
||||
uci_r:foreach("firewall", "forwarding",
|
||||
function(s)
|
||||
if s.src and s.dest and s[what] == name then
|
||||
forwards[#forwards+1] = forwarding(s['.name'])
|
||||
end
|
||||
end)
|
||||
|
||||
return forwards
|
||||
end
|
||||
|
||||
function zone.add_forwarding_to(self, dest)
|
||||
local exist, forward
|
||||
|
||||
for _, forward in ipairs(self:get_forwardings_by('src')) do
|
||||
if forward:dest() == dest then
|
||||
exist = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not exist and dest ~= self:name() and _valid_id(dest) then
|
||||
local s = uci_r:section("firewall", "forwarding", nil, {
|
||||
src = self:name(),
|
||||
dest = dest
|
||||
})
|
||||
|
||||
return s and forwarding(s)
|
||||
end
|
||||
end
|
||||
|
||||
function zone.add_forwarding_from(self, src)
|
||||
local exist, forward
|
||||
|
||||
for _, forward in ipairs(self:get_forwardings_by('dest')) do
|
||||
if forward:src() == src then
|
||||
exist = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not exist and src ~= self:name() and _valid_id(src) then
|
||||
local s = uci_r:section("firewall", "forwarding", nil, {
|
||||
src = src,
|
||||
dest = self:name()
|
||||
})
|
||||
|
||||
return s and forwarding(s)
|
||||
end
|
||||
end
|
||||
|
||||
function zone.del_forwardings_by(self, what)
|
||||
local name = self:name()
|
||||
|
||||
uci_r:delete_all("firewall", "forwarding",
|
||||
function(s)
|
||||
return (s.src and s.dest and s[what] == name)
|
||||
end)
|
||||
end
|
||||
|
||||
function zone.add_redirect(self, options)
|
||||
options = options or { }
|
||||
options.src = self:name()
|
||||
|
||||
local s = uci_r:section("firewall", "redirect", nil, options)
|
||||
return s and redirect(s)
|
||||
end
|
||||
|
||||
function zone.add_rule(self, options)
|
||||
options = options or { }
|
||||
options.src = self:name()
|
||||
|
||||
local s = uci_r:section("firewall", "rule", nil, options)
|
||||
return s and rule(s)
|
||||
end
|
||||
|
||||
function zone.get_color(self)
|
||||
if self and self:name() == "lan" then
|
||||
return "#90f090"
|
||||
elseif self and self:name() == "wan" then
|
||||
return "#f09090"
|
||||
elseif self then
|
||||
math.randomseed(tpl.hash(self:name()))
|
||||
|
||||
local r = math.random(128)
|
||||
local g = math.random(128)
|
||||
local min = 0
|
||||
local max = 128
|
||||
|
||||
if ( r + g ) < 128 then
|
||||
min = 128 - r - g
|
||||
else
|
||||
max = 255 - r - g
|
||||
end
|
||||
|
||||
local b = min + math.floor( math.random() * ( max - min ) )
|
||||
|
||||
return "#%02x%02x%02x" % { 0xFF - r, 0xFF - g, 0xFF - b }
|
||||
else
|
||||
return "#eeeeee"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
forwarding = utl.class()
|
||||
function forwarding.__init__(self, f)
|
||||
self.sid = f
|
||||
end
|
||||
|
||||
function forwarding.src(self)
|
||||
return uci_r:get("firewall", self.sid, "src")
|
||||
end
|
||||
|
||||
function forwarding.dest(self)
|
||||
return uci_r:get("firewall", self.sid, "dest")
|
||||
end
|
||||
|
||||
function forwarding.src_zone(self)
|
||||
local z = zone(self:src())
|
||||
return z.sid and z
|
||||
end
|
||||
|
||||
function forwarding.dest_zone(self)
|
||||
local z = zone(self:dest())
|
||||
return z.sid and z
|
||||
end
|
||||
|
||||
|
||||
rule = utl.class()
|
||||
function rule.__init__(self, f)
|
||||
self.sid = f
|
||||
end
|
||||
|
||||
function rule.get(self, opt)
|
||||
return _get("firewall", self.sid, opt)
|
||||
end
|
||||
|
||||
function rule.set(self, opt, val)
|
||||
return _set("firewall", self.sid, opt, val)
|
||||
end
|
||||
|
||||
function rule.src(self)
|
||||
return uci_r:get("firewall", self.sid, "src")
|
||||
end
|
||||
|
||||
function rule.dest(self)
|
||||
return uci_r:get("firewall", self.sid, "dest")
|
||||
end
|
||||
|
||||
function rule.src_zone(self)
|
||||
return zone(self:src())
|
||||
end
|
||||
|
||||
function rule.dest_zone(self)
|
||||
return zone(self:dest())
|
||||
end
|
||||
|
||||
|
||||
redirect = utl.class()
|
||||
function redirect.__init__(self, f)
|
||||
self.sid = f
|
||||
end
|
||||
|
||||
function redirect.get(self, opt)
|
||||
return _get("firewall", self.sid, opt)
|
||||
end
|
||||
|
||||
function redirect.set(self, opt, val)
|
||||
return _set("firewall", self.sid, opt, val)
|
||||
end
|
||||
|
||||
function redirect.src(self)
|
||||
return uci_r:get("firewall", self.sid, "src")
|
||||
end
|
||||
|
||||
function redirect.dest(self)
|
||||
return uci_r:get("firewall", self.sid, "dest")
|
||||
end
|
||||
|
||||
function redirect.src_zone(self)
|
||||
return zone(self:src())
|
||||
end
|
||||
|
||||
function redirect.dest_zone(self)
|
||||
return zone(self:dest())
|
||||
end
|
||||
10
modules/luci-compat/luasrc/view/cbi/browser.htm
Normal file
10
modules/luci-compat/luasrc/view/cbi/browser.htm
Normal file
@@ -0,0 +1,10 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<input class="cbi-input-text" type="text"<%=
|
||||
attr("id", cbid) ..
|
||||
attr("name", cbid) ..
|
||||
attr("value", self:cfgvalue(section) or self.default) ..
|
||||
attr("data-browser", self.default_path or "")
|
||||
%> />
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
7
modules/luci-compat/luasrc/view/cbi/button.htm
Normal file
7
modules/luci-compat/luasrc/view/cbi/button.htm
Normal file
@@ -0,0 +1,7 @@
|
||||
<%+cbi/valueheader%>
|
||||
<% if self:cfgvalue(section) ~= false then %>
|
||||
<input class="cbi-button cbi-button-<%=self.inputstyle or "button" %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> />
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
<%+cbi/valuefooter%>
|
||||
2
modules/luci-compat/luasrc/view/cbi/cell_valuefooter.htm
Normal file
2
modules/luci-compat/luasrc/view/cbi/cell_valuefooter.htm
Normal file
@@ -0,0 +1,2 @@
|
||||
</div>
|
||||
</div>
|
||||
12
modules/luci-compat/luasrc/view/cbi/cell_valueheader.htm
Normal file
12
modules/luci-compat/luasrc/view/cbi/cell_valueheader.htm
Normal file
@@ -0,0 +1,12 @@
|
||||
<%-
|
||||
local title = luci.util.trim(striptags(self.title))
|
||||
local descr = luci.util.trim(striptags(self.description))
|
||||
local ftype = self.typename or (self.template and self.template:gsub("^.+/", ""))
|
||||
-%>
|
||||
<div class="td cbi-value-field<% if self.error and self.error[section] then %> cbi-value-error<% end %><% if self.password then %> nowrap<% end %>"<%=
|
||||
attr("data-name", self.option) ..
|
||||
ifattr(ftype and #ftype > 0, "data-type", ftype) ..
|
||||
ifattr(title and #title > 0, "data-title", title, true) ..
|
||||
ifattr(descr and #descr > 0, "data-description", descr, true)
|
||||
%>>
|
||||
<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>">
|
||||
1
modules/luci-compat/luasrc/view/cbi/compound.htm
Normal file
1
modules/luci-compat/luasrc/view/cbi/compound.htm
Normal file
@@ -0,0 +1 @@
|
||||
<%- self:render_children() %>
|
||||
24
modules/luci-compat/luasrc/view/cbi/delegator.htm
Normal file
24
modules/luci-compat/luasrc/view/cbi/delegator.htm
Normal file
@@ -0,0 +1,24 @@
|
||||
<%- self.active:render() %>
|
||||
<div class="cbi-page-actions">
|
||||
<input type="hidden" name="cbi.delg.current" value="<%=self.current%>" />
|
||||
<% for _, x in ipairs(self.chain) do %>
|
||||
<input type="hidden" name="cbi.delg.path" value="<%=x%>" />
|
||||
<% end %>
|
||||
<% if not self.disallow_pageactions then %>
|
||||
<% if self.allow_finish and not self:get_next(self.current) then %>
|
||||
<input class="cbi-button cbi-button-finish" type="submit" value="<%:Finish%>" />
|
||||
<% elseif self:get_next(self.current) then %>
|
||||
<input class="cbi-button cbi-button-next" type="submit" value="<%:Next »%>" />
|
||||
<% end %>
|
||||
<% if self.allow_cancel then %>
|
||||
<input class="cbi-button cbi-button-cancel" type="submit" name="cbi.cancel" value="<%:Cancel%>" />
|
||||
<% end %>
|
||||
<% if self.allow_reset then %>
|
||||
<input class="cbi-button cbi-button-reset" type="reset" value="<%:Reset%>" />
|
||||
<% end %>
|
||||
<% if self.allow_back and self:get_prev(self.current) then %>
|
||||
<input class="cbi-button cbi-button-back" type="submit" name="cbi.delg.back" value="<%:« Back%>" />
|
||||
<% end %>
|
||||
<% end %>
|
||||
<script type="text/javascript">cbi_d_update();</script>
|
||||
</div>
|
||||
19
modules/luci-compat/luasrc/view/cbi/dropdown.htm
Normal file
19
modules/luci-compat/luasrc/view/cbi/dropdown.htm
Normal file
@@ -0,0 +1,19 @@
|
||||
<%+cbi/valueheader%>
|
||||
<div<%=attr("data-ui-widget", luci.util.serialize_json({
|
||||
"Dropdown", self:cfgvalue(section) or self.default, self:choices(), {
|
||||
id = cbid,
|
||||
name = cbid,
|
||||
sort = self.keylist,
|
||||
multiple = self.multiple,
|
||||
datatype = self.datatype,
|
||||
optional = self.optional or self.rmempty,
|
||||
readonly = self.readonly,
|
||||
maxlength = self.maxlength,
|
||||
placeholder = self.placeholder,
|
||||
display_items = self.display or self.size or 3,
|
||||
dropdown_items = self.dropdown or self.display or self.size or 5,
|
||||
custom_placeholder = self.custom or
|
||||
(self.multiple and translate("Enter custom values") or translate("Enter custom value"))
|
||||
}
|
||||
}))%>></div>
|
||||
<%+cbi/valuefooter%>
|
||||
13
modules/luci-compat/luasrc/view/cbi/dvalue.htm
Normal file
13
modules/luci-compat/luasrc/view/cbi/dvalue.htm
Normal file
@@ -0,0 +1,13 @@
|
||||
<%+cbi/valueheader%>
|
||||
<% if self.href then %><a href="<%=self.href%>"><% end -%>
|
||||
<%
|
||||
local val = self:cfgvalue(section) or self.default or ""
|
||||
if not self.rawhtml then
|
||||
write(pcdata(val))
|
||||
else
|
||||
write(val)
|
||||
end
|
||||
%>
|
||||
<%- if self.href then %></a><%end%>
|
||||
<input type="hidden" id="<%=cbid%>" value="<%=pcdata(self:cfgvalue(section) or self.default or "")%>" />
|
||||
<%+cbi/valuefooter%>
|
||||
12
modules/luci-compat/luasrc/view/cbi/dynlist.htm
Normal file
12
modules/luci-compat/luasrc/view/cbi/dynlist.htm
Normal file
@@ -0,0 +1,12 @@
|
||||
<%+cbi/valueheader%>
|
||||
<div<%=attr("data-ui-widget", luci.util.serialize_json({
|
||||
"DynamicList", self:cfgvalue(section) or self.default, self:choices(), {
|
||||
name = cbid,
|
||||
size = self.size,
|
||||
sort = self.keylist,
|
||||
datatype = self.datatype,
|
||||
optional = self.optional or self.rmempty,
|
||||
placeholder = self.placeholder
|
||||
}
|
||||
}))%>></div>
|
||||
<%+cbi/valuefooter%>
|
||||
19
modules/luci-compat/luasrc/view/cbi/error.htm
Normal file
19
modules/luci-compat/luasrc/view/cbi/error.htm
Normal file
@@ -0,0 +1,19 @@
|
||||
<div class="cbi-map" id="cbi-<%=self.config%>">
|
||||
<% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
|
||||
<% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
|
||||
|
||||
<p class="alert-message danger">
|
||||
<%: The configuration file could not be loaded due to the following error: %><br />
|
||||
<code><%=pcdata(self.error)%></code>
|
||||
</p>
|
||||
|
||||
<textarea name="cbi.source" style="width:100%; margin-bottom:1em" rows="<%=math.max(self.source:cmatch("\n"), 10)%>"><%=pcdata(self.source)%></textarea>
|
||||
|
||||
<p class="alert-message">
|
||||
<%: Edit the raw configuration data above to fix any error and hit "Save" to reload the page. %>
|
||||
</p>
|
||||
|
||||
<div class="cbi-page-actions">
|
||||
<input class="cbi-button cbi-button-apply" type="submit" name="cbi.save" value="<%:Save%>" />
|
||||
</div>
|
||||
</div>
|
||||
41
modules/luci-compat/luasrc/view/cbi/footer.htm
Normal file
41
modules/luci-compat/luasrc/view/cbi/footer.htm
Normal file
@@ -0,0 +1,41 @@
|
||||
<%
|
||||
local display_back = (redirect and not flow.hidebackbtn)
|
||||
local display_skip = (flow.skip)
|
||||
local display_apply = (not autoapply and not flow.hideapplybtn)
|
||||
local display_save = (not flow.hidesavebtn)
|
||||
local display_reset = (not flow.hideresetbtn)
|
||||
|
||||
if pageaction and
|
||||
(display_back or display_skip or display_apply or display_save or display_reset)
|
||||
then
|
||||
%><div class="cbi-page-actions"><%
|
||||
|
||||
if display_back then
|
||||
%><input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> <%
|
||||
end
|
||||
|
||||
if display_skip then
|
||||
%><input class="cbi-button cbi-button-skip" type="button" value="<%:Skip%>" onclick="cbi_submit(this, 'cbi.skip')" /> <%
|
||||
end
|
||||
|
||||
if display_apply then
|
||||
%><input class="cbi-button cbi-button-apply" type="button" value="<%:Save & Apply%>" onclick="cbi_submit(this, 'cbi.apply')" /> <%
|
||||
end
|
||||
|
||||
if display_save then
|
||||
%><input class="cbi-button cbi-button-save" type="submit" value="<%:Save%>" /> <%
|
||||
end
|
||||
|
||||
if display_reset then
|
||||
%><input class="cbi-button cbi-button-reset" type="button" value="<%:Reset%>" onclick="location.href='<%=REQUEST_URI%>'" /> <%
|
||||
end
|
||||
|
||||
%></div><%
|
||||
end
|
||||
%>
|
||||
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">cbi_init();</script>
|
||||
|
||||
<%+footer%>
|
||||
12
modules/luci-compat/luasrc/view/cbi/full_valuefooter.htm
Normal file
12
modules/luci-compat/luasrc/view/cbi/full_valuefooter.htm
Normal file
@@ -0,0 +1,12 @@
|
||||
<% if self.description and #self.description > 0 then -%>
|
||||
<% if not luci.util.instanceof(self, luci.cbi.DynamicList) and (not luci.util.instanceof(self, luci.cbi.Flag) or self.orientation == "horizontal") then -%>
|
||||
<br />
|
||||
<%- end %>
|
||||
<div class="cbi-value-description">
|
||||
<%=self.description%>
|
||||
</div>
|
||||
<%- end %>
|
||||
<%- if self.title and #self.title > 0 then -%>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
9
modules/luci-compat/luasrc/view/cbi/full_valueheader.htm
Normal file
9
modules/luci-compat/luasrc/view/cbi/full_valueheader.htm
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="cbi-value<% if self.error and self.error[section] then %> cbi-value-error<% end %><% if self.last_child then %> cbi-value-last<% end %><% if self.password then %> nowrap<% end %>" id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>">
|
||||
<%- if self.title and #self.title > 0 then -%>
|
||||
<label class="cbi-value-title"<%= attr("for", cbid) %>>
|
||||
<%- if self.titleref then -%><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=self.titleref%>"><%- end -%>
|
||||
<%-=self.title-%>
|
||||
<%- if self.titleref then -%></a><%- end -%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<%- end -%>
|
||||
12
modules/luci-compat/luasrc/view/cbi/fvalue.htm
Normal file
12
modules/luci-compat/luasrc/view/cbi/fvalue.htm
Normal file
@@ -0,0 +1,12 @@
|
||||
<%+cbi/valueheader%>
|
||||
<div<%=attr("data-ui-widget", luci.util.serialize_json({
|
||||
"Checkbox", self:cfgvalue(section) or self.default, {
|
||||
id = cbid,
|
||||
name = cbid,
|
||||
readonly = self.readonly,
|
||||
hiddenname = "cbi.cbe." .. self.config .. "." .. section .. "." .. self.option,
|
||||
value_enabled = self.enabled or 1,
|
||||
value_disabled = self.disabled or 0
|
||||
}
|
||||
}))%>></div>
|
||||
<%+cbi/valuefooter%>
|
||||
18
modules/luci-compat/luasrc/view/cbi/header.htm
Normal file
18
modules/luci-compat/luasrc/view/cbi/header.htm
Normal file
@@ -0,0 +1,18 @@
|
||||
<%+header%>
|
||||
<form method="post" name="cbi" action="<%=REQUEST_URI%>" enctype="multipart/form-data" onreset="return cbi_validate_reset(this)" onsubmit="return cbi_validate_form(this, '<%:Some fields are invalid, cannot save values!%>')"<%=
|
||||
attr("data-strings", luci.util.serialize_json({
|
||||
label = {
|
||||
choose = translate('-- Please choose --'),
|
||||
custom = translate('-- custom --'),
|
||||
},
|
||||
path = {
|
||||
resource = resource,
|
||||
browser = url("admin/filebrowser")
|
||||
}
|
||||
}))
|
||||
%>>
|
||||
<div>
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input type="hidden" name="cbi.submit" value="1" />
|
||||
<input type="submit" value="<%:Save%>" class="hidden" />
|
||||
</div>
|
||||
27
modules/luci-compat/luasrc/view/cbi/ipaddr.htm
Normal file
27
modules/luci-compat/luasrc/view/cbi/ipaddr.htm
Normal file
@@ -0,0 +1,27 @@
|
||||
<%+cbi/valueheader%>
|
||||
<script type="text/javascript">
|
||||
function switchToCIDRList(ev) {
|
||||
var input = ev.target.previousElementSibling,
|
||||
usecidr = document.getElementById(input.id + '_usecidr');
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
usecidr.value = '1';
|
||||
cbi_d_update();
|
||||
}
|
||||
</script>
|
||||
<input data-update="change"<%=
|
||||
attr("id", cbid) ..
|
||||
attr("name", cbid) ..
|
||||
attr("type", "text") ..
|
||||
attr("class", "cbi-input-text") ..
|
||||
attr("value", self:cfgvalue(section) or self.default) ..
|
||||
ifattr(self.size, "size") ..
|
||||
ifattr(self.placeholder, "placeholder") ..
|
||||
ifattr(self.datatype, "data-type", self.datatype) ..
|
||||
ifattr(self.datatype, "data-optional", self.optional or self.rmempty) ..
|
||||
ifattr(self.combobox_manual, "data-manual", self.combobox_manual) ..
|
||||
ifattr(#self.keylist > 0, "data-choices", { self.keylist, self.vallist })
|
||||
%> /><!--
|
||||
--><button class="cbi-button cbi-button-neutral" title="<%:Switch to CIDR list notation%>" aria-label="<%:Switch to CIDR list notation%>" onclick="switchToCIDRList(event)">…</button>
|
||||
<%+cbi/valuefooter%>
|
||||
14
modules/luci-compat/luasrc/view/cbi/lvalue.htm
Normal file
14
modules/luci-compat/luasrc/view/cbi/lvalue.htm
Normal file
@@ -0,0 +1,14 @@
|
||||
<%+cbi/valueheader%>
|
||||
<div<%=attr("data-ui-widget", luci.util.serialize_json({
|
||||
"Select", self:cfgvalue(section) or self.default, self:choices(), {
|
||||
id = cbid,
|
||||
name = cbid,
|
||||
size = self.size,
|
||||
sort = self.keylist,
|
||||
widget = self.widget,
|
||||
datatype = self.datatype,
|
||||
optional = self.optional,
|
||||
placeholder = self.placeholder
|
||||
}
|
||||
}))%>></div>
|
||||
<%+cbi/valuefooter%>
|
||||
40
modules/luci-compat/luasrc/view/cbi/map.htm
Normal file
40
modules/luci-compat/luasrc/view/cbi/map.htm
Normal file
@@ -0,0 +1,40 @@
|
||||
<%- if firstmap and messages then local msg; for _, msg in ipairs(messages) do -%>
|
||||
<div class="alert-message warning"><%=pcdata(msg)%></div>
|
||||
<%- end end -%>
|
||||
|
||||
<div class="cbi-map" id="cbi-<%=self.config%>">
|
||||
<% if self.title and #self.title > 0 then %>
|
||||
<h2 name="content"><%=self.title%></h2>
|
||||
<% end %>
|
||||
<% if self.description and #self.description > 0 then %>
|
||||
<div class="cbi-map-descr"><%=self.description%></div>
|
||||
<% end %>
|
||||
<% if self.tabbed then %>
|
||||
<div>
|
||||
<% for i, section in ipairs(self.children) do
|
||||
tab = section.section or section.sectiontype %>
|
||||
<div class="cbi-tabcontainer"<%=
|
||||
attr("id", "container.m-%s.%s" %{ self.config, tab }) ..
|
||||
attr("data-tab", tab) ..
|
||||
attr("data-tab-title", section.title or tab)
|
||||
%>>
|
||||
<% section:render() %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if not self.save then -%>
|
||||
<div class="cbi-section-error">
|
||||
<% for _, section in ipairs(self.children) do %>
|
||||
<% if section.error and section.error[section.section] then -%>
|
||||
<ul><li>
|
||||
<%:One or more invalid/required values on tab%>: <%=section.title or section.section or section.sectiontype%>
|
||||
</li></ul>
|
||||
<%- end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%- end %>
|
||||
<% else %>
|
||||
<%- self:render_children() %>
|
||||
<% end %>
|
||||
</div>
|
||||
24
modules/luci-compat/luasrc/view/cbi/mvalue.htm
Normal file
24
modules/luci-compat/luasrc/view/cbi/mvalue.htm
Normal file
@@ -0,0 +1,24 @@
|
||||
<%+cbi/valueheader%>
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local values = {}
|
||||
local value
|
||||
for value in util.imatch(self:cfgvalue(section) or self.default) do
|
||||
values[#values+1] = value
|
||||
end
|
||||
%>
|
||||
<div<%=attr("data-ui-widget", luci.util.serialize_json({
|
||||
"Select", values, self:choices(), {
|
||||
id = cbid,
|
||||
name = cbid,
|
||||
size = self.size,
|
||||
sort = self.keylist,
|
||||
multiple = true,
|
||||
widget = self.widget,
|
||||
datatype = self.datatype,
|
||||
optional = self.optional or self.rmempty,
|
||||
readonly = self.readonly,
|
||||
placeholder = self.placeholder
|
||||
}
|
||||
}))%>></div>
|
||||
<%+cbi/valuefooter%>
|
||||
29
modules/luci-compat/luasrc/view/cbi/nsection.htm
Normal file
29
modules/luci-compat/luasrc/view/cbi/nsection.htm
Normal file
@@ -0,0 +1,29 @@
|
||||
<% if self:cfgvalue(self.section) then section = self.section %>
|
||||
<div class="cbi-section">
|
||||
<% if self.title and #self.title > 0 then -%>
|
||||
<legend><%=self.title%></legend>
|
||||
<%- end %>
|
||||
<% if self.description and #self.description > 0 then -%>
|
||||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<%- end %>
|
||||
<% if self.addremove then -%>
|
||||
<div class="cbi-section-remove right">
|
||||
<input type="submit" class="cbi-button" name="cbi.rns.<%=self.config%>.<%=section%>" value="<%:Delete%>" />
|
||||
</div>
|
||||
<%- end %>
|
||||
<div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>">
|
||||
<%+cbi/ucisection%>
|
||||
</div>
|
||||
</div>
|
||||
<% elseif self.addremove then %>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<div class="cbi-section" id="cbi-<%=self.config%>-<%=self.section%>">
|
||||
<% if self.title and #self.title > 0 then -%>
|
||||
<legend><%=self.title%></legend>
|
||||
<%- end %>
|
||||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cns.<%=self.config%>.<%=self.section%>" value="<%:Add%>" />
|
||||
</div>
|
||||
<%- end %>
|
||||
<% end %>
|
||||
<!-- /nsection -->
|
||||
37
modules/luci-compat/luasrc/view/cbi/nullsection.htm
Normal file
37
modules/luci-compat/luasrc/view/cbi/nullsection.htm
Normal file
@@ -0,0 +1,37 @@
|
||||
<div class="cbi-section">
|
||||
<% if self.title and #self.title > 0 then -%>
|
||||
<legend><%=self.title%></legend>
|
||||
<%- end %>
|
||||
<% if self.description and #self.description > 0 then -%>
|
||||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<%- end %>
|
||||
<div class="cbi-section-node">
|
||||
<div id="cbi-<%=self.config%>-<%=tostring(self):sub(8)%>">
|
||||
<% self:render_children(1, scope or {}) %>
|
||||
</div>
|
||||
<% if self.error and self.error[1] then -%>
|
||||
<div class="cbi-section-error">
|
||||
<ul><% for _, e in ipairs(self.error[1]) do -%>
|
||||
<li>
|
||||
<%- if e == "invalid" then -%>
|
||||
<%:One or more fields contain invalid values!%>
|
||||
<%- elseif e == "missing" then -%>
|
||||
<%:One or more required fields have no value!%>
|
||||
<%- else -%>
|
||||
<%=pcdata(e)%>
|
||||
<%- end -%>
|
||||
</li>
|
||||
<%- end %></ul>
|
||||
</div>
|
||||
<%- end %>
|
||||
</div>
|
||||
</div>
|
||||
<%-
|
||||
if type(self.hidden) == "table" then
|
||||
for k, v in pairs(self.hidden) do
|
||||
-%>
|
||||
<input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" />
|
||||
<%-
|
||||
end
|
||||
end
|
||||
%>
|
||||
77
modules/luci-compat/luasrc/view/cbi/simpleform.htm
Normal file
77
modules/luci-compat/luasrc/view/cbi/simpleform.htm
Normal file
@@ -0,0 +1,77 @@
|
||||
<%
|
||||
if not self.embedded then
|
||||
%><form method="post" enctype="multipart/form-data" action="<%=REQUEST_URI%>">
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input type="hidden" name="cbi.submit" value="1" /><%
|
||||
end
|
||||
|
||||
%><div class="cbi-map" id="cbi-<%=self.config%>"><%
|
||||
|
||||
if self.title and #self.title > 0 then
|
||||
%><h2 name="content"><%=self.title%></h2><%
|
||||
end
|
||||
|
||||
if self.description and #self.description > 0 then
|
||||
%><div class="cbi-map-descr"><%=self.description%></div><%
|
||||
end
|
||||
|
||||
self:render_children()
|
||||
|
||||
%></div><%
|
||||
|
||||
if self.message then
|
||||
%><div class="alert-message notice"><%=self.message%></div><%
|
||||
end
|
||||
|
||||
if self.errmessage then
|
||||
%><div class="alert-message warning"><%=self.errmessage%></div><%
|
||||
end
|
||||
|
||||
if not self.embedded then
|
||||
if type(self.hidden) == "table" then
|
||||
local k, v
|
||||
for k, v in pairs(self.hidden) do
|
||||
%><input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" /><%
|
||||
end
|
||||
end
|
||||
|
||||
local display_back = (redirect)
|
||||
local display_cancel = (self.cancel ~= false and self.on_cancel)
|
||||
local display_skip = (self.flow and self.flow.skip)
|
||||
local display_submit = (self.submit ~= false)
|
||||
local display_reset = (self.reset ~= false)
|
||||
|
||||
if display_back or display_cancel or display_skip or display_submit or display_reset then
|
||||
%><div class="cbi-page-actions"><%
|
||||
|
||||
if display_back then
|
||||
%><input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> <%
|
||||
end
|
||||
|
||||
if display_cancel then
|
||||
local label = pcdata(self.cancel or translate("Cancel"))
|
||||
%><input class="cbi-button cbi-button-link" type="button" value="<%=label%>" onclick="cbi_submit(this, 'cbi.cancel')" /> <%
|
||||
end
|
||||
|
||||
if display_skip then
|
||||
%><input class="cbi-button cbi-button-neutral" type="button" value="<%:Skip%>" onclick="cbi_submit(this, 'cbi.skip')" /> <%
|
||||
end
|
||||
|
||||
if display_submit then
|
||||
local label = pcdata(self.submit or translate("Submit"))
|
||||
%><input class="cbi-button cbi-button-save" type="submit" value="<%=label%>" /> <%
|
||||
end
|
||||
|
||||
if display_reset then
|
||||
local label = pcdata(self.reset or translate("Reset"))
|
||||
%><input class="cbi-button cbi-button-reset" type="reset" value="<%=label%>" /> <%
|
||||
end
|
||||
|
||||
%></div><%
|
||||
end
|
||||
|
||||
%></form><%
|
||||
end
|
||||
%>
|
||||
|
||||
<script type="text/javascript">cbi_init();</script>
|
||||
14
modules/luci-compat/luasrc/view/cbi/tabcontainer.htm
Normal file
14
modules/luci-compat/luasrc/view/cbi/tabcontainer.htm
Normal file
@@ -0,0 +1,14 @@
|
||||
<% for _, tab in ipairs(self.tab_names) do data = self.tabs[tab] %>
|
||||
<div class="cbi-tabcontainer"<%=
|
||||
attr("id", "container.%s.%s.%s" %{ self.config, section, tab }) ..
|
||||
attr("data-tab", tab) ..
|
||||
attr("data-tab-title", data.title) ..
|
||||
attr("data-tab-active", tostring(tab == self.selected_tab))
|
||||
%>>
|
||||
<% if data.description then %>
|
||||
<div class="cbi-tab-descr"><%=data.description%></div>
|
||||
<% end %>
|
||||
|
||||
<% self:render_tab(tab, section, scope or {}) %>
|
||||
</div>
|
||||
<% end %>
|
||||
203
modules/luci-compat/luasrc/view/cbi/tblsection.htm
Normal file
203
modules/luci-compat/luasrc/view/cbi/tblsection.htm
Normal file
@@ -0,0 +1,203 @@
|
||||
<%-
|
||||
local rowcnt = 0
|
||||
|
||||
function rowstyle()
|
||||
rowcnt = rowcnt + 1
|
||||
if rowcnt % 2 == 0 then
|
||||
return " cbi-rowstyle-1"
|
||||
else
|
||||
return " cbi-rowstyle-2"
|
||||
end
|
||||
end
|
||||
|
||||
function width(o)
|
||||
if o.width then
|
||||
if type(o.width) == 'number' then
|
||||
return ' style="width:%dpx"' % o.width
|
||||
end
|
||||
return ' style="width:%s"' % o.width
|
||||
end
|
||||
return ''
|
||||
end
|
||||
|
||||
local has_titles = false
|
||||
local has_descriptions = false
|
||||
|
||||
local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "anonymous"
|
||||
local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title", translate("Name"))
|
||||
|
||||
local i, k
|
||||
for i, k in pairs(self.children) do
|
||||
if not k.typename then
|
||||
k.typename = k.template and k.template:gsub("^.+/", "") or ""
|
||||
end
|
||||
|
||||
if not has_titles and k.title and #k.title > 0 then
|
||||
has_titles = true
|
||||
end
|
||||
|
||||
if not has_descriptions and k.description and #k.description > 0 then
|
||||
has_descriptions = true
|
||||
end
|
||||
end
|
||||
|
||||
function render_titles()
|
||||
if not has_titles then
|
||||
return
|
||||
end
|
||||
|
||||
%><div class="tr cbi-section-table-titles <%=anonclass%>"<%=titlename%>><%
|
||||
|
||||
local i, k
|
||||
for i, k in ipairs(self.children) do
|
||||
if not k.optional then
|
||||
%><div class="th cbi-section-table-cell"<%=
|
||||
width(k) .. attr('data-type', k.typename) %>><%
|
||||
|
||||
if k.titleref then
|
||||
%><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=k.titleref%>"><%
|
||||
end
|
||||
|
||||
write(k.title)
|
||||
|
||||
if k.titleref then
|
||||
%></a><%
|
||||
end
|
||||
|
||||
%></div><%
|
||||
end
|
||||
end
|
||||
|
||||
if self.sortable or self.extedit or self.addremove then
|
||||
%><div class="th cbi-section-table-cell cbi-section-actions"></div><%
|
||||
end
|
||||
|
||||
%></div><%
|
||||
|
||||
rowcnt = rowcnt + 1
|
||||
end
|
||||
|
||||
function render_descriptions()
|
||||
if not has_descriptions then
|
||||
return
|
||||
end
|
||||
|
||||
%><div class="tr cbi-section-table-descr <%=anonclass%>"><%
|
||||
|
||||
local i, k
|
||||
for i, k in ipairs(self.children) do
|
||||
if not k.optional then
|
||||
%><div class="th cbi-section-table-cell"<%=
|
||||
width(k) .. attr("data-type", k.typename) %>><%
|
||||
|
||||
write(k.description)
|
||||
|
||||
%></div><%
|
||||
end
|
||||
end
|
||||
|
||||
if self.sortable or self.extedit or self.addremove then
|
||||
%><div class="th cbi-section-table-cell cbi-section-actions"></div><%
|
||||
end
|
||||
|
||||
%></div><%
|
||||
|
||||
rowcnt = rowcnt + 1
|
||||
end
|
||||
|
||||
-%>
|
||||
|
||||
<!-- tblsection -->
|
||||
<div class="cbi-section cbi-tblsection" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
|
||||
<% if self.title and #self.title > 0 then -%>
|
||||
<h3><%=self.title%></h3>
|
||||
<%- end %>
|
||||
<%- if self.sortable then -%>
|
||||
<input type="hidden" id="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" name="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" value="" />
|
||||
<%- end -%>
|
||||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<div class="table cbi-section-table">
|
||||
<%-
|
||||
render_titles()
|
||||
render_descriptions()
|
||||
|
||||
local isempty, section, i, k = true, nil, nil
|
||||
for i, k in ipairs(self:cfgsections()) do
|
||||
isempty = false
|
||||
section = k
|
||||
|
||||
local sectionname = striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k)
|
||||
local sectiontitle = ifattr(sectionname and (not self.anonymous or self.sectiontitle), "data-title", sectionname, true)
|
||||
local colorclass = (self.extedit or self.rowcolors) and rowstyle() or ""
|
||||
local scope = {
|
||||
valueheader = "cbi/cell_valueheader",
|
||||
valuefooter = "cbi/cell_valuefooter"
|
||||
}
|
||||
-%>
|
||||
<div class="tr cbi-section-table-row<%=colorclass%>" id="cbi-<%=self.config%>-<%=section%>"<%=sectiontitle%>>
|
||||
<%-
|
||||
local node
|
||||
for k, node in ipairs(self.children) do
|
||||
if not node.optional then
|
||||
node:render(section, scope or {})
|
||||
end
|
||||
end
|
||||
-%>
|
||||
|
||||
<%- if self.sortable or self.extedit or self.addremove then -%>
|
||||
<div class="td cbi-section-table-cell nowrap cbi-section-actions">
|
||||
<div>
|
||||
<%- if self.sortable then -%>
|
||||
<input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="return cbi_row_swap(this, true, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move up%>" />
|
||||
<input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="return cbi_row_swap(this, false, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move down%>" />
|
||||
<% end; if self.extedit then -%>
|
||||
<input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>"
|
||||
<%- if type(self.extedit) == "string" then
|
||||
%> onclick="location.href='<%=self.extedit:format(section)%>'"
|
||||
<%- elseif type(self.extedit) == "function" then
|
||||
%> onclick="location.href='<%=self:extedit(section)%>'"
|
||||
<%- end
|
||||
%> alt="<%:Edit%>" title="<%:Edit%>" />
|
||||
<% end; if self.addremove then %>
|
||||
<input class="cbi-button cbi-button-remove" type="submit" value="<%:Delete%>" onclick="this.form.cbi_state='del-section'; return true" name="cbi.rts.<%=self.config%>.<%=k%>" alt="<%:Delete%>" title="<%:Delete%>" />
|
||||
<%- end -%>
|
||||
</div>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
<%- end -%>
|
||||
|
||||
<%- if isempty then -%>
|
||||
<div class="tr cbi-section-table-row placeholder">
|
||||
<div class="td"><em><%:This section contains no values yet%></em></div>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
|
||||
<% if self.error then %>
|
||||
<div class="cbi-section-error">
|
||||
<ul><% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%>
|
||||
<li><%=pcdata(e):gsub("\n","<br />")%></li>
|
||||
<%- end end %></ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%- if self.addremove then -%>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<div class="cbi-section-create cbi-tblsection-create">
|
||||
<% if self.anonymous then %>
|
||||
<input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" title="<%:Add%>" />
|
||||
<% else %>
|
||||
<% if self.invalid_cts then -%>
|
||||
<div class="cbi-section-error"><%:Invalid%></div>
|
||||
<%- end %>
|
||||
<div>
|
||||
<input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" data-type="uciname" data-optional="true" />
|
||||
</div>
|
||||
<input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
|
||||
<% end %>
|
||||
</div>
|
||||
<%- end %>
|
||||
<%- end -%>
|
||||
</div>
|
||||
<!-- /tblsection -->
|
||||
52
modules/luci-compat/luasrc/view/cbi/tsection.htm
Normal file
52
modules/luci-compat/luasrc/view/cbi/tsection.htm
Normal file
@@ -0,0 +1,52 @@
|
||||
<div class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
|
||||
<% if self.title and #self.title > 0 then -%>
|
||||
<legend><%=self.title%></legend>
|
||||
<%- end %>
|
||||
<% if self.error_msg and #self.error_msg > 0 then -%>
|
||||
<div class="cbi-section-error">
|
||||
<%=self.error_msg%>
|
||||
</div>
|
||||
<%- end %>
|
||||
<% if self.description and #self.description > 0 then -%>
|
||||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<%- end %>
|
||||
<% local isempty = true for i, k in ipairs(self:cfgsections()) do -%>
|
||||
<% if self.addremove then -%>
|
||||
<div class="cbi-section-remove right">
|
||||
<input type="submit" name="cbi.rts.<%=self.config%>.<%=k%>" onclick="this.form.cbi_state='del-section'; return true" value="<%:Delete%>" class="cbi-button" />
|
||||
</div>
|
||||
<%- end %>
|
||||
|
||||
<%- section = k; isempty = false -%>
|
||||
|
||||
<% if not self.anonymous then -%>
|
||||
<h3><%=section:upper()%></h3>
|
||||
<%- end %>
|
||||
|
||||
<div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>">
|
||||
<%+cbi/ucisection%>
|
||||
</div>
|
||||
<%- end %>
|
||||
|
||||
<% if isempty then -%>
|
||||
<em><%:This section contains no values yet%><br /><br /></em>
|
||||
<%- end %>
|
||||
|
||||
<% if self.addremove then -%>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<div class="cbi-section-create">
|
||||
<% if self.anonymous then -%>
|
||||
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
|
||||
<%- else -%>
|
||||
<% if self.invalid_cts then -%>
|
||||
<div class="cbi-section-error"><%:Invalid%></div>
|
||||
<%- end %>
|
||||
<div>
|
||||
<input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>." name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>." data-type="uciname" data-optional="true" />
|
||||
</div>
|
||||
<input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
|
||||
<%- end %>
|
||||
</div>
|
||||
<%- end %>
|
||||
<%- end %>
|
||||
</div>
|
||||
5
modules/luci-compat/luasrc/view/cbi/tvalue.htm
Normal file
5
modules/luci-compat/luasrc/view/cbi/tvalue.htm
Normal file
@@ -0,0 +1,5 @@
|
||||
<%+cbi/valueheader%>
|
||||
<textarea class="cbi-input-textarea" <% if not self.size then %> style="width: 100%"<% else %> cols="<%=self.size%>"<% end %> data-update="change"<%= attr("name", cbid) .. attr("id", cbid) .. ifattr(self.rows, "rows") .. ifattr(self.wrap, "wrap") .. ifattr(self.readonly, "readonly") %>>
|
||||
<%-=pcdata(self:cfgvalue(section) or self.default)-%>
|
||||
</textarea>
|
||||
<%+cbi/valuefooter%>
|
||||
56
modules/luci-compat/luasrc/view/cbi/ucisection.htm
Normal file
56
modules/luci-compat/luasrc/view/cbi/ucisection.htm
Normal file
@@ -0,0 +1,56 @@
|
||||
<%-
|
||||
if type(self.hidden) == "table" then
|
||||
for k, v in pairs(self.hidden) do
|
||||
-%>
|
||||
<input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" />
|
||||
<%-
|
||||
end
|
||||
end
|
||||
%>
|
||||
|
||||
<% if self.tabs then %>
|
||||
<%+cbi/tabcontainer%>
|
||||
<% else %>
|
||||
<% self:render_children(section, scope or {}) %>
|
||||
<% end %>
|
||||
|
||||
<% if self.error and self.error[section] then -%>
|
||||
<div class="cbi-section-error" data-index="<%=#self.children + 1%>">
|
||||
<ul><% for _, e in ipairs(self.error[section]) do -%>
|
||||
<li>
|
||||
<%- if e == "invalid" then -%>
|
||||
<%:One or more fields contain invalid values!%>
|
||||
<%- elseif e == "missing" then -%>
|
||||
<%:One or more required fields have no value!%>
|
||||
<%- else -%>
|
||||
<%=pcdata(e)%>
|
||||
<%- end -%>
|
||||
</li>
|
||||
<%- end %></ul>
|
||||
</div>
|
||||
<%- end %>
|
||||
|
||||
<% if self.optionals[section] and #self.optionals[section] > 0 or self.dynamic then %>
|
||||
<div class="cbi-optionals" data-index="<%=#self.children + 1%>">
|
||||
<%-
|
||||
if self.dynamic then
|
||||
local keys, vals, name, opt = { }, { }
|
||||
for name, opt in pairs(self.optionals[section]) do
|
||||
keys[#keys+1] = name
|
||||
vals[#vals+1] = opt.title
|
||||
end
|
||||
-%>
|
||||
<input type="text" id="cbi.opt.<%=self.config%>.<%=section%>" name="cbi.opt.<%=self.config%>.<%=section%>" data-type="uciname" data-optional="true"<%=
|
||||
ifattr(#keys > 0, "data-choices", luci.util.json_encode({keys, vals}))
|
||||
%> />
|
||||
<%- else -%>
|
||||
<select id="cbi.opt.<%=self.config%>.<%=section%>" name="cbi.opt.<%=self.config%>.<%=section%>" data-optionals="true">
|
||||
<option><%: -- Additional Field -- %></option>
|
||||
<% for key, val in pairs(self.optionals[section]) do -%>
|
||||
<option id="cbi-<%=self.config.."-"..section.."-"..val.option%>" value="<%=val.option%>" data-index="<%=val.index%>" data-depends="<%=pcdata(val:deplist2json(section))%>"><%=striptags(val.title)%></option>
|
||||
<%- end %>
|
||||
</select>
|
||||
<%- end -%>
|
||||
<input type="submit" class="cbi-button cbi-button-fieldadd" value="<%:Add%>" />
|
||||
</div>
|
||||
<% end %>
|
||||
14
modules/luci-compat/luasrc/view/cbi/upload.htm
Normal file
14
modules/luci-compat/luasrc/view/cbi/upload.htm
Normal file
@@ -0,0 +1,14 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<div<%=attr("data-ui-widget", luci.util.serialize_json({
|
||||
"FileUpload", self:cfgvalue(section) or self.default, {
|
||||
id = cbid,
|
||||
name = cbid,
|
||||
show_hidden = self.show_hidden,
|
||||
enable_remove = self.enable_remove,
|
||||
enable_upload = self.enable_upload,
|
||||
root_directory = "/" --self.root_directory
|
||||
}
|
||||
}))%>></div>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
35
modules/luci-compat/luasrc/view/cbi/value.htm
Normal file
35
modules/luci-compat/luasrc/view/cbi/value.htm
Normal file
@@ -0,0 +1,35 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<% local choices = self:choices()
|
||||
if choices then %>
|
||||
<div<%=attr("data-ui-widget", luci.util.serialize_json({
|
||||
"Combobox", self:cfgvalue(section) or self.default, choices, {
|
||||
id = cbid,
|
||||
name = cbid,
|
||||
size = self.size,
|
||||
sort = self.keylist,
|
||||
datatype = self.datatype,
|
||||
optional = self.optional or self.rmempty,
|
||||
readonly = self.readonly,
|
||||
maxlength = self.maxlength,
|
||||
placeholder = self.placeholder,
|
||||
custom_placeholder = self.combobox_manual
|
||||
}
|
||||
}))%>></div>
|
||||
<% else %>
|
||||
<div<%=attr("data-ui-widget", luci.util.serialize_json({
|
||||
"Textfield", self:cfgvalue(section) or self.default, {
|
||||
id = cbid,
|
||||
name = cbid,
|
||||
size = self.size,
|
||||
datatype = self.datatype,
|
||||
optional = self.optional or self.rmempty,
|
||||
password = self.password,
|
||||
readonly = self.readonly,
|
||||
maxlength = self.maxlength,
|
||||
placeholder = self.placeholder
|
||||
}
|
||||
}))%>></div>
|
||||
<% end %>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
1
modules/luci-compat/luasrc/view/cbi/valuefooter.htm
Normal file
1
modules/luci-compat/luasrc/view/cbi/valuefooter.htm
Normal file
@@ -0,0 +1 @@
|
||||
<% include( valuefooter or "cbi/full_valuefooter" ) %>
|
||||
1
modules/luci-compat/luasrc/view/cbi/valueheader.htm
Normal file
1
modules/luci-compat/luasrc/view/cbi/valueheader.htm
Normal file
@@ -0,0 +1 @@
|
||||
<% include( valueheader or "cbi/full_valueheader" ) %>
|
||||
173
modules/luci-compat/luasrc/view/cbi/wireless_modefreq.htm
Normal file
173
modules/luci-compat/luasrc/view/cbi/wireless_modefreq.htm
Normal file
@@ -0,0 +1,173 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var freqlist = <%= luci.http.write_json(self.iwinfo.freqlist) %>;
|
||||
var hwmodes = <%= luci.http.write_json(self.iwinfo.hwmodelist or {}) %>;
|
||||
var htmodes = <%= luci.http.write_json(self.iwinfo.htmodelist) %>;
|
||||
var acs = <%= luci.http.write_json(self.hostapd_acs or 0) %>;
|
||||
|
||||
var channels = {
|
||||
'11g': [
|
||||
'auto', 'auto', true
|
||||
],
|
||||
'11a': [
|
||||
'auto', 'auto', true
|
||||
]
|
||||
};
|
||||
|
||||
if (acs < 1) {
|
||||
channels[(freqlist[freqlist.length - 1].mhz > 2484) ? '11a' : '11g'].length = 0;
|
||||
}
|
||||
|
||||
for (var i = 0; i < freqlist.length; i++)
|
||||
channels[(freqlist[i].mhz > 2484) ? '11a' : '11g'].push(
|
||||
freqlist[i].channel,
|
||||
'%d (%d MHz)'.format(freqlist[i].channel, freqlist[i].mhz),
|
||||
!freqlist[i].restricted
|
||||
);
|
||||
|
||||
var modes = [
|
||||
'', 'Legacy', true,
|
||||
'n', 'N', hwmodes.n,
|
||||
'ac', 'AC', hwmodes.ac
|
||||
];
|
||||
|
||||
var htmodes = {
|
||||
'': [
|
||||
'', '-', true
|
||||
],
|
||||
'n': [
|
||||
'HT20', '20 MHz', htmodes.HT20,
|
||||
'HT40', '40 MHz', htmodes.HT40
|
||||
],
|
||||
'ac': [
|
||||
'VHT20', '20 MHz', htmodes.VHT20,
|
||||
'VHT40', '40 MHz', htmodes.VHT40,
|
||||
'VHT80', '80 MHz', htmodes.VHT80,
|
||||
'VHT160', '160 MHz', htmodes.VHT160
|
||||
]
|
||||
};
|
||||
|
||||
var bands = {
|
||||
'': [
|
||||
'11g', '2.4 GHz', (channels['11g'].length > 3),
|
||||
'11a', '5 GHz', (channels['11a'].length > 3)
|
||||
],
|
||||
'n': [
|
||||
'11g', '2.4 GHz', (channels['11g'].length > 3),
|
||||
'11a', '5 GHz', (channels['11a'].length > 3)
|
||||
],
|
||||
'ac': [
|
||||
'11a', '5 GHz', true
|
||||
]
|
||||
};
|
||||
|
||||
function cbi_set_values(sel, vals)
|
||||
{
|
||||
if (sel.vals)
|
||||
sel.vals.selected = sel.selectedIndex;
|
||||
|
||||
while (sel.options[0])
|
||||
sel.remove(0);
|
||||
|
||||
for (var i = 0; vals && i < vals.length; i += 3)
|
||||
{
|
||||
if (!vals[i+2])
|
||||
continue;
|
||||
|
||||
var opt = document.createElement('option');
|
||||
opt.value = vals[i+0];
|
||||
opt.text = vals[i+1];
|
||||
|
||||
sel.add(opt);
|
||||
}
|
||||
|
||||
if (!isNaN(vals.selected))
|
||||
sel.selectedIndex = vals.selected;
|
||||
|
||||
sel.parentNode.style.display = (sel.options.length <= 1) ? 'none' : '';
|
||||
sel.vals = vals;
|
||||
}
|
||||
|
||||
function cbi_toggle_wifi_mode(id)
|
||||
{
|
||||
cbi_toggle_wifi_htmode(id);
|
||||
cbi_toggle_wifi_band(id);
|
||||
}
|
||||
|
||||
function cbi_toggle_wifi_htmode(id)
|
||||
{
|
||||
var mode = document.getElementById(id + '.mode');
|
||||
var bwdt = document.getElementById(id + '.htmode');
|
||||
|
||||
cbi_set_values(bwdt, htmodes[mode.value]);
|
||||
}
|
||||
|
||||
function cbi_toggle_wifi_band(id)
|
||||
{
|
||||
var mode = document.getElementById(id + '.mode');
|
||||
var band = document.getElementById(id + '.band');
|
||||
|
||||
cbi_set_values(band, bands[mode.value]);
|
||||
cbi_toggle_wifi_channel(id);
|
||||
}
|
||||
|
||||
function cbi_toggle_wifi_channel(id)
|
||||
{
|
||||
var band = document.getElementById(id + '.band');
|
||||
var chan = document.getElementById(id + '.channel');
|
||||
|
||||
cbi_set_values(chan, channels[band.value]);
|
||||
}
|
||||
|
||||
function cbi_init_wifi(id)
|
||||
{
|
||||
var mode = document.getElementById(id + '.mode');
|
||||
var band = document.getElementById(id + '.band');
|
||||
var chan = document.getElementById(id + '.channel');
|
||||
var bwdt = document.getElementById(id + '.htmode');
|
||||
|
||||
cbi_set_values(mode, modes);
|
||||
|
||||
if (/VHT20|VHT40|VHT80|VHT160/.test(<%= luci.http.write_json(self.map:get(section, "htmode")) %>))
|
||||
mode.value = 'ac';
|
||||
else if (/HT20|HT40/.test(<%= luci.http.write_json(self.map:get(section, "htmode")) %>))
|
||||
mode.value = 'n';
|
||||
else
|
||||
mode.value = '';
|
||||
|
||||
cbi_toggle_wifi_mode(id);
|
||||
|
||||
if (/a/.test(<%= luci.http.write_json(self.map:get(section, "hwmode")) %>))
|
||||
band.value = '11a';
|
||||
else
|
||||
band.value = '11g';
|
||||
|
||||
cbi_toggle_wifi_band(id);
|
||||
|
||||
bwdt.value = <%= luci.http.write_json(self.map:get(section, "htmode")) %>;
|
||||
chan.value = <%= luci.http.write_json(self.map:get(section, "channel")) %>;
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
<label style="float:left; margin-right:3px">
|
||||
<%:Mode%><br />
|
||||
<select style="width:auto" id="<%= cbid %>.mode" name="<%= cbid %>.mode" onchange="cbi_toggle_wifi_mode('<%= cbid %>')"></select>
|
||||
</label>
|
||||
<label style="float:left; margin-right:3px">
|
||||
<%:Band%><br />
|
||||
<select style="width:auto" id="<%= cbid %>.band" name="<%= cbid %>.band" onchange="cbi_toggle_wifi_band('<%= cbid %>')"></select>
|
||||
</label>
|
||||
<label style="float:left; margin-right:3px">
|
||||
<%:Channel%><br />
|
||||
<select style="width:auto" id="<%= cbid %>.channel" name="<%= cbid %>.channel"></select>
|
||||
</label>
|
||||
<label style="float:left; margin-right:3px">
|
||||
<%:Width%><br />
|
||||
<select style="width:auto" id="<%= cbid %>.htmode" name="<%= cbid %>.htmode"></select>
|
||||
</label>
|
||||
<br style="clear:left" />
|
||||
|
||||
<script type="text/javascript">cbi_init_wifi('<%= cbid %>');</script>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
Reference in New Issue
Block a user