From 140d7670260d7d931a278566741620393e014c11 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 11 Aug 2015 09:47:54 -0700 Subject: [PATCH] [Code Style] Use prototypes in general UI bundle WTD-1482. --- .../src/controllers/BottomBarController.js | 24 ++- .../src/controllers/ClickAwayController.js | 100 ++++++------ .../src/controllers/SelectorController.js | 147 +++++++++--------- .../src/controllers/SplitPaneController.js | 97 ++++++------ .../src/controllers/ToggleController.js | 54 +++---- .../src/controllers/TreeNodeController.js | 96 ++++++------ .../general/src/services/UrlService.js | 98 ++++++------ 7 files changed, 299 insertions(+), 317 deletions(-) diff --git a/platform/commonUI/general/src/controllers/BottomBarController.js b/platform/commonUI/general/src/controllers/BottomBarController.js index 18e3e04dfc..d53d76fce6 100644 --- a/platform/commonUI/general/src/controllers/BottomBarController.js +++ b/platform/commonUI/general/src/controllers/BottomBarController.js @@ -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; } ); diff --git a/platform/commonUI/general/src/controllers/ClickAwayController.js b/platform/commonUI/general/src/controllers/ClickAwayController.js index 390e24f50a..9c7c6f8091 100644 --- a/platform/commonUI/general/src/controllers/ClickAwayController.js +++ b/platform/commonUI/general/src/controllers/ClickAwayController.js @@ -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; } ); diff --git a/platform/commonUI/general/src/controllers/SelectorController.js b/platform/commonUI/general/src/controllers/SelectorController.js index 87f9b22b84..26fe5f4d62 100644 --- a/platform/commonUI/general/src/controllers/SelectorController.js +++ b/platform/commonUI/general/src/controllers/SelectorController.js @@ -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; } ); diff --git a/platform/commonUI/general/src/controllers/SplitPaneController.js b/platform/commonUI/general/src/controllers/SplitPaneController.js index 9eb9daa4c6..75dfed28d9 100644 --- a/platform/commonUI/general/src/controllers/SplitPaneController.js +++ b/platform/commonUI/general/src/controllers/SplitPaneController.js @@ -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; } ); diff --git a/platform/commonUI/general/src/controllers/ToggleController.js b/platform/commonUI/general/src/controllers/ToggleController.js index d6e73414a1..9d7d493f15 100644 --- a/platform/commonUI/general/src/controllers/ToggleController.js +++ b/platform/commonUI/general/src/controllers/ToggleController.js @@ -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; } ); diff --git a/platform/commonUI/general/src/controllers/TreeNodeController.js b/platform/commonUI/general/src/controllers/TreeNodeController.js index 3310bf2ae0..3c3829700b 100644 --- a/platform/commonUI/general/src/controllers/TreeNodeController.js +++ b/platform/commonUI/general/src/controllers/TreeNodeController.js @@ -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; } ); diff --git a/platform/commonUI/general/src/services/UrlService.js b/platform/commonUI/general/src/services/UrlService.js index 79931add04..5d57b03ca0 100644 --- a/platform/commonUI/general/src/services/UrlService.js +++ b/platform/commonUI/general/src/services/UrlService.js @@ -36,62 +36,52 @@ define( * @memberof platform/commonUI/general */ function UrlService($location) { - // Returns the url for the mode wanted - // and the domainObject passed in. A path - // is returned. The view is defaulted to - // the current location's (current object's) - // view set. - function urlForLocation(mode, domainObject) { - var context = domainObject && - domainObject.getCapability('context'), - objectPath = context ? context.getPath() : [], - ids = objectPath.map(function (domainObject) { - return domainObject.getId(); - }), - // Parses the path together. Starts with the - // default index.html file, then the mode passed - // into the service, followed by ids in the url - // joined by '/', and lastly the view path from - // the current location - path = mode + "/" + ids.slice(1).join("/"); - return path; - } - - // Uses the Url for the current location - // from the urlForLocation function and - // includes the view and the index path - function urlForNewTab(mode, domainObject) { - var viewPath = "?view=" + $location.search().view, - newTabPath = - "index.html#" + urlForLocation(mode, domainObject) + viewPath; - return newTabPath; - } - - return { - /** - * Returns the Url path for a specific domain object - * without the index.html path and the view path - * @param {value} value of the browse or edit mode - * for the path - * @param {DomainObject} value of the domain object - * to get the path of - * @memberof platform/commonUI/general.UrlService# - */ - urlForNewTab: urlForNewTab, - /** - * Returns the Url path for a specific domain object - * including the index.html path and the view path - * allowing a new tab to hold the correct characteristics - * @param {value} value of the browse or edit mode - * for the path - * @param {DomainObject} value of the domain object - * to get the path of - * @memberof platform/commonUI/general.UrlService# - */ - urlForLocation: urlForLocation - }; + this.$location = $location; } + /** + * Returns the Url path for a specific domain object + * without the index.html path and the view path + * @param {string} mode value of browse or edit mode + * for the path + * @param {DomainObject} value of the domain object + * to get the path of + * @returns {string} URL for the domain object + */ + UrlService.prototype.urlForLocation = function (mode, domainObject) { + var context = domainObject && + domainObject.getCapability('context'), + objectPath = context ? context.getPath() : [], + ids = objectPath.map(function (domainObject) { + return domainObject.getId(); + }); + + // Parses the path together. Starts with the + // default index.html file, then the mode passed + // into the service, followed by ids in the url + // joined by '/', and lastly the view path from + // the current location + return mode + "/" + ids.slice(1).join("/"); + }; + + /** + * Returns the Url path for a specific domain object + * including the index.html path and the view path + * allowing a new tab to hold the correct characteristics + * @param {string} mode value of browse or edit mode + * for the path + * @param {DomainObject} value of the domain object + * to get the path of + * @returns {string} URL for the domain object + */ + UrlService.prototype.urlForNewTab = function (mode, domainObject) { + var viewPath = "?view=" + this.$location.search().view, + newTabPath = + "index.html#" + this.urlForLocation(mode, domainObject) + + viewPath; + return newTabPath; + }; + return UrlService; } );