vibe-editor 0.0.4 → 0.0.6

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 (78) hide show
  1. package/package.json +66 -61
  2. package/src/scripts/js/Core.js +28 -9
  3. package/src/scripts/js/entry.js +6 -5
  4. package/src/scripts/js/gui/Annotations.js +27 -12
  5. package/src/scripts/js/gui/ScoreManipulator.js +6 -4
  6. package/src/scripts/js/gui/Tabbar.js +13 -4
  7. package/src/scripts/js/handlers/AnnotationChangeHandler.js +13 -1
  8. package/src/scripts/js/handlers/InsertModeHandler.js +3 -3
  9. package/src/scripts/js/handlers/PhantomElementHandler.js +3 -10
  10. package/src/scripts/js/handlers/WindowHandler.js +7 -7
  11. package/src/scripts/js/scripts/Core.js +932 -0
  12. package/src/scripts/js/scripts/MusicProcessor.js +810 -0
  13. package/src/scripts/js/scripts/VIBE.js +219 -0
  14. package/src/scripts/js/scripts/datastructures/MeasureMatrix.js +156 -0
  15. package/src/scripts/js/scripts/gui/Annotations.js +549 -0
  16. package/src/scripts/js/scripts/gui/Cursor.js +203 -0
  17. package/src/scripts/js/scripts/gui/PhantomElement.js +132 -0
  18. package/src/scripts/js/scripts/gui/ScoreManipulator.js +188 -0
  19. package/src/scripts/js/scripts/gui/Tabbar.js +705 -0
  20. package/src/scripts/js/{gui/Toolbar copy.js → scripts/gui/Toolbar.js} +15 -11
  21. package/src/scripts/js/scripts/handlers/AnnotationChangeHandler.js +650 -0
  22. package/src/scripts/js/scripts/handlers/ClickModeHandler.js +535 -0
  23. package/src/scripts/js/{gui → scripts/handlers}/CustomAnnotationShapeDrawer.js +34 -17
  24. package/src/scripts/js/{handlers/ModHandler.js → scripts/handlers/CustomToolbarHandler.js} +54 -66
  25. package/src/scripts/js/scripts/handlers/GlobalKeyboardHandler.js +372 -0
  26. package/src/scripts/js/scripts/handlers/Handler.js +2 -0
  27. package/src/scripts/js/{handlers/InsertModeHandler_deprecated.js → scripts/handlers/InsertModeHandler.js} +117 -164
  28. package/src/scripts/js/scripts/handlers/KeyModeHandler.js +405 -0
  29. package/src/scripts/js/scripts/handlers/LabelHandler.js +463 -0
  30. package/src/scripts/js/scripts/handlers/NoteDragHandler.js +97 -0
  31. package/src/scripts/js/scripts/handlers/PhantomElementHandler.js +161 -0
  32. package/src/scripts/js/scripts/handlers/ScoreManipulatorHandler.js +233 -0
  33. package/src/scripts/js/scripts/handlers/SidebarHandler.js +506 -0
  34. package/src/scripts/js/scripts/handlers/TooltipHandler.js +132 -0
  35. package/src/scripts/js/scripts/handlers/WindowHandler.js +278 -0
  36. package/src/scripts/js/scripts/utils/MEIOperations.js +2121 -0
  37. package/src/scripts/js/{utils/Mouse2MEI.js → scripts/utils/Mouse2SVG.js} +225 -57
  38. package/src/scripts/js/scripts/utils/SVGEditor.js +453 -0
  39. package/src/scripts/js/scripts/utils/Types.js +2 -0
  40. package/src/scripts/js/{utils/VerovioWrapper copy.js → scripts/utils/VerovioWrapper.js} +32 -18
  41. package/src/scripts/js/scripts/utils/coordinates.js +78 -0
  42. package/src/scripts/js/utils/Mouse2SVG.js +11 -4
  43. package/src/scripts/js/utils/VerovioWrapper.js +4 -4
  44. package/src/scripts/js/utils/coordinates.js +26 -2
  45. package/src/styles/vibe.css +32 -6
  46. package/src/scripts/js/.DS_Store +0 -0
  47. package/src/scripts/js/MusicPlayer.js +0 -572
  48. package/src/scripts/js/datastructures/ScoreGraph copy.js +0 -432
  49. package/src/scripts/js/gui/CustomAnnotationDrawer.js +0 -114
  50. package/src/scripts/js/handlers/AnnotationDragHandler.js +0 -113
  51. package/src/scripts/js/handlers/AnnotationLineHandler.js +0 -113
  52. package/src/scripts/js/handlers/ArticulationHandler.js +0 -20
  53. package/src/scripts/js/handlers/HarmonyHandler.js +0 -282
  54. package/src/scripts/js/handlers/InsertModeHandler copy.js +0 -423
  55. package/src/scripts/js/handlers/KeyModeHandler copy.js +0 -407
  56. package/src/scripts/js/handlers/KeyModeHandler_deprecated.js +0 -411
  57. package/src/scripts/js/handlers/NoteDragHandler copy.js +0 -148
  58. package/src/scripts/js/handlers/NoteDragHandler_deprecated.js +0 -150
  59. package/src/scripts/js/handlers/SelectionHandler.js +0 -262
  60. package/src/scripts/js/utils/RectWrapper.js +0 -10
  61. package/src/scripts/js/utils/SVGFiller.js +0 -245
  62. package/src/scripts/js/utils/VerovioWrapperLocal.js +0 -156
  63. package/src/scripts/js/utils/firefoxBBoxes.js +0 -143
  64. /package/src/scripts/js/{assets → scripts/assets}/mei_template.js +0 -0
  65. /package/src/scripts/js/{constants.js → scripts/constants.js} +0 -0
  66. /package/src/scripts/js/{datastructures → scripts/datastructures}/ScoreGraph.js +0 -0
  67. /package/src/scripts/js/{datastructures → scripts/datastructures}/ScoreGraph_deprecated.js +0 -0
  68. /package/src/scripts/js/{datastructures → scripts/datastructures}/ScoreNode.js +0 -0
  69. /package/src/scripts/js/{gui → scripts/gui}/HarmonyLabel.js +0 -0
  70. /package/src/scripts/js/{gui → scripts/gui}/Label.js +0 -0
  71. /package/src/scripts/js/{gui → scripts/gui}/TempoLabel.js +0 -0
  72. /package/src/scripts/js/{handlers → scripts/handlers}/DeleteHandler.js +0 -0
  73. /package/src/scripts/js/{utils → scripts/utils}/DOMCreator.js +0 -0
  74. /package/src/scripts/js/{utils → scripts/utils}/MEIConverter.js +0 -0
  75. /package/src/scripts/js/{utils → scripts/utils}/ReactWrapper.js +0 -0
  76. /package/src/scripts/js/{utils → scripts/utils}/convenienceQueries.js +0 -0
  77. /package/src/scripts/js/{utils → scripts/utils}/mappings.js +0 -0
  78. /package/src/scripts/js/{utils → scripts/utils}/random.js +0 -0
@@ -0,0 +1,463 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const meiConverter = require("../utils/MEIConverter");
4
+ const meiOperation = require("../utils/MEIOperations");
5
+ const constants_1 = require("../constants");
6
+ const random_1 = require("../utils/random");
7
+ const HarmonyLabel_1 = require("../gui/HarmonyLabel");
8
+ const TempoLabel_1 = require("../gui/TempoLabel");
9
+ const cq = require("../utils/convenienceQueries");
10
+ const mappings_1 = require("../utils/mappings");
11
+ const labelClasses = ["harm", "tempo", "note", "chord", "fb"];
12
+ const labelSelectors = "." + labelClasses.join(",.");
13
+ class LabelHandler {
14
+ constructor(containerId) {
15
+ this.setHarmonyLabelHandlerClick = (function setHarmonyLabelHandler(e) {
16
+ //if (this.container.classList.contains("harmonyMode")) {
17
+ if (this.container.querySelector("#annotGroupKM > #harmonyAnnotButton.selected")) {
18
+ this.harmonyLabelHandler(e);
19
+ }
20
+ }).bind(this);
21
+ this.setTempoLabelHandlerClick = (function setTempoLabelHandlerClick(e) {
22
+ this.tempoLabelHandler(e);
23
+ }).bind(this);
24
+ this.setHarmonyLabelHandlerKey = (function setHarmonyLabelHandler(e) {
25
+ if (!cq.hasActiveElement(this.containerId))
26
+ return;
27
+ var isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
28
+ var ctrl = e.ctrlKey;
29
+ if (isMac) {
30
+ ctrl = e.metaKey;
31
+ }
32
+ if (ctrl) {
33
+ if (e.key === "k" && Array.from(this.vrvSVG.querySelectorAll(".note, .chord, .rest, .mrest")).some(el => el.classList.contains("marked"))) {
34
+ e.preventDefault();
35
+ this.harmonyLabelHandler(e);
36
+ }
37
+ }
38
+ }).bind(this);
39
+ this.activateHarmonyHighlight = (function highlightNextHarmonyHandler(e) {
40
+ if (e.type === "mouseleave" && !this.isGlobal) {
41
+ this.interactionOverlay.addEventListener("mousemove", this.activateHarmonyHighlight);
42
+ }
43
+ if (!this.isGlobal) {
44
+ this.highlightNextHarmony(e);
45
+ }
46
+ }).bind(this);
47
+ this.deactivateHarmonyHighlight = (function deactivateHighlight(e) {
48
+ // document.querySelectorAll(".marked").forEach(m => {
49
+ // m.classList.remove("marked")
50
+ // })
51
+ this.interactionOverlay.removeEventListener("mousemove", this.activateHarmonyHighlight);
52
+ }).bind(this);
53
+ this.modifyLabelHandler = (function modifyLabelHandler(e) {
54
+ e.stopImmediatePropagation();
55
+ this.vrvSVG.querySelectorAll(".marked").forEach(m => {
56
+ var _a;
57
+ m.classList.remove("marked");
58
+ (_a = this.interactionOverlay.querySelector("*[refId=" + m.id + "]")) === null || _a === void 0 ? void 0 : _a.classList.remove("marked");
59
+ });
60
+ this.modifyLabel(e);
61
+ }).bind(this);
62
+ /**
63
+ * Wrapper function for submitlabel()
64
+ */
65
+ this.submitLabelHandler = (function submitHandler(e) {
66
+ if (!cq.hasActiveElement(this.containerId))
67
+ return;
68
+ if (e.key === "Enter" && this.labelCanvas.hasChildNodes()) {
69
+ e.target.removeEventListener("keydown", this.submitLabelHandler);
70
+ this.submitLabel();
71
+ }
72
+ }).bind(this);
73
+ this.typeLabelHandler = (function (e) {
74
+ if (!cq.hasActiveElement(this.containerId))
75
+ return;
76
+ var factor = 1.3;
77
+ var t = e.target;
78
+ var parent = t.parentElement;
79
+ var tWidth = (t.getBoundingClientRect().width * factor).toString();
80
+ var tHeigth = (t.getBoundingClientRect().height * factor).toString();
81
+ parent.setAttribute("width", tWidth);
82
+ parent.setAttribute("height", tHeigth);
83
+ }).bind(this);
84
+ this.closeModifyWindowHandler = (function closeModifyWindow(e) {
85
+ if (e instanceof KeyboardEvent) {
86
+ if (e.key === "Escape") {
87
+ this.closeModifyWindow();
88
+ }
89
+ }
90
+ else if (e instanceof MouseEvent && !e.target.classList.contains("labelFO")) {
91
+ this.closeModifyWindow();
92
+ }
93
+ }).bind(this);
94
+ this.setContainerId(containerId);
95
+ this.addCanvas();
96
+ }
97
+ /**
98
+ * Set own canvas for manipulating labels
99
+ */
100
+ addCanvas() {
101
+ this.rootBBox = this.interactionOverlay.getBoundingClientRect();
102
+ var rootWidth = this.rootBBox.width.toString();
103
+ var rootHeigth = this.rootBBox.height.toString();
104
+ var vb = this.interactionOverlay.getAttribute("viewBox");
105
+ this.labelCanvas = this.interactionOverlay.querySelector("#labelCanvas");
106
+ if (!this.labelCanvas) {
107
+ this.labelCanvas = document.createElementNS(constants_1.constants._SVGNS_, "svg");
108
+ this.labelCanvas.setAttribute("id", "labelCanvas");
109
+ this.labelCanvas.classList.add("canvas");
110
+ //this.labelCanvas.setAttribute("viewBox", ["0", "0", rootWidth, rootHeigth].join(" "))
111
+ }
112
+ //this.labelCanvas.setAttribute("viewBox", vb)
113
+ this.interactionOverlay.insertBefore(this.labelCanvas, this.interactionOverlay.firstChild);
114
+ return this;
115
+ }
116
+ /**
117
+ * Create label instances for elements already present in the score.
118
+ */
119
+ initLabels() {
120
+ this.labels = new Map();
121
+ this.vrvSVG.querySelectorAll(labelSelectors).forEach(el => {
122
+ var _a;
123
+ var className = labelClasses.filter(l => this.vrvSVG.querySelector("#" + el.id).classList.contains(l))[0];
124
+ var inputString = "";
125
+ switch (className) {
126
+ case "harm":
127
+ if (el.querySelector(".fb") !== null) {
128
+ this.currentMEI.querySelectorAll("#" + el.id + " f").forEach(f => {
129
+ inputString += " " + f.textContent;
130
+ });
131
+ inputString = inputString.trim();
132
+ }
133
+ else {
134
+ inputString = this.currentMEI.getElementById(el.id).textContent;
135
+ }
136
+ this.labels.set(el.id, new HarmonyLabel_1.default(inputString, el.id, this.currentMEI));
137
+ break;
138
+ case "tempo":
139
+ inputString = ((_a = Array.from(this.vrvSVG.querySelector("#" + el.id).querySelectorAll(".text")).filter(e => /\d+/.test(e.textContent))[0]) === null || _a === void 0 ? void 0 : _a.textContent.match(/\d+/).join("")) || "";
140
+ this.labels.set(el.id, new TempoLabel_1.default(inputString, el.id, this.currentMEI));
141
+ break;
142
+ }
143
+ });
144
+ }
145
+ setListeners() {
146
+ document.querySelectorAll(".sylTextRect").forEach(s => {
147
+ s.remove();
148
+ });
149
+ // isGlobal = false: Editor is not in harmony mode
150
+ if (!this.isGlobal) {
151
+ this.interactionOverlay.addEventListener("click", this.setHarmonyLabelHandlerClick, true);
152
+ this.interactionOverlay.addEventListener("mousemove", this.activateHarmonyHighlight);
153
+ this.interactionOverlay.addEventListener("keydown", this.closeModifyWindowHandler, true);
154
+ }
155
+ this.interactionOverlay.addEventListener("click", this.closeModifyWindowHandler);
156
+ document.addEventListener("keydown", this.setHarmonyLabelHandlerKey);
157
+ this.interactionOverlay.querySelectorAll(labelSelectors).forEach(h => {
158
+ h.addEventListener("mouseover", this.deactivateHarmonyHighlight);
159
+ h.addEventListener("mouseleave", this.activateHarmonyHighlight);
160
+ h.addEventListener("dblclick", this.modifyLabelHandler);
161
+ });
162
+ this.interactionOverlay.querySelectorAll(".harm, .label, .manipulator").forEach(h => h.addEventListener("click", (e) => {
163
+ e.stopImmediatePropagation();
164
+ e.stopPropagation();
165
+ })); // prevent inseerting notes, wenn cursor is over a harm symbol
166
+ return this;
167
+ }
168
+ removeListeners() {
169
+ this.interactionOverlay.removeEventListener("click", this.closeModifyWindowHandler);
170
+ this.interactionOverlay.removeEventListener("click", this.setHarmonyLabelHandlerClick);
171
+ document.removeEventListener("keydown", this.setHarmonyLabelHandlerKey);
172
+ this.interactionOverlay.removeEventListener("mousemove", this.activateHarmonyHighlight);
173
+ this.interactionOverlay.removeEventListener("keydown", this.closeModifyWindowHandler);
174
+ this.interactionOverlay.querySelectorAll(labelSelectors).forEach(h => {
175
+ h.removeEventListener("mouseenter", this.deactivateHarmonyHighlight);
176
+ h.removeEventListener("mouseleave", this.activateHarmonyHighlight);
177
+ h.removeEventListener("dblclick", this.modifyLabelHandler);
178
+ });
179
+ return this;
180
+ }
181
+ // HARMONY LABELS
182
+ /**
183
+ * Open Inputbox for (first) selected Note
184
+ */
185
+ harmonyLabelHandler(e) {
186
+ var nextNote = this.vrvSVG.querySelector(".note.marked, .chord.marked");
187
+ if (nextNote === null) {
188
+ return;
189
+ }
190
+ var nextNoteBBox = nextNote.getBoundingClientRect();
191
+ var staffBBox = nextNote.closest(".staff").getBoundingClientRect();
192
+ var canvasMatrix = this.labelCanvas.getScreenCTM().inverse();
193
+ var ptNoteLT = new DOMPoint(nextNoteBBox.left, nextNoteBBox.top);
194
+ ptNoteLT = ptNoteLT.matrixTransform(canvasMatrix);
195
+ var ptNoteRB = new DOMPoint(nextNoteBBox.right, nextNoteBBox.bottom);
196
+ ptNoteRB = ptNoteRB.matrixTransform(canvasMatrix);
197
+ var ptNoteWidth = Math.abs(ptNoteRB.x - ptNoteLT.x);
198
+ var ptNoteHeight = Math.abs(ptNoteRB.y - ptNoteLT.y);
199
+ var ptStaffLT = new DOMPoint(staffBBox.left, staffBBox.top);
200
+ ptStaffLT = ptStaffLT.matrixTransform(canvasMatrix);
201
+ var ptStaffRB = new DOMPoint(staffBBox.right, staffBBox.bottom);
202
+ ptStaffRB = ptStaffRB.matrixTransform(canvasMatrix);
203
+ var ptStaffWidth = Math.abs(ptStaffRB.x - ptStaffLT.x);
204
+ var ptStaffHeight = Math.abs(ptStaffRB.y - ptStaffLT.y);
205
+ var posx = ptNoteLT.x - ptNoteWidth / 2; //nextNoteBBox.left - nextNoteBBox.width/2 - window.scrollX - rootBBox.x - root.scrollLeft
206
+ var posy = ptStaffRB.y; //staffBBox.bottom - window.scrollY - rootBBox.y - root.scrollLeft
207
+ var tstamp = meiOperation.getElementTimestampById(nextNote.id, this.currentMEI);
208
+ var existsTstamp = Array.from(this.currentMEI.getElementById(nextNote.id).closest("measure").querySelectorAll("harm")).some(h => {
209
+ if (h.getAttribute("tstamp") !== null) {
210
+ return parseFloat(h.getAttribute("tstamp")) === tstamp;
211
+ }
212
+ else {
213
+ return false;
214
+ }
215
+ });
216
+ var hasStartId = this.currentMEI.querySelector("harm[startid=\"" + nextNote.id + "\"]") !== null;
217
+ var isEmptyLabelCanvas = !this.labelCanvas.hasChildNodes();
218
+ if (!hasStartId && isEmptyLabelCanvas && !existsTstamp) {
219
+ this.createInputBox(posx, posy, nextNote.id, "harm");
220
+ }
221
+ else if (!isEmptyLabelCanvas) {
222
+ this.closeModifyWindow();
223
+ }
224
+ }
225
+ setLabel(labelString, bboxId) {
226
+ var className = labelClasses.filter(l => this.vrvSVG.querySelector("#" + bboxId).classList.contains(l))[0];
227
+ var label;
228
+ switch (className) {
229
+ case "note":
230
+ case "chord":
231
+ case "harm":
232
+ label = new HarmonyLabel_1.default(labelString, bboxId, this.currentMEI);
233
+ break;
234
+ case "tempo":
235
+ label = new TempoLabel_1.default(labelString, bboxId, this.currentMEI);
236
+ break;
237
+ default:
238
+ return;
239
+ }
240
+ if (this.labels.get(label.getElement().id) == undefined) {
241
+ this.labels.set(label.getElement().id, label);
242
+ }
243
+ return label;
244
+ }
245
+ highlightNextHarmony(e, active = true) {
246
+ if (!active) {
247
+ return;
248
+ }
249
+ var pt = new DOMPoint(e.clientX, e.clientY);
250
+ var rootMatrix = this.labelCanvas.getScreenCTM().inverse();
251
+ pt = pt.matrixTransform(rootMatrix);
252
+ var posx = pt.x;
253
+ var posy = pt.y;
254
+ var nextNoteBBox = this.m2s.findScoreTarget(posx, posy);
255
+ if (nextNoteBBox == undefined) {
256
+ return;
257
+ }
258
+ var el = this.vrvSVG.querySelector("#" + nextNoteBBox.id);
259
+ if (el.closest(".chord") !== null) {
260
+ el = el.closest(".chord");
261
+ }
262
+ if (!el.classList.contains("marked")) {
263
+ this.vrvSVG.querySelectorAll(".marked").forEach(m => {
264
+ var _a;
265
+ m.classList.remove("marked");
266
+ (_a = this.interactionOverlay.querySelector("[refId=" + m.id + "]")) === null || _a === void 0 ? void 0 : _a.classList.remove("marked");
267
+ });
268
+ el.classList.add("marked");
269
+ }
270
+ }
271
+ /**
272
+ * modify existing label
273
+ * @param e
274
+ * @returns
275
+ */
276
+ modifyLabel(e) {
277
+ var _a, _b;
278
+ this.closeModifyWindow();
279
+ var target = e.target;
280
+ if (target.id === "") {
281
+ var refId = (_a = target.closest("[refId]")) === null || _a === void 0 ? void 0 : _a.getAttribute("refId");
282
+ if (refId === null)
283
+ return;
284
+ target = (_b = this.vrvSVG.querySelector("#" + refId)) === null || _b === void 0 ? void 0 : _b.closest(".harm");
285
+ }
286
+ target = target.closest(labelSelectors);
287
+ target.setAttribute("visibility", "hidden");
288
+ var targetBBox = target.getBoundingClientRect();
289
+ var pt = new DOMPoint(targetBBox.x, targetBBox.y);
290
+ var rootMatrix = this.labelCanvas.getScreenCTM().inverse();
291
+ pt = pt.matrixTransform(rootMatrix);
292
+ var posx = pt.x - 5;
293
+ var posy = pt.y - 5;
294
+ // prevent double input boxes for same Element
295
+ this.elementId = target.id;
296
+ if (this.container.querySelector("*[refElementId=\"" + target.id + "\"]") !== null) {
297
+ return;
298
+ }
299
+ var className = labelClasses.filter(l => target.classList.contains(l))[0]; //assume only one output, therefore alway return idx 0
300
+ this.createInputBox(posx, posy, target.id, className);
301
+ }
302
+ /**
303
+ * Close the modifier Window and make the hidden Element visible again
304
+ */
305
+ closeModifyWindow() {
306
+ try {
307
+ Array.from(this.labelCanvas.children).forEach(c => {
308
+ c === null || c === void 0 ? void 0 : c.remove();
309
+ });
310
+ }
311
+ catch (_a) { }
312
+ // clean MEI from empty harm Elements
313
+ this.currentMEI.querySelectorAll(labelClasses.join(",")).forEach(h => {
314
+ var _a;
315
+ if (h.id === "")
316
+ return;
317
+ (_a = this.container.querySelector("#" + h.id)) === null || _a === void 0 ? void 0 : _a.setAttribute("visibility", "visible");
318
+ });
319
+ }
320
+ /**
321
+ * Save label information in current MEI
322
+ */
323
+ submitLabel() {
324
+ var labelDiv = this.labelCanvas.getElementsByClassName("labelDiv")[0];
325
+ var text = labelDiv.textContent;
326
+ var refElementClass = labelClasses.filter(l => this.container.querySelector("#" + labelDiv.closest("g").getAttribute("refElementId")).classList.contains(l))[0]; // assume only one result
327
+ var label = this.labels.get(labelDiv.closest("g").getAttribute("refElementId"));
328
+ if (refElementClass === "harm") { // change existing harm
329
+ let harmLabel = label;
330
+ harmLabel.modifyLabel(text);
331
+ //this.currentMEI.getElementById(harmLabel.getElement().id).replaceWith(harmLabel.getElement())
332
+ }
333
+ else if (["note", "chord"].some(cn => refElementClass === cn)) { //create new harm
334
+ let harmLabel = this.setLabel(labelDiv.textContent, labelDiv.closest("g").getAttribute("refElementId"));
335
+ this.currentMEI.getElementById(harmLabel.getStartId()).closest("measure").append(harmLabel.getElement());
336
+ }
337
+ else if (refElementClass === "tempo") { // change existing tempo
338
+ var tempoLabel = label;
339
+ tempoLabel.modifyLabel(text);
340
+ }
341
+ this.closeModifyWindow();
342
+ meiOperation.cleanUp(this.currentMEI);
343
+ var mei = meiConverter.restoreXmlIdTags(this.currentMEI);
344
+ this.loadDataCallback("", mei, false).then(() => {
345
+ this.reset();
346
+ });
347
+ }
348
+ createInputBox(posx, posy, targetId, targetClass) {
349
+ var textGroup = document.createElementNS(constants_1.constants._SVGNS_, "g");
350
+ textGroup.setAttribute("id", random_1.uuidv4());
351
+ textGroup.setAttribute("refElementId", targetId);
352
+ var text = document.createElementNS(constants_1.constants._SVGNS_, "svg");
353
+ text.classList.add("labelText");
354
+ var textForeignObject = document.createElementNS(constants_1.constants._SVGNS_, "foreignObject");
355
+ textForeignObject.classList.add("labelFO");
356
+ var textDiv = document.createElement("div");
357
+ textDiv.setAttribute("contenteditable", "true");
358
+ switch (targetClass) {
359
+ case "harm":
360
+ if (this.labels.get(targetId) != undefined) {
361
+ var t = this.labels.get(targetId).getInput();
362
+ for (const [key, value] of mappings_1.unicodeToKey.entries()) {
363
+ t = t.replace(key, value);
364
+ }
365
+ textDiv.textContent = t;
366
+ }
367
+ else {
368
+ textDiv.textContent = "";
369
+ }
370
+ break;
371
+ case "tempo":
372
+ textDiv.textContent = Array.from(this.container.querySelector("#" + targetId).querySelectorAll(".text")).filter(el => /\d+/.test(el.textContent))[0].textContent.match(/\d+/).join("") || "";
373
+ break;
374
+ default:
375
+ return;
376
+ }
377
+ textDiv.classList.add("labelDiv");
378
+ text.append(textForeignObject);
379
+ this.container.appendChild(textDiv);
380
+ var rectPadding = 5;
381
+ text.setAttribute("x", (posx + rectPadding).toString());
382
+ text.setAttribute("y", (posy).toString());
383
+ textForeignObject.setAttribute("x", "0");
384
+ textForeignObject.setAttribute("y", "0");
385
+ textForeignObject.setAttribute("height", "1000"); //(textDiv.clientHeight + 2 * rectPadding).toString())
386
+ textForeignObject.setAttribute("width", "1000"); //(textDiv.clientHeight + 2 * rectPadding).toString())
387
+ this.labelCanvas.appendChild(textGroup);
388
+ textGroup.appendChild(text);
389
+ textForeignObject.appendChild(textDiv);
390
+ // Special Listeners while Editing Harmonies
391
+ var that = this;
392
+ textDiv.addEventListener("focus", function () {
393
+ that.removeListeners();
394
+ that.musicPlayer.removePlayListener();
395
+ });
396
+ textDiv.addEventListener("blur", function () {
397
+ textDiv.dispatchEvent(new KeyboardEvent("keydown", { "key": "Enter" })); // trigger submitLabel when bluring
398
+ that.setListeners();
399
+ that.musicPlayer.setPlayListener();
400
+ });
401
+ textDiv.addEventListener("keydown", this.submitLabelHandler);
402
+ textDiv.addEventListener("keydown", this.typeLabelHandler);
403
+ textDiv.focus();
404
+ }
405
+ getTimestamp(note) {
406
+ var layer = note.closest("layer");
407
+ var elements = Array.from(layer.querySelectorAll("*[dur]"));
408
+ elements = elements.filter((v, i) => i <= elements.indexOf(note));
409
+ var tstamp = 0;
410
+ elements.forEach(e => {
411
+ var dur = parseInt(e.getAttribute("dur"));
412
+ tstamp += 4 / dur;
413
+ var dots = e.getAttribute("dots");
414
+ var add = dur;
415
+ if (dots !== null) {
416
+ for (var i = 0; i < parseInt(dots); i++) {
417
+ add = add / 2;
418
+ tstamp += add;
419
+ }
420
+ }
421
+ });
422
+ return tstamp;
423
+ }
424
+ reset() {
425
+ this.setContainerId(this.containerId);
426
+ this.addCanvas();
427
+ this.initLabels();
428
+ this.removeListeners();
429
+ this.setListeners();
430
+ return this;
431
+ }
432
+ setm2s(m2s) {
433
+ this.m2s = m2s;
434
+ return this;
435
+ }
436
+ setCurrentMEI(mei) {
437
+ this.currentMEI = mei;
438
+ return this;
439
+ }
440
+ setMusicProcessor(musicPlayer) {
441
+ this.musicPlayer = musicPlayer;
442
+ return this;
443
+ }
444
+ setGlobal(global) {
445
+ this.isGlobal = global;
446
+ return this;
447
+ }
448
+ getGlobal() {
449
+ return this.isGlobal;
450
+ }
451
+ setLoadDataCallback(loadDataCallback) {
452
+ this.loadDataCallback = loadDataCallback;
453
+ return this;
454
+ }
455
+ setContainerId(id) {
456
+ this.containerId = id;
457
+ this.container = document.getElementById(id);
458
+ this.vrvSVG = cq.getVrvSVG(id);
459
+ this.interactionOverlay = cq.getInteractOverlay(id);
460
+ return this;
461
+ }
462
+ }
463
+ exports.default = LabelHandler;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const coordinates = require("../utils/coordinates");
4
+ const cq = require("../utils/convenienceQueries");
5
+ const interactjs_1 = require("interactjs");
6
+ /**
7
+ * Class that handles insert mode, events, and actions.
8
+ */
9
+ class NoteDragHandler {
10
+ constructor(containerId) {
11
+ this.setContainerId(containerId);
12
+ }
13
+ setListeners() {
14
+ var that = this;
15
+ this.noteDragListener = interactjs_1.default("#" + this.containerId + " #interactionOverlay .notehead rect")
16
+ .draggable({
17
+ startAxis: "y",
18
+ lockAxis: "y",
19
+ listeners: {
20
+ move: this.dragNote.bind(this),
21
+ end(event) {
22
+ that.deleteTempDistances();
23
+ that.insertCallback(that.newNote, true);
24
+ }
25
+ },
26
+ modifiers: [
27
+ interactjs_1.default.modifiers.restrictRect({
28
+ endOnly: true
29
+ })
30
+ ]
31
+ });
32
+ }
33
+ removeListeners() {
34
+ var _a;
35
+ (_a = this.noteDragListener) === null || _a === void 0 ? void 0 : _a.unset();
36
+ }
37
+ resetListeners() {
38
+ this.removeListeners();
39
+ this.setListeners();
40
+ return this;
41
+ }
42
+ deleteTempDistances() {
43
+ var _a;
44
+ (_a = cq.getInteractOverlay(this.containerId)) === null || _a === void 0 ? void 0 : _a.querySelectorAll("*[distY]").forEach(d => {
45
+ d.removeAttribute("distY");
46
+ d.classList.remove("moving");
47
+ });
48
+ }
49
+ dragNote(e) {
50
+ var _a;
51
+ var noteHeadBBox = e.target;
52
+ this.noteDragEvent = new MouseEvent("draggingNote", e);
53
+ noteHeadBBox.dispatchEvent(this.noteDragEvent);
54
+ var refNote = cq.getVrvSVG(this.containerId).querySelector("#" + noteHeadBBox.parentElement.getAttribute("refId")).closest(".note");
55
+ var note = cq.getInteractOverlay(this.containerId).querySelector("*[refId=\"" + refNote.id + "\"] rect");
56
+ if (!noteHeadBBox.classList.contains("moving"))
57
+ noteHeadBBox.classList.add("moving");
58
+ var headPos = this.newPos(noteHeadBBox, e);
59
+ this.m2s.defineNote(headPos.x, headPos.y, {});
60
+ this.newNote = this.m2s.getNewNote();
61
+ if (refNote.closest(".chord") !== null) {
62
+ this.newNote.chordElement = refNote.closest(".chord");
63
+ (_a = this.currentMEI.querySelector("#" + refNote.id)) === null || _a === void 0 ? void 0 : _a.remove();
64
+ }
65
+ }
66
+ newPos(target, e) {
67
+ var pt = coordinates.transformToDOMMatrixCoordinates(e.clientX, e.clientY, target.closest("*[viewBox]"));
68
+ var edy = pt.y;
69
+ var ptDist = coordinates.transformToDOMMatrixCoordinates(target.getBoundingClientRect().x, target.getBoundingClientRect().y, target.closest("*[viewBox]"));
70
+ var distY = (parseFloat(target.getAttribute('distY'))) || edy - ptDist.y;
71
+ target.setAttribute("distY", distY.toString());
72
+ target.setAttribute("y", (edy - distY).toString());
73
+ return { x: pt.x, y: pt.y };
74
+ }
75
+ //////////////// GETTER/ SETTER ////////////
76
+ setMusicProcessor(musicPlayer) {
77
+ this.musicPlayer = musicPlayer;
78
+ return this;
79
+ }
80
+ setCurrentMEI(xmlDoc) {
81
+ this.currentMEI = xmlDoc;
82
+ return this;
83
+ }
84
+ setm2s(m2s) {
85
+ this.m2s = m2s;
86
+ return this;
87
+ }
88
+ setInsertCallback(insertCallback) {
89
+ this.insertCallback = insertCallback;
90
+ return this;
91
+ }
92
+ setContainerId(id) {
93
+ this.containerId = id;
94
+ return this;
95
+ }
96
+ }
97
+ exports.default = NoteDragHandler;