[Code Style] Use prototypes in general UI bundle

WTD-1482.
This commit is contained in:
Victor Woeltjen
2015-08-11 09:47:54 -07:00
parent be5cad212a
commit 140d767026
7 changed files with 299 additions and 317 deletions

View File

@ -43,21 +43,19 @@ define(
};
}
indicators = indicators.map(present);
return {
/**
* Get all indicators to display.
* @returns {Indicator[]} all indicators
* to display in the bottom bar.
* @memberof platform/commonUI/general.BottomBarController#
*/
getIndicators: function () {
return indicators;
}
};
this.indicators = indicators.map(present);
}
/**
* Get all indicators to display.
* @returns {Indicator[]} all indicators
* to display in the bottom bar.
* @memberof platform/commonUI/general.BottomBarController#
*/
BottomBarController.prototype.getIndicators = function () {
return this.indicators;
};
return BottomBarController;
}
);

View File

@ -37,69 +37,63 @@ define(
* @param $document the document element, injected by Angular
*/
function ClickAwayController($scope, $document) {
var state = false,
clickaway;
var self = this;
// Track state, but also attach and detach a listener for
// mouseup events on the document.
function deactivate() {
state = false;
$document.off("mouseup", clickaway);
}
function activate() {
state = true;
$document.on("mouseup", clickaway);
}
function changeState() {
if (state) {
deactivate();
} else {
activate();
}
}
this.state = false;
this.$scope = $scope;
this.$document = $document;
// Callback used by the document listener. Deactivates;
// note also $scope.$apply is invoked to indicate that
// the state of this controller has changed.
clickaway = function () {
deactivate();
this.clickaway = function () {
self.deactivate();
$scope.$apply();
return false;
};
return {
/**
* Get the current state of the toggle.
* @return {boolean} true if active
* @memberof platform/commonUI/general.ClickAwayController#
*/
isActive: function () {
return state;
},
/**
* Set a new state for the toggle.
* @return {boolean} true to activate
* @memberof platform/commonUI/general.ClickAwayController#
*/
setState: function (newState) {
if (state !== newState) {
changeState();
}
},
/**
* Toggle the current state; activate if it is inactive,
* deactivate if it is active.
* @memberof platform/commonUI/general.ClickAwayController#
*/
toggle: function () {
changeState();
}
};
}
// Track state, but also attach and detach a listener for
// mouseup events on the document.
ClickAwayController.prototype.deactivate = function () {
this.state = false;
this.$document.off("mouseup", this.clickaway);
};
ClickAwayController.prototype.activate = function () {
this.state = true;
this.$document.on("mouseup", this.clickaway);
};
/**
* Get the current state of the toggle.
* @return {boolean} true if active
*/
ClickAwayController.prototype.isActive =function () {
return this.state;
};
/**
* Set a new state for the toggle.
* @return {boolean} true to activate
*/
ClickAwayController.prototype.setState = function (newState) {
if (this.state !== newState) {
this.toggle();
}
};
/**
* Toggle the current state; activate if it is inactive,
* deactivate if it is active.
*/
ClickAwayController.prototype.toggle = function () {
if (this.state) {
this.deactivate();
} else {
this.activate();
}
};
return ClickAwayController;
}
);

View File

@ -39,28 +39,17 @@ define(
function SelectorController(objectService, $scope) {
var treeModel = {},
listModel = {},
selectedObjects = [],
rootObject,
previousSelected;
previousSelected,
self = this;
// For watch; look at the user's selection in the tree
function getTreeSelection() {
return treeModel.selectedObject;
}
// Get the value of the field being edited
function getField() {
return $scope.ngModel[$scope.field] || [];
}
// Get the value of the field being edited
function setField(value) {
$scope.ngModel[$scope.field] = value;
}
// Store root object for subsequent exposure to template
function storeRoot(objects) {
rootObject = objects[ROOT_ID];
self.rootObject = objects[ROOT_ID];
}
// Check that a selection is of the valid type
@ -83,7 +72,8 @@ define(
function updateSelectedObjects(objects) {
// Look up from the
function getObject(id) { return objects[id]; }
selectedObjects = ids.filter(getObject).map(getObject);
self.selectedObjects =
ids.filter(getObject).map(getObject);
}
// Look up objects by id, then populate right-hand list
@ -94,68 +84,85 @@ define(
$scope.$watch(getTreeSelection, validateTreeSelection);
// Make sure right-hand list matches underlying model
$scope.$watchCollection(getField, updateList);
$scope.$watchCollection(function () {
return self.getField();
}, updateList);
// Look up root object, then store it
objectService.getObjects([ROOT_ID]).then(storeRoot);
return {
/**
* Get the root object to show in the left-hand tree.
* @returns {DomainObject} the root object
* @memberof platform/commonUI/general.SelectorController#
*/
root: function () {
return rootObject;
},
/**
* Add a domain object to the list of selected objects.
* @param {DomainObject} the domain object to select
* @memberof platform/commonUI/general.SelectorController#
*/
select: function (domainObject) {
var id = domainObject && domainObject.getId(),
list = getField() || [];
// Only select if we have a valid id,
// and it isn't already selected
if (id && list.indexOf(id) === -1) {
setField(list.concat([id]));
}
},
/**
* Remove a domain object from the list of selected objects.
* @param {DomainObject} the domain object to select
* @memberof platform/commonUI/general.SelectorController#
*/
deselect: function (domainObject) {
var id = domainObject && domainObject.getId(),
list = getField() || [];
// Only change if this was a valid id,
// for an object which was already selected
if (id && list.indexOf(id) !== -1) {
// Filter it out of the current field
setField(list.filter(function (otherId) {
return otherId !== id;
}));
// Clear the current list selection
delete listModel.selectedObject;
}
},
/**
* Get the currently-selected domain objects.
* @returns {DomainObject[]} the current selection
* @memberof platform/commonUI/general.SelectorController#
*/
selected: function () {
return selectedObjects;
},
// Expose tree/list model for use in template directly
treeModel: treeModel,
listModel: listModel
};
this.$scope = $scope;
this.selectedObjects = [];
// Expose tree/list model for use in template directly
this.treeModel = treeModel;
this.listModel = listModel;
}
// Set the value of the field being edited
SelectorController.prototype.setField = function (value) {
this.$scope.ngModel[this.$scope.field] = value;
};
// Get the value of the field being edited
SelectorController.prototype.getField = function () {
return this.$scope.ngModel[this.$scope.field] || [];
};
/**
* Get the root object to show in the left-hand tree.
* @returns {DomainObject} the root object
*/
SelectorController.prototype.root = function () {
return this.rootObject;
};
/**
* Add a domain object to the list of selected objects.
* @param {DomainObject} the domain object to select
*/
SelectorController.prototype.select = function (domainObject) {
var id = domainObject && domainObject.getId(),
list = this.getField() || [];
// Only select if we have a valid id,
// and it isn't already selected
if (id && list.indexOf(id) === -1) {
this.setField(list.concat([id]));
}
};
/**
* Remove a domain object from the list of selected objects.
* @param {DomainObject} the domain object to select
*/
SelectorController.prototype.deselect = function (domainObject) {
var id = domainObject && domainObject.getId(),
list = this.getField() || [];
// Only change if this was a valid id,
// for an object which was already selected
if (id && list.indexOf(id) !== -1) {
// Filter it out of the current field
this.setField(list.filter(function (otherId) {
return otherId !== id;
}));
// Clear the current list selection
delete this.listModel.selectedObject;
}
};
/**
* Get the currently-selected domain objects.
* @returns {DomainObject[]} the current selection
*/
SelectorController.prototype.selected = function () {
return this.selectedObjects;
};
return SelectorController;
}
);

View File

@ -36,59 +36,54 @@ define(
* @constructor
*/
function SplitPaneController() {
var current = 200,
start = 200,
assigned = false;
return {
/**
* Get the current position of the splitter, in pixels
* from the left edge.
* @returns {number} position of the splitter, in pixels
* @memberof platform/commonUI/general.SplitPaneController#
*/
state: function (defaultState) {
// Set the state to the desired default, if we don't have a
// "real" current state yet.
if (arguments.length > 0 && !assigned) {
current = defaultState;
assigned = true;
}
return current;
},
/**
* Begin moving the splitter; this will note the splitter's
* current position, which is necessary for correct
* interpretation of deltas provided by mct-drag.
* @memberof platform/commonUI/general.SplitPaneController#
*/
startMove: function () {
start = current;
},
/**
* Move the splitter a number of pixels to the right
* (negative numbers move the splitter to the left.)
* This movement is relative to the position of the
* splitter when startMove was last invoked.
* @param {number} delta number of pixels to move
* @memberof platform/commonUI/general.SplitPaneController#
*/
move: function (delta, minimum, maximum) {
// Ensure defaults for minimum/maximum
maximum = isNaN(maximum) ? DEFAULT_MAXIMUM : maximum;
minimum = isNaN(minimum) ? DEFAULT_MINIMUM : minimum;
// Update current splitter state
current = Math.min(
maximum,
Math.max(minimum, start + delta)
);
//console.log(current + "; minimum: " + minimum + "; max: " + maximum);
}
};
this.current = 200;
this.start = 200;
this.assigned = false;
}
/**
* Get the current position of the splitter, in pixels
* from the left edge.
* @returns {number} position of the splitter, in pixels
*/
SplitPaneController.prototype.state = function (defaultState) {
// Set the state to the desired default, if we don't have a
// "real" current state yet.
if (arguments.length > 0 && !this.assigned) {
this.current = defaultState;
this.assigned = true;
}
return this.current;
};
/**
* Begin moving the splitter; this will note the splitter's
* current position, which is necessary for correct
* interpretation of deltas provided by mct-drag.
*/
SplitPaneController.prototype.startMove = function () {
this.start = this.current;
};
/**
* Move the splitter a number of pixels to the right
* (negative numbers move the splitter to the left.)
* This movement is relative to the position of the
* splitter when startMove was last invoked.
* @param {number} delta number of pixels to move
*/
SplitPaneController.prototype.move = function (delta, minimum, maximum) {
// Ensure defaults for minimum/maximum
maximum = isNaN(maximum) ? DEFAULT_MAXIMUM : maximum;
minimum = isNaN(minimum) ? DEFAULT_MINIMUM : minimum;
// Update current splitter state
this.current = Math.min(
maximum,
Math.max(minimum, this.start + delta)
);
};
return SplitPaneController;
}
);

View File

@ -34,37 +34,33 @@ define(
* @constructor
*/
function ToggleController() {
var state = false;
return {
/**
* Get the current state of the toggle.
* @return {boolean} true if active
* @memberof platform/commonUI/general.ToggleController#
*/
isActive: function () {
return state;
},
/**
* Set a new state for the toggle.
* @return {boolean} true to activate
* @memberof platform/commonUI/general.ToggleController#
*/
setState: function (newState) {
state = newState;
},
/**
* Toggle the current state; activate if it is inactive,
* deactivate if it is active.
* @memberof platform/commonUI/general.ToggleController#
*/
toggle: function () {
state = !state;
}
};
this.state = false;
}
/**
* Get the current state of the toggle.
* @return {boolean} true if active
*/
ToggleController.prototype.isActive = function () {
return this.state;
};
/**
* Set a new state for the toggle.
* @return {boolean} true to activate
*/
ToggleController.prototype.setState = function (newState) {
this.state = newState;
};
/**
* Toggle the current state; activate if it is inactive,
* deactivate if it is active.
*/
ToggleController.prototype.toggle = function () {
this.state = !this.state;
};
return ToggleController;
}
);

View File

@ -51,10 +51,9 @@ define(
* @memberof platform/commonUI/general
* @constructor
*/
function TreeNodeController($scope, $timeout, $rootScope) {
var selectedObject = ($scope.ngModel || {}).selectedObject,
isSelected = false,
hasBeenExpanded = false;
function TreeNodeController($scope, $timeout) {
var self = this,
selectedObject = ($scope.ngModel || {}).selectedObject;
// Look up the id for a domain object. A convenience
// for mapping; additionally does some undefined-checking.
@ -77,17 +76,6 @@ define(
checkPath(nodePath, navPath, index + 1));
}
// Track that a node has been expanded, either by the
// user or automatically to show a selection.
function trackExpansion() {
if (!hasBeenExpanded) {
// Run on a timeout; if a lot of expansion needs to
// occur (e.g. if the selection is several nodes deep) we
// want this to be spread across multiple digest cycles.
$timeout(function () { hasBeenExpanded = true; }, 0);
}
}
// Consider the currently-navigated object and update
// parameters which support display.
function checkSelection() {
@ -102,7 +90,7 @@ define(
// Deselect; we will reselect below, iff we are
// exactly at the end of the path.
isSelected = false;
self.isSelectedFlag = false;
// Expand if necessary (if the navigated object will
// be in this node's subtree)
@ -121,12 +109,12 @@ define(
// at the end of the path, highlight;
// otherwise, expand.
if (nodePath.length === navPath.length) {
isSelected = true;
self.isSelectedFlag = true;
} else { // node path is shorter: Expand!
if ($scope.toggle) {
$scope.toggle.setState(true);
}
trackExpansion();
self.trackExpansion();
}
}
@ -139,41 +127,55 @@ define(
selectedObject = object;
checkSelection();
}
this.isSelectedFlag = false;
this.hasBeenExpandedFlag = false;
this.$timeout = $timeout;
// Listen for changes which will effect display parameters
$scope.$watch("ngModel.selectedObject", setSelection);
$scope.$watch("domainObject", checkSelection);
return {
/**
* This method should be called when a node is expanded
* to record that this has occurred, to support one-time
* lazy loading of the node's subtree.
* @memberof platform/commonUI/general.TreeNodeController#
*/
trackExpansion: trackExpansion,
/**
* Check if this not has ever been expanded.
* @returns true if it has been expanded
* @memberof platform/commonUI/general.TreeNodeController#
*/
hasBeenExpanded: function () {
return hasBeenExpanded;
},
/**
* Check whether or not the domain object represented by
* this tree node should be highlighted.
* An object will be highlighted if it matches
* ngModel.selectedObject
* @returns true if this should be highlighted
* @memberof platform/commonUI/general.TreeNodeController#
*/
isSelected: function () {
return isSelected;
}
};
}
/**
* This method should be called when a node is expanded
* to record that this has occurred, to support one-time
* lazy loading of the node's subtree.
*/
TreeNodeController.prototype.trackExpansion = function () {
var self = this;
if (!self.hasBeenExpanded()) {
// Run on a timeout; if a lot of expansion needs to
// occur (e.g. if the selection is several nodes deep) we
// want this to be spread across multiple digest cycles.
self.$timeout(function () {
self.hasBeenExpandedFlag = true;
}, 0);
}
};
/**
* Check if this not has ever been expanded.
* @returns true if it has been expanded
*/
TreeNodeController.prototype.hasBeenExpanded = function () {
return this.hasBeenExpandedFlag;
};
/**
* Check whether or not the domain object represented by
* this tree node should be highlighted.
* An object will be highlighted if it matches
* ngModel.selectedObject
* @returns true if this should be highlighted
*/
TreeNodeController.prototype.isSelected = function () {
return this.isSelectedFlag;
};
return TreeNodeController;
}
);