abcjs
Version:
Renderer for abc music notation
113 lines (101 loc) • 3.56 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.textarea = document.getElementById(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;