diff --git a/Editor.js b/Editor.js index 1bc453f..bf82d70 100644 --- a/Editor.js +++ b/Editor.js @@ -211,6 +211,7 @@ class Editor extends List { } + diff --git a/EditorInputBase.js b/EditorInputBase.js new file mode 100644 index 0000000..51d4ef7 --- /dev/null +++ b/EditorInputBase.js @@ -0,0 +1,107 @@ +class EditorInputBase extends EditorEntryBase { + constructor(id, label) { + super(id); + + this.input_ = document.createElement('input'); + this.input_.type = 'text'; + this.listen(this.input_, 'keydown', (e) => this.onInputKeyDown(e)); + this.listen(this.input_, 'input', (e) => this.onInput(e)); + this.listen(this.input_, 'blur', (e) => this.onBlur(e)); + this.elem_.appendChild(this.input_); + + this.lastSnapshotLabel_ = ''; + + if (label) { + this.setLabel(label); + } + } + + afterDomAdd() { + this.input_.focus(); + } + + serialize(base) { + base.id = this.getId(); + base.label = this.getLabel(); + return base; + } + + getLabel() { + return this.input_.value; + } + + setLabel(label) { + this.input_.value = label; + this.lastSnapshotLabel_ = label; + this.onInput(); + } + + wantFocus() { + return this.getLabel() == ''; + } + + onInput() { + this.elem_.setAttribute('data-arch-refresh', ''); + } + + onBlur() { + if (this.getLabel() != this.lastSnapshotLabel_) { + this.lastSnapshotLabel_ = this.getLabel(); + this.elem_.setAttribute('data-arch-snapshot', ''); + } + } + + onInputKeyDown(e) { + switch (e.key) { + case 'Enter': + e.preventDefault(); + e.stopPropagation(); + if (this.elem_.nextElementSibling && + this.elem_.nextElementSibling.xArchObj && + this.elem_.nextElementSibling.xArchObj.wantFocus()) { + this.elem_.nextElementSibling.xArchObj.startEdit(); + } else { + this.stopEdit(); + } + break; + + case 'Escape': + case '`': + e.preventDefault(); + e.stopPropagation(); + this.stopEdit(); + break; + + case 'ArrowUp': + case 'ArrowDown': + case 'PageUp': + case 'PageDown': + this.stopEdit(); + break; + + default: + e.stopPropagation(); + break; + } + } + + onKeyDown(e) { + super.onKeyDown(e); + + switch (e.key) { + case 'Enter': + this.startEdit(); + e.stopPropagation(); + e.preventDefault(); + break; + } + } + + startEdit() { + this.input_.focus(); + } + + stopEdit() { + this.elem_.focus(); + } +} diff --git a/EditorLabel.js b/EditorLabel.js index 058c9bb..b978642 100644 --- a/EditorLabel.js +++ b/EditorLabel.js @@ -1,102 +1,21 @@ -// TODO: Factor out common code with EditorNode -class EditorLabel extends EditorEntryBase { - constructor(id) { - super(id); +class EditorLabel extends EditorInputBase { + constructor(id, label) { + super(id, label); this.elem_.classList.add('label'); - - this.input_ = document.createElement('input'); - this.input_.type = 'text'; this.input_.placeholder = 'label'; - this.listen(this.input_, 'keydown', (e) => this.onInputKeyDown(e)); - this.listen(this.input_, 'input', (e) => this.onInput(e)); - this.listen(this.input_, 'blur', (e) => this.onBlur(e)); - this.elem_.appendChild(this.input_); - - this.lastSnapshotLabel_ = ''; - } - - afterDomAdd() { - this.input_.focus(); } serialize() { - return { + return super.serialize({ type: 'label', - id: this.getId(), - label: this.getLabel(), - }; - } - - getLabel() { - return this.input_.value; - } - - setLabel(label) { - this.input_.value = label; - this.lastSnapshotLabel_ = label; - this.onInput(); - } - - wantFocus() { - return this.getLabel() == ''; - } - - onInput() { - this.elem_.setAttribute('data-arch-refresh', ''); - } - - onBlur() { - if (this.getLabel() != this.lastSnapshotLabel_) { - this.lastSnapshotLabel_ = this.getLabel(); - this.elem_.setAttribute('data-arch-snapshot', ''); - } - } - - onInputKeyDown(e) { - switch (e.key) { - case 'Enter': - e.preventDefault(); - e.stopPropagation(); - if (this.elem_.nextElementSibling && - this.elem_.nextElementSibling.xArchObj && - this.elem_.nextElementSibling.xArchObj.wantFocus()) { - this.elem_.nextElementSibling.xArchObj.startEdit(); - } else { - this.stopEdit(); - } - break; - - case 'Escape': - case '`': - e.preventDefault(); - e.stopPropagation(); - this.stopEdit(); - break; - - case 'ArrowUp': - case 'ArrowDown': - case 'PageUp': - case 'PageDown': - this.stopEdit(); - break; - - default: - e.stopPropagation(); - break; - } + }); } onKeyDown(e) { super.onKeyDown(e); switch (e.key) { - case 'Enter': - this.startEdit(); - e.stopPropagation(); - e.preventDefault(); - break; - case ' ': // We don't support highlighting, but stop propagation e.stopPropagation(); @@ -105,14 +24,6 @@ class EditorLabel extends EditorEntryBase { } } - startEdit() { - this.input_.focus(); - } - - stopEdit() { - this.elem_.focus(); - } - static unserialize(ser) { let label = new EditorLabel(ser.id); label.setLabel(ser.label); diff --git a/EditorNode.js b/EditorNode.js index 29bedf1..f1826fb 100644 --- a/EditorNode.js +++ b/EditorNode.js @@ -1,55 +1,22 @@ -class EditorNode extends EditorEntryBase { +class EditorNode extends EditorInputBase { constructor(id, label) { - super(id); + super(id, label); this.elem_.classList.add('node'); - - this.input_ = document.createElement('input'); - this.input_.type = 'text'; this.input_.placeholder = 'node name'; - this.listen(this.input_, 'keydown', (e) => this.onInputKeyDown(e)); - this.listen(this.input_, 'input', (e) => this.onInput(e)); - this.listen(this.input_, 'blur', (e) => this.onBlur(e)); - this.elem_.appendChild(this.input_); - - this.lastSnapshotLabel_ = ''; - - if (label) { - this.setLabel(label); - } - } - - afterDomAdd() { - this.input_.focus(); } serialize() { - return { + return super.serialize({ type: 'node', - id: this.getId(), - label: this.getLabel(), highlight: this.elem_.classList.contains('highlight'), - }; - } - - getLabel() { - return this.input_.value; - } - - setLabel(label) { - this.input_.value = label; - this.lastSnapshotLabel_ = label; - this.onInput(); + }); } setHighlight(highlight) { this.elem_.classList.toggle('highlight', highlight); } - wantFocus() { - return this.getLabel() == ''; - } - isSoft() { // Nested nodes are presumed to be references to other nodes if they exist let iter = this.elem_.parentElement; @@ -61,61 +28,10 @@ class EditorNode extends EditorEntryBase { return false; } - onInput() { - this.elem_.setAttribute('data-arch-refresh', ''); - } - - onBlur() { - if (this.getLabel() != this.lastSnapshotLabel_) { - this.lastSnapshotLabel_ = this.getLabel(); - this.elem_.setAttribute('data-arch-snapshot', ''); - } - } - - onInputKeyDown(e) { - switch (e.key) { - case 'Enter': - e.preventDefault(); - e.stopPropagation(); - if (this.elem_.nextElementSibling && - this.elem_.nextElementSibling.xArchObj && - this.elem_.nextElementSibling.xArchObj.wantFocus()) { - this.elem_.nextElementSibling.xArchObj.startEdit(); - } else { - this.stopEdit(); - } - break; - - case 'Escape': - case '`': - e.preventDefault(); - e.stopPropagation(); - this.stopEdit(); - break; - - case 'ArrowUp': - case 'ArrowDown': - case 'PageUp': - case 'PageDown': - this.stopEdit(); - break; - - default: - e.stopPropagation(); - break; - } - } - onKeyDown(e) { super.onKeyDown(e); switch (e.key) { - case 'Enter': - this.startEdit(); - e.stopPropagation(); - e.preventDefault(); - break; - case ' ': this.elem_.classList.toggle('highlight'); this.elem_.setAttribute('data-arch-snapshot', ''); @@ -126,14 +42,6 @@ class EditorNode extends EditorEntryBase { } } - startEdit() { - this.input_.focus(); - } - - stopEdit() { - this.elem_.focus(); - } - static unserialize(ser) { let node = new EditorNode(ser.id); node.setLabel(ser.label);