OSDN Git Service

luci-base: form.js: handle SectionValue objects in GridSection modals
authorJo-Philipp Wich <jo@mein.io>
Mon, 16 May 2022 09:55:11 +0000 (11:55 +0200)
committerJo-Philipp Wich <jo@mein.io>
Mon, 16 May 2022 11:40:49 +0000 (13:40 +0200)
The existing logic for cloning section options into the modal form section
container did not properly handle SectionValue objects. Introduce a new
`cloneOptions()` helper to recursively traverse and properly clowning
such nested sections.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/htdocs/luci-static/resources/form.js

index 6786d3d..3b2e89e 100644 (file)
@@ -3150,34 +3150,38 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
        },
 
        /** @private */
-       renderMoreOptionsModal: function(section_id, ev) {
-               var parent = this.map,
-                   title = parent.title,
-                   name = null,
-                   m = new CBIMap(this.map.config, null, null),
-                   s = m.section(CBINamedSection, section_id, this.sectiontype);
+       cloneOptions: function(src_section, dest_section) {
+               for (var i = 0; i < src_section.children.length; i++) {
+                       var o1 = src_section.children[i];
 
-               m.parent = parent;
-               m.section = section_id;
-               m.readonly = parent.readonly;
+                       if (o1.modalonly === false && src_section === this)
+                               continue;
 
-               s.tabs = this.tabs;
-               s.tab_names = this.tab_names;
+                       var o2;
 
-               if ((name = this.titleFn('modaltitle', section_id)) != null)
-                       title = name;
-               else if ((name = this.titleFn('sectiontitle', section_id)) != null)
-                       title = '%s - %s'.format(parent.title, name);
-               else if (!this.anonymous)
-                       title = '%s - %s'.format(parent.title, section_id);
+                       if (o1.subsection) {
+                               o2 = dest_section.option(o1.constructor, o1.option, o1.subsection.constructor, o1.subsection.sectiontype, o1.subsection.title, o1.subsection.description);
 
-               for (var i = 0; i < this.children.length; i++) {
-                       var o1 = this.children[i];
+                               for (var k in o1.subsection) {
+                                       if (!o1.subsection.hasOwnProperty(k))
+                                               continue;
 
-                       if (o1.modalonly === false)
-                               continue;
+                                       switch (k) {
+                                       case 'map':
+                                       case 'children':
+                                       case 'parentoption':
+                                               continue;
 
-                       var o2 = s.option(o1.constructor, o1.option, o1.title, o1.description);
+                                       default:
+                                               o2.subsection[k] = o1.subsection[k];
+                                       }
+                               }
+
+                               this.cloneOptions(o1.subsection, o2.subsection);
+                       }
+                       else {
+                               o2 = dest_section.option(o1.constructor, o1.option, o1.title, o1.description);
+                       }
 
                        for (var k in o1) {
                                if (!o1.hasOwnProperty(k))
@@ -3189,6 +3193,7 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
                                case 'option':
                                case 'title':
                                case 'description':
+                               case 'subsection':
                                        continue;
 
                                default:
@@ -3196,6 +3201,31 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
                                }
                        }
                }
+       },
+
+       /** @private */
+       renderMoreOptionsModal: function(section_id, ev) {
+               var parent = this.map,
+                   title = parent.title,
+                   name = null,
+                   m = new CBIMap(this.map.config, null, null),
+                   s = m.section(CBINamedSection, section_id, this.sectiontype);
+
+               m.parent = parent;
+               m.section = section_id;
+               m.readonly = parent.readonly;
+
+               s.tabs = this.tabs;
+               s.tab_names = this.tab_names;
+
+               if ((name = this.titleFn('modaltitle', section_id)) != null)
+                       title = name;
+               else if ((name = this.titleFn('sectiontitle', section_id)) != null)
+                       title = '%s - %s'.format(parent.title, name);
+               else if (!this.anonymous)
+                       title = '%s - %s'.format(parent.title, section_id);
+
+               this.cloneOptions(this, s);
 
                return Promise.resolve(this.addModalOptions(s, section_id, ev)).then(L.bind(m.render, m)).then(L.bind(function(nodes) {
                        var mapNode = this.getActiveModalMap(),