/**
* @module Shared
*/
/**
* I am the RouteNavigation.
*
* I parse the query and the hash fragment of the current URL, and expose those parameters to the app.
* Also, I listen to changes in the hash fragment, and can call callbacks for them.
*
* @class RouteNavigation
* @static
*/
FrameTrail.defineModule('RouteNavigation', function(){
var projectID = getQueryVariable('project'),
hypervideoID = getQueryVariable('hypervideo'),
annotationID = '',
hashTime = '',
oldAnnotationID = '',
onAnnotationChange,
oldHashTime = '',
onHashTimeChange;
/**
* I return a complete path (or URL) for a resource file based on the src attribute of a resource object.
* @method getResourceURL
* @param {String} src
* @return String
*/
function getResourceURL(src) {
if (/^https?:/.exec(src)) {
return src;
} else {
return '../_data/projects/' + projectID + '/resources/' + src;
}
};
/**
* I return the value of a query parameter.
* @method getQueryVariable
* @param {String} variable
* @return String
* @private
*/
function getQueryVariable(variable) {
var query = window.location.search.substring(1),
vars = query.split("&"),
pair;
for (var i = 0; i < vars.length; i++) {
pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
}
/**
* I return the value of a hash parameter.
* @method getHashVariable
* @param {String} variable
* @return String
* @private
*/
function getHashVariable(variable) {
var hash = window.location.hash.substring(1),
vars = hash.split("&"),
pair;
for (var i = 0; i < vars.length; i++) {
pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
}
/**
* I return an object with various info about the execution environment.
* @method checkEnvironment
* @return Object
* @private
*/
function checkEnvironment() {
var environmentObj = {
'server': (document.location.protocol == 'file:') ? false : true,
'hostname': document.location.hostname
}
return environmentObj;
}
/**
* I set the hypervideo id
* (in case it changes while the application is running).
* @method setHashVariable
* @param {String} id
* @private
*/
function setHypervideoID(id) {
hypervideoID = id;
}
/**
* I change the value of a hash parameter.
* @method setHashVariable
* @param {String} key
* @param {String} value
* @private
*/
function setHashVariable(key, value) {
var hash = window.location.hash.substring(1),
vars = hash.split("&"),
pair;
for (var i = 0; i < vars.length; i++) {
pair = vars[i].split("=");
if (pair[0] == key) {
pair[1] = value.toString();
}
vars[i] = pair.join('=')
}
window.location.hash = vars.join('&')
}
/**
* I update the application state, when the hash fragment has changed.
*
* Currently, I am only listing to changes of the parameter "annotations" and "t" (hashTime).
*
* @method routeHasChanged
* @private
*/
function routeHasChanged(){
annotationID = getHashVariable('annotations');
if (annotationID !== oldAnnotationID) {
oldAnnotationID = annotationID;
onAnnotationChange && onAnnotationChange.call();
}
hashTime = getHashVariable('t');
if (hashTime !== oldHashTime) {
oldHashTime = hashTime;
onHashTimeChange && onHashTimeChange.call();
}
}
$(window).on('hashchange', routeHasChanged);
$(window).on('popstate', function(event) {
/*
* when accessed from the overview panel,
* event.originalEvent.state.editMode
* contains the previous editMode state
*/
var hypervideoID = getQueryVariable('hypervideo');
if ( hypervideoID ) {
if ( FrameTrail.getState('editMode') ) {
FrameTrail.changeState('editMode', false);
FrameTrail.module('HypervideoModel').updateHypervideo(hypervideoID, true);
} else {
FrameTrail.module('HypervideoModel').updateHypervideo(hypervideoID);
}
}
});
routeHasChanged();
return {
/**
* The projectID, as parsed from the query part of the URL.
* @attribute projectID
* @type String
* @readOnly
*/
get projectID() { return projectID },
/**
* The hypervideoID, as parsed from the query part of the URL.
* @attribute hypervideoID
* @type String
* @readOnly
*/
get hypervideoID() { return hypervideoID },
/**
* Manually set the hypervideo id.
*
* @attribute id
* @type String
*/
set hypervideoID(id) { return setHypervideoID(id) },
/**
* NOT USED YET
*
* @attribute annotationID
* @type String
*/
get annotationID() { return annotationID },
set annotationID(id) { return setHashVariable('annotations', id) },
/**
* NOT USED YET
*
* Will be called, when the hash fragment's annotationID changes.
*
* @attribute onAnnotationChange
* @type Function
*/
set onAnnotationChange(handler) { return onAnnotationChange = handler },
/**
* I get or set the hashTime (#t=) fragment
* @attribute hashTime
* @type String
*/
get hashTime() { return hashTime },
set hashTime(seconds) { return setHashVariable('t', seconds) },
/**
* I get the object containing various info about the execution environment
* @type Object
*/
get environment() { return checkEnvironment() },
/**
* Will be called, when the hashTime (#t=) fragment changes.
*
* @attribute onHashTimeChange
* @type Function
*/
set onHashTimeChange(handler) { return onHashTimeChange = handler },
getResourceURL: getResourceURL
};
});