mirror of
https://github.com/openwrt/luci.git
synced 2025-12-21 21:24:35 +04:00
luci-base: convert JavaScript code to ES6 style
Convert existing JavaScript code in LuCI base to utilize ES6 standard features such as spread arguments, arrow functions, object method declarations etc. This makes the code somewhat easier to follow and slightly smaller. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,10 @@
|
|||||||
'require baseclass';
|
'require baseclass';
|
||||||
'require request';
|
'require request';
|
||||||
|
|
||||||
var rpcRequestID = 1,
|
let rpcRequestID = 1;
|
||||||
rpcSessionID = L.env.sessionid || '00000000000000000000000000000000',
|
let rpcSessionID = L.env.sessionid ?? '00000000000000000000000000000000';
|
||||||
rpcBaseURL = L.url('admin/ubus'),
|
let rpcBaseURL = L.url('admin/ubus');
|
||||||
rpcInterceptorFns = [];
|
const rpcInterceptorFns = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class rpc
|
* @class rpc
|
||||||
@@ -18,14 +18,14 @@ var rpcRequestID = 1,
|
|||||||
*/
|
*/
|
||||||
return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
||||||
/* privates */
|
/* privates */
|
||||||
call: function(req, cb, nobatch) {
|
call(req, cb, nobatch) {
|
||||||
var q = '';
|
let q = '';
|
||||||
|
|
||||||
if (Array.isArray(req)) {
|
if (Array.isArray(req)) {
|
||||||
if (req.length == 0)
|
if (req.length == 0)
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
|
|
||||||
for (var i = 0; i < req.length; i++)
|
for (let i = 0; i < req.length; i++)
|
||||||
if (req[i].params)
|
if (req[i].params)
|
||||||
q += '%s%s.%s'.format(
|
q += '%s%s.%s'.format(
|
||||||
q ? ';' : '/',
|
q ? ';' : '/',
|
||||||
@@ -35,14 +35,14 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return request.post(rpcBaseURL + q, req, {
|
return request.post(rpcBaseURL + q, req, {
|
||||||
timeout: (L.env.rpctimeout || 20) * 1000,
|
timeout: (L.env.rpctimeout ?? 20) * 1000,
|
||||||
nobatch: nobatch,
|
nobatch,
|
||||||
credentials: true
|
credentials: true
|
||||||
}).then(cb, cb);
|
}).then(cb, cb);
|
||||||
},
|
},
|
||||||
|
|
||||||
parseCallReply: function(req, res) {
|
parseCallReply(req, res) {
|
||||||
var msg = null;
|
let msg = null;
|
||||||
|
|
||||||
if (res instanceof Error)
|
if (res instanceof Error)
|
||||||
return req.reject(res);
|
return req.reject(res);
|
||||||
@@ -62,14 +62,14 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* The interceptor args are intentionally swapped.
|
* The interceptor args are intentionally swapped.
|
||||||
* Response is passed as first arg to align with Request class interceptors
|
* Response is passed as first arg to align with Request class interceptors
|
||||||
*/
|
*/
|
||||||
Promise.all(rpcInterceptorFns.map(function(fn) { return fn(msg, req) }))
|
Promise.all(rpcInterceptorFns.map(fn => fn(msg, req)))
|
||||||
.then(this.handleCallReply.bind(this, req, msg))
|
.then(this.handleCallReply.bind(this, req, msg))
|
||||||
.catch(req.reject);
|
.catch(req.reject);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleCallReply: function(req, msg) {
|
handleCallReply(req, msg) {
|
||||||
var type = Object.prototype.toString,
|
const type = Object.prototype.toString;
|
||||||
ret = null;
|
let ret = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* verify message frame */
|
/* verify message frame */
|
||||||
@@ -98,7 +98,7 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req.expect) {
|
if (req.expect) {
|
||||||
for (var key in req.expect) {
|
for (const key in req.expect) {
|
||||||
if (ret != null && key != '')
|
if (ret != null && key != '')
|
||||||
ret = ret[key];
|
ret = ret[key];
|
||||||
|
|
||||||
@@ -140,20 +140,17 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* more arguments, a promise resolving to an object describing the method
|
* more arguments, a promise resolving to an object describing the method
|
||||||
* signatures of each requested `ubus` object name will be returned.
|
* signatures of each requested `ubus` object name will be returned.
|
||||||
*/
|
*/
|
||||||
list: function() {
|
list(...args) {
|
||||||
var msg = {
|
const msg = {
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
id: rpcRequestID++,
|
id: rpcRequestID++,
|
||||||
method: 'list',
|
method: 'list',
|
||||||
params: arguments.length ? this.varargs(arguments) : undefined
|
params: args.length ? args : undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise(L.bind(function(resolveFn, rejectFn) {
|
return new Promise(L.bind(function(resolve, reject) {
|
||||||
/* store request info */
|
/* store request info */
|
||||||
var req = {
|
const req = { resolve, reject };
|
||||||
resolve: resolveFn,
|
|
||||||
reject: rejectFn
|
|
||||||
};
|
|
||||||
|
|
||||||
/* call rpc */
|
/* call rpc */
|
||||||
this.call(msg, this.parseCallReply.bind(this, req));
|
this.call(msg, this.parseCallReply.bind(this, req));
|
||||||
@@ -296,37 +293,36 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* Returns a new function implementing the method call described in
|
* Returns a new function implementing the method call described in
|
||||||
* `options`.
|
* `options`.
|
||||||
*/
|
*/
|
||||||
declare: function(options) {
|
declare(options) {
|
||||||
return Function.prototype.bind.call(function(rpc, options) {
|
return Function.prototype.bind.call(function(rpc, options, ...args) {
|
||||||
var args = this.varargs(arguments, 2);
|
return new Promise((resolve, reject) => {
|
||||||
return new Promise(function(resolveFn, rejectFn) {
|
|
||||||
/* build parameter object */
|
/* build parameter object */
|
||||||
var p_off = 0;
|
let p_off = 0;
|
||||||
var params = { };
|
const params = { };
|
||||||
if (Array.isArray(options.params))
|
if (Array.isArray(options.params))
|
||||||
for (p_off = 0; p_off < options.params.length; p_off++)
|
for (p_off = 0; p_off < options.params.length; p_off++)
|
||||||
params[options.params[p_off]] = args[p_off];
|
params[options.params[p_off]] = args[p_off];
|
||||||
|
|
||||||
/* all remaining arguments are private args */
|
/* all remaining arguments are private args */
|
||||||
var priv = [ undefined, undefined ];
|
const priv = [ undefined, undefined ];
|
||||||
for (; p_off < args.length; p_off++)
|
for (; p_off < args.length; p_off++)
|
||||||
priv.push(args[p_off]);
|
priv.push(args[p_off]);
|
||||||
|
|
||||||
/* store request info */
|
/* store request info */
|
||||||
var req = {
|
const req = {
|
||||||
expect: options.expect,
|
expect: options.expect,
|
||||||
filter: options.filter,
|
filter: options.filter,
|
||||||
resolve: resolveFn,
|
resolve,
|
||||||
reject: rejectFn,
|
reject,
|
||||||
params: params,
|
params,
|
||||||
priv: priv,
|
priv,
|
||||||
object: options.object,
|
object: options.object,
|
||||||
method: options.method,
|
method: options.method,
|
||||||
raise: options.reject
|
raise: options.reject
|
||||||
};
|
};
|
||||||
|
|
||||||
/* build message object */
|
/* build message object */
|
||||||
var msg = {
|
const msg = {
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
id: rpcRequestID++,
|
id: rpcRequestID++,
|
||||||
method: 'call',
|
method: 'call',
|
||||||
@@ -351,7 +347,7 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* Returns the 32 byte session ID string used for authenticating remote
|
* Returns the 32 byte session ID string used for authenticating remote
|
||||||
* requests.
|
* requests.
|
||||||
*/
|
*/
|
||||||
getSessionID: function() {
|
getSessionID() {
|
||||||
return rpcSessionID;
|
return rpcSessionID;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -362,7 +358,7 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* Sets the 32 byte session ID string used for authenticating remote
|
* Sets the 32 byte session ID string used for authenticating remote
|
||||||
* requests.
|
* requests.
|
||||||
*/
|
*/
|
||||||
setSessionID: function(sid) {
|
setSessionID(sid) {
|
||||||
rpcSessionID = sid;
|
rpcSessionID = sid;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -372,7 +368,7 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
* Returns the RPC URL endpoint to issue requests against.
|
* Returns the RPC URL endpoint to issue requests against.
|
||||||
*/
|
*/
|
||||||
getBaseURL: function() {
|
getBaseURL() {
|
||||||
return rpcBaseURL;
|
return rpcBaseURL;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -382,7 +378,7 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* @param {string} url
|
* @param {string} url
|
||||||
* Sets the RPC URL endpoint to issue requests against.
|
* Sets the RPC URL endpoint to issue requests against.
|
||||||
*/
|
*/
|
||||||
setBaseURL: function(url) {
|
setBaseURL(url) {
|
||||||
rpcBaseURL = url;
|
rpcBaseURL = url;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -396,7 +392,7 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
* Returns the textual description of the code.
|
* Returns the textual description of the code.
|
||||||
*/
|
*/
|
||||||
getStatusText: function(statusCode) {
|
getStatusText(statusCode) {
|
||||||
switch (statusCode) {
|
switch (statusCode) {
|
||||||
case 0: return _('Command OK');
|
case 0: return _('Command OK');
|
||||||
case 1: return _('Invalid command');
|
case 1: return _('Invalid command');
|
||||||
@@ -459,9 +455,10 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* @returns {LuCI.rpc~interceptorFn}
|
* @returns {LuCI.rpc~interceptorFn}
|
||||||
* Returns the given function value.
|
* Returns the given function value.
|
||||||
*/
|
*/
|
||||||
addInterceptor: function(interceptorFn) {
|
addInterceptor(interceptorFn) {
|
||||||
if (typeof(interceptorFn) == 'function')
|
if (typeof(interceptorFn) == 'function')
|
||||||
rpcInterceptorFns.push(interceptorFn);
|
rpcInterceptorFns.push(interceptorFn);
|
||||||
|
|
||||||
return interceptorFn;
|
return interceptorFn;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -475,11 +472,14 @@ return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
|||||||
* Returns `true` if the given function has been removed or `false`
|
* Returns `true` if the given function has been removed or `false`
|
||||||
* if it has not been found.
|
* if it has not been found.
|
||||||
*/
|
*/
|
||||||
removeInterceptor: function(interceptorFn) {
|
removeInterceptor(interceptorFn) {
|
||||||
var oldlen = rpcInterceptorFns.length, i = oldlen;
|
const oldlen = rpcInterceptorFns.length;
|
||||||
|
let i = oldlen;
|
||||||
|
|
||||||
while (i--)
|
while (i--)
|
||||||
if (rpcInterceptorFns[i] === interceptorFn)
|
if (rpcInterceptorFns[i] === interceptorFn)
|
||||||
rpcInterceptorFns.splice(i, 1);
|
rpcInterceptorFns.splice(i, 1);
|
||||||
|
|
||||||
return (rpcInterceptorFns.length < oldlen);
|
return (rpcInterceptorFns.length < oldlen);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
'require baseclass';
|
'require baseclass';
|
||||||
|
|
||||||
function isEmpty(object, ignore) {
|
function isEmpty(object, ignore) {
|
||||||
for (var property in object)
|
for (const property in object)
|
||||||
if (object.hasOwnProperty(property) && property != ignore)
|
if (object.hasOwnProperty(property) && property != ignore)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ function isEmpty(object, ignore) {
|
|||||||
* UCI configuration data.
|
* UCI configuration data.
|
||||||
*/
|
*/
|
||||||
return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
||||||
__init__: function() {
|
__init__() {
|
||||||
this.state = {
|
this.state = {
|
||||||
newidx: 0,
|
newidx: 0,
|
||||||
values: { },
|
values: { },
|
||||||
@@ -100,14 +100,14 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* A newly generated, unique section ID in the form `newXXXXXX`
|
* A newly generated, unique section ID in the form `newXXXXXX`
|
||||||
* where `X` denotes a hexadecimal digit.
|
* where `X` denotes a hexadecimal digit.
|
||||||
*/
|
*/
|
||||||
createSID: function(conf) {
|
createSID(conf) {
|
||||||
var v = this.state.values,
|
const v = this.state.values;
|
||||||
n = this.state.creates,
|
const n = this.state.creates;
|
||||||
sid;
|
let sid;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
sid = "new%06x".format(Math.random() * 0xFFFFFF);
|
sid = "new%06x".format(Math.random() * 0xFFFFFF);
|
||||||
} while ((n[conf] && n[conf][sid]) || (v[conf] && v[conf][sid]));
|
} while ((n[conf]?.[sid]) || (v[conf]?.[sid]));
|
||||||
|
|
||||||
return sid;
|
return sid;
|
||||||
},
|
},
|
||||||
@@ -131,30 +131,30 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* not in extended notation. Returns `null` when an extended ID could
|
* not in extended notation. Returns `null` when an extended ID could
|
||||||
* not be resolved to existing section ID.
|
* not be resolved to existing section ID.
|
||||||
*/
|
*/
|
||||||
resolveSID: function(conf, sid) {
|
resolveSID(conf, sid) {
|
||||||
if (typeof(sid) != 'string')
|
if (typeof(sid) != 'string')
|
||||||
return sid;
|
return sid;
|
||||||
|
|
||||||
var m = /^@([a-zA-Z0-9_-]+)\[(-?[0-9]+)\]$/.exec(sid);
|
const m = /^@([a-zA-Z0-9_-]+)\[(-?[0-9]+)\]$/.exec(sid);
|
||||||
|
|
||||||
if (m) {
|
if (m) {
|
||||||
var type = m[1],
|
const type = m[1];
|
||||||
pos = +m[2],
|
const pos = +m[2];
|
||||||
sections = this.sections(conf, type),
|
const sections = this.sections(conf, type);
|
||||||
section = sections[pos >= 0 ? pos : sections.length + pos];
|
const section = sections[pos >= 0 ? pos : sections.length + pos];
|
||||||
|
|
||||||
return section ? section['.name'] : null;
|
return section?.['.name'] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sid;
|
return sid;
|
||||||
},
|
},
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
reorderSections: function() {
|
reorderSections() {
|
||||||
var v = this.state.values,
|
const v = this.state.values;
|
||||||
n = this.state.creates,
|
const n = this.state.creates;
|
||||||
r = this.state.reorder,
|
const r = this.state.reorder;
|
||||||
tasks = [];
|
const tasks = [];
|
||||||
|
|
||||||
if (Object.keys(r).length === 0)
|
if (Object.keys(r).length === 0)
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
@@ -163,24 +163,22 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
gather all created and existing sections, sort them according
|
gather all created and existing sections, sort them according
|
||||||
to their index value and issue an uci order call
|
to their index value and issue an uci order call
|
||||||
*/
|
*/
|
||||||
for (var c in r) {
|
for (const c in r) {
|
||||||
var o = [ ];
|
const o = [ ];
|
||||||
|
|
||||||
if (n[c])
|
if (n[c])
|
||||||
for (var s in n[c])
|
for (const s in n[c])
|
||||||
o.push(n[c][s]);
|
o.push(n[c][s]);
|
||||||
|
|
||||||
for (var s in v[c])
|
for (const s in v[c])
|
||||||
o.push(v[c][s]);
|
o.push(v[c][s]);
|
||||||
|
|
||||||
if (o.length > 0) {
|
if (o.length > 0) {
|
||||||
o.sort(function(a, b) {
|
o.sort((a, b) => a['.index'] - b['.index']);
|
||||||
return (a['.index'] - b['.index']);
|
|
||||||
});
|
|
||||||
|
|
||||||
var sids = [ ];
|
const sids = [ ];
|
||||||
|
|
||||||
for (var i = 0; i < o.length; i++)
|
for (let i = 0; i < o.length; i++)
|
||||||
sids.push(o[i]['.name']);
|
sids.push(o[i]['.name']);
|
||||||
|
|
||||||
tasks.push(this.callOrder(c, sids));
|
tasks.push(this.callOrder(c, sids));
|
||||||
@@ -192,7 +190,7 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
loadPackage: function(packageName) {
|
loadPackage(packageName) {
|
||||||
if (this.loaded[packageName] == null)
|
if (this.loaded[packageName] == null)
|
||||||
return (this.loaded[packageName] = this.callLoad(packageName));
|
return (this.loaded[packageName] = this.callLoad(packageName));
|
||||||
|
|
||||||
@@ -217,22 +215,22 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* Returns a promise resolving to the names of the configurations
|
* Returns a promise resolving to the names of the configurations
|
||||||
* that have been successfully loaded.
|
* that have been successfully loaded.
|
||||||
*/
|
*/
|
||||||
load: function(packages) {
|
load(packages) {
|
||||||
var self = this,
|
const self = this;
|
||||||
pkgs = [ ],
|
const pkgs = [ ];
|
||||||
tasks = [];
|
const tasks = [];
|
||||||
|
|
||||||
if (!Array.isArray(packages))
|
if (!Array.isArray(packages))
|
||||||
packages = [ packages ];
|
packages = [ packages ];
|
||||||
|
|
||||||
for (var i = 0; i < packages.length; i++)
|
for (let i = 0; i < packages.length; i++)
|
||||||
if (!self.state.values[packages[i]]) {
|
if (!self.state.values[packages[i]]) {
|
||||||
pkgs.push(packages[i]);
|
pkgs.push(packages[i]);
|
||||||
tasks.push(self.loadPackage(packages[i]));
|
tasks.push(self.loadPackage(packages[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(tasks).then(function(responses) {
|
return Promise.all(tasks).then(responses => {
|
||||||
for (var i = 0; i < responses.length; i++)
|
for (let i = 0; i < responses.length; i++)
|
||||||
self.state.values[pkgs[i]] = responses[i];
|
self.state.values[pkgs[i]] = responses[i];
|
||||||
|
|
||||||
if (responses.length)
|
if (responses.length)
|
||||||
@@ -249,11 +247,11 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* The name of the configuration or an array of configuration
|
* The name of the configuration or an array of configuration
|
||||||
* names to unload.
|
* names to unload.
|
||||||
*/
|
*/
|
||||||
unload: function(packages) {
|
unload(packages) {
|
||||||
if (!Array.isArray(packages))
|
if (!Array.isArray(packages))
|
||||||
packages = [ packages ];
|
packages = [ packages ];
|
||||||
|
|
||||||
for (var i = 0; i < packages.length; i++) {
|
for (let i = 0; i < packages.length; i++) {
|
||||||
delete this.state.values[packages[i]];
|
delete this.state.values[packages[i]];
|
||||||
delete this.state.creates[packages[i]];
|
delete this.state.creates[packages[i]];
|
||||||
delete this.state.changes[packages[i]];
|
delete this.state.changes[packages[i]];
|
||||||
@@ -281,13 +279,11 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* Returns the section ID of the newly added section which is equivalent
|
* Returns the section ID of the newly added section which is equivalent
|
||||||
* to the given name for non-anonymous sections.
|
* to the given name for non-anonymous sections.
|
||||||
*/
|
*/
|
||||||
add: function(conf, type, name) {
|
add(conf, type, name) {
|
||||||
var n = this.state.creates,
|
const n = this.state.creates;
|
||||||
sid = name || this.createSID(conf);
|
const sid = name || this.createSID(conf);
|
||||||
|
|
||||||
if (!n[conf])
|
|
||||||
n[conf] = { };
|
|
||||||
|
|
||||||
|
n[conf] ??= { };
|
||||||
n[conf][sid] = {
|
n[conf][sid] = {
|
||||||
'.type': type,
|
'.type': type,
|
||||||
'.name': sid,
|
'.name': sid,
|
||||||
@@ -308,23 +304,20 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* @param {string} sid
|
* @param {string} sid
|
||||||
* The ID of the section to remove.
|
* The ID of the section to remove.
|
||||||
*/
|
*/
|
||||||
remove: function(conf, sid) {
|
remove(conf, sid) {
|
||||||
var v = this.state.values,
|
const v = this.state.values;
|
||||||
n = this.state.creates,
|
const n = this.state.creates;
|
||||||
c = this.state.changes,
|
const c = this.state.changes;
|
||||||
d = this.state.deletes;
|
const d = this.state.deletes;
|
||||||
|
|
||||||
/* requested deletion of a just created section */
|
/* requested deletion of a just created section */
|
||||||
if (n[conf] && n[conf][sid]) {
|
if (n[conf]?.[sid]) {
|
||||||
delete n[conf][sid];
|
delete n[conf][sid];
|
||||||
}
|
}
|
||||||
else if (v[conf] && v[conf][sid]) {
|
else if (v[conf]?.[sid]) {
|
||||||
if (c[conf])
|
delete c[conf]?.[sid];
|
||||||
delete c[conf][sid];
|
|
||||||
|
|
||||||
if (!d[conf])
|
|
||||||
d[conf] = { };
|
|
||||||
|
|
||||||
|
d[conf] ??= { };
|
||||||
d[conf][sid] = true;
|
d[conf][sid] = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -397,35 +390,35 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* Returns a sorted array of the section objects within the given
|
* Returns a sorted array of the section objects within the given
|
||||||
* configuration, filtered by type of a type has been specified.
|
* configuration, filtered by type of a type has been specified.
|
||||||
*/
|
*/
|
||||||
sections: function(conf, type, cb) {
|
sections(conf, type, cb) {
|
||||||
var sa = [ ],
|
const sa = [ ];
|
||||||
v = this.state.values[conf],
|
const v = this.state.values[conf];
|
||||||
n = this.state.creates[conf],
|
const n = this.state.creates[conf];
|
||||||
c = this.state.changes[conf],
|
const c = this.state.changes[conf];
|
||||||
d = this.state.deletes[conf];
|
const d = this.state.deletes[conf];
|
||||||
|
|
||||||
if (!v)
|
if (!v)
|
||||||
return sa;
|
return sa;
|
||||||
|
|
||||||
for (var s in v)
|
for (const s in v)
|
||||||
if (!d || d[s] !== true)
|
if (!d || d[s] !== true)
|
||||||
if (!type || v[s]['.type'] == type)
|
if (!type || v[s]['.type'] == type)
|
||||||
sa.push(Object.assign({ }, v[s], c ? c[s] : null));
|
sa.push(Object.assign({ }, v[s], c ? c[s] : null));
|
||||||
|
|
||||||
if (n)
|
if (n)
|
||||||
for (var s in n)
|
for (const s in n)
|
||||||
if (!type || n[s]['.type'] == type)
|
if (!type || n[s]['.type'] == type)
|
||||||
sa.push(Object.assign({ }, n[s]));
|
sa.push(Object.assign({ }, n[s]));
|
||||||
|
|
||||||
sa.sort(function(a, b) {
|
sa.sort((a, b) => {
|
||||||
return a['.index'] - b['.index'];
|
return a['.index'] - b['.index'];
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var i = 0; i < sa.length; i++)
|
for (let i = 0; i < sa.length; i++)
|
||||||
sa[i]['.index'] = i;
|
sa[i]['.index'] = i;
|
||||||
|
|
||||||
if (typeof(cb) == 'function')
|
if (typeof(cb) == 'function')
|
||||||
for (var i = 0; i < sa.length; i++)
|
for (let i = 0; i < sa.length; i++)
|
||||||
cb.call(this, sa[i], sa[i]['.name']);
|
cb.call(this, sa[i], sa[i]['.name']);
|
||||||
|
|
||||||
return sa;
|
return sa;
|
||||||
@@ -456,11 +449,11 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* - Returns `null` if the config, section or option has not been
|
* - Returns `null` if the config, section or option has not been
|
||||||
* found or if the corresponding configuration is not loaded.
|
* found or if the corresponding configuration is not loaded.
|
||||||
*/
|
*/
|
||||||
get: function(conf, sid, opt) {
|
get(conf, sid, opt) {
|
||||||
var v = this.state.values,
|
const v = this.state.values;
|
||||||
n = this.state.creates,
|
const n = this.state.creates;
|
||||||
c = this.state.changes,
|
const c = this.state.changes;
|
||||||
d = this.state.deletes;
|
const d = this.state.deletes;
|
||||||
|
|
||||||
sid = this.resolveSID(conf, sid);
|
sid = this.resolveSID(conf, sid);
|
||||||
|
|
||||||
@@ -468,10 +461,7 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
/* requested option in a just created section */
|
/* requested option in a just created section */
|
||||||
if (n[conf] && n[conf][sid]) {
|
if (n[conf]?.[sid]) {
|
||||||
if (!n[conf])
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (opt == null)
|
if (opt == null)
|
||||||
return n[conf][sid];
|
return n[conf][sid];
|
||||||
|
|
||||||
@@ -481,16 +471,16 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
/* requested an option value */
|
/* requested an option value */
|
||||||
if (opt != null) {
|
if (opt != null) {
|
||||||
/* check whether option was deleted */
|
/* check whether option was deleted */
|
||||||
if (d[conf] && d[conf][sid])
|
if (d[conf]?.[sid])
|
||||||
if (d[conf][sid] === true || d[conf][sid][opt])
|
if (d[conf][sid] === true || d[conf][sid][opt])
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
/* check whether option was changed */
|
/* check whether option was changed */
|
||||||
if (c[conf] && c[conf][sid] && c[conf][sid][opt] != null)
|
if (c[conf]?.[sid][opt] != null)
|
||||||
return c[conf][sid][opt];
|
return c[conf][sid][opt];
|
||||||
|
|
||||||
/* return base value */
|
/* return base value */
|
||||||
if (v[conf] && v[conf][sid])
|
if (v[conf]?.[sid])
|
||||||
return v[conf][sid][opt];
|
return v[conf][sid][opt];
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -499,21 +489,21 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
/* requested an entire section */
|
/* requested an entire section */
|
||||||
if (v[conf]) {
|
if (v[conf]) {
|
||||||
/* check whether entire section was deleted */
|
/* check whether entire section was deleted */
|
||||||
if (d[conf] && d[conf][sid] === true)
|
if (d[conf]?.[sid] === true)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var s = v[conf][sid] || null;
|
const s = v[conf][sid] || null;
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
/* merge changes */
|
/* merge changes */
|
||||||
if (c[conf] && c[conf][sid])
|
if (c[conf]?.[sid])
|
||||||
for (var opt in c[conf][sid])
|
for (const opt in c[conf][sid])
|
||||||
if (c[conf][sid][opt] != null)
|
if (c[conf][sid][opt] != null)
|
||||||
s[opt] = c[conf][sid][opt];
|
s[opt] = c[conf][sid][opt];
|
||||||
|
|
||||||
/* merge deletions */
|
/* merge deletions */
|
||||||
if (d[conf] && d[conf][sid])
|
if (d[conf]?.[sid])
|
||||||
for (var opt in d[conf][sid])
|
for (const opt in d[conf][sid])
|
||||||
delete s[opt];
|
delete s[opt];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,18 +534,18 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* the option will be removed, otherwise it will be set or overwritten
|
* the option will be removed, otherwise it will be set or overwritten
|
||||||
* with the given value.
|
* with the given value.
|
||||||
*/
|
*/
|
||||||
set: function(conf, sid, opt, val) {
|
set(conf, sid, opt, val) {
|
||||||
var v = this.state.values,
|
const v = this.state.values;
|
||||||
n = this.state.creates,
|
const n = this.state.creates;
|
||||||
c = this.state.changes,
|
const c = this.state.changes;
|
||||||
d = this.state.deletes;
|
const d = this.state.deletes;
|
||||||
|
|
||||||
sid = this.resolveSID(conf, sid);
|
sid = this.resolveSID(conf, sid);
|
||||||
|
|
||||||
if (sid == null || opt == null || opt.charAt(0) == '.')
|
if (sid == null || opt == null || opt.charAt(0) == '.')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (n[conf] && n[conf][sid]) {
|
if (n[conf]?.[sid]) {
|
||||||
if (val != null)
|
if (val != null)
|
||||||
n[conf][sid][opt] = val;
|
n[conf][sid][opt] = val;
|
||||||
else
|
else
|
||||||
@@ -567,17 +557,14 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* only set in existing sections */
|
/* only set in existing sections */
|
||||||
if (!v[conf] || !v[conf][sid])
|
if (!v[conf]?.[sid])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!c[conf])
|
c[conf] ??= {};
|
||||||
c[conf] = {};
|
c[conf][sid] ??= {};
|
||||||
|
|
||||||
if (!c[conf][sid])
|
|
||||||
c[conf][sid] = {};
|
|
||||||
|
|
||||||
/* undelete option */
|
/* undelete option */
|
||||||
if (d[conf] && d[conf][sid]) {
|
if (d[conf]?.[sid]) {
|
||||||
if (isEmpty(d[conf][sid], opt))
|
if (isEmpty(d[conf][sid], opt))
|
||||||
delete d[conf][sid];
|
delete d[conf][sid];
|
||||||
else
|
else
|
||||||
@@ -588,7 +575,7 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* revert any change for to-be-deleted option */
|
/* revert any change for to-be-deleted option */
|
||||||
if (c[conf] && c[conf][sid]) {
|
if (c[conf]?.[sid]) {
|
||||||
if (isEmpty(c[conf][sid], opt))
|
if (isEmpty(c[conf][sid], opt))
|
||||||
delete c[conf][sid];
|
delete c[conf][sid];
|
||||||
else
|
else
|
||||||
@@ -596,12 +583,9 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* only delete existing options */
|
/* only delete existing options */
|
||||||
if (v[conf] && v[conf][sid] && v[conf][sid].hasOwnProperty(opt)) {
|
if (v[conf]?.[sid].hasOwnProperty(opt)) {
|
||||||
if (!d[conf])
|
d[conf] ??= { };
|
||||||
d[conf] = { };
|
d[conf][sid] ??= { };
|
||||||
|
|
||||||
if (!d[conf][sid])
|
|
||||||
d[conf][sid] = { };
|
|
||||||
|
|
||||||
if (d[conf][sid] !== true)
|
if (d[conf][sid] !== true)
|
||||||
d[conf][sid][opt] = true;
|
d[conf][sid][opt] = true;
|
||||||
@@ -625,7 +609,7 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* @param {string} opt
|
* @param {string} opt
|
||||||
* The name of the option to remove.
|
* The name of the option to remove.
|
||||||
*/
|
*/
|
||||||
unset: function(conf, sid, opt) {
|
unset(conf, sid, opt) {
|
||||||
return this.set(conf, sid, opt, null);
|
return this.set(conf, sid, opt, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -656,12 +640,11 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* - Returns `null` if the config, section or option has not been
|
* - Returns `null` if the config, section or option has not been
|
||||||
* found or if the corresponding configuration is not loaded.
|
* found or if the corresponding configuration is not loaded.
|
||||||
*/
|
*/
|
||||||
get_first: function(conf, type, opt) {
|
get_first(conf, type, opt) {
|
||||||
var sid = null;
|
let sid = null;
|
||||||
|
|
||||||
this.sections(conf, type, function(s) {
|
this.sections(conf, type, s => {
|
||||||
if (sid == null)
|
sid ??= s['.name'];
|
||||||
sid = s['.name'];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.get(conf, sid, opt);
|
return this.get(conf, sid, opt);
|
||||||
@@ -691,12 +674,11 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* the option will be removed, otherwise it will be set or overwritten
|
* the option will be removed, otherwise it will be set or overwritten
|
||||||
* with the given value.
|
* with the given value.
|
||||||
*/
|
*/
|
||||||
set_first: function(conf, type, opt, val) {
|
set_first(conf, type, opt, val) {
|
||||||
var sid = null;
|
let sid = null;
|
||||||
|
|
||||||
this.sections(conf, type, function(s) {
|
this.sections(conf, type, s => {
|
||||||
if (sid == null)
|
sid ??= s['.name'];
|
||||||
sid = s['.name'];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.set(conf, sid, opt, val);
|
return this.set(conf, sid, opt, val);
|
||||||
@@ -721,7 +703,7 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* @param {string} opt
|
* @param {string} opt
|
||||||
* The option name to set the value for.
|
* The option name to set the value for.
|
||||||
*/
|
*/
|
||||||
unset_first: function(conf, type, opt) {
|
unset_first(conf, type, opt) {
|
||||||
return this.set_first(conf, type, opt, null);
|
return this.set_first(conf, type, opt, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -756,14 +738,15 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* Returns `true` when the section was successfully moved, or `false`
|
* Returns `true` when the section was successfully moved, or `false`
|
||||||
* when either the section specified by `sid1` or by `sid2` is not found.
|
* when either the section specified by `sid1` or by `sid2` is not found.
|
||||||
*/
|
*/
|
||||||
move: function(conf, sid1, sid2, after) {
|
move(conf, sid1, sid2, after) {
|
||||||
var sa = this.sections(conf),
|
const sa = this.sections(conf);
|
||||||
s1 = null, s2 = null;
|
let s1 = null;
|
||||||
|
let s2 = null;
|
||||||
|
|
||||||
sid1 = this.resolveSID(conf, sid1);
|
sid1 = this.resolveSID(conf, sid1);
|
||||||
sid2 = this.resolveSID(conf, sid2);
|
sid2 = this.resolveSID(conf, sid2);
|
||||||
|
|
||||||
for (var i = 0; i < sa.length; i++) {
|
for (let i = 0; i < sa.length; i++) {
|
||||||
if (sa[i]['.name'] != sid1)
|
if (sa[i]['.name'] != sid1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -779,7 +762,7 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
sa.push(s1);
|
sa.push(s1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (var i = 0; i < sa.length; i++) {
|
for (let i = 0; i < sa.length; i++) {
|
||||||
if (sa[i]['.name'] != sid2)
|
if (sa[i]['.name'] != sid2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -792,7 +775,7 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < sa.length; i++)
|
for (let i = 0; i < sa.length; i++)
|
||||||
this.get(conf, sa[i]['.name'])['.index'] = i;
|
this.get(conf, sa[i]['.name'])['.index'] = i;
|
||||||
|
|
||||||
this.state.reorder[conf] = true;
|
this.state.reorder[conf] = true;
|
||||||
@@ -810,21 +793,21 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* Returns a promise resolving to an array of configuration names which
|
* Returns a promise resolving to an array of configuration names which
|
||||||
* have been reloaded by the save operation.
|
* have been reloaded by the save operation.
|
||||||
*/
|
*/
|
||||||
save: function() {
|
save() {
|
||||||
var v = this.state.values,
|
const v = this.state.values;
|
||||||
n = this.state.creates,
|
const n = this.state.creates;
|
||||||
c = this.state.changes,
|
const c = this.state.changes;
|
||||||
d = this.state.deletes,
|
const d = this.state.deletes;
|
||||||
r = this.state.reorder,
|
const r = this.state.reorder;
|
||||||
self = this,
|
const self = this;
|
||||||
snew = [ ],
|
const snew = [ ];
|
||||||
pkgs = { },
|
let pkgs = { };
|
||||||
tasks = [];
|
const tasks = [];
|
||||||
|
|
||||||
if (d)
|
if (d)
|
||||||
for (var conf in d) {
|
for (const conf in d) {
|
||||||
for (var sid in d[conf]) {
|
for (const sid in d[conf]) {
|
||||||
var o = d[conf][sid];
|
const o = d[conf][sid];
|
||||||
|
|
||||||
if (o === true)
|
if (o === true)
|
||||||
tasks.push(self.callDelete(conf, sid, null));
|
tasks.push(self.callDelete(conf, sid, null));
|
||||||
@@ -836,14 +819,14 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n)
|
if (n)
|
||||||
for (var conf in n) {
|
for (const conf in n) {
|
||||||
for (var sid in n[conf]) {
|
for (const sid in n[conf]) {
|
||||||
var p = {
|
const p = {
|
||||||
config: conf,
|
config: conf,
|
||||||
values: { }
|
values: { }
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var k in n[conf][sid]) {
|
for (const k in n[conf][sid]) {
|
||||||
if (k == '.type')
|
if (k == '.type')
|
||||||
p.type = n[conf][sid][k];
|
p.type = n[conf][sid][k];
|
||||||
else if (k == '.create')
|
else if (k == '.create')
|
||||||
@@ -860,27 +843,27 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (c)
|
if (c)
|
||||||
for (var conf in c) {
|
for (const conf in c) {
|
||||||
for (var sid in c[conf])
|
for (const sid in c[conf])
|
||||||
tasks.push(self.callSet(conf, sid, c[conf][sid]));
|
tasks.push(self.callSet(conf, sid, c[conf][sid]));
|
||||||
|
|
||||||
pkgs[conf] = true;
|
pkgs[conf] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
for (var conf in r)
|
for (const conf in r)
|
||||||
pkgs[conf] = true;
|
pkgs[conf] = true;
|
||||||
|
|
||||||
return Promise.all(tasks).then(function(responses) {
|
return Promise.all(tasks).then(responses => {
|
||||||
/*
|
/*
|
||||||
array "snew" holds references to the created uci sections,
|
array "snew" holds references to the created uci sections,
|
||||||
use it to assign the returned names of the new sections
|
use it to assign the returned names of the new sections
|
||||||
*/
|
*/
|
||||||
for (var i = 0; i < snew.length; i++)
|
for (let i = 0; i < snew.length; i++)
|
||||||
snew[i]['.name'] = responses[i];
|
snew[i]['.name'] = responses[i];
|
||||||
|
|
||||||
return self.reorderSections();
|
return self.reorderSections();
|
||||||
}).then(function() {
|
}).then(() => {
|
||||||
pkgs = Object.keys(pkgs);
|
pkgs = Object.keys(pkgs);
|
||||||
|
|
||||||
self.unload(pkgs);
|
self.unload(pkgs);
|
||||||
@@ -900,20 +883,20 @@ return baseclass.extend(/** @lends LuCI.uci.prototype */ {
|
|||||||
* @returns {Promise<number>}
|
* @returns {Promise<number>}
|
||||||
* Returns a promise resolving/rejecting with the `ubus` RPC status code.
|
* Returns a promise resolving/rejecting with the `ubus` RPC status code.
|
||||||
*/
|
*/
|
||||||
apply: function(timeout) {
|
apply(timeout) {
|
||||||
var self = this,
|
const self = this;
|
||||||
date = new Date();
|
const date = new Date();
|
||||||
|
|
||||||
if (typeof(timeout) != 'number' || timeout < 1)
|
if (typeof(timeout) != 'number' || timeout < 1)
|
||||||
timeout = 10;
|
timeout = 10;
|
||||||
|
|
||||||
return self.callApply(timeout, true).then(function(rv) {
|
return self.callApply(timeout, true).then(rv => {
|
||||||
if (rv != 0)
|
if (rv != 0)
|
||||||
return Promise.reject(rv);
|
return Promise.reject(rv);
|
||||||
|
|
||||||
var try_deadline = date.getTime() + 1000 * timeout;
|
const try_deadline = date.getTime() + 1000 * timeout;
|
||||||
var try_confirm = function() {
|
const try_confirm = () => {
|
||||||
return self.callConfirm().then(function(rv) {
|
return self.callConfirm().then(rv => {
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
if (date.getTime() < try_deadline)
|
if (date.getTime() < try_deadline)
|
||||||
window.setTimeout(try_confirm, 250);
|
window.setTimeout(try_confirm, 250);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,10 +5,10 @@ function bytelen(x) {
|
|||||||
return new Blob([x]).size;
|
return new Blob([x]).size;
|
||||||
}
|
}
|
||||||
|
|
||||||
var Validator = baseclass.extend({
|
const Validator = baseclass.extend({
|
||||||
__name__: 'Validation',
|
__name__: 'Validation',
|
||||||
|
|
||||||
__init__: function(field, type, optional, vfunc, validatorFactory) {
|
__init__(field, type, optional, vfunc, validatorFactory) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.optional = optional;
|
this.optional = optional;
|
||||||
this.vfunc = vfunc;
|
this.vfunc = vfunc;
|
||||||
@@ -16,7 +16,7 @@ var Validator = baseclass.extend({
|
|||||||
this.factory = validatorFactory;
|
this.factory = validatorFactory;
|
||||||
},
|
},
|
||||||
|
|
||||||
assert: function(condition, message) {
|
assert(condition, message) {
|
||||||
if (!condition) {
|
if (!condition) {
|
||||||
this.field.classList.add('cbi-input-invalid');
|
this.field.classList.add('cbi-input-invalid');
|
||||||
this.error = message;
|
this.error = message;
|
||||||
@@ -28,8 +28,8 @@ var Validator = baseclass.extend({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
apply: function(name, value, args) {
|
apply(name, value, args) {
|
||||||
var func;
|
let func;
|
||||||
|
|
||||||
if (typeof(name) === 'function')
|
if (typeof(name) === 'function')
|
||||||
func = name;
|
func = name;
|
||||||
@@ -44,7 +44,7 @@ var Validator = baseclass.extend({
|
|||||||
return func.apply(this, args);
|
return func.apply(this, args);
|
||||||
},
|
},
|
||||||
|
|
||||||
validate: function() {
|
validate() {
|
||||||
/* element is detached */
|
/* element is detached */
|
||||||
if (!findParent(this.field, 'body') && !findParent(this.field, '[data-field]'))
|
if (!findParent(this.field, 'body') && !findParent(this.field, '[data-field]'))
|
||||||
return true;
|
return true;
|
||||||
@@ -53,7 +53,7 @@ var Validator = baseclass.extend({
|
|||||||
this.value = (this.field.value != null) ? this.field.value : '';
|
this.value = (this.field.value != null) ? this.field.value : '';
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
var valid;
|
let valid;
|
||||||
|
|
||||||
if (this.value.length === 0)
|
if (this.value.length === 0)
|
||||||
valid = this.assert(this.optional, _('non-empty value'));
|
valid = this.assert(this.optional, _('non-empty value'));
|
||||||
@@ -61,7 +61,7 @@ var Validator = baseclass.extend({
|
|||||||
valid = this.vstack[0].apply(this, this.vstack[1]);
|
valid = this.vstack[0].apply(this, this.vstack[1]);
|
||||||
|
|
||||||
if (valid !== true) {
|
if (valid !== true) {
|
||||||
var message = _('Expecting: %s').format(this.error);
|
const message = _('Expecting: %s').format(this.error);
|
||||||
this.field.setAttribute('data-tooltip', message);
|
this.field.setAttribute('data-tooltip', message);
|
||||||
this.field.setAttribute('data-tooltip-style', 'error');
|
this.field.setAttribute('data-tooltip-style', 'error');
|
||||||
this.field.dispatchEvent(new CustomEvent('validation-failure', {
|
this.field.dispatchEvent(new CustomEvent('validation-failure', {
|
||||||
@@ -97,22 +97,22 @@ var Validator = baseclass.extend({
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var ValidatorFactory = baseclass.extend({
|
const ValidatorFactory = baseclass.extend({
|
||||||
__name__: 'ValidatorFactory',
|
__name__: 'ValidatorFactory',
|
||||||
|
|
||||||
create: function(field, type, optional, vfunc) {
|
create(field, type, optional, vfunc) {
|
||||||
return new Validator(field, type, optional, vfunc, this);
|
return new Validator(field, type, optional, vfunc, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
compile: function(code) {
|
compile(code) {
|
||||||
var pos = 0;
|
let pos = 0;
|
||||||
var esc = false;
|
let esc = false;
|
||||||
var depth = 0;
|
let depth = 0;
|
||||||
var stack = [ ];
|
const stack = [ ];
|
||||||
|
|
||||||
code += ',';
|
code += ',';
|
||||||
|
|
||||||
for (var i = 0; i < code.length; i++) {
|
for (let i = 0; i < code.length; i++) {
|
||||||
if (esc) {
|
if (esc) {
|
||||||
esc = false;
|
esc = false;
|
||||||
continue;
|
continue;
|
||||||
@@ -128,7 +128,7 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
case 44:
|
case 44:
|
||||||
if (depth <= 0) {
|
if (depth <= 0) {
|
||||||
if (pos < i) {
|
if (pos < i) {
|
||||||
var label = code.substring(pos, i);
|
let label = code.substring(pos, i);
|
||||||
label = label.replace(/\\(.)/g, '$1');
|
label = label.replace(/\\(.)/g, '$1');
|
||||||
label = label.replace(/^[ \t]+/g, '');
|
label = label.replace(/^[ \t]+/g, '');
|
||||||
label = label.replace(/[ \t]+$/g, '');
|
label = label.replace(/[ \t]+$/g, '');
|
||||||
@@ -170,15 +170,15 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return stack;
|
return stack;
|
||||||
},
|
},
|
||||||
|
|
||||||
parseInteger: function(x) {
|
parseInteger(x) {
|
||||||
return (/^-?\d+$/.test(x) ? +x : NaN);
|
return (/^-?\d+$/.test(x) ? +x : NaN);
|
||||||
},
|
},
|
||||||
|
|
||||||
parseDecimal: function(x) {
|
parseDecimal(x) {
|
||||||
return (/^-?\d+(?:\.\d+)?$/.test(x) ? +x : NaN);
|
return (/^-?\d+(?:\.\d+)?$/.test(x) ? +x : NaN);
|
||||||
},
|
},
|
||||||
|
|
||||||
parseIPv4: function(x) {
|
parseIPv4(x) {
|
||||||
if (!x.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/))
|
if (!x.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -188,34 +188,35 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return [ +RegExp.$1, +RegExp.$2, +RegExp.$3, +RegExp.$4 ];
|
return [ +RegExp.$1, +RegExp.$2, +RegExp.$3, +RegExp.$4 ];
|
||||||
},
|
},
|
||||||
|
|
||||||
parseIPv6: function(x) {
|
parseIPv6(x) {
|
||||||
if (x.match(/^([a-fA-F0-9:]+):(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/)) {
|
if (x.match(/^([a-fA-F0-9:]+):(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/)) {
|
||||||
var v6 = RegExp.$1, v4 = this.parseIPv4(RegExp.$2);
|
const v6 = RegExp.$1;
|
||||||
|
const v4 = this.parseIPv4(RegExp.$2);
|
||||||
|
|
||||||
if (!v4)
|
if (!v4)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
x = v6 + ':' + (v4[0] * 256 + v4[1]).toString(16)
|
x = `${v6}:${(v4[0] * 256 + v4[1]).toString(16)}:${(v4[2] * 256 + v4[3]).toString(16)}`;
|
||||||
+ ':' + (v4[2] * 256 + v4[3]).toString(16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!x.match(/^[a-fA-F0-9:]+$/))
|
if (!x.match(/^[a-fA-F0-9:]+$/))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var prefix_suffix = x.split(/::/);
|
const prefix_suffix = x.split(/::/);
|
||||||
|
|
||||||
if (prefix_suffix.length > 2)
|
if (prefix_suffix.length > 2)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var prefix = (prefix_suffix[0] || '0').split(/:/);
|
const prefix = (prefix_suffix[0] || '0').split(/:/);
|
||||||
var suffix = prefix_suffix.length > 1 ? (prefix_suffix[1] || '0').split(/:/) : [];
|
const suffix = prefix_suffix.length > 1 ? (prefix_suffix[1] || '0').split(/:/) : [];
|
||||||
|
|
||||||
if (suffix.length ? (prefix.length + suffix.length > 7)
|
if (suffix.length ? (prefix.length + suffix.length > 7)
|
||||||
: ((prefix_suffix.length < 2 && prefix.length < 8) || prefix.length > 8))
|
: ((prefix_suffix.length < 2 && prefix.length < 8) || prefix.length > 8))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var i, word;
|
let i;
|
||||||
var words = [];
|
let word;
|
||||||
|
const words = [];
|
||||||
|
|
||||||
for (i = 0, word = parseInt(prefix[0], 16); i < prefix.length; word = parseInt(prefix[++i], 16))
|
for (i = 0, word = parseInt(prefix[0], 16); i < prefix.length; word = parseInt(prefix[++i], 16))
|
||||||
if (prefix[i].length <= 4 && !isNaN(word) && word <= 0xFFFF)
|
if (prefix[i].length <= 4 && !isNaN(word) && word <= 0xFFFF)
|
||||||
@@ -236,112 +237,112 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
types: {
|
types: {
|
||||||
integer: function() {
|
integer() {
|
||||||
return this.assert(!isNaN(this.factory.parseInteger(this.value)), _('valid integer value'));
|
return this.assert(!isNaN(this.factory.parseInteger(this.value)), _('valid integer value'));
|
||||||
},
|
},
|
||||||
|
|
||||||
uinteger: function() {
|
uinteger() {
|
||||||
return this.assert(this.factory.parseInteger(this.value) >= 0, _('positive integer value'));
|
return this.assert(this.factory.parseInteger(this.value) >= 0, _('positive integer value'));
|
||||||
},
|
},
|
||||||
|
|
||||||
float: function() {
|
float() {
|
||||||
return this.assert(!isNaN(this.factory.parseDecimal(this.value)), _('valid decimal value'));
|
return this.assert(!isNaN(this.factory.parseDecimal(this.value)), _('valid decimal value'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ufloat: function() {
|
ufloat() {
|
||||||
return this.assert(this.factory.parseDecimal(this.value) >= 0, _('positive decimal value'));
|
return this.assert(this.factory.parseDecimal(this.value) >= 0, _('positive decimal value'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ipaddr: function(nomask) {
|
ipaddr(nomask) {
|
||||||
return this.assert(this.apply('ip4addr', null, [nomask]) || this.apply('ip6addr', null, [nomask]),
|
return this.assert(this.apply('ip4addr', null, [nomask]) || this.apply('ip6addr', null, [nomask]),
|
||||||
nomask ? _('valid IP address') : _('valid IP address or prefix'));
|
nomask ? _('valid IP address') : _('valid IP address or prefix'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ip4addr: function(nomask) {
|
ip4addr(nomask) {
|
||||||
var re = nomask ? /^(\d+\.\d+\.\d+\.\d+)$/ : /^(\d+\.\d+\.\d+\.\d+)(?:\/(\d+\.\d+\.\d+\.\d+)|\/(\d{1,2}))?$/,
|
const re = nomask ? /^(\d+\.\d+\.\d+\.\d+)$/ : /^(\d+\.\d+\.\d+\.\d+)(?:\/(\d+\.\d+\.\d+\.\d+)|\/(\d{1,2}))?$/;
|
||||||
m = this.value.match(re);
|
const m = this.value.match(re);
|
||||||
|
|
||||||
return this.assert(m && this.factory.parseIPv4(m[1]) && (m[2] ? this.factory.parseIPv4(m[2]) : (m[3] ? this.apply('ip4prefix', m[3]) : true)),
|
return this.assert(m && this.factory.parseIPv4(m[1]) && (m[2] ? this.factory.parseIPv4(m[2]) : (m[3] ? this.apply('ip4prefix', m[3]) : true)),
|
||||||
nomask ? _('valid IPv4 address') : _('valid IPv4 address or network'));
|
nomask ? _('valid IPv4 address') : _('valid IPv4 address or network'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ip6addr: function(nomask) {
|
ip6addr(nomask) {
|
||||||
var re = nomask ? /^([0-9a-fA-F:.]+)$/ : /^([0-9a-fA-F:.]+)(?:\/(\d{1,3}))?$/,
|
const re = nomask ? /^([0-9a-fA-F:.]+)$/ : /^([0-9a-fA-F:.]+)(?:\/(\d{1,3}))?$/;
|
||||||
m = this.value.match(re);
|
const m = this.value.match(re);
|
||||||
|
|
||||||
return this.assert(m && this.factory.parseIPv6(m[1]) && (m[2] ? this.apply('ip6prefix', m[2]) : true),
|
return this.assert(m && this.factory.parseIPv6(m[1]) && (m[2] ? this.apply('ip6prefix', m[2]) : true),
|
||||||
nomask ? _('valid IPv6 address') : _('valid IPv6 address or prefix'));
|
nomask ? _('valid IPv6 address') : _('valid IPv6 address or prefix'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ip4prefix: function() {
|
ip4prefix() {
|
||||||
return this.assert(!isNaN(this.value) && this.value >= 0 && this.value <= 32,
|
return this.assert(!isNaN(this.value) && this.value >= 0 && this.value <= 32,
|
||||||
_('valid IPv4 prefix value (0-32)'));
|
_('valid IPv4 prefix value (0-32)'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ip6prefix: function() {
|
ip6prefix() {
|
||||||
return this.assert(!isNaN(this.value) && this.value >= 0 && this.value <= 128,
|
return this.assert(!isNaN(this.value) && this.value >= 0 && this.value <= 128,
|
||||||
_('valid IPv6 prefix value (0-128)'));
|
_('valid IPv6 prefix value (0-128)'));
|
||||||
},
|
},
|
||||||
|
|
||||||
cidr: function(negative) {
|
cidr(negative) {
|
||||||
return this.assert(this.apply('cidr4', null, [negative]) || this.apply('cidr6', null, [negative]),
|
return this.assert(this.apply('cidr4', null, [negative]) || this.apply('cidr6', null, [negative]),
|
||||||
_('valid IPv4 or IPv6 CIDR'));
|
_('valid IPv4 or IPv6 CIDR'));
|
||||||
},
|
},
|
||||||
|
|
||||||
cidr4: function(negative) {
|
cidr4(negative) {
|
||||||
var m = this.value.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(-)?(\d{1,2})$/);
|
const m = this.value.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(-)?(\d{1,2})$/);
|
||||||
return this.assert(m && this.factory.parseIPv4(m[1]) && (negative || !m[2]) && this.apply('ip4prefix', m[3]),
|
return this.assert(m && this.factory.parseIPv4(m[1]) && (negative || !m[2]) && this.apply('ip4prefix', m[3]),
|
||||||
_('valid IPv4 CIDR'));
|
_('valid IPv4 CIDR'));
|
||||||
},
|
},
|
||||||
|
|
||||||
cidr6: function(negative) {
|
cidr6(negative) {
|
||||||
var m = this.value.match(/^([0-9a-fA-F:.]+)\/(-)?(\d{1,3})$/);
|
const m = this.value.match(/^([0-9a-fA-F:.]+)\/(-)?(\d{1,3})$/);
|
||||||
return this.assert(m && this.factory.parseIPv6(m[1]) && (negative || !m[2]) && this.apply('ip6prefix', m[3]),
|
return this.assert(m && this.factory.parseIPv6(m[1]) && (negative || !m[2]) && this.apply('ip6prefix', m[3]),
|
||||||
_('valid IPv6 CIDR'));
|
_('valid IPv6 CIDR'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ipnet4: function() {
|
ipnet4() {
|
||||||
var m = this.value.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
|
const m = this.value.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
|
||||||
return this.assert(m && this.factory.parseIPv4(m[1]) && this.factory.parseIPv4(m[2]), _('IPv4 network in address/netmask notation'));
|
return this.assert(m && this.factory.parseIPv4(m[1]) && this.factory.parseIPv4(m[2]), _('IPv4 network in address/netmask notation'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ipnet6: function() {
|
ipnet6() {
|
||||||
var m = this.value.match(/^([0-9a-fA-F:.]+)\/([0-9a-fA-F:.]+)$/);
|
const m = this.value.match(/^([0-9a-fA-F:.]+)\/([0-9a-fA-F:.]+)$/);
|
||||||
return this.assert(m && this.factory.parseIPv6(m[1]) && this.factory.parseIPv6(m[2]), _('IPv6 network in address/netmask notation'));
|
return this.assert(m && this.factory.parseIPv6(m[1]) && this.factory.parseIPv6(m[2]), _('IPv6 network in address/netmask notation'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ip6hostid: function() {
|
ip6hostid() {
|
||||||
if (this.value == "eui64" || this.value == "random")
|
if (this.value == "eui64" || this.value == "random")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var v6 = this.factory.parseIPv6(this.value);
|
const v6 = this.factory.parseIPv6(this.value);
|
||||||
return this.assert(!(!v6 || v6[0] || v6[1] || v6[2] || v6[3]), _('valid IPv6 host id'));
|
return this.assert(!(!v6 || v6[0] || v6[1] || v6[2] || v6[3]), _('valid IPv6 host id'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ipmask: function(negative) {
|
ipmask(negative) {
|
||||||
return this.assert(this.apply('ipmask4', null, [negative]) || this.apply('ipmask6', null, [negative]),
|
return this.assert(this.apply('ipmask4', null, [negative]) || this.apply('ipmask6', null, [negative]),
|
||||||
_('valid network in address/netmask notation'));
|
_('valid network in address/netmask notation'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ipmask4: function(negative) {
|
ipmask4(negative) {
|
||||||
return this.assert(this.apply('cidr4', null, [negative]) || this.apply('ipnet4') || this.apply('ip4addr'),
|
return this.assert(this.apply('cidr4', null, [negative]) || this.apply('ipnet4') || this.apply('ip4addr'),
|
||||||
_('valid IPv4 network'));
|
_('valid IPv4 network'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ipmask6: function(negative) {
|
ipmask6(negative) {
|
||||||
return this.assert(this.apply('cidr6', null, [negative]) || this.apply('ipnet6') || this.apply('ip6addr'),
|
return this.assert(this.apply('cidr6', null, [negative]) || this.apply('ipnet6') || this.apply('ip6addr'),
|
||||||
_('valid IPv6 network'));
|
_('valid IPv6 network'));
|
||||||
},
|
},
|
||||||
|
|
||||||
port: function() {
|
port() {
|
||||||
var p = this.factory.parseInteger(this.value);
|
const p = this.factory.parseInteger(this.value);
|
||||||
return this.assert(p >= 0 && p <= 65535, _('valid port value'));
|
return this.assert(p >= 0 && p <= 65535, _('valid port value'));
|
||||||
},
|
},
|
||||||
|
|
||||||
portrange: function() {
|
portrange() {
|
||||||
if (this.value.match(/^(\d+)-(\d+)$/)) {
|
if (this.value.match(/^(\d+)-(\d+)$/)) {
|
||||||
var p1 = +RegExp.$1;
|
const p1 = +RegExp.$1;
|
||||||
var p2 = +RegExp.$2;
|
const p2 = +RegExp.$2;
|
||||||
return this.assert(p1 <= p2 && p2 <= 65535,
|
return this.assert(p1 <= p2 && p2 <= 65535,
|
||||||
_('valid port or port range (port1-port2)'));
|
_('valid port or port range (port1-port2)'));
|
||||||
}
|
}
|
||||||
@@ -349,18 +350,18 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return this.assert(this.apply('port'), _('valid port or port range (port1-port2)'));
|
return this.assert(this.apply('port'), _('valid port or port range (port1-port2)'));
|
||||||
},
|
},
|
||||||
|
|
||||||
macaddr: function(multicast) {
|
macaddr(multicast) {
|
||||||
var m = this.value.match(/^([a-fA-F0-9]{2}):([a-fA-F0-9]{2}:){4}[a-fA-F0-9]{2}$/);
|
const m = this.value.match(/^([a-fA-F0-9]{2}):([a-fA-F0-9]{2}:){4}[a-fA-F0-9]{2}$/);
|
||||||
return this.assert(m != null && !(+m[1] & 1) == !multicast,
|
return this.assert(m != null && !(+m[1] & 1) == !multicast,
|
||||||
multicast ? _('valid multicast MAC address') : _('valid MAC address'));
|
multicast ? _('valid multicast MAC address') : _('valid MAC address'));
|
||||||
},
|
},
|
||||||
|
|
||||||
host: function(ipv4only) {
|
host(ipv4only) {
|
||||||
return this.assert(this.apply('hostname') || this.apply(ipv4only == 1 ? 'ip4addr' : 'ipaddr', null, ['nomask']),
|
return this.assert(this.apply('hostname') || this.apply(ipv4only == 1 ? 'ip4addr' : 'ipaddr', null, ['nomask']),
|
||||||
_('valid hostname or IP address'));
|
_('valid hostname or IP address'));
|
||||||
},
|
},
|
||||||
|
|
||||||
hostname: function(strict) {
|
hostname(strict) {
|
||||||
if (this.value.length <= 253)
|
if (this.value.length <= 253)
|
||||||
return this.assert(
|
return this.assert(
|
||||||
(this.value.match(/^[a-zA-Z0-9_]+$/) != null ||
|
(this.value.match(/^[a-zA-Z0-9_]+$/) != null ||
|
||||||
@@ -372,26 +373,26 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return this.assert(false, _('valid hostname'));
|
return this.assert(false, _('valid hostname'));
|
||||||
},
|
},
|
||||||
|
|
||||||
network: function() {
|
network() {
|
||||||
return this.assert(this.apply('uciname') || this.apply('hostname') || this.apply('ip4addr') || this.apply('ip6addr'),
|
return this.assert(this.apply('uciname') || this.apply('hostname') || this.apply('ip4addr') || this.apply('ip6addr'),
|
||||||
_('valid UCI identifier, hostname or IP address range'));
|
_('valid UCI identifier, hostname or IP address range'));
|
||||||
},
|
},
|
||||||
|
|
||||||
hostport: function(ipv4only) {
|
hostport(ipv4only) {
|
||||||
var hp = this.value.split(/:/);
|
const hp = this.value.split(/:/);
|
||||||
return this.assert(hp.length == 2 && this.apply('host', hp[0], [ipv4only]) && this.apply('port', hp[1]),
|
return this.assert(hp.length == 2 && this.apply('host', hp[0], [ipv4only]) && this.apply('port', hp[1]),
|
||||||
_('valid host:port'));
|
_('valid host:port'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ip4addrport: function() {
|
ip4addrport() {
|
||||||
var hp = this.value.split(/:/);
|
const hp = this.value.split(/:/);
|
||||||
return this.assert(hp.length == 2 && this.apply('ip4addr', hp[0], [true]) && this.apply('port', hp[1]),
|
return this.assert(hp.length == 2 && this.apply('ip4addr', hp[0], [true]) && this.apply('port', hp[1]),
|
||||||
_('valid IPv4 address:port'));
|
_('valid IPv4 address:port'));
|
||||||
},
|
},
|
||||||
|
|
||||||
ipaddrport: function(bracket) {
|
ipaddrport(bracket) {
|
||||||
var m4 = this.value.match(/^([^\[\]:]+):(\d+)$/),
|
const m4 = this.value.match(/^([^\[\]:]+):(\d+)$/);
|
||||||
m6 = this.value.match((bracket == 1) ? /^\[(.+)\]:(\d+)$/ : /^([^\[\]]+):(\d+)$/);
|
const m6 = this.value.match((bracket == 1) ? /^\[(.+)\]:(\d+)$/ : /^([^\[\]]+):(\d+)$/);
|
||||||
|
|
||||||
if (m4)
|
if (m4)
|
||||||
return this.assert(this.apply('ip4addr', m4[1], [true]) && this.apply('port', m4[2]),
|
return this.assert(this.apply('ip4addr', m4[1], [true]) && this.apply('port', m4[2]),
|
||||||
@@ -401,8 +402,8 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
_('valid address:port'));
|
_('valid address:port'));
|
||||||
},
|
},
|
||||||
|
|
||||||
wpakey: function() {
|
wpakey() {
|
||||||
var v = this.value;
|
const v = this.value;
|
||||||
|
|
||||||
if (v.length == 64)
|
if (v.length == 64)
|
||||||
return this.assert(v.match(/^[a-fA-F0-9]{64}$/), _('valid hexadecimal WPA key'));
|
return this.assert(v.match(/^[a-fA-F0-9]{64}$/), _('valid hexadecimal WPA key'));
|
||||||
@@ -410,8 +411,8 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return this.assert((v.length >= 8) && (v.length <= 63), _('key between 8 and 63 characters'));
|
return this.assert((v.length >= 8) && (v.length <= 63), _('key between 8 and 63 characters'));
|
||||||
},
|
},
|
||||||
|
|
||||||
wepkey: function() {
|
wepkey() {
|
||||||
var v = this.value;
|
let v = this.value;
|
||||||
|
|
||||||
if (v.substr(0, 2) === 's:')
|
if (v.substr(0, 2) === 's:')
|
||||||
v = v.substr(2);
|
v = v.substr(2);
|
||||||
@@ -422,12 +423,12 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return this.assert((v.length === 5) || (v.length === 13), _('key with either 5 or 13 characters'));
|
return this.assert((v.length === 5) || (v.length === 13), _('key with either 5 or 13 characters'));
|
||||||
},
|
},
|
||||||
|
|
||||||
uciname: function() {
|
uciname() {
|
||||||
return this.assert(this.value.match(/^[a-zA-Z0-9_]+$/), _('valid UCI identifier'));
|
return this.assert(this.value.match(/^[a-zA-Z0-9_]+$/), _('valid UCI identifier'));
|
||||||
},
|
},
|
||||||
|
|
||||||
netdevname: function() {
|
netdevname() {
|
||||||
var v = this.value;
|
const v = this.value;
|
||||||
|
|
||||||
if (v == '.' || v == '..')
|
if (v == '.' || v == '..')
|
||||||
return this.assert(false, _('valid network device name, not "." or ".."'));
|
return this.assert(false, _('valid network device name, not "." or ".."'));
|
||||||
@@ -435,44 +436,44 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return this.assert(v.match(/^[^:\/%\s]{1,15}$/), _('valid network device name between 1 and 15 characters not containing ":", "/", "%" or spaces'));
|
return this.assert(v.match(/^[^:\/%\s]{1,15}$/), _('valid network device name between 1 and 15 characters not containing ":", "/", "%" or spaces'));
|
||||||
},
|
},
|
||||||
|
|
||||||
range: function(min, max) {
|
range(min, max) {
|
||||||
var val = this.factory.parseDecimal(this.value);
|
const val = this.factory.parseDecimal(this.value);
|
||||||
return this.assert(val >= +min && val <= +max, _('value between %f and %f').format(min, max));
|
return this.assert(val >= +min && val <= +max, _('value between %f and %f').format(min, max));
|
||||||
},
|
},
|
||||||
|
|
||||||
min: function(min) {
|
min(min) {
|
||||||
return this.assert(this.factory.parseDecimal(this.value) >= +min, _('value greater or equal to %f').format(min));
|
return this.assert(this.factory.parseDecimal(this.value) >= +min, _('value greater or equal to %f').format(min));
|
||||||
},
|
},
|
||||||
|
|
||||||
max: function(max) {
|
max(max) {
|
||||||
return this.assert(this.factory.parseDecimal(this.value) <= +max, _('value smaller or equal to %f').format(max));
|
return this.assert(this.factory.parseDecimal(this.value) <= +max, _('value smaller or equal to %f').format(max));
|
||||||
},
|
},
|
||||||
|
|
||||||
length: function(len) {
|
length(len) {
|
||||||
return this.assert(bytelen(this.value) == +len,
|
return this.assert(bytelen(this.value) == +len,
|
||||||
_('value with %d characters').format(len));
|
_('value with %d characters').format(len));
|
||||||
},
|
},
|
||||||
|
|
||||||
rangelength: function(min, max) {
|
rangelength(min, max) {
|
||||||
var len = bytelen(this.value);
|
const len = bytelen(this.value);
|
||||||
return this.assert((len >= +min) && (len <= +max),
|
return this.assert((len >= +min) && (len <= +max),
|
||||||
_('value between %d and %d characters').format(min, max));
|
_('value between %d and %d characters').format(min, max));
|
||||||
},
|
},
|
||||||
|
|
||||||
minlength: function(min) {
|
minlength(min) {
|
||||||
return this.assert(bytelen(this.value) >= +min,
|
return this.assert(bytelen(this.value) >= +min,
|
||||||
_('value with at least %d characters').format(min));
|
_('value with at least %d characters').format(min));
|
||||||
},
|
},
|
||||||
|
|
||||||
maxlength: function(max) {
|
maxlength(max) {
|
||||||
return this.assert(bytelen(this.value) <= +max,
|
return this.assert(bytelen(this.value) <= +max,
|
||||||
_('value with at most %d characters').format(max));
|
_('value with at most %d characters').format(max));
|
||||||
},
|
},
|
||||||
|
|
||||||
or: function() {
|
or() {
|
||||||
var errors = [];
|
const errors = [];
|
||||||
|
|
||||||
for (var i = 0; i < arguments.length; i += 2) {
|
for (let i = 0; i < arguments.length; i += 2) {
|
||||||
if (typeof arguments[i] != 'function') {
|
if (typeof arguments[i] != 'function') {
|
||||||
if (arguments[i] == this.value)
|
if (arguments[i] == this.value)
|
||||||
return this.assert(true);
|
return this.assert(true);
|
||||||
@@ -487,13 +488,13 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var t = _('One of the following: %s');
|
const t = _('One of the following: %s');
|
||||||
|
|
||||||
return this.assert(false, t.format('\n - ' + errors.join('\n - ')));
|
return this.assert(false, t.format(`\n - ${errors.join('\n - ')}`));
|
||||||
},
|
},
|
||||||
|
|
||||||
and: function() {
|
and() {
|
||||||
for (var i = 0; i < arguments.length; i += 2) {
|
for (let i = 0; i < arguments.length; i += 2) {
|
||||||
if (typeof arguments[i] != 'function') {
|
if (typeof arguments[i] != 'function') {
|
||||||
if (arguments[i] != this.value)
|
if (arguments[i] != this.value)
|
||||||
return this.assert(false, '"%s"'.format(arguments[i]));
|
return this.assert(false, '"%s"'.format(arguments[i]));
|
||||||
@@ -507,7 +508,7 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return this.assert(true);
|
return this.assert(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
neg: function() {
|
neg() {
|
||||||
this.value = this.value.replace(/^[ \t]*![ \t]*/, '');
|
this.value = this.value.replace(/^[ \t]*![ \t]*/, '');
|
||||||
|
|
||||||
if (arguments[0].apply(this, arguments[1]))
|
if (arguments[0].apply(this, arguments[1]))
|
||||||
@@ -516,64 +517,58 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return this.assert(false, _('Potential negation of: %s').format(this.error));
|
return this.assert(false, _('Potential negation of: %s').format(this.error));
|
||||||
},
|
},
|
||||||
|
|
||||||
list: function(subvalidator, subargs) {
|
list(subvalidator, subargs) {
|
||||||
this.field.setAttribute('data-is-list', 'true');
|
this.field.setAttribute('data-is-list', 'true');
|
||||||
|
|
||||||
var tokens = this.value.match(/[^ \t]+/g);
|
const tokens = this.value.match(/[^ \t]+/g);
|
||||||
for (var i = 0; i < tokens.length; i++)
|
for (let i = 0; i < tokens.length; i++)
|
||||||
if (!this.apply(subvalidator, tokens[i], subargs))
|
if (!this.apply(subvalidator, tokens[i], subargs))
|
||||||
return this.assert(false, this.error);
|
return this.assert(false, this.error);
|
||||||
|
|
||||||
return this.assert(true);
|
return this.assert(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
phonedigit: function() {
|
phonedigit() {
|
||||||
return this.assert(this.value.match(/^[0-9\*#!\.]+$/),
|
return this.assert(this.value.match(/^[0-9\*#!\.]+$/),
|
||||||
_('valid phone digit (0-9, "*", "#", "!" or ".")'));
|
_('valid phone digit (0-9, "*", "#", "!" or ".")'));
|
||||||
},
|
},
|
||||||
|
|
||||||
timehhmmss: function() {
|
timehhmmss() {
|
||||||
return this.assert(this.value.match(/^[0-6][0-9]:[0-6][0-9]:[0-6][0-9]$/),
|
return this.assert(this.value.match(/^[0-6][0-9]:[0-6][0-9]:[0-6][0-9]$/),
|
||||||
_('valid time (HH:MM:SS)'));
|
_('valid time (HH:MM:SS)'));
|
||||||
},
|
},
|
||||||
|
|
||||||
dateyyyymmdd: function() {
|
dateyyyymmdd() {
|
||||||
if (this.value.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/)) {
|
if (this.value.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/)) {
|
||||||
var year = +RegExp.$1,
|
const year = +RegExp.$1;
|
||||||
month = +RegExp.$2,
|
const month = +RegExp.$2;
|
||||||
day = +RegExp.$3,
|
const day = +RegExp.$3;
|
||||||
days_in_month = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
|
const days_in_month = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
|
||||||
|
|
||||||
var is_leap_year = function(year) {
|
const is_leap_year = year => (!(year % 4) && (year % 100)) || !(year % 400);
|
||||||
return ((!(year % 4) && (year % 100)) || !(year % 400));
|
const get_days_in_month = (month, year) => (month === 2 && is_leap_year(year)) ? 29 : days_in_month[month - 1];
|
||||||
}
|
|
||||||
|
|
||||||
var get_days_in_month = function(month, year) {
|
|
||||||
return (month === 2 && is_leap_year(year)) ? 29 : days_in_month[month - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Firewall rules in the past don't make sense */
|
/* Firewall rules in the past don't make sense */
|
||||||
return this.assert(year >= 2015 && month && month <= 12 && day && day <= get_days_in_month(month, year),
|
return this.assert(year >= 2015 && month && month <= 12 && day && day <= get_days_in_month(month, year),
|
||||||
_('valid date (YYYY-MM-DD)'));
|
_('valid date (YYYY-MM-DD)'));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.assert(false, _('valid date (YYYY-MM-DD)'));
|
return this.assert(false, _('valid date (YYYY-MM-DD)'));
|
||||||
},
|
},
|
||||||
|
|
||||||
unique: function(subvalidator, subargs) {
|
unique(subvalidator, subargs) {
|
||||||
var ctx = this,
|
const ctx = this;
|
||||||
option = findParent(ctx.field, '[data-widget][data-name]'),
|
const option = findParent(ctx.field, '[data-widget][data-name]');
|
||||||
section = findParent(option, '.cbi-section'),
|
const section = findParent(option, '.cbi-section');
|
||||||
query = '[data-widget="%s"][data-name="%s"]'.format(option.getAttribute('data-widget'), option.getAttribute('data-name')),
|
const query = '[data-widget="%s"][data-name="%s"]'.format(option.getAttribute('data-widget'), option.getAttribute('data-name'));
|
||||||
unique = true;
|
let unique = true;
|
||||||
|
|
||||||
section.querySelectorAll(query).forEach(function(sibling) {
|
section.querySelectorAll(query).forEach(sibling => {
|
||||||
if (sibling === option)
|
if (sibling === option)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var input = sibling.querySelector('[data-type]'),
|
const input = sibling.querySelector('[data-type]');
|
||||||
values = input ? (input.getAttribute('data-is-list') ? input.value.match(/[^ \t]+/g) : [ input.value ]) : null;
|
const values = input ? (input.getAttribute('data-is-list') ? input.value.match(/[^ \t]+/g) : [ input.value ]) : null;
|
||||||
|
|
||||||
if (values !== null && values.indexOf(ctx.value) !== -1)
|
if (values !== null && values.indexOf(ctx.value) !== -1)
|
||||||
unique = false;
|
unique = false;
|
||||||
@@ -588,24 +583,24 @@ var ValidatorFactory = baseclass.extend({
|
|||||||
return this.assert(true);
|
return this.assert(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
hexstring: function() {
|
hexstring() {
|
||||||
return this.assert(this.value.match(/^([a-f0-9][a-f0-9]|[A-F0-9][A-F0-9])+$/),
|
return this.assert(this.value.match(/^([a-f0-9][a-f0-9]|[A-F0-9][A-F0-9])+$/),
|
||||||
_('hexadecimal encoded value'));
|
_('hexadecimal encoded value'));
|
||||||
},
|
},
|
||||||
|
|
||||||
string: function() {
|
string() {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
directory: function() {
|
directory() {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
file: function() {
|
file() {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
device: function() {
|
device() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user