luci2: add AbstractWidget.appendTo() to support appending widgets to a container
[project/luci2/ui.git] / luci2 / htdocs / luci2 / luci2.js
index 2bf73c8..291af57 100644 (file)
@@ -387,7 +387,7 @@ function LuCI2()
        };
 
        this.globals = {
-               timeout:  3000,
+               timeout:  15000,
                resource: '/luci2',
                sid:      '00000000000000000000000000000000'
        };
@@ -977,6 +977,57 @@ function LuCI2()
                        method: 'switch_status',
                        params: [ 'switch' ],
                        expect: { ports: [ ] }
+               }),
+
+
+               runPing: _luci2.rpc.declare({
+                       object: 'luci2.network',
+                       method: 'ping',
+                       params: [ 'data' ],
+                       expect: { '': { code: -1 } }
+               }),
+
+               runPing6: _luci2.rpc.declare({
+                       object: 'luci2.network',
+                       method: 'ping6',
+                       params: [ 'data' ],
+                       expect: { '': { code: -1 } }
+               }),
+
+               runTraceroute: _luci2.rpc.declare({
+                       object: 'luci2.network',
+                       method: 'traceroute',
+                       params: [ 'data' ],
+                       expect: { '': { code: -1 } }
+               }),
+
+               runTraceroute6: _luci2.rpc.declare({
+                       object: 'luci2.network',
+                       method: 'traceroute6',
+                       params: [ 'data' ],
+                       expect: { '': { code: -1 } }
+               }),
+
+               runNslookup: _luci2.rpc.declare({
+                       object: 'luci2.network',
+                       method: 'nslookup',
+                       params: [ 'data' ],
+                       expect: { '': { code: -1 } }
+               }),
+
+
+               setUp: _luci2.rpc.declare({
+                       object: 'luci2.network',
+                       method: 'ifup',
+                       params: [ 'data' ],
+                       expect: { '': { code: -1 } }
+               }),
+
+               setDown: _luci2.rpc.declare({
+                       object: 'luci2.network',
+                       method: 'ifdown',
+                       params: [ 'data' ],
+                       expect: { '': { code: -1 } }
                })
        };
 
@@ -1137,6 +1188,57 @@ function LuCI2()
                }
        };
 
+       this.firewall = {
+               getZoneColor: function(zone)
+               {
+                       if ($.isPlainObject(zone))
+                               zone = zone.name;
+
+                       if (zone == 'lan')
+                               return '#90f090';
+                       else if (zone == 'wan')
+                               return '#f09090';
+
+                       for (var i = 0, hash = 0;
+                                i < zone.length;
+                                hash = zone.charCodeAt(i++) + ((hash << 5) - hash));
+
+                       for (var i = 0, color = '#';
+                                i < 3;
+                                color += ('00' + ((hash >> i++ * 8) & 0xFF).tozoneing(16)).slice(-2));
+
+                       return color;
+               },
+
+               findZoneByNetwork: function(network)
+               {
+                       var self = this;
+                       var zone = undefined;
+
+                       return _luci2.uci.foreach('firewall', 'zone', function(z) {
+                               if (!z.name || !z.network)
+                                       return;
+
+                               if (!$.isArray(z.network))
+                                       z.network = z.network.split(/\s+/);
+
+                               for (var i = 0; i < z.network.length; i++)
+                               {
+                                       if (z.network[i] == network)
+                                       {
+                                               zone = z;
+                                               break;
+                                       }
+                               }
+                       }).then(function() {
+                               if (zone)
+                                       zone.color = self.getZoneColor(zone);
+
+                               return zone;
+                       });
+               }
+       };
+
        this.system = {
                getSystemInfo: _luci2.rpc.declare({
                        object: 'system',
@@ -2064,9 +2166,17 @@ function LuCI2()
                                .append(_luci2.globals.mainMenu.render(2, 900));
                },
 
-               renderView: function(node)
+               renderView: function()
                {
+                       var node = arguments[0];
                        var name = node.view.split(/\//).join('.');
+                       var args = [ ];
+
+                       for (var i = 1; i < arguments.length; i++)
+                               args.push(arguments[i]);
+
+                       if (_luci2.globals.currentView)
+                               _luci2.globals.currentView.finish();
 
                        _luci2.ui.renderViewMenu();
 
@@ -2076,7 +2186,10 @@ function LuCI2()
                        _luci2.setHash('view', node.view);
 
                        if (_luci2._views[name] instanceof _luci2.ui.view)
-                               return _luci2._views[name].render();
+                       {
+                               _luci2.globals.currentView = _luci2._views[name];
+                               return _luci2._views[name].render.apply(_luci2._views[name], args);
+                       }
 
                        var url = _luci2.globals.resource + '/view/' + name + '.js';
 
@@ -2100,7 +2213,8 @@ function LuCI2()
                                                acls: node.write || { }
                                        });
 
-                                       return _luci2._views[name].render();
+                                       _luci2.globals.currentView = _luci2._views[name];
+                                       return _luci2._views[name].render.apply(_luci2._views[name], args);
                                }
                                catch(e) {
                                        alert('Unable to instantiate view "%s": %s'.format(url, e));
@@ -2225,6 +2339,10 @@ function LuCI2()
 
                insertInto: function(id) {
                        return $(id).empty().append(this.render());
+               },
+
+               appendTo: function(id) {
+                       return $(id).append(this.render());
                }
        });
 
@@ -2277,9 +2395,50 @@ function LuCI2()
                                container.append($('<div />').addClass('cbi-map-descr').append(this.description));
 
                        var self = this;
+                       var args = [ ];
+
+                       for (var i = 0; i < arguments.length; i++)
+                               args.push(arguments[i]);
+
                        return this._fetch_template().then(function() {
-                               return _luci2.deferrable(self.execute());
+                               return _luci2.deferrable(self.execute.apply(self, args));
                        });
+               },
+
+               repeat: function(func, interval)
+               {
+                       var self = this;
+
+                       if (!self._timeouts)
+                               self._timeouts = [ ];
+
+                       var index = self._timeouts.length;
+
+                       if (typeof(interval) != 'number')
+                               interval = 5000;
+
+                       var setTimer, runTimer;
+
+                       setTimer = function() {
+                               self._timeouts[index] = window.setTimeout(runTimer, interval);
+                       };
+
+                       runTimer = function() {
+                               _luci2.deferrable(func.call(self)).then(setTimer);
+                       };
+
+                       runTimer();
+               },
+
+               finish: function()
+               {
+                       if ($.isArray(this._timeouts))
+                       {
+                               for (var i = 0; i < this._timeouts.length; i++)
+                                       window.clearTimeout(this._timeouts[i]);
+
+                               delete this._timeouts;
+                       }
                }
        });
 
@@ -2621,7 +2780,9 @@ function LuCI2()
        this.ui.devicebadge = AbstractWidget.extend({
                render: function()
                {
-                       var dev = this.options.l3_device || this.options.device || '?';
+                       var l2dev = this.options.l2_device || this.options.device;
+                       var l3dev = this.options.l3_device;
+                       var dev = l3dev || l2dev || '?';
 
                        var span = document.createElement('span');
                                span.className = 'ifacebadge';
@@ -2662,7 +2823,7 @@ function LuCI2()
                                var type = 'ethernet';
                                var desc = _luci2.tr('Ethernet device');
 
-                               if (this.options.l3_device != this.options.device)
+                               if (l3dev != l2dev)
                                {
                                        type = 'tunnel';
                                        desc = _luci2.tr('Tunnel interface');
@@ -2912,6 +3073,7 @@ function LuCI2()
                                }
                        }
 
+                       validation.i18n('Must be a valid IPv6 address');
                        return false;
                },
 
@@ -5561,33 +5723,6 @@ function LuCI2()
                        });
                },
 
-               dialog: function(id)
-               {
-                       var d = $('<div />');
-                       var p = $('<p />');
-
-                       $('<img />')
-                               .attr('src', _luci2.globals.resource + '/icons/loading.gif')
-                               .css('vertical-align', 'middle')
-                               .css('padding-right', '10px')
-                               .appendTo(p);
-
-                       p.append(_luci2.tr('Loading data...'));
-
-                       p.appendTo(d);
-                       d.appendTo(id);
-
-                       return d.dialog({
-                               modal: true,
-                               draggable: false,
-                               resizable: false,
-                               height: 90,
-                               open: function() {
-                                       $(this).parent().children('.ui-dialog-titlebar').hide();
-                               }
-                       });
-               },
-
                insertInto: function(id)
                {
                        var self = this;