mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
216 lines
7.5 KiB
JavaScript
216 lines
7.5 KiB
JavaScript
define([
|
|
'utils/add-logging'
|
|
], function( addLogging ){
|
|
//ASSUMES: backbone
|
|
//==============================================================================
|
|
/** @class Mixin to add logging capabilities to an object.
|
|
* Designed to allow switching an objects log output off/on at one central
|
|
* statement. Can be used with plain browser console (or something more
|
|
* complex like an AJAX logger).
|
|
* <br />NOTE: currently only uses the console.debug log function
|
|
* (as opposed to debug, error, warn, etc.)
|
|
* @name LoggableMixin
|
|
*
|
|
* @example
|
|
* // Add to your models/views at the definition using chaining:
|
|
* var MyModel = Backbone.Model.extend( LoggableMixin ).extend({ // ... });
|
|
*
|
|
* // or - more explicitly AFTER the definition:
|
|
* var MyModel = Backbone.Model.extend({
|
|
* logger : console
|
|
* // ...
|
|
* this.log( '$#%& it! - broken already...' );
|
|
* })
|
|
* _.extend( MyModel.prototype, LoggableMixin )
|
|
*
|
|
*/
|
|
var LoggableMixin = /** @lends LoggableMixin# */{
|
|
|
|
/** The logging object whose log function will be used to output
|
|
* messages. Null will supress all logging. Commonly set to console.
|
|
*/
|
|
// replace null with console (if available) to see all logs
|
|
logger : null,
|
|
_logNamespace : '?',
|
|
|
|
/** Output log messages/arguments to logger.
|
|
* @param {Arguments} ... (this function is variadic)
|
|
* @returns undefined if not this.logger
|
|
*/
|
|
log : function(){
|
|
if( this.logger ){
|
|
var log = this.logger.log;
|
|
if( typeof this.logger.log === 'object' ){
|
|
log = Function.prototype.bind.call( this.logger.log, this.logger );
|
|
}
|
|
return log.apply( this.logger, arguments );
|
|
}
|
|
return undefined;
|
|
}
|
|
};
|
|
addLogging( LoggableMixin );
|
|
|
|
|
|
//==============================================================================
|
|
/** Backbone model that syncs to the browser's sessionStorage API.
|
|
*/
|
|
var SessionStorageModel = Backbone.Model.extend({
|
|
initialize : function( initialAttrs ){
|
|
// check for sessionStorage and error if no id is provided
|
|
this._checkEnabledSessionStorage();
|
|
if( !initialAttrs.id ){
|
|
throw new Error( 'SessionStorageModel requires an id in the initial attributes' );
|
|
}
|
|
this.id = initialAttrs.id;
|
|
|
|
// load existing from storage (if any), clear any attrs set by bbone before init is called,
|
|
// layer initial over existing and defaults, and save
|
|
var existing = ( !this.isNew() )?( this._read( this ) ):( {} );
|
|
this.clear({ silent: true });
|
|
this.save( _.extend( {}, this.defaults, existing, initialAttrs ), { silent: true });
|
|
|
|
// save on any change to it immediately
|
|
this.on( 'change', function(){
|
|
this.save();
|
|
});
|
|
},
|
|
|
|
_checkEnabledSessionStorage : function(){
|
|
try {
|
|
return sessionStorage.length;
|
|
} catch( err ){
|
|
alert( 'Please enable cookies in your browser for this Galaxy site' );
|
|
return false;
|
|
}
|
|
},
|
|
|
|
/** override of bbone sync to save to sessionStorage rather than REST
|
|
* bbone options (success, errror, etc.) should still apply
|
|
*/
|
|
sync : function( method, model, options ){
|
|
if( !options.silent ){
|
|
model.trigger( 'request', model, {}, options );
|
|
}
|
|
var returned;
|
|
switch( method ){
|
|
case 'create' : returned = this._create( model ); break;
|
|
case 'read' : returned = this._read( model ); break;
|
|
case 'update' : returned = this._update( model ); break;
|
|
case 'delete' : returned = this._delete( model ); break;
|
|
}
|
|
if( returned !== undefined || returned !== null ){
|
|
if( options.success ){ options.success(); }
|
|
} else {
|
|
if( options.error ){ options.error(); }
|
|
}
|
|
return returned;
|
|
},
|
|
|
|
/** set storage to the stringified item */
|
|
_create : function( model ){
|
|
var json = model.toJSON(),
|
|
set = sessionStorage.setItem( model.id, JSON.stringify( json ) );
|
|
return ( set === null )?( set ):( json );
|
|
},
|
|
|
|
/** read and parse json from storage */
|
|
_read : function( model ){
|
|
return JSON.parse( sessionStorage.getItem( model.id ) );
|
|
},
|
|
|
|
/** set storage to the item (alias to create) */
|
|
_update : function( model ){
|
|
return model._create( model );
|
|
},
|
|
|
|
/** remove the item from storage */
|
|
_delete : function( model ){
|
|
return sessionStorage.removeItem( model.id );
|
|
},
|
|
|
|
/** T/F whether sessionStorage contains the model's id (data is present) */
|
|
isNew : function(){
|
|
return !sessionStorage.hasOwnProperty( this.id );
|
|
},
|
|
|
|
_log : function(){
|
|
return JSON.stringify( this.toJSON(), null, ' ' );
|
|
},
|
|
toString : function(){
|
|
return 'SessionStorageModel(' + this.id + ')';
|
|
}
|
|
|
|
});
|
|
(function(){
|
|
SessionStorageModel.prototype = _.omit( SessionStorageModel.prototype, 'url', 'urlRoot' );
|
|
}());
|
|
|
|
|
|
//==============================================================================
|
|
var HiddenUntilActivatedViewMixin = /** @lends hiddenUntilActivatedMixin# */{
|
|
//TODO: since this is a mixin, consider moving toggle, hidden into HUAVOptions
|
|
|
|
/** */
|
|
hiddenUntilActivated : function( $activator, options ){
|
|
// call this in your view's initialize fn
|
|
options = options || {};
|
|
this.HUAVOptions = {
|
|
$elementShown : this.$el,
|
|
showFn : jQuery.prototype.toggle,
|
|
showSpeed : 'fast'
|
|
};
|
|
_.extend( this.HUAVOptions, options || {});
|
|
/** has this been shown already (and onshowFirstTime called)? */
|
|
this.HUAVOptions.hasBeenShown = this.HUAVOptions.$elementShown.is( ':visible' );
|
|
this.hidden = this.isHidden();
|
|
|
|
if( $activator ){
|
|
var mixin = this;
|
|
$activator.on( 'click', function( ev ){
|
|
mixin.toggle( mixin.HUAVOptions.showSpeed );
|
|
});
|
|
}
|
|
},
|
|
|
|
isHidden : function(){
|
|
return ( this.HUAVOptions.$elementShown.is( ':hidden' ) );
|
|
},
|
|
|
|
/** */
|
|
toggle : function(){
|
|
// can be called manually as well with normal toggle arguments
|
|
//TODO: better as a callback (when the show/hide is actually done)
|
|
// show
|
|
if( this.hidden ){
|
|
// fire the optional fns on the first/each showing - good for render()
|
|
if( !this.HUAVOptions.hasBeenShown ){
|
|
if( _.isFunction( this.HUAVOptions.onshowFirstTime ) ){
|
|
this.HUAVOptions.hasBeenShown = true;
|
|
this.HUAVOptions.onshowFirstTime.call( this );
|
|
}
|
|
}
|
|
if( _.isFunction( this.HUAVOptions.onshow ) ){
|
|
this.HUAVOptions.onshow.call( this );
|
|
this.trigger( 'hiddenUntilActivated:shown', this );
|
|
}
|
|
this.hidden = false;
|
|
|
|
// hide
|
|
} else {
|
|
if( _.isFunction( this.HUAVOptions.onhide ) ){
|
|
this.HUAVOptions.onhide.call( this );
|
|
this.trigger( 'hiddenUntilActivated:hidden', this );
|
|
}
|
|
this.hidden = true;
|
|
}
|
|
return this.HUAVOptions.showFn.apply( this.HUAVOptions.$elementShown, arguments );
|
|
}
|
|
};
|
|
|
|
//==============================================================================
|
|
return {
|
|
LoggableMixin : LoggableMixin,
|
|
SessionStorageModel : SessionStorageModel,
|
|
HiddenUntilActivatedViewMixin : HiddenUntilActivatedViewMixin
|
|
};});
|