mirror of https://github.com/kenzok8/small.git
update 2025-01-15 16:16:42
This commit is contained in:
parent
d486cd3a96
commit
29bc41f295
|
@ -26,9 +26,9 @@ const monospacefonts = [
|
||||||
];
|
];
|
||||||
|
|
||||||
return baseclass.extend({
|
return baseclass.extend({
|
||||||
rulesetdoc: rulesetdoc,
|
rulesetdoc,
|
||||||
sharktaikogif: sharktaikogif,
|
sharktaikogif,
|
||||||
monospacefonts: monospacefonts,
|
monospacefonts,
|
||||||
|
|
||||||
dashrepos: [
|
dashrepos: [
|
||||||
['zephyruso/zashboard', _('zashboard')],
|
['zephyruso/zashboard', _('zashboard')],
|
||||||
|
@ -231,8 +231,8 @@ return baseclass.extend({
|
||||||
],
|
],
|
||||||
|
|
||||||
CBIListValue: form.ListValue.extend({
|
CBIListValue: form.ListValue.extend({
|
||||||
renderWidget: function(/* ... */) {
|
renderWidget(/* ... */) {
|
||||||
var frameEl = form.ListValue.prototype.renderWidget.apply(this, arguments);
|
let frameEl = form.ListValue.prototype.renderWidget.apply(this, arguments);
|
||||||
|
|
||||||
frameEl.querySelector('select').style["min-width"] = '10em';
|
frameEl.querySelector('select').style["min-width"] = '10em';
|
||||||
|
|
||||||
|
@ -243,8 +243,8 @@ return baseclass.extend({
|
||||||
CBIStaticList: form.DynamicList.extend({
|
CBIStaticList: form.DynamicList.extend({
|
||||||
__name__: 'CBI.StaticList',
|
__name__: 'CBI.StaticList',
|
||||||
|
|
||||||
renderWidget: function(/* ... */) {
|
renderWidget(/* ... */) {
|
||||||
var El = form.DynamicList.prototype.renderWidget.apply(this, arguments);
|
let El = form.DynamicList.prototype.renderWidget.apply(this, arguments);
|
||||||
|
|
||||||
El.querySelector('.add-item ul > li[data-value="-"]')?.remove();
|
El.querySelector('.add-item ul > li[data-value="-"]')?.remove();
|
||||||
|
|
||||||
|
@ -253,8 +253,8 @@ return baseclass.extend({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
CBITextValue: form.TextValue.extend({
|
CBITextValue: form.TextValue.extend({
|
||||||
renderWidget: function(/* ... */) {
|
renderWidget(/* ... */) {
|
||||||
var frameEl = form.TextValue.prototype.renderWidget.apply(this, arguments);
|
let frameEl = form.TextValue.prototype.renderWidget.apply(this, arguments);
|
||||||
|
|
||||||
frameEl.querySelector('textarea').style.fontFamily = monospacefonts.join(',');
|
frameEl.querySelector('textarea').style.fontFamily = monospacefonts.join(',');
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ return baseclass.extend({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// thanks to homeproxy
|
// thanks to homeproxy
|
||||||
calcStringMD5: function(e) {
|
calcStringMD5(e) {
|
||||||
/* Thanks to https://stackoverflow.com/a/41602636 */
|
/* Thanks to https://stackoverflow.com/a/41602636 */
|
||||||
function h(a, b) {
|
function h(a, b) {
|
||||||
var c, d, e, f, g;
|
var c, d, e, f, g;
|
||||||
|
@ -345,13 +345,13 @@ return baseclass.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
// thanks to homeproxy
|
// thanks to homeproxy
|
||||||
decodeBase64Str: function(str) {
|
decodeBase64Str(str) {
|
||||||
if (!str)
|
if (!str)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
/* Thanks to luci-app-ssr-plus */
|
/* Thanks to luci-app-ssr-plus */
|
||||||
str = str.replace(/-/g, '+').replace(/_/g, '/');
|
str = str.replace(/-/g, '+').replace(/_/g, '/');
|
||||||
var padding = (4 - (str.length % 4)) % 4;
|
let padding = (4 - (str.length % 4)) % 4;
|
||||||
if (padding)
|
if (padding)
|
||||||
str = str + Array(padding + 1).join('=');
|
str = str + Array(padding + 1).join('=');
|
||||||
|
|
||||||
|
@ -360,8 +360,8 @@ return baseclass.extend({
|
||||||
).join(''));
|
).join(''));
|
||||||
},
|
},
|
||||||
|
|
||||||
generateRand: function(type, length) {
|
generateRand(type, length) {
|
||||||
var byteArr;
|
let byteArr;
|
||||||
if (['base64', 'hex'].includes(type))
|
if (['base64', 'hex'].includes(type))
|
||||||
byteArr = crypto.getRandomValues(new Uint8Array(length));
|
byteArr = crypto.getRandomValues(new Uint8Array(length));
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -393,7 +393,7 @@ return baseclass.extend({
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
removeBlankAttrs: function(self, res) {
|
removeBlankAttrs(self, res) {
|
||||||
if (Array.isArray(res)) {
|
if (Array.isArray(res)) {
|
||||||
return res
|
return res
|
||||||
.filter(item => !self.isEmpty(item))
|
.filter(item => !self.isEmpty(item))
|
||||||
|
@ -411,7 +411,7 @@ return baseclass.extend({
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
getFeatures: function() {
|
getFeatures() {
|
||||||
const callGetFeatures = rpc.declare({
|
const callGetFeatures = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'get_features',
|
method: 'get_features',
|
||||||
|
@ -421,7 +421,7 @@ return baseclass.extend({
|
||||||
return L.resolveDefault(callGetFeatures(), {});
|
return L.resolveDefault(callGetFeatures(), {});
|
||||||
},
|
},
|
||||||
|
|
||||||
getServiceStatus: function(instance) {
|
getServiceStatus(instance) {
|
||||||
var conf = 'fchomo';
|
var conf = 'fchomo';
|
||||||
const callServiceList = rpc.declare({
|
const callServiceList = rpc.declare({
|
||||||
object: 'service',
|
object: 'service',
|
||||||
|
@ -432,7 +432,7 @@ return baseclass.extend({
|
||||||
|
|
||||||
return L.resolveDefault(callServiceList(conf), {})
|
return L.resolveDefault(callServiceList(conf), {})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
var isRunning = false;
|
let isRunning = false;
|
||||||
try {
|
try {
|
||||||
isRunning = res[conf]['instances'][instance].running;
|
isRunning = res[conf]['instances'][instance].running;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
@ -440,7 +440,7 @@ return baseclass.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getClashAPI: function(instance) {
|
getClashAPI(instance) {
|
||||||
const callGetClashAPI = rpc.declare({
|
const callGetClashAPI = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'get_clash_api',
|
method: 'get_clash_api',
|
||||||
|
@ -452,8 +452,8 @@ return baseclass.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
// thanks to homeproxy
|
// thanks to homeproxy
|
||||||
loadDefaultLabel: function(section_id) {
|
loadDefaultLabel(section_id) {
|
||||||
var label = uci.get(this.config, section_id, 'label');
|
const label = uci.get(this.config, section_id, 'label');
|
||||||
if (label) {
|
if (label) {
|
||||||
return label;
|
return label;
|
||||||
} else {
|
} else {
|
||||||
|
@ -463,12 +463,12 @@ return baseclass.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
// thanks to homeproxy
|
// thanks to homeproxy
|
||||||
loadModalTitle: function(title, addtitle, section_id) {
|
loadModalTitle(title, addtitle, section_id) {
|
||||||
var label = uci.get(this.config, section_id, 'label');
|
const label = uci.get(this.config, section_id, 'label');
|
||||||
return label ? title + ' » ' + label : addtitle;
|
return label ? title + ' » ' + label : addtitle;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadProxyGroupLabel: function(preadds, section_id) {
|
loadProxyGroupLabel(preadds, section_id) {
|
||||||
delete this.keylist;
|
delete this.keylist;
|
||||||
delete this.vallist;
|
delete this.vallist;
|
||||||
|
|
||||||
|
@ -483,7 +483,7 @@ return baseclass.extend({
|
||||||
return this.super('load', section_id);
|
return this.super('load', section_id);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadNodeLabel: function(section_id) {
|
loadNodeLabel(section_id) {
|
||||||
delete this.keylist;
|
delete this.keylist;
|
||||||
delete this.vallist;
|
delete this.vallist;
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ return baseclass.extend({
|
||||||
return this.super('load', section_id);
|
return this.super('load', section_id);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadProviderLabel: function(section_id) {
|
loadProviderLabel(section_id) {
|
||||||
delete this.keylist;
|
delete this.keylist;
|
||||||
delete this.vallist;
|
delete this.vallist;
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ return baseclass.extend({
|
||||||
return this.super('load', section_id);
|
return this.super('load', section_id);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadRulesetLabel: function(behaviors, section_id) {
|
loadRulesetLabel(behaviors, section_id) {
|
||||||
delete this.keylist;
|
delete this.keylist;
|
||||||
delete this.vallist;
|
delete this.vallist;
|
||||||
|
|
||||||
|
@ -523,7 +523,7 @@ return baseclass.extend({
|
||||||
return this.super('load', section_id);
|
return this.super('load', section_id);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadSubRuleGroup: function(section_id) {
|
loadSubRuleGroup(section_id) {
|
||||||
delete this.keylist;
|
delete this.keylist;
|
||||||
delete this.vallist;
|
delete this.vallist;
|
||||||
|
|
||||||
|
@ -540,8 +540,8 @@ return baseclass.extend({
|
||||||
return this.super('load', section_id);
|
return this.super('load', section_id);
|
||||||
},
|
},
|
||||||
|
|
||||||
renderStatus: function(self, ElId, isRunning, instance, noGlobal) {
|
renderStatus(self, ElId, isRunning, instance, noGlobal) {
|
||||||
var visible = isRunning && (isRunning.http || isRunning.https);
|
const visible = isRunning && (isRunning.http || isRunning.https);
|
||||||
|
|
||||||
return E([
|
return E([
|
||||||
E('button', {
|
E('button', {
|
||||||
|
@ -557,7 +557,7 @@ return baseclass.extend({
|
||||||
}, [ _('Open Dashboard') ])
|
}, [ _('Open Dashboard') ])
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
updateStatus: function(self, El, isRunning, instance, noGlobal) {
|
updateStatus(self, El, isRunning, instance, noGlobal) {
|
||||||
if (El) {
|
if (El) {
|
||||||
El.style.color = isRunning ? 'green' : 'red';
|
El.style.color = isRunning ? 'green' : 'red';
|
||||||
El.innerHTML = ' %s%s '.format(noGlobal ? instance + ' ' : '', isRunning ? _('Running') : _('Not Running'));
|
El.innerHTML = ' %s%s '.format(noGlobal ? instance + ' ' : '', isRunning ? _('Running') : _('Not Running'));
|
||||||
|
@ -576,24 +576,24 @@ return baseclass.extend({
|
||||||
|
|
||||||
return El;
|
return El;
|
||||||
},
|
},
|
||||||
getDashURL: function(self, isRunning) {
|
getDashURL(self, isRunning) {
|
||||||
var tls = isRunning.https ? 's' : '',
|
const tls = isRunning.https ? 's' : '';
|
||||||
host = window.location.hostname,
|
const host = window.location.hostname;
|
||||||
port = isRunning.https ? isRunning.https.split(':').pop() : isRunning.http.split(':').pop(),
|
const port = isRunning.https ? isRunning.https.split(':').pop() : isRunning.http.split(':').pop();
|
||||||
secret = isRunning.secret,
|
const secret = isRunning.secret;
|
||||||
repo = isRunning.dashboard_repo;
|
const repo = isRunning.dashboard_repo;
|
||||||
|
|
||||||
return 'http%s://%s:%s/ui/'.format(tls, host, port) +
|
return 'http%s://%s:%s/ui/'.format(tls, host, port) +
|
||||||
String.format(self.dashrepos_urlparams[repo] || '', host, port, secret)
|
String.format(self.dashrepos_urlparams[repo] || '', host, port, secret)
|
||||||
},
|
},
|
||||||
|
|
||||||
renderResDownload: function(self, section_id) {
|
renderResDownload(self, section_id) {
|
||||||
var section_type = this.section.sectiontype;
|
const section_type = this.section.sectiontype;
|
||||||
var type = uci.get(this.config, section_id, 'type'),
|
const type = uci.get(this.config, section_id, 'type');
|
||||||
url = uci.get(this.config, section_id, 'url'),
|
const url = uci.get(this.config, section_id, 'url');
|
||||||
header = uci.get(this.config, section_id, 'header');
|
const header = uci.get(this.config, section_id, 'header');
|
||||||
|
|
||||||
var El = E([
|
let El = E([
|
||||||
E('button', {
|
E('button', {
|
||||||
class: 'cbi-button cbi-button-add',
|
class: 'cbi-button cbi-button-add',
|
||||||
disabled: (type !== 'http') || null,
|
disabled: (type !== 'http') || null,
|
||||||
|
@ -613,13 +613,13 @@ return baseclass.extend({
|
||||||
return El;
|
return El;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderSectionAdd: function(prefmt, LC, extra_class) {
|
renderSectionAdd(prefmt, LC, extra_class) {
|
||||||
var el = form.GridSection.prototype.renderSectionAdd.apply(this, [ extra_class ]),
|
let el = form.GridSection.prototype.renderSectionAdd.apply(this, [ extra_class ]),
|
||||||
nameEl = el.querySelector('.cbi-section-create-name');
|
nameEl = el.querySelector('.cbi-section-create-name');
|
||||||
ui.addValidator(nameEl, 'uciname', true, (v) => {
|
ui.addValidator(nameEl, 'uciname', true, (v) => {
|
||||||
var button = el.querySelector('.cbi-section-create > .cbi-button-add');
|
let button = el.querySelector('.cbi-section-create > .cbi-button-add');
|
||||||
var prefix = prefmt?.prefix ? prefmt.prefix : '',
|
const prefix = prefmt?.prefix ? prefmt.prefix : '';
|
||||||
suffix = prefmt?.suffix ? prefmt.suffix : '';
|
const suffix = prefmt?.suffix ? prefmt.suffix : '';
|
||||||
|
|
||||||
if (!v) {
|
if (!v) {
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
|
@ -642,14 +642,14 @@ return baseclass.extend({
|
||||||
return el;
|
return el;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleAdd: function(prefmt, ev, name) {
|
handleAdd(prefmt, ev, name) {
|
||||||
var prefix = prefmt?.prefix ? prefmt.prefix : '',
|
const prefix = prefmt?.prefix ? prefmt.prefix : '';
|
||||||
suffix = prefmt?.suffix ? prefmt.suffix : '';
|
const suffix = prefmt?.suffix ? prefmt.suffix : '';
|
||||||
|
|
||||||
return form.GridSection.prototype.handleAdd.apply(this, [ ev, prefix + name + suffix ]);
|
return form.GridSection.prototype.handleAdd.apply(this, [ ev, prefix + name + suffix ]);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleReload: function(instance, ev, section_id) {
|
handleReload(instance, ev, section_id) {
|
||||||
instance = instance || '';
|
instance = instance || '';
|
||||||
return fs.exec('/etc/init.d/fchomo', ['reload', instance])
|
return fs.exec('/etc/init.d/fchomo', ['reload', instance])
|
||||||
.then((res) => { /* return window.location = window.location.href.split('#')[0] */ })
|
.then((res) => { /* return window.location = window.location.href.split('#')[0] */ })
|
||||||
|
@ -658,8 +658,8 @@ return baseclass.extend({
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
handleRemoveIdles: function(self) {
|
handleRemoveIdles(self) {
|
||||||
var section_type = this.sectiontype;
|
const section_type = this.sectiontype;
|
||||||
|
|
||||||
let loaded = [];
|
let loaded = [];
|
||||||
uci.sections(this.config, section_type, (section, sid) => loaded.push(sid));
|
uci.sections(this.config, section_type, (section, sid) => loaded.push(sid));
|
||||||
|
@ -702,14 +702,14 @@ return baseclass.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
textvalue2Value: function(section_id) {
|
textvalue2Value(section_id) {
|
||||||
var cval = this.cfgvalue(section_id);
|
let cval = this.cfgvalue(section_id);
|
||||||
var i = this.keylist.indexOf(cval);
|
let i = this.keylist.indexOf(cval);
|
||||||
|
|
||||||
return this.vallist[i];
|
return this.vallist[i];
|
||||||
},
|
},
|
||||||
|
|
||||||
validateAuth: function(section_id, value) {
|
validateAuth(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return true;
|
return true;
|
||||||
if (!value.match(/^[\w-]{3,}:[^:]+$/))
|
if (!value.match(/^[\w-]{3,}:[^:]+$/))
|
||||||
|
@ -717,7 +717,7 @@ return baseclass.extend({
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
validateAuthUsername: function(section_id, value) {
|
validateAuthUsername(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return true;
|
return true;
|
||||||
if (!value.match(/^[\w-]{3,}$/))
|
if (!value.match(/^[\w-]{3,}$/))
|
||||||
|
@ -725,7 +725,7 @@ return baseclass.extend({
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
validateAuthPassword: function(section_id, value) {
|
validateAuthPassword(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return true;
|
return true;
|
||||||
if (!value.match(/^[^:]+$/))
|
if (!value.match(/^[^:]+$/))
|
||||||
|
@ -734,24 +734,24 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateCommonPort: function(section_id, value) {
|
validateCommonPort(section_id, value) {
|
||||||
// thanks to homeproxy
|
// thanks to homeproxy
|
||||||
var stubValidator = {
|
let stubValidator = {
|
||||||
factory: validation,
|
factory: validation,
|
||||||
apply: function(type, value, args) {
|
apply(type, value, args) {
|
||||||
if (value != null)
|
if (value != null)
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
||||||
return validation.types[type].apply(this, args);
|
return validation.types[type].apply(this, args);
|
||||||
},
|
},
|
||||||
assert: function(condition) {
|
assert(condition) {
|
||||||
return !!condition;
|
return !!condition;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (value && !value.match(/common(_stun)?/)) {
|
if (value && !value.match(/common(_stun)?/)) {
|
||||||
var ports = [];
|
let ports = [];
|
||||||
for (var i of value.split(',')) {
|
for (let i of value.split(',')) {
|
||||||
if (!stubValidator.apply('port', i) && !stubValidator.apply('portrange', i))
|
if (!stubValidator.apply('port', i) && !stubValidator.apply('portrange', i))
|
||||||
return _('Expecting: %s').format(_('valid port value'));
|
return _('Expecting: %s').format(_('valid port value'));
|
||||||
if (ports.includes(i))
|
if (ports.includes(i))
|
||||||
|
@ -763,12 +763,12 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateJson: function(section_id, value) {
|
validateJson(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var obj = JSON.parse(value.trim());
|
let obj = JSON.parse(value.trim());
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return _('Expecting: %s').format(_('valid JSON format'));
|
return _('Expecting: %s').format(_('valid JSON format'));
|
||||||
}
|
}
|
||||||
|
@ -779,7 +779,7 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateBase64Key: function(length, section_id, value) {
|
validateBase64Key(length, section_id, value) {
|
||||||
/* Thanks to luci-proto-wireguard */
|
/* Thanks to luci-proto-wireguard */
|
||||||
if (value)
|
if (value)
|
||||||
if (value.length !== length || !value.match(/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/) || value[length-1] !== '=')
|
if (value.length !== length || !value.match(/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/) || value[length-1] !== '=')
|
||||||
|
@ -788,8 +788,8 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateShadowsocksPassword: function(self, encmode, section_id, value) {
|
validateShadowsocksPassword(self, encmode, section_id, value) {
|
||||||
var length = self.shadowsocks_cipher_length[encmode];
|
let length = self.shadowsocks_cipher_length[encmode];
|
||||||
if (typeof length !== 'undefined') {
|
if (typeof length !== 'undefined') {
|
||||||
length = Math.ceil(length/3)*4;
|
length = Math.ceil(length/3)*4;
|
||||||
if (encmode.match(/^2022-/)) {
|
if (encmode.match(/^2022-/)) {
|
||||||
|
@ -806,7 +806,7 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateBytesize: function(section_id, value) {
|
validateBytesize(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -815,7 +815,7 @@ return baseclass.extend({
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
validateTimeDuration: function(section_id, value) {
|
validateTimeDuration(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -825,11 +825,11 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateUniqueValue: function(section_id, value) {
|
validateUniqueValue(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return _('Expecting: %s').format(_('non-empty value'));
|
return _('Expecting: %s').format(_('non-empty value'));
|
||||||
|
|
||||||
var duplicate = false;
|
let duplicate = false;
|
||||||
uci.sections(this.config, this.section.sectiontype, (res) => {
|
uci.sections(this.config, this.section.sectiontype, (res) => {
|
||||||
if (res['.name'] !== section_id)
|
if (res['.name'] !== section_id)
|
||||||
if (res[this.option] === value)
|
if (res[this.option] === value)
|
||||||
|
@ -841,12 +841,12 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateUrl: function(section_id, value) {
|
validateUrl(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var url = new URL(value);
|
let url = new URL(value);
|
||||||
if (!url.hostname)
|
if (!url.hostname)
|
||||||
return _('Expecting: %s').format(_('valid URL'));
|
return _('Expecting: %s').format(_('valid URL'));
|
||||||
}
|
}
|
||||||
|
@ -857,7 +857,7 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateUUID: function(section_id, value) {
|
validateUUID(section_id, value) {
|
||||||
if (!value)
|
if (!value)
|
||||||
return true;
|
return true;
|
||||||
else if (value.match('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') === null)
|
else if (value.match('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') === null)
|
||||||
|
@ -866,7 +866,7 @@ return baseclass.extend({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
lsDir: function(type) {
|
lsDir(type) {
|
||||||
const callLsDir = rpc.declare({
|
const callLsDir = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'dir_ls',
|
method: 'dir_ls',
|
||||||
|
@ -882,7 +882,7 @@ return baseclass.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
readFile: function(type, filename) {
|
readFile(type, filename) {
|
||||||
const callReadFile = rpc.declare({
|
const callReadFile = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'file_read',
|
method: 'file_read',
|
||||||
|
@ -898,7 +898,7 @@ return baseclass.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
writeFile: function(type, filename, content) {
|
writeFile(type, filename, content) {
|
||||||
const callWriteFile = rpc.declare({
|
const callWriteFile = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'file_write',
|
method: 'file_write',
|
||||||
|
@ -914,7 +914,7 @@ return baseclass.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
downloadFile: function(type, filename, url, header) {
|
downloadFile(type, filename, url, header) {
|
||||||
const callDownloadFile = rpc.declare({
|
const callDownloadFile = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'file_download',
|
method: 'file_download',
|
||||||
|
@ -930,7 +930,7 @@ return baseclass.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
removeFile: function(type, filename) {
|
removeFile(type, filename) {
|
||||||
const callRemoveFile = rpc.declare({
|
const callRemoveFile = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'file_remove',
|
method: 'file_remove',
|
||||||
|
@ -947,7 +947,7 @@ return baseclass.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
// thanks to homeproxy
|
// thanks to homeproxy
|
||||||
uploadCertificate: function(type, filename, ev) {
|
uploadCertificate(type, filename, ev) {
|
||||||
const callWriteCertificate = rpc.declare({
|
const callWriteCertificate = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'certificate_write',
|
method: 'certificate_write',
|
||||||
|
@ -966,7 +966,7 @@ return baseclass.extend({
|
||||||
}, this, ev.target))
|
}, this, ev.target))
|
||||||
.catch((e) => { ui.addNotification(null, E('p', e.message)) });
|
.catch((e) => { ui.addNotification(null, E('p', e.message)) });
|
||||||
},
|
},
|
||||||
uploadInitialPack: function(ev, section_id) {
|
uploadInitialPack(ev, section_id) {
|
||||||
const callWriteInitialPack = rpc.declare({
|
const callWriteInitialPack = rpc.declare({
|
||||||
object: 'luci.fchomo',
|
object: 'luci.fchomo',
|
||||||
method: 'initialpack_write',
|
method: 'initialpack_write',
|
||||||
|
|
|
@ -211,15 +211,15 @@ function flagToBool(flag) {
|
||||||
|
|
||||||
function renderPayload(s, total, uciconfig) {
|
function renderPayload(s, total, uciconfig) {
|
||||||
// common payload
|
// common payload
|
||||||
var initPayload = function(o, n, key, uciconfig) {
|
let initPayload = function(o, n, key, uciconfig) {
|
||||||
o.load = L.bind(function(n, key, uciconfig, section_id) {
|
o.load = L.bind(function(n, key, uciconfig, section_id) {
|
||||||
return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayload(n)[key];
|
return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayload(n)[key];
|
||||||
}, o, n, key, uciconfig);
|
}, o, n, key, uciconfig);
|
||||||
o.onchange = function(ev, section_id, value) {
|
o.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
let n = this.option.match(/^payload(\d+)_/)[1];
|
let n = this.option.match(/^payload(\d+)_/)[1];
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setPayload(n, {factor: value});
|
let rule = new RulesEntry(UIEl.getValue()).setPayload(n, {factor: value});
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -228,14 +228,14 @@ function renderPayload(s, total, uciconfig) {
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.modalonly = true;
|
o.modalonly = true;
|
||||||
}
|
}
|
||||||
var initDynamicPayload = function(o, n, key, uciconfig) {
|
let initDynamicPayload = function(o, n, key, uciconfig) {
|
||||||
o.load = L.bind(function(n, key, uciconfig, section_id) {
|
o.load = L.bind(function(n, key, uciconfig, section_id) {
|
||||||
return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayloads().slice(n).map(e => e[key] ?? '');
|
return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayloads().slice(n).map(e => e[key] ?? '');
|
||||||
}, o, n, key, uciconfig);
|
}, o, n, key, uciconfig);
|
||||||
o.validate = function(section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
value = this.formvalue(section_id);
|
value = this.formvalue(section_id);
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
var rule = new RulesEntry(UIEl.getValue());
|
let rule = new RulesEntry(UIEl.getValue());
|
||||||
|
|
||||||
let n = this.option.match(/^payload(\d+)_/)[1];
|
let n = this.option.match(/^payload(\d+)_/)[1];
|
||||||
let limit = rule.getPayloads().length;
|
let limit = rule.getPayloads().length;
|
||||||
|
@ -254,9 +254,9 @@ function renderPayload(s, total, uciconfig) {
|
||||||
o.modalonly = true;
|
o.modalonly = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var o, prefix;
|
let o, prefix;
|
||||||
// StaticList payload
|
// StaticList payload
|
||||||
for (var n=0; n<total; n++) {
|
for (let n=0; n<total; n++) {
|
||||||
prefix = `payload${n}_`;
|
prefix = `payload${n}_`;
|
||||||
|
|
||||||
o = s.option(form.ListValue, prefix + 'type', _('Type') + ` ${n+1}`);
|
o = s.option(form.ListValue, prefix + 'type', _('Type') + ` ${n+1}`);
|
||||||
|
@ -270,10 +270,10 @@ function renderPayload(s, total, uciconfig) {
|
||||||
})
|
})
|
||||||
initPayload(o, n, 'type', uciconfig);
|
initPayload(o, n, 'type', uciconfig);
|
||||||
o.onchange = function(ev, section_id, value) {
|
o.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
let n = this.option.match(/^payload(\d+)_/)[1];
|
let n = this.option.match(/^payload(\d+)_/)[1];
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setPayload(n, {type: value});
|
let rule = new RulesEntry(UIEl.getValue()).setPayload(n, {type: value});
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -344,10 +344,10 @@ function renderPayload(s, total, uciconfig) {
|
||||||
return boolToFlag(new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayload(n)[key]);
|
return boolToFlag(new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayload(n)[key]);
|
||||||
}, o, n, 'deny', uciconfig);
|
}, o, n, 'deny', uciconfig);
|
||||||
o.onchange = function(ev, section_id, value) {
|
o.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
let n = this.option.match(/^payload(\d+)_/)[1];
|
let n = this.option.match(/^payload(\d+)_/)[1];
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setPayload(n, {deny: flagToBool(value) || null});
|
let rule = new RulesEntry(UIEl.getValue()).setPayload(n, {deny: flagToBool(value) || null});
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -355,7 +355,7 @@ function renderPayload(s, total, uciconfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DynamicList payload
|
// DynamicList payload
|
||||||
var extenbox = {};
|
let extenbox = {};
|
||||||
Object.entries(hm.rules_logical_payload_count).filter(e => e[1].high === undefined).forEach((e) => {
|
Object.entries(hm.rules_logical_payload_count).filter(e => e[1].high === undefined).forEach((e) => {
|
||||||
let low = e[1].low;
|
let low = e[1].low;
|
||||||
let type = e[0];
|
let type = e[0];
|
||||||
|
@ -377,8 +377,8 @@ function renderPayload(s, total, uciconfig) {
|
||||||
initDynamicPayload(o, n, 'type', uciconfig);
|
initDynamicPayload(o, n, 'type', uciconfig);
|
||||||
o.validate = function(section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
value = this.formvalue(section_id);
|
value = this.formvalue(section_id);
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
var rule = new RulesEntry(UIEl.getValue());
|
let rule = new RulesEntry(UIEl.getValue());
|
||||||
|
|
||||||
let n = this.option.match(/^payload(\d+)_/)[1];
|
let n = this.option.match(/^payload(\d+)_/)[1];
|
||||||
value.forEach((val) => {
|
value.forEach((val) => {
|
||||||
|
@ -428,8 +428,8 @@ function renderPayload(s, total, uciconfig) {
|
||||||
}, o, n, 'deny', uciconfig);
|
}, o, n, 'deny', uciconfig);
|
||||||
o.validate = function(section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
value = this.formvalue(section_id);
|
value = this.formvalue(section_id);
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
var rule = new RulesEntry(UIEl.getValue());
|
let rule = new RulesEntry(UIEl.getValue());
|
||||||
|
|
||||||
let n = this.option.match(/^payload(\d+)_/)[1];
|
let n = this.option.match(/^payload(\d+)_/)[1];
|
||||||
let limit = rule.getPayloads().length;
|
let limit = rule.getPayloads().length;
|
||||||
|
@ -447,11 +447,11 @@ function renderPayload(s, total, uciconfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderRules(s, uciconfig) {
|
function renderRules(s, uciconfig) {
|
||||||
var o;
|
let o;
|
||||||
|
|
||||||
o = s.option(form.DummyValue, 'entry', _('Entry'));
|
o = s.option(form.DummyValue, 'entry', _('Entry'));
|
||||||
o.renderWidget = function(/* ... */) {
|
o.renderWidget = function(/* ... */) {
|
||||||
var El = form.DummyValue.prototype.renderWidget.apply(this, arguments);
|
let El = form.DummyValue.prototype.renderWidget.apply(this, arguments);
|
||||||
|
|
||||||
El.firstChild.innerText = new RulesEntry(El.querySelector('input').value).toString('mihomo');
|
El.firstChild.innerText = new RulesEntry(El.querySelector('input').value).toString('mihomo');
|
||||||
|
|
||||||
|
@ -488,9 +488,9 @@ function renderRules(s, uciconfig) {
|
||||||
UIEl.node.querySelector('input').disabled = 'true';
|
UIEl.node.querySelector('input').disabled = 'true';
|
||||||
});
|
});
|
||||||
|
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setParam('no-resolve').setParam('src');
|
let rule = new RulesEntry(UIEl.getValue()).setParam('no-resolve').setParam('src');
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -499,9 +499,9 @@ function renderRules(s, uciconfig) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
o.onchange = function(ev, section_id, value) {
|
o.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setKey('type', value);
|
let rule = new RulesEntry(UIEl.getValue()).setKey('type', value);
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -519,9 +519,9 @@ function renderRules(s, uciconfig) {
|
||||||
return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).detour;
|
return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).detour;
|
||||||
}
|
}
|
||||||
o.onchange = function(ev, section_id, value) {
|
o.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setKey('detour', value);
|
let rule = new RulesEntry(UIEl.getValue()).setKey('detour', value);
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -536,9 +536,9 @@ function renderRules(s, uciconfig) {
|
||||||
return boolToFlag(new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getParam('src'));
|
return boolToFlag(new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getParam('src'));
|
||||||
}
|
}
|
||||||
o.onchange = function(ev, section_id, value) {
|
o.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setParam('src', flagToBool(value) || null);
|
let rule = new RulesEntry(UIEl.getValue()).setParam('src', flagToBool(value) || null);
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -553,9 +553,9 @@ function renderRules(s, uciconfig) {
|
||||||
return boolToFlag(new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getParam('no-resolve'));
|
return boolToFlag(new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getParam('no-resolve'));
|
||||||
}
|
}
|
||||||
o.onchange = function(ev, section_id, value) {
|
o.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setParam('no-resolve', flagToBool(value) || null);
|
let rule = new RulesEntry(UIEl.getValue()).setParam('no-resolve', flagToBool(value) || null);
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -566,14 +566,14 @@ function renderRules(s, uciconfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
uci.load('fchomo')
|
uci.load('fchomo')
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(data) {
|
render(data) {
|
||||||
var dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo');
|
const dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo');
|
||||||
|
|
||||||
let m, s, o, ss, so;
|
let m, s, o, ss, so;
|
||||||
|
|
||||||
|
@ -836,9 +836,9 @@ return view.extend({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setKey('subrule', value === '1' ? ' ' : false);
|
let rule = new RulesEntry(UIEl.getValue()).setKey('subrule', value === '1' ? ' ' : false);
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -853,9 +853,9 @@ return view.extend({
|
||||||
return new RulesEntry(uci.get(data[0], section_id, 'entry')).subrule || '';
|
return new RulesEntry(uci.get(data[0], section_id, 'entry')).subrule || '';
|
||||||
}
|
}
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'entry');
|
let UIEl = this.section.getUIElement(section_id, 'entry');
|
||||||
|
|
||||||
var rule = new RulesEntry(UIEl.getValue()).setKey('subrule', value);
|
let rule = new RulesEntry(UIEl.getValue()).setKey('subrule', value);
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
UIEl.node.previousSibling.innerText = rule.toString('mihomo');
|
||||||
UIEl.setValue(rule.toString('json'));
|
UIEl.setValue(rule.toString('json'));
|
||||||
|
@ -941,8 +941,8 @@ return view.extend({
|
||||||
so.load = L.bind(loadDNSServerLabel, so);
|
so.load = L.bind(loadDNSServerLabel, so);
|
||||||
so.validate = L.bind(validateNameserver, so);
|
so.validate = L.bind(validateNameserver, so);
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
var ddesc = this.section.getUIElement(section_id, 'default_server').node.nextSibling;
|
let ddesc = this.section.getUIElement(section_id, 'default_server').node.nextSibling;
|
||||||
var fdesc = ev.target.nextSibling;
|
let fdesc = ev.target.nextSibling;
|
||||||
if (value.length > 0) {
|
if (value.length > 0) {
|
||||||
ddesc.innerHTML = _('Final DNS server (Used to Domestic-IP response)');
|
ddesc.innerHTML = _('Final DNS server (Used to Domestic-IP response)');
|
||||||
fdesc.innerHTML = _('Final DNS server (Used to Overseas-IP response)');
|
fdesc.innerHTML = _('Final DNS server (Used to Overseas-IP response)');
|
||||||
|
@ -998,9 +998,9 @@ return view.extend({
|
||||||
this.section.getUIElement(section_id, 'ecs').node.querySelector('input').disabled = null;
|
this.section.getUIElement(section_id, 'ecs').node.querySelector('input').disabled = null;
|
||||||
this.section.getUIElement(section_id, 'ecs-override').node.querySelector('input').disabled = null;
|
this.section.getUIElement(section_id, 'ecs-override').node.querySelector('input').disabled = null;
|
||||||
} else {
|
} else {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'address');
|
let UIEl = this.section.getUIElement(section_id, 'address');
|
||||||
|
|
||||||
var newvalue = new DNSAddress(UIEl.getValue()).setParam('h3').setParam('ecs').setParam('ecs-override').toString();
|
let newvalue = new DNSAddress(UIEl.getValue()).setParam('h3').setParam('ecs').setParam('ecs-override').toString();
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = newvalue;
|
UIEl.node.previousSibling.innerText = newvalue;
|
||||||
UIEl.setValue(newvalue);
|
UIEl.setValue(newvalue);
|
||||||
|
@ -1015,9 +1015,9 @@ return view.extend({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'address');
|
let UIEl = this.section.getUIElement(section_id, 'address');
|
||||||
|
|
||||||
var newvalue = ('N' + UIEl.getValue()).replace(/^[^#]+/, value);
|
let newvalue = ('N' + UIEl.getValue()).replace(/^[^#]+/, value);
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = newvalue;
|
UIEl.node.previousSibling.innerText = newvalue;
|
||||||
UIEl.setValue(newvalue);
|
UIEl.setValue(newvalue);
|
||||||
|
@ -1033,9 +1033,9 @@ return view.extend({
|
||||||
return new DNSAddress(uci.get(data[0], section_id, 'address')).parseParam('detour');
|
return new DNSAddress(uci.get(data[0], section_id, 'address')).parseParam('detour');
|
||||||
}
|
}
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'address');
|
let UIEl = this.section.getUIElement(section_id, 'address');
|
||||||
|
|
||||||
var newvalue = new DNSAddress(UIEl.getValue()).setParam('detour', value).toString();
|
let newvalue = new DNSAddress(UIEl.getValue()).setParam('detour', value).toString();
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = newvalue;
|
UIEl.node.previousSibling.innerText = newvalue;
|
||||||
UIEl.setValue(newvalue);
|
UIEl.setValue(newvalue);
|
||||||
|
@ -1049,9 +1049,9 @@ return view.extend({
|
||||||
return boolToFlag(new DNSAddress(uci.get(data[0], section_id, 'address')).parseParam('h3'));
|
return boolToFlag(new DNSAddress(uci.get(data[0], section_id, 'address')).parseParam('h3'));
|
||||||
}
|
}
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'address');
|
let UIEl = this.section.getUIElement(section_id, 'address');
|
||||||
|
|
||||||
var newvalue = new DNSAddress(UIEl.getValue()).setParam('h3', flagToBool(value) || null).toString();
|
let newvalue = new DNSAddress(UIEl.getValue()).setParam('h3', flagToBool(value) || null).toString();
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = newvalue;
|
UIEl.node.previousSibling.innerText = newvalue;
|
||||||
UIEl.setValue(newvalue);
|
UIEl.setValue(newvalue);
|
||||||
|
@ -1065,9 +1065,9 @@ return view.extend({
|
||||||
return new DNSAddress(uci.get(data[0], section_id, 'address')).parseParam('ecs');
|
return new DNSAddress(uci.get(data[0], section_id, 'address')).parseParam('ecs');
|
||||||
}
|
}
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'address');
|
let UIEl = this.section.getUIElement(section_id, 'address');
|
||||||
|
|
||||||
var newvalue = new DNSAddress(UIEl.getValue()).setParam('ecs', value).toString();
|
let newvalue = new DNSAddress(UIEl.getValue()).setParam('ecs', value).toString();
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = newvalue;
|
UIEl.node.previousSibling.innerText = newvalue;
|
||||||
UIEl.setValue(newvalue);
|
UIEl.setValue(newvalue);
|
||||||
|
@ -1082,9 +1082,9 @@ return view.extend({
|
||||||
return boolToFlag(new DNSAddress(uci.get(data[0], section_id, 'address')).parseParam('ecs-override'));
|
return boolToFlag(new DNSAddress(uci.get(data[0], section_id, 'address')).parseParam('ecs-override'));
|
||||||
}
|
}
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
var UIEl = this.section.getUIElement(section_id, 'address');
|
let UIEl = this.section.getUIElement(section_id, 'address');
|
||||||
|
|
||||||
var newvalue = new DNSAddress(UIEl.getValue()).setParam('ecs-override', flagToBool(value) || null).toString();
|
let newvalue = new DNSAddress(UIEl.getValue()).setParam('ecs-override', flagToBool(value) || null).toString();
|
||||||
|
|
||||||
UIEl.node.previousSibling.innerText = newvalue;
|
UIEl.node.previousSibling.innerText = newvalue;
|
||||||
UIEl.setValue(newvalue);
|
UIEl.setValue(newvalue);
|
||||||
|
@ -1144,7 +1144,7 @@ return view.extend({
|
||||||
|
|
||||||
so = ss.option(form.DummyValue, '_entry', _('Entry'));
|
so = ss.option(form.DummyValue, '_entry', _('Entry'));
|
||||||
so.load = function(section_id) {
|
so.load = function(section_id) {
|
||||||
var option = uci.get(data[0], section_id, 'type');
|
const option = uci.get(data[0], section_id, 'type');
|
||||||
|
|
||||||
return uci.get(data[0], section_id, option)?.join(',');
|
return uci.get(data[0], section_id, option)?.join(',');
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,10 +45,10 @@ function handleResUpdate(type, repo) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Dynamic repo
|
// Dynamic repo
|
||||||
var label;
|
let label;
|
||||||
if (repo) {
|
if (repo) {
|
||||||
var section_id = this.section.section;
|
const section_id = this.section.section;
|
||||||
var weight = document.getElementById(this.cbid(section_id));
|
let weight = document.getElementById(this.cbid(section_id));
|
||||||
if (weight)
|
if (weight)
|
||||||
repo = weight.firstChild.value,
|
repo = weight.firstChild.value,
|
||||||
label = weight.firstChild.selectedOptions[0].label;
|
label = weight.firstChild.selectedOptions[0].label;
|
||||||
|
@ -79,7 +79,7 @@ function handleResUpdate(type, repo) {
|
||||||
|
|
||||||
function renderResVersion(El, type, repo) {
|
function renderResVersion(El, type, repo) {
|
||||||
return L.resolveDefault(callResVersion(type, repo), {}).then((res) => {
|
return L.resolveDefault(callResVersion(type, repo), {}).then((res) => {
|
||||||
var resEl = E([
|
let resEl = E([
|
||||||
E('button', {
|
E('button', {
|
||||||
'class': 'cbi-button cbi-button-apply',
|
'class': 'cbi-button cbi-button-apply',
|
||||||
'click': ui.createHandlerFn(this, handleResUpdate, type, repo)
|
'click': ui.createHandlerFn(this, handleResUpdate, type, repo)
|
||||||
|
@ -107,7 +107,7 @@ function updateResVersion(El, version) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderNATBehaviorTest(El) {
|
function renderNATBehaviorTest(El) {
|
||||||
var resEl = E('div', { 'class': 'control-group' }, [
|
let resEl = E('div', { 'class': 'control-group' }, [
|
||||||
E('select', {
|
E('select', {
|
||||||
'id': '_status_nattest_l4proto',
|
'id': '_status_nattest_l4proto',
|
||||||
'class': 'cbi-input-select',
|
'class': 'cbi-input-select',
|
||||||
|
@ -119,9 +119,9 @@ function renderNATBehaviorTest(El) {
|
||||||
E('button', {
|
E('button', {
|
||||||
'class': 'cbi-button cbi-button-apply',
|
'class': 'cbi-button cbi-button-apply',
|
||||||
'click': ui.createHandlerFn(this, function() {
|
'click': ui.createHandlerFn(this, function() {
|
||||||
var stun = this.formvalue(this.section.section);
|
const stun = this.formvalue(this.section.section);
|
||||||
var l4proto = document.getElementById('_status_nattest_l4proto').value;
|
const l4proto = document.getElementById('_status_nattest_l4proto').value;
|
||||||
var l4proto_idx = document.getElementById('_status_nattest_l4proto').selectedIndex;
|
const l4proto_idx = document.getElementById('_status_nattest_l4proto').selectedIndex;
|
||||||
|
|
||||||
return fs.exec_direct('/etc/fchomo/scripts/natcheck.sh', [stun, l4proto, getRandom(32768, 61000)]).then((stdout) => {
|
return fs.exec_direct('/etc/fchomo/scripts/natcheck.sh', [stun, l4proto, getRandom(32768, 61000)]).then((stdout) => {
|
||||||
this.description = '<details><summary>' + _('Expand/Collapse result') + '</summary>' + stdout + '</details>';
|
this.description = '<details><summary>' + _('Expand/Collapse result') + '</summary>' + stdout + '</details>';
|
||||||
|
@ -144,7 +144,7 @@ function renderNATBehaviorTest(El) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
uci.load('fchomo'),
|
uci.load('fchomo'),
|
||||||
hm.getFeatures(),
|
hm.getFeatures(),
|
||||||
|
@ -158,17 +158,17 @@ return view.extend({
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(data) {
|
render(data) {
|
||||||
var features = data[1],
|
const features = data[1];
|
||||||
hosts = data[2]?.hosts,
|
const hosts = data[2]?.hosts;
|
||||||
CisRunning = data[3],
|
const CisRunning = data[3];
|
||||||
CclashAPI = data[4],
|
const CclashAPI = data[4];
|
||||||
SisRunning = data[5],
|
const SisRunning = data[5];
|
||||||
SclashAPI = data[6],
|
const SclashAPI = data[6];
|
||||||
res_ver_geoip = data[7],
|
const res_ver_geoip = data[7];
|
||||||
res_ver_geosite = data[8];
|
const res_ver_geosite = data[8];
|
||||||
|
|
||||||
var dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo');
|
const dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo');
|
||||||
|
|
||||||
let m, s, o, ss, so;
|
let m, s, o, ss, so;
|
||||||
|
|
||||||
|
@ -224,13 +224,13 @@ return view.extend({
|
||||||
expect: { '': {} }
|
expect: { '': {} }
|
||||||
});
|
});
|
||||||
|
|
||||||
var ElId = '_connection_check_results';
|
const ElId = '_connection_check_results';
|
||||||
|
|
||||||
return E([
|
return E([
|
||||||
E('button', {
|
E('button', {
|
||||||
'class': 'cbi-button cbi-button-apply',
|
'class': 'cbi-button cbi-button-apply',
|
||||||
'click': ui.createHandlerFn(this, function() {
|
'click': ui.createHandlerFn(this, function() {
|
||||||
var weight = document.getElementById(ElId);
|
let weight = document.getElementById(ElId);
|
||||||
|
|
||||||
weight.innerHTML = '';
|
weight.innerHTML = '';
|
||||||
return hm.checkurls.forEach((site) => {
|
return hm.checkurls.forEach((site) => {
|
||||||
|
@ -258,7 +258,7 @@ return view.extend({
|
||||||
so.readonly = true;
|
so.readonly = true;
|
||||||
} else {
|
} else {
|
||||||
so.renderWidget = function(/* ... */) {
|
so.renderWidget = function(/* ... */) {
|
||||||
var El = form.Value.prototype.renderWidget.apply(this, arguments);
|
let El = form.Value.prototype.renderWidget.apply(this, arguments);
|
||||||
|
|
||||||
return renderNATBehaviorTest.call(this, El);
|
return renderNATBehaviorTest.call(this, El);
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ return view.extend({
|
||||||
so.value.apply(so, repo);
|
so.value.apply(so, repo);
|
||||||
})
|
})
|
||||||
so.renderWidget = function(/* ... */) {
|
so.renderWidget = function(/* ... */) {
|
||||||
var El = form.ListValue.prototype.renderWidget.apply(this, arguments);
|
let El = form.ListValue.prototype.renderWidget.apply(this, arguments);
|
||||||
|
|
||||||
El.classList.add('control-group');
|
El.classList.add('control-group');
|
||||||
El.firstChild.style.width = '10em';
|
El.firstChild.style.width = '10em';
|
||||||
|
@ -327,7 +327,7 @@ return view.extend({
|
||||||
so.onchange = function(ev, section_id, value) {
|
so.onchange = function(ev, section_id, value) {
|
||||||
this.default = value;
|
this.default = value;
|
||||||
|
|
||||||
var weight = ev.target;
|
let weight = ev.target;
|
||||||
if (weight)
|
if (weight)
|
||||||
return L.resolveDefault(callResVersion('dashboard', value), {}).then((res) => {
|
return L.resolveDefault(callResVersion('dashboard', value), {}).then((res) => {
|
||||||
updateResVersion(weight.lastChild, res.version);
|
updateResVersion(weight.lastChild, res.version);
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
'require fchomo as hm';
|
'require fchomo as hm';
|
||||||
|
|
||||||
var isReadonlyView = !L.hasViewPermission() || null;
|
const isReadonlyView = !L.hasViewPermission() || null;
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load() {
|
||||||
return L.resolveDefault(hm.readFile('templates', 'hosts.yaml'), '');
|
return L.resolveDefault(hm.readFile('templates', 'hosts.yaml'), '');
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSave: function(ev) {
|
handleSave(ev) {
|
||||||
var value = (document.querySelector('textarea').value || '').trim().replace(/\r\n/g, '\n') + '\n';
|
let value = (document.querySelector('textarea').value || '').trim().replace(/\r\n/g, '\n') + '\n';
|
||||||
|
|
||||||
return hm.writeFile('templates', 'hosts.yaml', value).then(function(rc) {
|
return hm.writeFile('templates', 'hosts.yaml', value).then(function(rc) {
|
||||||
document.querySelector('textarea').value = value;
|
document.querySelector('textarea').value = value;
|
||||||
|
@ -22,7 +22,7 @@ return view.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(content) {
|
render(content) {
|
||||||
return E([
|
return E([
|
||||||
E('h2', _('Hosts')),
|
E('h2', _('Hosts')),
|
||||||
E('p', { 'class': 'cbi-section-descr' }, _('Custom internal hosts. Support <code>yaml</code> or <code>json</code> format.')),
|
E('p', { 'class': 'cbi-section-descr' }, _('Custom internal hosts. Support <code>yaml</code> or <code>json</code> format.')),
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
'require view';
|
'require view';
|
||||||
|
|
||||||
/* Thanks to luci-app-aria2 */
|
/* Thanks to luci-app-aria2 */
|
||||||
var css = ' \
|
const css = ' \
|
||||||
#log_textarea { \
|
#log_textarea { \
|
||||||
padding: 10px; \
|
padding: 10px; \
|
||||||
text-align: left; \
|
text-align: left; \
|
||||||
|
@ -23,7 +23,7 @@ var css = ' \
|
||||||
background-color: #33ccff; \
|
background-color: #33ccff; \
|
||||||
}';
|
}';
|
||||||
|
|
||||||
var hm_dir = '/var/run/fchomo';
|
const hm_dir = '/var/run/fchomo';
|
||||||
|
|
||||||
function getRuntimeLog(name, filename) {
|
function getRuntimeLog(name, filename) {
|
||||||
const callLogClean = rpc.declare({
|
const callLogClean = rpc.declare({
|
||||||
|
@ -33,13 +33,13 @@ function getRuntimeLog(name, filename) {
|
||||||
expect: { '': {} }
|
expect: { '': {} }
|
||||||
});
|
});
|
||||||
|
|
||||||
var log_textarea = E('div', { 'id': 'log_textarea' },
|
let log_textarea = E('div', { 'id': 'log_textarea' },
|
||||||
E('pre', {
|
E('pre', {
|
||||||
'class': 'spinning'
|
'class': 'spinning'
|
||||||
}, _('Collecting data...'))
|
}, _('Collecting data...'))
|
||||||
);
|
);
|
||||||
|
|
||||||
var log;
|
let log;
|
||||||
poll.add(L.bind(function() {
|
poll.add(L.bind(function() {
|
||||||
return fs.read_direct(String.format('%s/%s.log', hm_dir, filename), 'text')
|
return fs.read_direct(String.format('%s/%s.log', hm_dir, filename), 'text')
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
|
@ -86,7 +86,7 @@ function getRuntimeLog(name, filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
render: function(data) {
|
render(data) {
|
||||||
let m, s, o, ss, so;
|
let m, s, o, ss, so;
|
||||||
|
|
||||||
m = new form.Map('fchomo');
|
m = new form.Map('fchomo');
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
'require tools.widgets as widgets';
|
'require tools.widgets as widgets';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
uci.load('fchomo')
|
uci.load('fchomo')
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(data) {
|
render(data) {
|
||||||
let m, s, o, ss, so;
|
let m, s, o, ss, so;
|
||||||
|
|
||||||
m = new form.Map('fchomo', _('Edit node'));
|
m = new form.Map('fchomo', _('Edit node'));
|
||||||
|
@ -151,7 +151,7 @@ return view.extend({
|
||||||
so = ss.taboption('field_general', form.Value, 'shadowsocks_password', _('Password'));
|
so = ss.taboption('field_general', form.Value, 'shadowsocks_password', _('Password'));
|
||||||
so.password = true;
|
so.password = true;
|
||||||
so.validate = function(section_id, value) {
|
so.validate = function(section_id, value) {
|
||||||
var encmode = this.section.getOption('shadowsocks_chipher').formvalue(section_id);
|
const encmode = this.section.getOption('shadowsocks_chipher').formvalue(section_id);
|
||||||
return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value);
|
return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value);
|
||||||
}
|
}
|
||||||
so.depends({type: 'ss', shadowsocks_chipher: /.+/});
|
so.depends({type: 'ss', shadowsocks_chipher: /.+/});
|
||||||
|
@ -278,7 +278,7 @@ return view.extend({
|
||||||
so = ss.taboption('field_general', form.Value, 'trojan_ss_password', _('Shadowsocks password'));
|
so = ss.taboption('field_general', form.Value, 'trojan_ss_password', _('Shadowsocks password'));
|
||||||
so.password = true;
|
so.password = true;
|
||||||
so.validate = function(section_id, value) {
|
so.validate = function(section_id, value) {
|
||||||
var encmode = this.section.getOption('trojan_ss_chipher').formvalue(section_id);
|
const encmode = this.section.getOption('trojan_ss_chipher').formvalue(section_id);
|
||||||
return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value);
|
return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value);
|
||||||
}
|
}
|
||||||
so.depends({type: 'trojan', trojan_ss_enabled: '1'});
|
so.depends({type: 'trojan', trojan_ss_enabled: '1'});
|
||||||
|
@ -470,9 +470,9 @@ return view.extend({
|
||||||
so = ss.taboption('field_general', form.Flag, 'tls', _('TLS'));
|
so = ss.taboption('field_general', form.Flag, 'tls', _('TLS'));
|
||||||
so.default = so.disabled;
|
so.default = so.disabled;
|
||||||
so.validate = function(section_id, value) {
|
so.validate = function(section_id, value) {
|
||||||
var type = this.section.getOption('type').formvalue(section_id);
|
const type = this.section.getOption('type').formvalue(section_id);
|
||||||
var tls = this.section.getUIElement(section_id, 'tls').node.querySelector('input');
|
let tls = this.section.getUIElement(section_id, 'tls').node.querySelector('input');
|
||||||
var tls_alpn = this.section.getUIElement(section_id, 'tls_alpn');
|
let tls_alpn = this.section.getUIElement(section_id, 'tls_alpn');
|
||||||
|
|
||||||
// Force enabled
|
// Force enabled
|
||||||
if (['trojan', 'hysteria', 'hysteria2', 'tuic'].includes(type)) {
|
if (['trojan', 'hysteria', 'hysteria2', 'tuic'].includes(type)) {
|
||||||
|
@ -585,7 +585,7 @@ return view.extend({
|
||||||
so.value('grpc', _('gRPC'));
|
so.value('grpc', _('gRPC'));
|
||||||
so.value('ws', _('WebSocket'));
|
so.value('ws', _('WebSocket'));
|
||||||
so.validate = function(section_id, value) {
|
so.validate = function(section_id, value) {
|
||||||
var type = this.section.getOption('type').formvalue(section_id);
|
const type = this.section.getOption('type').formvalue(section_id);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'vmess':
|
case 'vmess':
|
||||||
|
@ -793,7 +793,7 @@ return view.extend({
|
||||||
ss.sectiontitle = L.bind(hm.loadDefaultLabel, ss);
|
ss.sectiontitle = L.bind(hm.loadDefaultLabel, ss);
|
||||||
/* Remove idle files start */
|
/* Remove idle files start */
|
||||||
ss.renderSectionAdd = function(/* ... */) {
|
ss.renderSectionAdd = function(/* ... */) {
|
||||||
var el = hm.renderSectionAdd.apply(this, [prefmt, false].concat(Array.prototype.slice.call(arguments)));
|
let el = hm.renderSectionAdd.apply(this, [prefmt, false].concat(Array.prototype.slice.call(arguments)));
|
||||||
|
|
||||||
el.appendChild(E('button', {
|
el.appendChild(E('button', {
|
||||||
'class': 'cbi-button cbi-button-add',
|
'class': 'cbi-button cbi-button-add',
|
||||||
|
@ -828,7 +828,7 @@ return view.extend({
|
||||||
|
|
||||||
so = ss.option(form.DummyValue, '_value', _('Value'));
|
so = ss.option(form.DummyValue, '_value', _('Value'));
|
||||||
so.load = function(section_id) {
|
so.load = function(section_id) {
|
||||||
var option = uci.get(data[0], section_id, 'type');
|
const option = uci.get(data[0], section_id, 'type');
|
||||||
|
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'file':
|
case 'file':
|
||||||
|
@ -1079,8 +1079,8 @@ return view.extend({
|
||||||
|
|
||||||
so = ss.option(form.DummyValue, '_value', _('Value'));
|
so = ss.option(form.DummyValue, '_value', _('Value'));
|
||||||
so.load = function(section_id) {
|
so.load = function(section_id) {
|
||||||
var type = uci.get(data[0], section_id, 'type');
|
const type = uci.get(data[0], section_id, 'type');
|
||||||
var detour = uci.get(data[0], section_id, 'chain_tail_group') || uci.get(data[0], section_id, 'chain_tail');
|
const detour = uci.get(data[0], section_id, 'chain_tail_group') || uci.get(data[0], section_id, 'chain_tail');
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'node':
|
case 'node':
|
||||||
|
@ -1111,7 +1111,7 @@ return view.extend({
|
||||||
so.load = L.bind(hm.loadNodeLabel, so);
|
so.load = L.bind(hm.loadNodeLabel, so);
|
||||||
so.rmempty = false;
|
so.rmempty = false;
|
||||||
so.validate = function(section_id, value) {
|
so.validate = function(section_id, value) {
|
||||||
var chain_tail = this.section.getUIElement(section_id, 'chain_tail').getValue();
|
const chain_tail = this.section.getUIElement(section_id, 'chain_tail').getValue();
|
||||||
|
|
||||||
if (value === chain_tail)
|
if (value === chain_tail)
|
||||||
return _('Expecting: %s').format(_('Different chain head/tail'));
|
return _('Expecting: %s').format(_('Different chain head/tail'));
|
||||||
|
@ -1126,8 +1126,8 @@ return view.extend({
|
||||||
so.value('', _('-- Please choose --'));
|
so.value('', _('-- Please choose --'));
|
||||||
so.load = L.bind(hm.loadNodeLabel, so);
|
so.load = L.bind(hm.loadNodeLabel, so);
|
||||||
so.validate = function(section_id, value) {
|
so.validate = function(section_id, value) {
|
||||||
var chain_head = this.section.getUIElement(section_id, 'chain_head').getValue();
|
const chain_head = this.section.getUIElement(section_id, 'chain_head').getValue();
|
||||||
var chain_tail = this.section.getUIElement(section_id, 'chain_tail').getValue();
|
const chain_tail = this.section.getUIElement(section_id, 'chain_tail').getValue();
|
||||||
value = this.getUIElement(section_id).getValue();
|
value = this.getUIElement(section_id).getValue();
|
||||||
|
|
||||||
if (value.includes(chain_head) || value.includes(chain_tail))
|
if (value.includes(chain_head) || value.includes(chain_tail))
|
||||||
|
@ -1136,10 +1136,10 @@ return view.extend({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
so.textvalue = function(section_id) {
|
so.textvalue = function(section_id) {
|
||||||
var cvals = this.cfgvalue(section_id);
|
let cvals = this.cfgvalue(section_id);
|
||||||
//alert(Array.prototype.join.call(cvals, ':'));
|
//alert(Array.prototype.join.call(cvals, ':'));
|
||||||
return cvals ? '» ' + cvals.map((cval) => {
|
return cvals ? '» ' + cvals.map((cval) => {
|
||||||
var i = this.keylist.indexOf(cval);
|
let i = this.keylist.indexOf(cval);
|
||||||
|
|
||||||
return this.vallist[i];
|
return this.vallist[i];
|
||||||
}).join(' » ') + ' »' : '»';
|
}).join(' » ') + ' »' : '»';
|
||||||
|
@ -1159,7 +1159,7 @@ return view.extend({
|
||||||
so.load = L.bind(hm.loadNodeLabel, so);
|
so.load = L.bind(hm.loadNodeLabel, so);
|
||||||
so.rmempty = false;
|
so.rmempty = false;
|
||||||
so.validate = function(section_id, value) {
|
so.validate = function(section_id, value) {
|
||||||
var chain_head = this.section.getUIElement(section_id, 'chain_head').getValue();
|
const chain_head = this.section.getUIElement(section_id, 'chain_head').getValue();
|
||||||
|
|
||||||
if (value === chain_head)
|
if (value === chain_head)
|
||||||
return _('Expecting: %s').format(_('Different chain head/tail'));
|
return _('Expecting: %s').format(_('Different chain head/tail'));
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
'require fchomo as hm';
|
'require fchomo as hm';
|
||||||
|
|
||||||
function parseRulesetLink(uri) {
|
function parseRulesetLink(uri) {
|
||||||
var config,
|
let config,
|
||||||
filefmt = new RegExp(/^(text|yaml|mrs)$/),
|
filefmt = new RegExp(/^(text|yaml|mrs)$/),
|
||||||
filebehav = new RegExp(/^(domain|ipcidr|classical)$/),
|
filebehav = new RegExp(/^(domain|ipcidr|classical)$/),
|
||||||
unuciname = new RegExp(/[^a-zA-Z0-9_]+/, "g");
|
unuciname = new RegExp(/[^a-zA-Z0-9_]+/, "g");
|
||||||
|
@ -26,7 +26,7 @@ function parseRulesetLink(uri) {
|
||||||
.replace(/[\s\.-]/g, '_').replace(unuciname, '');
|
.replace(/[\s\.-]/g, '_').replace(unuciname, '');
|
||||||
|
|
||||||
if (filefmt.test(format) && filebehav.test(behavior)) {
|
if (filefmt.test(format) && filebehav.test(behavior)) {
|
||||||
var fullpath = (url.username ? url.username + '@' : '') + url.host + url.pathname + (rawquery ? '?' + decodeURIComponent(rawquery) : '');
|
let fullpath = (url.username ? url.username + '@' : '') + url.host + url.pathname + (rawquery ? '?' + decodeURIComponent(rawquery) : '');
|
||||||
config = {
|
config = {
|
||||||
label: url.hash ? decodeURIComponent(url.hash.slice(1)) : name ? name : null,
|
label: url.hash ? decodeURIComponent(url.hash.slice(1)) : name ? name : null,
|
||||||
type: 'http',
|
type: 'http',
|
||||||
|
@ -90,13 +90,13 @@ function parseRulesetLink(uri) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
uci.load('fchomo')
|
uci.load('fchomo')
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(data) {
|
render(data) {
|
||||||
let m, s, o;
|
let m, s, o;
|
||||||
|
|
||||||
m = new form.Map('fchomo', _('Edit ruleset'));
|
m = new form.Map('fchomo', _('Edit ruleset'));
|
||||||
|
@ -113,7 +113,7 @@ return view.extend({
|
||||||
s.sectiontitle = L.bind(hm.loadDefaultLabel, s);
|
s.sectiontitle = L.bind(hm.loadDefaultLabel, s);
|
||||||
/* Import rule-set links and Remove idle files start */
|
/* Import rule-set links and Remove idle files start */
|
||||||
s.handleLinkImport = function() {
|
s.handleLinkImport = function() {
|
||||||
var textarea = new ui.Textarea('', {
|
let textarea = new ui.Textarea('', {
|
||||||
'placeholder': 'http(s)://github.com/ACL4SSR/ACL4SSR/raw/refs/heads/master/Clash/Providers/BanAD.yaml?fmt=yaml&behav=classical&rawq=good%3Djob#BanAD\n' +
|
'placeholder': 'http(s)://github.com/ACL4SSR/ACL4SSR/raw/refs/heads/master/Clash/Providers/BanAD.yaml?fmt=yaml&behav=classical&rawq=good%3Djob#BanAD\n' +
|
||||||
'file:///example.txt?fmt=text&behav=domain&fill=LmNuCg#CN%20TLD\n' +
|
'file:///example.txt?fmt=text&behav=domain&fill=LmNuCg#CN%20TLD\n' +
|
||||||
'inline://LSAnLmhrJwoK?behav=domain#HK%20TLD\n'
|
'inline://LSAnLmhrJwoK?behav=domain#HK%20TLD\n'
|
||||||
|
@ -133,17 +133,17 @@ return view.extend({
|
||||||
E('button', {
|
E('button', {
|
||||||
class: 'btn cbi-button-action',
|
class: 'btn cbi-button-action',
|
||||||
click: ui.createHandlerFn(this, function() {
|
click: ui.createHandlerFn(this, function() {
|
||||||
var input_links = textarea.getValue().trim().split('\n');
|
let input_links = textarea.getValue().trim().split('\n');
|
||||||
if (input_links && input_links[0]) {
|
if (input_links && input_links[0]) {
|
||||||
/* Remove duplicate lines */
|
/* Remove duplicate lines */
|
||||||
input_links = input_links.reduce((pre, cur) =>
|
input_links = input_links.reduce((pre, cur) =>
|
||||||
(!pre.includes(cur) && pre.push(cur), pre), []);
|
(!pre.includes(cur) && pre.push(cur), pre), []);
|
||||||
|
|
||||||
var imported_ruleset = 0;
|
let imported_ruleset = 0;
|
||||||
input_links.forEach((l) => {
|
input_links.forEach((l) => {
|
||||||
var config = parseRulesetLink(l);
|
let config = parseRulesetLink(l);
|
||||||
if (config) {
|
if (config) {
|
||||||
var sid = uci.add(data[0], 'ruleset', config.id);
|
let sid = uci.add(data[0], 'ruleset', config.id);
|
||||||
config.id = null;
|
config.id = null;
|
||||||
Object.keys(config).forEach((k) => {
|
Object.keys(config).forEach((k) => {
|
||||||
uci.set(data[0], sid, k, config[k] || '');
|
uci.set(data[0], sid, k, config[k] || '');
|
||||||
|
@ -172,7 +172,7 @@ return view.extend({
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
s.renderSectionAdd = function(/* ... */) {
|
s.renderSectionAdd = function(/* ... */) {
|
||||||
var el = hm.renderSectionAdd.apply(this, [prefmt, false].concat(Array.prototype.slice.call(arguments)));
|
let el = hm.renderSectionAdd.apply(this, [prefmt, false].concat(Array.prototype.slice.call(arguments)));
|
||||||
|
|
||||||
el.appendChild(E('button', {
|
el.appendChild(E('button', {
|
||||||
'class': 'cbi-button cbi-button-add',
|
'class': 'cbi-button cbi-button-add',
|
||||||
|
@ -212,7 +212,7 @@ return view.extend({
|
||||||
o.value('mrs', _('Binary file'));
|
o.value('mrs', _('Binary file'));
|
||||||
o.default = 'yaml';
|
o.default = 'yaml';
|
||||||
o.validate = function(section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
var behavior = this.section.getUIElement(section_id, 'behavior').getValue();
|
const behavior = this.section.getUIElement(section_id, 'behavior').getValue();
|
||||||
|
|
||||||
if (value === 'mrs' && behavior === 'classical')
|
if (value === 'mrs' && behavior === 'classical')
|
||||||
return _('Expecting: %s').format(_('Binary format only supports domain / ipcidr'));
|
return _('Expecting: %s').format(_('Binary format only supports domain / ipcidr'));
|
||||||
|
@ -220,8 +220,8 @@ return view.extend({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
o.textvalue = function(section_id) {
|
o.textvalue = function(section_id) {
|
||||||
var cval = this.cfgvalue(section_id) || this.default;
|
let cval = this.cfgvalue(section_id) || this.default;
|
||||||
var inline = L.bind(function() {
|
let inline = L.bind(function() {
|
||||||
let cval = this.cfgvalue(section_id) || this.default;
|
let cval = this.cfgvalue(section_id) || this.default;
|
||||||
return (cval === 'inline') ? true : false;
|
return (cval === 'inline') ? true : false;
|
||||||
}, s.getOption('type'));
|
}, s.getOption('type'));
|
||||||
|
@ -235,7 +235,7 @@ return view.extend({
|
||||||
o.value('ipcidr');
|
o.value('ipcidr');
|
||||||
o.default = 'classical';
|
o.default = 'classical';
|
||||||
o.validate = function(section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
var format = this.section.getUIElement(section_id, 'format').getValue();
|
const format = this.section.getUIElement(section_id, 'format').getValue();
|
||||||
|
|
||||||
if (value === 'classical' && format === 'mrs')
|
if (value === 'classical' && format === 'mrs')
|
||||||
return _('Expecting: %s').format(_('Binary format only supports domain / ipcidr'));
|
return _('Expecting: %s').format(_('Binary format only supports domain / ipcidr'));
|
||||||
|
@ -245,7 +245,7 @@ return view.extend({
|
||||||
|
|
||||||
o = s.option(form.DummyValue, '_value', _('Value'));
|
o = s.option(form.DummyValue, '_value', _('Value'));
|
||||||
o.load = function(section_id) {
|
o.load = function(section_id) {
|
||||||
var option = uci.get(data[0], section_id, 'type');
|
const option = uci.get(data[0], section_id, 'type');
|
||||||
|
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'file':
|
case 'file':
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
'require fchomo as hm';
|
'require fchomo as hm';
|
||||||
|
|
||||||
function handleGenKey(option) {
|
function handleGenKey(option) {
|
||||||
var section_id = this.section.section;
|
const section_id = this.section.section;
|
||||||
var type = this.section.getOption('type').formvalue(section_id);
|
const type = this.section.getOption('type').formvalue(section_id);
|
||||||
var widget = this.map.findElement('id', 'widget.cbid.fchomo.%s.%s'.format(section_id, option));
|
let widget = this.map.findElement('id', 'widget.cbid.fchomo.%s.%s'.format(section_id, option));
|
||||||
var password, required_method;
|
let password, required_method;
|
||||||
|
|
||||||
if (option === 'uuid' || option.match(/_uuid/))
|
if (option === 'uuid' || option.match(/_uuid/))
|
||||||
required_method = 'uuid';
|
required_method = 'uuid';
|
||||||
|
@ -44,8 +44,8 @@ function handleGenKey(option) {
|
||||||
const CBIPWGenValue = form.Value.extend({
|
const CBIPWGenValue = form.Value.extend({
|
||||||
__name__: 'CBI.PWGenValue',
|
__name__: 'CBI.PWGenValue',
|
||||||
|
|
||||||
renderWidget: function() {
|
renderWidget() {
|
||||||
var node = form.Value.prototype.renderWidget.apply(this, arguments);
|
let node = form.Value.prototype.renderWidget.apply(this, arguments);
|
||||||
|
|
||||||
(node.querySelector('.control-group') || node).appendChild(E('button', {
|
(node.querySelector('.control-group') || node).appendChild(E('button', {
|
||||||
'class': 'cbi-button cbi-button-add',
|
'class': 'cbi-button cbi-button-add',
|
||||||
|
@ -58,16 +58,16 @@ const CBIPWGenValue = form.Value.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
uci.load('fchomo'),
|
uci.load('fchomo'),
|
||||||
hm.getFeatures()
|
hm.getFeatures()
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(data) {
|
render(data) {
|
||||||
var dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo'),
|
const dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo');
|
||||||
features = data[1];
|
const features = data[1];
|
||||||
|
|
||||||
let m, s, o;
|
let m, s, o;
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ return view.extend({
|
||||||
o = s.option(CBIPWGenValue, 'shadowsocks_password', _('Password'));
|
o = s.option(CBIPWGenValue, 'shadowsocks_password', _('Password'));
|
||||||
o.password = true;
|
o.password = true;
|
||||||
o.validate = function(section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
var encmode = this.section.getOption('shadowsocks_chipher').formvalue(section_id);
|
const encmode = this.section.getOption('shadowsocks_chipher').formvalue(section_id);
|
||||||
return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value);
|
return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value);
|
||||||
}
|
}
|
||||||
o.depends({type: 'shadowsocks', shadowsocks_chipher: /.+/});
|
o.depends({type: 'shadowsocks', shadowsocks_chipher: /.+/});
|
||||||
|
@ -270,9 +270,9 @@ return view.extend({
|
||||||
o = s.option(form.Flag, 'tls', _('TLS'));
|
o = s.option(form.Flag, 'tls', _('TLS'));
|
||||||
o.default = o.disabled;
|
o.default = o.disabled;
|
||||||
o.validate = function(section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
var type = this.section.getOption('type').formvalue(section_id);
|
const type = this.section.getOption('type').formvalue(section_id);
|
||||||
var tls = this.section.getUIElement(section_id, 'tls').node.querySelector('input');
|
let tls = this.section.getUIElement(section_id, 'tls').node.querySelector('input');
|
||||||
var tls_alpn = this.section.getUIElement(section_id, 'tls_alpn');
|
let tls_alpn = this.section.getUIElement(section_id, 'tls_alpn');
|
||||||
|
|
||||||
// Force enabled
|
// Force enabled
|
||||||
if (['tuic', 'hysteria2'].includes(type)) {
|
if (['tuic', 'hysteria2'].includes(type)) {
|
||||||
|
|
Loading…
Reference in New Issue