10 else if (Array.isArray(x))
12 else if (typeof(x) == 'object')
15 var s = String(x).trim();
20 return s.split(/\s+/);
23 var CBIZoneSelect = form.ListValue.extend({
24 __name__: 'CBI.ZoneSelect',
26 load: function(section_id) {
27 return Promise.all([ firewall.getZones(), network.getNetworks() ]).then(L.bind(function(zn) {
29 this.networks = zn[1];
31 return this.super('load', section_id);
35 filter: function(section_id, value) {
39 lookupZone: function(name) {
40 return this.zones.filter(function(zone) { return zone.getName() == name })[0];
43 lookupNetwork: function(name) {
44 return this.networks.filter(function(network) { return network.getName() == name })[0];
47 renderWidget: function(section_id, option_index, cfgvalue) {
48 var values = toArray((cfgvalue != null) ? cfgvalue : this.default),
51 if (this.allowlocal) {
52 choices[''] = E('span', {
54 'style': 'background-color:' + firewall.getColorForName(null)
56 E('strong', _('Device')),
57 (this.allowany || this.allowlocal)
58 ? ' (%s)'.format(this.alias != 'dest' ? _('output') : _('input')) : ''
61 else if (!this.multiple && (this.rmempty || this.optional)) {
62 choices[''] = E('span', {
64 'style': 'background-color:' + firewall.getColorForName(null)
65 }, E('em', _('unspecified')));
69 choices['*'] = E('span', {
71 'style': 'background-color:' + firewall.getColorForName(null)
73 E('strong', _('Any zone')),
74 (this.allowany && this.allowlocal) ? ' (%s)'.format(_('forward')) : ''
78 for (var i = 0; i < this.zones.length; i++) {
79 var zone = this.zones[i],
80 name = zone.getName(),
81 networks = zone.getNetworks(),
84 if (!this.filter(section_id, name))
87 for (var j = 0; j < networks.length; j++) {
88 var network = this.lookupNetwork(networks[j]);
93 var span = E('span', {
94 'class': 'ifacebadge' + (network.getName() == this.network ? ' ifacebadge-active' : '')
95 }, network.getName() + ': ');
97 var devices = network.isBridge() ? network.getDevices() : toArray(network.getDevice());
99 for (var k = 0; k < devices.length; k++) {
100 span.appendChild(E('img', {
101 'title': devices[k].getI18n(),
102 'src': L.resource('icons/%s%s.png'.format(devices[k].getType(), devices[k].isUp() ? '' : '_disabled'))
107 span.appendChild(E('em', _('(empty)')));
113 ifaces.push(E('em', _('(empty)')));
115 choices[name] = E('span', {
116 'class': 'zonebadge',
117 'style': 'background-color:' + zone.getColor()
118 }, [ E('strong', name) ].concat(ifaces));
121 var widget = new ui.Dropdown(values, choices, {
122 id: this.cbid(section_id),
124 multiple: this.multiple,
125 optional: this.optional || this.rmempty,
126 select_placeholder: E('em', _('unspecified')),
127 display_items: this.display_size || this.size || 3,
128 dropdown_items: this.dropdown_size || this.size || 5,
129 validate: L.bind(this.validate, this, section_id),
130 create: !this.nocreate,
132 '<li data-value="{{value}}">' +
133 '<span class="zonebadge" style="background:repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px)">' +
134 '<strong>{{value}}:</strong> <em>('+_('create')+')</em>' +
139 return widget.render();
143 var CBIZoneForwards = form.DummyValue.extend({
144 __name__: 'CBI.ZoneForwards',
146 load: function(section_id) {
147 return Promise.all([ firewall.getDefaults(), firewall.getZones(), network.getNetworks() ]).then(L.bind(function(dzn) {
148 this.defaults = dzn[0];
150 this.networks = dzn[2];
152 return this.super('load', section_id);
156 renderZone: function(zone) {
157 var name = zone.getName(),
158 networks = zone.getNetworks(),
161 for (var j = 0; j < networks.length; j++) {
162 var network = this.networks.filter(function(net) { return net.getName() == networks[j] })[0];
167 var span = E('span', {
168 'class': 'ifacebadge' + (network.getName() == this.network ? ' ifacebadge-active' : '')
169 }, network.getName() + ': ');
171 var devices = network.isBridge() ? network.getDevices() : toArray(network.getDevice());
173 for (var k = 0; k < devices.length && devices[k]; k++) {
174 span.appendChild(E('img', {
175 'title': devices[k].getI18n(),
176 'src': L.resource('icons/%s%s.png'.format(devices[k].getType(), devices[k].isUp() ? '' : '_disabled'))
181 span.appendChild(E('em', _('(empty)')));
187 ifaces.push(E('span', { 'class': 'ifacebadge' }, E('em', _('(empty)'))));
190 'class': 'zonebadge cbi-tooltip-container',
191 'style': 'background-color:' + zone.getColor()
194 E('div', { 'class': 'cbi-tooltip' }, ifaces)
198 renderWidget: function(section_id, option_index, cfgvalue) {
199 var value = (cfgvalue != null) ? cfgvalue : this.default,
200 zone = this.zones.filter(function(z) { return z.getName() == value })[0];
205 var forwards = zone.getForwardingsBy('src'),
208 for (var i = 0; i < forwards.length; i++) {
209 var dzone = forwards[i].getDestinationZone();
214 dzones.push(this.renderZone(dzone));
218 dzones.push(E('label', { 'class': 'zonebadge zonebadge-empty' },
219 E('strong', this.defaults.getForward())));
221 return E('div', { 'class': 'zone-forwards' }, [
222 E('div', { 'class': 'zone-src' }, this.renderZone(zone)),
224 E('div', { 'class': 'zone-dest' }, dzones)
229 var CBINetworkSelect = form.ListValue.extend({
230 __name__: 'CBI.NetworkSelect',
232 load: function(section_id) {
233 return network.getNetworks().then(L.bind(function(networks) {
234 this.networks = networks;
236 return this.super('load', section_id);
240 filter: function(section_id, value) {
244 renderWidget: function(section_id, option_index, cfgvalue) {
245 var values = toArray((cfgvalue != null) ? cfgvalue : this.default),
249 for (var i = 0; i < values.length; i++)
250 checked[values[i]] = true;
254 if (!this.multiple && (this.rmempty || this.optional))
255 choices[''] = E('em', _('unspecified'));
257 for (var i = 0; i < this.networks.length; i++) {
258 var network = this.networks[i],
259 name = network.getName();
261 if (name == 'loopback' || !this.filter(section_id, name))
264 if (this.novirtual && network.isVirtual())
267 var span = E('span', { 'class': 'ifacebadge' }, network.getName() + ': '),
268 devices = network.isBridge() ? network.getDevices() : toArray(network.getDevice());
270 for (var j = 0; j < devices.length && devices[j]; j++) {
271 span.appendChild(E('img', {
272 'title': devices[j].getI18n(),
273 'src': L.resource('icons/%s%s.png'.format(devices[j].getType(), devices[j].isUp() ? '' : '_disabled'))
277 if (!devices.length) {
278 span.appendChild(E('em', { 'class': 'hide-close' }, _('(no interfaces attached)')));
279 span.appendChild(E('em', { 'class': 'hide-open' }, '-'));
285 choices[name] = span;
288 var widget = new ui.Dropdown(this.multiple ? values : values[0], choices, {
289 id: this.cbid(section_id),
291 multiple: this.multiple,
292 optional: this.optional || this.rmempty,
293 select_placeholder: E('em', _('unspecified')),
294 display_items: this.display_size || this.size || 3,
295 dropdown_items: this.dropdown_size || this.size || 5,
296 validate: L.bind(this.validate, this, section_id),
297 create: !this.nocreate,
299 '<li data-value="{{value}}">' +
300 '<span class="ifacebadge" style="background:repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px)">' +
301 '{{value}}: <em>('+_('create')+')</em>' +
306 return widget.render();
311 return L.Class.extend({
312 ZoneSelect: CBIZoneSelect,
313 ZoneForwards: CBIZoneForwards,
314 NetworkSelect: CBINetworkSelect