Merge pull request #1502 from dibdot/adblock
[project/luci.git] / modules / luci-base / luasrc / cbi.lua
index 2f97539..2184395 100644 (file)
@@ -262,6 +262,7 @@ function Node.render_children(self, ...)
        local k, node
        for k, node in ipairs(self.children) do
                node.last_child = (k == #self.children)
+               node.index = k
                node:render(...)
        end
 end
@@ -385,41 +386,45 @@ function Map.parse(self, readinput, ...)
 
        Node.parse(self, ...)
 
-       self:_run_hooks("on_save", "on_before_save")
-       for i, config in ipairs(self.parsechain) do
-               self.uci:save(config)
-       end
-       self:_run_hooks("on_after_save")
-       if (not self.proceed and self.flow.autoapply) or luci.http.formvalue("cbi.apply") then
-               self:_run_hooks("on_before_commit")
+       if self.save then
+               self:_run_hooks("on_save", "on_before_save")
                for i, config in ipairs(self.parsechain) do
-                       self.uci:commit(config)
+                       self.uci:save(config)
+               end
+               self:_run_hooks("on_after_save")
+               if (not self.proceed and self.flow.autoapply) or luci.http.formvalue("cbi.apply") then
+                       self:_run_hooks("on_before_commit")
+                       for i, config in ipairs(self.parsechain) do
+                               self.uci:commit(config)
+
+                               -- Refresh data because commit changes section names
+                               self.uci:load(config)
+                       end
+                       self:_run_hooks("on_commit", "on_after_commit", "on_before_apply")
+                       if self.apply_on_parse then
+                               self.uci:apply(self.parsechain)
+                               self:_run_hooks("on_apply", "on_after_apply")
+                       else
+                               -- This is evaluated by the dispatcher and delegated to the
+                               -- template which in turn fires XHR to perform the actual
+                               -- apply actions.
+                               self.apply_needed = true
+                       end
 
-                       -- Refresh data because commit changes section names
-                       self.uci:load(config)
+                       -- Reparse sections
+                       Node.parse(self, true)
                end
-               self:_run_hooks("on_commit", "on_after_commit", "on_before_apply")
-               if self.apply_on_parse then
-                       self.uci:apply(self.parsechain)
-                       self:_run_hooks("on_apply", "on_after_apply")
-               else
-                       -- This is evaluated by the dispatcher and delegated to the
-                       -- template which in turn fires XHR to perform the actual
-                       -- apply actions.
-                       self.apply_needed = true
+               for i, config in ipairs(self.parsechain) do
+                       self.uci:unload(config)
+               end
+               if type(self.commit_handler) == "function" then
+                       self:commit_handler(self:submitstate())
                end
-
-               -- Reparse sections
-               Node.parse(self, true)
-       end
-       for i, config in ipairs(self.parsechain) do
-               self.uci:unload(config)
-       end
-       if type(self.commit_handler) == "function" then
-               self:commit_handler(self:submitstate())
        end
 
-       if self.proceed then
+       if not self.save then
+               self.state = FORM_INVALID
+       elseif self.proceed then
                self.state = FORM_PROCEED
        elseif self.changed then
                self.state = FORM_CHANGED
@@ -881,6 +886,7 @@ function AbstractSection.render_tab(self, tab, ...)
        local k, node
        for k, node in ipairs(self.tabs[tab].childs) do
                node.last_child = (k == #self.tabs[tab].childs)
+               node.index = k
                node:render(...)
        end
 end
@@ -1290,7 +1296,6 @@ function AbstractValue.__init__(self, map, section, option, ...)
        self.tag_reqerror = {}
        self.tag_error = {}
        self.deps = {}
-       self.subdeps = {}
        --self.cast = "string"
 
        self.track_missing = false
@@ -1314,7 +1319,30 @@ function AbstractValue.depends(self, field, value)
                deps = field
        end
 
-       table.insert(self.deps, {deps=deps, add=""})
+       table.insert(self.deps, deps)
+end
+
+-- Serialize dependencies
+function AbstractValue.deplist2json(self, section, deplist)
+       local deps, i, d = { }
+
+       if type(self.deps) == "table" then
+               for i, d in ipairs(deplist or self.deps) do
+                       local a, k, v = { }
+                       for k, v in pairs(d) do
+                               if k:find("!", 1, true) then
+                                       a[k] = v
+                               elseif k:find(".", 1, true) then
+                                       a['cbid.%s' % k] = v
+                               else
+                                       a['cbid.%s.%s.%s' %{ self.config, section, k }] = v
+                               end
+                       end
+                       deps[#deps+1] = a
+               end
+       end
+
+       return util.serialize_json(deps)
 end
 
 -- Generates the unique CBID
@@ -1595,15 +1623,16 @@ function ListValue.__init__(self, ...)
        AbstractValue.__init__(self, ...)
        self.template  = "cbi/lvalue"
 
-       self.keylist = {}
-       self.vallist = {}
        self.size   = 1
        self.widget = "select"
+
+       self:reset_values()
 end
 
 function ListValue.reset_values(self)
        self.keylist = {}
        self.vallist = {}
+       self.deplist = {}
 end
 
 function ListValue.value(self, key, val, ...)
@@ -1614,10 +1643,7 @@ function ListValue.value(self, key, val, ...)
        val = val or key
        table.insert(self.keylist, tostring(key))
        table.insert(self.vallist, tostring(val))
-
-       for i, deps in ipairs({...}) do
-               self.subdeps[#self.subdeps + 1] = {add = "-"..key, deps=deps}
-       end
+       table.insert(self.deplist, {...})
 end
 
 function ListValue.validate(self, val)
@@ -1641,11 +1667,10 @@ function MultiValue.__init__(self, ...)
        AbstractValue.__init__(self, ...)
        self.template = "cbi/mvalue"
 
-       self.keylist = {}
-       self.vallist = {}
-
        self.widget = "checkbox"
        self.delimiter = " "
+
+       self:reset_values()
 end
 
 function MultiValue.render(self, ...)
@@ -1659,6 +1684,7 @@ end
 function MultiValue.reset_values(self)
        self.keylist = {}
        self.vallist = {}
+       self.deplist = {}
 end
 
 function MultiValue.value(self, key, val)
@@ -1733,8 +1759,7 @@ function DynamicList.__init__(self, ...)
        AbstractValue.__init__(self, ...)
        self.template  = "cbi/dynlist"
        self.cast = "table"
-       self.keylist = {}
-       self.vallist = {}
+       self:reset_values()
 end
 
 function DynamicList.reset_values(self)