diff options
Diffstat (limited to 'tests.mjs')
| -rw-r--r-- | tests.mjs | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/tests.mjs b/tests.mjs new file mode 100644 index 0000000..e7095f8 --- /dev/null +++ b/tests.mjs @@ -0,0 +1,133 @@ +import { chromaticScale } from "./scale.mjs"; + +customElements.define('x-string', class extends HTMLElement { + static observedAttributes = ['tonic', 'value', 'frets']; + constructor() { + super(); + console.debug('x-string#constructor', this); + const template = this.querySelector('template').content; + const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(template.cloneNode(true)); + console.debug('attached', template, 'to shadow root', shadowRoot); + + this.muted.onclick = this.muteClicked.bind(this); + this.tonic.onclick = this.fretClicked.bind(this); + } + + get tonic() { + return this.fretList.querySelector('.tonic'); + } + + get fretList() { + return this.querySelector('.fretlist'); + } + + get fretInputs() { + return this.querySelectorAll('.fretlist input[name="string"]'); + } + + get muted() { + return this.querySelector('input[name="muted"]'); + } + + get selected() { + return this.querySelector('[slot="selected"]'); + } + + get chromIndex() { + return chromaticScale.indexOf(this.getAttribute('tonic')); + } + + muteClicked(e) { + e.preventDefault(); + console.debug('x-string#muteClicked', this, e.target.checked); + if (e.target.checked) { + this.setAttribute('value', 'x'); + } else { + this.setAttribute('value', this.getAttribute('tonic')); + } + } + + fretClicked(e) { + e.preventDefault(); + console.debug('x-string#fretClicked', this, e.target.getAttribute('value')); + this.setAttribute('value', e.target.getAttribute('value')); + } + + attributeChangedCallback(name, old, v) { + console.debug('x-string#attributeChangedCallback', this, name, old, v); + switch (name) { + case 'tonic': + return this.updateTonic(v); + case 'value': + return this.updateValue(v); + case 'frets': + return this.updateFrets(Number(old || '0'), Number(v)); + } + } + + updateTonic(tonic) { + console.debug('x-string#updateTonic', this, tonic); + + // for compat with the radio inputs. + this.tonic.setAttribute('value', tonic); + this.tonic.textContent = tonic; + + // update all fret values + this.fretInputs + .forEach((fret, i) => { + console.debug(' -- fret', i, fret); + fret.setAttribute('value', i.toString()); + }); + } + + updateValue(value) { + console.debug('x-string#updateValue', this, value); + this.selected.textContent = value; + if (value === 'x') { + this.classList.add('muted'); + this.muted.checked = true; + return; + } else { + this.classList.remove('muted'); + this.muted.checked = false; + } + + this.fretInputs + .forEach(fret => { + fret.checked = this.getAttribute('value') === fret.getAttribute('value'); + if (fret.checked) { + fret.classList.add('checked'); + } else { + fret.classList.remove('checked'); + } + console.debug(' -- fret', fret, fret.checked); + }); + } + + updateFrets(old, frets) { + console.debug('x-string#updateFrets', this, old, frets); + if (old < frets) { + const tonic = this.getAttribute('tonic'); + if (!tonic) { + return; + } + + const chromIndex = this.chromIndex; + const fretList = this.fretList; + for (let i = old+1; i <= frets; i++) { + const note = chromaticScale[chromIndex + i]; + console.debug(' -- appending fret', i, 'from', note, fretList); + + const input = document.createElement('input'); + input.setAttribute('type', 'radio'); + input.setAttribute('name', 'string'); + input.setAttribute('value', note); + input.onclick = this.fretClicked.bind(this); + + const li = document.createElement('li'); + li.appendChild(input); + fretList.appendChild(li); + } + } + } +}); |
