Procházet zdrojové kódy

feat(Options): add options interface for osmd constructor (#368)

changes OpenSheetMusicDisplay constructor to accept options object instead of individual parameters

* add Enum to DrawingParameters class, setter method that changes parameters depending on Enum

* refactor(tests): move createOSMD() to TestUtils

* refactor: DrawingParametersEnum with string values, docstrings

* fix(resize): fix OSMD.autoResize(), handleResize(), fix tests

fix render being called via autoResize() in OSMD constructor before sample loaded

fix load MXL from string test failing because it called autoResize()
which calls render(), despite options.autoResize set to false for all tests

* refactor(OSMD doc): OSMD docstrings more technical, add compact mode options

* refactor(DrawingParameters): add setForDefault method, drawHiddenNotes parameter

* OSMDOptions: add options for default notehead & stem color, drawHiddenNotes (not yet supported)

* add note color options (unsupported), refactor(OSMD): add enableOrDisableCursor(), setDrawingParameters()

* add options for credits (unsupported)
Simon před 6 roky
rodič
revize
9da9cb4207

+ 12 - 4
demo/index.js

@@ -113,12 +113,17 @@ import { OpenSheetMusicDisplay } from '../src/OpenSheetMusicDisplay/OpenSheetMus
             openSheetMusicDisplay.DrawSkyLine = !openSheetMusicDisplay.DrawSkyLine;
         }
 
-        bottomlineDebug .onclick = function() {
+        bottomlineDebug.onclick = function() {
             openSheetMusicDisplay.DrawBottomLine = !openSheetMusicDisplay.DrawBottomLine;
         }
 
         // Create OSMD object and canvas
-        openSheetMusicDisplay = new OpenSheetMusicDisplay(canvas, false, backendSelect.value);
+        openSheetMusicDisplay = new OpenSheetMusicDisplay(canvas, {
+            autoResize: true,
+            backend: backendSelect.value,
+            drawingParameters: "default",
+            disableCursor: false,
+        });
         openSheetMusicDisplay.setLogLevel('info');
         document.body.appendChild(canvas);
 
@@ -163,7 +168,11 @@ import { OpenSheetMusicDisplay } from '../src/OpenSheetMusicDisplay/OpenSheetMus
             openSheetMusicDisplay.cursor.hide();
         });
         showCursorBtn.addEventListener("click", function() {
-            openSheetMusicDisplay.cursor.show();
+            if (openSheetMusicDisplay.cursor) {
+                openSheetMusicDisplay.cursor.show();
+            } else {
+                console.info("Can't show cursor, as it was disabled (e.g. by drawingParameters).");
+            }
         });
 
         backendSelect.addEventListener("change", function(e) {
@@ -178,7 +187,6 @@ import { OpenSheetMusicDisplay } from '../src/OpenSheetMusicDisplay/OpenSheetMus
     }
 
     function Resize(startCallback, endCallback) {
-
       var rtime;
       var timeout = false;
       var delta = 200;

+ 1 - 1
karma.conf.js

@@ -81,7 +81,7 @@ module.exports = function (config) {
         client: {
             captureConsole: true,
             mocha: {
-                timeout: process.env.timeout || 2000
+                timeout: process.env.timeout || 6000
             }
         },
 

+ 65 - 0
src/MusicalScore/Graphical/DrawingParameters.ts

@@ -1,4 +1,15 @@
+export enum DrawingParametersEnum {
+    AllOn = "allon",
+    Compact = "compact",
+    Default = "default",
+    Leadsheet = "leadsheet",
+    Preview = "preview",
+    Thumbnail = "thumbnail",
+}
+
 export class DrawingParameters {
+    /** will set other settings if changed with set method */
+    private drawingParametersEnum: DrawingParametersEnum;
     public drawHighlights: boolean;
     public drawErrors: boolean;
     public drawSelectionStartSymbol: boolean;
@@ -8,6 +19,43 @@ export class DrawingParameters {
     public drawScrollIndicator: boolean;
     public drawComments: boolean;
     public drawMarkedAreas: boolean;
+    public drawTitle: boolean = true;
+    public drawCredits: boolean = true;
+    public drawPartName: boolean = true;
+    /** Draw notes set to be invisible (print-object="no" in XML). */
+    public drawHiddenNotes: boolean = false;
+    public defaultColorNoteHead: string; // TODO not yet supported
+    public defaultColorStem: string; // TODO not yet supported
+
+    constructor(drawingParameters: DrawingParametersEnum = DrawingParametersEnum.Default) {
+        this.DrawingParametersEnum = drawingParameters;
+    }
+
+    /** Sets drawing parameters enum and changes settings flags accordingly. */
+    public set DrawingParametersEnum(drawingParametersEnum: DrawingParametersEnum) {
+        this.drawingParametersEnum = drawingParametersEnum;
+        switch (drawingParametersEnum) {
+            case DrawingParametersEnum.AllOn:
+                this.setForAllOn();
+                break;
+            case DrawingParametersEnum.Thumbnail:
+                this.setForThumbnail();
+                break;
+            case DrawingParametersEnum.Leadsheet:
+                this.setForLeadsheet();
+                break;
+            case DrawingParametersEnum.Compact:
+                this.setForCompactMode();
+                break;
+            case DrawingParametersEnum.Default:
+            default:
+                this.setForDefault();
+        }
+    }
+
+    public get DrawingParametersEnum(): DrawingParametersEnum {
+        return this.drawingParametersEnum;
+    }
 
     public setForAllOn(): void {
         this.drawHighlights = true;
@@ -19,6 +67,15 @@ export class DrawingParameters {
         this.drawScrollIndicator = true;
         this.drawComments = true;
         this.drawMarkedAreas = true;
+        this.drawTitle = true;
+        this.drawCredits = true;
+        this.drawPartName = true;
+        this.drawHiddenNotes = true;
+    }
+
+    public setForDefault(): void {
+        this.setForAllOn();
+        this.drawHiddenNotes = false;
     }
 
     public setForThumbnail(): void {
@@ -31,6 +88,14 @@ export class DrawingParameters {
         this.drawScrollIndicator = false;
         this.drawComments = true;
         this.drawMarkedAreas = true;
+        this.drawHiddenNotes = false;
+    }
+
+    public setForCompactMode(): void {
+        this.drawTitle = false;
+        this.drawCredits = false;
+        this.drawPartName = false;
+        this.drawHiddenNotes = false;
     }
 
     public setForLeadsheet(): void {

+ 2 - 6
src/MusicalScore/Graphical/MusicSheetDrawer.ts

@@ -52,14 +52,10 @@ export abstract class MusicSheetDrawer {
     private phonicScoreMode: PhonicScoreModes = PhonicScoreModes.Manual;
 
     constructor(textMeasurer: ITextMeasurer,
-                isPreviewImageDrawer: boolean = false) {
+                drawingParameters: DrawingParameters) {
         this.textMeasurer = textMeasurer;
         this.splitScreenLineColor = -1;
-        if (isPreviewImageDrawer) {
-            this.drawingParameters.setForThumbnail();
-        } else {
-            this.drawingParameters.setForAllOn();
-        }
+        this.drawingParameters = drawingParameters;
     }
 
     public set Mode(value: PhonicScoreModes) {

+ 3 - 2
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts

@@ -23,6 +23,7 @@ import { PlacementEnum } from "../../VoiceData/Expressions/AbstractExpression";
 import {GraphicalInstantaneousTempoExpression} from "../GraphicalInstantaneousTempoExpression";
 import {GraphicalInstantaneousDynamicExpression} from "../GraphicalInstantaneousDynamicExpression";
 import log = require("loglevel");
+import {DrawingParameters} from "../DrawingParameters";
 
 /**
  * This is a global constant which denotes the height in pixels of the space between two lines of the stave
@@ -37,8 +38,8 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
 
     constructor(element: HTMLElement,
                 backend: VexFlowBackend,
-                isPreviewImageDrawer: boolean = false) {
-        super(new VexFlowTextMeasurer(), isPreviewImageDrawer);
+                drawingParameters: DrawingParameters = new DrawingParameters()) {
+        super(new VexFlowTextMeasurer(), drawingParameters);
         this.backend = backend;
     }
 

+ 1 - 3
src/OpenSheetMusicDisplay/Cursor.ts

@@ -28,6 +28,7 @@ export class Cursor {
   private hidden: boolean = true;
   private cursorElement: HTMLImageElement;
 
+  /** Initialize the cursor. Necessary before using functions like show() and next(). */
   public init(manager: MusicPartManager, graphic: GraphicalMusicSheet): void {
     this.manager = manager;
     this.reset();
@@ -42,9 +43,6 @@ export class Cursor {
   public show(): void {
     this.hidden = false;
     this.update();
-    // Forcing the sheet to re-render is not necessary anymore,
-    // since the cursor is an HTML element.
-    // this.openSheetMusicDisplay.render();
   }
 
   private getStaffEntriesFromVoiceEntry(voiceEntry: VoiceEntry): VexFlowStaffEntry {

+ 43 - 0
src/OpenSheetMusicDisplay/OSMDOptions.ts

@@ -0,0 +1,43 @@
+import { DrawingParametersEnum } from "../MusicalScore/Graphical/DrawingParameters";
+
+/** Possible options for the OpenSheetMusicDisplay constructor, none are mandatory. */
+export interface IOSMDOptions {
+    /** Not yet supported. Will always beam automatically. */ // TODO
+    autoBeam?: boolean;
+    /** Automatically resize score with canvas size. Default is true. */
+    autoResize?: boolean;
+    /** Not yet supported. Will always place stems automatically. */ // TODO
+    autoStem?: boolean;
+    /** Render Backend, will be SVG if given undefined, SVG or svg, otherwise Canvas. */
+    backend?: string;
+    /** Don't show/load cursor. Will override disableCursor in drawingParameters. */
+    disableCursor?: boolean;
+    /** Parameters like drawing a Leadsheet or (Thumbnail) Preview, disabling Cursor. */
+    drawingParameters?: string | DrawingParametersEnum;
+    /** Whether to draw hidden/invisible notes (print-object="no" in XML). Default false. Not yet supported. */ // TODO
+    drawHiddenNotes?: boolean;
+    /** Default color for a note head (without stem). Default black. Not yet supported. */ // TODO
+    defaultColorNoteHead?: string;
+    /** Default color for a note stem. Default black. Not yet supported. */ // TODO
+    defaultColorStem?: string;
+    /** Whether to draw the title of the piece. Not yet supported. */ // TODO
+    drawTitle?: boolean;
+    /** Whether to draw credits (title, composer, arranger, copyright etc., see <credit>. Not yet supported. */ // TODO
+    drawCredits?: boolean;
+    /** Whether to draw part (instrument) names. Not yet supported. */ // TODO
+    drawPartName?: boolean;
+}
+
+/** Handles [[IOSMDOptions]], e.g. returning default options with OSMDOptionsStandard() */
+export class OSMDOptions {
+    /** Returns the default options for OSMD.
+     * These are e.g. used if no options are given in the [[OpenSheetMusicDisplay]] constructor.
+     */
+    public static OSMDOptionsStandard(): IOSMDOptions {
+        return {
+            autoResize: true,
+            backend: "svg",
+            drawingParameters: DrawingParametersEnum.Default,
+        };
+    }
+}

+ 97 - 24
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -13,14 +13,26 @@ import {MXLHelper} from "../Common/FileIO/Mxl";
 import {Promise} from "es6-promise";
 import {AJAX} from "./AJAX";
 import * as log from "loglevel";
+import {DrawingParametersEnum, DrawingParameters} from "../MusicalScore/Graphical/DrawingParameters";
+import {IOSMDOptions, OSMDOptions} from "./OSMDOptions";
 
+/**
+ * The main class and control point of OpenSheetMusicDisplay.<br>
+ * It can display MusicXML sheet music files in an HTML element container.<br>
+ * After the constructor, use load() and render() to load and render a MusicXML file.
+ */
 export class OpenSheetMusicDisplay {
     /**
-     * The easy way of displaying a MusicXML sheet music file
-     * @param container is either the ID, or the actual "div" element which will host the music sheet
-     * @autoResize automatically resize the sheet to full page width on window resize
+     * Creates and attaches an OpenSheetMusicDisplay object to an HTML element container.<br>
+     * After the constructor, use load() and render() to load and render a MusicXML file.
+     * @param container The container element OSMD will be rendered into.<br>
+     *                  Either a string specifying the ID of an HTML container element,<br>
+     *                  or a reference to the HTML element itself (e.g. div)
+     * @param options An object for rendering options like the backend (svg/canvas) or autoResize.<br>
+     *                For defaults see the OSMDOptionsStandard method in the [[OSMDOptions]] class.
      */
-    constructor(container: string|HTMLElement, autoResize: boolean = false, backend: string = "svg") {
+    constructor(container: string|HTMLElement,
+                options: IOSMDOptions = OSMDOptions.OSMDOptionsStandard()) {
         // Store container element
         if (typeof container === "string") {
             // ID passed
@@ -33,22 +45,23 @@ export class OpenSheetMusicDisplay {
             throw new Error("Please pass a valid div container to OpenSheetMusicDisplay");
         }
 
-        if (backend === "svg") {
+        if (options.backend === undefined || options.backend.toLowerCase() === "svg") {
             this.backend = new SvgVexFlowBackend();
         } else {
             this.backend = new CanvasVexFlowBackend();
         }
 
+        this.setDrawingParameters(options);
+
         this.backend.initialize(this.container);
         this.canvas = this.backend.getCanvas();
-        const inner: HTMLElement = this.backend.getInnerElement();
+        this.innerElement = this.backend.getInnerElement();
+        this.enableOrDisableCursor(this.drawingParameters.drawCursors);
 
         // Create the drawer
-        this.drawer = new VexFlowMusicSheetDrawer(this.canvas, this.backend, false);
-        // Create the cursor
-        this.cursor = new Cursor(inner, this);
+        this.drawer = new VexFlowMusicSheetDrawer(this.canvas, this.backend, this.drawingParameters);
 
-        if (autoResize) {
+        if (options.autoResize) {
             this.autoResize();
         }
     }
@@ -59,9 +72,11 @@ export class OpenSheetMusicDisplay {
     private container: HTMLElement;
     private canvas: HTMLElement;
     private backend: VexFlowBackend;
+    private innerElement: HTMLElement;
     private sheet: MusicSheet;
     private drawer: VexFlowMusicSheetDrawer;
     private graphic: GraphicalMusicSheet;
+    private drawingParameters: DrawingParameters;
 
     /**
      * Load a MusicXML file
@@ -124,7 +139,9 @@ export class OpenSheetMusicDisplay {
         const reader: MusicSheetReader = new MusicSheetReader();
         this.sheet = reader.createMusicSheet(score, "Unknown path");
         this.graphic = new GraphicalMusicSheet(this.sheet, calc);
-        this.cursor.init(this.sheet.MusicPartManager, this.graphic);
+        if (this.drawingParameters.drawCursors) {
+            this.cursor.init(this.sheet.MusicPartManager, this.graphic);
+        }
         log.info(`Loaded sheet ${this.sheet.TitleString} successfully.`);
         return Promise.resolve({});
     }
@@ -147,15 +164,9 @@ export class OpenSheetMusicDisplay {
         this.sheet.pageWidth = width / this.zoom / 10.0;
         // Calculate again
         this.graphic.reCalculate();
-        this.graphic.Cursors.length = 0;
-        /*this.graphic.Cursors.push(this.graphic.calculateCursorLineAtTimestamp(new Fraction(0, 4), OutlineAndFillStyleEnum.PlaybackCursor));
-        this.graphic.Cursors.push(this.graphic.calculateCursorLineAtTimestamp(new Fraction(1, 4), OutlineAndFillStyleEnum.PlaybackCursor));
-        this.graphic.Cursors.push(this.graphic.calculateCursorLineAtTimestamp(new Fraction(2, 4), OutlineAndFillStyleEnum.PlaybackCursor));
-        this.graphic.Cursors.push(this.graphic.calculateCursorLineAtTimestamp(new Fraction(3, 4), OutlineAndFillStyleEnum.PlaybackCursor));
-        this.graphic.Cursors.push(this.graphic.calculateCursorLineAtTimestamp(new Fraction(4, 4), OutlineAndFillStyleEnum.PlaybackCursor));
-        this.graphic.Cursors.push(this.graphic.calculateCursorLineAtTimestamp(new Fraction(5, 4), OutlineAndFillStyleEnum.PlaybackCursor));
-        this.graphic.Cursors.push(this.graphic.calculateCursorLineAtTimestamp(new Fraction(6, 4), OutlineAndFillStyleEnum.PlaybackCursor));
-        this.graphic.Cursors.push(this.graphic.calculateCursorLineAtTimestamp(new Fraction(7, 4), OutlineAndFillStyleEnum.PlaybackCursor));*/
+        if (this.drawingParameters.drawCursors) {
+            this.graphic.Cursors.length = 0;
+        }
         // Update Sheet Page
         const height: number = this.graphic.MusicPages[0].PositionAndShape.BorderBottom * 10.0 * this.zoom;
         this.drawer.clear();
@@ -163,8 +174,10 @@ export class OpenSheetMusicDisplay {
         this.drawer.scale(this.zoom);
         // Finally, draw
         this.drawer.drawSheet(this.graphic);
-        // Update the cursor position
-        this.cursor.update();
+        if (this.drawingParameters.drawCursors) {
+            // Update the cursor position
+            this.cursor.update();
+        }
     }
 
     /**
@@ -201,7 +214,9 @@ export class OpenSheetMusicDisplay {
      * FIXME: Probably unnecessary
      */
     private reset(): void {
-        this.cursor.hide();
+        if (this.drawingParameters.drawCursors) {
+            this.cursor.hide();
+        }
         this.sheet = undefined;
         this.graphic = undefined;
         this.zoom = 1.0;
@@ -213,6 +228,7 @@ export class OpenSheetMusicDisplay {
      * Attach the appropriate handler to the window.onResize event
      */
     private autoResize(): void {
+
         const self: OpenSheetMusicDisplay = this;
         this.handleResize(
             () => {
@@ -229,7 +245,9 @@ export class OpenSheetMusicDisplay {
                 //    document.documentElement.offsetWidth
                 //);
                 //self.container.style.width = width + "px";
-                self.render();
+                if (this.graphic !== undefined) {
+                    self.render();
+                }
             }
         );
     }
@@ -240,6 +258,9 @@ export class OpenSheetMusicDisplay {
      * @param endCallback is the function called when resizing (kind-of) ends
      */
     private handleResize(startCallback: () => void, endCallback: () => void): void {
+        if (this.graphic === undefined) {
+            return;
+        }
         let rtime: number;
         let timeout: number = undefined;
         const delta: number = 200;
@@ -274,7 +295,59 @@ export class OpenSheetMusicDisplay {
         window.setTimeout(endCallback, 1);
     }
 
+    /** Enable or disable (hide) the cursor.
+     * @param enable whether to enable (true) or disable (false) the cursor
+     */
+    public enableOrDisableCursor(enable: boolean): void {
+        this.drawingParameters.drawCursors = enable;
+        if (enable) {
+            if (!this.cursor) {
+                this.cursor = new Cursor(this.innerElement, this);
+                if (this.sheet && this.graphic) { // else init is called in load()
+                    this.cursor.init(this.sheet.MusicPartManager, this.graphic);
+                }
+            }
+        } else { // disable cursor
+            if (!this.cursor) {
+                return;
+            }
+            this.cursor.hide();
+            // this.cursor = undefined;
+            // TODO cursor should be disabled, not just hidden. otherwise user can just call osmd.cursor.hide().
+            // however, this could cause null calls (cursor.next() etc), maybe that needs some solution.
+        }
+    }
+
     //#region GETTER / SETTER
+    private setDrawingParameters(options: IOSMDOptions): void {
+        this.drawingParameters = new DrawingParameters();
+        if (options.drawingParameters) {
+            this.drawingParameters.DrawingParametersEnum = DrawingParametersEnum[options.drawingParameters];
+        }
+        // individual drawing parameters options
+        if (options.disableCursor) {
+            this.drawingParameters.drawCursors = false;
+        }
+        if (options.drawHiddenNotes) {
+            this.drawingParameters.drawHiddenNotes = true;
+        }
+        if (options.drawTitle !== undefined) {
+            this.drawingParameters.drawTitle = options.drawTitle;
+        }
+        if (options.drawPartName !== undefined) {
+            this.drawingParameters.drawPartName = options.drawPartName;
+        }
+        if (options.drawCredits !== undefined) {
+            this.drawingParameters.drawCredits = options.drawCredits;
+        }
+        if (options.defaultColorNoteHead) {
+            this.drawingParameters.defaultColorNoteHead = options.defaultColorNoteHead;
+        }
+        if (options.defaultColorStem) {
+            this.drawingParameters.defaultColorStem = options.defaultColorStem;
+        }
+    }
+
     public set DrawSkyLine(value: boolean) {
         if (this.drawer) {
             this.drawer.skyLineVisible = value;

+ 2 - 1
test/Common/FileIO/Xml_Test.ts

@@ -48,7 +48,8 @@ describe("XML interface", () => {
             // Load the xml file content
             const score: Document = TestUtils.getScore(scoreName);
             const div: HTMLElement = document.createElement("div");
-            const openSheetMusicDisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+            const openSheetMusicDisplay: OpenSheetMusicDisplay =
+                TestUtils.createOpenSheetMusicDisplay(div);
             openSheetMusicDisplay.load(score);
             done();
         }).timeout(3000);

+ 11 - 12
test/Common/OSMD/OSMD_Test.ts

@@ -2,7 +2,6 @@ import chai = require("chai");
 import {OpenSheetMusicDisplay} from "../../../src/OpenSheetMusicDisplay/OpenSheetMusicDisplay";
 import {TestUtils} from "../../Util/TestUtils";
 
-
 describe("OpenSheetMusicDisplay Main Export", () => {
     let container1: HTMLElement;
 
@@ -24,7 +23,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("load MXL from string", (done: MochaDone) => {
         const mxl: string = TestUtils.getMXL("Mozart_Clarinet_Quintet_Excerpt.mxl");
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         opensheetmusicdisplay.load(mxl).then(
             (_: {}) => {
                 opensheetmusicdisplay.render();
@@ -37,7 +36,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("load invalid MXL from string", (done: MochaDone) => {
         const mxl: string = "\x50\x4b\x03\x04";
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         opensheetmusicdisplay.load(mxl).then(
             (_: {}) => {
                 done(new Error("Corrupted MXL appears to be loaded correctly"));
@@ -56,7 +55,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
         const score: Document = TestUtils.getScore("MuzioClementi_SonatinaOpus36No1_Part1.xml");
         const xml: string = new XMLSerializer().serializeToString(score);
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         opensheetmusicdisplay.load(xml).then(
             (_: {}) => {
                 opensheetmusicdisplay.render();
@@ -69,7 +68,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("load XML Document", (done: MochaDone) => {
         const score: Document = TestUtils.getScore("MuzioClementi_SonatinaOpus36No1_Part1.xml");
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         opensheetmusicdisplay.load(score).then(
             (_: {}) => {
                 opensheetmusicdisplay.render();
@@ -82,7 +81,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("load MXL Document by URL", (done: MochaDone) => {
         const url: string = "base/test/data/Mozart_Clarinet_Quintet_Excerpt.mxl";
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         opensheetmusicdisplay.load(url).then(
             (_: {}) => {
                 opensheetmusicdisplay.render();
@@ -95,7 +94,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("load something invalid by URL", (done: MochaDone) => {
         const url: string = "https://www.google.com";
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         opensheetmusicdisplay.load(url).then(
             (_: {}) => {
                 done(new Error("Invalid URL appears to be loaded correctly"));
@@ -113,7 +112,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("load invalid URL", (done: MochaDone) => {
         const url: string = "https://www.afjkhfjkauu2ui3z2uiu.com";
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         opensheetmusicdisplay.load(url).then(
             (_: {}) => {
                 done(new Error("Invalid URL appears to be loaded correctly"));
@@ -131,7 +130,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("load invalid XML string", (done: MochaDone) => {
         const xml: string = "<?xml";
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         opensheetmusicdisplay.load(xml).then(
             (_: {}) => {
                 done(new Error("Corrupted XML appears to be loaded correctly"));
@@ -148,7 +147,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
 
     it("render without loading", (done: MochaDone) => {
         const div: HTMLElement = TestUtils.getDivElement(document);
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         chai.expect(() => {
             return opensheetmusicdisplay.render();
         }).to.throw(/load/);
@@ -167,7 +166,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("test width 500", (done: MochaDone) => {
         const div: HTMLElement = container1;
         div.style.width = "500px";
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         const score: Document = TestUtils.getScore("MuzioClementi_SonatinaOpus36No1_Part1.xml");
         opensheetmusicdisplay.load(score).then(
             (_: {}) => {
@@ -182,7 +181,7 @@ describe("OpenSheetMusicDisplay Main Export", () => {
     it("test width 200", (done: MochaDone) => {
         const div: HTMLElement = container1;
         div.style.width = "200px";
-        const opensheetmusicdisplay: OpenSheetMusicDisplay = new OpenSheetMusicDisplay(div);
+        const opensheetmusicdisplay: OpenSheetMusicDisplay = TestUtils.createOpenSheetMusicDisplay(div);
         const score: Document = TestUtils.getScore("MuzioClementi_SonatinaOpus36No1_Part1.xml");
         opensheetmusicdisplay.load(score).then(
             (_: {}) => {

+ 2 - 1
test/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer_Test.ts

@@ -9,6 +9,7 @@ import {IXmlElement} from "../../../../src/Common/FileIO/Xml";
 import {Fraction} from "../../../../src/Common/DataObjects/Fraction";
 import {VexFlowBackend} from "../../../../src/MusicalScore/Graphical/VexFlow/VexFlowBackend";
 import {CanvasVexFlowBackend} from "../../../../src/MusicalScore/Graphical/VexFlow/CanvasVexFlowBackend";
+import {DrawingParameters} from "../../../../src/MusicalScore/Graphical/DrawingParameters";
 
 /* tslint:disable:no-unused-expression */
 describe("VexFlow Music Sheet Drawer", () => {
@@ -47,7 +48,7 @@ describe("VexFlow Music Sheet Drawer", () => {
         const canvas: HTMLCanvasElement = document.createElement("canvas");
         const backend: VexFlowBackend = new CanvasVexFlowBackend();
         backend.initialize(canvas);
-        const drawer: VexFlowMusicSheetDrawer = new VexFlowMusicSheetDrawer(canvas, backend);
+        const drawer: VexFlowMusicSheetDrawer = new VexFlowMusicSheetDrawer(canvas, backend, new DrawingParameters());
         drawer.drawSheet(gms);
         done();
     });

+ 5 - 0
test/Util/TestUtils.ts

@@ -1,3 +1,5 @@
+import { OpenSheetMusicDisplay } from "../../src/OpenSheetMusicDisplay/OpenSheetMusicDisplay";
+
 /**
  * This class collects useful methods to interact with test data.
  * During tests, XML and MXL documents are preprocessed by karma,
@@ -37,4 +39,7 @@ export class TestUtils {
         }
     }
 
+    public static createOpenSheetMusicDisplay(div: HTMLElement): OpenSheetMusicDisplay {
+        return new OpenSheetMusicDisplay(div);
+    }
 }

+ 1 - 1
webpack.prod.js

@@ -35,6 +35,6 @@ module.exports = merge(common, {
             path: path.resolve(__dirname, 'build'),
             filename: './statistics.html'
         }),
-        new Cleaner(pathsToClean, {verbose: true, dry: false})
+        new Cleaner(pathsToClean, { verbose: true, dry: false })
     ]
 })