summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fretboard.mjs49
-rw-r--r--index.html275
-rw-r--r--key-picker.mjs38
-rw-r--r--main.mjs29
-rw-r--r--notes.org6
5 files changed, 230 insertions, 167 deletions
diff --git a/fretboard.mjs b/fretboard.mjs
index 8b330cc..38fdc0f 100644
--- a/fretboard.mjs
+++ b/fretboard.mjs
@@ -83,15 +83,42 @@ function openClick(e) {
formChanged(elt.closest('form'));
}
-export default function (form) {
- console.debug('Fretboard()', form);
- form.onchange = handleFormChanged;
- form.querySelectorAll('.open').forEach(elt => {
- elt.onclick = openClick;
- });
- form.querySelectorAll('input[type="radio"]').forEach(elt => {
- elt.onmousedown = fretMousedown;
- elt.onclick = fretClick;
- });
- formChanged(form);
+// export default function (form, { onSave }) {
+// }
+
+export default class extends HTMLElement {
+ static name = 'x-fretboard'
+ static register() {
+ console.debug('Registering Element', this.name, this);
+ customElements.define(this.name, this);
+ }
+
+ constructor() {
+ super();
+
+ console.debug('Fretboard#constructor', this);
+ }
+
+ connectedCallback() {
+ console.debug('Fretboard#connectedCallback', this);
+
+ // TODO: don't trawl the dom, custom element means we know
+ // what's inside.
+ const form = this.querySelector('form');
+ form.onchange = handleFormChanged;
+ form.querySelectorAll('.open').forEach(elt => {
+ elt.onclick = openClick;
+ });
+ form.querySelectorAll('input[type="radio"]').forEach(elt => {
+ elt.onmousedown = fretMousedown;
+ elt.onclick = fretClick;
+ });
+ form.querySelectorAll('.save').forEach(elt => {
+ elt.onclick = (e) => {
+ e.preventDefault();
+ console.log('Fretboard#onSave');
+ };
+ })
+ formChanged(form);
+ }
}
diff --git a/index.html b/index.html
index 7bee462..edf0061 100644
--- a/index.html
+++ b/index.html
@@ -8,149 +8,154 @@
</head>
<body>
- <form id='fretboard'>
- <table>
- <thead>
- <tr>
- <td class='open'>open</td>
- <td class='fret1'></td>
- <td class='fret2'></td>
- <td class='fret3'>•</td>
- <td class='fret4'></td>
- <td class='fret5'>••</td>
- <td class='fret6'></td>
- <td class='fret7'>•</td>
- <td class='selected'>selected</td>
- </tr>
- </thead>
+ <x-fretboard>
+ <form id='fretboard'>
+ <table>
+ <thead>
+ <tr>
+ <td class='open'>open</td>
+ <td class='fret1'></td>
+ <td class='fret2'></td>
+ <td class='fret3'>•</td>
+ <td class='fret4'></td>
+ <td class='fret5'>••</td>
+ <td class='fret6'></td>
+ <td class='fret7'>•</td>
+ <td class='selected'>selected</td>
+ </tr>
+ </thead>
- <tbody>
- <tr class='string1'>
- <td class='open' x-data-note='E'>E</td>
- <td x-data-note='F'><input type='radio' name='string1' value='fret1'></td>
- <td x-data-note='F♯'><input type='radio' name='string1' value='fret2'></td>
- <td x-data-note='G'><input type='radio' name='string1' value='fret3'></td>
- <td x-data-note='G♯'><input type='radio' name='string1' value='fret4'></td>
- <td x-data-note='A'><input type='radio' name='string1' value='fret5'></td>
- <td x-data-note='A♯'><input type='radio' name='string1' value='fret6'></td>
- <td x-data-note='B'><input type='radio' name='string1' value='fret7'></td>
- <td class='selected'></td>
- </tr>
- <tr class='string2'>
- <td class='open' x-data-note='A'>A</td>
- <td x-data-note='A♯'><input type='radio' name='string2' value='fret1'></td>
- <td x-data-note='B'><input type='radio' name='string2' value='fret2'></td>
- <td x-data-note='C'><input type='radio' name='string2' value='fret3'></td>
- <td x-data-note='C♯'><input type='radio' name='string2' value='fret4'></td>
- <td x-data-note='D'><input type='radio' name='string2' value='fret5'></td>
- <td x-data-note='D♯'><input type='radio' name='string2' value='fret6'></td>
- <td x-data-note='E'><input type='radio' name='string2' value='fret7'></td>
- <td class='selected'></td>
- </tr>
- <tr class='string3'>
- <td class='open' x-data-note='D'>D</td>
- <td x-data-note='D♯'><input type='radio' name='string3' value='fret1'></td>
- <td x-data-note='E'><input type='radio' name='string3' value='fret2'></td>
- <td x-data-note='F'><input type='radio' name='string3' value='fret3'></td>
- <td x-data-note='F♯'><input type='radio' name='string3' value='fret4'></td>
- <td x-data-note='G'><input type='radio' name='string3' value='fret5'></td>
- <td x-data-note='G♯'><input type='radio' name='string3' value='fret6'></td>
- <td x-data-note='A'><input type='radio' name='string3' value='fret7'></td>
- <td class='selected'></td>
- </tr>
- <tr class='string4'>
- <td class='open' x-data-note='G'>G</td>
- <td x-data-note='G♯'><input type='radio' name='string4' value='fret1'></td>
- <td x-data-note='A'><input type='radio' name='string4' value='fret2'></td>
- <td x-data-note='A♯'><input type='radio' name='string4' value='fret3'></td>
- <td x-data-note='B'><input type='radio' name='string4' value='fret4'></td>
- <td x-data-note='C'><input type='radio' name='string4' value='fret5'></td>
- <td x-data-note='C♯'><input type='radio' name='string4' value='fret6'></td>
- <td x-data-note='D'><input type='radio' name='string4' value='fret7'></td>
- <td class='selected'></td>
- </tr>
- <tr class='string5'>
- <td class='open' x-data-note='B'>B</td>
- <td x-data-note='C'><input type='radio' name='string5' value='fret1'></td>
- <td x-data-note='C♯'><input type='radio' name='string5' value='fret2'></td>
- <td x-data-note='D'><input type='radio' name='string5' value='fret3'></td>
- <td x-data-note='D♯'><input type='radio' name='string5' value='fret4'></td>
- <td x-data-note='E'><input type='radio' name='string5' value='fret5'></td>
- <td x-data-note='F'><input type='radio' name='string5' value='fret6'></td>
- <td x-data-note='F♯'><input type='radio' name='string5' value='fret7'></td>
- <td class='selected'></td>
- </tr>
- <tr class='string6'>
- <td class='open' x-data-note='E'>E</td>
- <td x-data-note='F'><input type='radio' name='string6' value='fret1'></td>
- <td x-data-note='F♯'><input type='radio' name='string6' value='fret2'></td>
- <td x-data-note='G'><input type='radio' name='string6' value='fret3'></td>
- <td x-data-note='G♯'><input type='radio' name='string6' value='fret4'></td>
- <td x-data-note='A'><input type='radio' name='string6' value='fret5'></td>
- <td x-data-note='A♯'><input type='radio' name='string6' value='fret6'></td>
- <td x-data-note='B'><input type='radio' name='string6' value='fret7'></td>
- <td class='selected'></td>
- </tr>
- </tbody>
- </table>
+ <tbody>
+ <tr class='string1'>
+ <td class='open' x-data-note='E'>E</td>
+ <td x-data-note='F'><input type='radio' name='string1' value='fret1'></td>
+ <td x-data-note='F♯'><input type='radio' name='string1' value='fret2'></td>
+ <td x-data-note='G'><input type='radio' name='string1' value='fret3'></td>
+ <td x-data-note='G♯'><input type='radio' name='string1' value='fret4'></td>
+ <td x-data-note='A'><input type='radio' name='string1' value='fret5'></td>
+ <td x-data-note='A♯'><input type='radio' name='string1' value='fret6'></td>
+ <td x-data-note='B'><input type='radio' name='string1' value='fret7'></td>
+ <td class='selected'></td>
+ </tr>
+ <tr class='string2'>
+ <td class='open' x-data-note='A'>A</td>
+ <td x-data-note='A♯'><input type='radio' name='string2' value='fret1'></td>
+ <td x-data-note='B'><input type='radio' name='string2' value='fret2'></td>
+ <td x-data-note='C'><input type='radio' name='string2' value='fret3'></td>
+ <td x-data-note='C♯'><input type='radio' name='string2' value='fret4'></td>
+ <td x-data-note='D'><input type='radio' name='string2' value='fret5'></td>
+ <td x-data-note='D♯'><input type='radio' name='string2' value='fret6'></td>
+ <td x-data-note='E'><input type='radio' name='string2' value='fret7'></td>
+ <td class='selected'></td>
+ </tr>
+ <tr class='string3'>
+ <td class='open' x-data-note='D'>D</td>
+ <td x-data-note='D♯'><input type='radio' name='string3' value='fret1'></td>
+ <td x-data-note='E'><input type='radio' name='string3' value='fret2'></td>
+ <td x-data-note='F'><input type='radio' name='string3' value='fret3'></td>
+ <td x-data-note='F♯'><input type='radio' name='string3' value='fret4'></td>
+ <td x-data-note='G'><input type='radio' name='string3' value='fret5'></td>
+ <td x-data-note='G♯'><input type='radio' name='string3' value='fret6'></td>
+ <td x-data-note='A'><input type='radio' name='string3' value='fret7'></td>
+ <td class='selected'></td>
+ </tr>
+ <tr class='string4'>
+ <td class='open' x-data-note='G'>G</td>
+ <td x-data-note='G♯'><input type='radio' name='string4' value='fret1'></td>
+ <td x-data-note='A'><input type='radio' name='string4' value='fret2'></td>
+ <td x-data-note='A♯'><input type='radio' name='string4' value='fret3'></td>
+ <td x-data-note='B'><input type='radio' name='string4' value='fret4'></td>
+ <td x-data-note='C'><input type='radio' name='string4' value='fret5'></td>
+ <td x-data-note='C♯'><input type='radio' name='string4' value='fret6'></td>
+ <td x-data-note='D'><input type='radio' name='string4' value='fret7'></td>
+ <td class='selected'></td>
+ </tr>
+ <tr class='string5'>
+ <td class='open' x-data-note='B'>B</td>
+ <td x-data-note='C'><input type='radio' name='string5' value='fret1'></td>
+ <td x-data-note='C♯'><input type='radio' name='string5' value='fret2'></td>
+ <td x-data-note='D'><input type='radio' name='string5' value='fret3'></td>
+ <td x-data-note='D♯'><input type='radio' name='string5' value='fret4'></td>
+ <td x-data-note='E'><input type='radio' name='string5' value='fret5'></td>
+ <td x-data-note='F'><input type='radio' name='string5' value='fret6'></td>
+ <td x-data-note='F♯'><input type='radio' name='string5' value='fret7'></td>
+ <td class='selected'></td>
+ </tr>
+ <tr class='string6'>
+ <td class='open' x-data-note='E'>E</td>
+ <td x-data-note='F'><input type='radio' name='string6' value='fret1'></td>
+ <td x-data-note='F♯'><input type='radio' name='string6' value='fret2'></td>
+ <td x-data-note='G'><input type='radio' name='string6' value='fret3'></td>
+ <td x-data-note='G♯'><input type='radio' name='string6' value='fret4'></td>
+ <td x-data-note='A'><input type='radio' name='string6' value='fret5'></td>
+ <td x-data-note='A♯'><input type='radio' name='string6' value='fret6'></td>
+ <td x-data-note='B'><input type='radio' name='string6' value='fret7'></td>
+ <td class='selected'></td>
+ </tr>
+ </tbody>
+ </table>
- <button class='save-chord'>+</button>
- </form>
+ <button class='save'>+</button>
+ </form>
+ </x-fretboard>
- <form id='key-picker'>
- <fieldset>
- <legend>key</legend>
- <label for='tonic'>tonic:</label>
- <select id='tonic' name='tonic'>
- <option value='C' selected>C</option>
- <option value='C♯'>C♯</option>
- <option value='D'>D</option>
- <option value='D♯'>D♯</option>
- <option value='E'>E</option>
- <option value='F'>F</option>
- <option value='F♯'>F♯</option>
- <option value='G'>G</option>
- <option value='G♯'>G♯</option>
- <option value='A'>A</option>
- <option value='A♯'>A♯</option>
- <option value='B'>B</option>
- </select>
- <label for='scale'>scale:</label>
- <select id='scale' name='scale'>
- <option value='major' selected>major</option>
- <option value='minor'>minor</option>
- <option value='aug'>augmented</option>
- <option value='dim'>diminished</option>
- </select>
+ <x-key-picker>
+ <form id='key-picker'>
+ <fieldset>
+ <legend>key</legend>
+ <label for='tonic'>tonic:</label>
+ <select id='tonic' name='tonic'>
+ <option value='C' selected>C</option>
+ <option value='C♯'>C♯</option>
+ <option value='D'>D</option>
+ <option value='D♯'>D♯</option>
+ <option value='E'>E</option>
+ <option value='F'>F</option>
+ <option value='F♯'>F♯</option>
+ <option value='G'>G</option>
+ <option value='G♯'>G♯</option>
+ <option value='A'>A</option>
+ <option value='A♯'>A♯</option>
+ <option value='B'>B</option>
+ </select>
+ <label for='scale'>scale:</label>
+ <select id='scale' name='scale'>
+ <option value='major' selected>major</option>
+ <option value='minor'>minor</option>
+ <option value='aug'>augmented</option>
+ <option value='dim'>diminished</option>
+ </select>
- <hr>
+ <hr>
- <ol class='notes'>
- <li class='tonic'>C</li>
- <li class='second'>D</li>
- <li class='third'>E</li>
- <li class='fourth'>F</li>
- <li class='fifth'>G</li>
- <li class='sixth'>A</li>
- <li class='seventh'>B</li>
- </ol>
- <hr>
+ <ol class='notes'>
+ <li class='tonic'>C</li>
+ <li class='second'>D</li>
+ <li class='third'>E</li>
+ <li class='fourth'>F</li>
+ <li class='fifth'>G</li>
+ <li class='sixth'>A</li>
+ <li class='seventh'>B</li>
+ </ol>
+ <hr>
- <p>Available triads:</p>
- <ul class='chords'>
- <li>Amin</li>
- <li>C</li>
- <li>Dmin</li>
- <li>Emin</li>
- <li>F</li>
- <li>G</li>
- </ul>
- </fieldset>
- </form>
+ <p>Available triads:</p>
+ <ul class='chords'>
+ <li>Amin</li>
+ <li>C</li>
+ <li>Dmin</li>
+ <li>Emin</li>
+ <li>F</li>
+ <li>G</li>
+ </ul>
+ </fieldset>
+ </form>
+ </x-key-picker>
- <form id='saved-chords'>
+ <x-chords-history></x-chords-history>
+ <form id='history'>
<fieldset>
- <legend>saved</legend>
+ <legend>history</legend>
<ol>
<li>GCEGCE</li>
<li>EBEGBE</li>
diff --git a/key-picker.mjs b/key-picker.mjs
index 3aa8340..b24422d 100644
--- a/key-picker.mjs
+++ b/key-picker.mjs
@@ -106,15 +106,33 @@ function handleFormChanged(e) {
formChanged(e.target.form);
}
-export default function (form) {
- console.debug('KeyPicker()', form);
- form.onchange = handleFormChanged;
- form.querySelectorAll('.notes li').forEach(elt => {
- elt.onmouseenter = handleNoteEnter;
- elt.onmouseleave = handleNoteLeave;
- elt.onclick = handleNoteClick;
- });
- formChanged(form);
+export default class extends HTMLElement {
+ static name = 'x-key-picker'
+ static register() {
+ console.debug('Registering Element', this.name, this);
+ customElements.define(this.name, this);
+ }
+
+ constructor() {
+ super();
+
+ console.debug('KeyPicker#constructor', this);
+ }
+
+ connectedCallback() {
+ console.debug('KeyPicker#connectedCallback', this);
- console.log('bjc', 'Cdim', DiminishedScale('C').toString());
+ // TODO: don't trawl the dom, custom element means we know
+ // what's inside.
+ const form = this.querySelector('form');
+ form.onchange = handleFormChanged;
+ form.querySelectorAll('.notes li').forEach(elt => {
+ elt.onmouseenter = handleNoteEnter;
+ elt.onmouseleave = handleNoteLeave;
+ elt.onclick = handleNoteClick;
+ });
+ formChanged(form);
+
+ console.log('bjc', 'Cdim', DiminishedScale('C').toString());
+ }
}
diff --git a/main.mjs b/main.mjs
index 3054208..f0e4ed8 100644
--- a/main.mjs
+++ b/main.mjs
@@ -2,25 +2,32 @@ import Fretboard, { fretToNote } from './fretboard.mjs';
import KeyPicker from './key-picker.mjs';
import History from './history.mjs';
+function memoize(fn) {
+ let val = undefined;
+ return function () {
+ if (val === undefined) {
+ val = fn();
+ }
+ return val;
+ }
+}
+
function notes(form) {
const strings = ['string1', 'string2', 'string3', 'string4', 'string5', 'string6'];
const formData = new FormData(form);
- console.log('notes', form, formData);
+ console.debug('notes', form, formData);
return strings.map((klass) => fretToNote(form, klass, formData.get(klass)));
}
function onSave(form) {
- console.log('we done saved', form, notes(form));
+ console.debug('we done saved', form, notes(form));
}
+function init() {
+ console.debug('App#init', this);
-function main() {
- const fretboard = document.getElementById('fretboard');
- const keyPicker = document.getElementById('key-picker');
- const history = document.getElementById('history');
-
- Fretboard(fretboard, { onSave });
- KeyPicker(keyPicker);
- History(history, keyPicker);
+ Fretboard.register();
+ KeyPicker.register();
+ History.register();
}
-document.addEventListener('DOMContentLoaded', main);
+document.addEventListener('DOMContentLoaded', init);
diff --git a/notes.org b/notes.org
index 82d94de..01cb344 100644
--- a/notes.org
+++ b/notes.org
@@ -1,3 +1,9 @@
+* convert to web components
+https://developer.mozilla.org/en-US/docs/Web/API/Web_components
+** don't trawl dom when setting up behavior
+since it's a custom element, we should know its exact layout at all
+times, so ~querySelector~ shouldn't be necessary.
+
* well-tempered scale
| semi-tones | freq | just | interval |
|------------+-----------+------+----------|