abcjs
Version:
Renderer for abc music notation
119 lines (107 loc) • 3.71 kB
JavaScript
// abc_editor.js
// window.ABCJS.Editor is the interface class for the area that contains the ABC text. It is responsible for
// holding the text of the tune and calling the parser and the rendering engines.
//
// EditArea is an example of using a textarea as the control that is shown to the user. As long as
// the same interface is used, window.ABCJS.Editor can use a different type of object.
//
// EditArea:
// - constructor(textareaid)
// This contains the id of a textarea control that will be used.
// - addSelectionListener(listener)
// A callback class that contains the entry point fireSelectionChanged()
// - addChangeListener(listener)
// A callback class that contains the entry point fireChanged()
// - getSelection()
// returns the object { start: , end: } with the current selection in characters
// - setSelection(start, end)
// start and end are the character positions that should be selected.
// - getString()
// returns the ABC text that is currently displayed.
// - setString(str)
// sets the ABC text that is currently displayed, and resets the initialText variable
// - getElem()
// returns the textarea element
// - string initialText
// Contains the starting text. This can be compared against the current text to see if anything changed.
//
// Polyfill for CustomEvent for old IE versions
try {
if (typeof window.CustomEvent !== "function") {
var CustomEvent = function (event, params) {
params = params || {bubbles: false, cancelable: false, detail: undefined};
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
};
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
}
} catch (e) {
// if we aren't in a browser, this code will crash, but it is not needed then either.
}
var EditArea = function (textareaid) {
this.isEditArea = true
if (typeof textareaid === "string") {
this.textarea = document.getElementById(textareaid);
if (!this.textarea)
this.textarea = document.querySelector(textareaid)
} else
this.textarea = textareaid;
this.initialText = this.textarea.value;
this.isDragging = false;
}
EditArea.prototype.addSelectionListener = function (listener) {
this.textarea.onmousemove = function (ev) {
if (this.isDragging)
listener.fireSelectionChanged();
};
};
EditArea.prototype.addChangeListener = function (listener) {
this.changelistener = listener;
this.textarea.onkeyup = function () {
listener.fireChanged();
};
this.textarea.onmousedown = function () {
this.isDragging = true;
listener.fireSelectionChanged();
};
this.textarea.onmouseup = function () {
this.isDragging = false;
listener.fireChanged();
};
this.textarea.onchange = function () {
listener.fireChanged();
};
};
//TODO won't work under IE?
EditArea.prototype.getSelection = function () {
return {start: this.textarea.selectionStart, end: this.textarea.selectionEnd};
};
EditArea.prototype.setSelection = function (start, end) {
if (this.textarea.setSelectionRange)
this.textarea.setSelectionRange(start, end);
else if (this.textarea.createTextRange) {
// For IE8
var e = this.textarea.createTextRange();
e.collapse(true);
e.moveEnd('character', end);
e.moveStart('character', start);
e.select();
}
this.textarea.focus();
};
EditArea.prototype.getString = function () {
return this.textarea.value;
};
EditArea.prototype.setString = function (str) {
this.textarea.value = str;
this.initialText = this.getString();
if (this.changelistener) {
this.changelistener.fireChanged();
}
};
EditArea.prototype.getElem = function () {
return this.textarea;
};
module.exports = EditArea;