abcjs 6.1.0 → 6.1.3
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.
- package/README.md +4 -0
- package/RELEASE.md +29 -0
- package/SECURITY.md +9 -0
- package/abcjs-audio.css +1 -0
- package/dist/abcjs-basic-min.js +2 -2
- package/dist/abcjs-basic.js +151 -130
- package/dist/abcjs-basic.js.map +1 -1
- package/dist/abcjs-plugin-min.js +2 -2
- package/package.json +1 -1
- package/src/api/abc_tunebook_svg.js +2 -98
- package/src/tablatures/tab-renderer.js +1 -1
- package/src/write/abc_engraver_controller.js +72 -1
- package/src/write/draw/draw.js +8 -0
- package/src/write/draw/staff-group.js +5 -5
- package/src/write/selection.js +48 -12
- package/src/write/svg.js +1 -1
- package/types/index.d.ts +44 -0
- package/version.js +1 -1
package/dist/abcjs-basic.js
CHANGED
|
@@ -1101,101 +1101,6 @@ function renderOne(div, tune, params, tuneNumber, lineOffset) {
|
|
|
1101
1101
|
var parent = div.parentNode;
|
|
1102
1102
|
parent.style.width = div.style.width;
|
|
1103
1103
|
}
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
function renderEachLineSeparately(div, tune, params, tuneNumber) {
|
|
1107
|
-
function initializeTuneLine(tune) {
|
|
1108
|
-
var obj = new Tune();
|
|
1109
|
-
obj.formatting = tune.formatting;
|
|
1110
|
-
obj.media = tune.media;
|
|
1111
|
-
obj.version = tune.version;
|
|
1112
|
-
return obj;
|
|
1113
|
-
} // Before rendering, chop up the returned tune into an array where each element is a line.
|
|
1114
|
-
// The first element of the array gets the title and other items that go on top, the last element
|
|
1115
|
-
// of the array gets the extra text that goes on bottom. Each element gets any non-music info that comes before it.
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
var tunes = [];
|
|
1119
|
-
var tuneLine;
|
|
1120
|
-
|
|
1121
|
-
for (var i = 0; i < tune.lines.length; i++) {
|
|
1122
|
-
var line = tune.lines[i];
|
|
1123
|
-
if (!tuneLine) tuneLine = initializeTuneLine(tune);
|
|
1124
|
-
|
|
1125
|
-
if (i === 0) {
|
|
1126
|
-
// These items go on top of the music
|
|
1127
|
-
tuneLine.copyTopInfo(tune);
|
|
1128
|
-
} // push the lines until we get to a music line
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
tuneLine.lines.push(line);
|
|
1132
|
-
|
|
1133
|
-
if (line.staff) {
|
|
1134
|
-
tunes.push(tuneLine);
|
|
1135
|
-
tuneLine = undefined;
|
|
1136
|
-
}
|
|
1137
|
-
} // Add any extra stuff to the last line.
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
if (tuneLine) {
|
|
1141
|
-
var lastLine = tunes[tunes.length - 1];
|
|
1142
|
-
|
|
1143
|
-
for (var j = 0; j < tuneLine.lines.length; j++) {
|
|
1144
|
-
lastLine.lines.push(tuneLine.lines[j]);
|
|
1145
|
-
}
|
|
1146
|
-
} // These items go below the music
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
tuneLine = tunes[tunes.length - 1];
|
|
1150
|
-
tuneLine.copyBottomInfo(tune); // Now create sub-divs and render each line. Need to copy the params to change the padding for the interior slices.
|
|
1151
|
-
|
|
1152
|
-
var ep = {};
|
|
1153
|
-
|
|
1154
|
-
for (var key in params) {
|
|
1155
|
-
if (params.hasOwnProperty(key)) {
|
|
1156
|
-
ep[key] = params[key];
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
var origPaddingTop = ep.paddingtop;
|
|
1161
|
-
var origPaddingBottom = ep.paddingbottom;
|
|
1162
|
-
var currentScrollY = div.parentNode.scrollTop; // If there is scrolling it will be lost during the redraw so remember it.
|
|
1163
|
-
|
|
1164
|
-
var currentScrollX = div.parentNode.scrollLeft;
|
|
1165
|
-
div.innerHTML = "";
|
|
1166
|
-
var lineCount = 0;
|
|
1167
|
-
|
|
1168
|
-
for (var k = 0; k < tunes.length; k++) {
|
|
1169
|
-
var lineEl = document.createElement("div");
|
|
1170
|
-
div.appendChild(lineEl);
|
|
1171
|
-
|
|
1172
|
-
if (k === 0) {
|
|
1173
|
-
ep.paddingtop = origPaddingTop;
|
|
1174
|
-
ep.paddingbottom = 0;
|
|
1175
|
-
} else if (k === tunes.length - 1) {
|
|
1176
|
-
ep.paddingtop = 10;
|
|
1177
|
-
ep.paddingbottom = origPaddingBottom;
|
|
1178
|
-
} else {
|
|
1179
|
-
ep.paddingtop = 10;
|
|
1180
|
-
ep.paddingbottom = 0;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
if (k < tunes.length - 1) {
|
|
1184
|
-
// If it is not the last line, force stretchlast. If it is, stretchlast might have been set by the input parameters.
|
|
1185
|
-
tunes[k].formatting = parseCommon.clone(tunes[k].formatting);
|
|
1186
|
-
tunes[k].formatting.stretchlast = true;
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
renderOne(lineEl, tunes[k], ep, tuneNumber, lineCount);
|
|
1190
|
-
lineCount += tunes[k].lines.length;
|
|
1191
|
-
if (k === 0) tune.engraver = tunes[k].engraver;else {
|
|
1192
|
-
if (!tune.engraver.staffgroups) tune.engraver.staffgroups = tunes[k].engraver.staffgroups;else if (tunes[k].engraver.staffgroups.length > 0) tune.engraver.staffgroups.push(tunes[k].engraver.staffgroups[0]);
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
if (currentScrollX || currentScrollY) {
|
|
1197
|
-
div.parentNode.scrollTo(currentScrollX, currentScrollY);
|
|
1198
|
-
}
|
|
1199
1104
|
} // A quick way to render a tune from javascript when interactivity is not required.
|
|
1200
1105
|
// This is used when a javascript routine has some abc text that it wants to render
|
|
1201
1106
|
// in a div or collection of divs. One tune or many can be rendered.
|
|
@@ -1266,8 +1171,9 @@ var renderAbc = function renderAbc(output, abc, parserParams, engraverParams, re
|
|
|
1266
1171
|
if (!removeDiv && params.wrap && params.staffwidth) {
|
|
1267
1172
|
tune = doLineWrapping(div, tune, tuneNumber, abcString, params);
|
|
1268
1173
|
return tune;
|
|
1269
|
-
}
|
|
1174
|
+
}
|
|
1270
1175
|
|
|
1176
|
+
renderOne(div, tune, params, tuneNumber, 0);
|
|
1271
1177
|
if (removeDiv) div.parentNode.removeChild(div);
|
|
1272
1178
|
return null;
|
|
1273
1179
|
}
|
|
@@ -1288,7 +1194,7 @@ function doLineWrapping(div, tune, tuneNumber, abcString, params) {
|
|
|
1288
1194
|
if (warnings) tune.warnings = warnings;
|
|
1289
1195
|
}
|
|
1290
1196
|
|
|
1291
|
-
|
|
1197
|
+
renderOne(div, tune, ret.revisedParams, tuneNumber, 0);
|
|
1292
1198
|
tune.explanation = ret.explanation;
|
|
1293
1199
|
return tune;
|
|
1294
1200
|
}
|
|
@@ -19066,7 +18972,7 @@ TabRenderer.prototype.doLayout = function () {
|
|
|
19066
18972
|
var padd = 3;
|
|
19067
18973
|
var prevIndex = this.staffIndex;
|
|
19068
18974
|
var previousStaff = staffGroup.staffs[prevIndex];
|
|
19069
|
-
var tabTop =
|
|
18975
|
+
var tabTop = this.tabSize + padd - previousStaff.bottom - lyricsHeight;
|
|
19070
18976
|
|
|
19071
18977
|
if (previousStaff.isTabStaff) {
|
|
19072
18978
|
tabTop = previousStaff.top;
|
|
@@ -21992,6 +21898,7 @@ var tablatures = __webpack_require__(/*! ../api/abc_tablatures */ "./src/api/abc
|
|
|
21992
21898
|
|
|
21993
21899
|
var EngraverController = function EngraverController(paper, params) {
|
|
21994
21900
|
params = params || {};
|
|
21901
|
+
this.oneSvgPerLine = params.oneSvgPerLine;
|
|
21995
21902
|
this.selectionColor = params.selectionColor;
|
|
21996
21903
|
this.dragColor = params.dragColor ? params.dragColor : params.selectionColor;
|
|
21997
21904
|
this.dragging = !!params.dragging;
|
|
@@ -22208,8 +22115,82 @@ EngraverController.prototype.engraveTune = function (abcTune, tuneNumber, lineOf
|
|
|
22208
22115
|
var ret = draw(this.renderer, this.classes, abcTune, this.width, maxWidth, this.responsive, scale, this.selectTypes, tuneNumber, lineOffset);
|
|
22209
22116
|
this.staffgroups = ret.staffgroups;
|
|
22210
22117
|
this.selectables = ret.selectables;
|
|
22211
|
-
|
|
22212
|
-
|
|
22118
|
+
|
|
22119
|
+
if (this.oneSvgPerLine) {
|
|
22120
|
+
var div = this.renderer.paper.svg.parentNode;
|
|
22121
|
+
this.svgs = splitSvgIntoLines(div, abcTune.metaText.title, this.responsive);
|
|
22122
|
+
} else {
|
|
22123
|
+
this.svgs = [this.renderer.paper.svg];
|
|
22124
|
+
}
|
|
22125
|
+
|
|
22126
|
+
setupSelection(this, this.svgs);
|
|
22127
|
+
};
|
|
22128
|
+
|
|
22129
|
+
function splitSvgIntoLines(output, title, responsive) {
|
|
22130
|
+
// Each line is a top level <g> in the svg. To split it into separate
|
|
22131
|
+
// svgs iterate through each of those and put them in a new svg. Since
|
|
22132
|
+
// they are placed absolutely, the viewBox needs to be manipulated to
|
|
22133
|
+
// get the correct vertical positioning.
|
|
22134
|
+
// We copy all the attributes from the original svg except for the aria-label
|
|
22135
|
+
// since we want that to include a count. And the height is now a fraction of the original svg.
|
|
22136
|
+
if (!title) title = "Untitled";
|
|
22137
|
+
var source = output.querySelector("svg");
|
|
22138
|
+
if (responsive === 'resize') output.style.paddingBottom = '';
|
|
22139
|
+
var style = source.querySelector("style");
|
|
22140
|
+
var width = responsive === 'resize' ? source.viewBox.baseVal.width : source.getAttribute("width");
|
|
22141
|
+
var sections = output.querySelectorAll("svg > g"); // each section is a line, or the top matter or the bottom matter, or text that has been inserted.
|
|
22142
|
+
|
|
22143
|
+
var nextTop = 0; // There are often gaps between the elements for spacing, so the actual top and height needs to be inferred.
|
|
22144
|
+
|
|
22145
|
+
var wrappers = []; // Create all the elements and place them at once because we use the current svg to get data. It would disappear after placing the first line.
|
|
22146
|
+
|
|
22147
|
+
var svgs = [];
|
|
22148
|
+
|
|
22149
|
+
for (var i = 0; i < sections.length; i++) {
|
|
22150
|
+
var section = sections[i];
|
|
22151
|
+
var box = section.getBBox();
|
|
22152
|
+
var gapBetweenLines = box.y - nextTop; // take the margin into account
|
|
22153
|
+
|
|
22154
|
+
var height = box.height + gapBetweenLines;
|
|
22155
|
+
var wrapper = document.createElement("div");
|
|
22156
|
+
var divStyles = "overflow: hidden;";
|
|
22157
|
+
if (responsive !== 'resize') divStyles += "height:" + height + "px;";
|
|
22158
|
+
wrapper.setAttribute("style", divStyles);
|
|
22159
|
+
var svg = duplicateSvg(source);
|
|
22160
|
+
var fullTitle = "Sheet Music for \"" + title + "\" section " + (i + 1);
|
|
22161
|
+
svg.setAttribute("aria-label", fullTitle);
|
|
22162
|
+
if (responsive !== 'resize') svg.setAttribute("height", height);
|
|
22163
|
+
if (responsive === 'resize') svg.style.position = '';
|
|
22164
|
+
svg.setAttribute("viewBox", "0 " + nextTop + " " + width + " " + height);
|
|
22165
|
+
svg.appendChild(style.cloneNode(true));
|
|
22166
|
+
var titleEl = document.createElement("title");
|
|
22167
|
+
titleEl.innerText = fullTitle;
|
|
22168
|
+
svg.appendChild(titleEl);
|
|
22169
|
+
svg.appendChild(section);
|
|
22170
|
+
wrapper.appendChild(svg);
|
|
22171
|
+
svgs.push(svg);
|
|
22172
|
+
output.appendChild(wrapper); //wrappers.push(wrapper)
|
|
22173
|
+
|
|
22174
|
+
nextTop = box.y + box.height;
|
|
22175
|
+
} // for (i = 0; i < wrappers.length; i++)
|
|
22176
|
+
// output.appendChild(wrappers[i])
|
|
22177
|
+
|
|
22178
|
+
|
|
22179
|
+
output.removeChild(source);
|
|
22180
|
+
return svgs;
|
|
22181
|
+
}
|
|
22182
|
+
|
|
22183
|
+
function duplicateSvg(source) {
|
|
22184
|
+
var svgNS = "http://www.w3.org/2000/svg";
|
|
22185
|
+
var svg = document.createElementNS(svgNS, "svg");
|
|
22186
|
+
|
|
22187
|
+
for (var i = 0; i < source.attributes.length; i++) {
|
|
22188
|
+
var attr = source.attributes[i];
|
|
22189
|
+
if (attr.name !== "height" && attr.name != "aria-label") svg.setAttribute(attr.name, attr.value);
|
|
22190
|
+
}
|
|
22191
|
+
|
|
22192
|
+
return svg;
|
|
22193
|
+
}
|
|
22213
22194
|
|
|
22214
22195
|
EngraverController.prototype.getDim = function (historyEl) {
|
|
22215
22196
|
// Get the dimensions on demand because the getBBox call is expensive.
|
|
@@ -24576,8 +24557,10 @@ var Selectables = __webpack_require__(/*! ./selectables */ "./src/write/draw/sel
|
|
|
24576
24557
|
|
|
24577
24558
|
function draw(renderer, classes, abcTune, width, maxWidth, responsive, scale, selectTypes, tuneNumber, lineOffset) {
|
|
24578
24559
|
var selectables = new Selectables(renderer.paper, selectTypes, tuneNumber);
|
|
24560
|
+
renderer.paper.openGroup();
|
|
24579
24561
|
renderer.moveY(renderer.padding.top);
|
|
24580
24562
|
nonMusic(renderer, abcTune.topText, selectables);
|
|
24563
|
+
renderer.paper.closeGroup();
|
|
24581
24564
|
renderer.moveY(renderer.spacing.music);
|
|
24582
24565
|
var staffgroups = [];
|
|
24583
24566
|
|
|
@@ -24586,6 +24569,8 @@ function draw(renderer, classes, abcTune, width, maxWidth, responsive, scale, se
|
|
|
24586
24569
|
var abcLine = abcTune.lines[line];
|
|
24587
24570
|
|
|
24588
24571
|
if (abcLine.staff) {
|
|
24572
|
+
renderer.paper.openGroup();
|
|
24573
|
+
|
|
24589
24574
|
if (abcLine.vskip) {
|
|
24590
24575
|
renderer.moveY(abcLine.vskip);
|
|
24591
24576
|
}
|
|
@@ -24595,17 +24580,22 @@ function draw(renderer, classes, abcTune, width, maxWidth, responsive, scale, se
|
|
|
24595
24580
|
staffgroup.line = lineOffset + line; // If there are non-music lines then the staffgroup array won't line up with the line array, so this keeps track.
|
|
24596
24581
|
|
|
24597
24582
|
staffgroups.push(staffgroup);
|
|
24583
|
+
renderer.paper.closeGroup();
|
|
24598
24584
|
} else if (abcLine.nonMusic) {
|
|
24585
|
+
renderer.paper.openGroup();
|
|
24599
24586
|
nonMusic(renderer, abcLine.nonMusic, selectables);
|
|
24587
|
+
renderer.paper.closeGroup();
|
|
24600
24588
|
}
|
|
24601
24589
|
}
|
|
24602
24590
|
|
|
24603
24591
|
classes.reset();
|
|
24604
24592
|
|
|
24605
24593
|
if (abcTune.bottomText && abcTune.bottomText.rows && abcTune.bottomText.rows.length > 0) {
|
|
24594
|
+
renderer.paper.openGroup();
|
|
24606
24595
|
renderer.moveY(24); // TODO-PER: Empirically discovered. What variable should this be?
|
|
24607
24596
|
|
|
24608
24597
|
nonMusic(renderer, abcTune.bottomText, selectables);
|
|
24598
|
+
renderer.paper.closeGroup();
|
|
24609
24599
|
}
|
|
24610
24600
|
|
|
24611
24601
|
setPaperSize(renderer, maxWidth, scale, responsive);
|
|
@@ -25672,8 +25662,8 @@ function drawStaffGroup(renderer, params, selectables, lineNumber) {
|
|
|
25672
25662
|
// renderer.y will be offset at the beginning of each staff by the amount required to make the relative pitch work.
|
|
25673
25663
|
// If there are multiple staves, then renderer.y will be incremented for each new staff.
|
|
25674
25664
|
var colorIndex; // An invisible marker is useful to be able to find where each system starts.
|
|
25665
|
+
//addInvisibleMarker(renderer, "abcjs-top-of-system");
|
|
25675
25666
|
|
|
25676
|
-
addInvisibleMarker(renderer, "abcjs-top-of-system");
|
|
25677
25667
|
var startY = renderer.y; // So that it can be restored after we're done.
|
|
25678
25668
|
// Set the absolute Y position for each staff here, so the voice drawing below can just use if.
|
|
25679
25669
|
|
|
@@ -25865,20 +25855,11 @@ function printBrace(renderer, absoluteY, brace, index, selectables) {
|
|
|
25865
25855
|
}
|
|
25866
25856
|
}
|
|
25867
25857
|
}
|
|
25868
|
-
}
|
|
25858
|
+
} // function addInvisibleMarker(renderer, className) {
|
|
25859
|
+
// var y = Math.round(renderer.y);
|
|
25860
|
+
// renderer.paper.pathToBack({path:"M 0 " + y + " L 0 0", stroke:"none", fill:"none", "stroke-opacity": 0, "fill-opacity": 0, 'class': renderer.controller.classes.generate(className), 'data-vertical': y });
|
|
25861
|
+
// }
|
|
25869
25862
|
|
|
25870
|
-
function addInvisibleMarker(renderer, className) {
|
|
25871
|
-
var y = Math.round(renderer.y);
|
|
25872
|
-
renderer.paper.pathToBack({
|
|
25873
|
-
path: "M 0 " + y + " L 0 0",
|
|
25874
|
-
stroke: "none",
|
|
25875
|
-
fill: "none",
|
|
25876
|
-
"stroke-opacity": 0,
|
|
25877
|
-
"fill-opacity": 0,
|
|
25878
|
-
'class': renderer.controller.classes.generate(className),
|
|
25879
|
-
'data-vertical': y
|
|
25880
|
-
});
|
|
25881
|
-
}
|
|
25882
25863
|
|
|
25883
25864
|
function boxAllElements(renderer, voices, which) {
|
|
25884
25865
|
for (var i = 0; i < which.length; i++) {
|
|
@@ -28045,7 +28026,7 @@ module.exports = layoutVoice;
|
|
|
28045
28026
|
|
|
28046
28027
|
var spacing = __webpack_require__(/*! ./abc_spacing */ "./src/write/abc_spacing.js");
|
|
28047
28028
|
|
|
28048
|
-
function setupSelection(engraver) {
|
|
28029
|
+
function setupSelection(engraver, svgs) {
|
|
28049
28030
|
engraver.rangeHighlight = rangeHighlight;
|
|
28050
28031
|
|
|
28051
28032
|
if (engraver.dragging) {
|
|
@@ -28062,14 +28043,21 @@ function setupSelection(engraver) {
|
|
|
28062
28043
|
}
|
|
28063
28044
|
}
|
|
28064
28045
|
|
|
28065
|
-
|
|
28066
|
-
|
|
28067
|
-
|
|
28046
|
+
for (var i = 0; i < svgs.length; i++) {
|
|
28047
|
+
svgs[i].addEventListener('touchstart', mouseDown.bind(engraver));
|
|
28048
|
+
svgs[i].addEventListener('touchmove', mouseMove.bind(engraver));
|
|
28049
|
+
svgs[i].addEventListener('touchend', mouseUp.bind(engraver));
|
|
28050
|
+
svgs[i].addEventListener('mousedown', mouseDown.bind(engraver));
|
|
28051
|
+
svgs[i].addEventListener('mousemove', mouseMove.bind(engraver));
|
|
28052
|
+
svgs[i].addEventListener('mouseup', mouseUp.bind(engraver));
|
|
28053
|
+
}
|
|
28068
28054
|
}
|
|
28069
28055
|
|
|
28070
|
-
function getCoord(ev
|
|
28056
|
+
function getCoord(ev) {
|
|
28071
28057
|
var scaleX = 1;
|
|
28072
|
-
var scaleY = 1;
|
|
28058
|
+
var scaleY = 1;
|
|
28059
|
+
var svg = ev.target.closest('svg');
|
|
28060
|
+
var yOffset = 0; // when renderer.options.responsive === 'resize' the click coords are in relation to the HTML
|
|
28073
28061
|
// element, we need to convert to the SVG viewBox coords
|
|
28074
28062
|
|
|
28075
28063
|
if (svg.viewBox.baseVal) {
|
|
@@ -28077,6 +28065,7 @@ function getCoord(ev, svg) {
|
|
|
28077
28065
|
// Chrome makes these values null when no viewBox is given.
|
|
28078
28066
|
if (svg.viewBox.baseVal.width !== 0) scaleX = svg.viewBox.baseVal.width / svg.clientWidth;
|
|
28079
28067
|
if (svg.viewBox.baseVal.height !== 0) scaleY = svg.viewBox.baseVal.height / svg.clientHeight;
|
|
28068
|
+
yOffset = svg.viewBox.baseVal.y;
|
|
28080
28069
|
}
|
|
28081
28070
|
|
|
28082
28071
|
var svgClicked = ev.target.tagName === "svg";
|
|
@@ -28094,7 +28083,7 @@ function getCoord(ev, svg) {
|
|
|
28094
28083
|
x = x * scaleX;
|
|
28095
28084
|
y = y * scaleY; //console.log(x, y)
|
|
28096
28085
|
|
|
28097
|
-
return [x, y];
|
|
28086
|
+
return [x, y + yOffset];
|
|
28098
28087
|
}
|
|
28099
28088
|
|
|
28100
28089
|
function elementFocused(ev) {
|
|
@@ -28175,7 +28164,7 @@ function keyboardSelection(ev) {
|
|
|
28175
28164
|
|
|
28176
28165
|
function findElementInHistory(selectables, el) {
|
|
28177
28166
|
for (var i = 0; i < selectables.length; i++) {
|
|
28178
|
-
if (el === selectables[i].svgEl) return i;
|
|
28167
|
+
if (el.dataset.index === selectables[i].svgEl.dataset.index) return i;
|
|
28179
28168
|
}
|
|
28180
28169
|
|
|
28181
28170
|
return -1;
|
|
@@ -28268,7 +28257,7 @@ function getMousePosition(self, ev) {
|
|
|
28268
28257
|
y = box[1]; //console.log("clicked on", clickedOn, x, y, self.selectables[clickedOn].svgEl.getBBox(), ev.target.getBBox());
|
|
28269
28258
|
} else {
|
|
28270
28259
|
// See if they clicked close to an element.
|
|
28271
|
-
box = getCoord(ev
|
|
28260
|
+
box = getCoord(ev);
|
|
28272
28261
|
x = box[0];
|
|
28273
28262
|
y = box[1];
|
|
28274
28263
|
clickedOn = findElementByCoord(self, x, y); //console.log("clicked near", clickedOn, x, y, printEl(ev.target));
|
|
@@ -28281,11 +28270,28 @@ function getMousePosition(self, ev) {
|
|
|
28281
28270
|
};
|
|
28282
28271
|
}
|
|
28283
28272
|
|
|
28273
|
+
function attachMissingTouchEventAttributes(touchEv) {
|
|
28274
|
+
var rect = touchEv.target.getBoundingClientRect();
|
|
28275
|
+
var offsetX = touchEv.touches[0].pageX - rect.left;
|
|
28276
|
+
var offsetY = touchEv.touches[0].pageY - rect.top;
|
|
28277
|
+
touchEv.touches[0].offsetX = offsetX;
|
|
28278
|
+
touchEv.touches[0].offsetY = offsetY;
|
|
28279
|
+
touchEv.touches[0].layerX = touchEv.touches[0].pageX;
|
|
28280
|
+
touchEv.touches[0].layerY = touchEv.touches[0].pageY;
|
|
28281
|
+
}
|
|
28282
|
+
|
|
28284
28283
|
function mouseDown(ev) {
|
|
28285
28284
|
// "this" is the EngraverController because of the bind(this) when setting the event listener.
|
|
28286
|
-
var
|
|
28285
|
+
var _ev = ev;
|
|
28286
|
+
|
|
28287
|
+
if (ev.type === 'touchstart') {
|
|
28288
|
+
attachMissingTouchEventAttributes(ev);
|
|
28289
|
+
_ev = ev.touches[0];
|
|
28290
|
+
}
|
|
28291
|
+
|
|
28292
|
+
var positioning = getMousePosition(this, _ev); // Only start dragging if the user clicked close enough to an element and clicked with the main mouse button.
|
|
28287
28293
|
|
|
28288
|
-
if (positioning.clickedOn >= 0 && ev.button === 0) {
|
|
28294
|
+
if (positioning.clickedOn >= 0 && (ev.type === 'touchstart' || ev.button === 0)) {
|
|
28289
28295
|
this.dragTarget = this.selectables[positioning.clickedOn];
|
|
28290
28296
|
this.dragIndex = positioning.clickedOn;
|
|
28291
28297
|
this.dragMechanism = "mouse";
|
|
@@ -28302,9 +28308,17 @@ function mouseDown(ev) {
|
|
|
28302
28308
|
}
|
|
28303
28309
|
|
|
28304
28310
|
function mouseMove(ev) {
|
|
28305
|
-
|
|
28311
|
+
var _ev = ev;
|
|
28312
|
+
|
|
28313
|
+
if (ev.type === 'touchmove') {
|
|
28314
|
+
attachMissingTouchEventAttributes(ev);
|
|
28315
|
+
_ev = ev.touches[0];
|
|
28316
|
+
}
|
|
28317
|
+
|
|
28318
|
+
this.lastTouchMove = ev; // "this" is the EngraverController because of the bind(this) when setting the event listener.
|
|
28319
|
+
|
|
28306
28320
|
if (!this.dragTarget || !this.dragging || !this.dragTarget.isDraggable || this.dragMechanism !== 'mouse') return;
|
|
28307
|
-
var positioning = getMousePosition(this,
|
|
28321
|
+
var positioning = getMousePosition(this, _ev);
|
|
28308
28322
|
var yDist = Math.round((positioning.y - this.dragMouseStart.y) / spacing.STEP);
|
|
28309
28323
|
|
|
28310
28324
|
if (yDist !== this.dragYStep) {
|
|
@@ -28315,6 +28329,13 @@ function mouseMove(ev) {
|
|
|
28315
28329
|
|
|
28316
28330
|
function mouseUp(ev) {
|
|
28317
28331
|
// "this" is the EngraverController because of the bind(this) when setting the event listener.
|
|
28332
|
+
var _ev = ev;
|
|
28333
|
+
|
|
28334
|
+
if (ev.type === 'touchend') {
|
|
28335
|
+
attachMissingTouchEventAttributes(this.lastTouchMove);
|
|
28336
|
+
_ev = this.lastTouchMove.touches[0];
|
|
28337
|
+
}
|
|
28338
|
+
|
|
28318
28339
|
if (!this.dragTarget) return;
|
|
28319
28340
|
clearSelection.bind(this)();
|
|
28320
28341
|
|
|
@@ -28323,7 +28344,7 @@ function mouseUp(ev) {
|
|
|
28323
28344
|
this.dragTarget.absEl.highlight(undefined, this.selectionColor);
|
|
28324
28345
|
}
|
|
28325
28346
|
|
|
28326
|
-
notifySelect.bind(this)(this.dragTarget, this.dragYStep, this.selectables.length, this.dragIndex,
|
|
28347
|
+
notifySelect.bind(this)(this.dragTarget, this.dragYStep, this.selectables.length, this.dragIndex, _ev);
|
|
28327
28348
|
|
|
28328
28349
|
if (this.dragTarget.svgEl && this.dragTarget.svgEl.focus) {
|
|
28329
28350
|
this.dragTarget.svgEl.focus();
|
|
@@ -28884,7 +28905,7 @@ Svg.prototype.closeGroup = function () {
|
|
|
28884
28905
|
|
|
28885
28906
|
if (g && g.children.length === 0) {
|
|
28886
28907
|
// If nothing was added to the group it is because all the elements were invisible. We don't need the group, then.
|
|
28887
|
-
|
|
28908
|
+
g.parentElement.removeChild(g);
|
|
28888
28909
|
return null;
|
|
28889
28910
|
}
|
|
28890
28911
|
|
|
@@ -29130,7 +29151,7 @@ module.exports = unhighlight;
|
|
|
29130
29151
|
\********************/
|
|
29131
29152
|
/***/ (function(module) {
|
|
29132
29153
|
|
|
29133
|
-
var version = '6.1.
|
|
29154
|
+
var version = '6.1.3';
|
|
29134
29155
|
module.exports = version;
|
|
29135
29156
|
|
|
29136
29157
|
/***/ })
|