diff --git a/dae/Makefile b/dae/Makefile index b6b1a201..a2c371a5 100644 --- a/dae/Makefile +++ b/dae/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dae -PKG_VERSION:=2026.07.13 +PKG_VERSION:=2026.07.16 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=f303e94cebeda73de63a5ab00652009a12f2384e +PKG_SOURCE_VERSION:=eee7c94db84bca2a0384c7bb5d4f6d7d8a539ec7 PKG_SOURCE_URL:=https://github.com/olicesx/dae.git PKG_MIRROR_HASH:=skip diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua index 860f9106..e3f3d9a1 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua @@ -15,7 +15,8 @@ o.rmempty = false o.default = false -- [[ ACLs Settings ]]-- -s = m:section(TypedSection, "acl_rule") +local cfgname = "acl_rule" +s = m:section(TypedSection, cfgname) s.template = "cbi/tblsection" s.sortable = true s.anonymous = true @@ -103,4 +104,9 @@ o:value("1:65535", translate("All")) o:value("53", "53") ]]-- +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.target_cfgname = cfgname +m:append(sortable) + return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua index abff0091..c4784a87 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua @@ -103,7 +103,8 @@ end o:depends("health_check_type", "passwall_logic") -- [[ Balancing Settings ]]-- -s = m:section(TypedSection, "haproxy_config", translate("Node List")) +local cfgname = "haproxy_config" +s = m:section(TypedSection, cfgname, translate("Node List")) s.description = "" .. translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") .. "
" .. translate("Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!") .. "
" @@ -179,6 +180,11 @@ o:value(0, translate("Primary")) o:value(1, translate("Standby")) o.rmempty = false +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.target_cfgname = cfgname +m:append(sortable) + m:append(Template(appname .. "/haproxy/js")) return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua index 326b2df0..276f2813 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua @@ -129,7 +129,8 @@ o.cfgvalue = function(self, section) translate("Manual subscription All")) end -s = m:section(TypedSection, "subscribe_list", "", "" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "") +local cfgname = "subscribe_list" +s = m:section(TypedSection, cfgname, "", "" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "") s.addremove = true s.anonymous = true s.sortable = true @@ -150,7 +151,7 @@ o.validate = function(self, value, section) return nil, translate("Remark cannot be empty.") end local duplicate = false - m.uci:foreach(appname, "subscribe_list", function(e) + m.uci:foreach(appname, cfgname, function(e) if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then duplicate = true return false @@ -225,6 +226,11 @@ o.cfgvalue = function(self, section) section, translate("Manual subscription")) end +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.target_cfgname = cfgname +m:append(sortable) + m:append(Template(appname .. "/node_subscribe/js")) return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua index 8ad9e7e1..979d4fe4 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua @@ -142,8 +142,10 @@ end s:append(Template(appname .. "/rule/rule_version")) +local cfgname = "shunt_rules" + if has_xray or has_singbox then - s = m:section(TypedSection, "shunt_rules", "Sing-Box/Xray " .. translate("Shunt Rule"), "" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "") + s = m:section(TypedSection, cfgname, "Sing-Box/Xray " .. translate("Shunt Rule"), "" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "") s.template = "cbi/tblsection" s.anonymous = false s.addremove = true @@ -165,4 +167,9 @@ if has_xray or has_singbox then o = s:option(DummyValue, "remarks", translate("Remarks")) end +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.target_cfgname = cfgname +m:append(sortable) + return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/index.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/index.lua index 752c306e..f3a147a5 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/server/index.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/index.lua @@ -13,7 +13,8 @@ t.addremove = false e = t:option(Flag, "enable", translate("Enable")) e.rmempty = false -t = m:section(TypedSection, "user", translate("Users Manager")) +local cfgname = "user" +t = m:section(TypedSection, cfgname, translate("Users Manager")) t.anonymous = true t.addremove = true t.sortable = true @@ -88,6 +89,12 @@ e = t:option(Flag, "log", translate("Log")) e.default = "1" e.rmempty = false +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.appname = m.config +sortable.target_cfgname = cfgname +m:append(sortable) + m:append(Template(appname .. "/server/log")) m:append(Template(appname .. "/server/users_list_status")) diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm index 9de708e5..0e8940ef 100644 --- a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm @@ -403,7 +403,7 @@ function lv_expandGroupOfCurrent(cbid, listContainer, hiddenSelect) { const key = hiddenSelect.options[0].value; if (!key) return; - const targetLi = listContainer.querySelector("li[data-key='" + key.replace(/'/g,"\\'") + "']"); + const targetLi = listContainer.querySelector(`li[data-key='${CSS.escape(key)}']`); if (!targetLi) return; let parentGroup = targetLi.closest(".lv-group"); if (parentGroup) { diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm index 1f784d04..d470ea4b 100644 --- a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm @@ -402,7 +402,7 @@ function v_expandGroupOfCurrent(cbid, listContainer, hiddenInput) { const key = hiddenInput.value; if (!key) return; - const targetLi = listContainer.querySelector("li[data-key='" + key.replace(/'/g,"\\'") + "']"); + const targetLi = listContainer.querySelector(`li[data-key='${CSS.escape(key)}']`); if (!targetLi) return; let parentGroup = targetLi.closest(".v-group"); if (parentGroup) { diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/sortable.htm b/luci-app-passwall/luasrc/view/passwall/cbi/sortable.htm new file mode 100644 index 00000000..2f508eaf --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/sortable.htm @@ -0,0 +1,159 @@ +<% +local api = self.api +local appname = self.appname or api.appname +local target_cfgname = self.target_cfgname +-%> + + + \ No newline at end of file diff --git a/luci-app-passwall/luasrc/view/passwall/haproxy/js.htm b/luci-app-passwall/luasrc/view/passwall/haproxy/js.htm index 22256df1..6c84ed97 100644 --- a/luci-app-passwall/luasrc/view/passwall/haproxy/js.htm +++ b/luci-app-passwall/luasrc/view/passwall/haproxy/js.htm @@ -2,46 +2,8 @@ local api = require "luci.passwall.api" local appname = api.appname -%> - diff --git a/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm b/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm index c0834a1c..d8ec0378 100644 --- a/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm +++ b/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm @@ -4,16 +4,8 @@ local fs = api.fs local has_old_geoip = fs.access("/tmp/bak_v2ray/geoip.dat") local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat") -%> -
@@ -219,120 +187,5 @@ local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat") } ); } - - //分流规则添加拖拽排序 - document.addEventListener("DOMContentLoaded", function () { - function initSortableForTable() { - var section = document.getElementById("cbi-<%=api.appname%>-shunt_rules"); - if (!section) return; - - hideSortColumn(section); - - // === 插入 drag handle === - var rows = section.querySelectorAll("tr"); - rows.forEach(function(row) { - var btn = row.querySelector(".cbi-button-remove:last-of-type"); - if (!btn) return; - if (btn.nextElementSibling && btn.nextElementSibling.classList.contains("drag-handle")) return; - var handle = document.createElement("span"); - handle.className = "drag-handle center"; - handle.title = "<%:Drag to reorder%>"; - handle.innerHTML = "⠿"; - btn.after(handle); - }); - - // === 初始化 Sortable === - var table = section.getElementsByTagName("table")[0]; - if (!table) return; - var root = table.tBodies[0] || table; - if (root._sortable_initialized) return root._sortable_instance; - root._sortable_initialized = true; - - // 保存原始顺序 - root._origOrder = getCurrentOrder(root); - - try { - root._sortable_instance = Sortable.create(root, { - handle: ".drag-handle", - draggable: "tr.cbi-section-table-row", - animation: 150, - ghostClass: "dragging-row", - fallbackOnBody: true, - forceFallback: false, - swapThreshold: 0.65, - onEnd: function (evt) { - updateHiddenInput(root, section); - } - }); - return root._sortable_instance; - } catch (e) { - root._sortable_initialized = false; - console.error("Sortable init failed:", e); - } - } - - // 获取 table 当前行顺序 - function getCurrentOrder(root) { - var order = []; - var rows = root.querySelectorAll("tr.cbi-section-table-row"); - rows.forEach(function (tr) { - var id = tr.id || ""; - if (id.startsWith("cbi-<%=api.appname%>-")) - id = id.replace("cbi-<%=api.appname%>-", ""); - order.push(id); - }); - return order; - } - - // 拖拽完成后更新 hidden input - function updateHiddenInput(root, section) { - var newOrder = getCurrentOrder(root); - var changed = newOrder.join(" ") !== root._origOrder.join(" "); - var hiddenInput = section.querySelector('input[type="hidden"][id^="cbi.sts."]'); - if (hiddenInput) { - hiddenInput.value = changed ? newOrder.join(" ") : ""; - } - } - - // 隐藏18.06 up/down 列 - function hideSortColumn(section) { - var table = section.getElementsByTagName("table")[0]; - if(!table) return; - var rows = table.querySelectorAll("tr.cbi-section-table-row"); - if(!rows.length) return; - var colCount = rows[0].children.length, sortCol = -1; - for(var col=0; col= THRESHOLD) - setTimeout(initSortableForTable, 200); - else - requestAnimationFrame(tick); - } - tick(); - })(); - }); //]]> diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue_com.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue_com.htm index 9de708e5..0e8940ef 100644 --- a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue_com.htm +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue_com.htm @@ -403,7 +403,7 @@ function lv_expandGroupOfCurrent(cbid, listContainer, hiddenSelect) { const key = hiddenSelect.options[0].value; if (!key) return; - const targetLi = listContainer.querySelector("li[data-key='" + key.replace(/'/g,"\\'") + "']"); + const targetLi = listContainer.querySelector(`li[data-key='${CSS.escape(key)}']`); if (!targetLi) return; let parentGroup = targetLi.closest(".lv-group"); if (parentGroup) { diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value_com.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value_com.htm index 1f784d04..d470ea4b 100644 --- a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value_com.htm +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value_com.htm @@ -402,7 +402,7 @@ function v_expandGroupOfCurrent(cbid, listContainer, hiddenInput) { const key = hiddenInput.value; if (!key) return; - const targetLi = listContainer.querySelector("li[data-key='" + key.replace(/'/g,"\\'") + "']"); + const targetLi = listContainer.querySelector(`li[data-key='${CSS.escape(key)}']`); if (!targetLi) return; let parentGroup = targetLi.closest(".v-group"); if (parentGroup) {