diff --git a/platform/commonUI/browse/src/navigation/OrphanNavigationHandler.js b/platform/commonUI/browse/src/navigation/OrphanNavigationHandler.js
index 2a319876b5..00d6423fa4 100644
--- a/platform/commonUI/browse/src/navigation/OrphanNavigationHandler.js
+++ b/platform/commonUI/browse/src/navigation/OrphanNavigationHandler.js
@@ -58,7 +58,7 @@ define([], function () {
function checkNavigation() {
var navigatedObject = navigationService.getNavigation();
- if (navigatedObject.hasCapability('context')) {
+ if (navigatedObject && navigatedObject.hasCapability('context')) {
if (!navigatedObject.getCapability('editor').isEditContextRoot()) {
preventOrphanNavigation(navigatedObject);
}
diff --git a/platform/features/hyperlink/res/templates/hyperlink.html b/platform/features/hyperlink/res/templates/hyperlink.html
index 3734e89470..5e3fc597c8 100644
--- a/platform/features/hyperlink/res/templates/hyperlink.html
+++ b/platform/features/hyperlink/res/templates/hyperlink.html
@@ -19,10 +19,10 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
-
- {{domainObject.getModel().displayText}}
+ 'c-hyperlink--button u-fills-container' : hyperlink.isButton(),
+ 'c-hyperlink--link' : !hyperlink.isButton() }">
+ {{domainObject.getModel().displayText}}
diff --git a/platform/features/layout/res/templates/layout.html b/platform/features/layout/res/templates/layout.html
deleted file mode 100644
index e18c877006..0000000000
--- a/platform/features/layout/res/templates/layout.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/platform/features/layout/src/LayoutController.js b/platform/features/layout/src/LayoutController.js
deleted file mode 100644
index ed3b016ae2..0000000000
--- a/platform/features/layout/src/LayoutController.js
+++ /dev/null
@@ -1,524 +0,0 @@
-/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, 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 object types and associated views for
- * display-building.
- * @namespace platform/features/layout
- */
-define(
- [
- 'zepto',
- './LayoutDrag'
- ],
- function (
- $,
- LayoutDrag
- ) {
-
- var DEFAULT_DIMENSIONS = [12, 8],
- DEFAULT_GRID_SIZE = [32, 32],
- MINIMUM_FRAME_SIZE = [320, 180];
-
- var DEFAULT_HIDDEN_FRAME_TYPES = [
- 'hyperlink'
- ];
-
- /**
- * The LayoutController is responsible for supporting the
- * Layout view. It arranges frames according to saved configuration
- * and provides methods for updating these based on mouse
- * movement.
- * @memberof platform/features/layout
- * @constructor
- * @param {Scope} $scope the controller's Angular scope
- */
- function LayoutController($scope, $element, openmct) {
- var self = this,
- callbackCount = 0;
-
- this.$element = $element;
-
- // Update grid size when it changed
- function updateGridSize(layoutGrid) {
- var oldSize = self.gridSize;
-
- self.gridSize = layoutGrid || DEFAULT_GRID_SIZE;
-
- // Only update panel positions if this actually changed things
- if (self.gridSize[0] !== oldSize[0] ||
- self.gridSize[1] !== oldSize[1]) {
- self.layoutPanels(Object.keys(self.positions));
- }
- }
-
- // Position a panel after a drop event
- function handleDrop(e, id, position) {
- if (e.defaultPrevented) {
- return;
- }
-
- $scope.configuration = $scope.configuration || {};
- $scope.configuration.panels = $scope.configuration.panels || {};
-
- self.openmct.objects.get(id).then(function (object) {
- $scope.configuration.panels[id] = {
- position: [
- Math.floor(position.x / self.gridSize[0]),
- Math.floor(position.y / self.gridSize[1])
- ],
- dimensions: self.defaultDimensions(),
- hasFrame: self.getDefaultFrame(object.type)
- };
-
- // Store the id so that the newly-dropped object
- // gets selected during refresh composition
- self.droppedIdToSelectAfterRefresh = id;
-
- self.commit();
-
- // Populate template-facing position for this id
- self.rawPositions[id] = $scope.configuration.panels[id];
- self.populatePosition(id);
- refreshComposition();
- });
-
- // Layout may contain embedded views which will
- // listen for drops, so call preventDefault() so
- // that they can recognize that this event is handled.
- e.preventDefault();
- }
-
- //Will fetch fully contextualized composed objects, and populate
- // scope with them.
- function refreshComposition() {
- //Keep a track of how many composition callbacks have been made
- var thisCount = ++callbackCount;
-
- $scope.domainObject.useCapability('composition').then(function (composition) {
- var ids;
-
- //Is this callback for the most recent composition
- // request? If not, discard it. Prevents race condition
- if (thisCount === callbackCount) {
- ids = composition.map(function (object) {
- return object.getId();
- }) || [];
-
- $scope.composition = composition;
- self.layoutPanels(ids);
- self.setFrames(ids);
-
- if (self.selectedId &&
- self.selectedId !== $scope.domainObject.getId() &&
- composition.indexOf(self.selectedId) === -1) {
- // Click triggers selection of layout parent.
- self.$element[0].click();
- }
- }
- });
- }
-
- // End drag; we don't want to put $scope into this
- // because it triggers "cpws" (copy window or scope)
- // errors in Angular.
- this.endDragInScope = function () {
- // Write to configuration; this is watched and
- // saved by the EditRepresenter.
- $scope.configuration =
- $scope.configuration || {};
-
- $scope.configuration.panels =
- $scope.configuration.panels || {};
-
- $scope.configuration.panels[self.activeDragId] =
- $scope.configuration.panels[self.activeDragId] || {};
-
- $scope.configuration.panels[self.activeDragId].position =
- self.rawPositions[self.activeDragId].position;
- $scope.configuration.panels[self.activeDragId].dimensions =
- self.rawPositions[self.activeDragId].dimensions;
-
- self.commit();
- };
-
- // Sets the selectable object in response to the selection change event.
- function setSelection(selectable) {
- var selection = selectable[0];
-
- if (!selection) {
- delete self.selectedId;
- return;
- }
-
- self.selectedId = selection.context.oldItem.getId();
- self.drilledIn = undefined;
- self.selectable = selectable;
- }
-
- this.positions = {};
- this.rawPositions = {};
- this.gridSize = DEFAULT_GRID_SIZE;
- this.$scope = $scope;
- this.drilledIn = undefined;
- this.openmct = openmct;
-
- // Watch for changes to the grid size in the model
- $scope.$watch("model.layoutGrid", updateGridSize);
-
- // Update composed objects on screen, and position panes
- $scope.$watchCollection("model.composition", refreshComposition);
-
- openmct.selection.on('change', setSelection);
-
- $scope.$on("$destroy", function () {
- openmct.selection.off("change", setSelection);
- self.unlisten();
- });
-
- $scope.$on("mctDrop", handleDrop);
-
- self.unlisten = self.$scope.domainObject.getCapability('mutation').listen(function (model) {
- $scope.configuration = model.configuration.layout;
- $scope.model = model;
- var panels = $scope.configuration.panels;
-
- Object.keys(panels).forEach(function (key) {
- if (self.frames && self.frames.hasOwnProperty(key)) {
- self.frames[key] = panels[key].hasFrame;
- }
- });
- });
- }
-
- // Utility function to copy raw positions from configuration,
- // without writing directly to configuration (to avoid triggering
- // persistence from watchers during drags).
- function shallowCopy(obj, keys) {
- var copy = {};
- keys.forEach(function (k) {
- copy[k] = obj[k];
- });
- return copy;
- }
-
- /**
- * Set the frames value. If a configuration panel has "hasFrame' property,
- * use that value, otherwise set a default value. A 'hyperlink' object should
- * have no frame by default.
- *
- * @param {string[]} ids the object ids
- * @private
- */
- LayoutController.prototype.setFrames = function (ids) {
- var panels = shallowCopy(this.$scope.configuration.panels || {}, ids);
- this.frames = {};
-
- this.$scope.composition.forEach(function (object) {
- var id = object.getId();
- panels[id] = panels[id] || {};
-
- if (panels[id].hasOwnProperty('hasFrame')) {
- this.frames[id] = panels[id].hasFrame;
- } else {
- this.frames[id] = this.getDefaultFrame(object.getModel().type);
- }
- }, this);
- };
-
- /**
- * Gets the default value for frame.
- *
- * @param type the domain object type
- * @return {boolean} true if the object should have
- * frame by default, false, otherwise
- */
- LayoutController.prototype.getDefaultFrame = function (type) {
- return DEFAULT_HIDDEN_FRAME_TYPES.indexOf(type) === -1;
- };
-
- // Convert from { positions: ..., dimensions: ... } to an
- // appropriate ng-style argument, to position frames.
- LayoutController.prototype.convertPosition = function (raw) {
- var gridSize = this.gridSize;
- // Multiply position/dimensions by grid size
- return {
- left: (gridSize[0] * raw.position[0]) + 'px',
- top: (gridSize[1] * raw.position[1]) + 'px',
- width: (gridSize[0] * raw.dimensions[0]) + 'px',
- height: (gridSize[1] * raw.dimensions[1]) + 'px',
- minWidth: (gridSize[0] * raw.dimensions[0]) + 'px',
- minHeight: (gridSize[1] * raw.dimensions[1]) + 'px'
- };
- };
-
- // Generate default positions for a new panel
- LayoutController.prototype.defaultDimensions = function () {
- var gridSize = this.gridSize;
- return MINIMUM_FRAME_SIZE.map(function (min, i) {
- return Math.max(
- Math.ceil(min / gridSize[i]),
- DEFAULT_DIMENSIONS[i]
- );
- });
- };
-
- // Generate a default position (in its raw format) for a frame.
- // Use an index to ensure that default positions are unique.
- LayoutController.prototype.defaultPosition = function (index) {
- return {
- position: [index, index],
- dimensions: this.defaultDimensions()
- };
- };
-
- // Store a computed position for a contained frame by its
- // domain object id. Called in a forEach loop, so arguments
- // are as expected there.
- LayoutController.prototype.populatePosition = function (id, index) {
- this.rawPositions[id] =
- this.rawPositions[id] || this.defaultPosition(index || 0);
- this.positions[id] =
- this.convertPosition(this.rawPositions[id]);
- };
-
- /**
- * Get a style object for a frame with the specified domain
- * object identifier, suitable for use in an `ng-style`
- * directive to position a frame as configured for this layout.
- * @param {string} id the object identifier
- * @returns {Object.