diff --git a/l3config.js b/l3config.js index e6a8b92..9988e05 100644 --- a/l3config.js +++ b/l3config.js @@ -1,5 +1,27 @@ "use strict"; +function makeTag(tag, attrs, ...children) { + let ret = document.createElement(tag); + for (const [attr, value] of Object.entries(attrs)) { + ret.setAttribute(attr, value); + } + children.forEach((child) => ret.append(child)); + return ret; +} + +function makeTagFunc(tag) { + return (attrs, ...children) => makeTag(tag, attrs, ...children); +} + +const table = makeTagFunc('table'); +const thead = makeTagFunc('thead'); +const tbody = makeTagFunc('tbody'); +const tr = makeTagFunc('tr'); +const th = makeTagFunc('th'); +const td = makeTagFunc('td'); + +const button = makeTagFunc('button'); + function makeFieldset() { return document.createElement('fieldset'); } @@ -37,6 +59,21 @@ function makeLabel(label, forId) { return ret; } +function makeTableEntry(tagName, entry) { + let ret = document.createElement(tagName); + ret.append(entry); + return ret; +} +function makeTableRow(tagName, ...columns) { + let row = document.createElement('tr'); + + for (const column of columns) { + row.appendChild(makeTableEntry(tagName, column)); + } + + return row; +} + class L3Section { constructor(legend, presetname, ...inputs) { this.legend = legend; @@ -239,6 +276,77 @@ class L3Select { } } +class L3MultiStateButton { + constructor(...states) { + this.states = states; + this.button = undefined; + } + node() { + this.button = document.createElement('button'); + this.button.setAttribute('type', 'button'); + this.button.addEventListener('click', () => this.#nextState()); + this.#nextState(); + return this.button; + } + #nextState() { + const cur = this.button.value || this.states.length - 1; + const next = (cur + 1) % this.states.length; + this.button.value = next; + this.button.replaceChildren(makeText(this.states[next])); + } + option() { + return undefined; + } +} + +class L3PortMapping { + constructor(...interfaces) { + this.interfaces = interfaces; + this.vlans = []; + } + +} + +class L3Table { + constructor(columns, template) { + this.columns = columns; + this.template = template; + this.inputs = []; + this.ninputs = 0; + } + node() { + let tablebody = tbody({}); + + return table({}, + thead({}, + tr({}, makeButton("+", () => tablebody.appendChild(this.#makeRow())), ...this.columns), + ), + tablebody, + ); + + } + #makeRow() { + let delbutton = button({type: 'button', 'class': 'del'}, "-"); + + const idsuffix = `-${this.ninputs++}`; + let newinputs = this.template(idsuffix); + let row = tr({}, + td({}, delbutton), + ...newinputs.map((newinput) => td({}, newinput)), + ); + delbutton.addEventListener('click', () => this.#removeInput(newinputs, row)); + + return row; + } + #removeInput(del, row) { + this.inputs = this.inputs.filter(input => input != del); + row.remove(); + } + option() { + return this.inputs.map(input => input.option()); + } +} + class L3MultiInput { constructor(label, template) { this.label = label; @@ -317,6 +425,7 @@ function initForm() { return new L3Input(undefined,'gatewayRouterIP6'+idsuffix, 'router_ip6', {type: 'text', maxlength: 39, placeholder: 'Router IPv6 Address'}); }), new L3Input(undefined, 'gatewayConfigVersion', 'config_version', {type: 'hidden', value: 2, disabled: ''}), + new L3MultiStateButton('-', 'U', 'T'), )); l3cfg.addSection(new L3Section('dns', undefined, new L3Select('Preset','dnsAnycastSelect', 'server', {name: 'anycast'}, @@ -359,6 +468,15 @@ function initForm() { ['U-NII-2 Channels (Indoor + DFS)', UNII2Channels], ['U-NII-2E Channels (Indoor + Outdoor + DFS)', UNII2EChannels], ), + + )); + l3cfg.addSection(new L3Section('VLAN (test)', undefined, + new L3Table(["VLAN", "Comment"], function(idsuffix) { + return [ + makeInput('vlan'+idsuffix, {type: 'number', min: 1, max: 4094, required: '', placeholder: '1..4094'}), + makeInput('vlancomment'+idsuffix, {type: 'text'}), + ]; + }), )); l3cfg.addSection(new L3MultiSection('VLAN', function(idsuffix) { return new L3Section('vlan', makeInput('vlanSectionName'+idsuffix, {type: 'number', min: 1, max: 4094, required: '', placeholder: '1..4094'}),