/** @class @readonly @desc Instantiates a controller for a new loading spinner overlay within desired context element. @arg {String|Element|jQuery} [context='body'] - Container reference or query selector to create spinner within. @arg {Boolean} [opaque=false] - Whether to completely obscure content behind spinner. @arg {Function} [callback] - Function to call after spinner completely fades in. */ var SpinnerClass = function(context, opaque, callback) { /* properties */ /** @member {Boolean} SpinnerClass#opaque @readonly @desc Whether {@link SpinnerClass#$element} completely obscures content behind it. @see {@link SpinnerClass} */ this.opaque = opaque || false; /** @member {jQuery} SpinnerClass#$context @readonly @desc Element containing spinner layer. @see {@link SpinnerClass} */ this.$context = (typeof context === 'string' ? $(context) : context) || $('body'); /** @member {jQuery} SpinnerClass#$element @readonly @desc Layer containing spinner graphic. @see {@link SpinnerClass} */ this.$element = null; var instance = this, callback = callback || function () {}; /* methods */ /** @method SpinnerClass#show @readonly @desc Reveals spinner layer. @arg {Function} callback - Function to call after layer is revealed. */ this.show = function (callback) { this.$element = $(templates.spinner({'opaque': this.opaque})); callback = callback || function () {}; $('body').append(this.$element); this.$element.fadeIn( { 'duration': 250, 'easing' : 'easeInOutCubic', 'done' : callback }); }; /** @method SpinnerClass#hide @readonly @desc Conceals spinner layer. @arg {Function} callback - Function to call after layer is concealed. */ this.hide = function (callback) { this.$element.fadeOut( { 'duration': 250, 'easing' : 'easeInOutCubic', 'done' : function () { instance.$element.remove(); callback && callback(); } }); }; /** @method SpinnerClass#remove @readonly @desc Destroys spinner layer. @todo {@link SpinnerClass#hide} already removes, so this is redundant. */ this.remove = function () { this.hide(function () { instance.$element.remove(); }); }; /* construct */ this.show(callback); log(L_INFO, 'SpinnerClass', 'new instance'); }; /** @class @readonly @desc Instantiates a timer object, useful for benchmarking. @arg {String|Element|jQuery} [context='body'] - Container reference or query selector to create spinner within. @arg {Boolean} [opaque=false] - Whether to completely hide content behind spinner. @arg {Function} [callback] - Function to call after spinner completely fades in. */ var TimerClass = function () { /* properties */ var timestamp = function () { return (new Date()).getTime(); }, value = 0; /* methods */ /** @method TimerClass#started @readonly @desc Discloses when timer was instantiated/reset. @returns {Number} Integer timestamp (ms). */ this.started = function () { return value; }; /** @method TimerClass#elapsed @readonly @desc Discloses duration since timer was instantiated/reset. @returns {Number} Integer duration (ms). */ this.elapsed = function (showUnits) { return (timestamp() - value) + (showUnits ? 'ms' : ''); }; /** @method TimerClass#reset @readonly @desc Adjusts instantiation time to now. @returns {Number} Integer timestamp (ms). */ this.reset = function () { value = timestamp(); return this.started(); }; /* construct */ this.reset(); };