Files
architype/Editor.js

222 lines
5.4 KiB
JavaScript
Raw Normal View History

2019-07-03 01:42:17 +00:00
<!--# include file="List.js" -->
class Editor extends List {
2019-07-10 08:14:53 +00:00
constructor(container, limitsByType) {
2019-07-03 01:42:17 +00:00
super(container);
2019-07-10 08:14:53 +00:00
this.limitsByType_ = new Map(limitsByType || [
[EditorNode, [0, Number.POSITIVE_INFINITY]],
[EditorGroup, [0, Number.POSITIVE_INFINITY]],
[EditorLink, [0, Number.POSITIVE_INFINITY]],
[EditorLabel, [0, 1]],
2019-07-10 21:32:52 +00:00
[EditorHelp, [0, Number.POSITIVE_INFINITY]],
2019-07-10 08:14:53 +00:00
]);
2019-07-03 01:42:17 +00:00
this.container_.classList.add('editor');
// Needs to accept focus to receive keydown, but shouldn't be in the normal
// tab flow.
this.container_.tabIndex = 99999;
this.container_.addEventListener('keydown', e => { this.onKeyDown(e); });
this.container_.focus();
}
clear() {
this.container_.innerHTML = '';
}
2019-07-10 08:14:53 +00:00
serialize(type) {
2019-07-03 01:42:17 +00:00
// Doesn't have a type, only used as part of other objects
let ret = [];
2019-07-10 08:14:53 +00:00
for (let entry of this.getEntries(type)) {
2019-07-03 01:42:17 +00:00
ret.push(entry.serialize());
}
return ret;
}
unserialize(ser) {
for (let entry of ser) {
2019-07-10 21:32:52 +00:00
let elem = EditorEntryBase.unserialize(entry);
if (elem) {
this.container_.appendChild(elem);
} else {
console.log('failed to unserialize', entry);
}
2019-07-03 01:42:17 +00:00
}
}
2019-07-10 08:14:53 +00:00
mayAdd(type) {
let limits = this.limitsByType_.get(type);
if (!limits) {
return false;
}
return this.getEntries(type).length < limits[1];
}
mayDelete(type) {
let limits = this.limitsByType_.get(type);
if (!limits) {
return false;
}
return this.getEntries(type).length > limits[0];
2019-07-03 01:42:17 +00:00
}
addNodeAfter(...rest) {
2019-07-10 08:14:53 +00:00
if (this.mayAdd(EditorNode)) {
2019-07-13 01:54:08 +00:00
return EditorNode.addAfter(this.container_, this.getSelected(), ...rest);
2019-07-03 01:42:17 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-03 01:42:17 +00:00
}
addNodeBefore(...rest) {
2019-07-10 08:14:53 +00:00
if (this.mayAdd(EditorNode)) {
2019-07-13 01:54:08 +00:00
return EditorNode.addBefore(this.container_, this.getSelected(), ...rest);
2019-07-03 01:42:17 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-03 01:42:17 +00:00
}
addLabelBefore(...rest) {
2019-07-10 08:14:53 +00:00
if (this.mayAdd(EditorLabel)) {
return EditorLabel.addBefore(this.container_, this.getSelected(), ...rest);
2019-07-10 04:09:54 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-10 04:09:54 +00:00
}
addLabelAfter(...rest) {
2019-07-10 08:14:53 +00:00
if (this.mayAdd(EditorLabel)) {
return EditorLabel.addAfter(this.container_, this.getSelected(), ...rest);
2019-07-10 04:09:54 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-10 04:09:54 +00:00
}
addLinkAfter(...rest) {
2019-07-10 08:14:53 +00:00
if (this.mayAdd(EditorLink)) {
2019-07-13 01:54:08 +00:00
return EditorLink.addAfter(this.container_, this.getSelected(),
this.queryEntries('.highlight', EditorNode),
...rest);
2019-07-03 01:42:17 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-03 01:42:17 +00:00
}
addLinkBefore(...rest) {
2019-07-10 08:14:53 +00:00
if (this.mayAdd(EditorLink)) {
2019-07-13 01:54:08 +00:00
return EditorLink.addBefore(this.container_, this.getSelected(),
this.queryEntries('.highlight', EditorNode),
...rest);
2019-07-03 01:42:17 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-03 01:42:17 +00:00
}
addGroupAfter(...rest) {
2019-07-10 08:14:53 +00:00
if (this.mayAdd(EditorGroup)) {
2019-07-13 01:54:08 +00:00
return EditorGroup.addAfter(this.container_, this.getSelected(),
this.queryEntries('.highlight', EditorNode),
...rest);
2019-07-03 01:42:17 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-03 01:42:17 +00:00
}
addGroupBefore(...rest) {
2019-07-10 08:14:53 +00:00
if (this.mayAdd(EditorGroup)) {
2019-07-13 01:54:08 +00:00
return EditorGroup.addBefore(this.container_, this.getSelected(),
this.queryEntries('.highlight', EditorNode),
...rest);
2019-07-03 01:42:17 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-03 01:42:17 +00:00
}
2019-07-10 21:32:52 +00:00
addHelpAfter(...rest) {
2019-07-10 21:32:52 +00:00
if (this.mayAdd(EditorHelp)) {
return EditorHelp.addAfter(this.container_, this.getSelected(), ...rest);
2019-07-10 21:32:52 +00:00
}
2019-07-13 01:54:08 +00:00
return null;
2019-07-10 21:32:52 +00:00
}
2019-07-03 01:42:17 +00:00
onKeyDown(e) {
switch (e.key) {
2019-07-10 04:09:54 +00:00
case 'a':
2019-07-11 19:58:22 +00:00
if (this.addLabelAfter()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-10 04:09:54 +00:00
return;
case 'A':
2019-07-11 19:58:22 +00:00
if (this.addLabelBefore()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-10 04:09:54 +00:00
return;
2019-07-03 01:42:17 +00:00
case 'g':
2019-07-11 19:58:22 +00:00
if (this.addGroupAfter()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-03 01:42:17 +00:00
return;
case 'G':
2019-07-11 19:58:22 +00:00
if (this.addGroupBefore()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-03 01:42:17 +00:00
return;
case 'i':
2019-07-11 19:58:22 +00:00
if (this.addLinkAfter()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-03 01:42:17 +00:00
return;
case 'I':
2019-07-11 19:58:22 +00:00
if (this.addLinkBefore()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-03 01:42:17 +00:00
return;
case 'n':
2019-07-11 19:58:22 +00:00
if (this.addNodeAfter()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-03 01:42:17 +00:00
return;
case 'N':
2019-07-11 19:58:22 +00:00
if (this.addNodeBefore()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-03 01:42:17 +00:00
return;
2019-07-10 21:32:52 +00:00
case '?':
2019-07-11 19:58:22 +00:00
if (this.addHelpAfter()) {
e.stopPropagation();
e.preventDefault();
}
2019-07-10 21:32:52 +00:00
return;
2019-07-11 04:28:55 +00:00
case 'Escape':
case '`':
if (!this.container_.parentElement.xArchObj) {
for (let entry of this.queryEntries('.highlight')) {
entry.setHighlight(false);
}
e.stopPropagation();
e.preventDefault();
return;
2019-07-11 04:28:55 +00:00
}
2019-07-03 01:42:17 +00:00
}
super.onKeyDown(e);
}
}
2019-07-10 04:09:54 +00:00
<!--# include file="EditorEntryBase.js" -->
<!--# include file="EditorInputBase.js" -->
2019-07-10 04:09:54 +00:00
<!--# include file="EditorGroup.js" -->
2019-07-10 21:32:52 +00:00
<!--# include file="EditorHelp.js" -->
2019-07-10 04:09:54 +00:00
<!--# include file="EditorLabel.js" -->
<!--# include file="EditorLink.js" -->
<!--# include file="EditorNode.js" -->