Merge pull request #402 from nasa/open209

[Clocks/Timers] Update code style
This commit is contained in:
akhenry 2016-01-06 14:07:15 -08:00
commit 9cc03123b1
9 changed files with 236 additions and 187 deletions

View File

@ -35,10 +35,21 @@ define(
* Both "Start" and "Restart" share this implementation, but * Both "Start" and "Restart" share this implementation, but
* control their visibility with different `appliesTo` behavior. * control their visibility with different `appliesTo` behavior.
* *
* @implements Action * @implements {Action}
* @memberof platform/features/clock
* @constructor
* @param {Function} now a function which returns the current
* time (typically wrapping `Date.now`)
* @param {ActionContext} context the context for this action
*/ */
function AbstractStartTimerAction(now, context) { function AbstractStartTimerAction(now, context) {
var domainObject = context.domainObject; this.domainObject = context.domainObject;
this.now = now;
}
AbstractStartTimerAction.prototype.perform = function () {
var domainObject = this.domainObject,
now = this.now;
function doPersist() { function doPersist() {
var persistence = domainObject.getCapability('persistence'); var persistence = domainObject.getCapability('persistence');
@ -49,13 +60,9 @@ define(
model.timestamp = now(); model.timestamp = now();
} }
return {
perform: function () {
return domainObject.useCapability('mutation', setTimestamp) return domainObject.useCapability('mutation', setTimestamp)
.then(doPersist); .then(doPersist);
}
}; };
}
return AbstractStartTimerAction; return AbstractStartTimerAction;
} }

View File

@ -31,12 +31,22 @@ define(
* *
* Behaves the same as (and delegates functionality to) * Behaves the same as (and delegates functionality to)
* the "Start" action. * the "Start" action.
* @implements Action *
* @extends {platform/features/clock.AbstractTimerAction}
* @implements {Action}
* @memberof platform/features/clock
* @constructor
* @param {Function} now a function which returns the current
* time (typically wrapping `Date.now`)
* @param {ActionContext} context the context for this action
*/ */
function RestartTimerAction(now, context) { function RestartTimerAction(now, context) {
return new AbstractStartTimerAction(now, context); AbstractStartTimerAction.apply(this, [ now, context ]);
} }
RestartTimerAction.prototype =
Object.create(AbstractStartTimerAction.prototype);
RestartTimerAction.appliesTo = function (context) { RestartTimerAction.appliesTo = function (context) {
var model = var model =
(context.domainObject && context.domainObject.getModel()) (context.domainObject && context.domainObject.getModel())

View File

@ -32,12 +32,21 @@ define(
* Sets the reference timestamp in a timer to the current * Sets the reference timestamp in a timer to the current
* time, such that it begins counting up. * time, such that it begins counting up.
* *
* @implements Action * @extends {platform/features/clock.AbstractTimerAction}
* @implements {Action}
* @memberof platform/features/clock
* @constructor
* @param {Function} now a function which returns the current
* time (typically wrapping `Date.now`)
* @param {ActionContext} context the context for this action
*/ */
function StartTimerAction(now, context) { function StartTimerAction(now, context) {
return new AbstractStartTimerAction(now, context); AbstractStartTimerAction.apply(this, [ now, context ]);
} }
StartTimerAction.prototype =
Object.create(AbstractStartTimerAction.prototype);
StartTimerAction.appliesTo = function (context) { StartTimerAction.appliesTo = function (context) {
var model = var model =
(context.domainObject && context.domainObject.getModel()) (context.domainObject && context.domainObject.getModel())

View File

@ -30,19 +30,21 @@ define(
* Controller for views of a Clock domain object. * Controller for views of a Clock domain object.
* *
* @constructor * @constructor
* @memberof platform/features/clock
* @param {angular.Scope} $scope the Angular scope
* @param {platform/features/clock.TickerService} tickerService
* a service used to align behavior with clock ticks
*/ */
function ClockController($scope, tickerService) { function ClockController($scope, tickerService) {
var text, var lastTimestamp,
ampm,
use24,
lastTimestamp,
unlisten, unlisten,
timeFormat; timeFormat,
self = this;
function update() { function update() {
var m = moment.utc(lastTimestamp); var m = moment.utc(lastTimestamp);
text = timeFormat && m.format(timeFormat); self.textValue = timeFormat && m.format(timeFormat);
ampm = m.format("A"); // Just the AM or PM part self.ampmValue = m.format("A"); // Just the AM or PM part
} }
function tick(timestamp) { function tick(timestamp) {
@ -56,8 +58,8 @@ define(
if (clockFormat !== undefined) { if (clockFormat !== undefined) {
baseFormat = clockFormat[0]; baseFormat = clockFormat[0];
use24 = clockFormat[1] === 'clock24'; self.use24 = clockFormat[1] === 'clock24';
timeFormat = use24 ? timeFormat = self.use24 ?
baseFormat.replace('hh', "HH") : baseFormat; baseFormat.replace('hh', "HH") : baseFormat;
update(); update();
@ -69,31 +71,31 @@ define(
// Listen for clock ticks ... and stop listening on destroy // Listen for clock ticks ... and stop listening on destroy
unlisten = tickerService.listen(tick); unlisten = tickerService.listen(tick);
$scope.$on('$destroy', unlisten); $scope.$on('$destroy', unlisten);
}
return {
/** /**
* Get the clock's time zone, as displayable text. * Get the clock's time zone, as displayable text.
* @returns {string} * @returns {string}
*/ */
zone: function () { ClockController.prototype.zone = function () {
return "UTC"; return "UTC";
}, };
/** /**
* Get the current time, as displayable text. * Get the current time, as displayable text.
* @returns {string} * @returns {string}
*/ */
text: function () { ClockController.prototype.text = function () {
return text; return this.textValue;
}, };
/** /**
* Get the text to display to qualify a time as AM or PM. * Get the text to display to qualify a time as AM or PM.
* @returns {string} * @returns {string}
*/ */
ampm: function () { ClockController.prototype.ampm = function () {
return use24 ? '' : ampm; return this.use24 ? '' : this.ampmValue;
}
}; };
}
return ClockController; return ClockController;
} }

View File

@ -31,6 +31,12 @@ define(
* *
* This is a short-term workaround to assure Timer views stay * This is a short-term workaround to assure Timer views stay
* up-to-date; should be replaced by a global auto-refresh. * up-to-date; should be replaced by a global auto-refresh.
*
* @constructor
* @memberof platform/features/clock
* @param {angular.Scope} $scope the Angular scope
* @param {platform/features/clock.TickerService} tickerService
* a service used to align behavior with clock ticks
*/ */
function RefreshingController($scope, tickerService) { function RefreshingController($scope, tickerService) {
var unlisten; var unlisten;

View File

@ -33,26 +33,30 @@ define(
* Controller for views of a Timer domain object. * Controller for views of a Timer domain object.
* *
* @constructor * @constructor
* @memberof platform/features/clock
* @param {angular.Scope} $scope the Angular scope
* @param $window Angular-provided window object
* @param {Function} now a function which returns the current
* time (typically wrapping `Date.now`)
*/ */
function TimerController($scope, $window, now) { function TimerController($scope, $window, now) {
var timerObject, var timerObject,
relevantAction,
sign = '',
text = '',
formatter, formatter,
active = true, active = true,
relativeTimestamp, relativeTimestamp,
lastTimestamp; lastTimestamp,
self = this;
function update() { function update() {
var timeDelta = lastTimestamp - relativeTimestamp; var timeDelta = lastTimestamp - relativeTimestamp;
if (formatter && !isNaN(timeDelta)) { if (formatter && !isNaN(timeDelta)) {
text = formatter(timeDelta); self.textValue = formatter(timeDelta);
sign = timeDelta < 0 ? "-" : timeDelta >= 1000 ? "+" : ""; self.signValue = timeDelta < 0 ? "-" :
timeDelta >= 1000 ? "+" : "";
} else { } else {
text = ""; self.textValue = "";
sign = ""; self.signValue = "";
} }
} }
@ -75,7 +79,7 @@ define(
updateFormat(formatKey); updateFormat(formatKey);
updateTimestamp(timestamp); updateTimestamp(timestamp);
relevantAction = actionCapability && self.relevantAction = actionCapability &&
actionCapability.getActions(actionKey)[0]; actionCapability.getActions(actionKey)[0];
update(); update();
@ -92,13 +96,14 @@ define(
} }
function tick() { function tick() {
var lastSign = sign, lastText = text; var lastSign = self.signValue,
lastText = self.textValue;
lastTimestamp = now(); lastTimestamp = now();
update(); update();
// We're running in an animation frame, not in a digest cycle. // We're running in an animation frame, not in a digest cycle.
// We need to trigger a digest cycle if our displayable data // We need to trigger a digest cycle if our displayable data
// changes. // changes.
if (lastSign !== sign || lastText !== text) { if (lastSign !== self.signValue || lastText !== self.textValue) {
$scope.$apply(); $scope.$apply();
} }
if (active) { if (active) {
@ -117,50 +122,58 @@ define(
active = false; active = false;
}); });
return { this.$scope = $scope;
this.signValue = '';
this.textValue = '';
this.updateObject = updateObject;
}
/** /**
* Get the glyph to display for the start/restart button. * Get the glyph to display for the start/restart button.
* @returns {string} glyph to display * @returns {string} glyph to display
*/ */
buttonGlyph: function () { TimerController.prototype.buttonGlyph = function () {
return relevantAction ? return this.relevantAction ?
relevantAction.getMetadata().glyph : ""; this.relevantAction.getMetadata().glyph : "";
}, };
/** /**
* Get the text to show for the start/restart button * Get the text to show for the start/restart button
* (e.g. in a tooltip) * (e.g. in a tooltip)
* @returns {string} name of the action * @returns {string} name of the action
*/ */
buttonText: function () { TimerController.prototype.buttonText = function () {
return relevantAction ? return this.relevantAction ?
relevantAction.getMetadata().name : ""; this.relevantAction.getMetadata().name : "";
}, };
/** /**
* Perform the action associated with the start/restart button. * Perform the action associated with the start/restart button.
*/ */
clickButton: function () { TimerController.prototype.clickButton = function () {
if (relevantAction) { if (this.relevantAction) {
relevantAction.perform(); this.relevantAction.perform();
updateObject($scope.domainObject); this.updateObject(this.$scope.domainObject);
} }
}, };
/** /**
* Get the sign (+ or -) of the current timer value, as * Get the sign (+ or -) of the current timer value, as
* displayable text. * displayable text.
* @returns {string} sign of the current timer value * @returns {string} sign of the current timer value
*/ */
sign: function () { TimerController.prototype.sign = function () {
return sign; return this.signValue;
}, };
/** /**
* Get the text to display for the current timer value. * Get the text to display for the current timer value.
* @returns {string} current timer value * @returns {string} current timer value
*/ */
text: function () { TimerController.prototype.text = function () {
return text; return this.textValue;
}
}; };
}
return TimerController; return TimerController;
} }

View File

@ -37,8 +37,10 @@ define(
* supports `TimerController`. * supports `TimerController`.
* *
* @constructor * @constructor
* @memberof platform/features/clock
*/ */
function TimerFormatter() { function TimerFormatter() {
}
// Round this timestamp down to the second boundary // Round this timestamp down to the second boundary
// (e.g. 1124ms goes down to 1000ms, -2400ms goes down to -3000ms) // (e.g. 1124ms goes down to 1000ms, -2400ms goes down to -3000ms)
@ -46,35 +48,27 @@ define(
return Math.abs(Math.floor(duration / 1000) * 1000); return Math.abs(Math.floor(duration / 1000) * 1000);
} }
// Short-form format, e.g. 02:22:11
function short(duration) {
return moment.duration(toWholeSeconds(duration), 'ms')
.format(SHORT_FORMAT, { trim: false });
}
// Long-form format, e.g. 3d 02:22:11
function long(duration) {
return moment.duration(toWholeSeconds(duration), 'ms')
.format(LONG_FORMAT, { trim: false });
}
return {
/** /**
* Format a duration for display, using the short form. * Format a duration for display, using the short form.
* (e.g. 03:33:11) * (e.g. 03:33:11)
* @param {number} duration the duration, in milliseconds * @param {number} duration the duration, in milliseconds
* @param {boolean} sign true if positive * @param {boolean} sign true if positive
*/ */
short: short, TimerFormatter.prototype.short = function (duration) {
return moment.duration(toWholeSeconds(duration), 'ms')
.format(SHORT_FORMAT, { trim: false });
};
/** /**
* Format a duration for display, using the long form. * Format a duration for display, using the long form.
* (e.g. 0d 03:33:11) * (e.g. 0d 03:33:11)
* @param {number} duration the duration, in milliseconds * @param {number} duration the duration, in milliseconds
* @param {boolean} sign true if positive * @param {boolean} sign true if positive
*/ */
long: long TimerFormatter.prototype.long = function (duration) {
return moment.duration(toWholeSeconds(duration), 'ms')
.format(LONG_FORMAT, { trim: false });
}; };
}
return TimerFormatter; return TimerFormatter;
} }

View File

@ -28,31 +28,39 @@ define(
/** /**
* Indicator that displays the current UTC time in the status area. * Indicator that displays the current UTC time in the status area.
* @implements Indicator * @implements {Indicator}
* @memberof platform/features/clock
* @param {platform/features/clock.TickerService} tickerService
* a service used to align behavior with clock ticks
* @param {string} indicatorFormat format string for timestamps
* shown in this indicator
*/ */
function ClockIndicator(tickerService, CLOCK_INDICATOR_FORMAT) { function ClockIndicator(tickerService, indicatorFormat) {
var text = ""; var self = this;
this.text = "";
tickerService.listen(function (timestamp) { tickerService.listen(function (timestamp) {
text = moment.utc(timestamp).format(CLOCK_INDICATOR_FORMAT) + " UTC"; self.text = moment.utc(timestamp)
.format(indicatorFormat) + " UTC";
}); });
return {
getGlyph: function () {
return "C";
},
getGlyphClass: function () {
return "no-icon no-collapse float-right subtle";
},
getText: function () {
return text;
},
getDescription: function () {
return "";
} }
ClockIndicator.prototype.getGlyph = function () {
return "C";
}; };
} ClockIndicator.prototype.getGlyphClass = function () {
return "no-icon no-collapse float-right subtle";
};
ClockIndicator.prototype.getText = function () {
return this.text;
};
ClockIndicator.prototype.getDescription = function () {
return "";
};
return ClockIndicator; return ClockIndicator;
} }

View File

@ -30,23 +30,23 @@ define(
* Calls functions every second, as close to the actual second * Calls functions every second, as close to the actual second
* tick as is feasible. * tick as is feasible.
* @constructor * @constructor
* @memberof platform/features/clock
* @param $timeout Angular's $timeout * @param $timeout Angular's $timeout
* @param {Function} now function to provide the current time in ms * @param {Function} now function to provide the current time in ms
*/ */
function TickerService($timeout, now) { function TickerService($timeout, now) {
var callbacks = [], var self = this;
last = now() - 1000;
function tick() { function tick() {
var timestamp = now(), var timestamp = now(),
millis = timestamp % 1000; millis = timestamp % 1000;
// Only update callbacks if a second has actually passed. // Only update callbacks if a second has actually passed.
if (timestamp >= last + 1000) { if (timestamp >= self.last + 1000) {
callbacks.forEach(function (callback) { self.callbacks.forEach(function (callback) {
callback(timestamp); callback(timestamp);
}); });
last = timestamp - millis; self.last = timestamp - millis;
} }
// Try to update at exactly the next second // Try to update at exactly the next second
@ -55,35 +55,35 @@ define(
tick(); tick();
return { this.callbacks = [];
this.last = now() - 1000;
}
/** /**
* Listen for clock ticks. The provided callback will * Listen for clock ticks. The provided callback will
* be invoked with the current timestamp (in milliseconds * be invoked with the current timestamp (in milliseconds
* since Jan 1 1970) at regular intervals, as near to the * since Jan 1 1970) at regular intervals, as near to the
* second boundary as possible. * second boundary as possible.
* *
* @method listen
* @name TickerService#listen
* @param {Function} callback callback to invoke * @param {Function} callback callback to invoke
* @returns {Function} a function to unregister this listener * @returns {Function} a function to unregister this listener
*/ */
listen: function (callback) { TickerService.prototype.listen = function (callback) {
callbacks.push(callback); var self = this;
self.callbacks.push(callback);
// Provide immediate feedback // Provide immediate feedback
callback(last); callback(this.last);
// Provide a deregistration function // Provide a deregistration function
return function () { return function () {
callbacks = callbacks.filter(function (cb) { self.callbacks = self.callbacks.filter(function (cb) {
return cb !== callback; return cb !== callback;
}); });
}; };
}
}; };
}
return TickerService; return TickerService;
} }
); );