startHeartbeat: function()
{
this._hearbeatInterval = window.setInterval(function() {
- _luci2.session.isAlive(function(alive) {
+ _luci2.session.isAlive().then(function(alive) {
if (!alive)
{
_luci2.session.stopHeartbeat();
stopHeartbeat: function()
{
if (typeof(this._hearbeatInterval) != 'undefined')
+ {
window.clearInterval(this._hearbeatInterval);
+ delete this._hearbeatInterval;
+ }
}
};
this.ui = {
+ saveScrollTop: function()
+ {
+ this._scroll_top = $(document).scrollTop();
+ },
+
+ restoreScrollTop: function()
+ {
+ if (typeof(this._scroll_top) == 'undefined')
+ return;
+
+ $(document).scrollTop(this._scroll_top);
+
+ delete this._scroll_top;
+ },
+
loading: function(enable)
{
var win = $(window);
_luci2.session.isAlive().then(function(access) {
if (access)
{
+ _luci2.session.startHeartbeat();
_luci2._login_deferred.resolve();
}
else
return _luci2._login_deferred;
},
+ cryptPassword: _luci2.rpc.declare({
+ object: 'luci2.ui',
+ method: 'crypt',
+ params: [ 'data' ],
+ expect: { crypt: '' }
+ }),
+
_acl_merge_scope: function(acl_scope, scope)
{
if (_luci2._views[name] instanceof _luci2.ui.view)
return _luci2._views[name].render();
- return $.ajax(_luci2.globals.resource + '/view/' + name + '.js', {
+ var url = _luci2.globals.resource + '/view/' + name + '.js';
+
+ return $.ajax(url, {
method: 'GET',
cache: true,
dataType: 'text'
}).then(function(data) {
try {
- var viewConstructor = (new Function(['L', '$'], 'return ' + data))(_luci2, $);
+ var viewConstructorSource = (
+ '(function(L, $) {\n' +
+ 'return %s' +
+ '})(_luci2, $);\n\n' +
+ '//@ sourceURL=%s'
+ ).format(data, url);
+
+ var viewConstructor = eval(viewConstructorSource);
_luci2._views[name] = new viewConstructor({
name: name,
return _luci2._views[name].render();
}
- catch(e) { };
+ catch(e) {
+ alert('Unable to instantiate view "%s": %s'.format(url, e));
+ };
return $.Deferred().resolve();
});
};
- var AbstractValue = AbstractWidget.extend({
+ this.cbi.AbstractValue = AbstractWidget.extend({
init: function(name, options)
{
this.name = name;
{
if (typeof(d[i]) == 'string')
dep[d[i]] = true;
- else if (d[i] instanceof AbstractValue)
+ else if (d[i] instanceof _luci2.cbi.AbstractValue)
dep[d[i].name] = true;
}
}
- else if (d instanceof AbstractValue)
+ else if (d instanceof _luci2.cbi.AbstractValue)
{
dep = { };
dep[d.name] = (typeof(v) == 'undefined') ? true : v;
}
});
- this.cbi.CheckboxValue = AbstractValue.extend({
+ this.cbi.CheckboxValue = this.cbi.AbstractValue.extend({
widget: function(sid)
{
var o = this.options;
}
});
- this.cbi.InputValue = AbstractValue.extend({
+ this.cbi.InputValue = this.cbi.AbstractValue.extend({
widget: function(sid)
{
var i = $('<input />')
}
});
- this.cbi.PasswordValue = AbstractValue.extend({
+ this.cbi.PasswordValue = this.cbi.AbstractValue.extend({
widget: function(sid)
{
var i = $('<input />')
}
});
- this.cbi.ListValue = AbstractValue.extend({
+ this.cbi.ListValue = this.cbi.AbstractValue.extend({
widget: function(sid)
{
var s = $('<select />');
}
});
- this.cbi.ComboBox = AbstractValue.extend({
+ this.cbi.ComboBox = this.cbi.AbstractValue.extend({
_change: function(ev)
{
var s = ev.target;
}
});
- this.cbi.DummyValue = AbstractValue.extend({
+ this.cbi.DummyValue = this.cbi.AbstractValue.extend({
widget: function(sid)
{
return $('<div />')
}
});
- this.cbi.NetworkList = AbstractValue.extend({
+ this.cbi.NetworkList = this.cbi.AbstractValue.extend({
load: function(sid)
{
var self = this;
if (!self.interfaces)
{
self.interfaces = [ ];
- return _luci2.network.getNetworkStatus(function(ifaces) {
+ return _luci2.network.getNetworkStatus().then(function(ifaces) {
self.interfaces = ifaces;
self = null;
});
type = 'wifi';
desc = _luci2.tr('Wireless Network');
}
- else if (dev.name.indexOf('.') > 0)
+ else if (dev.device.indexOf('.') > 0)
{
type = 'vlan';
desc = _luci2.tr('VLAN interface');
return $('<img />')
.attr('src', _luci2.globals.resource + '/icons/' + type + (dev.up ? '' : '_disabled') + '.png')
- .attr('title', '%s (%s)'.format(desc, dev.name));
+ .attr('title', '%s (%s)'.format(desc, dev.device));
},
widget: function(sid)
var iface = this.interfaces[i];
var badge = $('<span />')
.addClass('ifacebadge')
- .text('%s: '.format(iface.name));
+ .text('%s: '.format(iface['interface']));
- if (iface.subdevices)
- for (var j = 0; j < iface.subdevices.length; j++)
- badge.append(this._device_icon(iface.subdevices[j]));
+ if (iface.device && iface.device.subdevices)
+ for (var j = 0; j < iface.device.subdevices.length; j++)
+ badge.append(this._device_icon(iface.device.subdevices[j]));
else if (iface.device)
badge.append(this._device_icon(iface.device));
else
.append($('<input />')
.attr('name', itype + id)
.attr('type', itype)
- .attr('value', iface.name)
- .prop('checked', !!check[iface.name])
+ .attr('value', iface['interface'])
+ .prop('checked', !!check[iface['interface']])
.addClass('cbi-input-' + itype))
.append(badge))
.appendTo(ul);
});
- var AbstractSection = AbstractWidget.extend({
+ this.cbi.AbstractSection = AbstractWidget.extend({
id: function()
{
var s = [ arguments[0], this.map.uci_package, this.uci_type ];
var w = widget ? new widget(name, options) : null;
- if (!(w instanceof AbstractValue))
+ if (!(w instanceof _luci2.cbi.AbstractValue))
throw 'Widget must be an instance of AbstractValue';
w.section = this;
}
});
- this.cbi.TypedSection = AbstractSection.extend({
+ this.cbi.TypedSection = this.cbi.AbstractSection.extend({
init: function(uci_type, options)
{
this.uci_type = uci_type;
if (addb.prop('disabled') || name === '')
return;
+ _luci2.ui.saveScrollTop();
+
self.active_panel = -1;
self.map.save();
self.add(name);
self.map.redraw();
+
+ _luci2.ui.restoreScrollTop();
},
_remove: function(ev)
var self = ev.data.self;
var sid = ev.data.sid;
+ if (ev.data.index == (self.sections().length - 1))
+ self.active_panel = -1;
+
+ _luci2.ui.saveScrollTop();
+
self.map.save();
self.remove(sid);
self.map.redraw();
+ _luci2.ui.restoreScrollTop();
+
ev.stopPropagation();
},
for (var i = 0; i < this.options.teasers.length; i++)
{
var f = this.options.teasers[i];
- if (f instanceof AbstractValue)
+ if (f instanceof _luci2.cbi.AbstractValue)
tf.push(f);
- else if (typeof(f) == 'string' && this.fields[f] instanceof AbstractValue)
+ else if (typeof(f) == 'string' && this.fields[f] instanceof _luci2.cbi.AbstractValue)
tf.push(this.fields[f]);
}
}
return add;
},
- _render_remove: function(sid)
+ _render_remove: function(sid, index)
{
var text = _luci2.tr('Remove');
var ttip = _luci2.tr('Remove this section');
.addClass('cbi-button')
.addClass('cbi-button-remove')
.val(text).attr('title', ttip)
- .click({ self: this, sid: sid }, this._remove);
+ .click({ self: this, sid: sid, index: index }, this._remove);
},
_render_caption: function(sid)
$('<div />')
.addClass('cbi-section-remove')
.addClass('right')
- .append(this._render_remove(sid))
+ .append(this._render_remove(sid, panel_index))
.appendTo(head);
var body = $('<div />')
deletes: { }
};
- this.active_panel = 0;
+ if (typeof(this.active_panel) == 'undefined')
+ this.active_panel = 0;
var packages = { };
{
var w = widget ? new widget(uci_type, options) : null;
- if (!(w instanceof AbstractSection))
+ if (!(w instanceof _luci2.cbi.AbstractSection))
throw 'Widget must be an instance of AbstractSection';
w.map = this;
for (var k in this.uci.creates[c][s])
{
if (k == '.type')
- r.type = this.uci.creates[i][k];
+ r.type = this.uci.creates[c][s][k];
else if (k == '.create')
- r.name = this.uci.creates[i][k];
+ r.name = this.uci.creates[c][s][k];
else if (k.charAt(0) != '.')
- r.values[k] = this.uci.creates[i][k];
+ r.values[k] = this.uci.creates[c][s][k];
}
_luci2.uci.add(r.config, r.type, r.name, r.values);
var self = this;
+ _luci2.ui.saveScrollTop();
_luci2.ui.loading(true);
return this.save().then(send_cb).then(function() {
self = null;
_luci2.ui.loading(false);
+ _luci2.ui.restoreScrollTop();
});
},