Update On Mon Dec 15 19:43:21 CET 2025

This commit is contained in:
github-action[bot]
2025-12-15 19:43:22 +01:00
parent e3fa06eaac
commit 4456ecc632
128 changed files with 12001 additions and 876 deletions

View File

@@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=25.12.13
PKG_VERSION:=25.12.16
PKG_RELEASE:=1
PKG_PO_VERSION:=$(PKG_VERSION)

File diff suppressed because one or more lines are too long

View File

@@ -9,9 +9,7 @@ if not arg[1] or not m:get(arg[1]) then
luci.http.redirect(m.redirect)
end
if api.is_js_luci() then
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
end
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
local fs = api.fs
local sys = api.sys
@@ -198,9 +196,7 @@ o:depends({ _hide_node_option = "1", ['!reverse'] = true })
o = s:option(ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>")
o.default = ""
o:depends({ _hide_node_option = false, use_global_config = false })
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {}
o = s:option(DummyValue, "_tcp_node_bool", "")
@@ -213,9 +209,7 @@ o.default = ""
o:value("", translate("Close"))
o:value("tcp", translate("Same as the tcp node"))
o:depends({ _tcp_node_bool = "1" })
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"",""}
o = s:option(DummyValue, "_udp_node_bool", "")

View File

@@ -11,9 +11,7 @@ local has_chnroute = fs.access("/usr/share/passwall/rules/chnroute")
m = Map(appname)
api.set_apply_on_parse(m)
if api.is_js_luci() then
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
end
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
local nodes_table = {}
for _, e in ipairs(api.get_valid_nodes()) do
@@ -109,17 +107,13 @@ o.rmempty = false
---- TCP Node
o = s:taboption("Main", ListValue, "tcp_node", "<a style='color: red'>" .. translate("TCP Node") .. "</a>")
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o:value("", translate("Close"))
o.group = {""}
---- UDP Node
o = s:taboption("Main", ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o:value("", translate("Close"))
o:value("tcp", translate("Same as the tcp node"))
o.group = {"",""}
@@ -169,9 +163,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
o = s:taboption("Main", ListValue, vid .. "-main_node", string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not."))
o:depends(vid .. "-preproxy_enabled", "1")
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {}
for k1, v1 in pairs(socks_list) do
o:value(v1.id, v1.remark)
@@ -209,9 +201,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
o:value("_default", translate("Default"))
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"","","",""}
local pt = s:taboption("Main", ListValue, vid .. "-".. id .. "_proxy_tag", string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
@@ -252,9 +242,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
o:depends("tcp_node", v.id)
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"",""}
for k1, v1 in pairs(socks_list) do
o:value(v1.id, v1.remark)
@@ -388,6 +376,7 @@ end
---- DNS Forward Mode
o = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode"))
o.default = "tcp"
o:value("udp", translatef("Requery DNS By %s", "UDP"))
o:value("tcp", translatef("Requery DNS By %s", "TCP"))
if api.is_finded("dns2socks") then
@@ -773,9 +762,7 @@ o.default = 1
o.rmempty = false
o = s2:option(ListValue, "node", translate("Socks Node"))
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {}
o = s2:option(DummyValue, "now_node", translate("Current Node"))

View File

@@ -10,9 +10,7 @@ if not arg[1] or not m:get(arg[1]) then
end
m:append(Template(appname .. "/cbi/nodes_multivalue_com"))
if api.is_js_luci() then
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
end
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
s = m:section(NamedSection, arg[1], "nodes", "")
s.addremove = false

View File

@@ -147,7 +147,7 @@ o = s:option(DummyValue, "_stop", translate("Delete All Subscribe Node"))
o.rawhtml = true
function o.cfgvalue(self, section)
return string.format(
[[<button type="button" class="cbi-button cbi-button-remove" onclick="return confirmDeleteAll()">%s</button>]],
[[<input type="button" class="btn cbi-button cbi-button-remove" onclick="return confirmDeleteAll()" value="%s" />]],
translate("Delete All Subscribe Node"))
end
@@ -155,7 +155,7 @@ o = s:option(DummyValue, "_update", translate("Manual subscription All"))
o.rawhtml = true
o.cfgvalue = function(self, section)
return string.format([[
<button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribeAll()">%s</button>]],
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribeAll()" value="%s" />]],
translate("Manual subscription All"))
end
@@ -231,7 +231,7 @@ o.rawhtml = true
function o.cfgvalue(self, section)
local remark = m:get(section, "remark") or ""
return string.format(
[[<button type="button" class="cbi-button cbi-button-remove" onclick="return confirmDeleteNode('%s')">%s</button>]],
[[<input type="button" class="btn cbi-button cbi-button-remove" onclick="return confirmDeleteNode('%s')" value="%s" />]],
remark, translate("Delete the subscribed node"))
end
@@ -239,7 +239,7 @@ o = s:option(DummyValue, "_update", translate("Manual subscription"))
o.rawhtml = true
o.cfgvalue = function(self, section)
return string.format([[
<button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')">%s</button>]],
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')" value="%s" />]],
section, translate("Manual subscription"))
end

View File

@@ -13,9 +13,7 @@ function m.commit_handler(self)
self:del(arg[1], "md5")
end
if api.is_js_luci() then
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
end
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
if api.is_js_luci() then
m.apply_on_parse = false
@@ -276,17 +274,13 @@ descrStr = translate(descrStr) .. "<br>" .. translate("Only support a layer of p
o1 = s:option(ListValue, "preproxy_node", translate("Preproxy Node"))
o1:depends({ ["chain_proxy"] = "1" })
o1.description = descrStr
if api.is_js_luci() then
o1.template = appname .. "/cbi/nodes_listvalue"
end
o1.template = appname .. "/cbi/nodes_listvalue"
o1.group = {}
o2 = s:option(ListValue, "to_node", translate("Landing Node"))
o2:depends({ ["chain_proxy"] = "2" })
o2.description = descrStr
if api.is_js_luci() then
o2.template = appname .. "/cbi/nodes_listvalue"
end
o2.template = appname .. "/cbi/nodes_listvalue"
o2.group = {}
for k, v in pairs(nodes_table) do

View File

@@ -10,9 +10,7 @@ if not arg[1] or not m:get(arg[1]) then
end
m:append(Template(appname .. "/cbi/nodes_multivalue_com"))
if api.is_js_luci() then
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
end
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
@@ -50,9 +48,7 @@ socks_node = s:option(ListValue, "node", translate("Node"))
if auto_switch_tip then
socks_node.description = auto_switch_tip
end
if api.is_js_luci() then
socks_node.template = appname .. "/cbi/nodes_listvalue"
end
socks_node.template = appname .. "/cbi/nodes_listvalue"
socks_node.group = {}
o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost."))

View File

@@ -149,9 +149,7 @@ o.default = "random"
o = s:option(ListValue, _n("fallback_node"), translate("Fallback Node"))
o:value("", translate("Close(Not use)"))
o:depends({ [_n("protocol")] = "_balancing" })
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {""}
local function check_fallback_chain(fb)
for k, v in pairs(fallback_table) do
@@ -213,9 +211,7 @@ if #nodes_table > 0 then
o = s:option(ListValue, _n("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not."))
o:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true })
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {}
for k, v in pairs(socks_list) do
o:value(v.id, v.remark)
@@ -242,9 +238,7 @@ m.uci:foreach(appname, "shunt_rules", function(e)
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
o:depends({ [_n("protocol")] = "_shunt" })
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"","","",""}
if #nodes_table > 0 then
@@ -284,9 +278,7 @@ local o = s:option(ListValue, _n("default_node"), string.format('* <a style="col
o:depends({ [_n("protocol")] = "_shunt" })
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"",""}
if #nodes_table > 0 then
@@ -746,16 +738,12 @@ end
o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o1:depends({ [_n("chain_proxy")] = "1" })
if api.is_js_luci() then
o1.template = appname .. "/cbi/nodes_listvalue"
end
o1.template = appname .. "/cbi/nodes_listvalue"
o1.group = {}
o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
o2:depends({ [_n("chain_proxy")] = "2" })
if api.is_js_luci() then
o2.template = appname .. "/cbi/nodes_listvalue"
end
o2.template = appname .. "/cbi/nodes_listvalue"
o2.group = {}
for k, v in pairs(nodes_table) do

View File

@@ -189,9 +189,7 @@ if #nodes_table > 0 then
o = s:option(ListValue, _n("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not."))
o:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true })
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {}
for k, v in pairs(socks_list) do
o:value(v.id, v.remark)
@@ -218,9 +216,7 @@ m.uci:foreach(appname, "shunt_rules", function(e)
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
o:depends({ [_n("protocol")] = "_shunt" })
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"","","",""}
if #nodes_table > 0 then
@@ -260,9 +256,7 @@ local o = s:option(ListValue, _n("default_node"), string.format('* <a style="col
o:depends({ [_n("protocol")] = "_shunt" })
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
if api.is_js_luci() then
o.template = appname .. "/cbi/nodes_listvalue"
end
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"",""}
if #nodes_table > 0 then
@@ -839,16 +833,12 @@ end
o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o1:depends({ [_n("chain_proxy")] = "1" })
if api.is_js_luci() then
o1.template = appname .. "/cbi/nodes_listvalue"
end
o1.template = appname .. "/cbi/nodes_listvalue"
o1.group = {}
o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
o2:depends({ [_n("chain_proxy")] = "2" })
if api.is_js_luci() then
o2.template = appname .. "/cbi/nodes_listvalue"
end
o2.template = appname .. "/cbi/nodes_listvalue"
o2.group = {}
for k, v in pairs(nodes_table) do

View File

@@ -399,7 +399,8 @@ for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" and e.type == type_name then
nodes_table[#nodes_table + 1] = {
id = e[".name"],
remarks = e["remark"]
remarks = e["remark"],
group = e["group"]
}
end
end
@@ -409,7 +410,12 @@ o:value("", translate("Close"))
o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface"))
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
o.template = api.appname .. "/cbi/nodes_listvalue"
o.group = {"","","",""}
for k, v in pairs(nodes_table) do
o:value(v.id, v.remarks)
o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)"))

View File

@@ -397,7 +397,8 @@ for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" and e.type == type_name then
nodes_table[#nodes_table + 1] = {
id = e[".name"],
remarks = e["remark"]
remarks = e["remark"],
group = e["group"]
}
end
end
@@ -407,7 +408,12 @@ o:value("", translate("Close"))
o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface"))
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
o.template = api.appname .. "/cbi/nodes_listvalue"
o.group = {"","","",""}
for k, v in pairs(nodes_table) do
o:value(v.id, v.remarks)
o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)"))

View File

@@ -1,6 +1,7 @@
local api = require "luci.passwall.api"
local appname = api.appname
local fs = api.fs
local types_dir = "/usr/lib/lua/luci/model/cbi/passwall/server/type/"
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/"
m = Map("passwall_server", translate("Server Config"))
m.redirect = api.url("server")
@@ -10,6 +11,8 @@ if not arg[1] or not m:get(arg[1]) then
luci.http.redirect(m.redirect)
end
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
s = m:section(NamedSection, arg[1], "user", "")
s.addremove = false
s.dynamic = false

View File

@@ -101,7 +101,7 @@ window.lv_dropdown_data["<%=cbid%>"] = <%=json.stringify(dropdown_data)%>;
<span class="lv-arrow-down"></span>
</div>
<!-- 下拉面板 -->
<div id="<%=cbid%>.panel" class="cbi-listvalue-panel lv-dropdown-panel">
<div id="<%=cbid%>.panel" class="cbi-listvalue-panel lv-dropdown-panel" style="display:none;">
<!-- 搜索框 -->
<div style="padding:8px;border-bottom:1px solid #f0f0f0;">
<input id="<%=cbid%>.search" class="cbi-input-text lv-dropdown-search" type="text" placeholder="<%:Search nodes...%>" />
@@ -130,12 +130,10 @@ window.lv_dropdown_data["<%=cbid%>"] = <%=json.stringify(dropdown_data)%>;
display.addEventListener("click", function(e){
e.stopPropagation();
lv_render_dropdown_list(cbid,panel,listContainer,hiddenSelect,labelSpan,searchInput,display);
const panelStyle = window.getComputedStyle(panel);
const isPanelVisible = panelStyle.display !== "none";
document.querySelectorAll(".cbi-listvalue-panel").forEach(p=>{
if (p !== panel) p.style.display = "none";
});
if (isPanelVisible) {
if (panel.style.display !== "none") {
lv_closePanel(cbid,panel,listContainer,hiddenSelect,searchInput);
} else {
lv_openPanel(cbid,display,panel,listContainer,hiddenSelect,searchInput);

View File

@@ -91,7 +91,6 @@ local appname = api.appname
top: 0;
left: 0;
z-index: 2147483647;
display: none;
border: 1px solid #dcdcdc;
border-radius: 4px;
box-shadow: 0 6px 18px rgba(0,0,0,0.08);
@@ -255,7 +254,7 @@ local appname = api.appname
const styleBody = window.getComputedStyle(document.body)
const styleNode = document.createElement('style')
const styleNames = ["width", "color", "height", "padding", "margin", "lineHeight", "border", "borderRadius"]
const styleNames = ["width", "color", "height", "padding", "margin", "lineHeight", "border", "borderRadius", "minWidth", "minHeight"]
document.head.appendChild(styleNode)
// trace back from option -> select -> body for background color
const optionColor = !lv_isTransparent(styleOption.backgroundColor) ? styleOption.backgroundColor : !lv_isTransparent(styleSelect.backgroundColor) ? styleSelect.backgroundColor : styleBody.backgroundColor
@@ -431,7 +430,9 @@ local appname = api.appname
});
}
if (targetLi) {
targetLi.scrollIntoView({ block: "nearest" });
requestAnimationFrame(() => {
targetLi.scrollIntoView({ block: "nearest" });
});
}
}
@@ -491,8 +492,14 @@ local appname = api.appname
panel._docClickHandler = handler;
document.addEventListener("click", handler);
// 滚动 / resize 自动 reposition
const repositionHandler = function() {
lv_repositionPanel(panel, display);
let ticking = false;
const repositionHandler = function () {
if (ticking) return;
ticking = true;
requestAnimationFrame(function () {
ticking = false;
lv_repositionPanel(panel, display);
});
};
panel._repositionHandler = repositionHandler;
window.addEventListener("scroll", repositionHandler, true);
@@ -522,8 +529,6 @@ local appname = api.appname
"&":"&amp;", "<":"&lt;", ">":"&gt;", '"':"&quot;", "'":"&#39;"
}[c]));
}
// 通用渲染函数
function lv_render_dropdown_list(cbid, panel, listContainer, hiddenSelect, labelSpan, searchInput, display) {
if (window.lv_dropdown_rendered[cbid]) return;
const data = window.lv_dropdown_data[cbid];
@@ -596,17 +601,21 @@ local appname = api.appname
if(!li || li === listContainer) return;
const key = li.getAttribute('data-key') || "";
const text = li.querySelector(".lv-item-label")?.textContent || li.textContent || key;
//动态改值
hiddenSelect.options[0].value =key;
hiddenSelect.value = key;
labelSpan.textContent = text;
labelSpan.title = text;
try {
var evt = new Event('change', { bubbles: true });
hiddenSelect.dispatchEvent(evt);
} catch(e){}
lv_highlightSelectedItem(listContainer, hiddenSelect);
lv_updateGroupCounts(cbid, listContainer, hiddenSelect, searchInput);
if (key !== hiddenSelect.value) {
//动态改值
hiddenSelect.options[0].value = key;
hiddenSelect.value = key;
labelSpan.textContent = text;
labelSpan.title = text;
setTimeout(() => {
try {
const evt = new Event('change', { bubbles: true });
hiddenSelect.dispatchEvent(evt);
} catch(e){}
}, 0);
lv_highlightSelectedItem(listContainer, hiddenSelect);
lv_updateGroupCounts(cbid, listContainer, hiddenSelect, searchInput);
}
lv_closePanel(cbid,panel,listContainer,hiddenSelect,searchInput);
});

View File

@@ -34,8 +34,6 @@ local api = require "luci.passwall.api"
);
}
<% if api.is_js_luci() then %>
var global_id = null;
var global = document.getElementById("cbi-passwall-global");
if (global) {
@@ -124,122 +122,6 @@ local api = require "luci.passwall.api"
}
}
<% else %>
var global_id = null;
var global = document.getElementById("cbi-passwall-global");
if (global) {
var node = global.getElementsByClassName("cbi-section-node")[0];
var node_id = node.getAttribute("id");
global_id = node_id;
var reg1 = new RegExp("(?<=" + node_id + "-).*?(?=(_node))")
for (var i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].childNodes && node.childNodes[i].childNodes.length > 0) {
for (var k = 0; k < node.childNodes[i].childNodes.length; k++) {
try {
var dom = node.childNodes[i].childNodes[k];
if (dom.id) {
var s = dom.id.match(reg1);
if (s) {
var cbi_id = global_id + "-"
var dom_id = dom.id.split(cbi_id).join(cbi_id.split("-").join(".")).split("cbi.").join("cbid.")
var node_select = document.getElementsByName(dom_id)[0];
var node_select_value = node_select.value;
if (node_select_value && node_select_value != "" && node_select_value.indexOf("_default") != 0 && node_select_value.indexOf("_direct") != 0 && node_select_value.indexOf("_blackhole") != 0) {
if (global_id != null && node_select_value.indexOf("tcp") == 0) {
var d = global_id + "-tcp_node";
d = d.replace("cbi-", "cbid-").replace(new RegExp("-", 'g'), ".");
var dom = document.getElementsByName(d)[0];
var _node_select_value = dom.value;
if (_node_select_value && _node_select_value != "") {
node_select_value = _node_select_value;
}
}
if (node_select.tagName == "INPUT") {
node_select = document.getElementById("cbi.combobox." + dom_id);
}
var new_html = ""
if (true) {
var to_url = '<%=api.url("node_config")%>/' + node_select_value;
if (node_select_value.indexOf("Socks_") == 0) {
to_url = '<%=api.url("socks_config")%>/' + node_select_value.substring("Socks_".length);
}
var new_a = document.createElement("a");
new_a.innerHTML = "<%:Edit%>";
new_a.href = "#";
new_a.setAttribute("onclick", "location.href='" + to_url + "'");
new_html = new_a.outerHTML;
}
if (s[0] == "tcp" || s[0] == "udp") {
var log_a = document.createElement("a");
log_a.innerHTML = "<%:Log%>";
log_a.href = "#";
log_a.setAttribute("onclick", "window.open('" + '<%=api.url("get_redir_log")%>' + "?name=default&proto=" + s[0] + "', '_blank')");
new_html += "&nbsp&nbsp" + log_a.outerHTML;
}
node_select.insertAdjacentHTML("afterend", "&nbsp&nbsp" + new_html);
}
}
}
} catch(err) {
}
}
}
}
}
var socks = document.getElementById("cbi-passwall-socks");
if (socks) {
var socks_enabled_dom = document.getElementById(global_id + "-socks_enabled");
socks_enabled_dom.parentNode.removeChild(socks_enabled_dom);
var descr = socks.getElementsByClassName("cbi-section-descr")[0];
descr.outerHTML = socks_enabled_dom.outerHTML;
rows = socks.getElementsByClassName("cbi-section-table-row");
for (var i = 0; i < rows.length; i++) {
try {
var row = rows[i];
var id = row.id;
if (!id) continue;
var dom_id = id + "-node";
var node = document.getElementById(dom_id);
var dom_id = dom_id.replace("cbi-", "cbid-").replace(new RegExp("-", 'g'), ".");
var node_select = document.getElementsByName(dom_id)[0];
var node_select_value = node_select.value;
if (node_select_value && node_select_value != "") {
var v = document.getElementById(dom_id + "-" + node_select_value);
if (v) {
node_select.title = v.text;
} else {
node_select.title = node_select.options[node_select.options.selectedIndex].text;
}
var new_html = ""
var new_a = document.createElement("a");
new_a.innerHTML = "<%:Edit%>";
new_a.href = "#";
new_a.setAttribute("onclick","location.href='" + '<%=api.url("node_config")%>' + "/" + node_select_value + "'");
new_html = new_a.outerHTML;
var log_a = document.createElement("a");
log_a.innerHTML = "<%:Log%>";
log_a.href = "#";
log_a.setAttribute("onclick", "window.open('" + '<%=api.url("get_socks_log")%>' + "?name=" + id.replace("cbi-passwall-", "") + "', '_blank')");
new_html += "&nbsp" + log_a.outerHTML;
node_select.insertAdjacentHTML("afterend", "&nbsp&nbsp" + new_html);
}
} catch(err) {
}
}
}
<% end %>
var selects = document.querySelectorAll("select[id*='dns_shunt']");
selects.forEach(function (select, index) {
if (select.value === "chinadns-ng") {

View File

@@ -1657,7 +1657,9 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:Generate QRCode%>' onclick="return genQrcode(this, '<%=self.option%>', '<%=self.value%>')" />
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:Export Config File%>' onclick="return exportConfigFile(this, '<%=self.value%>')" />
<div id="qrcode_div" style="margin-top: 1rem;display:none">
<div id="qrcode"></div>
<div id="qrcode" style="display:flex;justify-content:center;"></div>
</div>
<div style="text-align:center;">
<span id="<%=self.option%>-status"></span>
</div>
<span id="<%=self.option%>-status"></span>
<%+cbi/valuefooter%>

View File

@@ -1121,7 +1121,7 @@ msgid "Are you sure you want to delete all subscribed nodes?"
msgstr "您确定要删除所有已订阅的节点吗?"
msgid "Manual subscription All"
msgstr "手动订阅全部"
msgstr "手动订阅全部链接"
msgid "This remark already exists, please change a new remark."
msgstr "此备注已存在,请改一个新的备注。"