|
UiGuide
TimeSide UI integration guide
Featured Table of contents IntroductionThe TimeSide UI features a powerful DHTML-based interactive player with time marking capabilities. It can be used as a standalone client-side component. As of June 2011, it is supported in all major browsers: Internet Explorer (IE) 7+, Firefox (FF) 3.5+ and Chrome 9+ The player can be created and manipulated using a JavaScript object oriented API, customized using CSS and skins, and dynamically resized:
See here for a live example with enhanced marker objects, as explained in the Marker section. For reference, here is the structure of the dynamically generated markup structure: Markup structure<div class="ts-ruler"> <!-- upper <div> (ruler) -->
<svg class="ts-ruler-lines"> <!-- The ruler lines -->
<a class="ts-pointer"><span/></a> <!-- pointer label -->
<a class="ts-marker"><span/></a> <!-- marker label -->
...
</div>
<div class="ts-wave"> <!-- central <div> (wave) -->
<div class="image-canvas"> <!-- svgs container. Should not be modified by custom css-->
<svg class="ts-pointer-canvas"> <!-- Pointer vertical line -->
<svg class="ts-marker-canvas"> <!-- Marker vertical line -->
...
</div>
<div class="image-container"> <!-- wave image container. Should not be modified by custom css-->
<img class="image"/> <!-- wave image. Should not be modified by custom css-->
</div>
</div>
<div class="ts-control"> <!-- bottom <div> (control) -->
<a class='ts-play ts-button'></a>
<a class='ts-pause ts-button'></a>
<a class='ts-rewind ts-button'></a>
<a class='ts-forward ts-button'></a>
<a class='ts-set-marker ts-button'></a>
<a class='ts-volume-speaker ts-button'></a>
<div class='ts-volume-wrapper-div'>
<a class='ts-volume-bar-container'>
<span class='ts-volume-bar'></span>
</a>
</div>
<div class='ts-wait'></div>
</div>
<!-- Note that all svg's might be vml object if svg is not supported (thanks to Raphael library, see doc below -->Setup and DependenciesThe easiest way to get started is to copy the content of the TimeSide UI package on your webserver, for example in a timeside-ui/ folder. A few external JavaScript packages are required, and must be loaded before TimeSide UI:
For conveniency these libraries are bundled in the TimeSide UI package. So settings things up should be easily done within the <head/> tag: <script type="text/javascript" src="timeside-ui/lib/jquery-1.6.min.js"></script> <script type="text/javascript" src="timeside-ui/lib/soundmanager2-nodebug-jsmin.js"></script> <script type="text/javascript" src="timeside-ui/timeside.js"></script> Of course, you are free to load your preferred versions of the dependencies, provided they meet the requirements outlined above. As svg is not supported in all browsers (specifically, IE7 and IE8), the TimeSide library first checks for svg support and, in negative case, loads and delegates the Raphael Graphics Library for building vml graphics (an old format of IE). The library is also bundled in in the TimeSide UI package Getting startedFew notes before getting started: the whole TimeSide UI API resides under the Timeside JavaScript global object (The goal is to strictly avoid polluting the global namespace). To initialize the TimeSide player it is sufficient to call the method Timeside.load as described below. The method is executed once the document is ready, so that it can be safely called everywhere in the code; it first loads all necessary timeside scripts (including Raphael library if necessary) whose path is retrieved by searching the src attribute of the timeside.js <script>: therefore, move your timeside-ui/ folder wherever you want but do not move any JavaScript file within it! SoundManager has properties which configure debug mode, flash movie path and other behaviours. At minimum, the soundManager.url property must be assigned a path used to look for the necessary flash movie. Therefore, before loading the player it is necessary to write something like: <script type="text/javascript"> soundManager.url = '/path/to/swfs/'; // path (directory) where SM2 .SWF files will be found. </script> where '/path/to/swfs/' is the path of the '/swf' folder inside the downloaded TimeSide package. Please refer to soundManager configuration for more properties. We are aware that in JavaScript Integer and Float types are treated as a numeric type. However, in the remainder of the document (especially in code examples) we will avoid formality in order to be exhaustive. Therefore, when possible we will use the notations int and float A simple (static) playerA simple graphical player can be embedded in your HTML page by calling, e.g.: Timeside.load({
container: "#player",
sound: "/path-to/my_sound.mp3"
soundDuration: 149264,
soundImage: "/path-to/my_image.png"
}
);where: container: string or object is the player containing <div>, in one of the following formats Note that
sound: string or object is the sound to be played, in one of the following formats: duration: int is the sound duration in milliseconds. A typical example is t calculate it server-side by means of TimeSide analysers and sent to the page. This parameter is mandatory, otherwise the sound object should be first loaded in order to know its duration, and then the player (and thus, the HTML page) rendered and displayed. In any case, it is possible to query the sound object (at the cost of slowing down page rendering), but in this case the sound object must be preloaded:
soundImage: string is the wave image URL, in string format A more complex (dynamic) playerTo fully take advantage of all player capabilities (e.g., dynamic resizing, control over the loading process, marker management, player management once loaded) we can create a player by calling: Timeside.load({
container: "#player",
sound: "/path-to/my_sound.mp3"
soundDuration: 149264,
soundImage: function(width,height){...},
imageSize: {width: 170,height: 30}, //optional
markersArray: [marker_1, ...., marker_N], //optional
newMarker: function(offset){...}, //optional
onError: function(errorMsgString){...}, //optional
onReady: function(player){...}, //optional
onReadyWithImage: function(player){...}, //optional
messages: {loading: 'loading', ...} //optional
}
);where container, sound and duration are specified above, and: soundImage: string or function is the wave image URL. It can be: imageSize: object is a JavaScript object with two properties, 'width' and 'height', which specifiy the initial default size of the wave <div>. Any other value (undefined, null, non-JavaScript object) will be ignored and has no effect on the initial size (which will be thus calculated according to the css rules). Accordingly, an object with only one property 'width' or 'height' will skip the missing one and set only the existing one. Note: Usually the player is embedded in a web page with components interacting with each other. Thus it might be more convenient to skip this parameter and specify player dimensions properties in a separate stylesheet (see CSS and skins section for details) as for all other page elements. Keep in mind however, that if no css at all is provided on the player elements, imageSize must be specified to properly display at least the wave image markersArray: Array is an array of markers to be visualized on the player ruler when the player loads. In the remainder of this doc, a marker is a JavaScript object with only one required key, offset, which indicates the marker time position as a float in the format seconds.milliseconds, e.g.:
When the player is fully loaded, markers are stored in an Array-like object (markerMap) instance of TimesideArray. The map is sorted in ascending order according to markers offset. An (unique) id is automatically set on each marker in order to manage the case of two markers with the same offset (see notes on newMarker below for details). Adding, removal and getting marker elements is performed via a binary search algorithm which is substantially faster as the number of markers N grows large (log2(N) maximum iterations) newMarker: boolean or function controls whether new markers can be added to the player (and graphically on the player ruler). Possible values are:
function(offset){
return {
offset: parseFloat(offset),
description: "",
title: "",
isEditable: true,
isSavedOnServer: false
}
};Obviously, the object returned by newMarker should be consistent with the elements of the parameter markersArray, if the latter is provided as a non emtpy array. Notes: the marker offset must be a JavaScript number (we provided as hint the use of JavaScript function parseFloat in the example above). It is extremely important for each offset to be a number. As JavaScript is a weakly typed language, passing non-number offsets might lead to subtle errors to catch: imagine for instance two markers with offsets "10.5" and "9.5" (strings). The markers would be normally inserted in the map. However, as "10.5" < "9.5", their insertion order would be incorrect, and the insertion index of any other marker inserted afterwards unpredictable. As a consequence, the positions of the marker labels on the player ruler would mismatch their index, and - even worse - any custom method that relies upon markers control and management might fail). The property isEditable, although not mandatory, determines whether or not the marker offset can be changed, i.e. if it can be moved on the player ruler. If missing, it defaults to false. Therefore, in the example above, clicking the button 'add marker' will display a dynamic marker (movable with mouse events); on the other hand, if newMarker is simply set to true, clicking the button 'add marker' will display a static marker (isEditable is missing by default). The editable property of each marker can be changed via the property player.setMarkerEditable, as explained in details in the player marker properties Summarizing, a marker is a JavaScript object which the user must provide at least with one required key, offset, as float. However, to tell the whole story, a marker is stored in the markerMap as an object with at least three properties: offset (float, required), isEditable (boolean, if missing is set to false) and id (if missing is automatically created by the markerMap and must be unique for each marker). By default it is a string with fixed length derived from the current timestamp and a randomly generated number. A user defined id must be unique for each marker and should be consistently comparable against other ids, as for markers with the same offset, ids will determine the necessary sort order and, if equal, that the two markers are equal. In general, there is no reason to implement a custom id onError: function(string) a callback to be executed when an error occurs. This includes non existing container, sound duration NaN (or non-positive) etcetera. The string argument passed to the callback is the error message. It is not fired on sound errors (see notes below for onReady) onReady: function(player) a callback to be executed when the player is fully loaded. The argument player passed to the callback is the newly created player, which in any case from the execution of this callback on will be globally accessible via the variable Timeside.player. Notes: onReady is fired when the player is fully loaded, although the wave image could still be loading. To know the status of the loading process, use the property player.isImgRefreshing (see player properties and methods for details). To execute a callback once the player is ready and the sound image is fully loaded, use the property onReadyWithImage (see below) onReady is executed even in case of sound error (e.g. if soundManager or the player sound object is not succesfully initialized) as this does not interfere with the correct player layout. Sound error messages are stored in the property player.soundErrorMsg. Bad sound urls (eg, pointing to non existing files) are cought once the player.play is called, so that at this stage player.soundErrorMsg might be empty (no error) even if the sound is not playable onReadyWithImage: function(player) a callback to be executed when the player is fully loaded and its image has been loaded. This callback is likely to be called after onReady. The argument player passed to the callback is the newly created player, which in any case from the execution of this callback on will be globally accessible via the variable Timeside.player onReadyWithImage is also executed even if the sound object of the player is not succesfully initialized (see notes on onReady above) messages: Object Property setting an object with the default messages to be displayed on the wait panel. The player has three types of default messages:messages.loading = "loading" //displayed when playback is started and sound is loading messages.buffering = "buffering" //displayed when playback is started and sound is buffering messages.imgRefreshing = "refreshing img" //displayed when image is being loading and not-yet displayedwhich can be customized in messages. These properties can be also set after the player is loaded via the property player.msgs. Setting a property to the empty string (or any other value which evaluates to false, e.g. undefined) will NOT display the wait panel when the corresponding event is fired Markers control and managementWith customized marker objects (i.e., when the parameter newMarker described above is a user defined function) the user might want also to interact with the player in order to add/edit/remove markers. As we will see more specifically in the last section, each class defined in the variable TimeSide (as well as the player object) is instance of Timeside.classes.TimesideClass, a function with methods for adding listeners and action notifications, the same way standard event types (e.g., 'onclick') are bound to document elements. The marker-specific eventTypes bound to the player object are three (for a complete list, see subsection "Default event types" in Event listening and notification): player.bind('markerAdded',callback(data));
player.bind('markerRemoved',callback(data));
player.bind('markerMoved',callback(data));where callback is a function which must take a parameter data (JavaScript object), which reads: 'markerAdded': data={
marker: object, //The newly created marker
index: int //The index of the newly created marker
}'markerRemoved': data={
marker: object, //The marker removed
index: int //The index of the removed marker
}'markerMoved': data={
marker: object, //The marker moved
oldOffset: float, //The old offset of the marker. The new offset (new offset != old offset) is marker.offset
fromIndex: int, //The old index of the moved marker
toIndex: int, //The new index of the moved marker. It might be equal to fromIndex
// if the marker did not "cross" any other marker in the markermap
}If you are familiar with jQuery, note that the syntax is exactly the same as jQuery.bind(eventType,handler), the only difference is a third (optional) parameter which denotes the reference to the this keyword inside the callback, e.g.: player.bind('markerAdded',function(data){
var p = this; //refers to Timeside.player object
},Timeside.player);ExamplesAs a (quite foolish) example, if we want to alert the user every time a new marker is added, we can write: Timeside.player.bind('markerAdded', function(data){
alert('new marker added at time '+data.marker.offset+' and index '+data.index);
});and click on the player 'add marker' button to see the alert dialog displaying the message As a more complex example, imagine we want a player where:
To achieve this, we can imagine that each time the user presses the 'add marker' button on the player, we add a 'row' on a spearated <div> (which we created) which could look like this:
1st step: Initialize the player with newMarkerCallback returning objects of the type, e.g.: {
isEditable: true,
offset: parseFloat(offset),
title: "", //default marker title when, e.g., the add marker button is pressed
}2nd step: add bindings to the player: var p = Timeside.player;
p.bind('markerAdded', function(data){
var m = data.marker; //reference to the newly created marker
//create html elements:
var okButton = jQuery('<input/>').attr('type','button').val('ok');
var textInput = jQuery('<input/>').attr('type','text').val(m.title);
var deleteButton = jQuery('<input/>').attr('type','button').val('delete');
//do other stuff, e.g. append elements to a div or a container etcetera...
//Now: When the user clicks the ok button, set marker title according to the text input value
okButton.click(function(){
m.title = textInput.val();
});
//When the user clicks the remove button, remove the marker
//this will fire events of type 'markerRemoved'
deleteButton.click(function(){
p.removeMarker(m); //note that p.removeMarker(data.index) is safe ONLY if the markers cannot be moved
});
});
//listen for marker removal events:
p.bind('markerRemoved', function(data){
//remove components, e.g., the <div> containing the input, ok and delete button associated to the removed marker
});
//listen for marker move events:
p.bind('markerMoved', function(data){
//reorder inputs and ok buttons to match the marker order
//Eg:
//detach div at index data.fromIndex
//re-insert the div at index data.toIndex
});LayoutCSS and skinsThe appearance of TimeSide UI can be fully customized through CSS rules, applied to the markup structure. Two default skins are also provided in the skins/ subfolder. They can be set in the standard way within the <head/> tag: <link type="text/css" href="timeside-ui/skin/lab/style.css" /> or <link type="text/css" href="timeside-ui/skin/classic/style.css" /> The default skins exploit contextual selectors (e.g., ".player .ts-ruler"), so the player must embedded in (or in a child of) a div of class 'ts-player', e.g.: <div class="ts-player" />
<!--player is contained here somewhere...-->
</div>If you don't like this restriction, feel free to modify the css according to your needs. We only suggest to embed the player this way at first to see what's going on behind the scene (by exploring the css files) before providing your custom skins. Notes (in the remainder of this section, we will denote R, W and C as player ruler, wave and control <div>s, whose css class selectors are ".ts-ruler", ".ts-wave" and ".ts-control", respectively. See player figure and and markup structure in the Introduction):
Therefore, setting player total width is quite straighforward: you can set it by means of css width property on W (this is actually what happens when imgSize width is specified), or you can simply provide no css width property at all for any player <div>, letting the player fit the avilable parent width. In any case, according to what stated above, do not specify the same width property for W, R and C (is useless), and do not specify different width propertis for W, R and C (is dangerous). Setting the player total height is done separately on W, R and C css height properties in the standard way, i.e., by means of css rules applied on them or their contained elements. Two remarks on JavaScript code: first, most of W sub components (sound image, marker and ruler vertical lines) are "stretched" automatically to fit all the available room (which also means that some of their css can not be customized), so W must have a nonzero non 'auto' height. Second, the height of the vector-graphics ruler of R is set as the height of two lines of text, i.e., according to R 'font-size' and 'line-height' css properties (if missing they wil be inherited from the parent)
"clip-rect", "cursor",'fill', "fill-opacity", "opacity",
"stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit","stroke-opacity","stroke-width", "text-anchor" .ts-svg-marker-canvas{
stroke-width:2;
}will set a stroke of width 2 on the elements of class 'ts-svg-marker-canvas' in all browsers, whereas
.ts-svg-ruler-lines{
stroke: white; //ERROR on non svg supporting browsers which PREVENTS the player to be loaded!!
}Any other value seems to be safe. We suggest however to provide those properties as standard hexadecimal values:
Dynamic resizingUnlike Flash-based media players, the DHTML-based TimeSide player can be resized in various ways (as explained in the previous section) by dynamically modifying the CSS rules of the player elements or those of one of its containers in the HTML page, or by simply resizing the browser window if the player size is relative to the window. The TimeSide.Player class can automatically track browser window resize events if its property setDynamicsResize is called with true as argument (it is false by default). In this case, the player checks at regular intervals (JavaScript setInterval method) potential size changes. If it is the case, it calls player.refreshImage() which in turn calls player.imageCallback (which can specified when loading the player via the parameter soundImage). Obviously, for accurate high quality server-side resizing/resampling, setDynamicResize(true) should be called if player.imageCallback is a callback returning a width- and height-dependent image (where width and height are the callback arguments). Note that in case of repeated size changes (such as, i.e., window mouse resizing while dragging) only the last resize is fired. This attempts to prevent several unnecessary refreshImage calls which might lead to an unresponsive page. Basically, each time a player size change is detected, refreshImage is called within a delay of time only if meanwhile it's size has not changed again
Timeside UI codeThe TimeSide player is created and can be manipulated using a JavaScript object oriented API. The JavaScript inheritance-simulating techniques is accomplshed by means of a 'Class' function which is the ancestor class of all TimeSide classes: Inhertance Structure/*
*Function name defined in: Description
*/
Class (`timeside.js`) //The base javscript function with class functionalities:
| // simple inheritance and super method calling
|
+- TimesideClass (`timeside.js`) //Class implementation ancestor class of all Timeside classes
|
+- RulerMarker (`rulermarker.js`) //TimesideClass for building each marker on the ruler (including pointer)
|
+- Player (`player.js`) //TimesideClass for building the player
|
+- TimesideArray (`timeside.js`) //TimesideClass with array-like properties and methods
|
+- MarkerMap (`markermap.js`) //TimesideArray for managing markers
|
+- Ruler (`ruler.js`) //TimesideArray for building the ruler and managing rulermarkersAs already mentioned, the only variable created on the window object is the Timeside variable, which includes: Timeside = {
Class, //The Class object whereby each element of Timeside.classes has been created,
classes : {
TimesideClass, //accessible with Timeside.classes.TimesideClass
TimesideArray, //accessible with Timeside.classes.TimesideArray
MarkerMap, //...
Ruler, //...
RulerMarker, //...
Player //...
},
player, //The player object = new Timeside.classes.Player(...) accessible with Timeside.player
//when the player is created:
//player.getMarkerMap() returns the player markerMap object = new Timeside.classes.MarkerMap(...)
//player.getRuler() returns the player ruler object = new Timeside.classes.Ruler(...)
//player.getRuler().toArray()[i] returns the ruler i-th marker = new Timeside.classes.RulerMarker(...)
//player.getRuler().getPointer() returns the ruler pointer = new Timeside.classes.RulerMarker(...) as well
load(), //Function to be called in order to initialize Timeside.player (see above)
config, //object with configuration properties to be used in load
utils //object with utilities functions/properties to be used by Timeside classes
}Therefore, once fully initialized, the user can work with the accessible Timeside.player object (instance of Timeside.classes.Player) The Player object: properties and methodsHere properties and method of the player object. player is a shorthand for Timeside.player Playbackplayer.play() Starts playback. This method is called by the 'play' button on the control <div/> player.setSoundPosition(offset) Sets the sound position and moves the pointer on the player ruler accordingly. This method is called by the 'play' button on the control <div/>
player.playState //Read-only property. Do not modify! Property returning an integer indicating the player play state. Read-only property. Do not modify! Possible values are: player.pause() Pauses playback. This method is called by the 'pause' button on the control <div/> (this method is actually stopping the sound object. This allows to more reliably work with the sound.position property) player.rewind() Sets the sound position (and moves the pointer) to the previous marker position (according to the current sound position), or to the start of sound if no previous marker is found. This method is called by the 'rewind' button on the control <div/> player.forward() Sets the sound position (and moves the pointer) to the next marker position (according to the current sound position), or to the end of sound if no previous marker is found. This method is called by the 'forward' button on the control <div/> player.getSound() Returns the sound object associated to the player. Manipulating the sound object directly is discouraged, as it might interfere with the player object. This method is intended for retrieving properties not directly accessible via the player object. Returns undefined if a sound error occurs player.soundErrorMsg Returns the empty string if the sound object of the player has been succesfully initialized. Otherwise, it is a string denoting the error occurred. This includes soundManager errors (including flash errors for non-html5 supporting browsers), bad sound-object (or sound-object parameters), invalid urls. The case of urls not pointing to existing and "playable" audio files will be cought only the first time player.play is called. player.showSoundErrorMessage() Callback to be executed when player.play is called and the sound object of the player has not been succesfully initialized. It can be overridden: by default, it shows an alert dialog with the content of player.soundErrorMsg player.soundPosition //Read-only property. Do not modify! Returns the current sound position, in the format seconds.milliseconds (e.g., 45.672). Read-only property. Do not modify! player.getSoundDuration() Returns the total duration of the sound, in the format seconds.milliseconds (e.g., 45.672) player.setSoundVolume(volume) Sets the volume of the sound. This method is called by the volume-related button(s) on the control <div/>
player.soundVolume //Read-only property. Do not modify! Returns a number between 0 and 100 denoting the sound volume. Read-only property. Do not modify! player.readyState() Returns a numeric value indicating a sound's current load status:
Note: If the player is created by passing an already created sound object, readyState() might be 2 even if player.soundErrorMsg is empty. Otherwise, if the player is created by means of a url string or an object denoting the sound object default properties, player.soundErrorMsg might be a non-empty string even if readyState() is not 2 (e.g., it might be 0, i.e. uninitialized) Markersplayer.newMarker(offset) Function that builds and returns the marker object with offset property equals to offset. Can be overridden (see above) for custom markers
player.addMarker(offset) Adds a new marker at offset . Calls by default player.newMarker(offset) and puts in the map the returned marker. This method is called by the 'add marker' button on the control <div/> (if visible)
player.removeMarker(identifier) Removes a marker
player.moveMarker(identifier, newOffset) Moves a marker to a new offset
player.getMarker(index) Returns the index-th marker of the player, or undefined if index is lower than zero or greater than len - 1, where len is the number of markers of the player
player.setMarkerEditable(identifier, value) Sets a marker property isEditable = value. You can change also directly the property isEditable on each markerm but this will not fire events of type "markerEditStateChanged", so avoid it if you want notifications when a marker has changed its editable state (see "Default event types" in the section Event listening and notification)
player.each(callback) player.each(startIndex, callback) player.each(startIndex, endIndex, callback) Iterates over the player markers. Each time callback runs, it is passed two arguments: the current loop iteration i, and the marker at index i.
Example: print on the console the informations about all the current markers:
Layoutplayer.imageCallback(width, height) Function that returns the wave image to be displayed according to the wave <div/> width and height. The function must return a valid URL pointing to an image. This allows, e.g., to perform high quality server-side resizing/resampling by querying Timeside grapher for a sound image with given width and height. This callback is specified as starting player parameter (see above)
player.refreshImage() Forces a refresh of the image. Set the wave image src to the url returned by imageCallback player.isImgRefreshing //Read-only property, do not modify! Boolean value indicating whether or not the wave image is being loading and not-yet displayed. Read-only property. Do not modify! player.resize() Forces a resize of the player. It resizes the player ruler and control and calls player.refreshImage() player.setDynamicResize(value) Sets dynamic resize. If value is true, the player starts checking at regular interval potential size changes and in case, it will set the wave image src to the url returned by imageCallback
player.getImageUrl() Returns a string of the URL of the wave image (i.e., the src attribute of the wave <img/>) player.getImageSize() Returns an object with two number properties, width an height, denoting the size of the wave image Miscellaneousplayer.setWait(message) Sets the content of the wait panel (<div/>) in the lower right corner of the player (see player image in the Introduction) and hides or shows the <div/> accordingly
player.msgs Property returning an object with the default messages to be displayed on the wait panel (<div/> innerHTML). There are currently three types of default messages: msgs.loading = 'loading' //displayed when playback is started and sound is loading msgs.buffering = 'buffering' //displayed when playback is started and sound is buffering msgs.imgRefreshing = 'refreshing img' //displayed when image is being loading and not-yet displayed These properties can be customized after the player is loaded. Setting a property of player.msgs to the empty string (or any other value which evaluates to false, e.g. undefined) will NOT display the wait panel when the corresponding event is fired Event listening and notificationplayer.bind(eventType, callback) player.bind(eventType, callback, thisArgInCalback) Binds a callback to eventType. The function callback will be executed each time fire(eventType) will be called on the player (see below).
player.fire(eventType) player.fire(eventType, data) Fires (triggers) all callbacks associated to eventType by means of player.bind(eventType,...). It does nothing if no callback is bound to eventType
player.unbind() player.unbind(eventType) Unbinds (i.e., removes from memory) all callbacks bound to eventType
As in jQuery bind, If the eventType string contains a period (.) character, then the event is namespaced. The period character separates the event from its namespace. For example, in the call .bind('markerMove.name', function(data){...}), the string "markerMove" is the event type, and the string "name" is the namespace. Namespacing allows us to unbind or trigger some events of a type without affecting others. Accordingly, when a callback is bound in this fashion, we can still unbind it the normal way: .unbind('markerMove') or alternatively, if we want to avoid affecting other callbacks, we can be more specific, i.e. .unbind('markerMove.name'). Note that TimeSide namespacing does not have the whole funtionalities of jQuery namespacing, please refer only to those just described. Moreover, consider that in the TimeSide library a period character is considered a namespace separator only if it splits non-empty strings. In other words, event types such as ".name" or "name." will be considered as they are, without namespaces. As in jQuery namespacing, if a string contains more than a period character, the first period only will be considered the namespace separator.
Default event typesFunctions which interact with the player can bind calbacks to the following event types implemented by default:
Notes: Events of type "markerMouseEvent" are fired on markers regardless of the property isEditable, which on the other hand dictates if mouse events move a marker on the player ruler and consequently, if the eventType "markerMoved" is fired. Due to browser differences in handling mouse events and the need to avoid multiple notifications for different events (e.g., 'click' and 'dragend'), "click", "dragstart" and "dragend" eventNames are fired according to the "mousedown" eventName following the schema: mouse is pressed: fire "markerMouseEvent" with eventName="mousemove". If the mouse button is the left one, then: | |||||||||||||||||||||||||||||||||||||||||