Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

abcjs

Package Overview
Dependencies
Maintainers
1
Versions
116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

abcjs - npm Package Compare versions

Comparing version 6.1.0 to 6.1.1

SECURITY.md

2

package.json
{
"name": "abcjs",
"version": "6.1.0",
"version": "6.1.1",
"description": "Renderer for abc music notation",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -11,2 +11,6 @@ ![abcjs](https://paulrosen.github.io/abcjs/img/abcjs_comp_extended_08.svg)

## Announcement: version 6.1.1
There is a little difference in the generated SVG: Now each line is surrounded with a `<g>` element. This probably won't affect your program unless you are doing very specific manipulation of the SVG.
## Announcement: version 6.1.0

@@ -13,0 +17,0 @@

@@ -0,1 +1,15 @@

# Version 6.1.1
## Bugs
* rewrite oneSvgPerLine; fixes selection and keeping multiline items (like slurs) correctly.
## Features
* added mobile browser TouchEvent support for dragging
## Documentation
* fixed some typescript definitions
# Version 6.1.0

@@ -2,0 +16,0 @@

@@ -62,92 +62,2 @@ var tunebook = require('./abc_tunebook');

function renderEachLineSeparately(div, tune, params, tuneNumber) {
function initializeTuneLine(tune) {
var obj = new Tune();
obj.formatting = tune.formatting;
obj.media = tune.media;
obj.version = tune.version;
return obj;
}
// Before rendering, chop up the returned tune into an array where each element is a line.
// The first element of the array gets the title and other items that go on top, the last element
// of the array gets the extra text that goes on bottom. Each element gets any non-music info that comes before it.
var tunes = [];
var tuneLine;
for (var i = 0; i < tune.lines.length; i++) {
var line = tune.lines[i];
if (!tuneLine)
tuneLine = initializeTuneLine(tune);
if (i === 0) {
// These items go on top of the music
tuneLine.copyTopInfo(tune);
}
// push the lines until we get to a music line
tuneLine.lines.push(line);
if (line.staff) {
tunes.push(tuneLine);
tuneLine = undefined;
}
}
// Add any extra stuff to the last line.
if (tuneLine) {
var lastLine = tunes[tunes.length-1];
for (var j = 0; j < tuneLine.lines.length; j++)
lastLine.lines.push(tuneLine.lines[j]);
}
// These items go below the music
tuneLine = tunes[tunes.length-1];
tuneLine.copyBottomInfo(tune);
// Now create sub-divs and render each line. Need to copy the params to change the padding for the interior slices.
var ep = {};
for (var key in params) {
if (params.hasOwnProperty(key)) {
ep[key] = params[key];
}
}
var origPaddingTop = ep.paddingtop;
var origPaddingBottom = ep.paddingbottom;
var currentScrollY = div.parentNode.scrollTop; // If there is scrolling it will be lost during the redraw so remember it.
var currentScrollX = div.parentNode.scrollLeft;
div.innerHTML = "";
var lineCount = 0;
for (var k = 0; k < tunes.length; k++) {
var lineEl = document.createElement("div");
div.appendChild(lineEl);
if (k === 0) {
ep.paddingtop = origPaddingTop;
ep.paddingbottom = 0;
} else if (k === tunes.length-1) {
ep.paddingtop = 10;
ep.paddingbottom = origPaddingBottom;
} else {
ep.paddingtop = 10;
ep.paddingbottom = 0;
}
if (k < tunes.length-1) {
// If it is not the last line, force stretchlast. If it is, stretchlast might have been set by the input parameters.
tunes[k].formatting = parseCommon.clone(tunes[k].formatting);
tunes[k].formatting.stretchlast = true;
}
renderOne(lineEl, tunes[k], ep, tuneNumber, lineCount);
lineCount += tunes[k].lines.length;
if (k === 0)
tune.engraver = tunes[k].engraver;
else {
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]);
}
}
if (currentScrollX || currentScrollY) {
div.parentNode.scrollTo(currentScrollX, currentScrollY);
}
}
// A quick way to render a tune from javascript when interactivity is not required.

@@ -218,6 +128,3 @@ // This is used when a javascript routine has some abc text that it wants to render

}
else if (removeDiv || !params.oneSvgPerLine || tune.lines.length < 2)
renderOne(div, tune, params, tuneNumber, 0);
else
renderEachLineSeparately(div, tune, params, tuneNumber);
renderOne(div, tune, params, tuneNumber, 0);
if (removeDiv)

@@ -244,6 +151,3 @@ div.parentNode.removeChild(div);

}
if (!params.oneSvgPerLine || tune.lines.length < 2)
renderOne(div, tune, ret.revisedParams, tuneNumber, 0);
else
renderEachLineSeparately(div, tune, ret.revisedParams, tuneNumber);
renderOne(div, tune, ret.revisedParams, tuneNumber, 0);
tune.explanation = ret.explanation;

@@ -250,0 +154,0 @@ return tune;

@@ -35,2 +35,3 @@ // abc_engraver_controller.js: Controls the engraving process of an ABCJS abstract syntax tree as produced by ABCJS/parse

params = params || {};
this.oneSvgPerLine = params.oneSvgPerLine;
this.selectionColor = params.selectionColor;

@@ -250,5 +251,67 @@ this.dragColor = params.dragColor ? params.dragColor : params.selectionColor;

setupSelection(this);
if (this.oneSvgPerLine) {
var div = this.renderer.paper.svg.parentNode
this.svgs = splitSvgIntoLines(div, abcTune.metaText.title)
} else {
this.svgs = [this.renderer.paper.svg];
}
setupSelection(this, this.svgs);
};
function splitSvgIntoLines(output, title) {
// Each line is a top level <g> in the svg. To split it into separate
// svgs iterate through each of those and put them in a new svg. Since
// they are placed absolutely, the viewBox needs to be manipulated to
// get the correct vertical positioning.
// We copy all the attributes from the original svg except for the aria-label
// since we want that to include a count. And the height is now a fraction of the original svg.
if (!title) title = "Untitled"
var source = output.querySelector("svg")
var style = source.querySelector("style")
var width = source.getAttribute("width")
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.
var nextTop = 0 // There are often gaps between the elements for spacing, so the actual top and height needs to be inferred.
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.
var svgs = []
for (var i = 0; i < sections.length; i++) {
var section = sections[i]
var box = section.getBBox()
var gapBetweenLines = box.y - nextTop // take the margin into account
var height = box.height + gapBetweenLines;
var wrapper = document.createElement("div");
wrapper.setAttribute("style", "overflow: hidden;height:"+height+"px;")
var svg = duplicateSvg(source)
var fullTitle = "Sheet Music for \"" + title + "\" section " + (i+1)
svg.setAttribute("aria-label", fullTitle)
svg.setAttribute("height", height)
svg.setAttribute("viewBox", "0 " + nextTop + " " + width + " " + height )
svg.appendChild(style.cloneNode(true))
var titleEl = document.createElement("title")
titleEl.innerText = fullTitle
svg.appendChild(titleEl)
svg.appendChild(section)
wrapper.appendChild(svg)
svgs.push(svg)
output.appendChild(wrapper)
//wrappers.push(wrapper)
nextTop = box.y+box.height
}
// for (i = 0; i < wrappers.length; i++)
// output.appendChild(wrappers[i])
output.removeChild(source)
return svgs;
}
function duplicateSvg(source) {
var svgNS = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(svgNS, "svg");
for (var i = 0; i < source.attributes.length; i++) {
var attr = source.attributes[i];
if (attr.name !== "height" && attr.name != "aria-label")
svg.setAttribute(attr.name, attr.value)
}
return svg;
}
EngraverController.prototype.getDim = function(historyEl) {

@@ -255,0 +318,0 @@ // Get the dimensions on demand because the getBBox call is expensive.

@@ -9,4 +9,6 @@ var drawStaffGroup = require('./staff-group');

var selectables = new Selectables(renderer.paper, selectTypes, tuneNumber);
renderer.paper.openGroup()
renderer.moveY(renderer.padding.top);
nonMusic(renderer, abcTune.topText, selectables);
renderer.paper.closeGroup()
renderer.moveY(renderer.spacing.music);

@@ -18,2 +20,3 @@ var staffgroups = [];

if (abcLine.staff) {
renderer.paper.openGroup()
if (abcLine.vskip) {

@@ -27,4 +30,7 @@ renderer.moveY(abcLine.vskip);

staffgroups.push(staffgroup);
renderer.paper.closeGroup()
} else if (abcLine.nonMusic) {
renderer.paper.openGroup()
nonMusic(renderer, abcLine.nonMusic, selectables);
renderer.paper.closeGroup()
}

@@ -35,4 +41,6 @@ }

if (abcTune.bottomText && abcTune.bottomText.rows && abcTune.bottomText.rows.length > 0) {
renderer.paper.openGroup()
renderer.moveY(24); // TODO-PER: Empirically discovered. What variable should this be?
nonMusic(renderer, abcTune.bottomText, selectables);
renderer.paper.closeGroup()
}

@@ -39,0 +47,0 @@ setPaperSize(renderer, maxWidth, scale, responsive);

@@ -18,3 +18,3 @@ var spacing = require('../abc_spacing');

// An invisible marker is useful to be able to find where each system starts.
addInvisibleMarker(renderer, "abcjs-top-of-system");
//addInvisibleMarker(renderer, "abcjs-top-of-system");

@@ -181,6 +181,6 @@ var startY = renderer.y; // So that it can be restored after we're done.

function addInvisibleMarker(renderer, className) {
var y = Math.round(renderer.y);
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 });
}
// function addInvisibleMarker(renderer, className) {
// var y = Math.round(renderer.y);
// 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 });
// }

@@ -187,0 +187,0 @@ function boxAllElements(renderer, voices, which) {

var spacing = require('./abc_spacing');
function setupSelection(engraver) {
function setupSelection(engraver, svgs) {
engraver.rangeHighlight = rangeHighlight;

@@ -17,10 +17,17 @@ if (engraver.dragging) {

}
engraver.renderer.paper.svg.addEventListener('mousedown', mouseDown.bind(engraver));
engraver.renderer.paper.svg.addEventListener('mousemove', mouseMove.bind(engraver));
engraver.renderer.paper.svg.addEventListener('mouseup', mouseUp.bind(engraver));
for (var i = 0; i < svgs.length; i++) {
svgs[i].addEventListener('touchstart', mouseDown.bind(engraver));
svgs[i].addEventListener('touchmove', mouseMove.bind(engraver));
svgs[i].addEventListener('touchend', mouseUp.bind(engraver));
svgs[i].addEventListener('mousedown', mouseDown.bind(engraver));
svgs[i].addEventListener('mousemove', mouseMove.bind(engraver));
svgs[i].addEventListener('mouseup', mouseUp.bind(engraver));
}
}
function getCoord(ev, svg) {
function getCoord(ev) {
var scaleX = 1;
var scaleY = 1;
var svg = ev.target.closest('svg')
var yOffset = 0

@@ -35,2 +42,3 @@ // when renderer.options.responsive === 'resize' the click coords are in relation to the HTML

scaleY = svg.viewBox.baseVal.height / svg.clientHeight
yOffset = svg.viewBox.baseVal.y
}

@@ -53,3 +61,3 @@

return [x, y];
return [x, y+yOffset];
}

@@ -126,3 +134,3 @@

for (var i = 0; i < selectables.length; i++) {
if (el === selectables[i].svgEl)
if (el.dataset.index === selectables[i].svgEl.dataset.index)
return i;

@@ -223,3 +231,3 @@ }

// See if they clicked close to an element.
box = getCoord(ev, self.renderer.paper.svg);
box = getCoord(ev);
x = box[0];

@@ -233,9 +241,26 @@ y = box[1];

function attachMissingTouchEventAttributes(touchEv) {
var rect = touchEv.target.getBoundingClientRect();
var offsetX = touchEv.touches[0].pageX - rect.left;
var offsetY = touchEv.touches[0].pageY - rect.top;
touchEv.touches[0].offsetX = offsetX;
touchEv.touches[0].offsetY = offsetY;
touchEv.touches[0].layerX = touchEv.touches[0].pageX;
touchEv.touches[0].layerY = touchEv.touches[0].pageY;
}
function mouseDown(ev) {
// "this" is the EngraverController because of the bind(this) when setting the event listener.
var _ev = ev;
if (ev.type === 'touchstart') {
attachMissingTouchEventAttributes(ev);
_ev = ev.touches[0];
}
var positioning = getMousePosition(this, ev);
var positioning = getMousePosition(this, _ev);
// Only start dragging if the user clicked close enough to an element and clicked with the main mouse button.
if (positioning.clickedOn >= 0 && ev.button === 0) {
if (positioning.clickedOn >= 0 && (ev.type === 'touchstart' || ev.button === 0)) {
this.dragTarget = this.selectables[positioning.clickedOn];

@@ -253,2 +278,8 @@ this.dragIndex = positioning.clickedOn;

function mouseMove(ev) {
var _ev = ev;
if (ev.type === 'touchmove') {
attachMissingTouchEventAttributes(ev);
_ev = ev.touches[0];
}
this.lastTouchMove = ev;
// "this" is the EngraverController because of the bind(this) when setting the event listener.

@@ -259,3 +290,3 @@

var positioning = getMousePosition(this, ev);
var positioning = getMousePosition(this, _ev);

@@ -271,2 +302,7 @@ var yDist = Math.round((positioning.y - this.dragMouseStart.y)/spacing.STEP);

// "this" is the EngraverController because of the bind(this) when setting the event listener.
var _ev = ev;
if (ev.type === 'touchend') {
attachMissingTouchEventAttributes(this.lastTouchMove);
_ev = this.lastTouchMove.touches[0];
}

@@ -282,3 +318,3 @@ if (!this.dragTarget)

notifySelect.bind(this)(this.dragTarget, this.dragYStep, this.selectables.length, this.dragIndex, ev);
notifySelect.bind(this)(this.dragTarget, this.dragYStep, this.selectables.length, this.dragIndex, _ev);
if (this.dragTarget.svgEl && this.dragTarget.svgEl.focus) {

@@ -285,0 +321,0 @@ this.dragTarget.svgEl.focus();

@@ -174,2 +174,4 @@ declare module 'abcjs' {

export type AbstractEngraver = any;
export type NoteProperties = any; // TODO

@@ -508,2 +510,30 @@

export interface EngraverController {
classes: any;
dragColor: string;
dragIndex: number;
dragMouseStart: { x: number, y: number; };
dragTarget: null | any;
dragYStep: number;
dragging: boolean;
engraver: AbstractEngraver;
getFontAndAttr: any;
getTextSize: any;
listeners: [ClickListener];
rangeHighlight: any;
renderer: any;
responsive?: boolean;
scale: number;
initialClef?: any;
selectTypes: boolean | Array<DragTypes>;
selectables: Array<Selectable>;
selected: Array<any>;
selectionColor: string;
space: number;
staffgroups: [any];
staffwidthPrint: number;
staffwidthScreen: number;
width: number;
}
export interface MetaText {

@@ -717,2 +747,3 @@ "abc-copyright"?: string;

formatting: Formatting;
engraver?: EngraverController;
lines: Array<TuneLine>;

@@ -738,2 +769,3 @@ media: Media;

setUpAudio: (options: SynthOptions) => AudioTracks;
makeVoicesArray: () => Array<Selectable[]>
lineBreaks?: Array<number>;

@@ -745,2 +777,12 @@ visualTranspose?: number;

export interface Selectable {
absEl: AbsoluteElement;
isDraggable: boolean;
staffPos: {
height: number;
top: number;
zero: number;
}
}
export interface AbcElem {

@@ -1099,2 +1141,4 @@ el_type: string //TODO enumerate these

export function extractMeasures(abc: string) : Array<MeasureList>;
export function strTranspose(originalAbc: string, visualObj: TuneObject, steps: number): string;

@@ -1101,0 +1145,0 @@ //

@@ -1,3 +0,3 @@

var version = '6.1.0';
var version = '6.1.1';
module.exports = version;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc