vibe-editor 0.0.1-dev → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +5 -0
  2. package/package.json +3 -3
  3. package/src/scripts/js/Core.js +14 -14
  4. package/src/scripts/js/VIBE.js +3 -1
  5. package/src/scripts/js/assets/mei_template.js +2 -2
  6. package/src/scripts/js/datastructures/ScoreGraph copy.js +432 -0
  7. package/src/scripts/js/datastructures/ScoreGraph.js +92 -47
  8. package/src/scripts/js/datastructures/ScoreGraph_deprecated.js +432 -0
  9. package/src/scripts/js/datastructures/ScoreNode.js +4 -0
  10. package/src/scripts/js/entry.js +2 -2
  11. package/src/scripts/js/gui/Annotations.js +4 -3
  12. package/src/scripts/js/gui/HarmonyLabel.js +1 -1
  13. package/src/scripts/js/gui/ScoreManipulator.js +7 -7
  14. package/src/scripts/js/gui/Tabbar.js +9 -8
  15. package/src/scripts/js/gui/TempoLabel.js +1 -1
  16. package/src/scripts/js/gui/Toolbar.js +1 -1
  17. package/src/scripts/js/handlers/AnnotationChangeHandler.js +3 -3
  18. package/src/scripts/js/handlers/ClickModeHandler.js +10 -3
  19. package/src/scripts/js/handlers/CustomAnnotationShapeDrawer.js +2 -2
  20. package/src/scripts/js/handlers/CustomToolbarHandler.js +4 -4
  21. package/src/scripts/js/handlers/InsertModeHandler.js +7 -4
  22. package/src/scripts/js/handlers/KeyModeHandler.js +40 -17
  23. package/src/scripts/js/handlers/LabelHandler.js +3 -2
  24. package/src/scripts/js/handlers/NoteDragHandler.js +1 -1
  25. package/src/scripts/js/handlers/ScoreManipulatorHandler.js +11 -0
  26. package/src/scripts/js/handlers/SideBarHandler.js +1 -1
  27. package/src/scripts/js/handlers/TooltipHandler.js +1 -1
  28. package/src/scripts/js/utils/MEIOperations.js +28 -25
  29. package/src/scripts/js/utils/Mouse2SVG.js +10 -8
  30. package/src/scripts/js/utils/ReactWrapper.js +1 -1
  31. package/src/scripts/js/utils/SVGEditor.js +15 -5
  32. package/src/scripts/js/utils/mappings.js +17 -14
package/README.md CHANGED
@@ -6,6 +6,11 @@ Current version on github: ![GitHub package.json version](https://img.shields.io
6
6
 
7
7
  A score editor using verovio as rendering engine
8
8
 
9
+ ## Getting started
10
+ - Install node modules: `npm install`
11
+ - Transpile TypeScript in watch mode: `tsc -w`
12
+ - Build the application: `npm run build`
13
+
9
14
  ## Initializing
10
15
  To initailize the score editor only need two different things are needed
11
16
  1. The `container` the score editor will be displayed in. The container must contain an ID, since many editors can be displayed on one page.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-editor",
3
- "version": "0.0.1-dev",
3
+ "version": "0.0.2",
4
4
  "main": "src/scripts/js/VIBE.js",
5
5
  "keywords": [],
6
6
  "author": "Matthias Nowakowski",
@@ -36,7 +36,7 @@
36
36
  "eslint-plugin-react-hooks": "^4.6.0",
37
37
  "file-loader": "^6.2.0",
38
38
  "h5p-lib-controls": "^0.0.15",
39
- "interactjs": "^1.10.11",
39
+ "interactjs": "1.10.11",
40
40
  "midi-player-js": "^2.0.16",
41
41
  "mini-css-extract-plugin": "^2.6.0",
42
42
  "node-sass": "^7.0.1",
@@ -47,7 +47,7 @@
47
47
  "soundfont-player": "^0.12.0",
48
48
  "style-loader": "^3.3.1",
49
49
  "tone": "^14.7.77",
50
- "typescript": "^4.6.2",
50
+ "typescript": "4.6.3",
51
51
  "update": "^0.7.4",
52
52
  "web-midi-api": "^2.2.5",
53
53
  "webpack": "^5.88.2",
@@ -194,7 +194,7 @@ class Core {
194
194
  return new Promise((resolve, reject) => {
195
195
  var _a;
196
196
  var message = {
197
- id: random_1.uuidv4(),
197
+ id: (0, random_1.uuidv4)(),
198
198
  action: 'renderToSVG',
199
199
  pageNo: pageNo
200
200
  };
@@ -307,7 +307,7 @@ class Core {
307
307
  }
308
308
  //just render the data once to make pagecount accessible
309
309
  var message = {
310
- id: random_1.uuidv4(),
310
+ id: (0, random_1.uuidv4)(),
311
311
  action: 'renderData',
312
312
  mei: d,
313
313
  isUrl: u
@@ -328,7 +328,7 @@ class Core {
328
328
  that.createSVGOverlay(true);
329
329
  that.svgEditor.setXY((_a = that.windowHandler) === null || _a === void 0 ? void 0 : _a.getX(), (_b = that.windowHandler) === null || _b === void 0 ? void 0 : _b.getY());
330
330
  that.getMEI("").then(mei => {
331
- var _a, _b;
331
+ var _a;
332
332
  that.currentMEI = mei;
333
333
  that.currentMEIDoc = that.getCurrentMEI(true);
334
334
  that.currentMEIDoc.querySelectorAll("[dur='breve']").forEach(d => d.setAttribute("dur", "0.5"));
@@ -350,12 +350,12 @@ class Core {
350
350
  .hideRedundantRests(that.currentMEIDoc);
351
351
  that.undoMEIStacks.push(mei);
352
352
  var lastAddedClass = "lastAdded";
353
- that.container.querySelectorAll("." + lastAddedClass).forEach(m => {
354
- m.classList.remove(lastAddedClass);
355
- });
353
+ // that.container.querySelectorAll("." + lastAddedClass).forEach(m => {
354
+ // m.classList.replace("lastAdded", "marked") //remove(lastAddedClass)
355
+ // })
356
356
  if (that.lastInsertedNoteId && ["textmode", "clickmode"].some(mode => that.container.classList.contains(mode))) {
357
- (_a = that.container.querySelector("#" + that.lastInsertedNoteId)) === null || _a === void 0 ? void 0 : _a.classList.add(lastAddedClass);
358
- (_b = that.container.querySelector("#" + that.lastInsertedNoteId)) === null || _b === void 0 ? void 0 : _b.classList.add("marked");
357
+ //that.container.querySelector("#" + that.lastInsertedNoteId)?.classList.add(lastAddedClass)
358
+ (_a = that.container.querySelector("#" + that.lastInsertedNoteId)) === null || _a === void 0 ? void 0 : _a.classList.add("marked");
359
359
  }
360
360
  if (that.meiChangedCallback) {
361
361
  that.meiChangedCallback(that.currentMEI);
@@ -373,11 +373,11 @@ class Core {
373
373
  .update();
374
374
  that.scoreGraph = new ScoreGraph_1.default(that.currentMEIDoc, that.containerId, null);
375
375
  //the first condition should only occur at first starting the score editor
376
- if (that.container.querySelector(".lastAdded") === null && that.scoreGraph.getCurrentNode() == undefined) {
377
- that.scoreGraph.setCurrentNodeById(that.container.querySelector(".staff > .layer :is(.note, .rest, .mRest").id);
376
+ if (!that.container.querySelector(".lastAdded, .marked")) { //that.scoreGraph.getCurrentNode() == undefined) {
377
+ that.scoreGraph.setCurrentNodeById(that.container.querySelector("#vrvSVG .staff > .layer.activeLayer :is(.note, .rest, .mRest").id);
378
378
  }
379
379
  else { //second condition always sets lastAdded Note
380
- that.scoreGraph.setCurrentNodeById((_a = that.container.querySelector(".lastAdded")) === null || _a === void 0 ? void 0 : _a.id);
380
+ that.scoreGraph.setCurrentNodeById((_a = that.container.querySelector("#vrvSVG :is(.lastAdded, .marked)")) === null || _a === void 0 ? void 0 : _a.id);
381
381
  }
382
382
  that.initializeHandlers();
383
383
  that.musicProcessor.setScoreGraph(that.scoreGraph);
@@ -549,7 +549,7 @@ class Core {
549
549
  return new Promise((resolve, reject) => {
550
550
  const message = {
551
551
  action: "getMEI",
552
- id: random_1.uuidv4()
552
+ id: (0, random_1.uuidv4)()
553
553
  };
554
554
  var response;
555
555
  response = this.verovioWrapper.setMessage(message);
@@ -566,7 +566,7 @@ class Core {
566
566
  return new Promise((resolve, reject) => {
567
567
  const message = {
568
568
  action: "renderToMidi",
569
- id: random_1.uuidv4()
569
+ id: (0, random_1.uuidv4)()
570
570
  };
571
571
  var response = this.verovioWrapper.setMessage(message);
572
572
  if (response.midi) {
@@ -804,7 +804,7 @@ class Core {
804
804
  * @returns {string} - serialized svg
805
805
  */
806
806
  getSVG(plain = true) {
807
- var svgDom = this.container.querySelector("#svgContainer");
807
+ var svgDom = this.container; //.querySelector("#svgContainer")
808
808
  if (plain) {
809
809
  svgDom.querySelectorAll(".lastAdded, .marked").forEach(sd => {
810
810
  sd.classList.remove("lastAdded");
@@ -5,7 +5,7 @@ const Core_1 = require("./Core");
5
5
  const dc = require("./utils/DOMCreator");
6
6
  const Tabbar_1 = require("./gui/Tabbar");
7
7
  /**
8
- * Main Class for the VerovioScoreEditor
8
+ * Main Class for the Verovio Interface for Browser based Editing
9
9
  */
10
10
  class VIBE {
11
11
  /**
@@ -112,6 +112,8 @@ class VIBE {
112
112
  this.container.append(dc.makeNewDiv("modGroup", btnGrpClass, { role: "group" }));
113
113
  //parentElement for local accidental Buttons
114
114
  this.container.append(dc.makeNewDiv("accidGroup", btnGrpClass, { role: "group" }));
115
+ //parentElement for local articulation Buttons
116
+ this.container.append(dc.makeNewDiv("articGroup", btnGrpClass, { role: "group" }));
115
117
  //sidebarList
116
118
  this.container.append(dc.makeNewDiv("sidebarContainer", "sidebar closedSidebar"));
117
119
  //parentElement for sidebar open/close
@@ -134,7 +134,7 @@ class MeiTemplate {
134
134
  }
135
135
  createTempo(mm, mmUnit, tstamp = null, startId = null) {
136
136
  var newElement = document.createElementNS(constants_1.constants._MEINS_, "tempo");
137
- newElement.setAttribute("id", random_1.uuidv4());
137
+ newElement.setAttribute("id", (0, random_1.uuidv4)());
138
138
  newElement.setAttribute("place", "above");
139
139
  if (startId === null && tstamp === null) {
140
140
  throw new Error("Tempo MUST either have timestamp or startId");
@@ -148,7 +148,7 @@ class MeiTemplate {
148
148
  newElement.setAttribute("midi.bpm", (parseFloat(mm) * parseFloat(mmUnit)).toString());
149
149
  newElement.setAttribute("staff", "1");
150
150
  var rend = document.createElementNS(constants_1.constants._MEINS_, "rend");
151
- rend.setAttribute("id", random_1.uuidv4());
151
+ rend.setAttribute("id", (0, random_1.uuidv4)());
152
152
  rend.setAttribute("fontname", "VerovioText");
153
153
  rend.textContent = "__";
154
154
  newElement.appendChild(rend);
@@ -0,0 +1,432 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ScoreNode_1 = require("./ScoreNode");
4
+ const cq = require("../utils/convenienceQueries");
5
+ const meiNodeSelector = "note, rest, mRest, chord, layer";
6
+ const documentNodeSelector = ".clef, .meterSig, .keySig, .note, .rest, .mRest, .chord"; //, .layer"
7
+ const documentNodeSelector2 = ".clef, .meterSig, .keySig, .layer .note, .layer .rest, .layer .mRest, .layer .chord"; //, :scope > .layer"
8
+ class ScoreGraph {
9
+ constructor(xmlDoc, containerId, miditimes) {
10
+ this.containerId = containerId;
11
+ this.container = document.getElementById(containerId);
12
+ this.vrvSVG = cq.getVrvSVG(containerId);
13
+ this.interactionOverlay = cq.getInteractOverlay(containerId);
14
+ this.populate(xmlDoc, miditimes);
15
+ }
16
+ /**
17
+ * @deprecated
18
+ * Use function populate instead
19
+ * @param xmlDoc
20
+ */
21
+ altPop(xmlDoc) {
22
+ var documentNodes = Array.from(cq.getVrvSVG(this.containerId).querySelectorAll(documentNodeSelector));
23
+ var documentNodes = documentNodes.filter(dn => {
24
+ if (!dn.classList.contains("note")) {
25
+ return dn;
26
+ }
27
+ if (dn.classList.contains("note")) {
28
+ if (dn.closest(".chord") === null) {
29
+ return dn;
30
+ }
31
+ }
32
+ });
33
+ var nodeCoodrs = new Map();
34
+ var root = cq.getVrvSVG(this.containerId);
35
+ var rootBBox = root.getBoundingClientRect();
36
+ documentNodes.forEach(dn => {
37
+ var dnx = dn.getBoundingClientRect().x - rootBBox.x - root.scrollLeft - window.pageXOffset;
38
+ var dny = dn.getBoundingClientRect().y - rootBBox.y - root.scrollTop - window.pageYOffset;
39
+ nodeCoodrs.set(dn, { x: dnx, y: dny });
40
+ });
41
+ for (const [key, value] of nodeCoodrs.entries()) {
42
+ var closestLeft;
43
+ var closestRight;
44
+ var closestTop;
45
+ var closestDown;
46
+ for (const [key, value] of nodeCoodrs.entries()) {
47
+ //TODO
48
+ }
49
+ }
50
+ }
51
+ /**
52
+ * Populate scoreGraoh according to mei
53
+ * Add midi timeCode
54
+ * @param xmlDoc
55
+ * @param miditimes
56
+ */
57
+ populate(xmlDoc, miditimes) {
58
+ var _a, _b, _c;
59
+ this.graph = new Map();
60
+ this.midiTimes = miditimes;
61
+ xmlDoc.querySelectorAll(meiNodeSelector).forEach(e => {
62
+ if ((e.tagName === "note" && e.closest("chord") !== null)) { // || (e.tagName === "layer" && e.children.length > 0)){
63
+ return;
64
+ }
65
+ this.graph.set(e.id, new ScoreNode_1.default(e.id));
66
+ });
67
+ cq.getVrvSVG(this.containerId).querySelectorAll(documentNodeSelector).forEach(e => {
68
+ if ((e.classList.contains("note") && e.closest(".chord") !== null)) {
69
+ return;
70
+ }
71
+ this.graph.set(e.id, new ScoreNode_1.default(e.id));
72
+ });
73
+ var layerCount = 0;
74
+ xmlDoc.querySelectorAll("layer").forEach(l => {
75
+ if (parseInt(l.getAttribute("n")) > layerCount) {
76
+ layerCount = parseInt(l.getAttribute("n"));
77
+ }
78
+ });
79
+ var staffCount = 0;
80
+ xmlDoc.querySelectorAll("staff").forEach(l => {
81
+ if (parseInt(l.getAttribute("n")) > staffCount) {
82
+ staffCount = parseInt(l.getAttribute("n"));
83
+ }
84
+ });
85
+ // Assign left/right nodes
86
+ var layerArray;
87
+ for (var s = 0; s < staffCount; s++) {
88
+ for (var i = 0; i < layerCount; i++) {
89
+ layerArray = Array.from(xmlDoc.querySelectorAll("staff[n=\"" + (s + 1).toString() + "\"] > layer[n=\"" + (i + 1).toString() + "\"]"));
90
+ var elements = new Array();
91
+ layerArray.forEach(l => {
92
+ if (cq.getVrvSVG(this.containerId).querySelector("#" + l.id) === null)
93
+ return;
94
+ let staff = cq.getVrvSVG(this.containerId).querySelector("#" + l.id).closest(".measure").querySelector(".staff[n='" + l.closest("staff").getAttribute("n") + "']");
95
+ var documentNodes = Array.from(staff.querySelectorAll(documentNodeSelector2));
96
+ var documentNodes = documentNodes.filter(dn => {
97
+ if (!dn.classList.contains("note")) {
98
+ return dn;
99
+ }
100
+ if (dn.classList.contains("note")) {
101
+ if (dn.closest(".chord") === null) {
102
+ return dn;
103
+ }
104
+ }
105
+ });
106
+ elements.push(...documentNodes);
107
+ elements.forEach((el, idx) => {
108
+ var currentNode = this.graph.get(el.id);
109
+ var prevSibling = idx === 0 ? null : this.graph.get(elements[idx - 1].id);
110
+ var nextSibling = idx === elements.length - 1 ? null : this.graph.get(elements[idx + 1].id);
111
+ if (idx > 0) {
112
+ currentNode.setLeft(prevSibling);
113
+ }
114
+ else { // empty Node at beginning of Layer
115
+ this.graph.set("BOL" + i.toString(), new ScoreNode_1.default("BOL" + i.toString()));
116
+ this.graph.get("BOL" + i.toString()).setLeft(null);
117
+ this.graph.get("BOL" + i.toString()).setUp(null);
118
+ this.graph.get("BOL" + i.toString()).setDown(null);
119
+ this.graph.get("BOL" + i.toString()).setRight(currentNode);
120
+ currentNode.setLeft(this.graph.get("BOL" + i.toString()));
121
+ }
122
+ currentNode.setRight(nextSibling);
123
+ });
124
+ });
125
+ }
126
+ }
127
+ //Assign up/down nodes
128
+ if (this.midiTimes) {
129
+ // miditimes contain svg Elements (not mei Elements!!!)
130
+ // first: direct up/down references
131
+ for (const [key, value] of this.midiTimes.entries()) {
132
+ var originArr = value;
133
+ var arr = new Array();
134
+ originArr.forEach(el => {
135
+ var chord = el.closest(".chord");
136
+ if (chord !== null && arr.indexOf(chord) === -1) {
137
+ arr.push(chord);
138
+ }
139
+ else if (chord === null) {
140
+ arr.push(el);
141
+ }
142
+ });
143
+ arr.forEach((note, idx) => {
144
+ var current = note;
145
+ var upSibling = idx === 0 ? null : this.graph.get(arr[idx - 1].id);
146
+ var downSibling = idx === arr.length - 1 ? null : this.graph.get(arr[idx + 1].id);
147
+ var currentNode = this.graph.get(current.id);
148
+ if (typeof currentNode.getTimeCode() === "undefined") {
149
+ currentNode.setTimeCode(key);
150
+ }
151
+ currentNode.setUp(upSibling);
152
+ currentNode.setDown(downSibling);
153
+ });
154
+ }
155
+ }
156
+ //DEAL WITH MRESTS
157
+ var staves = cq.getVrvSVG(this.containerId).querySelectorAll(".staff");
158
+ for (var i = 0; i < staves.length - 1; i++) {
159
+ var staffElements = staves[i].querySelectorAll(documentNodeSelector);
160
+ var emptyElements = staves[i + 1].querySelectorAll(".clef, .meterSig, .keySig, .mRest, .layer");
161
+ staffElements.forEach((se, idx) => {
162
+ var gn = this.graph.get(se.id);
163
+ if ((gn === null || gn === void 0 ? void 0 : gn.getDown()) === null || (gn === null || gn === void 0 ? void 0 : gn.getDown()) == undefined) {
164
+ var tempIdx = idx;
165
+ if (idx >= emptyElements.length) {
166
+ tempIdx = emptyElements.length - 1;
167
+ }
168
+ var gnEmpty = this.graph.get(emptyElements[tempIdx].id);
169
+ if ((gnEmpty === null || gnEmpty === void 0 ? void 0 : gnEmpty.getUp()) === null || (gnEmpty === null || gnEmpty === void 0 ? void 0 : gnEmpty.getUp()) == undefined) {
170
+ gn === null || gn === void 0 ? void 0 : gn.setDown(gnEmpty);
171
+ gnEmpty === null || gnEmpty === void 0 ? void 0 : gnEmpty.setUp(gn);
172
+ }
173
+ }
174
+ });
175
+ }
176
+ //extra iteration for Beginning of Layer
177
+ var currBol = null;
178
+ var prevBol = null;
179
+ for (const [key, value] of this.graph.entries()) {
180
+ if (key.indexOf("BOL") !== -1) {
181
+ currBol = value;
182
+ var bolIdx = key[key.length - 1];
183
+ if (bolIdx !== "0") {
184
+ currBol.setUp(prevBol);
185
+ if (prevBol !== null) {
186
+ prevBol.setDown(currBol);
187
+ }
188
+ }
189
+ prevBol = value;
190
+ }
191
+ }
192
+ //if there are no direct up/down references, assign closest references
193
+ for (const [key, value] of this.graph.entries()) {
194
+ var currentNode = value;
195
+ var leftNode = currentNode.getLeft();
196
+ var rightNode = currentNode.getRight();
197
+ if (currentNode.getUp() == undefined) {
198
+ currentNode.setUp(null);
199
+ }
200
+ if (currentNode.getDown() == undefined) {
201
+ currentNode.setDown(null);
202
+ }
203
+ // Get closest Node for UP reference
204
+ //check left
205
+ var closestTimeUp = 10 ** 10;
206
+ var upSet = null;
207
+ if (this.targetNodeIsLeftOrRight(currentNode, currentNode.getUp()) && leftNode !== null) {
208
+ if (leftNode.getUp() !== null && typeof leftNode.getDown() !== "undefined") {
209
+ closestTimeUp = (currentNode === null || currentNode === void 0 ? void 0 : currentNode.getTimeCode()) - ((_a = leftNode === null || leftNode === void 0 ? void 0 : leftNode.getUp()) === null || _a === void 0 ? void 0 : _a.getTimeCode()) || 0;
210
+ upSet = leftNode === null || leftNode === void 0 ? void 0 : leftNode.getUp();
211
+ }
212
+ }
213
+ //check right
214
+ if (this.targetNodeIsLeftOrRight(currentNode, currentNode.getUp()) && rightNode !== null) {
215
+ if (rightNode.getUp() !== null && typeof rightNode.getDown() !== "undefined") {
216
+ if ((((_b = rightNode.getUp()) === null || _b === void 0 ? void 0 : _b.getTimeCode()) - (currentNode === null || currentNode === void 0 ? void 0 : currentNode.getTimeCode())) < closestTimeUp) {
217
+ upSet = rightNode === null || rightNode === void 0 ? void 0 : rightNode.getUp();
218
+ }
219
+ }
220
+ }
221
+ if (upSet !== null && upSet !== currentNode && !this.targetNodeIsLeftOrRight(currentNode, upSet)) {
222
+ currentNode.setUp(upSet);
223
+ }
224
+ // Get closest Node for DOWN reference
225
+ // check left
226
+ var closestTimeDown = 10 ** 10;
227
+ var downSet = null;
228
+ if (this.targetNodeIsLeftOrRight(currentNode, currentNode.getDown()) && leftNode !== null) {
229
+ if (leftNode.getDown() !== null && typeof leftNode.getDown() !== "undefined") {
230
+ closestTimeDown = (currentNode === null || currentNode === void 0 ? void 0 : currentNode.getTimeCode()) - ((_c = leftNode === null || leftNode === void 0 ? void 0 : leftNode.getDown()) === null || _c === void 0 ? void 0 : _c.getTimeCode()) || 0;
231
+ downSet = leftNode.getDown();
232
+ }
233
+ }
234
+ // check right
235
+ if (this.targetNodeIsLeftOrRight(currentNode, currentNode.getDown()) && rightNode !== null) {
236
+ if (rightNode.getDown() !== null && rightNode.getDown() != undefined) {
237
+ if ((rightNode.getDown().getTimeCode() - currentNode.getTimeCode()) < closestTimeDown) {
238
+ downSet = rightNode.getDown();
239
+ }
240
+ }
241
+ }
242
+ if (downSet !== null && downSet !== currentNode && !this.targetNodeIsLeftOrRight(currentNode, downSet)) {
243
+ currentNode.setDown(downSet);
244
+ }
245
+ }
246
+ }
247
+ targetNodeIsLeftOrRight(startNode, targetNode) {
248
+ return this.targetIsNodeRight(startNode, targetNode) || this.targetIsNodeLeft(startNode, targetNode);
249
+ }
250
+ targetIsNodeLeft(startNode, targetNode) {
251
+ var tempNode = startNode;
252
+ var isLeft = false;
253
+ while (tempNode !== null) {
254
+ if (tempNode !== null) {
255
+ if (tempNode == undefined) {
256
+ return isLeft;
257
+ }
258
+ tempNode = tempNode.getLeft();
259
+ }
260
+ if (tempNode === targetNode) {
261
+ isLeft = true;
262
+ }
263
+ }
264
+ return isLeft;
265
+ }
266
+ targetIsNodeRight(startNode, targetNode) {
267
+ var tempNode = startNode;
268
+ var isRight = false;
269
+ while (tempNode !== null) {
270
+ if (tempNode !== null) {
271
+ if (tempNode == undefined) {
272
+ return isRight;
273
+ }
274
+ tempNode = tempNode.getRight();
275
+ }
276
+ if (tempNode === targetNode) {
277
+ isRight = true;
278
+ }
279
+ }
280
+ return isRight;
281
+ }
282
+ getCurrentNode() {
283
+ return this.currentNode;
284
+ }
285
+ setCurrentNodeById(id) {
286
+ var _a, _b;
287
+ if (id == undefined)
288
+ return;
289
+ var lastNode = this.currentNode;
290
+ this.currentNode = this.graph.get(id) || this.graph.get((_b = (_a = document.getElementById(id)) === null || _a === void 0 ? void 0 : _a.closest(".chord")) === null || _b === void 0 ? void 0 : _b.id) || lastNode;
291
+ if (this.currentNode == undefined) {
292
+ console.log(lastNode);
293
+ throw new Error("CurrentNode undefined although id is given: " + id);
294
+ }
295
+ }
296
+ setContainerId(containerId) {
297
+ this.containerId = containerId;
298
+ }
299
+ nextUp() {
300
+ var _a;
301
+ if (this.currentNode != undefined && ((_a = this.currentNode) === null || _a === void 0 ? void 0 : _a.getUp()) !== null) {
302
+ this.currentNode = this.currentNode.getUp();
303
+ }
304
+ return this.currentNode;
305
+ }
306
+ nextDown() {
307
+ var _a;
308
+ if (this.currentNode != undefined && ((_a = this.currentNode) === null || _a === void 0 ? void 0 : _a.getDown()) !== null) {
309
+ this.currentNode = this.currentNode.getDown();
310
+ }
311
+ return this.currentNode;
312
+ }
313
+ nextRight() {
314
+ var _a;
315
+ if (this.currentNode != undefined && ((_a = this.currentNode) === null || _a === void 0 ? void 0 : _a.getRight()) !== null) {
316
+ this.currentNode = this.currentNode.getRight();
317
+ }
318
+ return this.currentNode;
319
+ }
320
+ nextLeft() {
321
+ var _a;
322
+ if (this.currentNode != undefined && ((_a = this.currentNode) === null || _a === void 0 ? void 0 : _a.getLeft()) !== null) {
323
+ this.currentNode = this.currentNode.getLeft();
324
+ }
325
+ return this.currentNode;
326
+ }
327
+ nextMeasureRight() {
328
+ while (this.getCurrentNode().getRight().getDocElement().closest(".measure").id ===
329
+ this.getCurrentNode().getDocElement().closest(".measure").id) {
330
+ this.nextRight();
331
+ }
332
+ return this.currentNode;
333
+ }
334
+ nextMeasureLeft() {
335
+ while (this.getCurrentNode().getLeft().getDocElement().closest(".measure").id ===
336
+ this.getCurrentNode().getDocElement().closest(".measure").id) {
337
+ this.nextLeft();
338
+ }
339
+ return this.currentNode;
340
+ }
341
+ /**
342
+ * Go to next Element with given classname.
343
+ * Whatever comes first according to the classNames array.
344
+ * @param classNames
345
+ * @param direction
346
+ * @returns
347
+ */
348
+ getNextClass(classNames, direction) {
349
+ var _a;
350
+ if (typeof classNames === "string")
351
+ classNames = [classNames];
352
+ var currentId = (_a = this.currentNode) === null || _a === void 0 ? void 0 : _a.getId();
353
+ if ([null, undefined].some(id => id == currentId))
354
+ return;
355
+ var nextIsNull = false;
356
+ do {
357
+ switch (direction) {
358
+ case "ArrowLeft":
359
+ case "left":
360
+ this.nextLeft();
361
+ break;
362
+ case "ArrowRight":
363
+ case "right":
364
+ this.nextRight();
365
+ break;
366
+ case "ArrowUp":
367
+ case "up":
368
+ this.nextUp();
369
+ break;
370
+ case "ArrowDown":
371
+ case "down":
372
+ this.nextDown();
373
+ break;
374
+ default:
375
+ console.error(direction + " is not allowed. Use left, right, up or down");
376
+ return;
377
+ }
378
+ nextIsNull = [null, undefined].some(n => this.currentNode == n);
379
+ } while (!classNames.some(cn => { var _a, _b; return (_b = (_a = this.currentNode) === null || _a === void 0 ? void 0 : _a.getDocElement()) === null || _b === void 0 ? void 0 : _b.classList.contains(cn); }) && !nextIsNull);
380
+ if (nextIsNull) {
381
+ this.setCurrentNodeById(currentId);
382
+ }
383
+ return this.currentNode;
384
+ }
385
+ /**
386
+ * Find node based on class Names. Will not change state and pointers of the graph.
387
+ * To change this.currentNode, use getNextClass instead.
388
+ * @param classNames
389
+ * @param direction
390
+ * @returns
391
+ */
392
+ lookUp(classNames, direction) {
393
+ var _a;
394
+ if (typeof classNames === "string")
395
+ classNames = [classNames];
396
+ var currentId = (_a = this.currentNode) === null || _a === void 0 ? void 0 : _a.getId();
397
+ if ([null, undefined].some(id => id == currentId))
398
+ return;
399
+ var isNull = false;
400
+ var node = this.currentNode;
401
+ do {
402
+ switch (direction) {
403
+ case "ArrowLeft":
404
+ case "left":
405
+ node = node.getLeft();
406
+ break;
407
+ case "ArrowRight":
408
+ case "right":
409
+ node = node.getRight();
410
+ break;
411
+ case "ArrowUp":
412
+ case "up":
413
+ node = node.getUp();
414
+ break;
415
+ case "ArrowDown":
416
+ case "down":
417
+ node = node.getDown();
418
+ break;
419
+ default:
420
+ console.error(direction + " is not allowed. Use left, right, up or down");
421
+ return;
422
+ }
423
+ isNull = [null, undefined].some(n => node == n);
424
+ } while (!classNames.some(cn => { var _a; return (_a = node === null || node === void 0 ? void 0 : node.getDocElement()) === null || _a === void 0 ? void 0 : _a.classList.contains(cn); }) && !isNull);
425
+ return node;
426
+ }
427
+ //Check if ScoreGraph is at beginning of layer
428
+ isBOL() {
429
+ return this.currentNode.getLeft() === null && this.currentNode.getId().indexOf("BOL") !== -1;
430
+ }
431
+ }
432
+ exports.default = ScoreGraph;