From: Paul Donald Date: Thu, 29 Jan 2026 18:02:12 +0000 (+0100) Subject: luci-base: fix tab handling in modal dialogues X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=9a07b1b79d1ecbd119d13f4d231f7b4d5a3cfa2f;p=openwrt-luci.git luci-base: fix tab handling in modal dialogues When adding tabs in modal dialogues, the old code of simply assigning s.tabs = this.tabs was problematic because it was an array of objects whose behaviour would cause a traceback when s.tab is called in e.g. a protocol handler Modal when it was reopened. Now verify the properties do not already exist before assigning them. This means one can define s.tab(...) in a Modal UI without a try block (which would even then sometimes fail). Signed-off-by: Paul Donald --- diff --git a/modules/luci-base/htdocs/luci-static/resources/form.js b/modules/luci-base/htdocs/luci-static/resources/form.js index ae55480d78..c6e84e94e4 100644 --- a/modules/luci-base/htdocs/luci-static/resources/form.js +++ b/modules/luci-base/htdocs/luci-static/resources/form.js @@ -3339,8 +3339,26 @@ const CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection m.section = section_id; m.readonly = parent.readonly; - s.tabs = this.tabs; - s.tab_names = this.tab_names; + /* Clone tabs as both array and object. Otherwise calling renderMoreOptionsModal (reopening + the same Modal multiple times) results in errors when s.tab is called in the modal. This + allows Modal dialogues that declare new tabs to be opened multiple times without re-creating + tabs that 'already exist'. */ + if (this.tabs) { + s.tabs = Array.from(this.tabs); + for (const key in this.tabs) { + if (Object.prototype.hasOwnProperty.call(this.tabs, key) && isNaN(Number(key))) { + s.tabs[key] = this.tabs[key]; + } + } + } else { + s.tabs = undefined; + } + + if (this.tab_names) { + s.tab_names = Array.isArray(this.tab_names) ? this.tab_names.slice() : Object.assign({}, this.tab_names); + } else { + s.tab_names = undefined; + } this.cloneOptions(this, s);