Files
openmct/platform/commonUI/browse/src/BrowseController.js
2017-04-05 14:52:46 -07:00

167 lines
6.4 KiB
JavaScript

/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* This bundle implements Browse mode.
* @namespace platform/commonUI/browse
*/
define(
[],
function () {
/**
* The BrowseController is used to populate the initial scope in Browse
* mode. It loads the root object from the objectService and makes it
* available in the scope for Angular template's; this is the point at
* which Angular templates first have access to the domain object
* hierarchy.
*
* @memberof platform/commonUI/browse
* @constructor
*/
function BrowseController(
$scope,
$route,
$location,
objectService,
navigationService,
urlService,
defaultPath
) {
var initialPath = ($route.current.params.ids || defaultPath).split("/");
var currentIds;
$scope.treeModel = {
selectedObject: undefined,
onSelection: function (object) {
navigationService.setNavigation(object, true);
},
allowSelection: function (object) {
return navigationService.shouldNavigate();
}
};
function idsForObject(domainObject) {
return urlService
.urlForLocation("", domainObject)
.replace('/', '');
}
// Find an object in an array of objects.
function findObject(domainObjects, id) {
var i;
for (i = 0; i < domainObjects.length; i += 1) {
if (domainObjects[i].getId() === id) {
return domainObjects[i];
}
}
}
// helper, fetch a single object from the object service.
function getObject(id) {
return objectService.getObjects([id])
.then(function (results) {
return results[id];
});
}
// recursively locate and return an object inside of a container
// via a path. If at any point in the recursion it fails to find
// the next object, it will return the parent.
function findViaComposition(containerObject, path) {
var nextId = path.shift();
if (!nextId) {
return containerObject;
}
return containerObject.useCapability('composition')
.then(function (composees) {
var nextObject = findObject(composees, nextId);
if (!nextObject) {
return containerObject;
}
if (!nextObject.hasCapability('composition')) {
return nextObject;
}
return findViaComposition(nextObject, path);
});
}
function navigateToObject(desiredObject) {
$scope.navigatedObject = desiredObject;
$scope.treeModel.selectedObject = desiredObject;
currentIds = idsForObject(desiredObject);
$route.current.pathParams.ids = currentIds;
$location.path('/browse/' + currentIds);
}
function navigateToPath(path) {
return getObject('ROOT')
.then(function (root) {
return findViaComposition(root, path);
})
.then(function (object) {
navigationService.setNavigation(object);
});
}
getObject('ROOT')
.then(function (root) {
$scope.domainObject = root;
navigateToPath(initialPath);
});
// Handle navigation events from view service. Only navigates
// if path has changed.
function navigateDirectlyToModel(domainObject) {
var newIds = idsForObject(domainObject);
if (currentIds !== newIds) {
currentIds = newIds;
navigateToObject(domainObject);
}
}
// Listen for changes in navigation state.
navigationService.addListener(navigateDirectlyToModel);
// Listen for route changes which are caused by browser events
// (e.g. bookmarks to pages in OpenMCT) and prevent them. Instead,
// navigate to the path ourselves, which results in it being
// properly set.
$scope.$on('$routeChangeStart', function (event, route) {
if (route.$$route === $route.current.$$route &&
route.pathParams.ids !== $route.current.pathParams.ids) {
event.preventDefault();
navigateToPath(route.pathParams.ids.split('/'));
}
});
// Clean up when the scope is destroyed
$scope.$on("$destroy", function () {
navigationService.removeListener(navigateDirectlyToModel);
});
}
return BrowseController;
}
);