Compare commits
	
		
			124 Commits
		
	
	
		
			drag-and-d
			...
			misc-fixes
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 06524ce967 | ||
|   | 1ec529f360 | ||
|   | cf6458c69d | ||
|   | 3316500774 | ||
|   | 0f780587c0 | ||
|   | ea69508e22 | ||
|   | 4274d8cc0b | ||
|   | 1a2048332f | ||
|   | 38a875395f | ||
|   | f601ab03e7 | ||
|   | ee1d92d4a9 | ||
|   | 548286bacd | ||
|   | 9c9006d415 | ||
|   | 3219a64d09 | ||
|   | 570aa2c02a | ||
|   | c577d2e231 | ||
|   | 6bf4b3aba8 | ||
|   | b659f205f7 | ||
|   | 40d54df567 | ||
|   | b7fa5c7ba8 | ||
|   | 3b0605d17b | ||
|   | d93e7bfd1a | ||
|   | 104cd0ed29 | ||
|   | 7fb3d86d06 | ||
|   | dbb42e9bb6 | ||
|   | d1baa1f98b | ||
|   | 5ab68c0586 | ||
|   | 3cf78f509d | ||
|   | c6053e234a | ||
|   | 964c326535 | ||
|   | baf410a364 | ||
|   | 517a40a32b | ||
|   | 8b275b206b | ||
|   | a40a31aa4c | ||
|   | 6c0c1df010 | ||
|   | c552afff17 | ||
|   | 0837129ad5 | ||
|   | 6f3e2a8fbb | ||
|   | 4189a05758 | ||
|   | 97ccaa58c7 | ||
|   | 08ef932926 | ||
|   | 1d2ed0398c | ||
|   | 5a00e0c549 | ||
|   | ebcf47733f | ||
|   | 381d7e7615 | ||
|   | 8246b47668 | ||
|   | bc5e300ba9 | ||
|   | 57efef3160 | ||
|   | dfc5a9f040 | ||
|   | 57443d227d | ||
|   | d36441db73 | ||
|   | 327782835e | ||
|   | 994f6be535 | ||
|   | 72fc8a24a5 | ||
|   | 07002c12eb | ||
|   | c688d19e15 | ||
|   | c0ce448dc3 | ||
|   | 6c479d6d59 | ||
|   | 76ba487261 | ||
|   | e3f4da19f9 | ||
|   | c7ffcbf7e0 | ||
|   | a27b3737f1 | ||
|   | 78dccf1e0a | ||
|   | 9cb7e09aef | ||
|   | 4111c12895 | ||
|   | b6ec023920 | ||
|   | e8e7067993 | ||
|   | 0e9319e97b | ||
|   | df53af7b4d | ||
|   | bcbf244fd2 | ||
|   | 7ff5febae0 | ||
|   | 019d108bb2 | ||
|   | a14f628ca3 | ||
|   | 6116351dad | ||
|   | 23efef4469 | ||
|   | 95549f7be2 | ||
|   | 6338bd1168 | ||
|   | f7d0d2c166 | ||
|   | 7c2e10ba0e | ||
|   | 350d3c92e7 | ||
|   | 0f2918efaf | ||
|   | b72ad529aa | ||
|   | f77c6c821c | ||
|   | 248f160e73 | ||
|   | 5151f90bb8 | ||
|   | 402062110d | ||
|   | 1c8f23dea1 | ||
|   | 5ee22b3481 | ||
|   | 322a7bd5a8 | ||
|   | 0e30fba72d | ||
|   | 1c77ef142c | ||
|   | 853764d863 | ||
|   | d0ab59f9da | ||
|   | 21e08709cb | ||
|   | a1aa99837b | ||
|   | 037264b0bf | ||
|   | 1a06702dbe | ||
|   | 666bb41697 | ||
|   | e254fafb5c | ||
|   | 1dc1cc6c24 | ||
|   | baa5d10009 | ||
|   | ac2b9acccb | ||
|   | 075d4deecb | ||
|   | ac11f898d4 | ||
|   | dd31de6935 | ||
|   | 9e811e722f | ||
|   | 8ef53d85c4 | ||
|   | abcc5cb023 | ||
|   | 931871ff95 | ||
|   | 6b1e8862ef | ||
|   | 00ce246fc5 | ||
|   | c0c7d96429 | ||
|   | 92b2582d0d | ||
|   | 4084a1ac86 | ||
|   | cb1a1c2616 | ||
|   | ce6c1f173e | ||
|   | 30a4888363 | ||
|   | b0917a9866 | ||
|   | 464e5de947 | ||
|   | 47a07da17d | ||
|   | ec4c443299 | ||
|   | 3122168b0e | ||
|   | da3af4b3db | ||
|   | d026bc2134 | 
| @@ -37,25 +37,25 @@ define([ | ||||
|         }, | ||||
|         LIMITS = { | ||||
|             rh: { | ||||
|                 cssClass: "s-limit-upr s-limit-red", | ||||
|                 cssClass: "is-limit--upr is-limit--red", | ||||
|                 low: RED, | ||||
|                 high: Number.POSITIVE_INFINITY, | ||||
|                 name: "Red High" | ||||
|             }, | ||||
|             rl: { | ||||
|                 cssClass: "s-limit-lwr s-limit-red", | ||||
|                 cssClass: "is-limit--lwr is-limit--red", | ||||
|                 high: -RED, | ||||
|                 low: Number.NEGATIVE_INFINITY, | ||||
|                 name: "Red Low" | ||||
|             }, | ||||
|             yh: { | ||||
|                 cssClass: "s-limit-upr s-limit-yellow", | ||||
|                 cssClass: "is-limit--upr is-limit--yellow", | ||||
|                 low: YELLOW, | ||||
|                 high: RED, | ||||
|                 name: "Yellow High" | ||||
|             }, | ||||
|             yl: { | ||||
|                 cssClass: "s-limit-lwr s-limit-yellow", | ||||
|                 cssClass: "is-limit--lwr is-limit--yellow", | ||||
|                 low: -RED, | ||||
|                 high: -YELLOW, | ||||
|                 name: "Yellow Low" | ||||
|   | ||||
| @@ -43,15 +43,14 @@ define([ | ||||
|             form: [ | ||||
|                 { | ||||
|                     name: "State Duration (seconds)", | ||||
|                     control: "textfield", | ||||
|                     control: "numberfield", | ||||
|                     cssClass: "l-input-sm l-numeric", | ||||
|                     key: "duration", | ||||
|                     required: true, | ||||
|                     property: [ | ||||
|                         "telemetry", | ||||
|                         "duration" | ||||
|                     ], | ||||
|                     pattern: "^\\d*(\\.\\d*)?$" | ||||
|                     ] | ||||
|                 } | ||||
|             ], | ||||
|             initialize: function (object) { | ||||
|   | ||||
							
								
								
									
										217
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										217
									
								
								index.html
									
									
									
									
									
								
							| @@ -27,7 +27,7 @@ | ||||
|         <meta name="apple-mobile-web-app-capable" content="yes"> | ||||
|         <title></title> | ||||
|         <script src="dist/openmct.js"></script> | ||||
|         <link rel="stylesheet" href="dist/openmct.css"> | ||||
|         <link rel="stylesheet" href="dist/styles/openmct.css"> | ||||
|         <link rel="icon" type="image/png" href="dist/favicons/favicon-32x32.png" sizes="32x32"> | ||||
|         <link rel="icon" type="image/png" href="dist/favicons/favicon-96x96.png" sizes="96x96"> | ||||
|         <link rel="icon" type="image/png" href="dist/favicons/favicon-16x16.png" sizes="16x16"> | ||||
| @@ -36,7 +36,9 @@ | ||||
|     <body> | ||||
|     </body> | ||||
|     <script> | ||||
|         var THIRTY_MINUTES = 30 * 60 * 1000; | ||||
|         const FIVE_MINUTES = 5 * 60 * 1000; | ||||
|         const THIRTY_MINUTES = 30 * 60 * 1000; | ||||
|  | ||||
|         [ | ||||
|             'example/eventGenerator', | ||||
|             'example/styleguide' | ||||
| @@ -49,10 +51,12 @@ | ||||
|         openmct.install(openmct.plugins.ExampleImagery()); | ||||
|         openmct.install(openmct.plugins.UTCTimeSystem()); | ||||
|         openmct.install(openmct.plugins.ImportExport()); | ||||
|         openmct.install(openmct.plugins.FixedView()); | ||||
|         openmct.install(openmct.plugins.AutoflowView({ | ||||
|             type: "telemetry.panel" | ||||
|         })); | ||||
|         openmct.install(openmct.plugins.DisplayLayout({ | ||||
|             showAsView: ['summary-widget', 'example.imagery'] | ||||
|         })); | ||||
|         openmct.install(openmct.plugins.Conductor({ | ||||
|             menuOptions: [ | ||||
|                 { | ||||
| @@ -68,8 +72,8 @@ | ||||
|                     timeSystem: 'utc', | ||||
|                     clock: 'local', | ||||
|                     clockOffsets: { | ||||
|                         start: -25 * 60 * 1000, | ||||
|                         end: 5 * 60 * 1000 | ||||
|                         start: - THIRTY_MINUTES, | ||||
|                         end: FIVE_MINUTES | ||||
|                     } | ||||
|                 } | ||||
|             ] | ||||
| @@ -79,206 +83,9 @@ | ||||
|         openmct.install(openmct.plugins.FolderView()); | ||||
|         openmct.install(openmct.plugins.Tabs()); | ||||
|         openmct.install(openmct.plugins.FlexibleLayout()); | ||||
|         openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0}); | ||||
|         openmct.time.timeSystem('utc'); | ||||
|         openmct.install(openmct.plugins.LADTable()); | ||||
|         openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay'])); | ||||
|         openmct.install(openmct.plugins.ObjectMigration()); | ||||
|         openmct.start(); | ||||
|  | ||||
|         // openmct.toolbars.addProvider({ | ||||
|         //     name: "Testing Toolbar", | ||||
|         //     key: "testing", | ||||
|         //     description: "a mock toolbar that exercises all controls", | ||||
|         //     forSelection: function (selection) { | ||||
|         //         return true; // always applies. | ||||
|         //     }, | ||||
|         //     toolbar: function (selection) { | ||||
|         //         return [ | ||||
|         //             { | ||||
|         //                 control: 'menu', | ||||
|         //                 icon: 'icon-plus', | ||||
|         //                 label: 'Add', | ||||
|         //                 options: [ | ||||
|         //                     { name: 'Box', class: 'icon-box', title: 'Add Box' }, | ||||
|         //                     { name: 'Line', class: 'icon-line-horz', title: 'Add Line' }, | ||||
|         //                     { name: 'Text', class: 'icon-font', title: 'Add Text' }, | ||||
|         //                     { name: 'Image', class: 'icon-image', title: 'Add Image' } | ||||
|         //                 ] | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'separator' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'color-picker', | ||||
|         //                 icon: 'icon-paint-bucket', | ||||
|         //                 value: '#33ff00', | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'color-picker', | ||||
|         //                 icon: 'icon-pencil', | ||||
|         //                 value: '#ffffff', | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'color-picker', | ||||
|         //                 icon: 'icon-font', | ||||
|         //                 value: '#333333', | ||||
|         //             }, | ||||
|         // | ||||
|         //             { | ||||
|         //                 control: 'separator' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'select-menu', | ||||
|         //                 value: 11, | ||||
|         //                 options: [ | ||||
|         //                     { value: 9, name: '9 px' }, | ||||
|         //                     { value: 10, name: '10 px' }, | ||||
|         //                     { value: 11, name: '11 px' }, | ||||
|         //                     { value: 12, name: '12 px' }, | ||||
|         //                     { value: 13, name: '13 px' }, | ||||
|         //                     { value: 14, name: '14 px' }, | ||||
|         //                     { value: 16, name: '16 px' }, | ||||
|         //                     { value: 18, name: '18 px' }, | ||||
|         //                     { value: 20, name: '20 px' }, | ||||
|         //                     { value: 24, name: '24 px' }, | ||||
|         //                     { value: 28, name: '28 px' }, | ||||
|         //                     { value: 32, name: '32 px' }, | ||||
|         //                     { value: 40, name: '40 px' }, | ||||
|         //                     { value: 48, name: '48 px' }, | ||||
|         //                     { value: 56, name: '56 px' }, | ||||
|         //                     { value: 64, name: '64 px' }, | ||||
|         //                     { value: 72, name: '72 px' }, | ||||
|         //                     { value: 80, name: '80 px' }, | ||||
|         //                     { value: 88, name: '88 px' }, | ||||
|         //                     { value: 96, name: '96 px' }, | ||||
|         //                     { value: 128, name: '128 px' }, | ||||
|         //                     { value: 160, name: '160 px' } | ||||
|         //                 ] | ||||
|         //             }, | ||||
|         // | ||||
|         //             { | ||||
|         //                 control: 'separator' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'menu', | ||||
|         //                 icon: 'icon-layers', | ||||
|         //                 options: [ | ||||
|         //                     { name: 'Move to top', class: 'icon-arrow-double-up', title: 'Move to top' }, | ||||
|         //                     { name: 'Move up', class: 'icon-arrow-up', title: 'Move up' }, | ||||
|         //                     { name: 'Move down', class: 'icon-arrow-down', title: 'Move down' }, | ||||
|         //                     { name: 'Move to bottom', class: 'icon-arrow-double-down', title: 'Move to bottom' } | ||||
|         //                 ] | ||||
|         //             }, | ||||
|         // | ||||
|         //             { | ||||
|         //                 control: 'separator' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'button', | ||||
|         //                 icon: 'icon-gear' | ||||
|         //             }, | ||||
|         // | ||||
|         //             { | ||||
|         //                 control: 'separator' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'input', | ||||
|         //                 type: 'number', | ||||
|         //                 label: 'X', | ||||
|         //                 value: 1, | ||||
|         //                 title: 'X position' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'input', | ||||
|         //                 type: 'number', | ||||
|         //                 label: 'Y', | ||||
|         //                 value: 2, | ||||
|         //                 title: 'Y position' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'input', | ||||
|         //                 type: 'number', | ||||
|         //                 label: 'W', | ||||
|         //                 value: 3, | ||||
|         //                 title: 'Width' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'input', | ||||
|         //                 type: 'number', | ||||
|         //                 label: 'H', | ||||
|         //                 value: 4, | ||||
|         //                 title: 'Height' | ||||
|         //             }, | ||||
|         // | ||||
|         //             { | ||||
|         //                 control: 'separator' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'button', | ||||
|         //                 icon: 'icon-trash', | ||||
|         //                 label: 'delete', | ||||
|         //                 modifier: 'caution' | ||||
|         //             }, | ||||
|         // | ||||
|         //             { | ||||
|         //                 control: 'separator' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'checkbox', | ||||
|         //                 name: 'this is a checkbox', | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'separator' | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'toggle-button', | ||||
|         //                 title: 'Toggle Frame', | ||||
|         //                 property: 'hideFrame', | ||||
|         //                 value: false, | ||||
|         //                 options: [ | ||||
|         //                     { | ||||
|         //                         value: true, | ||||
|         //                         icon: 'icon-frame-hide' | ||||
|         //                     }, | ||||
|         //                     { | ||||
|         //                         value: false, | ||||
|         //                         icon: 'icon-frame-show' | ||||
|         //                     } | ||||
|         //                 ] | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'toggle-button', | ||||
|         //                 title: 'Snap to grid', | ||||
|         //                 property: 'snapToGrid', | ||||
|         //                 value: true, | ||||
|         //                 options: [ | ||||
|         //                     { | ||||
|         //                         value: true, | ||||
|         //                         icon: 'icon-grid-snap-to' | ||||
|         //                     }, | ||||
|         //                     { | ||||
|         //                         value: false, | ||||
|         //                         icon: 'icon-grid-snap-no' | ||||
|         //                     } | ||||
|         //                 ] | ||||
|         //             }, | ||||
|         //             { | ||||
|         //                 control: 'toggle-button', | ||||
|         //                 title: 'Toggle label', | ||||
|         //                 property: 'showLabel', | ||||
|         //                 value: true, | ||||
|         //                 options: [ | ||||
|         //                     { | ||||
|         //                         value: true, | ||||
|         //                         icon: 'icon-two-parts-both' | ||||
|         //                     }, | ||||
|         //                     { | ||||
|         //                         value: false, | ||||
|         //                         icon: 'icon-two-parts-one-only' | ||||
|         //                     } | ||||
|         //                 ] | ||||
|         //             } | ||||
|         //         ]; | ||||
|         //     } | ||||
|         // }); | ||||
|  | ||||
|     </script> | ||||
| </html> | ||||
|   | ||||
| @@ -25,7 +25,7 @@ | ||||
|     "eventemitter3": "^1.2.0", | ||||
|     "exports-loader": "^0.7.0", | ||||
|     "express": "^4.13.1", | ||||
|     "fast-sass-loader": "^1.4.5", | ||||
|     "fast-sass-loader": "1.4.6", | ||||
|     "file-loader": "^1.1.11", | ||||
|     "file-saver": "^1.3.8", | ||||
|     "git-rev-sync": "^1.4.0", | ||||
|   | ||||
| @@ -31,7 +31,6 @@ define([ | ||||
|     "./src/navigation/NavigateAction", | ||||
|     "./src/navigation/OrphanNavigationHandler", | ||||
|     "./src/windowing/NewTabAction", | ||||
|     "./src/windowing/WindowTitler", | ||||
|     "./res/templates/browse.html", | ||||
|     "./res/templates/browse-object.html", | ||||
|     "./res/templates/browse/object-header.html", | ||||
| @@ -52,7 +51,6 @@ define([ | ||||
|     NavigateAction, | ||||
|     OrphanNavigationHandler, | ||||
|     NewTabAction, | ||||
|     WindowTitler, | ||||
|     browseTemplate, | ||||
|     browseObjectTemplate, | ||||
|     objectHeaderTemplate, | ||||
| @@ -226,14 +224,6 @@ define([ | ||||
|                 } | ||||
|             ], | ||||
|             "runs": [ | ||||
|                 { | ||||
|                     "implementation": WindowTitler, | ||||
|                     "depends": [ | ||||
|                         "navigationService", | ||||
|                         "$rootScope", | ||||
|                         "$document" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|                     "implementation": OrphanNavigationHandler, | ||||
|                     "depends": [ | ||||
|   | ||||
| @@ -1,51 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * Updates the title of the current window to reflect the name | ||||
|          * of the currently navigated-to domain object. | ||||
|          * @memberof platform/commonUI/browse | ||||
|          * @constructor | ||||
|          */ | ||||
|         function WindowTitler(navigationService, $rootScope, $document) { | ||||
|             // Look up name of the navigated domain object... | ||||
|             function getNavigatedObjectName() { | ||||
|                 var navigatedObject = navigationService.getNavigation(); | ||||
|                 return navigatedObject && navigatedObject.getModel().name; | ||||
|             } | ||||
|  | ||||
|             // Set the window title... | ||||
|             function setTitle(name) { | ||||
|                 $document[0].title = name; | ||||
|             } | ||||
|  | ||||
|             // Watch the former, and invoke the latter | ||||
|             $rootScope.$watch(getNavigatedObjectName, setTitle); | ||||
|         } | ||||
|  | ||||
|         return WindowTitler; | ||||
|     } | ||||
| ); | ||||
| @@ -1,78 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /** | ||||
|  * WindowTitlerSpec. Created by vwoeltje on 11/6/14. | ||||
|  */ | ||||
| define( | ||||
|     ["../../src/windowing/WindowTitler"], | ||||
|     function (WindowTitler) { | ||||
|  | ||||
|         describe("The window titler", function () { | ||||
|             var mockNavigationService, | ||||
|                 mockRootScope, | ||||
|                 mockDocument, | ||||
|                 mockDomainObject, | ||||
|                 titler; // eslint-disable-line | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockNavigationService = jasmine.createSpyObj( | ||||
|                     'navigationService', | ||||
|                     ['getNavigation'] | ||||
|                 ); | ||||
|                 mockRootScope = jasmine.createSpyObj( | ||||
|                     '$rootScope', | ||||
|                     ['$watch'] | ||||
|                 ); | ||||
|                 mockDomainObject = jasmine.createSpyObj( | ||||
|                     'domainObject', | ||||
|                     ['getModel'] | ||||
|                 ); | ||||
|                 mockDocument = [{}]; | ||||
|  | ||||
|                 mockDomainObject.getModel.and.returnValue({ name: 'Test name' }); | ||||
|                 mockNavigationService.getNavigation.and.returnValue(mockDomainObject); | ||||
|  | ||||
|                 titler = new WindowTitler( | ||||
|                     mockNavigationService, | ||||
|                     mockRootScope, | ||||
|                     mockDocument | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("listens for changes to the name of the navigated object", function () { | ||||
|                 expect(mockRootScope.$watch).toHaveBeenCalledWith( | ||||
|                     jasmine.any(Function), | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|                 expect(mockRootScope.$watch.calls.mostRecent().args[0]()) | ||||
|                     .toEqual('Test name'); | ||||
|             }); | ||||
|  | ||||
|             it("sets the title to the name of the navigated object", function () { | ||||
|                 mockRootScope.$watch.calls.mostRecent().args[1]("Some name"); | ||||
|                 expect(mockDocument[0].title).toEqual("Some name"); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -28,6 +28,7 @@ define([ | ||||
|     "./res/templates/dialog.html", | ||||
|     "./res/templates/overlay-blocking-message.html", | ||||
|     "./res/templates/message.html", | ||||
|     "./res/templates/notification-message.html", | ||||
|     "./res/templates/overlay-message-list.html", | ||||
|     "./res/templates/overlay.html", | ||||
|     'legacyRegistry' | ||||
| @@ -39,6 +40,7 @@ define([ | ||||
|     dialogTemplate, | ||||
|     overlayBlockingMessageTemplate, | ||||
|     messageTemplate, | ||||
|     notificationMessageTemplate, | ||||
|     overlayMessageListTemplate, | ||||
|     overlayTemplate, | ||||
|     legacyRegistry | ||||
| @@ -63,7 +65,8 @@ define([ | ||||
|                     "depends": [ | ||||
|                         "$document", | ||||
|                         "$compile", | ||||
|                         "$rootScope" | ||||
|                         "$rootScope", | ||||
|                         "$timeout" | ||||
|                     ] | ||||
|                 } | ||||
|             ], | ||||
| @@ -88,6 +91,10 @@ define([ | ||||
|                     "key": "message", | ||||
|                     "template": messageTemplate | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "notification-message", | ||||
|                     "template": notificationMessageTemplate | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "overlay-message-list", | ||||
|                     "template": overlayMessageListTemplate | ||||
|   | ||||
| @@ -19,24 +19,24 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <div class="abs top-bar"> | ||||
|     <div class="dialog-title">{{ngModel.title}}</div> | ||||
|     <div class="hint">All fields marked <span class="req icon-asterisk"></span> are required.</div> | ||||
| <div class="c-overlay__top-bar"> | ||||
|     <div class="c-overlay__dialog-title">{{ngModel.title}}</div> | ||||
|     <div class="c-overlay__dialog-hint hint">All fields marked <span class="req icon-asterisk"></span> are required.</div> | ||||
| </div> | ||||
| <div class='abs editor'> | ||||
| <div class='c-overlay__contents-main'> | ||||
|     <mct-form ng-model="ngModel.value" | ||||
|               structure="ngModel.structure" | ||||
|               class="validates" | ||||
|               name="createForm"> | ||||
|     </mct-form> | ||||
| </div> | ||||
| <div class="abs bottom-bar"> | ||||
|     <a class='s-button major' | ||||
| <div class="c-overlay__button-bar"> | ||||
|     <a class='c-button c-button--major' | ||||
|        ng-class="{ disabled: !createForm.$valid }" | ||||
|        ng-click="ngModel.confirm()"> | ||||
|         OK | ||||
|     </a> | ||||
|     <a class='s-button' | ||||
|     <a class='c-button  ' | ||||
|        ng-click="ngModel.cancel()"> | ||||
|         Cancel | ||||
|     </a> | ||||
|   | ||||
| @@ -1,15 +1,32 @@ | ||||
| <div class="l-message" | ||||
| <div class="c-message" | ||||
|      ng-class="'message-severity-' + ngModel.severity"> | ||||
|     <div class="w-message-contents"> | ||||
|         <div class="top-bar"> | ||||
|             <div class="title">{{ngModel.message}}</div> | ||||
|         <div class="c-message__top-bar"> | ||||
|             <div class="c-message__title">{{ngModel.title}}</div> | ||||
|         </div> | ||||
|         <div class="c-message__hint" ng-hide="ngModel.hint === undefined"> | ||||
|             {{ngModel.hint}} | ||||
|             <span ng-if="ngModel.timestamp !== undefined">[{{ngModel.timestamp}}]</span> | ||||
|         </div> | ||||
|         <div class="message-body"> | ||||
|             <div class="message-action"> | ||||
|                 {{ngModel.actionText}} | ||||
|             </div> | ||||
|             <mct-include key="'progress-bar'" | ||||
|                          ng-model="ngModel" | ||||
|                          ng-show="ngModel.progressPerc !== undefined"></mct-include> | ||||
|                          ng-show="ngModel.progress !== undefined || ngModel.unknownProgress"></mct-include> | ||||
|         </div> | ||||
|         <div class="bottom-bar"> | ||||
|         <div class="c-overlay__button-bar"> | ||||
|             <button ng-repeat="dialogOption in ngModel.options" | ||||
|                class="c-button" | ||||
|                ng-click="dialogOption.callback()"> | ||||
|                 {{dialogOption.label}} | ||||
|             </button> | ||||
|             <button class="c-button c-button--major" | ||||
|                ng-if="ngModel.primaryOption" | ||||
|                ng-click="ngModel.primaryOption.callback()"> | ||||
|                 {{ngModel.primaryOption.label}} | ||||
|             </button> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| </div> | ||||
| @@ -0,0 +1,25 @@ | ||||
| <div class="c-message" | ||||
|      ng-class="'message-severity-' + ngModel.severity"> | ||||
|     <div class="w-message-contents"> | ||||
|         <div class="c-message__top-bar"> | ||||
|             <div class="c-message__title">{{ngModel.message}}</div> | ||||
|         </div> | ||||
|         <div class="message-body"> | ||||
|             <mct-include key="'progress-bar'" | ||||
|                          ng-model="ngModel" | ||||
|                          ng-show="ngModel.progressPerc !== undefined"></mct-include> | ||||
|         </div> | ||||
|         <div class="c-overlay__button-bar"> | ||||
|             <button ng-repeat="dialogOption in ngModel.options" | ||||
|                 class="c-button" | ||||
|                 ng-click="dialogOption.callback()"> | ||||
|                     {{dialogOption.label}} | ||||
|             </button> | ||||
|             <button class="c-button c-button--major" | ||||
|                 ng-if="ngModel.primaryOption" | ||||
|                 ng-click="ngModel.primaryOption.callback()"> | ||||
|                     {{ngModel.primaryOption.label}} | ||||
|             </button> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| @@ -1,22 +1,23 @@ | ||||
| <mct-container key="overlay"> | ||||
|     <div class="t-message-list"> | ||||
|         <div class="top-bar"> | ||||
|             <div class="dialog-title">{{ngModel.dialog.title}}</div> | ||||
|             <div class="hint">Displaying {{ngModel.dialog.messages.length}} message<span ng-show="ngModel.dialog.messages.length > 1 || | ||||
|                                                                                                   ngModel.dialog.messages.length == 0">s</span> | ||||
|     <div class="t-message-list c-overlay__contents"> | ||||
|         <div class="c-overlay__top-bar"> | ||||
|             <div class="c-overlay__dialog-title">{{ngModel.dialog.title}}</div> | ||||
|             <div class="c-overlay__dialog-hint">Displaying {{ngModel.dialog.messages.length}} message<span | ||||
|                     ng-show="ngModel.dialog.messages.length > 1 || | ||||
|                             ngModel.dialog.messages.length == 0">s</span> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="w-messages"> | ||||
|         <div class="w-messages c-overlay__messages"> | ||||
|             <mct-include | ||||
|                 ng-repeat="msg in ngModel.dialog.messages | orderBy: '-'" | ||||
|                 key="'message'" ng-model="msg.model"></mct-include> | ||||
|                 key="'notification-message'" ng-model="msg.model"></mct-include> | ||||
|         </div> | ||||
|         <div class="bottom-bar"> | ||||
|             <a ng-repeat="dialogAction in ngModel.dialog.actions" | ||||
|                class="s-button major" | ||||
|         <div class="c-overlay__bottom-bar"> | ||||
|             <button ng-repeat="dialogAction in ngModel.dialog.actions" | ||||
|                class="c-button c-button--major" | ||||
|                ng-click="dialogAction.action()"> | ||||
|                 {{dialogAction.label}} | ||||
|             </a> | ||||
|             </button> | ||||
|         </div> | ||||
|     </div> | ||||
| </mct-container> | ||||
|   | ||||
| @@ -19,18 +19,18 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <mct-container key="overlay"> | ||||
|     <div class="abs top-bar"> | ||||
|         <div class="dialog-title">{{ngModel.dialog.title}}</div> | ||||
|         <div class="hint">{{ngModel.dialog.hint}}</div> | ||||
| <mct-container key="c-overlay__contents"> | ||||
|     <div class=c-overlay__top-bar"> | ||||
|         <div class="c-overlay__dialog-title">{{ngModel.dialog.title}}</div> | ||||
|         <div class="c-overlay__dialog-hint hint">{{ngModel.dialog.hint}}</div> | ||||
|     </div> | ||||
|     <div class='abs editor'> | ||||
|     <div class='c-overlay__contents-main'> | ||||
|         <mct-include key="ngModel.dialog.template" | ||||
|                      parameters="ngModel.dialog.parameters" | ||||
|                      ng-model="ngModel.dialog.model"> | ||||
|         </mct-include> | ||||
|     </div> | ||||
|     <div class="abs bottom-bar"> | ||||
|     <div class="c-overlay__button-bar"> | ||||
|         <a ng-repeat="option in ngModel.dialog.options" | ||||
|            href='' | ||||
|            class="s-button lg" | ||||
|   | ||||
| @@ -19,12 +19,12 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <div class="abs overlay l-dialog" ng-class="{'delayEntry100ms' : ngModel.delay}"> | ||||
|     <div class="abs blocker"></div> | ||||
|     <div class="abs outer-holder"> | ||||
|         <a ng-click="ngModel.cancel()" | ||||
| <div class="c-overlay l-overlay-small" ng-class="{'delayEntry100ms' : ngModel.delay}"> | ||||
|     <div class="c-overlay__blocker"></div> | ||||
|     <div class="c-overlay__outer"> | ||||
|         <button ng-click="ngModel.cancel()" | ||||
|            ng-if="ngModel.cancel" | ||||
|            class="close icon-x-in-circle"></a> | ||||
|         <div class="abs inner-holder contents" ng-transclude></div> | ||||
|            class="c-click-icon c-overlay__close-button icon-x-in-circle"></button> | ||||
|         <div class="c-overlay__contents" ng-transclude></div> | ||||
|     </div> | ||||
| </div> | ||||
|   | ||||
| @@ -44,8 +44,9 @@ define( | ||||
|          * @memberof platform/commonUI/dialog | ||||
|          * @constructor | ||||
|          */ | ||||
|         function OverlayService($document, $compile, $rootScope) { | ||||
|         function OverlayService($document, $compile, $rootScope, $timeout) { | ||||
|             this.$compile = $compile; | ||||
|             this.$timeout = $timeout; | ||||
|  | ||||
|             // Don't include $document and $rootScope directly; | ||||
|             // avoids https://docs.angularjs.org/error/ng/cpws | ||||
| @@ -93,12 +94,14 @@ define( | ||||
|             scope.key = key; | ||||
|             scope.typeClass = typeClass || 't-dialog'; | ||||
|  | ||||
|             // Create the overlay element and add it to the document's body | ||||
|             element = this.$compile(TEMPLATE)(scope); | ||||
|              | ||||
|             // Append so that most recent dialog is last in DOM. This means the most recent dialog will be on top when | ||||
|             // multiple overlays with the same z-index are active. | ||||
|             this.findBody().append(element); | ||||
|             this.$timeout(() => { | ||||
|                 // Create the overlay element and add it to the document's body | ||||
|                 element = this.$compile(TEMPLATE)(scope); | ||||
|                  | ||||
|                 // Append so that most recent dialog is last in DOM. This means the most recent dialog will be on top when | ||||
|                 // multiple overlays with the same z-index are active. | ||||
|                 this.findBody().append(element); | ||||
|             }); | ||||
|  | ||||
|             return { | ||||
|                 dismiss: dismiss | ||||
|   | ||||
| @@ -35,16 +35,20 @@ define( | ||||
|                 mockTemplate, | ||||
|                 mockElement, | ||||
|                 mockScope, | ||||
|                 mockTimeout, | ||||
|                 overlayService; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockDocument = jasmine.createSpyObj("$document", ["find"]); | ||||
|                 mockCompile = jasmine.createSpy("$compile"); | ||||
|                 mockRootScope = jasmine.createSpyObj("$rootScope", ["$new"]); | ||||
|                 mockBody = jasmine.createSpyObj("body", ["prepend"]); | ||||
|                 mockBody = jasmine.createSpyObj("body", ["append"]); | ||||
|                 mockTemplate = jasmine.createSpy("template"); | ||||
|                 mockElement = jasmine.createSpyObj("element", ["remove"]); | ||||
|                 mockScope = jasmine.createSpyObj("scope", ["$destroy"]); | ||||
|                 mockTimeout = function (callback) { | ||||
|                     callback(); | ||||
|                 } | ||||
|  | ||||
|                 mockDocument.find.and.returnValue(mockBody); | ||||
|                 mockCompile.and.returnValue(mockTemplate); | ||||
| @@ -54,7 +58,8 @@ define( | ||||
|                 overlayService = new OverlayService( | ||||
|                     mockDocument, | ||||
|                     mockCompile, | ||||
|                     mockRootScope | ||||
|                     mockRootScope, | ||||
|                     mockTimeout | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
| @@ -67,7 +72,7 @@ define( | ||||
|  | ||||
|             it("adds the templated element to the body", function () { | ||||
|                 overlayService.createOverlay("test", {}); | ||||
|                 expect(mockBody.prepend).toHaveBeenCalledWith(mockElement); | ||||
|                 expect(mockBody.append).toHaveBeenCalledWith(mockElement); | ||||
|             }); | ||||
|  | ||||
|             it("places the provided model/key in its template's scope", function () { | ||||
|   | ||||
| @@ -32,7 +32,6 @@ define([ | ||||
|     "./src/actions/SaveAndStopEditingAction", | ||||
|     "./src/actions/SaveAsAction", | ||||
|     "./src/actions/CancelAction", | ||||
|     "./src/policies/EditActionPolicy", | ||||
|     "./src/policies/EditPersistableObjectsPolicy", | ||||
|     "./src/representers/EditRepresenter", | ||||
|     "./src/capabilities/EditorCapability", | ||||
| @@ -64,7 +63,6 @@ define([ | ||||
|     SaveAndStopEditingAction, | ||||
|     SaveAsAction, | ||||
|     CancelAction, | ||||
|     EditActionPolicy, | ||||
|     EditPersistableObjectsPolicy, | ||||
|     EditRepresenter, | ||||
|     EditorCapability, | ||||
| @@ -162,7 +160,7 @@ define([ | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "remove", | ||||
|                     "category": "contextual", | ||||
|                     "category": "legacy", | ||||
|                     "implementation": RemoveAction, | ||||
|                     "cssClass": "icon-trash", | ||||
|                     "name": "Remove", | ||||
| @@ -225,10 +223,6 @@ define([ | ||||
|                 } | ||||
|             ], | ||||
|             "policies": [ | ||||
|                 { | ||||
|                     "category": "action", | ||||
|                     "implementation": EditActionPolicy | ||||
|                 }, | ||||
|                 { | ||||
|                     "category": "action", | ||||
|                     "implementation": EditPersistableObjectsPolicy, | ||||
|   | ||||
| @@ -49,7 +49,7 @@ define( | ||||
|                     name: "Properties", | ||||
|                     rows: this.properties.map(function (property, index) { | ||||
|                         // Property definition is same as form row definition | ||||
|                         var row = Object.create(property.getDefinition()); | ||||
|                         var row = JSON.parse(JSON.stringify(property.getDefinition())); | ||||
|                         row.key = index; | ||||
|                         return row; | ||||
|                     }).filter(function (row) { | ||||
|   | ||||
| @@ -23,11 +23,7 @@ | ||||
| /** | ||||
|  * Module defining RemoveAction. Created by vwoeltje on 11/17/14. | ||||
|  */ | ||||
| define([ | ||||
|     './RemoveDialog' | ||||
| ], function ( | ||||
|     RemoveDialog | ||||
| ) { | ||||
| define([], function () { | ||||
|  | ||||
|     /** | ||||
|      * Construct an action which will remove the provided object manifestation. | ||||
| @@ -114,12 +110,7 @@ define([ | ||||
|             return parent.useCapability('mutation', doMutate); | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * Pass in the function to remove the domain object so it can be | ||||
|          * associated with an 'OK' button press | ||||
|          */ | ||||
|         dialog = new RemoveDialog(this.openmct, domainObject, removeFromContext); | ||||
|         dialog.show(); | ||||
|         removeFromContext(); | ||||
|     }; | ||||
|  | ||||
|     // Object needs to have a parent for Remove to be applicable | ||||
|   | ||||
| @@ -1,72 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([], function () { | ||||
|  | ||||
|     /** | ||||
|      * @callback removeCallback | ||||
|      * @param {DomainObject} domainObject the domain object to be removed | ||||
|      */ | ||||
|  | ||||
|     /** | ||||
|      * Construct a new Remove dialog. | ||||
|      * | ||||
|      * @param {DialogService} dialogService the service that shows the dialog | ||||
|      * @param {DomainObject} domainObject the domain object to be removed | ||||
|      * @param {removeCallback} removeCallback callback that handles removal of the domain object | ||||
|      * @memberof platform/commonUI/edit | ||||
|      * @constructor | ||||
|      */ | ||||
|     function RemoveDialog(openmct, domainObject, removeCallback) { | ||||
|         this.openmct = openmct; | ||||
|         this.domainObject = domainObject; | ||||
|         this.removeCallback = removeCallback; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a dialog to confirm the removal of a domain object. | ||||
|      */ | ||||
|     RemoveDialog.prototype.show = function () { | ||||
|         let dialog = this.openmct.overlays.dialog({ | ||||
|             title: 'Remove ' + this.domainObject.getModel().name, | ||||
|             iconClass: 'alert', | ||||
|             message: 'Warning! This action will permanently remove this object. Are you sure you want to continue?', | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     label: 'OK', | ||||
|                     callback: () => { | ||||
|                         this.removeCallback(); | ||||
|                         dialog.dismiss(); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     label: 'Cancel', | ||||
|                     callback: () => { | ||||
|                         dialog.dismiss(); | ||||
|                     } | ||||
|                 } | ||||
|             ] | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     return RemoveDialog; | ||||
| }); | ||||
| @@ -92,16 +92,7 @@ function ( | ||||
|          * @memberof platform/commonUI/edit.SaveAction# | ||||
|          */ | ||||
|     SaveAsAction.prototype.perform = function () { | ||||
|         // Discard the current root view (which will be the editing | ||||
|         // UI, which will have been pushed atop the Browse UI.) | ||||
|         function returnToBrowse(object) { | ||||
|             if (object) { | ||||
|                 object.getCapability("action").perform("navigate"); | ||||
|             } | ||||
|             return object; | ||||
|         } | ||||
|  | ||||
|         return this.save().then(returnToBrowse); | ||||
|         return this.save(); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
| @@ -169,15 +160,22 @@ function ( | ||||
|         } | ||||
|  | ||||
|         function saveAfterClone(clonedObject) { | ||||
|             return domainObject.getCapability("editor").save() | ||||
|                 .then(resolveWith(clonedObject)); | ||||
|             return this.openmct.editor.save().then(() => { | ||||
|                 // Force mutation for search indexing | ||||
|                 return clonedObject; | ||||
|             }) | ||||
|         } | ||||
|  | ||||
|         function finishEditing(clonedObject) { | ||||
|             return domainObject.getCapability("editor").finish() | ||||
|                 .then(function () { | ||||
|                     return fetchObject(clonedObject.getId()); | ||||
|                 }); | ||||
|             return fetchObject(clonedObject.getId()) | ||||
|         } | ||||
|  | ||||
|         function indexForSearch(savedObject) { | ||||
|             savedObject.useCapability('mutation', (model) => { | ||||
|                 return model; | ||||
|             }); | ||||
|  | ||||
|             return savedObject; | ||||
|         } | ||||
|  | ||||
|         function onSuccess(object) { | ||||
| @@ -190,7 +188,7 @@ function ( | ||||
|             if (reason !== "user canceled") { | ||||
|                 self.notificationService.error("Save Failed"); | ||||
|             } | ||||
|             return false; | ||||
|             throw reason; | ||||
|         } | ||||
|  | ||||
|         return getParent(domainObject) | ||||
| @@ -201,6 +199,7 @@ function ( | ||||
|             .then(undirtyOriginals) | ||||
|             .then(saveAfterClone) | ||||
|             .then(finishEditing) | ||||
|             .then(indexForSearch) | ||||
|             .then(hideBlockingDialog) | ||||
|             .then(onSuccess) | ||||
|             .catch(onFailure); | ||||
|   | ||||
| @@ -65,24 +65,40 @@ define( | ||||
|         CreateAction.prototype.perform = function () { | ||||
|             var newModel = this.type.getInitialModel(), | ||||
|                 openmct = this.openmct, | ||||
|                 newObject, | ||||
|                 editAction; | ||||
|  | ||||
|             function onSave() { | ||||
|                 openmct.editor.save(); | ||||
|             } | ||||
|                 newObject; | ||||
|  | ||||
|             function onCancel() { | ||||
|                 openmct.editor.cancel(); | ||||
|             } | ||||
|  | ||||
|             function isFirstViewEditable(domainObject) { | ||||
|                 let firstView = openmct.objectViews.get(domainObject)[0]; | ||||
|  | ||||
|                 return firstView && firstView.canEdit && firstView.canEdit(domainObject); | ||||
|             } | ||||
|  | ||||
|             function navigateAndEdit(object) { | ||||
|                 let objectPath = object.getCapability('context').getPath(), | ||||
|                     url = '#/browse/' + objectPath | ||||
|                         .slice(1) | ||||
|                         .map(function (o) { | ||||
|                             return o && openmct.objects.makeKeyString(o.getId()); | ||||
|                         }) | ||||
|                         .join('/'); | ||||
|  | ||||
|                 window.location.href = url; | ||||
|  | ||||
|                 if (isFirstViewEditable(object.useCapability('adapter'))) { | ||||
|                     openmct.editor.edit(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             newModel.type = this.type.getKey(); | ||||
|             newModel.location = this.parent.getId(); | ||||
|             newObject = this.parent.useCapability('instantiation', newModel); | ||||
|  | ||||
|             openmct.editor.edit(); | ||||
|             editAction = newObject.getCapability("action").getActions("edit")[0]; | ||||
|             newObject.getCapability("action").perform("save-as").then(onSave, onCancel); | ||||
|             newObject.getCapability("action").perform("save-as").then(navigateAndEdit, onCancel); | ||||
|             // TODO: support editing object without saving object first. | ||||
|             // Which means we have to toggle createwizard afterwards.  For now, | ||||
|             // We will disable this. | ||||
|   | ||||
| @@ -66,7 +66,7 @@ define( | ||||
|                 name: "Properties", | ||||
|                 rows: this.properties.map(function (property, index) { | ||||
|                     // Property definition is same as form row definition | ||||
|                     var row = Object.create(property.getDefinition()); | ||||
|                     var row = JSON.parse(JSON.stringify(property.getDefinition())); | ||||
|  | ||||
|                     // Use index as the key into the formValue; | ||||
|                     // this correlates to the indexing provided by | ||||
|   | ||||
| @@ -1,111 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * Policy controlling when the `edit` and/or `properties` actions | ||||
|          * can appear as applicable actions of the `view-control` category | ||||
|          * (shown as buttons in the top-right of browse mode.) | ||||
|          * @memberof platform/commonUI/edit | ||||
|          * @constructor | ||||
|          * @implements {Policy.<Action, ActionContext>} | ||||
|          */ | ||||
|         function EditActionPolicy(policyService) { | ||||
|             this.policyService = policyService; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Get a count of views which are not flagged as non-editable. | ||||
|          * @private | ||||
|          */ | ||||
|         EditActionPolicy.prototype.countEditableViews = function (context) { | ||||
|             var domainObject = context.domainObject, | ||||
|                 count = 0, | ||||
|                 type, views; | ||||
|  | ||||
|             if (!domainObject) { | ||||
|                 return count; | ||||
|             } | ||||
|  | ||||
|             type = domainObject.getCapability('type'); | ||||
|             views = domainObject.useCapability('view'); | ||||
|  | ||||
|  | ||||
|             // A view is editable unless explicitly flagged as not | ||||
|             (views || []).forEach(function (view) { | ||||
|                 if (isEditable(view) || | ||||
|                     (view.key === 'plot' && type.getKey() === 'telemetry.panel') || | ||||
|                     (view.key === 'table' && type.getKey() === 'table') || | ||||
|                     (view.key === 'rt-table' && type.getKey() === 'rttable') | ||||
|                 ) { | ||||
|                     count++; | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             function isEditable(view) { | ||||
|                 if (typeof view.editable === Function) { | ||||
|                     return view.editable(domainObject.useCapability('adapter')); | ||||
|                 } else { | ||||
|                     return view.editable === true; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return count; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the domain object is currently being edited. If | ||||
|          * so, the edit action is not applicable. | ||||
|          * @param context | ||||
|          * @returns {*|boolean} | ||||
|          */ | ||||
|         function isEditing(context) { | ||||
|             var domainObject = (context || {}).domainObject; | ||||
|             return domainObject && | ||||
|                 domainObject.hasCapability('editor') && | ||||
|                 domainObject.getCapability('editor').isEditContextRoot(); | ||||
|         } | ||||
|  | ||||
|         EditActionPolicy.prototype.allow = function (action, context) { | ||||
|             var key = action.getMetadata().key, | ||||
|                 category = (context || {}).category; | ||||
|  | ||||
|             // Restrict 'edit' to cases where there are editable | ||||
|             // views (similarly, restrict 'properties' to when | ||||
|             // the converse is true), and where the domain object is not | ||||
|             // already being edited. | ||||
|             if (key === 'edit') { | ||||
|                 return this.countEditableViews(context) > 0 && !isEditing(context); | ||||
|             } else if (key === 'properties' && category === 'view-control') { | ||||
|                 return this.countEditableViews(context) < 1 && !isEditing(context); | ||||
|             } | ||||
|  | ||||
|             // Like all policies, allow by default. | ||||
|             return true; | ||||
|         }; | ||||
|  | ||||
|         return EditActionPolicy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,49 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * Policy controlling which views should be visible in Edit mode. | ||||
|          * @memberof platform/commonUI/edit | ||||
|          * @constructor | ||||
|          * @implements {Policy.<View, DomainObject>} | ||||
|          */ | ||||
|         function EditableViewPolicy() { | ||||
|         } | ||||
|  | ||||
|         EditableViewPolicy.prototype.allow = function (view, domainObject) { | ||||
|             // If a view is flagged as non-editable, only allow it | ||||
|             // while we're not in Edit mode. | ||||
|             if ((view || {}).editable === false) { | ||||
|                 return !(domainObject.hasCapability('editor') && domainObject.getCapability('editor').inEditContext()); | ||||
|             } | ||||
|  | ||||
|             // Like all policies, allow by default. | ||||
|             return true; | ||||
|         }; | ||||
|  | ||||
|         return EditableViewPolicy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,138 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ["../../src/policies/EditActionPolicy"], | ||||
|     function (EditActionPolicy) { | ||||
|  | ||||
|         describe("The Edit action policy", function () { | ||||
|             var editableView, | ||||
|                 nonEditableView, | ||||
|                 testViews, | ||||
|                 testContext, | ||||
|                 mockDomainObject, | ||||
|                 mockEditAction, | ||||
|                 mockPropertiesAction, | ||||
|                 mockTypeCapability, | ||||
|                 mockEditorCapability, | ||||
|                 capabilities, | ||||
|                 plotView, | ||||
|                 policy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockDomainObject = jasmine.createSpyObj( | ||||
|                     'domainObject', | ||||
|                     [ | ||||
|                         'useCapability', | ||||
|                         'hasCapability', | ||||
|                         'getCapability' | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockEditorCapability = jasmine.createSpyObj('editorCapability', ['isEditContextRoot']); | ||||
|                 mockTypeCapability = jasmine.createSpyObj('type', ['getKey']); | ||||
|                 capabilities = { | ||||
|                     'editor': mockEditorCapability, | ||||
|                     'type': mockTypeCapability | ||||
|                 }; | ||||
|  | ||||
|                 mockEditAction = jasmine.createSpyObj('edit', ['getMetadata']); | ||||
|                 mockPropertiesAction = jasmine.createSpyObj('edit', ['getMetadata']); | ||||
|  | ||||
|                 mockDomainObject.getCapability.and.callFake(function (capability) { | ||||
|                     return capabilities[capability]; | ||||
|                 }); | ||||
|                 mockDomainObject.hasCapability.and.callFake(function (capability) { | ||||
|                     return !!capabilities[capability]; | ||||
|                 }); | ||||
|  | ||||
|                 editableView = { editable: true }; | ||||
|                 nonEditableView = { editable: false }; | ||||
|                 plotView = { key: "plot", editable: false }; | ||||
|                 testViews = []; | ||||
|  | ||||
|                 mockDomainObject.useCapability.and.callFake(function (c) { | ||||
|                     // Provide test views, only for the view capability | ||||
|                     return c === 'view' && testViews; | ||||
|                 }); | ||||
|  | ||||
|                 mockEditAction.getMetadata.and.returnValue({ key: 'edit' }); | ||||
|                 mockPropertiesAction.getMetadata.and.returnValue({ key: 'properties' }); | ||||
|  | ||||
|                 testContext = { | ||||
|                     domainObject: mockDomainObject, | ||||
|                     category: 'view-control' | ||||
|                 }; | ||||
|  | ||||
|                 policy = new EditActionPolicy(); | ||||
|             }); | ||||
|  | ||||
|             it("allows the edit action when there are editable views", function () { | ||||
|                 testViews = [editableView]; | ||||
|                 expect(policy.allow(mockEditAction, testContext)).toBe(true); | ||||
|             }); | ||||
|  | ||||
|             it("allows the edit properties action when there are no editable views", function () { | ||||
|                 testViews = [nonEditableView, nonEditableView]; | ||||
|                 expect(policy.allow(mockPropertiesAction, testContext)).toBe(true); | ||||
|             }); | ||||
|  | ||||
|             it("disallows the edit action when there are no editable views", function () { | ||||
|                 testViews = [nonEditableView, nonEditableView]; | ||||
|                 expect(policy.allow(mockEditAction, testContext)).toBe(false); | ||||
|             }); | ||||
|  | ||||
|             it("disallows the edit properties action when there are" + | ||||
|                 " editable views", function () { | ||||
|                 testViews = [editableView]; | ||||
|                 expect(policy.allow(mockPropertiesAction, testContext)).toBe(false); | ||||
|             }); | ||||
|  | ||||
|             it("disallows the edit action when object is already being" + | ||||
|                 " edited", function () { | ||||
|                 testViews = [editableView]; | ||||
|                 mockEditorCapability.isEditContextRoot.and.returnValue(true); | ||||
|                 expect(policy.allow(mockEditAction, testContext)).toBe(false); | ||||
|             }); | ||||
|  | ||||
|             it("allows editing of panels in plot view", function () { | ||||
|                 testViews = [plotView]; | ||||
|                 mockTypeCapability.getKey.and.returnValue('telemetry.panel'); | ||||
|  | ||||
|                 expect(policy.allow(mockEditAction, testContext)).toBe(true); | ||||
|             }); | ||||
|  | ||||
|             it("disallows editing of plot view when object not a panel type", function () { | ||||
|                 testViews = [plotView]; | ||||
|                 mockTypeCapability.getKey.and.returnValue('something.else'); | ||||
|  | ||||
|                 expect(policy.allow(mockEditAction, testContext)).toBe(false); | ||||
|             }); | ||||
|  | ||||
|  | ||||
|             it("allows the edit properties outside of the 'view-control' category", function () { | ||||
|                 testViews = [nonEditableView]; | ||||
|                 testContext.category = "something-else"; | ||||
|                 expect(policy.allow(mockPropertiesAction, testContext)).toBe(true); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,79 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ["../../src/policies/EditableViewPolicy"], | ||||
|     function (EditableViewPolicy) { | ||||
|  | ||||
|         describe("The editable view policy", function () { | ||||
|             var mockDomainObject, | ||||
|                 testMode, | ||||
|                 policy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testMode = true; // Act as if we're in Edit mode by default | ||||
|                 mockDomainObject = jasmine.createSpyObj( | ||||
|                     'domainObject', | ||||
|                     ['hasCapability', 'getCapability'] | ||||
|                 ); | ||||
|                 mockDomainObject.getCapability.and.returnValue({ | ||||
|                     inEditContext: function () { | ||||
|                         return true; | ||||
|                     } | ||||
|                 }); | ||||
|                 mockDomainObject.hasCapability.and.callFake(function (c) { | ||||
|                     return (c === 'editor') && testMode; | ||||
|                 }); | ||||
|  | ||||
|                 policy = new EditableViewPolicy(); | ||||
|             }); | ||||
|  | ||||
|             it("disallows views in edit mode that are flagged as non-editable", function () { | ||||
|                 expect(policy.allow({ editable: false }, mockDomainObject)) | ||||
|                     .toBeFalsy(); | ||||
|             }); | ||||
|  | ||||
|             it("allows views in edit mode that are flagged as editable", function () { | ||||
|                 expect(policy.allow({ editable: true }, mockDomainObject)) | ||||
|                     .toBeTruthy(); | ||||
|             }); | ||||
|  | ||||
|             it("allows any view outside of edit mode", function () { | ||||
|                 var testViews = [ | ||||
|                     { editable: false }, | ||||
|                     { editable: true }, | ||||
|                     { someKey: "some value" } | ||||
|                 ]; | ||||
|                 testMode = false; // Act as if we're not in Edit mode | ||||
|  | ||||
|                 testViews.forEach(function (testView) { | ||||
|                     expect(policy.allow(testView, mockDomainObject)).toBeTruthy(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("treats views with no defined 'editable' property as editable", function () { | ||||
|                 expect(policy.allow({ someKey: "some value" }, mockDomainObject)) | ||||
|                     .toBeTruthy(); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -19,7 +19,7 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <div class="t-object-label l-flex-row flex-elem grows"> | ||||
|     <div class="t-item-icon flex-elem {{type.getCssClass()}}" ng-class="{ 'l-icon-link':location.isLink() }"></div> | ||||
|     <div class='t-title-label flex-elem grows'>{{model.name}}</div> | ||||
| <div class="c-object-label"> | ||||
|     <div class="c-object-label__type-icon {{type.getCssClass()}}" ng-class="{ 'l-icon-link':location.isLink() }"></div> | ||||
|     <div class='c-object-label__name'>{{model.name}}</div> | ||||
| </div> | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| <div ng-controller="BannerController" ng-show="active.notification" | ||||
|      class="l-message-banner s-message-banner {{active.notification.model.severity}}" ng-class="{ | ||||
|      class="c-message-banner {{active.notification.model.severity}}" ng-class="{ | ||||
|      'minimized': active.notification.model.minimized, | ||||
|      'new': !active.notification.model.minimized}" | ||||
|      ng-click="maximize(active.notification)"> | ||||
|     <span class="banner-elem label"> | ||||
|     <span class="c-message-banner__message"> | ||||
|         {{active.notification.model.title}} | ||||
|     </span> | ||||
|     <span ng-show="active.notification.model.progress !== undefined || active.notification.model.unknownProgress"> | ||||
|         <mct-include key="'progress-bar'" class="banner-elem" | ||||
|         <mct-include key="'progress-bar'" class="c-message-banner__progress-bar" | ||||
|                      ng-model="active.notification.model"> | ||||
|         </mct-include> | ||||
|     </span> | ||||
| @@ -16,5 +16,5 @@ | ||||
|        ng-click="action(active.notification.model.primaryOption.callback, $event)"> | ||||
|         {{active.notification.model.primaryOption.label}} | ||||
|     </a> | ||||
|     <a class="banner-elem close icon-x" ng-click="dismiss(active.notification, $event)"></a> | ||||
|     <button class="c-message-banner__close-button c-click-icon icon-x-in-circle" ng-click="dismiss(active.notification, $event)"></button> | ||||
| </div> | ||||
|   | ||||
| @@ -20,14 +20,11 @@ | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <span ng-controller="ToggleController as toggle"> | ||||
|     <span ng-controller="TreeNodeController as treeNode"> | ||||
|         <span | ||||
|             class="tree-item menus-to-left" | ||||
|             ng-class="{selected: treeNode.isSelected()}" | ||||
|             > | ||||
|             <span | ||||
|                 class='ui-symbol view-control flex-elem' | ||||
|                 ng-class="{ 'has-children': model.composition !== undefined, expanded: toggle.isActive() }" | ||||
|     <div class="u-contents" ng-controller="TreeNodeController as treeNode"> | ||||
|         <div class="c-tree__item menus-to-left" | ||||
|             ng-class="{selected: treeNode.isSelected()}"> | ||||
|             <span class='c-disclosure-triangle c-tree__item__view-control' | ||||
|                 ng-class="{ 'is-enabled': model.composition !== undefined, 'c-disclosure-triangle--expanded': toggle.isActive() }" | ||||
|                 ng-click="toggle.toggle(); treeNode.trackExpansion()" | ||||
|                 > | ||||
|             </span> | ||||
| @@ -39,19 +36,15 @@ | ||||
|                 ng-click="treeNode.select()" | ||||
|                 > | ||||
|             </mct-representation> | ||||
|         </span> | ||||
|         <span | ||||
|             class="tree-item-subtree" | ||||
|         </div> | ||||
|         <div class="u-contents" | ||||
|             ng-show="toggle.isActive()" | ||||
|             ng-if="model.composition !== undefined" | ||||
|             > | ||||
|  | ||||
|             ng-if="model.composition !== undefined"> | ||||
|             <mct-representation key="'subtree'" | ||||
|                                 ng-model="ngModel" | ||||
|                                 parameters="parameters" | ||||
|                                 mct-object="treeNode.hasBeenExpanded() && domainObject"> | ||||
|             </mct-representation> | ||||
|  | ||||
|         </span> | ||||
|     </span> | ||||
|         </div> | ||||
|     </div> | ||||
| </span> | ||||
|   | ||||
| @@ -19,8 +19,8 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <ul class="tree"> | ||||
|     <li> | ||||
| <ul class="c-tree"> | ||||
|     <li class="c-tree__item-h"> | ||||
|         <mct-representation key="'tree-node'" | ||||
|                             mct-object="domainObject" | ||||
|                             ng-model="ngModel" | ||||
|   | ||||
| @@ -1,4 +1,2 @@ | ||||
| <span class="tree-item menus-to-left"> | ||||
| </span> | ||||
| <span class="tree-item-subtree"> | ||||
| </span> | ||||
| <span class="c-tree__item js-tree__item"></span> | ||||
| <span class="c-tree__item-subtree"></span> | ||||
|   | ||||
| @@ -1,2 +1 @@ | ||||
| <span class='ui-symbol view-control flex-elem'> | ||||
| </span> | ||||
| <span class='c-disclosure-triangle c-tree__item__view-control'></span> | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| <span class="rep-object-label"> | ||||
|     <div class="t-object-label l-flex-row flex-elem grows"> | ||||
|         <div class="t-item-icon flex-elem"></div> | ||||
|         <div class='t-title-label flex-elem grows'></div> | ||||
|     </div> | ||||
| </span> | ||||
| <div class="rep-object-label c-object-label c-tree__item__label"> | ||||
|     <div class="c-object-label__type-icon c-tree__item__type-icon t-item-icon"></div> | ||||
|     <div class="c-object-label__name c-tree__item__name t-title-label"></div> | ||||
| </div> | ||||
|   | ||||
| @@ -54,6 +54,7 @@ define( | ||||
|                     if (isDestroyed) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     var removeSelectable = openmct.selection.selectable( | ||||
|                         element[0], | ||||
|                         scope.$eval(attrs.mctSelectable), | ||||
|   | ||||
| @@ -37,9 +37,9 @@ define([ | ||||
|         this.expanded = state; | ||||
|  | ||||
|         if (state) { | ||||
|             this.el.addClass('expanded'); | ||||
|             this.el.addClass('c-disclosure-triangle--expanded'); | ||||
|         } else { | ||||
|             this.el.removeClass('expanded'); | ||||
|             this.el.removeClass('c-disclosure-triangle--expanded'); | ||||
|         } | ||||
|  | ||||
|         this.callbacks.forEach(function (callback) { | ||||
|   | ||||
| @@ -28,7 +28,7 @@ define([ | ||||
| ], function ($, nodeTemplate, ToggleView, TreeLabelView) { | ||||
|  | ||||
|     function TreeNodeView(gestureService, subtreeFactory, selectFn, openmct) { | ||||
|         this.li = $('<li>'); | ||||
|         this.li = $('<li class="c-tree__item-h">'); | ||||
|         this.openmct = openmct; | ||||
|         this.statusClasses = []; | ||||
|  | ||||
| @@ -38,7 +38,7 @@ define([ | ||||
|                 if (!this.subtreeView) { | ||||
|                     this.subtreeView = subtreeFactory(); | ||||
|                     this.subtreeView.model(this.activeObject); | ||||
|                     this.li.find('.tree-item-subtree').eq(0) | ||||
|                     this.li.find('.c-tree__item-subtree').eq(0) | ||||
|                         .append($(this.subtreeView.elements())); | ||||
|                 } | ||||
|                 $(this.subtreeView.elements()).removeClass('hidden'); | ||||
| @@ -85,9 +85,9 @@ define([ | ||||
|             var obj = domainObject.useCapability('adapter'); | ||||
|             var hasComposition =  this.openmct.composition.get(obj) !== undefined; | ||||
|             if (hasComposition) { | ||||
|                 $(this.toggleView.elements()).removeClass('no-children'); | ||||
|                 $(this.toggleView.elements()).addClass('is-enabled'); | ||||
|             } else { | ||||
|                 $(this.toggleView.elements()).addClass('no-children'); | ||||
|                 $(this.toggleView.elements()).removeClass('is-enabled'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -120,7 +120,7 @@ define([ | ||||
|             selectedIdPath = getIdPath(domainObject); | ||||
|  | ||||
|         if (this.onSelectionPath) { | ||||
|             this.li.find('.tree-item').eq(0).removeClass('selected'); | ||||
|             this.li.find('.js-tree__item').eq(0).removeClass('is-selected'); | ||||
|             if (this.subtreeView) { | ||||
|                 this.subtreeView.value(undefined); | ||||
|             } | ||||
| @@ -136,7 +136,7 @@ define([ | ||||
|  | ||||
|         if (this.onSelectionPath) { | ||||
|             if (activeIdPath.length === selectedIdPath.length) { | ||||
|                 this.li.find('.tree-item').eq(0).addClass('selected'); | ||||
|                 this.li.find('.js-tree__item').eq(0).addClass('is-selected'); | ||||
|             } else { | ||||
|                 // Expand to reveal the selection | ||||
|                 this.toggleView.value(true); | ||||
|   | ||||
| @@ -27,7 +27,7 @@ define([ | ||||
| ], function ($, TreeNodeView, spinnerTemplate) { | ||||
|  | ||||
|     function TreeView(gestureService, openmct, selectFn) { | ||||
|         this.ul = $('<ul class="tree"></ul>'); | ||||
|         this.ul = $('<ul class="c-tree"></ul>'); | ||||
|         this.nodeViews = []; | ||||
|         this.callbacks = []; | ||||
|         this.selectFn = selectFn || this.value.bind(this); | ||||
|   | ||||
| @@ -43,12 +43,25 @@ define( | ||||
|              * Launch a dialog showing a list of current notifications. | ||||
|              */ | ||||
|             $scope.showNotificationsList = function () { | ||||
|                 let notificationsList = openmct.notifications.notifications.map(notification => { | ||||
|                     if (notification.model.severity === 'alert' || notification.model.severity === 'info') { | ||||
|                         notification.model.primaryOption = { | ||||
|                             label: 'Dismiss', | ||||
|                             callback: () => { | ||||
|                                 let currentIndex = notificationsList.indexOf(notification); | ||||
|                                 notification.dismiss(); | ||||
|                                 notificationsList.splice(currentIndex, 1); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     return notification; | ||||
|                 }) | ||||
|                 dialogService.getDialogResponse('overlay-message-list', { | ||||
|                     dialog: { | ||||
|                         title: "Messages", | ||||
|                         //Launch the message list dialog with the models | ||||
|                         // from the notifications | ||||
|                         messages: openmct.notifications.notifications | ||||
|                         messages: notificationsList | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|   | ||||
| @@ -19,16 +19,14 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <div class="l-time-display l-digital l-clock s-clock" ng-controller="ClockController as clock"> | ||||
| 	<div class="l-elem-wrapper"> | ||||
| 	    <span class="l-elem timezone"> | ||||
| 	        {{clock.zone()}} | ||||
| 	    </span> | ||||
| 	    <span class="l-elem value active"> | ||||
| 	        {{clock.text()}} | ||||
| 	    </span> | ||||
| 	    <span class="l-elem ampm"> | ||||
| 	        {{clock.ampm()}} | ||||
| 	    </span> | ||||
| <div class="c-clock l-time-display" ng-controller="ClockController as clock"> | ||||
| 	<div class="c-clock__timezone"> | ||||
| 		{{clock.zone()}} | ||||
| 	</div> | ||||
| 	<div class="c-clock__value"> | ||||
| 		{{clock.text()}} | ||||
| 	</div> | ||||
| 	<div class="c-clock__ampm"> | ||||
| 		{{clock.ampm()}} | ||||
| 	</div> | ||||
| </div> | ||||
|   | ||||
| @@ -19,21 +19,19 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <div class="l-time-display l-digital l-timer s-timer s-state-{{timer.timerState}}" ng-controller="TimerController as timer"> | ||||
| 	<div class="l-elem-wrapper l-flex-row"> | ||||
|         <div class="l-elem-wrapper l-flex-row controls"> | ||||
|             <a ng-click="timer.clickStopButton()" | ||||
|                title="Stop" | ||||
|                class="flex-elem s-icon-button t-btn-stop icon-box"></a> | ||||
|             <a ng-click="timer.clickButton()" | ||||
|                title="{{timer.buttonText()}}" | ||||
|                class="flex-elem s-icon-button t-btn-pauseplay {{timer.buttonCssClass()}}"></a> | ||||
|         </div> | ||||
| 	    <span class="flex-elem l-value {{timer.signClass()}}"> | ||||
| 	        <span class="value" | ||||
| 		        ng-class="{ active:timer.text() }">{{timer.text() || "--:--:--"}} | ||||
|             </span> | ||||
| 	    </span> | ||||
| 	    <span ng-controller="RefreshingController"></span> | ||||
| <div class="c-timer is-{{timer.timerState}}" ng-controller="TimerController as timer"> | ||||
|     <div class="c-timer__controls"> | ||||
|         <button ng-click="timer.clickStopButton()" | ||||
|                 ng-hide="timer.timerState == 'stopped'" | ||||
|                 title="Reset" | ||||
|                 class="c-timer__ctrl-reset c-icon-button c-icon-button--major icon-reset"></button> | ||||
|         <button ng-click="timer.clickButton()" | ||||
|                 title="{{timer.buttonText()}}" | ||||
|                 class="c-timer__ctrl-pause-play c-icon-button c-icon-button--major {{timer.buttonCssClass()}}"></button> | ||||
|     </div> | ||||
|     <div class="c-timer__direction {{timer.signClass()}}" | ||||
|         ng-hide="!timer.signClass()"></div> | ||||
| 	<div class="c-timer__value">{{timer.text() || "--:--:--"}} | ||||
| 	</div> | ||||
| 	<span class="c-timer__ng-controller u-contents" ng-controller="RefreshingController"></span> | ||||
| </div> | ||||
|   | ||||
| @@ -1,475 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     "./src/FixedController", | ||||
|     "./templates/fixed.html", | ||||
|     "./templates/frame.html", | ||||
|     "./templates/elements/telemetry.html", | ||||
|     "./templates/elements/box.html", | ||||
|     "./templates/elements/line.html", | ||||
|     "./templates/elements/text.html", | ||||
|     "./templates/elements/image.html", | ||||
|     "legacyRegistry" | ||||
| ], function ( | ||||
|     FixedController, | ||||
|     fixedTemplate, | ||||
|     frameTemplate, | ||||
|     telemetryTemplate, | ||||
|     boxTemplate, | ||||
|     lineTemplate, | ||||
|     textTemplate, | ||||
|     imageTemplate, | ||||
|     legacyRegistry     | ||||
| ) { | ||||
|     return function() { | ||||
|         return function (openmct) { | ||||
|             openmct.legacyRegistry.register("platform/features/fixed", { | ||||
|                 "name": "Fixed position components.", | ||||
|                 "description": "Plug in adding Fixed Position object type.", | ||||
|                 "extensions": { | ||||
|                     "views": [ | ||||
|                         { | ||||
|                             "key": "fixed-display", | ||||
|                             "name": "Fixed Position Display", | ||||
|                             "cssClass": "icon-box-with-dashed-lines", | ||||
|                             "type": "telemetry.fixed", | ||||
|                             "template": fixedTemplate, | ||||
|                             "uses": ["composition"], | ||||
|                             "editable": true | ||||
|                         } | ||||
|                     ], | ||||
|                     "templates": [ | ||||
|                         { | ||||
|                             "key": "fixed.telemetry", | ||||
|                             "template": telemetryTemplate | ||||
|                         }, | ||||
|                         { | ||||
|                             "key": "fixed.box", | ||||
|                             "template": boxTemplate | ||||
|                         }, | ||||
|                         { | ||||
|                             "key": "fixed.line", | ||||
|                             "template": lineTemplate | ||||
|                         }, | ||||
|                         { | ||||
|                             "key": "fixed.text", | ||||
|                             "template": textTemplate | ||||
|                         }, | ||||
|                         { | ||||
|                             "key": "fixed.image", | ||||
|                             "template": imageTemplate | ||||
|                         } | ||||
|                     ], | ||||
|                     "controllers": [ | ||||
|                         { | ||||
|                             "key": "FixedController", | ||||
|                             "implementation": FixedController, | ||||
|                             "depends": [ | ||||
|                                 "$scope", | ||||
|                                 "$q", | ||||
|                                 "dialogService", | ||||
|                                 "openmct", | ||||
|                                 "$element" | ||||
|                             ] | ||||
|                         } | ||||
|                     ], | ||||
|                     "toolbars": [ | ||||
|                         { | ||||
|                             name: "Fixed Position Toolbar", | ||||
|                             key: "fixed.position", | ||||
|                             description: "Toolbar for the selected element inside a fixed position display.", | ||||
|                             forSelection: function (selection) { | ||||
|                                 if (!selection) { | ||||
|                                     return; | ||||
|                                 } | ||||
|                                  | ||||
|                                 return (openmct.editor.isEditing() && | ||||
|                                     selection[0] && selection[0].context.elementProxy && | ||||
|                                     ((selection[1] && selection[1].context.item.type === 'telemetry.fixed') || | ||||
|                                     (selection[0] && selection[0].context.item && selection[0].context.item.type === 'telemetry.fixed'))); | ||||
|                             }, | ||||
|                             toolbar: function (selection) { | ||||
|                                 var imageProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "url"]; | ||||
|                                 var boxProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill"]; | ||||
|                                 var textProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill", "color", "size", "text"]; | ||||
|                                 var lineProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "x2", "y2"]; | ||||
|                                 var telemetryProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill", "color", "size", "titled"]; | ||||
|                                 var fixedPageProperties = ["add"]; | ||||
|  | ||||
|                                 var properties = [], | ||||
|                                     fixedItem = selection[0] && selection[0].context.item, | ||||
|                                     elementProxy = selection[0] && selection[0].context.elementProxy, | ||||
|                                     domainObject = selection[1] && selection[1].context.item, | ||||
|                                     path; | ||||
|  | ||||
|                                 if (elementProxy) { | ||||
|                                     var type = elementProxy.element.type; | ||||
|                                     path = "configuration['fixed-display'].elements[" + elementProxy.index + "]"; | ||||
|                                     properties = | ||||
|                                         type === 'fixed.image' ? imageProperties : | ||||
|                                             type === 'fixed.text' ? textProperties : | ||||
|                                                 type === 'fixed.box' ? boxProperties : | ||||
|                                                     type === 'fixed.line' ? lineProperties : | ||||
|                                                         type === 'fixed.telemetry' ? telemetryProperties : []; | ||||
|                                 } else if (fixedItem) { | ||||
|                                     properties = domainObject && domainObject.type === 'layout' ? [] : fixedPageProperties; | ||||
|                                 } | ||||
|  | ||||
|                                 return [ | ||||
|                                     { | ||||
|                                         control: "menu", | ||||
|                                         domainObject: domainObject || selection[0].context.item, | ||||
|                                         method: function (option) { | ||||
|                                             selection[0].context.fixedController.add(option.key); | ||||
|                                         }, | ||||
|                                         key: "add", | ||||
|                                         icon: "icon-plus", | ||||
|                                         label: "Add", | ||||
|                                         options: [ | ||||
|                                             { | ||||
|                                                 "name": "Box", | ||||
|                                                 "class": "icon-box", | ||||
|                                                 "key": "fixed.box" | ||||
|                                             }, | ||||
|                                             { | ||||
|                                                 "name": "Line", | ||||
|                                                 "class": "icon-line-horz", | ||||
|                                                 "key": "fixed.line" | ||||
|                                             }, | ||||
|                                             { | ||||
|                                                 "name": "Text", | ||||
|                                                 "class": "icon-T", | ||||
|                                                 "key": "fixed.text" | ||||
|                                             }, | ||||
|                                             { | ||||
|                                                 "name": "Image", | ||||
|                                                 "class": "icon-image", | ||||
|                                                 "key": "fixed.image" | ||||
|                                             } | ||||
|                                         ] | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "menu", | ||||
|                                         domainObject: domainObject, | ||||
|                                         method: function (option) { | ||||
|                                             console.log('option', option) | ||||
|                                             selection[0].context.fixedController.order( | ||||
|                                                 selection[0].context.elementProxy, | ||||
|                                                 option.key | ||||
|                                             ); | ||||
|                                         }, | ||||
|                                         key: "order", | ||||
|                                         icon: "icon-layers", | ||||
|                                         title: "Move the selected object above or below other objects", | ||||
|                                         options: [ | ||||
|                                             { | ||||
|                                                 "name": "Move to Top", | ||||
|                                                 "class": "icon-arrow-double-up", | ||||
|                                                 "key": "top" | ||||
|                                             }, | ||||
|                                             { | ||||
|                                                 "name": "Move Up", | ||||
|                                                 "class": "icon-arrow-up", | ||||
|                                                 "key": "up" | ||||
|                                             }, | ||||
|                                             { | ||||
|                                                 "name": "Move Down", | ||||
|                                                 "class": "icon-arrow-down", | ||||
|                                                 "key": "down" | ||||
|                                             }, | ||||
|                                             { | ||||
|                                                 "name": "Move to Bottom", | ||||
|                                                 "class": "icon-arrow-double-down", | ||||
|                                                 "key": "bottom" | ||||
|                                             } | ||||
|                                         ] | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "color-picker", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".fill", | ||||
|                                         icon: "icon-paint-bucket", | ||||
|                                         title: "Set fill color", | ||||
|                                         key: 'fill' | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "color-picker", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".stroke", | ||||
|                                         icon: "icon-line-horz", | ||||
|                                         title: "Set border color", | ||||
|                                         key: 'stroke' | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "button", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".url", | ||||
|                                         icon: "icon-image", | ||||
|                                         title: "Edit image properties", | ||||
|                                         key: 'url', | ||||
|                                         dialog: { | ||||
|                                             control: "input", | ||||
|                                             type: "text", | ||||
|                                             name: "Image URL", | ||||
|                                             class: "l-input-lg", | ||||
|                                             required: true | ||||
|                                         } | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "color-picker", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".color", | ||||
|                                         icon: "icon-T", | ||||
|                                         mandatory: true, | ||||
|                                         title: "Set text color", | ||||
|                                         key: 'color' | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "select-menu", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".size", | ||||
|                                         title: "Set text size", | ||||
|                                         key: 'size', | ||||
|                                         options: [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96].map(function (size) { | ||||
|                                             return { "value": size + "px"}; | ||||
|                                         }) | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "input", | ||||
|                                         type: "number", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".x", | ||||
|                                         label: "X", | ||||
|                                         title: "X position", | ||||
|                                         key: "x", | ||||
|                                         class: "l-input-sm", | ||||
|                                         min: "0" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "input", | ||||
|                                         type: "number", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".y", | ||||
|                                         label: "Y", | ||||
|                                         title: "Y position", | ||||
|                                         key: "y", | ||||
|                                         class: "l-input-sm", | ||||
|                                         min: "0" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "input", | ||||
|                                         type: "number", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".x", | ||||
|                                         label: "X1", | ||||
|                                         title: "X1 position", | ||||
|                                         key: "x1", | ||||
|                                         class: "l-input-sm", | ||||
|                                         min: "0" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "input", | ||||
|                                         type: "number", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".y", | ||||
|                                         label: "Y1", | ||||
|                                         title: "Y1 position", | ||||
|                                         key: "y1", | ||||
|                                         class: "l-input-sm", | ||||
|                                         min: "0" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "input", | ||||
|                                         type: "number", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".x2", | ||||
|                                         label: "X2", | ||||
|                                         title: "X2 position", | ||||
|                                         key: "x2", | ||||
|                                         class: "l-input-sm", | ||||
|                                         min: "0" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "input", | ||||
|                                         type: "number", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".y2", | ||||
|                                         label: "Y2", | ||||
|                                         title: "Y2 position", | ||||
|                                         key: "y2", | ||||
|                                         class: "l-input-sm", | ||||
|                                         min: "0" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "input", | ||||
|                                         type: "number", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".height", | ||||
|                                         label: "H", | ||||
|                                         title: "Resize object height", | ||||
|                                         key: "height", | ||||
|                                         class: "l-input-sm", | ||||
|                                         min: "1" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "input", | ||||
|                                         type: "number", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".width", | ||||
|                                         label: "W", | ||||
|                                         title: "Resize object width", | ||||
|                                         key: "width", | ||||
|                                         class: "l-input-sm", | ||||
|                                         min: "1" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "toggle-button", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".useGrid", | ||||
|                                         key: "useGrid", | ||||
|                                         options: [ | ||||
|                                             { | ||||
|                                                 value: true, | ||||
|                                                 icon: 'icon-grid-snap-to', | ||||
|                                                 title: 'Snap to grid' | ||||
|                                             }, | ||||
|                                             { | ||||
|                                                 value: false, | ||||
|                                                 icon: 'icon-grid-snap-no', | ||||
|                                                 title: "Do not snap to grid" | ||||
|                                             } | ||||
|                                         ] | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "button", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".text", | ||||
|                                         icon: "icon-gear", | ||||
|                                         title: "Edit text properties", | ||||
|                                         key: "text", | ||||
|                                         dialog: { | ||||
|                                             control: "input", | ||||
|                                             type: "text", | ||||
|                                             name: "Text", | ||||
|                                             required: true | ||||
|                                         } | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "toggle-button", | ||||
|                                         domainObject: domainObject, | ||||
|                                         property: path + ".titled", | ||||
|                                         key: "titled", | ||||
|                                         options: [ | ||||
|                                             { | ||||
|                                                 value: true, | ||||
|                                                 icon: 'icon-two-parts-both', | ||||
|                                                 title: 'Show label' | ||||
|                                             }, | ||||
|                                             { | ||||
|                                                 value: false, | ||||
|                                                 icon: 'icon-two-parts-one-only', | ||||
|                                                 title: "Hide label" | ||||
|                                             } | ||||
|                                         ] | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         control: "button", | ||||
|                                         domainObject: domainObject, | ||||
|                                         method: function () { | ||||
|                                             selection[0].context.fixedController.remove( | ||||
|                                                 selection[0].context.elementProxy | ||||
|                                             ); | ||||
|                                         }, | ||||
|                                         key: "remove", | ||||
|                                         icon: "icon-trash" | ||||
|                                     } | ||||
|                                 ].filter(function (item) { | ||||
|                                     var filtered; | ||||
|  | ||||
|                                     properties.forEach(function (property) { | ||||
|                                         if (item.property && item.key === property || | ||||
|                                             item.method && item.key === property) { | ||||
|                                             filtered = item; | ||||
|                                         } | ||||
|                                     }); | ||||
|  | ||||
|                                     return filtered; | ||||
|                                 }); | ||||
|                             } | ||||
|                         } | ||||
|                     ], | ||||
|                     "types": [ | ||||
|                         { | ||||
|                             "key": "telemetry.fixed", | ||||
|                             "name": "Fixed Position Display", | ||||
|                             "cssClass": "icon-box-with-dashed-lines", | ||||
|                             "description": "Collect and display telemetry elements in " + | ||||
|                             "alphanumeric format in a simple canvas workspace. " + | ||||
|                             "Elements can be positioned and sized. " + | ||||
|                             "Lines, boxes and images can be added as well.", | ||||
|                             "priority": 899, | ||||
|                             "delegates": [ | ||||
|                                 "telemetry" | ||||
|                             ], | ||||
|                             "features": "creation", | ||||
|                             "contains": [ | ||||
|                                 { | ||||
|                                     "has": "telemetry" | ||||
|                                 } | ||||
|                             ], | ||||
|                             "model": { | ||||
|                                 "layoutGrid": [64, 16], | ||||
|                                 "composition": [] | ||||
|                             }, | ||||
|                             "properties": [ | ||||
|                                 { | ||||
|                                     "name": "Layout Grid", | ||||
|                                     "control": "composite", | ||||
|                                     "items": [ | ||||
|                                         { | ||||
|                                             "name": "Horizontal grid (px)", | ||||
|                                             "control": "textfield", | ||||
|                                             "cssClass": "l-input-sm l-numeric" | ||||
|                                         }, | ||||
|                                         { | ||||
|                                             "name": "Vertical grid (px)", | ||||
|                                             "control": "textfield", | ||||
|                                             "cssClass": "l-input-sm l-numeric" | ||||
|                                         } | ||||
|                                     ], | ||||
|                                     "pattern": "^(\\d*[1-9]\\d*)?$", | ||||
|                                     "property": "layoutGrid", | ||||
|                                     "conversion": "number[]" | ||||
|                                 } | ||||
|                             ], | ||||
|                             "views": [ | ||||
|                                 "fixed-display" | ||||
|                             ] | ||||
|                         } | ||||
|                     ] | ||||
|                 } | ||||
|             }); | ||||
|             openmct.legacyRegistry.enable("platform/features/fixed"); | ||||
|         }            | ||||
|     } | ||||
| }); | ||||
| @@ -1,720 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'lodash', | ||||
|         './FixedProxy', | ||||
|         './elements/ElementProxies', | ||||
|         './FixedDragHandle', | ||||
|         '../../../../src/api/objects/object-utils' | ||||
|     ], | ||||
|     function ( | ||||
|         _, | ||||
|         FixedProxy, | ||||
|         ElementProxies, | ||||
|         FixedDragHandle, | ||||
|         objectUtils | ||||
|     ) { | ||||
|  | ||||
|         var DEFAULT_DIMENSIONS = [2, 1]; | ||||
|  | ||||
|         // Convert from element x/y/width/height to an | ||||
|         // appropriate ng-style argument, to position elements. | ||||
|         function convertPosition(elementProxy) { | ||||
|             if (elementProxy.getStyle) { | ||||
|                 return elementProxy.getStyle(); | ||||
|             } | ||||
|  | ||||
|             var gridSize = elementProxy.getGridSize(); | ||||
|  | ||||
|             // Multiply position/dimensions by grid size | ||||
|             return { | ||||
|                 left: (gridSize[0] * elementProxy.element.x) + 'px', | ||||
|                 top: (gridSize[1] * elementProxy.element.y) + 'px', | ||||
|                 width: (gridSize[0] * elementProxy.element.width) + 'px', | ||||
|                 height: (gridSize[1] * elementProxy.element.height) + 'px' | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * The FixedController is responsible for supporting the | ||||
|          * Fixed Position 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 FixedController($scope, $q, dialogService, openmct, $element) { | ||||
|             this.names = {}; // Cache names by ID | ||||
|             this.values = {}; // Cache values by ID | ||||
|             this.elementProxiesById = {}; | ||||
|             this.telemetryObjects = {}; | ||||
|             this.subscriptions = {}; | ||||
|             this.openmct = openmct; | ||||
|             this.$element = $element; | ||||
|             this.$scope = $scope; | ||||
|             this.dialogService = dialogService; | ||||
|             this.$q = $q; | ||||
|             this.newDomainObject = $scope.domainObject.useCapability('adapter'); | ||||
|             this.fixedViewSelectable = false; | ||||
|  | ||||
|             var self = this; | ||||
|             [ | ||||
|                 'digest', | ||||
|                 'fetchHistoricalData', | ||||
|                 'getTelemetry', | ||||
|                 'setDisplayedValue', | ||||
|                 'subscribeToObject', | ||||
|                 'unsubscribe', | ||||
|                 'updateView' | ||||
|             ].forEach(function (name) { | ||||
|                 self[name] = self[name].bind(self); | ||||
|             }); | ||||
|  | ||||
|             // Decorate an element for display | ||||
|             function makeProxyElement(element, index, elements) { | ||||
|                 var ElementProxy = ElementProxies[element.type], | ||||
|                     e = ElementProxy && new ElementProxy(element, index, elements, self.gridSize); | ||||
|  | ||||
|                 if (e) { | ||||
|                     // Provide a displayable position (convert from grid to px) | ||||
|                     e.style = convertPosition(e); | ||||
|                     // Template names are same as type names, presently | ||||
|                     e.template = element.type; | ||||
|                 } | ||||
|  | ||||
|                 return e; | ||||
|             } | ||||
|  | ||||
|             // Decorate elements in the current configuration | ||||
|             function refreshElements() { | ||||
|                 var elements = (((self.newDomainObject.configuration || {})['fixed-display'] || {}).elements || []); | ||||
|  | ||||
|                 // Create the new proxies... | ||||
|                 self.elementProxies = elements.map(makeProxyElement); | ||||
|  | ||||
|                 if (self.selectedElementProxy) { | ||||
|                     // If selection is not in array, select parent. | ||||
|                     // Otherwise, set the element to select after refresh. | ||||
|                     var index = elements.indexOf(self.selectedElementProxy.element); | ||||
|                     if (index === -1) { | ||||
|                         self.$element[0].click(); | ||||
|                     } else if (!self.elementToSelectAfterRefresh) { | ||||
|                         self.elementToSelectAfterRefresh = self.elementProxies[index].element; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // Finally, rebuild lists of elements by id to | ||||
|                 // facilitate faster update when new telemetry comes in. | ||||
|                 self.elementProxiesById = {}; | ||||
|                 self.elementProxies.forEach(function (elementProxy) { | ||||
|                     var id = elementProxy.id; | ||||
|                     if (elementProxy.element.type === 'fixed.telemetry') { | ||||
|                         // Provide it a cached name/value to avoid flashing | ||||
|                         elementProxy.name = self.names[id]; | ||||
|                         elementProxy.value = self.values[id]; | ||||
|                         self.elementProxiesById[id] = self.elementProxiesById[id] || []; | ||||
|                         self.elementProxiesById[id].push(elementProxy); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             // Trigger a new query for telemetry data | ||||
|             function updateDisplayBounds(bounds, isTick) { | ||||
|                 if (!isTick) { | ||||
|                     //Reset values | ||||
|                     self.values = {}; | ||||
|                     refreshElements(); | ||||
|  | ||||
|                     //Fetch new data | ||||
|                     Object.values(self.telemetryObjects).forEach(function (object) { | ||||
|                         self.fetchHistoricalData(object); | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Add an element to this view | ||||
|             function addElement(element) { | ||||
|                 var index; | ||||
|                 var elements = (((self.newDomainObject.configuration || {})['fixed-display'] || {}).elements || []); | ||||
|                 elements.push(element); | ||||
|  | ||||
|                 if (self.selectedElementProxy) { | ||||
|                     index = elements.indexOf(self.selectedElementProxy.element); | ||||
|                 } | ||||
|  | ||||
|                 self.mutate("configuration['fixed-display'].elements", elements); | ||||
|                 elements = (self.newDomainObject.configuration)['fixed-display'].elements || []; | ||||
|                 self.elementToSelectAfterRefresh = elements[elements.length - 1]; | ||||
|  | ||||
|                 if (self.selectedElementProxy) { | ||||
|                     // Update the selected element with the new | ||||
|                     // value since newDomainOject is mutated. | ||||
|                     self.selectedElementProxy.element = elements[index]; | ||||
|                 } | ||||
|                 refreshElements(); | ||||
|             } | ||||
|  | ||||
|             // Position a panel after a drop event | ||||
|             function handleDrop(e, id, position) { | ||||
|                 // Don't handle this event if it has already been handled | ||||
|                 if (e.defaultPrevented) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 e.preventDefault(); | ||||
|  | ||||
|                 // Store the position of this element. | ||||
|                 // color is set to "" to let the CSS theme determine the default color | ||||
|                 addElement({ | ||||
|                     type: "fixed.telemetry", | ||||
|                     x: Math.floor(position.x / self.gridSize[0]), | ||||
|                     y: Math.floor(position.y / self.gridSize[1]), | ||||
|                     id: id, | ||||
|                     stroke: "transparent", | ||||
|                     color: "", | ||||
|                     titled: true, | ||||
|                     width: DEFAULT_DIMENSIONS[0], | ||||
|                     height: DEFAULT_DIMENSIONS[1], | ||||
|                     useGrid: true | ||||
|                 }); | ||||
|  | ||||
|                 // Subscribe to the new object to get telemetry | ||||
|                 self.openmct.objects.get(id).then(function (object) { | ||||
|                     self.getTelemetry(object); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             this.elementProxies = []; | ||||
|             this.addElement = addElement; | ||||
|             this.refreshElements = refreshElements; | ||||
|             this.fixedProxy = new FixedProxy(this.addElement, this.$q, this.dialogService); | ||||
|  | ||||
|             this.composition = this.openmct.composition.get(this.newDomainObject); | ||||
|             this.composition.on('add', this.onCompositionAdd, this); | ||||
|             this.composition.on('remove', this.onCompositionRemove, this); | ||||
|             this.composition.load(); | ||||
|  | ||||
|             // Position panes where they are dropped | ||||
|             $scope.$on("mctDrop", handleDrop); | ||||
|  | ||||
|             $scope.$on("$destroy", this.destroy.bind(this)); | ||||
|  | ||||
|             // Respond to external bounds changes | ||||
|             this.openmct.time.on("bounds", updateDisplayBounds); | ||||
|  | ||||
|             this.openmct.selection.on('change', this.setSelection.bind(this)); | ||||
|             this.openmct.editor.on('isEditing', this.handleEditing.bind(this)); | ||||
|  | ||||
|             this.$element.on('click', this.bypassSelection.bind(this)); | ||||
|             this.unlisten = this.openmct.objects.observe(this.newDomainObject, '*', function (obj) { | ||||
|                 this.newDomainObject = JSON.parse(JSON.stringify(obj)); | ||||
|                 this.updateElementPositions(this.newDomainObject.layoutGrid); | ||||
|             }.bind(this)); | ||||
|  | ||||
|             this.updateElementPositions(this.newDomainObject.layoutGrid); | ||||
|             refreshElements(); | ||||
|         } | ||||
|  | ||||
|         FixedController.prototype.updateElementPositions = function (layoutGrid) { | ||||
|             this.gridSize = layoutGrid; | ||||
|  | ||||
|             this.elementProxies.forEach(function (elementProxy) { | ||||
|                 elementProxy.setGridSize(this.gridSize); | ||||
|                 elementProxy.style = convertPosition(elementProxy); | ||||
|             }.bind(this)); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.onCompositionAdd = function (object) { | ||||
|             this.getTelemetry(object); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.onCompositionRemove = function (identifier) { | ||||
|             // Defer mutation of newDomainObject to prevent mutating an | ||||
|             // outdated version since this is triggered by a composition change. | ||||
|             setTimeout(function () { | ||||
|                 var id = objectUtils.makeKeyString(identifier); | ||||
|                 var elements = this.newDomainObject.configuration['fixed-display'].elements || []; | ||||
|                 var newElements = elements.filter(function (proxy) { | ||||
|                     return proxy.id !== id; | ||||
|                 }); | ||||
|                 this.mutate("configuration['fixed-display'].elements", newElements); | ||||
|  | ||||
|                 if (this.subscriptions[id]) { | ||||
|                     this.subscriptions[id](); | ||||
|                     delete this.subscriptions[id]; | ||||
|                 } | ||||
|  | ||||
|                 delete this.telemetryObjects[id]; | ||||
|                 this.refreshElements(); | ||||
|             }.bind(this)); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Removes an element from the view. | ||||
|          * | ||||
|          * @param {Object} elementProxy the element proxy to remove. | ||||
|          */ | ||||
|         FixedController.prototype.remove = function (elementProxy) { | ||||
|             var element = elementProxy.element; | ||||
|             var elements = this.newDomainObject.configuration['fixed-display'].elements || []; | ||||
|             elements.splice(elements.indexOf(element), 1); | ||||
|  | ||||
|             if (element.type === 'fixed.telemetry') { | ||||
|                 this.newDomainObject.composition = this.newDomainObject.composition.filter(function (identifier) { | ||||
|                     return objectUtils.makeKeyString(identifier) !== element.id; | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             this.mutate("configuration['fixed-display'].elements", elements); | ||||
|             this.refreshElements(); | ||||
|  | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Adds a new element to the view. | ||||
|          * | ||||
|          * @param {string} type the type of element to add. Supported types are: | ||||
|          * `fixed.image` | ||||
|          * `fixed.box` | ||||
|          * `fixed.text` | ||||
|          * `fixed.line` | ||||
|          */ | ||||
|         FixedController.prototype.add = function (type) { | ||||
|             this.fixedProxy.add(type); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Change the display order of the element proxy. | ||||
|          */ | ||||
|         FixedController.prototype.order = function (elementProxy, position) { | ||||
|             var elements = elementProxy.order(position); | ||||
|  | ||||
|             // Find the selected element index in the updated array. | ||||
|             var selectedElemenetIndex = elements.indexOf(this.selectedElementProxy.element); | ||||
|  | ||||
|             this.mutate("configuration['fixed-display'].elements", elements); | ||||
|             elements = (this.newDomainObject.configuration)['fixed-display'].elements || []; | ||||
|  | ||||
|             // Update the selected element with the new | ||||
|             // value since newDomainOject is mutated. | ||||
|             this.selectedElementProxy.element = elements[selectedElemenetIndex]; | ||||
|             this.refreshElements(); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.generateDragHandle = function (elementProxy, elementHandle) { | ||||
|             var index = this.elementProxies.indexOf(elementProxy); | ||||
|  | ||||
|             if (elementHandle) { | ||||
|                 elementHandle.element = elementProxy.element; | ||||
|                 elementProxy = elementHandle; | ||||
|             } | ||||
|  | ||||
|             return new FixedDragHandle( | ||||
|                 elementProxy, | ||||
|                 "configuration['fixed-display'].elements[" + index + "]", | ||||
|                 this | ||||
|             ); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.generateDragHandles = function (elementProxy) { | ||||
|             return elementProxy.handles().map(function (handle) { | ||||
|                 return this.generateDragHandle(elementProxy, handle); | ||||
|             }, this); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.updateSelectionStyle = function () { | ||||
|             this.selectedElementProxy.style = convertPosition(this.selectedElementProxy); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.setSelection = function (selectable) { | ||||
|             var selection = selectable[0]; | ||||
|  | ||||
|             if (this.selectionListeners) { | ||||
|                 this.selectionListeners.forEach(function (l) { | ||||
|                     l(); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             this.selectionListeners = []; | ||||
|  | ||||
|             if (!selection) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (selection.context.elementProxy) { | ||||
|                 this.selectedElementProxy = selection.context.elementProxy; | ||||
|                 this.attachSelectionListeners(); | ||||
|                 this.mvHandle = this.generateDragHandle(this.selectedElementProxy); | ||||
|                 this.resizeHandles = this.generateDragHandles(this.selectedElementProxy); | ||||
|             } else { | ||||
|                 // Make fixed view selectable if it's not already. | ||||
|                 if (!this.fixedViewSelectable && selectable.length === 1) { | ||||
|                     this.fixedViewSelectable = true; | ||||
|                     selection.context.fixedController = this; | ||||
|                     this.openmct.selection.select(selection); | ||||
|                 } | ||||
|  | ||||
|                 this.resizeHandles = []; | ||||
|                 this.mvHandle = undefined; | ||||
|                 this.selectedElementProxy = undefined; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.attachSelectionListeners = function () { | ||||
|             var index = this.elementProxies.indexOf(this.selectedElementProxy); | ||||
|             var path = "configuration['fixed-display'].elements[" + index + "]"; | ||||
|  | ||||
|             this.selectionListeners.push(this.openmct.objects.observe(this.newDomainObject, path + ".useGrid", function (newValue) { | ||||
|                 if (this.selectedElementProxy.useGrid() !== newValue) { | ||||
|                     this.selectedElementProxy.useGrid(newValue); | ||||
|                     this.updateSelectionStyle(); | ||||
|                     this.openmct.objects.mutate(this.newDomainObject, path, this.selectedElementProxy.element); | ||||
|                 } | ||||
|             }.bind(this))); | ||||
|             [ | ||||
|                 "width", | ||||
|                 "height", | ||||
|                 "stroke", | ||||
|                 "fill", | ||||
|                 "x", | ||||
|                 "y", | ||||
|                 "x1", | ||||
|                 "y1", | ||||
|                 "x2", | ||||
|                 "y2", | ||||
|                 "color", | ||||
|                 "size", | ||||
|                 "text", | ||||
|                 "titled" | ||||
|             ].forEach(function (property) { | ||||
|                 this.selectionListeners.push(this.openmct.objects.observe(this.newDomainObject, path + "." + property, function (newValue) { | ||||
|                     this.selectedElementProxy.element[property] = newValue; | ||||
|                     this.updateSelectionStyle(); | ||||
|                 }.bind(this))); | ||||
|             }.bind(this)); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.destroy = function () { | ||||
|             this.unsubscribe(); | ||||
|             this.unlisten(); | ||||
|             this.openmct.time.off("bounds", this.updateDisplayBounds); | ||||
|             this.openmct.selection.off("change", this.setSelection); | ||||
|             this.composition.off('add', this.onCompositionAdd, this); | ||||
|             this.composition.off('remove', this.onCompositionRemove, this); | ||||
|             this.openmct.editor.off('isEditing', this.handleEditing, this); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * A rate-limited digest function. Caps digests at 60Hz | ||||
|          * @private | ||||
|          */ | ||||
|         FixedController.prototype.digest = function () { | ||||
|             var self = this; | ||||
|  | ||||
|             if (!this.digesting) { | ||||
|                 this.digesting = true; | ||||
|                 requestAnimationFrame(function () { | ||||
|                     self.$scope.$digest(); | ||||
|                     self.digesting = false; | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Unsubscribe all listeners | ||||
|          * @private | ||||
|          */ | ||||
|         FixedController.prototype.unsubscribe = function () { | ||||
|             Object.values(this.subscriptions).forEach(function (unsubscribeFunc) { | ||||
|                 unsubscribeFunc(); | ||||
|             }); | ||||
|             this.subscriptions = {}; | ||||
|             this.telemetryObjects = {}; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Subscribe to the given domain object | ||||
|          * @private | ||||
|          * @param {object} object  Domain object to subscribe to | ||||
|          * @returns {object} The provided object, for chaining. | ||||
|          */ | ||||
|         FixedController.prototype.subscribeToObject = function (object) { | ||||
|             var self = this; | ||||
|             var timeAPI = this.openmct.time; | ||||
|             var id = objectUtils.makeKeyString(object.identifier); | ||||
|             this.subscriptions[id] = self.openmct.telemetry.subscribe(object, function (datum) { | ||||
|                 if (timeAPI.clock() !== undefined) { | ||||
|                     self.updateView(object, datum); | ||||
|                 } | ||||
|             }, {}); | ||||
|  | ||||
|             return object; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Print the values from the given datum against the provided object in the view. | ||||
|          * @private | ||||
|          * @param {object} telemetryObject The domain object associated with the given telemetry data | ||||
|          * @param {object} datum The telemetry datum containing the values to print | ||||
|          */ | ||||
|         FixedController.prototype.updateView = function (telemetryObject, datum) { | ||||
|             var metadata = this.openmct.telemetry.getMetadata(telemetryObject); | ||||
|             var valueMetadata = this.chooseValueMetadataToDisplay(metadata); | ||||
|             var formattedTelemetryValue = this.getFormattedTelemetryValueForKey(valueMetadata, datum); | ||||
|             var limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject); | ||||
|             var alarm = limitEvaluator && limitEvaluator.evaluate(datum, valueMetadata); | ||||
|  | ||||
|             this.setDisplayedValue( | ||||
|                 telemetryObject, | ||||
|                 formattedTelemetryValue, | ||||
|                 alarm && alarm.cssClass | ||||
|             ); | ||||
|             this.digest(); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * @private | ||||
|          */ | ||||
|         FixedController.prototype.getFormattedTelemetryValueForKey = function (valueMetadata, datum) { | ||||
|             var formatter = this.openmct.telemetry.getValueFormatter(valueMetadata); | ||||
|  | ||||
|             return formatter.format(datum); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * @private | ||||
|          */ | ||||
|         FixedController.prototype.chooseValueMetadataToDisplay = function (metadata) { | ||||
|             // If there is a range value, show that preferentially | ||||
|             var valueMetadata = metadata.valuesForHints(['range'])[0]; | ||||
|  | ||||
|             // If no range is defined, default to the highest priority non time-domain data. | ||||
|             if (valueMetadata === undefined) { | ||||
|                 var valuesOrderedByPriority = metadata.values(); | ||||
|                 valueMetadata = valuesOrderedByPriority.filter(function (values) { | ||||
|                     return !(values.hints.domain); | ||||
|                 })[0]; | ||||
|             } | ||||
|  | ||||
|             return valueMetadata; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Request the last historical data point for the given domain object | ||||
|          * @param {object} object | ||||
|          * @returns {object} the provided object for chaining. | ||||
|          */ | ||||
|         FixedController.prototype.fetchHistoricalData = function (object) { | ||||
|             var bounds = this.openmct.time.bounds(); | ||||
|             var self = this; | ||||
|  | ||||
|             self.openmct.telemetry.request(object, {start: bounds.start, end: bounds.end, size: 1}) | ||||
|                 .then(function (data) { | ||||
|                     if (data.length > 0) { | ||||
|                         self.updateView(object, data[data.length - 1]); | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|             return object; | ||||
|         }; | ||||
|  | ||||
|  | ||||
|         /** | ||||
|          * Print a value to the onscreen element associated with a given telemetry object. | ||||
|          * @private | ||||
|          * @param {object} telemetryObject The telemetry object associated with the value | ||||
|          * @param {string | number} value The value to print to screen | ||||
|          * @param {string} [cssClass] an optional CSS class to apply to the onscreen element. | ||||
|          */ | ||||
|         FixedController.prototype.setDisplayedValue = function (telemetryObject, value, cssClass) { | ||||
|             var id = objectUtils.makeKeyString(telemetryObject.identifier); | ||||
|             var self = this; | ||||
|  | ||||
|             (self.elementProxiesById[id] || []).forEach(function (element) { | ||||
|                 self.names[id] = telemetryObject.name; | ||||
|                 self.values[id] = value; | ||||
|                 element.name = self.names[id]; | ||||
|                 element.value = self.values[id]; | ||||
|                 element.cssClass = cssClass; | ||||
|             }); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.getTelemetry = function (domainObject) { | ||||
|             var id = objectUtils.makeKeyString(domainObject.identifier); | ||||
|  | ||||
|             if (this.subscriptions[id]) { | ||||
|                 this.subscriptions[id](); | ||||
|                 delete this.subscriptions[id]; | ||||
|             } | ||||
|             delete this.telemetryObjects[id]; | ||||
|  | ||||
|             if (!this.openmct.telemetry.isTelemetryObject(domainObject)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Initialize display | ||||
|             this.telemetryObjects[id] = domainObject; | ||||
|             this.setDisplayedValue(domainObject, ""); | ||||
|  | ||||
|             return Promise.resolve(domainObject) | ||||
|                 .then(this.fetchHistoricalData) | ||||
|                 .then(this.subscribeToObject); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Get the size of the grid, in pixels. The returned array | ||||
|          * is in the form `[x, y]`. | ||||
|          * @returns {number[]} the grid size | ||||
|          * @memberof platform/features/layout.FixedController# | ||||
|          */ | ||||
|         FixedController.prototype.getGridSize = function () { | ||||
|             return this.gridSize; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Get an array of elements in this panel; these are | ||||
|          * decorated proxies for both selection and display. | ||||
|          * @returns {Array} elements in this panel | ||||
|          */ | ||||
|         FixedController.prototype.getElements = function () { | ||||
|             return this.elementProxies; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Checks if the element should be selected or not. | ||||
|          * | ||||
|          * @param elementProxy the element to check | ||||
|          * @returns {boolean} true if the element should be selected. | ||||
|          */ | ||||
|         FixedController.prototype.shouldSelect = function (elementProxy) { | ||||
|             if (elementProxy.element === this.elementToSelectAfterRefresh) { | ||||
|                 delete this.elementToSelectAfterRefresh; | ||||
|                 return true; | ||||
|             } else { | ||||
|                 return false; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Checks if an element is currently selected. | ||||
|          * | ||||
|          * @returns {boolean} true if an element is selected. | ||||
|          */ | ||||
|         FixedController.prototype.isElementSelected = function () { | ||||
|             return (this.selectedElementProxy) ? true : false; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Gets the style for the selected element. | ||||
|          * | ||||
|          * @returns {string} element style | ||||
|          */ | ||||
|         FixedController.prototype.getSelectedElementStyle = function () { | ||||
|             return (this.selectedElementProxy) ? this.selectedElementProxy.style : undefined; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Gets the selected element. | ||||
|          * | ||||
|          * @returns the selected element | ||||
|          */ | ||||
|         FixedController.prototype.getSelectedElement = function () { | ||||
|             return this.selectedElementProxy; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Prevents the event from bubbling up if drag is in progress. | ||||
|          */ | ||||
|         FixedController.prototype.bypassSelection = function ($event) { | ||||
|             if (this.dragInProgress) { | ||||
|                 if ($event) { | ||||
|                     $event.stopPropagation(); | ||||
|                 } | ||||
|                 return; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Get drag handles. | ||||
|          * @returns {platform/features/layout.FixedDragHandle[]} | ||||
|          *          drag handles for the current selection | ||||
|          */ | ||||
|         FixedController.prototype.handles = function () { | ||||
|             return this.resizeHandles; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Get the handle to handle dragging to reposition an element. | ||||
|          * @returns {platform/features/layout.FixedDragHandle} the drag handle | ||||
|          */ | ||||
|         FixedController.prototype.moveHandle = function () { | ||||
|             return this.mvHandle; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Gets the selection context. | ||||
|          * | ||||
|          * @param elementProxy the element proxy | ||||
|          * @returns {object} the context object which includes elementProxy | ||||
|          */ | ||||
|         FixedController.prototype.getContext = function (elementProxy) { | ||||
|             return { | ||||
|                 elementProxy: elementProxy, | ||||
|                 fixedController: this | ||||
|             }; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * End drag. | ||||
|          * | ||||
|          * @param handle the resize handle | ||||
|          */ | ||||
|         FixedController.prototype.endDrag = function (handle) { | ||||
|             this.dragInProgress = true; | ||||
|  | ||||
|             setTimeout(function () { | ||||
|                 this.dragInProgress = false; | ||||
|             }.bind(this), 0); | ||||
|  | ||||
|             if (handle) { | ||||
|                 handle.endDrag(); | ||||
|             } else { | ||||
|                 this.moveHandle().endDrag(); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.mutate = function (path, value) { | ||||
|             this.openmct.objects.mutate(this.newDomainObject, path, value); | ||||
|         }; | ||||
|  | ||||
|         FixedController.prototype.handleEditing = function (isEditing) { | ||||
|             // Listen for edit mode changes and update selection if necessary. | ||||
|             // Mainly to ensure fixedController is on the selection context when editing. | ||||
|             this.setSelection(this.openmct.selection.get()); | ||||
|         } | ||||
|  | ||||
|         return FixedController; | ||||
|     } | ||||
| ); | ||||
| @@ -1,110 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         // Drag handle dimensions | ||||
|         var DRAG_HANDLE_SIZE = [6, 6]; | ||||
|  | ||||
|         /** | ||||
|          * Template-displayable drag handle for an element in fixed | ||||
|          * position mode. | ||||
|          * | ||||
|          * @param elementHandle the element handle | ||||
|          * @param configPath the configuration path of an element | ||||
|          * @param {Object} fixedControl the fixed controller | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          */ | ||||
|         function FixedDragHandle(elementHandle, configPath, fixedControl) { | ||||
|             this.elementHandle = elementHandle; | ||||
|             this.configPath = configPath; | ||||
|             this.fixedControl = fixedControl; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Get a CSS style to position this drag handle. | ||||
|          * | ||||
|          * @returns CSS style object (for `ng-style`) | ||||
|          * @memberof platform/features/layout.FixedDragHandle# | ||||
|          */ | ||||
|         FixedDragHandle.prototype.style = function () { | ||||
|             var gridSize = this.elementHandle.getGridSize(); | ||||
|  | ||||
|             // Adjust from grid to pixel coordinates | ||||
|             var x = this.elementHandle.x() * gridSize[0], | ||||
|                 y = this.elementHandle.y() * gridSize[1]; | ||||
|  | ||||
|             // Convert to a CSS style centered on that point | ||||
|             return { | ||||
|                 left: (x - DRAG_HANDLE_SIZE[0] / 2) + 'px', | ||||
|                 top: (y - DRAG_HANDLE_SIZE[1] / 2) + 'px', | ||||
|                 width: DRAG_HANDLE_SIZE[0] + 'px', | ||||
|                 height: DRAG_HANDLE_SIZE[1] + 'px' | ||||
|             }; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Start a drag gesture. This should be called when a drag | ||||
|          * begins to track initial state. | ||||
|          */ | ||||
|         FixedDragHandle.prototype.startDrag = function () { | ||||
|             // Cache initial x/y positions | ||||
|             this.dragging = { | ||||
|                 x: this.elementHandle.x(), | ||||
|                 y: this.elementHandle.y() | ||||
|             }; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Continue a drag gesture; update x/y positions. | ||||
|          * | ||||
|          * @param {number[]} delta x/y pixel difference since drag started | ||||
|          */ | ||||
|         FixedDragHandle.prototype.continueDrag = function (delta) { | ||||
|             var gridSize = this.elementHandle.getGridSize(); | ||||
|  | ||||
|             if (this.dragging) { | ||||
|                 // Update x/y positions (snapping to grid) | ||||
|                 var newX = this.dragging.x + Math.round(delta[0] / gridSize[0]); | ||||
|                 var newY = this.dragging.y + Math.round(delta[1] / gridSize[1]); | ||||
|  | ||||
|                 this.elementHandle.x(Math.max(0, newX)); | ||||
|                 this.elementHandle.y(Math.max(0, newY)); | ||||
|                 this.fixedControl.updateSelectionStyle(); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * End a drag gesture. This should be called when a drag | ||||
|          * concludes to trigger commit of changes. | ||||
|          */ | ||||
|         FixedDragHandle.prototype.endDrag = function () { | ||||
|             this.dragging = undefined; | ||||
|             this.fixedControl.mutate(this.configPath, this.elementHandle.element); | ||||
|         }; | ||||
|  | ||||
|         return FixedDragHandle; | ||||
|     } | ||||
| ); | ||||
| @@ -1,76 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./elements/ElementFactory'], | ||||
|     function (ElementFactory) { | ||||
|  | ||||
|         /** | ||||
|          * Proxy for configuring a fixed position view via the toolbar. | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param {Function} addElementCallback callback to invoke when | ||||
|          *        elements are created | ||||
|          * @param $q Angular's $q, for promise-handling | ||||
|          * @param {DialogService} dialogService dialog service to use | ||||
|          *        when adding a new element will require user input | ||||
|          */ | ||||
|         function FixedProxy(addElementCallback, $q, dialogService) { | ||||
|             this.factory = new ElementFactory(dialogService); | ||||
|             this.$q = $q; | ||||
|             this.addElementCallback = addElementCallback; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Add a new visual element to this view. Supported types are: | ||||
|          * | ||||
|          * * `fixed.image` | ||||
|          * * `fixed.box` | ||||
|          * * `fixed.text` | ||||
|          * * `fixed.line` | ||||
|          * | ||||
|          * @param {string} type the type of element to add | ||||
|          */ | ||||
|         FixedProxy.prototype.add = function (type) { | ||||
|             var addElementCallback = this.addElementCallback; | ||||
|  | ||||
|             // Place a configured element into the view configuration | ||||
|             function addElement(element) { | ||||
|                 // Configure common properties of the element | ||||
|                 element.x = element.x || 0; | ||||
|                 element.y = element.y || 0; | ||||
|                 element.width = element.width || 1; | ||||
|                 element.height = element.height || 1; | ||||
|                 element.type = type; | ||||
|                 element.useGrid = true; | ||||
|  | ||||
|                 // Finally, add it to the view's configuration | ||||
|                 addElementCallback(element); | ||||
|             } | ||||
|  | ||||
|             // Defer creation to the factory | ||||
|             this.$q.when(this.factory.createElement(type)).then(addElement); | ||||
|         }; | ||||
|  | ||||
|         return FixedProxy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,115 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * Handles drag interactions on frames in layouts. This will | ||||
|          * provides new positions/dimensions for frames based on | ||||
|          * relative pixel positions provided; these will take into account | ||||
|          * the grid size (in a snap-to sense) and will enforce some minimums | ||||
|          * on both position and dimensions. | ||||
|          * | ||||
|          * The provided position and dimensions factors will determine | ||||
|          * whether this is a move or a resize, and what type of resize it | ||||
|          * will be. For instance, a position factor of [1, 1] | ||||
|          * will move a frame along with the mouse as the drag | ||||
|          * proceeds, while a dimension factor of [0, 0] will leave | ||||
|          * dimensions unchanged. Combining these in different | ||||
|          * ways results in different handles; a position factor of | ||||
|          * [1, 0] and a dimensions factor of [-1, 0] will implement | ||||
|          * a left-edge resize, as the horizontal position will move | ||||
|          * with the mouse while the horizontal dimensions shrink in | ||||
|          * kind (and vertical properties remain unmodified.) | ||||
|          * | ||||
|          * @param {object} rawPosition the initial position/dimensions | ||||
|          *                 of the frame being interacted with | ||||
|          * @param {number[]} posFactor the position factor | ||||
|          * @param {number[]} dimFactor the dimensions factor | ||||
|          * @param {number[]} the size of each grid element, in pixels | ||||
|          * @constructor | ||||
|          * @memberof platform/features/layout | ||||
|          */ | ||||
|         function LayoutDrag(rawPosition, posFactor, dimFactor, gridSize) { | ||||
|             this.rawPosition = rawPosition; | ||||
|             this.posFactor = posFactor; | ||||
|             this.dimFactor = dimFactor; | ||||
|             this.gridSize = gridSize; | ||||
|         } | ||||
|  | ||||
|         // Convert a delta from pixel coordinates to grid coordinates, | ||||
|         // rounding to whole-number grid coordinates. | ||||
|         function toGridDelta(gridSize, pixelDelta) { | ||||
|             return pixelDelta.map(function (v, i) { | ||||
|                 return Math.round(v / gridSize[i]); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         // Utility function to perform element-by-element multiplication | ||||
|         function multiply(array, factors) { | ||||
|             return array.map(function (v, i) { | ||||
|                 return v * factors[i]; | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         // Utility function to perform element-by-element addition | ||||
|         function add(array, other) { | ||||
|             return array.map(function (v, i) { | ||||
|                 return v + other[i]; | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         // Utility function to perform element-by-element max-choosing | ||||
|         function max(array, other) { | ||||
|             return array.map(function (v, i) { | ||||
|                 return Math.max(v, other[i]); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /** | ||||
|          * Get a new position object in grid coordinates, with | ||||
|          * position and dimensions both offset appropriately | ||||
|          * according to the factors supplied in the constructor. | ||||
|          * @param {number[]} pixelDelta the offset from the | ||||
|          *        original position, in pixels | ||||
|          */ | ||||
|         LayoutDrag.prototype.getAdjustedPosition = function (pixelDelta) { | ||||
|             var gridDelta = toGridDelta(this.gridSize, pixelDelta); | ||||
|             return { | ||||
|                 position: max(add( | ||||
|                     this.rawPosition.position, | ||||
|                     multiply(gridDelta, this.posFactor) | ||||
|                 ), [0, 0]), | ||||
|                 dimensions: max(add( | ||||
|                     this.rawPosition.dimensions, | ||||
|                     multiply(gridDelta, this.dimFactor) | ||||
|                 ), [1, 1]) | ||||
|             }; | ||||
|         }; | ||||
|  | ||||
|         return LayoutDrag; | ||||
|  | ||||
|     } | ||||
| ); | ||||
| @@ -1,105 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2016, 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     'zepto', | ||||
|     '../../../commonUI/general/src/services/Overlay' | ||||
| ], function ( | ||||
|     $, | ||||
|     Overlay | ||||
| ) { | ||||
|     /** | ||||
|      * MCT Trigger Modal is intended for use in only one location: inside the | ||||
|      * object-header to allow views in a layout to be popped out in a modal. | ||||
|      * Users can close the modal and go back to normal, and everything generally | ||||
|      * just works fine. | ||||
|      * | ||||
|      * This code is sensitive to how our html is constructed-- particularly with | ||||
|      * how it locates the the container of an element in a layout. However, it | ||||
|      * should be able to handle slight relocations so long as it is always a | ||||
|      * descendent of a `.frame` element. | ||||
|      */ | ||||
|     function MCTTriggerModal($document) { | ||||
|  | ||||
|         function link($scope, $element) { | ||||
|             var actions = $scope.domainObject.getCapability('action'), | ||||
|                 notebookAction = actions.getActions({key: 'notebook-new-entry'})[0]; | ||||
|  | ||||
|             var frame = $element.parent(); | ||||
|  | ||||
|             for (var i = 0; i < 10; i++) { | ||||
|                 if (frame.hasClass('frame')) { | ||||
|                     break; | ||||
|                 } | ||||
|                 frame = frame.parent(); | ||||
|             } | ||||
|             if (!frame.hasClass('frame')) { | ||||
|                 $element.remove(); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             frame = frame[0]; | ||||
|  | ||||
|             var layoutContainer = frame.parentElement; | ||||
|  | ||||
|             var notebookButton = notebookAction ? | ||||
|                 [ | ||||
|                     { | ||||
|                         class: 'icon-notebook new-notebook-entry', | ||||
|                         title: 'New Notebook Entry', | ||||
|                         clickHandler: function (event) { | ||||
|                             event.stopPropagation(); | ||||
|                             notebookAction.perform(); | ||||
|                         } | ||||
|                     } | ||||
|                 ] : []; | ||||
|  | ||||
|             var overlayService = new Overlay ({ | ||||
|                 $document: $document, | ||||
|                 $scope: $scope, | ||||
|                 $element: frame, | ||||
|                 overlayWillMount: function () { | ||||
|                     $(frame).removeClass('frame frame-template'); | ||||
|                     layoutContainer.removeChild(frame); | ||||
|                 }, | ||||
|                 overlayDidUnmount: function () { | ||||
|                     $(frame).addClass('frame frame-template'); | ||||
|                     layoutContainer.appendChild(frame); | ||||
|                 }, | ||||
|                 browseBarButtons: notebookButton | ||||
|             }); | ||||
|  | ||||
|             $element.on('click', overlayService.toggleOverlay); | ||||
|             $scope.$on('$destroy', function () { | ||||
|                 $element.off('click', overlayService.toggleOverlay); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             restrict: 'A', | ||||
|             link: link | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     return MCTTriggerModal; | ||||
|  | ||||
| }); | ||||
| @@ -1,58 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * Utility function for creating getter-setter functions, | ||||
|          * since these are frequently useful for element proxies. | ||||
|          * | ||||
|          * An optional third argument may be supplied in order to | ||||
|          * constrain or modify arguments when using as a setter; | ||||
|          * this argument is a function which takes two arguments | ||||
|          * (the current value for the property, and the requested | ||||
|          * new value.) This is useful when values need to be kept | ||||
|          * in certain ranges; specifically, to keep x/y positions | ||||
|          * non-negative in a fixed position view. | ||||
|          * | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param {Object} object the object to get/set values upon | ||||
|          * @param {string} key the property to get/set | ||||
|          * @param {function} [updater] function used to process updates | ||||
|          */ | ||||
|         function AccessorMutator(object, key, updater) { | ||||
|             return function (value) { | ||||
|                 if (arguments.length > 0) { | ||||
|                     object[key] = updater ? | ||||
|                         updater(value, object[key]) : | ||||
|                         value; | ||||
|                 } | ||||
|                 return object[key]; | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return AccessorMutator; | ||||
|     } | ||||
| ); | ||||
| @@ -1,61 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./ElementProxy', './AccessorMutator'], | ||||
|     function (ElementProxy, AccessorMutator) { | ||||
|  | ||||
|         /** | ||||
|          * Selection proxy for Box elements in a fixed position view. | ||||
|          * Also serves as a superclass for Text elements, since those | ||||
|          * elements have a superset of Box properties. | ||||
|          * | ||||
|          * Note that arguments here are meant to match those expected | ||||
|          * by `Array.prototype.map` | ||||
|          * | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param element the fixed position element, as stored in its | ||||
|          *        configuration | ||||
|          * @param index the element's index within its array | ||||
|          * @param {number[]} gridSize the current layout grid size in [x,y] from | ||||
|          * @param {Array} elements the full array of elements | ||||
|          */ | ||||
|         function BoxProxy(element, index, elements, gridSize) { | ||||
|             var proxy = new ElementProxy(element, index, elements, gridSize); | ||||
|  | ||||
|             /** | ||||
|              * Get/set this element's fill color. (Omitting the | ||||
|              * argument makes this act as a getter.) | ||||
|              * @method | ||||
|              * @param {string} fill the new fill color | ||||
|              * @returns {string} the fill color | ||||
|              * @memberof platform/features/layout.BoxProxy# | ||||
|              */ | ||||
|             proxy.fill = new AccessorMutator(element, 'fill'); | ||||
|  | ||||
|             return proxy; | ||||
|         } | ||||
|  | ||||
|         return BoxProxy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,115 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         var INITIAL_STATES = { | ||||
|                 "fixed.image": { | ||||
|                     stroke: "transparent" | ||||
|                 }, | ||||
|                 "fixed.box": { | ||||
|                     fill: "#717171", | ||||
|                     border: "transparent", | ||||
|                     stroke: "transparent" | ||||
|                 }, | ||||
|                 "fixed.line": { | ||||
|                     x: 5, | ||||
|                     y: 9, | ||||
|                     x2: 6, | ||||
|                     y2: 6, | ||||
|                     stroke: "#717171" | ||||
|                 }, | ||||
|                 "fixed.text": { | ||||
|                     fill: "transparent", | ||||
|                     stroke: "transparent", | ||||
|                     size: "13px" | ||||
|                 } | ||||
|             }, | ||||
|             DIALOGS = { | ||||
|                 "fixed.image": { | ||||
|                     name: "Image Properties", | ||||
|                     sections: [ | ||||
|                         { | ||||
|                             rows: [ | ||||
|                                 { | ||||
|                                     key: "url", | ||||
|                                     control: "textfield", | ||||
|                                     name: "Image URL", | ||||
|                                     "cssClass": "l-input-lg", | ||||
|                                     required: true | ||||
|                                 } | ||||
|                             ] | ||||
|                         } | ||||
|                     ] | ||||
|                 }, | ||||
|                 "fixed.text": { | ||||
|                     name: "Text Element Properties", | ||||
|                     sections: [ | ||||
|                         { | ||||
|                             rows: [ | ||||
|                                 { | ||||
|                                     key: "text", | ||||
|                                     control: "textfield", | ||||
|                                     name: "Text", | ||||
|                                     required: true | ||||
|                                 } | ||||
|                             ] | ||||
|                         } | ||||
|                     ] | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|         /** | ||||
|          * The ElementFactory creates new instances of elements for the | ||||
|          * fixed position view, prompting for user input where necessary. | ||||
|          * @param {DialogService} dialogService service to request user input | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          */ | ||||
|         function ElementFactory(dialogService) { | ||||
|             this.dialogService = dialogService; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Create a new element for the fixed position view. | ||||
|          * @param {string} type the type of element to create | ||||
|          * @returns {Promise|object} the created element, or a promise | ||||
|          *          for that element | ||||
|          */ | ||||
|         ElementFactory.prototype.createElement = function (type) { | ||||
|             var initialState = INITIAL_STATES[type] || {}; | ||||
|  | ||||
|             // Clone that state | ||||
|             initialState = JSON.parse(JSON.stringify(initialState)); | ||||
|  | ||||
|             // Show a dialog to configure initial state, if appropriate | ||||
|             return DIALOGS[type] ? this.dialogService.getUserInput( | ||||
|                 DIALOGS[type], | ||||
|                 initialState | ||||
|             ) : initialState; | ||||
|         }; | ||||
|  | ||||
|         return ElementFactory; | ||||
|     } | ||||
| ); | ||||
| @@ -1,35 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./TelemetryProxy', './ImageProxy', './LineProxy', './BoxProxy', './TextProxy'], | ||||
|     function (TelemetryProxy, ImageProxy, LineProxy, BoxProxy, TextProxy) { | ||||
|  | ||||
|         return { | ||||
|             "fixed.telemetry": TelemetryProxy, | ||||
|             "fixed.line": LineProxy, | ||||
|             "fixed.box": BoxProxy, | ||||
|             "fixed.image": ImageProxy, | ||||
|             "fixed.text": TextProxy | ||||
|         }; | ||||
|     } | ||||
| ); | ||||
| @@ -1,209 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./AccessorMutator', './ResizeHandle', './UnitAccessorMutator'], | ||||
|     function (AccessorMutator, ResizeHandle, UnitAccessorMutator) { | ||||
|  | ||||
|         // Index deltas for changes in order | ||||
|         var ORDERS = { | ||||
|             top: Number.POSITIVE_INFINITY, | ||||
|             up: 1, | ||||
|             down: -1, | ||||
|             bottom: Number.NEGATIVE_INFINITY | ||||
|         }; | ||||
|  | ||||
|         // Mininmum pixel height and width for objects | ||||
|         var MIN_WIDTH = 10; | ||||
|         var MIN_HEIGHT = 10; | ||||
|  | ||||
|         // Ensure a value is non-negative (for x/y setters) | ||||
|         function clamp(value) { | ||||
|             return Math.max(value, 0); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Abstract superclass for other classes which provide useful | ||||
|          * interfaces upon an elements in a fixed position view. | ||||
|          * This handles the generic operations (e.g. remove) so that | ||||
|          * subclasses only need to implement element-specific behaviors. | ||||
|          * | ||||
|          * Note that arguments here are meant to match those expected | ||||
|          * by `Array.prototype.map` | ||||
|          * | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param element the fixed position element, as stored in its | ||||
|          *        configuration | ||||
|          * @param index the element's index within its array | ||||
|          * @param {Array} elements the full array of elements | ||||
|          * @param {number[]} gridSize the current layout grid size in [x,y] from | ||||
|          */ | ||||
|         function ElementProxy(element, index, elements, gridSize) { | ||||
|             /** | ||||
|              * The element as stored in the view configuration. | ||||
|              * @memberof platform/features/layout.ElementProxy# | ||||
|              */ | ||||
|             this.element = element; | ||||
|  | ||||
|             /** | ||||
|              * The current grid size of the layout. | ||||
|              * @memberof platform/features/layout.ElementProxy# | ||||
|              */ | ||||
|             this.gridSize = gridSize || [1,1]; //Ensure a reasonable default | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the x position of this element. | ||||
|              * Units are in fixed position grid space. | ||||
|              * @param {number} [x] the new x position (if setting) | ||||
|              * @returns {number} the x position | ||||
|              * @memberof platform/features/layout.ElementProxy# | ||||
|              */ | ||||
|             this.x = new AccessorMutator(element, 'x', clamp); | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the y position of this element. | ||||
|              * Units are in fixed position grid space. | ||||
|              * @param {number} [y] the new y position (if setting) | ||||
|              * @returns {number} the y position | ||||
|              * @memberof platform/features/layout.ElementProxy# | ||||
|              */ | ||||
|             this.y = new AccessorMutator(element, 'y', clamp); | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the stroke color of this element. | ||||
|              * @param {string} [stroke] the new stroke color (if setting) | ||||
|              * @returns {string} the stroke color | ||||
|              * @memberof platform/features/layout.ElementProxy# | ||||
|              */ | ||||
|             this.stroke = new AccessorMutator(element, 'stroke'); | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the width of this element. | ||||
|              * Units are in fixed position grid space. | ||||
|              * @param {number} [w] the new width (if setting) | ||||
|              * @returns {number} the width | ||||
|              * @memberof platform/features/layout.ElementProxy# | ||||
|              */ | ||||
|             this.width = new AccessorMutator(element, 'width'); | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the height of this element. | ||||
|              * Units are in fixed position grid space. | ||||
|              * @param {number} [h] the new height (if setting) | ||||
|              * @returns {number} the height | ||||
|              * @memberof platform/features/layout.ElementProxy# | ||||
|              */ | ||||
|             this.height = new AccessorMutator(element, 'height'); | ||||
|  | ||||
|             this.useGrid = new UnitAccessorMutator(this); | ||||
|             this.index = index; | ||||
|             this.elements = elements; | ||||
|             this.resizeHandles = [new ResizeHandle(this, this.element)]; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Change the display order of this element. | ||||
|          * @param {string} o where to move this element; | ||||
|          *        one of "top", "up", "down", or "bottom" | ||||
|          * @return {Array} the full array of elements | ||||
|          */ | ||||
|         ElementProxy.prototype.order = function (o) { | ||||
|             var index = this.index, | ||||
|                 elements = this.elements, | ||||
|                 element = this.element, | ||||
|                 delta = ORDERS[o] || 0, | ||||
|                 desired = Math.max( | ||||
|                     Math.min(index + delta, elements.length - 1), | ||||
|                     0 | ||||
|                 ); | ||||
|             // Move to the desired index, if this is a change | ||||
|             if ((desired !== index) && (elements[index] === element)) { | ||||
|                 // Splice out the current element | ||||
|                 elements.splice(index, 1); | ||||
|                 // Splice it back in at the correct index | ||||
|                 elements.splice(desired, 0, element); | ||||
|                 // Track change in index (proxy should be recreated | ||||
|                 // anyway, but be consistent) | ||||
|                 this.index = desired; | ||||
|             } | ||||
|  | ||||
|             return elements; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Get handles to control specific features of this element, | ||||
|          * e.g. corner size. | ||||
|          * @return {platform/features/layout.ElementHandle[]} handles | ||||
|          *         for moving/resizing this element | ||||
|          */ | ||||
|         ElementProxy.prototype.handles = function () { | ||||
|             return this.resizeHandles; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Returns which grid size the element is currently using. | ||||
|          * @return {number[]} The current grid size in [x,y] form if the element | ||||
|          *                    is currently using the grid, [1,1] if it is using | ||||
|          *                    pixels. | ||||
|          */ | ||||
|         ElementProxy.prototype.getGridSize = function () { | ||||
|             var gridSize; | ||||
|             // Default to using the grid if useGrid was not defined | ||||
|             if (typeof this.element.useGrid === 'undefined') { | ||||
|                 this.element.useGrid = true; | ||||
|             } | ||||
|             if (this.element.useGrid) { | ||||
|                 gridSize = this.gridSize; | ||||
|             } else { | ||||
|                 gridSize = [1,1]; | ||||
|             } | ||||
|             return gridSize; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Set the current grid size stored by this element proxy | ||||
|          * @param {number[]} gridSize The current layout grid size in [x,y] form | ||||
|          */ | ||||
|         ElementProxy.prototype.setGridSize = function (gridSize) { | ||||
|             this.gridSize = gridSize; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Get the current minimum element width in grid units | ||||
|          * @return {number} The current minimum element width | ||||
|          */ | ||||
|         ElementProxy.prototype.getMinWidth = function () { | ||||
|             return Math.ceil(MIN_WIDTH / this.getGridSize()[0]); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Get the current minimum element height in grid units | ||||
|          * @return {number} The current minimum element height | ||||
|          */ | ||||
|         ElementProxy.prototype.getMinHeight = function () { | ||||
|             return Math.ceil(MIN_HEIGHT / this.getGridSize()[1]); | ||||
|         }; | ||||
|  | ||||
|         return ElementProxy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,58 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./ElementProxy', './AccessorMutator'], | ||||
|     function (ElementProxy, AccessorMutator) { | ||||
|  | ||||
|         /** | ||||
|          * Selection proxy for Image elements in a fixed position view. | ||||
|          * | ||||
|          * Note that arguments here are meant to match those expected | ||||
|          * by `Array.prototype.map` | ||||
|          * | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param element the fixed position element, as stored in its | ||||
|          *        configuration | ||||
|          * @param index the element's index within its array | ||||
|          * @param {Array} elements the full array of elements | ||||
|          * @param {number[]} gridSize the current layout grid size in [x,y] from | ||||
|          * @augments {platform/features/layout.ElementProxy} | ||||
|          */ | ||||
|         function ImageProxy(element, index, elements, gridSize) { | ||||
|             var proxy = new ElementProxy(element, index, elements, gridSize); | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the displayed text of this element. | ||||
|              * @param {string} [text] the new text (if setting) | ||||
|              * @returns {string} the text | ||||
|              * @memberof platform/features/layout.ImageProxy# | ||||
|              */ | ||||
|             proxy.url = new AccessorMutator(element, 'url'); | ||||
|  | ||||
|             return proxy; | ||||
|         } | ||||
|  | ||||
|         return ImageProxy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,94 +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. | ||||
|  *****************************************************************************/ | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * Handle for changing x/y position of a line's end point. | ||||
|          * This is used to support drag handles for line elements | ||||
|          * in a fixed position view. Field names for opposite ends | ||||
|          * are provided to avoid zero-length lines. | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param element the line element | ||||
|          * @param {string} xProperty field which stores x position | ||||
|          * @param {string} yProperty field which stores y position | ||||
|          * @param {string} xOther field which stores x of other end | ||||
|          * @param {string} yOther field which stores y of other end | ||||
|          * @implements {platform/features/layout.ElementHandle} | ||||
|          */ | ||||
|         function LineHandle(element, elementProxy, xProperty, yProperty, xOther, yOther) { | ||||
|             this.elementProxy = elementProxy; | ||||
|             this.element = element; | ||||
|             this.xProperty = xProperty; | ||||
|             this.yProperty = yProperty; | ||||
|             this.xOther = xOther; | ||||
|             this.yOther = yOther; | ||||
|         } | ||||
|  | ||||
|         LineHandle.prototype.x = function (value) { | ||||
|             var element = this.element, | ||||
|                 xProperty = this.xProperty, | ||||
|                 yProperty = this.yProperty, | ||||
|                 xOther = this.xOther, | ||||
|                 yOther = this.yOther; | ||||
|  | ||||
|             if (arguments.length > 0) { | ||||
|                 // Ensure we stay in view | ||||
|                 value = Math.max(value, 0); | ||||
|                 // Make sure end points will still be different | ||||
|                 if (element[yOther] !== element[yProperty] || | ||||
|                     element[xOther] !== value) { | ||||
|                     element[xProperty] = value; | ||||
|                 } | ||||
|             } | ||||
|             return element[xProperty]; | ||||
|         }; | ||||
|  | ||||
|         LineHandle.prototype.y = function (value) { | ||||
|             var element = this.element, | ||||
|                 xProperty = this.xProperty, | ||||
|                 yProperty = this.yProperty, | ||||
|                 xOther = this.xOther, | ||||
|                 yOther = this.yOther; | ||||
|  | ||||
|             if (arguments.length > 0) { | ||||
|                 // Ensure we stay in view | ||||
|                 value = Math.max(value, 0); | ||||
|                 // Make sure end points will still be different | ||||
|                 if (element[xOther] !== element[xProperty] || | ||||
|                     element[yOther] !== value) { | ||||
|                     element[yProperty] = value; | ||||
|                 } | ||||
|             } | ||||
|             return element[yProperty]; | ||||
|         }; | ||||
|  | ||||
|         LineHandle.prototype.getGridSize = function () { | ||||
|             return this.elementProxy.getGridSize(); | ||||
|         }; | ||||
|  | ||||
|         return LineHandle; | ||||
|  | ||||
|     } | ||||
| ); | ||||
| @@ -1,171 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./ElementProxy', './LineHandle', './AccessorMutator'], | ||||
|     function (ElementProxy, LineHandle, AccessorMutator) { | ||||
|  | ||||
|         /** | ||||
|          * Selection/diplay proxy for line elements of a fixed position | ||||
|          * view. | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param element the fixed position element, as stored in its | ||||
|          *        configuration | ||||
|          * @param index the element's index within its array | ||||
|          * @param {Array} elements the full array of elements | ||||
|          * @param {number[]} gridSize the current layout grid size in [x,y] from | ||||
|          * @augments {platform/features/layout.ElementProxy} | ||||
|          */ | ||||
|         function LineProxy(element, index, elements, gridSize) { | ||||
|             var proxy = new ElementProxy(element, index, elements, gridSize), | ||||
|                 handles = [ | ||||
|                     new LineHandle(element, proxy, 'x', 'y', 'x2', 'y2'), | ||||
|                     new LineHandle(element, proxy, 'x2', 'y2', 'x', 'y') | ||||
|                 ]; | ||||
|  | ||||
|             /** | ||||
|              * Gets style specific to line proxy. | ||||
|              */ | ||||
|             proxy.getStyle = function () { | ||||
|                 var layoutGridSize = proxy.getGridSize(); | ||||
|  | ||||
|                 return { | ||||
|                     left: (layoutGridSize[0] * proxy.x()) + 'px', | ||||
|                     top: (layoutGridSize[1] * proxy.y()) + 'px', | ||||
|                     width: (layoutGridSize[0] * proxy.width()) + 'px', | ||||
|                     height: (layoutGridSize[1] * proxy.height()) + 'px' | ||||
|                 }; | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get the top-left x coordinate, in grid space, of | ||||
|              * this line's bounding box. | ||||
|              * @returns {number} the x coordinate | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.x = function (v) { | ||||
|                 var x = Math.min(element.x, element.x2), | ||||
|                     delta = Math.max(v, 0) - x; | ||||
|                 if (arguments.length > 0 && delta) { | ||||
|                     element.x += delta; | ||||
|                     element.x2 += delta; | ||||
|                 } | ||||
|                 return x; | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get the top-left y coordinate, in grid space, of | ||||
|              * this line's bounding box. | ||||
|              * @returns {number} the y coordinate | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.y = function (v) { | ||||
|                 var y = Math.min(element.y, element.y2), | ||||
|                     delta = Math.max(v, 0) - y; | ||||
|                 if (arguments.length > 0 && delta) { | ||||
|                     element.y += delta; | ||||
|                     element.y2 += delta; | ||||
|                 } | ||||
|                 return y; | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get the width, in grid space, of | ||||
|              * this line's bounding box. | ||||
|              * @returns {number} the width | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.width = function () { | ||||
|                 return Math.max(Math.abs(element.x - element.x2), 1); | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get the height, in grid space, of | ||||
|              * this line's bounding box. | ||||
|              * @returns {number} the height | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.height = function () { | ||||
|                 return Math.max(Math.abs(element.y - element.y2), 1); | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get the x position, in grid units relative to | ||||
|              * the top-left corner, of the first point in this line | ||||
|              * segment. | ||||
|              * @returns {number} the x position of the first point | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.x1 = function () { | ||||
|                 return element.x - proxy.x(); | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get the y position, in grid units relative to | ||||
|              * the top-left corner, of the first point in this line | ||||
|              * segment. | ||||
|              * @returns {number} the y position of the first point | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.y1 = function () { | ||||
|                 return element.y - proxy.y(); | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get the x position, in grid units relative to | ||||
|              * the top-left corner, of the second point in this line | ||||
|              * segment. | ||||
|              * @returns {number} the x position of the second point | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.x2 = function () { | ||||
|                 return element.x2 - proxy.x(); | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get the y position, in grid units relative to | ||||
|              * the top-left corner, of the second point in this line | ||||
|              * segment. | ||||
|              * @returns {number} the y position of the second point | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.y2 = function () { | ||||
|                 return element.y2 - proxy.y(); | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Get element handles for changing the position of end | ||||
|              * points of this line. | ||||
|              * @returns {LineHandle[]} line handles for both end points | ||||
|              * @memberof platform/features/layout.LineProxy# | ||||
|              */ | ||||
|             proxy.handles = function () { | ||||
|                 return handles; | ||||
|             }; | ||||
|  | ||||
|             return proxy; | ||||
|         } | ||||
|  | ||||
|         return LineProxy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,72 +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. | ||||
|  *****************************************************************************/ | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * @interface platform/features/layout.ElementHandle | ||||
|          * @private | ||||
|          */ | ||||
|  | ||||
|         /** | ||||
|          * Handle for changing width/height properties of an element. | ||||
|          * This is used to support drag handles for different | ||||
|          * element types in a fixed position view. | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          */ | ||||
|         function ResizeHandle(elementProxy, element) { | ||||
|             this.elementProxy = elementProxy; | ||||
|             this.element = element; | ||||
|         } | ||||
|  | ||||
|         ResizeHandle.prototype.x = function (value) { | ||||
|             var element = this.element; | ||||
|             if (arguments.length > 0) { | ||||
|                 element.width = Math.max( | ||||
|                     this.elementProxy.getMinWidth(), | ||||
|                     value - element.x | ||||
|                 ); | ||||
|             } | ||||
|             return element.x + element.width; | ||||
|         }; | ||||
|  | ||||
|         ResizeHandle.prototype.y = function (value) { | ||||
|             var element = this.element; | ||||
|             if (arguments.length > 0) { | ||||
|                 element.height = Math.max( | ||||
|                     this.elementProxy.getMinHeight(), | ||||
|                     value - element.y | ||||
|                 ); | ||||
|             } | ||||
|             return element.y + element.height; | ||||
|         }; | ||||
|  | ||||
|         ResizeHandle.prototype.getGridSize = function () { | ||||
|             return this.elementProxy.getGridSize(); | ||||
|         }; | ||||
|  | ||||
|         return ResizeHandle; | ||||
|  | ||||
|     } | ||||
| ); | ||||
| @@ -1,56 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./TextProxy'], | ||||
|     function (TextProxy) { | ||||
|  | ||||
|         /** | ||||
|          * Selection proxy for telemetry elements in a fixed position view. | ||||
|          * | ||||
|          * Note that arguments here are meant to match those expected | ||||
|          * by `Array.prototype.map` | ||||
|          * | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param element the fixed position element, as stored in its | ||||
|          *        configuration | ||||
|          * @param index the element's index within its array | ||||
|          * @param {Array} elements the full array of elements | ||||
|          * @param {number[]} gridSize the current layout grid size in [x,y] form | ||||
|          * @augments {platform/features/layout.ElementProxy} | ||||
|          */ | ||||
|         function TelemetryProxy(element, index, elements, gridSize) { | ||||
|             var proxy = new TextProxy(element, index, elements, gridSize); | ||||
|  | ||||
|             // Expose the domain object identifier | ||||
|             proxy.id = element.id; | ||||
|  | ||||
|             // Don't expose text configuration | ||||
|             delete proxy.text; | ||||
|  | ||||
|             return proxy; | ||||
|         } | ||||
|  | ||||
|         return TelemetryProxy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,75 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./BoxProxy', './AccessorMutator'], | ||||
|     function (BoxProxy, AccessorMutator) { | ||||
|  | ||||
|         /** | ||||
|          * Selection proxy for Text elements in a fixed position view. | ||||
|          * | ||||
|          * Note that arguments here are meant to match those expected | ||||
|          * by `Array.prototype.map` | ||||
|          * | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param element the fixed position element, as stored in its | ||||
|          *        configuration | ||||
|          * @param index the element's index within its array | ||||
|          * @param {Array} elements the full array of elements | ||||
|          * @param {number[]} gridSize the current layout grid size in [x,y] from | ||||
|          * @augments {platform/features/layout.ElementProxy} | ||||
|          */ | ||||
|         function TextProxy(element, index, elements, gridSize) { | ||||
|             var proxy = new BoxProxy(element, index, elements, gridSize); | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the text color of this element. | ||||
|              * @param {string} [color] the new text color (if setting) | ||||
|              * @returns {string} the text color | ||||
|              * @memberof platform/features/layout.TextProxy# | ||||
|              */ | ||||
|             proxy.color = new AccessorMutator(element, 'color'); | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the displayed text of this element. | ||||
|              * @param {string} [text] the new text (if setting) | ||||
|              * @returns {string} the text | ||||
|              * @memberof platform/features/layout.TextProxy# | ||||
|              */ | ||||
|             proxy.text = new AccessorMutator(element, 'text'); | ||||
|  | ||||
|             /** | ||||
|              * Get and/or set the text size of this element. | ||||
|              * | ||||
|              * @param {string} [size] the new text size (if setting) | ||||
|              * @returns {string} the text size | ||||
|              * @memberof platform/features/layout.TextProxy# | ||||
|              */ | ||||
|             proxy.size = new AccessorMutator(element, 'size'); | ||||
|  | ||||
|             return proxy; | ||||
|         } | ||||
|  | ||||
|         return TextProxy; | ||||
|     } | ||||
| ); | ||||
| @@ -1,92 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * Variant of AccessorMutator to handle the specific case of updating | ||||
|          * useGrid, in order update the positions appropriately from within | ||||
|          * the scope of UnitAccessorMutator | ||||
|          * | ||||
|          * @memberof platform/features/layout | ||||
|          * @constructor | ||||
|          * @param {ElementProxy} proxy ElementProxy object to perform the update | ||||
|          *                             upon | ||||
|          */ | ||||
|         function UnitAccessorMutator(elementProxy) { | ||||
|             var self = this; | ||||
|  | ||||
|             this.elementProxy = elementProxy; | ||||
|             return function (useGrid) { | ||||
|                 var current = elementProxy.element.useGrid; | ||||
|                 if (arguments.length > 0) { | ||||
|                     elementProxy.element.useGrid = useGrid; | ||||
|                     if (useGrid && !current) { | ||||
|                         self.convertCoordsTo('grid'); | ||||
|                     } else if (!useGrid && current) { | ||||
|                         self.convertCoordsTo('px'); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 return elementProxy.element.useGrid; | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * For the elementProxy object called upon, convert its element's | ||||
|          * coordinates and size from pixels to grid units, or vice-versa. | ||||
|          * @param {string} unit When called with 'px', converts grid units to | ||||
|          *                      pixels; when called with 'grid', snaps element | ||||
|          *                      to grid units | ||||
|          */ | ||||
|         UnitAccessorMutator.prototype.convertCoordsTo = function (unit) { | ||||
|             var proxy = this.elementProxy, | ||||
|                 gridSize = proxy.gridSize, | ||||
|                 element = proxy.element, | ||||
|                 minWidth = proxy.getMinWidth(), | ||||
|                 minHeight = proxy.getMinHeight(); | ||||
|             if (unit === 'px') { | ||||
|                 element.x = element.x * gridSize[0]; | ||||
|                 element.y = element.y * gridSize[1]; | ||||
|                 element.width = element.width * gridSize[0]; | ||||
|                 element.height = element.height * gridSize[1]; | ||||
|                 if (element.x2 && element.y2) { | ||||
|                     element.x2 = element.x2 * gridSize[0]; | ||||
|                     element.y2 = element.y2 * gridSize[1]; | ||||
|                 } | ||||
|             } else if (unit === 'grid') { | ||||
|                 element.x = Math.round(element.x / gridSize[0]); | ||||
|                 element.y = Math.round(element.y / gridSize[1]); | ||||
|                 element.width = Math.max(Math.round(element.width / gridSize[0]), minWidth); | ||||
|                 element.height = Math.max(Math.round(element.height / gridSize[1]), minHeight); | ||||
|                 if (element.x2 && element.y2) { | ||||
|                     element.x2 = Math.round(element.x2 / gridSize[0]); | ||||
|                     element.y2 = Math.round(element.y2 / gridSize[1]); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         return UnitAccessorMutator; | ||||
|     } | ||||
| ); | ||||
| @@ -1,26 +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. | ||||
| --> | ||||
| <div | ||||
| 	class="l-fixed-position-box" | ||||
| 	ng-style="{ background: ngModel.fill(), border: '1px ' + ngModel.stroke() + ' solid' }" | ||||
| 	> | ||||
| </div> | ||||
| @@ -1,26 +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. | ||||
| --> | ||||
| <div | ||||
| 	ng-style="{ 'background-image': 'url(' + ngModel.element.url + ')', border: '1px solid ' + ngModel.stroke() }" | ||||
|     class="l-fixed-position-image" | ||||
| 	> | ||||
| </div> | ||||
| @@ -1,31 +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. | ||||
| --> | ||||
| <svg ng-attr-width="{{ngModel.getGridSize()[0] * ngModel.width()}}" | ||||
|      ng-attr-height="{{ngModel.getGridSize()[1] * ngModel.height()}}"> | ||||
|     <line ng-attr-x1="{{ngModel.getGridSize()[0] * ngModel.x1() + 1}}" | ||||
|           ng-attr-y1="{{ngModel.getGridSize()[1] * ngModel.y1() + 1}}" | ||||
|           ng-attr-x2="{{ngModel.getGridSize()[0] * ngModel.x2() + 1}}" | ||||
|           ng-attr-y2="{{ngModel.getGridSize()[1] * ngModel.y2() + 1}}" | ||||
|           ng-attr-stroke="{{ngModel.stroke()}}" | ||||
|           stroke-width="2"> | ||||
|     </line> | ||||
| </svg> | ||||
| Before Width: | Height: | Size: 1.5 KiB | 
| @@ -1,39 +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. | ||||
| --> | ||||
| <div | ||||
|     class="l-fixed-position-text l-telemetry" | ||||
|     ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color(), 'font-size': ngModel.size() }" | ||||
|     > | ||||
|     <span | ||||
|         class="l-elem l-value l-obj-val-format" | ||||
|         data-value="{{ngModel.value}}" | ||||
|         ng-class="ngModel.cssClass" | ||||
|         > | ||||
|         {{ngModel.value}} | ||||
|     </span> | ||||
|     <span | ||||
|         class="l-elem l-title" | ||||
|         ng-show="ngModel.element.titled" | ||||
|         > | ||||
|         {{ngModel.name}} | ||||
|     </span> | ||||
| </div> | ||||
| @@ -1,27 +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. | ||||
| --> | ||||
| <div | ||||
| 	class="l-fixed-position-text l-static-text" | ||||
| 	ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color(), 'font-size': ngModel.size() }" | ||||
| 	> | ||||
|     {{ngModel.element.text}} | ||||
| </div> | ||||
| @@ -1,62 +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. | ||||
| --> | ||||
| <div class="t-fixed-position l-fixed-position" | ||||
|      ng-controller="FixedController as controller"> | ||||
|  | ||||
|     <!-- Background grid --> | ||||
|     <div class="l-fixed-position__grid-holder l-grid-holder c-grid" ng-click="controller.bypassSelection($event)"> | ||||
|         <div class="c-grid__x l-grid l-grid-x" | ||||
|              ng-if="!controller.getGridSize()[0] < 3" | ||||
|              ng-style="{ 'background-size': controller.getGridSize() [0] + 'px 100%' }"></div> | ||||
|         <div class="c-grid__y l-grid l-grid-y" | ||||
|              ng-if="!controller.getGridSize()[1] < 3" | ||||
|              ng-style="{ 'background-size': '100% ' + controller.getGridSize() [1] + 'px' }"></div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- Fixed position elements --> | ||||
|     <div ng-repeat="element in controller.getElements()" | ||||
|          class="l-fixed-position-item s-selectable s-moveable is-selectable is-moveable" | ||||
|          ng-style="element.style" | ||||
|          mct-selectable="controller.getContext(element)" | ||||
|          mct-init-select="controller.shouldSelect(element)"> | ||||
|         <mct-include key="element.template" | ||||
|                      parameters="{ gridSize: controller.getGridSize() }" | ||||
|                      ng-model="element"> | ||||
|         </mct-include> | ||||
|     </div> | ||||
|     <!-- Selection highlight, handles --> | ||||
|     <span class="c-frame-edit" ng-if="controller.isElementSelected()"> | ||||
|         <div class="c-frame-edit__move" | ||||
|              mct-drag-down="controller.moveHandle().startDrag()" | ||||
|              mct-drag="controller.moveHandle().continueDrag(delta)" | ||||
|              mct-drag-up="controller.endDrag()" | ||||
|              ng-style="controller.getSelectedElementStyle()"> | ||||
|         </div> | ||||
|         <div ng-repeat="handle in controller.handles()" | ||||
|              class="c-frame-edit__handle c-frame-edit__handle--nwse" | ||||
|              ng-style="handle.style()" | ||||
|              mct-drag-down="handle.startDrag()" | ||||
|              mct-drag="handle.continueDrag(delta)" | ||||
|              mct-drag-up="controller.endDrag(handle)"> | ||||
|         </div> | ||||
|     </span> | ||||
| </div> | ||||
| @@ -1,49 +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. | ||||
| --> | ||||
| <div class="frame frame-template t-frame-inner abs has-local-controls t-object-type-{{ domainObject.getModel().type }}"> | ||||
|     <div class="abs object-browse-bar l-flex-row"> | ||||
|         <div class="left flex-elem l-flex-row grows"> | ||||
|             <mct-representation | ||||
|                     key="'object-header-frame'" | ||||
|                     mct-object="domainObject" | ||||
|                     class="l-flex-row flex-elem object-header grows"> | ||||
|             </mct-representation> | ||||
|         </div> | ||||
|         <div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed h-local-controls local-controls-hidden"> | ||||
|             <mct-representation | ||||
|                     key="'switcher'" | ||||
|                     ng-model="representation" | ||||
|                     mct-object="domainObject"> | ||||
|             </mct-representation> | ||||
|             <a class="s-button icon-expand t-btn-view-large" | ||||
|                title="View large" | ||||
|                mct-trigger-modal> | ||||
|             </a> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="abs object-holder"> | ||||
|         <mct-representation | ||||
|                 key="representation.selected.key" | ||||
|                 mct-object="representation.selected.key && domainObject"> | ||||
|         </mct-representation> | ||||
|     </div> | ||||
| </div> | ||||
| @@ -1,641 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         "../src/FixedController", | ||||
|         "zepto" | ||||
|     ], | ||||
|     function ( | ||||
|         FixedController, | ||||
|         $ | ||||
|     ) { | ||||
|  | ||||
|         describe("The Fixed Position controller", function () { | ||||
|             var mockScope, | ||||
|                 mockQ, | ||||
|                 mockDialogService, | ||||
|                 mockFormatter, | ||||
|                 mockDomainObject, | ||||
|                 mockEvent, | ||||
|                 testGrid, | ||||
|                 testModel, | ||||
|                 testConfiguration, | ||||
|                 mockOpenMCT, | ||||
|                 mockTelemetryAPI, | ||||
|                 mockCompositionAPI, | ||||
|                 mockCompositionCollection, | ||||
|                 mockChildren, | ||||
|                 mockConductor, | ||||
|                 mockMetadata, | ||||
|                 mockTimeSystem, | ||||
|                 mockLimitEvaluator, | ||||
|                 mockSelection, | ||||
|                 mockObjects, | ||||
|                 mockNewDomainObject, | ||||
|                 unlistenFunc, | ||||
|                 $element = [], | ||||
|                 selectable = [], | ||||
|                 controller; | ||||
|  | ||||
|             // Utility function; find a $on calls for a given expression. | ||||
|             function findOn(expr) { | ||||
|                 var on; | ||||
|                 mockScope.$on.calls.all().forEach(function (call) { | ||||
|                     if (call.args[0] === expr) { | ||||
|                         on = call.args[1]; | ||||
|                     } | ||||
|                 }); | ||||
|                 return on; | ||||
|             } | ||||
|  | ||||
|             function makeMockDomainObject(id) { | ||||
|                 return { | ||||
|                     identifier: { | ||||
|                         key: "domainObject-" + id, | ||||
|                         namespace: "" | ||||
|                     }, | ||||
|                     name: "Point " + id | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockScope = jasmine.createSpyObj( | ||||
|                     '$scope', | ||||
|                     ["$on", "$watch", "$digest", "commit"] | ||||
|                 ); | ||||
|                 mockQ = jasmine.createSpyObj('$q', ['when']); | ||||
|                 mockDialogService = jasmine.createSpyObj( | ||||
|                     'dialogService', | ||||
|                     ['getUserInput'] | ||||
|                 ); | ||||
|                 mockFormatter = jasmine.createSpyObj( | ||||
|                     'telemetryFormatter', | ||||
|                     ['format'] | ||||
|                 ); | ||||
|                 mockFormatter.format.and.callFake(function (valueMetadata) { | ||||
|                     return "Formatted " + valueMetadata.value; | ||||
|                 }); | ||||
|  | ||||
|                 mockConductor = jasmine.createSpyObj('conductor', [ | ||||
|                     'on', | ||||
|                     'off', | ||||
|                     'bounds', | ||||
|                     'timeSystem', | ||||
|                     'clock' | ||||
|                 ]); | ||||
|                 mockConductor.bounds.and.returnValue({}); | ||||
|                 mockTimeSystem = { | ||||
|                     metadata: { | ||||
|                         key: 'key' | ||||
|                     } | ||||
|                 }; | ||||
|                 mockConductor.timeSystem.and.returnValue(mockTimeSystem); | ||||
|  | ||||
|                 mockEvent = jasmine.createSpyObj( | ||||
|                     'event', | ||||
|                     ['preventDefault'] | ||||
|                 ); | ||||
|  | ||||
|                 mockTelemetryAPI = jasmine.createSpyObj('telemetry', | ||||
|                     [ | ||||
|                         'subscribe', | ||||
|                         'request', | ||||
|                         'isTelemetryObject', | ||||
|                         'getMetadata', | ||||
|                         'limitEvaluator', | ||||
|                         'getValueFormatter' | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockTelemetryAPI.isTelemetryObject.and.returnValue(true); | ||||
|                 mockTelemetryAPI.request.and.returnValue(Promise.resolve([])); | ||||
|  | ||||
|                 testGrid = [123, 456]; | ||||
|                 testModel = { | ||||
|                     composition: ['a', 'b', 'c'], | ||||
|                     layoutGrid: testGrid | ||||
|                 }; | ||||
|                 testConfiguration = { elements: [ | ||||
|                     { type: "fixed.telemetry", id: 'a', x: 1, y: 1, useGrid: true}, | ||||
|                     { type: "fixed.telemetry", id: 'b', x: 1, y: 1, useGrid: true}, | ||||
|                     { type: "fixed.telemetry", id: 'c', x: 1, y: 1, useGrid: true} | ||||
|                 ]}; | ||||
|  | ||||
|                 mockChildren = testModel.composition.map(makeMockDomainObject); | ||||
|                 mockCompositionCollection = jasmine.createSpyObj('compositionCollection', [ | ||||
|                     'load', | ||||
|                     'on', | ||||
|                     'off' | ||||
|                 ]); | ||||
|                 mockCompositionAPI = jasmine.createSpyObj('composition', [ | ||||
|                     'get' | ||||
|                 ]); | ||||
|                 mockCompositionAPI.get.and.returnValue(mockCompositionCollection); | ||||
|                 mockCompositionCollection.load.and.returnValue( | ||||
|                     Promise.resolve(mockChildren) | ||||
|                 ); | ||||
|  | ||||
|                 mockScope.model = testModel; | ||||
|                 mockScope.configuration = testConfiguration; | ||||
|  | ||||
|                 mockNewDomainObject = jasmine.createSpyObj("newDomainObject", [ | ||||
|                     'layoutGrid', | ||||
|                     'configuration', | ||||
|                     'composition' | ||||
|                 ]); | ||||
|                 mockNewDomainObject.layoutGrid = testGrid; | ||||
|                 mockNewDomainObject.configuration = { | ||||
|                     'fixed-display': testConfiguration | ||||
|                 }; | ||||
|                 mockNewDomainObject.composition = ['a', 'b', 'c']; | ||||
|  | ||||
|                 mockDomainObject = jasmine.createSpyObj( | ||||
|                     'domainObject', | ||||
|                     ['getId', 'getModel', 'getCapability', 'useCapability'] | ||||
|                 ); | ||||
|                 mockDomainObject.useCapability.and.returnValue(mockNewDomainObject); | ||||
|                 mockScope.domainObject = mockDomainObject; | ||||
|  | ||||
|                 selectable[0] = { | ||||
|                     context: { | ||||
|                         oldItem: mockDomainObject | ||||
|                     } | ||||
|                 }; | ||||
|                 mockSelection = jasmine.createSpyObj("selection", [ | ||||
|                     'select', | ||||
|                     'on', | ||||
|                     'off', | ||||
|                     'get' | ||||
|                 ]); | ||||
|                 mockSelection.get.and.returnValue([]); | ||||
|  | ||||
|                 unlistenFunc = jasmine.createSpy("unlisten"); | ||||
|                 mockObjects = jasmine.createSpyObj('objects', [ | ||||
|                     'observe', | ||||
|                     'get' | ||||
|                 ]); | ||||
|                 mockObjects.observe.and.returnValue(unlistenFunc); | ||||
|  | ||||
|                 mockOpenMCT = { | ||||
|                     time: mockConductor, | ||||
|                     telemetry: mockTelemetryAPI, | ||||
|                     composition: mockCompositionAPI, | ||||
|                     selection: mockSelection, | ||||
|                     objects: mockObjects | ||||
|                 }; | ||||
|  | ||||
|                 $element = $('<div></div>'); | ||||
|                 spyOn($element[0], 'click'); | ||||
|  | ||||
|                 mockMetadata = jasmine.createSpyObj('mockMetadata', [ | ||||
|                     'valuesForHints', | ||||
|                     'value', | ||||
|                     'values' | ||||
|                 ]); | ||||
|                 mockMetadata.value.and.returnValue({ | ||||
|                     key: 'value' | ||||
|                 }); | ||||
|  | ||||
|                 mockMetadata.valuesForHints.and.callFake(function (hints) { | ||||
|                     if (hints === ['domain']) { | ||||
|                         return [{ | ||||
|                             key: 'time' | ||||
|                         }]; | ||||
|                     } else { | ||||
|                         return [{ | ||||
|                             key: 'value' | ||||
|                         }]; | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 mockLimitEvaluator = jasmine.createSpyObj('limitEvaluator', [ | ||||
|                     'evaluate' | ||||
|                 ]); | ||||
|  | ||||
|                 mockLimitEvaluator.evaluate.and.returnValue({}); | ||||
|  | ||||
|                 mockTelemetryAPI.getMetadata.and.returnValue(mockMetadata); | ||||
|                 mockTelemetryAPI.limitEvaluator.and.returnValue(mockLimitEvaluator); | ||||
|                 mockTelemetryAPI.getValueFormatter.and.returnValue(mockFormatter); | ||||
|  | ||||
|                 controller = new FixedController( | ||||
|                     mockScope, | ||||
|                     mockQ, | ||||
|                     mockDialogService, | ||||
|                     mockOpenMCT, | ||||
|                     $element | ||||
|                 ); | ||||
|                 spyOn(controller, "mutate"); | ||||
|             }); | ||||
|  | ||||
|             it("subscribes a domain object", function () { | ||||
|                 var object = makeMockDomainObject("mock"); | ||||
|  | ||||
|                 return controller.getTelemetry(object).then(function () { | ||||
|                     expect(mockTelemetryAPI.subscribe).toHaveBeenCalledWith( | ||||
|                         object, | ||||
|                         jasmine.any(Function), | ||||
|                         jasmine.any(Object) | ||||
|                     ); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("releases subscription when a domain objects is removed", function () { | ||||
|                 var unsubscribe = jasmine.createSpy('unsubscribe'); | ||||
|                 var unsubscribePromise = new Promise(function (resolve) { | ||||
|                     unsubscribe.and.callFake(resolve); | ||||
|                 }); | ||||
|                 var object = makeMockDomainObject("mock"); | ||||
|  | ||||
|                 mockTelemetryAPI.subscribe.and.returnValue(unsubscribe); | ||||
|                 return controller.getTelemetry(object).then(function () { | ||||
|                     controller.onCompositionRemove(object.identifier); | ||||
|                     return unsubscribePromise; | ||||
|                 }).then(function () { | ||||
|                     expect(unsubscribe).toHaveBeenCalled(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("exposes visible elements based on configuration", function () { | ||||
|                 var elements = controller.getElements(); | ||||
|  | ||||
|                 expect(elements.length).toEqual(3); | ||||
|                 expect(elements[0].id).toEqual('a'); | ||||
|                 expect(elements[1].id).toEqual('b'); | ||||
|                 expect(elements[2].id).toEqual('c'); | ||||
|             }); | ||||
|  | ||||
|             it("allows elements to be selected", function () { | ||||
|                 selectable[0].context.elementProxy = controller.getElements()[1]; | ||||
|                 mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); | ||||
|  | ||||
|                 expect(controller.isElementSelected()).toBe(true); | ||||
|             }); | ||||
|  | ||||
|             it("allows selection retrieval", function () { | ||||
|                 var elements = controller.getElements(); | ||||
|                 selectable[0].context.elementProxy = elements[1]; | ||||
|                 mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); | ||||
|  | ||||
|                 expect(controller.getSelectedElement()).toEqual(elements[1]); | ||||
|             }); | ||||
|  | ||||
|             it("selects the parent view when selected element is removed", function () { | ||||
|                 var elements = controller.getElements(); | ||||
|                 selectable[0].context.elementProxy = elements[1]; | ||||
|                 mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); | ||||
|                 controller.remove(elements[1]); | ||||
|  | ||||
|                 expect($element[0].click).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("retains selections during refresh", function () { | ||||
|                 // Get elements; remove one of them; trigger refresh. | ||||
|                 // Same element (at least by index) should still be selected. | ||||
|                 var elements = controller.getElements(); | ||||
|                 selectable[0].context.elementProxy = elements[1]; | ||||
|                 mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); | ||||
|  | ||||
|                 expect(controller.getSelectedElement()).toEqual(elements[1]); | ||||
|  | ||||
|                 controller.remove(elements[2]); | ||||
|                 elements = controller.getElements(); | ||||
|  | ||||
|                 // Verify removal, as test assumes this | ||||
|                 expect(elements.length).toEqual(2); | ||||
|  | ||||
|                 expect(controller.shouldSelect(elements[1])).toBe(true); | ||||
|             }); | ||||
|  | ||||
|             it("Displays received values for telemetry elements", function () { | ||||
|                 var elements; | ||||
|                 var mockTelemetry = { | ||||
|                     time: 100, | ||||
|                     value: 200 | ||||
|                 }; | ||||
|                 var testElement = {}; | ||||
|                 var telemetryObject = { | ||||
|                     identifier: { | ||||
|                         key: '12345' | ||||
|                     } | ||||
|                 }; | ||||
|                 mockConductor.clock.and.returnValue({}); | ||||
|                 controller.elementProxiesById = {}; | ||||
|                 controller.elementProxiesById['12345'] = [testElement]; | ||||
|                 controller.elementProxies = [testElement]; | ||||
|  | ||||
|                 controller.subscribeToObject(telemetryObject); | ||||
|                 mockTelemetryAPI.subscribe.calls.mostRecent().args[1](mockTelemetry); | ||||
|  | ||||
|                 return new Promise(function (resolve) { | ||||
|                     mockScope.$digest.and.callFake(resolve); | ||||
|                 }).then(function () { | ||||
|                     // Get elements that controller is now exposing | ||||
|                     elements = controller.getElements(); | ||||
|  | ||||
|                     // Formatted values should be available | ||||
|                     expect(elements[0].value).toEqual("Formatted 200"); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("updates elements styles when grid size changes", function () { | ||||
|                 // Grid size is initially set to testGrid which is [123, 456] | ||||
|                 var originalLeft = controller.getElements()[0].style.left; | ||||
|  | ||||
|                 // Change the grid size | ||||
|                 controller.updateElementPositions([20, 20]); | ||||
|  | ||||
|                 expect(controller.getElements()[0].style.left).not.toEqual(originalLeft); | ||||
|             }); | ||||
|  | ||||
|             it("listens for drop events", function () { | ||||
|                 mockScope.domainObject = mockDomainObject; | ||||
|                 mockScope.model = testModel; | ||||
|  | ||||
|                 // Layout should position panels according to | ||||
|                 // where the user dropped them, so it needs to | ||||
|                 // listen for drop events. | ||||
|                 expect(mockScope.$on).toHaveBeenCalledWith( | ||||
|                     'mctDrop', | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|  | ||||
|                 // Verify precondition | ||||
|                 expect(testConfiguration.elements.length).toEqual(3); | ||||
|  | ||||
|                 // Notify that a drop occurred | ||||
|                 testModel.composition.push('d'); | ||||
|  | ||||
|                 mockObjects.get.and.returnValue(Promise.resolve([])); | ||||
|  | ||||
|                 findOn('mctDrop')( | ||||
|                     mockEvent, | ||||
|                     'd', | ||||
|                     { x: 300, y: 100 } | ||||
|                 ); | ||||
|  | ||||
|                 // Should have added an element | ||||
|                 expect(testConfiguration.elements.length).toEqual(4); | ||||
|  | ||||
|                 // ...and prevented default... | ||||
|                 expect(mockEvent.preventDefault).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("ignores drops when default has been prevented", function () { | ||||
|                 // Avoids redundant drop-handling, WTD-1233 | ||||
|                 mockEvent.defaultPrevented = true; | ||||
|  | ||||
|                 // Notify that a drop occurred | ||||
|                 testModel.composition.push('d'); | ||||
|                 findOn('mctDrop')( | ||||
|                     mockEvent, | ||||
|                     'd', | ||||
|                     { x: 300, y: 100 } | ||||
|                 ); | ||||
|  | ||||
|                 // Should NOT have added an element | ||||
|                 expect(testConfiguration.elements.length).toEqual(3); | ||||
|             }); | ||||
|  | ||||
|             it("unsubscribes when destroyed", function () { | ||||
|                 var unsubscribe = jasmine.createSpy('unsubscribe'); | ||||
|                 var object = makeMockDomainObject("mock"); | ||||
|  | ||||
|                 mockTelemetryAPI.subscribe.and.returnValue(unsubscribe); | ||||
|  | ||||
|                 return controller.getTelemetry(object).then(function () { | ||||
|                     expect(unsubscribe).not.toHaveBeenCalled(); | ||||
|                     // Destroy the scope | ||||
|                     findOn('$destroy')(); | ||||
|  | ||||
|                     expect(unsubscribe).toHaveBeenCalled(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("exposes its grid size", function () { | ||||
|                 expect(controller.getGridSize()).toEqual(testGrid); | ||||
|             }); | ||||
|  | ||||
|             it("exposes drag handles", function () { | ||||
|                 var handles; | ||||
|                 selectable[0].context.elementProxy = controller.getElements()[1]; | ||||
|                 mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); | ||||
|  | ||||
|                 // Should have a non-empty array of handles | ||||
|                 handles = controller.handles(); | ||||
|  | ||||
|                 expect(handles).toEqual(jasmine.any(Array)); | ||||
|                 expect(handles.length).not.toEqual(0); | ||||
|  | ||||
|                 // And they should have start/continue/end drag methods | ||||
|                 handles.forEach(function (handle) { | ||||
|                     expect(handle.startDrag).toEqual(jasmine.any(Function)); | ||||
|                     expect(handle.continueDrag).toEqual(jasmine.any(Function)); | ||||
|                     expect(handle.endDrag).toEqual(jasmine.any(Function)); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("exposes a move handle", function () { | ||||
|                 selectable[0].context.elementProxy = controller.getElements()[1]; | ||||
|                 mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); | ||||
|  | ||||
|                 // Should have a move handle | ||||
|                 var handle = controller.moveHandle(); | ||||
|  | ||||
|                 // And it should have start/continue/end drag methods | ||||
|                 expect(handle.startDrag).toEqual(jasmine.any(Function)); | ||||
|                 expect(handle.continueDrag).toEqual(jasmine.any(Function)); | ||||
|                 expect(handle.endDrag).toEqual(jasmine.any(Function)); | ||||
|             }); | ||||
|  | ||||
|             it("updates selection style during drag", function () { | ||||
|                 var oldStyle; | ||||
|                 selectable[0].context.elementProxy = controller.getElements()[1]; | ||||
|                 mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); | ||||
|  | ||||
|                 // Get style | ||||
|                 oldStyle = controller.getSelectedElementStyle(); | ||||
|  | ||||
|                 // Start a drag gesture | ||||
|                 controller.moveHandle().startDrag(); | ||||
|  | ||||
|                 // Haven't moved yet; style shouldn't have updated yet | ||||
|                 expect(controller.getSelectedElementStyle()).toEqual(oldStyle); | ||||
|  | ||||
|                 // Drag a little | ||||
|                 controller.moveHandle().continueDrag([1000, 100]); | ||||
|  | ||||
|                 // Style should have been updated | ||||
|                 expect(controller.getSelectedElementStyle()).not.toEqual(oldStyle); | ||||
|             }); | ||||
|  | ||||
|             it("cleans up selection on scope destroy", function () { | ||||
|                 expect(mockScope.$on).toHaveBeenCalledWith( | ||||
|                     '$destroy', | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|  | ||||
|                 mockScope.$on.calls.mostRecent().args[1](); | ||||
|  | ||||
|                 expect(mockOpenMCT.selection.off).toHaveBeenCalledWith( | ||||
|                     'change', | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             describe("on display bounds changes", function () { | ||||
|                 var testBounds; | ||||
|                 var boundsChangeCallback; | ||||
|                 var objectOne; | ||||
|                 var objectTwo; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     testBounds = { start: 123, end: 321 }; | ||||
|                     boundsChangeCallback = mockConductor.on.calls.mostRecent().args[1]; | ||||
|                     objectOne = {}; | ||||
|                     objectTwo = {}; | ||||
|                     controller.telemetryObjects = [ | ||||
|                         objectOne, | ||||
|                         objectTwo | ||||
|                     ]; | ||||
|                     spyOn(controller, "fetchHistoricalData"); | ||||
|                     controller.fetchHistoricalData.and.callThrough(); | ||||
|                 }); | ||||
|  | ||||
|                 it("registers a bounds change listener", function () { | ||||
|                     expect(mockConductor.on).toHaveBeenCalledWith("bounds", jasmine.any(Function)); | ||||
|                 }); | ||||
|  | ||||
|                 it("requests only a single point", function () { | ||||
|                     mockConductor.clock.and.returnValue(undefined); | ||||
|                     boundsChangeCallback(testBounds); | ||||
|                     expect(mockTelemetryAPI.request.calls.count()).toBe(2); | ||||
|  | ||||
|                     mockTelemetryAPI.request.calls.all().forEach(function (call) { | ||||
|                         expect(call.args[1].size).toBe(1); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("Does not fetch historical data on tick", function () { | ||||
|                     boundsChangeCallback(testBounds, true); | ||||
|                     expect(mockTelemetryAPI.request.calls.count()).toBe(0); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("on receipt of telemetry", function () { | ||||
|                 var mockTelemetryObject; | ||||
|                 var testValue; | ||||
|                 var testElement; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     mockTelemetryObject = { | ||||
|                         identifier: { | ||||
|                             key: '12345' | ||||
|                         } | ||||
|                     }; | ||||
|                     testValue = 30; | ||||
|                     testElement = {}; | ||||
|  | ||||
|                     controller.elementProxiesById = {}; | ||||
|                     controller.elementProxiesById['12345'] = [testElement]; | ||||
|                     controller.elementProxies = [testElement]; | ||||
|                 }); | ||||
|  | ||||
|                 it("updates displayed values from historical telemetry", function () { | ||||
|                     spyOn(controller, "updateView"); | ||||
|                     controller.updateView.and.callThrough(); | ||||
|  | ||||
|                     mockTelemetryAPI.request.and.returnValue(Promise.resolve([{ | ||||
|                         time: 100, | ||||
|                         value: testValue | ||||
|                     }])); | ||||
|  | ||||
|                     controller.fetchHistoricalData(mockTelemetryObject); | ||||
|  | ||||
|                     return new Promise(function (resolve) { | ||||
|                         mockScope.$digest.and.callFake(resolve); | ||||
|                     }).then(function () { | ||||
|                         expect(controller.updateView).toHaveBeenCalled(); | ||||
|                         expect(controller.getElements()[0].value) | ||||
|                             .toEqual("Formatted " + testValue); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("selects an range value to display, if available", function () { | ||||
|                     mockMetadata.valuesForHints.and.returnValue([ | ||||
|                         { | ||||
|                             key: 'range', | ||||
|                             source: 'range' | ||||
|                         } | ||||
|                     ]); | ||||
|                     var key = controller.chooseValueMetadataToDisplay(mockMetadata).source; | ||||
|                     expect(key).toEqual('range'); | ||||
|                 }); | ||||
|  | ||||
|                 it("selects the first non-domain value to display, if no range available", function () { | ||||
|                     mockMetadata.valuesForHints.and.returnValue([]); | ||||
|                     mockMetadata.values.and.returnValue([ | ||||
|                         { | ||||
|                             key: 'domain', | ||||
|                             source: 'domain', | ||||
|                             hints: { | ||||
|                                 domain: 1 | ||||
|                             } | ||||
|                         }, | ||||
|                         { | ||||
|                             key: 'image', | ||||
|                             source: 'image', | ||||
|                             hints: { | ||||
|                                 image: 1 | ||||
|                             } | ||||
|                         } | ||||
|                     ]); | ||||
|                     var key = controller.chooseValueMetadataToDisplay(mockMetadata).source; | ||||
|                     expect(key).toEqual('image'); | ||||
|                 }); | ||||
|  | ||||
|                 it("reflects limit status", function () { | ||||
|                     mockLimitEvaluator.evaluate.and.returnValue({cssClass: "alarm-a"}); | ||||
|                     controller.updateView(mockTelemetryObject, [{ | ||||
|                         time: 100, | ||||
|                         value: testValue | ||||
|                     }]); | ||||
|  | ||||
|                     return new Promise(function (resolve) { | ||||
|                         mockScope.$digest.and.callFake(resolve); | ||||
|                     }).then(function () { | ||||
|                         // Limit-based CSS classes should be available | ||||
|                         expect(controller.getElements()[0].cssClass).toEqual("alarm-a"); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("listens for selection change events", function () { | ||||
|                     expect(mockOpenMCT.selection.on).toHaveBeenCalledWith( | ||||
|                         'change', | ||||
|                         jasmine.any(Function) | ||||
|                     ); | ||||
|                 }); | ||||
|  | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,92 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../src/FixedDragHandle'], | ||||
|     function (FixedDragHandle) { | ||||
|  | ||||
|         var TEST_GRID_SIZE = [13, 33]; | ||||
|  | ||||
|         describe("A fixed position drag handle", function () { | ||||
|             var mockElementHandle, | ||||
|                 mockConfigPath, | ||||
|                 mockFixedControl, | ||||
|                 handle; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockElementHandle = jasmine.createSpyObj( | ||||
|                     'elementHandle', | ||||
|                     ['x', 'y','getGridSize'] | ||||
|                 ); | ||||
|                 mockElementHandle.x.and.returnValue(6); | ||||
|                 mockElementHandle.y.and.returnValue(8); | ||||
|                 mockElementHandle.getGridSize.and.returnValue(TEST_GRID_SIZE); | ||||
|  | ||||
|                 mockFixedControl = jasmine.createSpyObj( | ||||
|                     'fixedControl', | ||||
|                     ['updateSelectionStyle', 'mutate'] | ||||
|                 ); | ||||
|                 mockFixedControl.updateSelectionStyle.and.returnValue(); | ||||
|                 mockFixedControl.mutate.and.returnValue(); | ||||
|  | ||||
|                 mockConfigPath = jasmine.createSpy('configPath'); | ||||
|  | ||||
|                 handle = new FixedDragHandle( | ||||
|                     mockElementHandle, | ||||
|                     mockConfigPath, | ||||
|                     mockFixedControl | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("provides a style for positioning", function () { | ||||
|                 var style = handle.style(); | ||||
|                 // 6 grid coords * 13 pixels - 3 pixels for centering | ||||
|                 expect(style.left).toEqual('75px'); | ||||
|                 // 8 grid coords * 33 pixels - 3 pixels for centering | ||||
|                 expect(style.top).toEqual('261px'); | ||||
|             }); | ||||
|  | ||||
|             it("allows handles to be dragged", function () { | ||||
|                 handle.startDrag(); | ||||
|                 handle.continueDrag([16, 8]); | ||||
|  | ||||
|                 // Should update x/y, snapped to grid | ||||
|                 expect(mockElementHandle.x).toHaveBeenCalledWith(7); | ||||
|                 expect(mockElementHandle.y).toHaveBeenCalledWith(8); | ||||
|  | ||||
|                 handle.continueDrag([-16, -35]); | ||||
|  | ||||
|                 // Should have interpreted relative to initial state | ||||
|                 expect(mockElementHandle.x).toHaveBeenCalledWith(5); | ||||
|                 expect(mockElementHandle.y).toHaveBeenCalledWith(7); | ||||
|  | ||||
|                 // Should have called updateSelectionStyle once per continueDrag | ||||
|                 expect(mockFixedControl.updateSelectionStyle.calls.count()).toEqual(2); | ||||
|  | ||||
|                 // Finally, ending drag should mutate | ||||
|                 handle.endDrag(); | ||||
|                 expect(mockFixedControl.mutate).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,71 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../src/FixedProxy'], | ||||
|     function (FixedProxy) { | ||||
|  | ||||
|         describe("Fixed Position view's selection proxy", function () { | ||||
|             var mockCallback, | ||||
|                 mockQ, | ||||
|                 mockDialogService, | ||||
|                 mockPromise, | ||||
|                 proxy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockCallback = jasmine.createSpy('callback'); | ||||
|                 mockQ = jasmine.createSpyObj('$q', ['when']); | ||||
|                 mockDialogService = jasmine.createSpyObj('dialogService', ['getUserInput']); | ||||
|                 mockPromise = jasmine.createSpyObj('promise', ['then']); | ||||
|  | ||||
|                 mockQ.when.and.returnValue(mockPromise); | ||||
|  | ||||
|                 proxy = new FixedProxy(mockCallback, mockQ, mockDialogService); | ||||
|             }); | ||||
|  | ||||
|             it("handles promised element creation", function () { | ||||
|                 // The element factory may return promises (e.g. if | ||||
|                 // user input is required) so make sure proxy is wrapping these | ||||
|                 proxy.add("fixed.box"); | ||||
|                 expect(mockQ.when).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("notifies its callback when an element is created", function () { | ||||
|                 proxy.add("fixed.box"); | ||||
|                 // Callback should not have been invoked yet | ||||
|                 expect(mockCallback).not.toHaveBeenCalled(); | ||||
|                 // Resolve the promise | ||||
|                 mockPromise.then.calls.mostRecent().args[0]({}); | ||||
|                 // Should have fired the callback | ||||
|                 expect(mockCallback).toHaveBeenCalledWith({ | ||||
|                     type: "fixed.box", | ||||
|                     x: 0, | ||||
|                     y: 0, | ||||
|                     width: 1, | ||||
|                     height: 1, | ||||
|                     useGrid: true | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,81 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ["../src/LayoutDrag"], | ||||
|     function (LayoutDrag) { | ||||
|  | ||||
|         describe("A Layout drag handler", function () { | ||||
|             var testPosition = { | ||||
|                 position: [8, 11], | ||||
|                 dimensions: [3, 2] | ||||
|             }; | ||||
|  | ||||
|             it("changes position by a supplied factor, rounding by grid size", function () { | ||||
|                 var handler = new LayoutDrag( | ||||
|                     testPosition, | ||||
|                     [1, 1], | ||||
|                     [0, 0], | ||||
|                     [10, 20] | ||||
|                 ); | ||||
|  | ||||
|                 expect(handler.getAdjustedPosition([37, 84])).toEqual({ | ||||
|                     position: [12, 15], | ||||
|                     dimensions: [3, 2] | ||||
|                 }); | ||||
|                 expect(handler.getAdjustedPosition([-37, 84])).toEqual({ | ||||
|                     position: [4, 15], | ||||
|                     dimensions: [3, 2] | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("changes dimensions by a supplied factor, rounding by grid size", function () { | ||||
|                 var handler = new LayoutDrag( | ||||
|                     testPosition, | ||||
|                     [0, 0], | ||||
|                     [1, 1], | ||||
|                     [10, 20] | ||||
|                 ); | ||||
|  | ||||
|                 expect(handler.getAdjustedPosition([37, 84])).toEqual({ | ||||
|                     position: [8, 11], | ||||
|                     dimensions: [7, 6] | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("allows mixing dimension and position factors", function () { | ||||
|                 var handler = new LayoutDrag( | ||||
|                     testPosition, | ||||
|                     [0, 1], | ||||
|                     [-1, 0], | ||||
|                     [10, 20] | ||||
|                 ); | ||||
|  | ||||
|                 expect(handler.getAdjustedPosition([11, 84])).toEqual({ | ||||
|                     position: [8, 15], | ||||
|                     dimensions: [2, 2] | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,128 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2016, 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     '../src/MCTTriggerModal' | ||||
| ], function ( | ||||
|     MCTTriggerModal | ||||
| ) { | ||||
|     describe('MCTTriggerModal', function () { | ||||
|         var $scope, | ||||
|             $element, | ||||
|             frame, | ||||
|             layoutContainer, | ||||
|             $document, | ||||
|             mctTriggerModal; | ||||
|  | ||||
|         function makeElement(classes, parentEl) { | ||||
|             var elem = jasmine.createSpyObj('element.' + classes.join('.'), [ | ||||
|                 'hasClass', | ||||
|                 'parent' | ||||
|             ]); | ||||
|             elem.hasClass.and.callFake(function (className) { | ||||
|                 return classes.indexOf(className) !== -1; | ||||
|             }); | ||||
|             elem.parent.and.returnValue(parentEl); | ||||
|             var div = document.createElement('div'); | ||||
|             div.className = classes.join(' '); | ||||
|             parentEl[0].appendChild(div); | ||||
|             elem[0] = div; | ||||
|             return elem; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         beforeEach(function () { | ||||
|             $scope = jasmine.createSpyObj('$scope', ['$on']); | ||||
|             $scope.domainObject = { getCapability: function () { | ||||
|                 return { getActions: function () { | ||||
|                     return []; | ||||
|                 }}; | ||||
|             }}; | ||||
|  | ||||
|             $element = jasmine.createSpyObj('$element', [ | ||||
|                 'parent', | ||||
|                 'remove', | ||||
|                 'on', | ||||
|                 'off' | ||||
|             ]); | ||||
|             layoutContainer = document.createElement('div'); | ||||
|             frame = makeElement(['frame'], [layoutContainer]); | ||||
|             var child = makeElement([], frame); | ||||
|             for (var i = 0; i < 5; i++) { | ||||
|                 child = makeElement([], child); | ||||
|             } | ||||
|             $element.parent.and.returnValue(child); | ||||
|             $document = [jasmine.createSpyObj('document', ['createElement'])]; | ||||
|             $document[0].body = document.createElement('div'); | ||||
|             $document[0].createElement.and.callFake(function (tag) { | ||||
|                 return document.createElement(tag); | ||||
|             }); | ||||
|  | ||||
|             mctTriggerModal = new MCTTriggerModal($document); | ||||
|         }); | ||||
|  | ||||
|         it('is a directive definition', function () { | ||||
|             expect(mctTriggerModal.restrict).toBe('A'); | ||||
|             expect(mctTriggerModal.link).toEqual(jasmine.any(Function)); | ||||
|         }); | ||||
|  | ||||
|         describe('link', function () { | ||||
|             beforeEach(function () { | ||||
|                 mctTriggerModal.link($scope, $element); | ||||
|             }); | ||||
|  | ||||
|             it('attaches handlers to $element', function () { | ||||
|                 expect($element.on).toHaveBeenCalledWith( | ||||
|                     'click', | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it('cleans up on $scope $destroy', function () { | ||||
|                 expect($scope.$on).toHaveBeenCalledWith( | ||||
|                     '$destroy', | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|                 $scope.$on.calls.mostRecent().args[1](); | ||||
|                 expect($element.off).toHaveBeenCalledWith( | ||||
|                     'click', | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it('opens and closes overlays', function () { | ||||
|                 [ | ||||
|                     'a.close', 'a.t-done', '.abs.blocker' | ||||
|                 ].forEach(function (selector) { | ||||
|                     $element.on.calls.mostRecent().args[1](); | ||||
|                     var container = $document[0].body.querySelector('.t-contents'); | ||||
|                     expect(container.children[0]).toBe(frame[0]); | ||||
|                     expect(layoutContainer.children[0]).not.toBe(frame[0]); | ||||
|                     $document[0].body.querySelector(selector) | ||||
|                         .dispatchEvent(new Event('click')); | ||||
|                     expect(container.children[0]).not.toBe(frame[0]); | ||||
|                     expect(layoutContainer.children[0]).toBe(frame[0]); | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -1,50 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/AccessorMutator'], | ||||
|     function (AccessorMutator) { | ||||
|  | ||||
|         describe("An accessor-mutator", function () { | ||||
|             var testObject, | ||||
|                 am; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testObject = { t: 42, other: 100 }; | ||||
|                 am = new AccessorMutator(testObject, 't'); | ||||
|             }); | ||||
|  | ||||
|             it("allows access to a property", function () { | ||||
|                 expect(am()).toEqual(42); | ||||
|             }); | ||||
|  | ||||
|             it("allows mutation of a property", function () { | ||||
|                 expect(am("some other value")).toEqual("some other value"); | ||||
|                 expect(testObject).toEqual({ | ||||
|                     t: "some other value", | ||||
|                     other: 100 | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,55 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/BoxProxy'], | ||||
|     function (BoxProxy) { | ||||
|  | ||||
|         describe("A fixed position box proxy", function () { | ||||
|             var testElement, | ||||
|                 testElements, | ||||
|                 proxy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testElement = { | ||||
|                     x: 1, | ||||
|                     y: 2, | ||||
|                     width: 42, | ||||
|                     height: 24, | ||||
|                     fill: "transparent" | ||||
|                 }; | ||||
|                 testElements = [{}, {}, testElement, {}]; | ||||
|                 proxy = new BoxProxy( | ||||
|                     testElement, | ||||
|                     testElements.indexOf(testElement), | ||||
|                     testElements | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("provides getter/setter for fill color", function () { | ||||
|                 expect(proxy.fill()).toEqual('transparent'); | ||||
|                 expect(proxy.fill('#FFF')).toEqual('#FFF'); | ||||
|                 expect(proxy.fill()).toEqual('#FFF'); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,69 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/ElementFactory'], | ||||
|     function (ElementFactory) { | ||||
|  | ||||
|         var DIALOG_ELEMENTS = ['image', 'text'], | ||||
|             NON_DIALOG_ELEMENTS = ['box', 'line']; | ||||
|  | ||||
|         describe("The fixed position element factory", function () { | ||||
|             var mockDialogService, | ||||
|                 mockPromise, | ||||
|                 factory; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockDialogService = jasmine.createSpyObj( | ||||
|                     'dialogService', | ||||
|                     ['getUserInput'] | ||||
|                 ); | ||||
|                 mockPromise = jasmine.createSpyObj( | ||||
|                     'promise', | ||||
|                     ['then'] | ||||
|                 ); | ||||
|  | ||||
|                 mockDialogService.getUserInput.and.returnValue(mockPromise); | ||||
|                 mockPromise.then.and.returnValue(mockPromise); | ||||
|  | ||||
|                 factory = new ElementFactory(mockDialogService); | ||||
|             }); | ||||
|  | ||||
|             DIALOG_ELEMENTS.forEach(function (type) { | ||||
|                 it("shows a dialog for " + type + " elements", function () { | ||||
|                     expect(factory.createElement('fixed.' + type)) | ||||
|                         .toEqual(mockPromise); | ||||
|                     expect(mockDialogService.getUserInput).toHaveBeenCalled(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             NON_DIALOG_ELEMENTS.forEach(function (type) { | ||||
|                 it("immediately provides " + type + " elements", function () { | ||||
|                     var result = factory.createElement('fixed.' + type); | ||||
|                     expect(result).toBeDefined(); | ||||
|                     expect(result).not.toEqual(mockPromise); | ||||
|                     expect(mockDialogService.getUserInput).not.toHaveBeenCalled(); | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,51 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/ElementProxies'], | ||||
|     function (ElementProxies) { | ||||
|  | ||||
|         // Expect these element types to have proxies | ||||
|         var ELEMENT_TYPES = [ | ||||
|             "fixed.telemetry", | ||||
|             "fixed.line", | ||||
|             "fixed.box", | ||||
|             "fixed.text", | ||||
|             "fixed.image" | ||||
|         ]; | ||||
|  | ||||
|         // Verify that the set of proxies exposed matches the specific | ||||
|         // list above. | ||||
|         describe("The set of element proxies", function () { | ||||
|             ELEMENT_TYPES.forEach(function (t) { | ||||
|                 it("exposes a proxy wrapper for " + t + " elements", function () { | ||||
|                     expect(typeof ElementProxies[t]).toEqual('function'); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("exposes no additional wrappers", function () { | ||||
|                 expect(Object.keys(ElementProxies).length) | ||||
|                     .toEqual(ELEMENT_TYPES.length); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,98 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/ElementProxy'], | ||||
|     function (ElementProxy) { | ||||
|  | ||||
|         describe("A fixed position element proxy", function () { | ||||
|             var testElement, | ||||
|                 testElements, | ||||
|                 proxy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testElement = { | ||||
|                     x: 1, | ||||
|                     y: 2, | ||||
|                     stroke: '#717171', | ||||
|                     width: 42, | ||||
|                     height: 24, | ||||
|                     useGrid: true | ||||
|                 }; | ||||
|                 testElements = [{}, {}, testElement, {}]; | ||||
|                 proxy = new ElementProxy( | ||||
|                     testElement, | ||||
|                     testElements.indexOf(testElement), | ||||
|                     testElements, | ||||
|                     [13,21] | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("exposes element properties", function () { | ||||
|                 Object.keys(testElement).forEach(function (k) { | ||||
|                     expect(proxy[k]()).toEqual(testElement[k]); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("allows order to be changed", function () { | ||||
|                 proxy.order("down"); | ||||
|                 expect(testElements).toEqual([{}, testElement, {}, {}]); | ||||
|                 proxy.order("up"); | ||||
|                 expect(testElements).toEqual([{}, {}, testElement, {}]); | ||||
|                 proxy.order("bottom"); | ||||
|                 expect(testElements).toEqual([testElement, {}, {}, {}]); | ||||
|                 proxy.order("top"); | ||||
|                 expect(testElements).toEqual([{}, {}, {}, testElement]); | ||||
|             }); | ||||
|  | ||||
|             it("ensures x/y values are non-negative", function () { | ||||
|                 proxy.x(-1); | ||||
|                 proxy.y(-400); | ||||
|                 expect(proxy.x()).toEqual(0); | ||||
|                 expect(proxy.y()).toEqual(0); | ||||
|             }); | ||||
|  | ||||
|             it("allows modifying the current grid size", function () { | ||||
|                 proxy.setGridSize([112,420]); | ||||
|                 expect(proxy.gridSize).toEqual([112,420]); | ||||
|             }); | ||||
|  | ||||
|             it("returns the current grid size only if the element snaps to grid", function () { | ||||
|                 expect(proxy.getGridSize()).toEqual([13,21]); | ||||
|                 proxy.useGrid(false); | ||||
|                 expect(proxy.getGridSize()).toEqual([1,1]); | ||||
|             }); | ||||
|  | ||||
|             it("returns the mininum height and width of an element currently used units", function () { | ||||
|                 // Assumes mininum height and width are 10, in pixels | ||||
|                 expect(proxy.getMinWidth()).toEqual(1); | ||||
|                 expect(proxy.getMinHeight()).toEqual(1); | ||||
|                 proxy.setGridSize([7,4]); | ||||
|                 expect(proxy.getMinWidth()).toEqual(2); | ||||
|                 expect(proxy.getMinHeight()).toEqual(3); | ||||
|                 proxy.useGrid(false); | ||||
|                 expect(proxy.getMinWidth()).toEqual(10); | ||||
|                 expect(proxy.getMinHeight()).toEqual(10); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,56 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/ImageProxy'], | ||||
|     function (ImageProxy) { | ||||
|  | ||||
|         describe("A fixed position image proxy", function () { | ||||
|             var testElement, | ||||
|                 testElements, | ||||
|                 proxy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testElement = { | ||||
|                     x: 1, | ||||
|                     y: 2, | ||||
|                     width: 42, | ||||
|                     height: 24, | ||||
|                     url: "http://www.nasa.gov" | ||||
|                 }; | ||||
|                 testElements = [{}, {}, testElement, {}]; | ||||
|                 proxy = new ImageProxy( | ||||
|                     testElement, | ||||
|                     testElements.indexOf(testElement), | ||||
|                     testElements | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("provides getter/setter for image URL", function () { | ||||
|                 expect(proxy.url()).toEqual("http://www.nasa.gov"); | ||||
|                 expect(proxy.url("http://www.nasa.gov/some.jpg")) | ||||
|                     .toEqual("http://www.nasa.gov/some.jpg"); | ||||
|                 expect(proxy.url()).toEqual("http://www.nasa.gov/some.jpg"); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,81 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/LineHandle'], | ||||
|     function (LineHandle) { | ||||
|  | ||||
|         describe("A fixed position drag handle", function () { | ||||
|             var testElement, | ||||
|                 mockElementProxy, | ||||
|                 handle, | ||||
|                 TEST_GRID_SIZE = [45, 21]; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testElement = { | ||||
|                     x: 3, | ||||
|                     y: 42, | ||||
|                     x2: 8, | ||||
|                     y2: 11, | ||||
|                     useGrid: true | ||||
|                 }; | ||||
|                 mockElementProxy = jasmine.createSpyObj('elementProxy', ['getGridSize']); | ||||
|                 mockElementProxy.getGridSize.and.returnValue(TEST_GRID_SIZE); | ||||
|  | ||||
|                 handle = new LineHandle(testElement, mockElementProxy, 'x', 'y', 'x2', 'y2'); | ||||
|             }); | ||||
|  | ||||
|             it("provides x/y grid coordinates for its corner", function () { | ||||
|                 expect(handle.x()).toEqual(3); | ||||
|                 expect(handle.y()).toEqual(42); | ||||
|             }); | ||||
|  | ||||
|             it("changes x and y positions", function () { | ||||
|                 handle.x(30); | ||||
|                 expect(testElement.x).toEqual(30); | ||||
|                 handle.y(40); | ||||
|                 expect(testElement.y).toEqual(40); | ||||
|             }); | ||||
|  | ||||
|             it("disallows values less than zero", function () { | ||||
|                 handle.x(-1); | ||||
|                 handle.y(-400); | ||||
|                 expect(testElement.x).toEqual(0); | ||||
|                 expect(testElement.y).toEqual(0); | ||||
|             }); | ||||
|  | ||||
|             it("ensures that end points remain different", function () { | ||||
|                 handle.x(testElement.x2); | ||||
|                 handle.y(testElement.y2); | ||||
|                 // First change should have been fine, because y was different | ||||
|                 expect(testElement.x).toEqual(testElement.x2); | ||||
|                 // Second change should have been rejected | ||||
|                 expect(testElement.y).not.toEqual(testElement.y2); | ||||
|             }); | ||||
|  | ||||
|             it("returns the correct grid size", function () { | ||||
|                 expect(handle.getGridSize()).toEqual(TEST_GRID_SIZE); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,95 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/LineProxy'], | ||||
|     function (LineProxy) { | ||||
|  | ||||
|         describe("A fixed position line proxy", function () { | ||||
|             var vertical, horizontal, diagonal, reversed; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 vertical = { x: 1, y: 4, x2: 1, y2: 8}; | ||||
|                 horizontal = { x: 3, y: 3, x2: 12, y2: 3}; | ||||
|                 diagonal = { x: 3, y: 8, x2: 5, y2: 11}; | ||||
|                 reversed = { x2: 3, y2: 8, x: 5, y: 11}; | ||||
|             }); | ||||
|  | ||||
|             it("ensures visible width for vertical lines", function () { | ||||
|                 expect(new LineProxy(vertical).width()).toEqual(1); | ||||
|             }); | ||||
|  | ||||
|             it("ensures visible height for horizontal lines", function () { | ||||
|                 expect(new LineProxy(horizontal).height()).toEqual(1); | ||||
|             }); | ||||
|  | ||||
|             it("provides a bounding box for lines", function () { | ||||
|                 var proxy = new LineProxy(diagonal); | ||||
|                 expect(proxy.x()).toEqual(3); | ||||
|                 expect(proxy.y()).toEqual(8); | ||||
|                 expect(proxy.width()).toEqual(2); | ||||
|                 expect(proxy.height()).toEqual(3); | ||||
|             }); | ||||
|  | ||||
|             it("bounds lines identically regardless of point order", function () { | ||||
|                 // That is, x(), width(), y(), and height() should always give | ||||
|                 // the same results for the same line segments, regardless of | ||||
|                 // which point is x,y and which is x2,y2 | ||||
|                 ['x', 'y', 'width', 'height'].forEach(function (method) { | ||||
|                     expect(new LineProxy(diagonal)[method]()) | ||||
|                         .toEqual(new LineProxy(reversed)[method]()); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("adjusts both ends when mutating x", function () { | ||||
|                 var proxy = new LineProxy(diagonal); | ||||
|                 proxy.x(6); | ||||
|                 expect(diagonal).toEqual({ x: 6, y: 8, x2: 8, y2: 11}); | ||||
|             }); | ||||
|  | ||||
|             it("adjusts both ends when mutating y", function () { | ||||
|                 var proxy = new LineProxy(diagonal); | ||||
|                 proxy.y(6); | ||||
|                 expect(diagonal).toEqual({ x: 3, y: 6, x2: 5, y2: 9}); | ||||
|             }); | ||||
|  | ||||
|             it("provides internal positions for SVG lines", function () { | ||||
|                 var proxy; | ||||
|                 proxy = new LineProxy(diagonal); | ||||
|                 expect(proxy.x1()).toEqual(0); | ||||
|                 expect(proxy.y1()).toEqual(0); | ||||
|                 expect(proxy.x2()).toEqual(2); | ||||
|                 expect(proxy.y2()).toEqual(3); | ||||
|                 proxy = new LineProxy(reversed); | ||||
|                 expect(proxy.x1()).toEqual(2); | ||||
|                 expect(proxy.y1()).toEqual(3); | ||||
|                 expect(proxy.x2()).toEqual(0); | ||||
|                 expect(proxy.y2()).toEqual(0); | ||||
|             }); | ||||
|  | ||||
|             it("provides handles for both ends", function () { | ||||
|                 expect(new LineProxy(diagonal).handles().length).toEqual(2); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,93 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/ResizeHandle'], | ||||
|     function (ResizeHandle) { | ||||
|  | ||||
|         var TEST_MIN_WIDTH = 4, | ||||
|             TEST_MIN_HEIGHT = 2, | ||||
|             TEST_GRID_SIZE = [34, 81]; | ||||
|  | ||||
|         describe("A fixed position drag handle", function () { | ||||
|             var testElement, | ||||
|                 mockElementProxy, | ||||
|                 handle; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testElement = { | ||||
|                     x: 3, | ||||
|                     y: 42, | ||||
|                     width: 30, | ||||
|                     height: 36, | ||||
|                     useGrid: true | ||||
|                 }; | ||||
|                 mockElementProxy = jasmine.createSpyObj('elementProxy', [ | ||||
|                     'getGridSize', | ||||
|                     'getMinWidth', | ||||
|                     'getMinHeight' | ||||
|                 ]); | ||||
|                 mockElementProxy.getGridSize.and.returnValue(TEST_GRID_SIZE); | ||||
|                 mockElementProxy.getMinWidth.and.returnValue(TEST_MIN_WIDTH); | ||||
|                 mockElementProxy.getMinHeight.and.returnValue(TEST_MIN_HEIGHT); | ||||
|  | ||||
|                 handle = new ResizeHandle( | ||||
|                     mockElementProxy, | ||||
|                     testElement | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("provides x/y grid coordinates for lower-right corner", function () { | ||||
|                 expect(handle.x()).toEqual(33); | ||||
|                 expect(handle.y()).toEqual(78); | ||||
|             }); | ||||
|  | ||||
|             it("changes width of an element", function () { | ||||
|                 handle.x(30); | ||||
|                 // Should change width, not x | ||||
|                 expect(testElement.x).toEqual(3); | ||||
|                 expect(testElement.width).toEqual(27); | ||||
|             }); | ||||
|  | ||||
|             it("changes height of an element", function () { | ||||
|                 handle.y(60); | ||||
|                 // Should change height, not y | ||||
|                 expect(testElement.y).toEqual(42); | ||||
|                 expect(testElement.height).toEqual(18); | ||||
|             }); | ||||
|  | ||||
|             it("enforces minimum width/height", function () { | ||||
|                 handle.x(testElement.x); | ||||
|                 handle.y(testElement.y); | ||||
|                 expect(testElement.x).toEqual(3); | ||||
|                 expect(testElement.y).toEqual(42); | ||||
|                 expect(testElement.width).toEqual(TEST_MIN_WIDTH); | ||||
|                 expect(testElement.height).toEqual(TEST_MIN_HEIGHT); | ||||
|             }); | ||||
|  | ||||
|             it("returns the correct grid size", function () { | ||||
|                 expect(handle.getGridSize()).toEqual(TEST_GRID_SIZE); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,54 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/TelemetryProxy'], | ||||
|     function (TelemetryProxy) { | ||||
|  | ||||
|         describe("A fixed position telemetry proxy", function () { | ||||
|             var testElement, | ||||
|                 testElements, | ||||
|                 proxy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testElement = { | ||||
|                     x: 1, | ||||
|                     y: 2, | ||||
|                     z: 3, | ||||
|                     width: 42, | ||||
|                     height: 24, | ||||
|                     id: "test-id" | ||||
|                 }; | ||||
|                 testElements = [{}, {}, testElement, {}]; | ||||
|                 proxy = new TelemetryProxy( | ||||
|                     testElement, | ||||
|                     testElements.indexOf(testElement), | ||||
|                     testElements | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("exposes the element's id", function () { | ||||
|                 expect(proxy.id).toEqual('test-id'); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,70 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/TextProxy'], | ||||
|     function (TextProxy) { | ||||
|  | ||||
|         describe("A fixed position text proxy", function () { | ||||
|             var testElement, | ||||
|                 testElements, | ||||
|                 proxy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testElement = { | ||||
|                     x: 1, | ||||
|                     y: 2, | ||||
|                     width: 42, | ||||
|                     height: 24, | ||||
|                     fill: "transparent", | ||||
|                     size: "20px" | ||||
|                 }; | ||||
|                 testElements = [{}, {}, testElement, {}]; | ||||
|                 proxy = new TextProxy( | ||||
|                     testElement, | ||||
|                     testElements.indexOf(testElement), | ||||
|                     testElements | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("provides getter/setter for fill color", function () { | ||||
|                 expect(proxy.fill()).toEqual('transparent'); | ||||
|                 expect(proxy.fill('#FFF')).toEqual('#FFF'); | ||||
|                 expect(proxy.fill()).toEqual('#FFF'); | ||||
|             }); | ||||
|  | ||||
|             it("provides getter/setter for text size", function () { | ||||
|                 expect(proxy.size()).toEqual('20px'); | ||||
|                 expect(proxy.size('12px')).toEqual('12px'); | ||||
|                 expect(proxy.size()).toEqual('12px'); | ||||
|             }); | ||||
|  | ||||
|             it("defaults to 13px for unspecified text size", function () { | ||||
|                 testElement = {x: 1, y: 2}; | ||||
|                 proxy = new TextProxy(testElement, 0, [testElement]); | ||||
|  | ||||
|                 expect(proxy.size()).toEqual('13px'); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,157 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/elements/UnitAccessorMutator'], | ||||
|     function (UnitAccessorMutator) { | ||||
|  | ||||
|         var GRID_SIZE = [13,17]; | ||||
|  | ||||
|         describe("An elementProxy.gridSize accessor-mutator", function () { | ||||
|             var mockElementProxy, | ||||
|                 testElement, | ||||
|                 mockLineProxy, | ||||
|                 testLine, | ||||
|                 uAM, | ||||
|                 uAMLine; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testElement = { | ||||
|                     x: 2, | ||||
|                     y: 3, | ||||
|                     width: 4, | ||||
|                     height: 5, | ||||
|                     useGrid: true | ||||
|                 }; | ||||
|  | ||||
|                 mockElementProxy = { | ||||
|                     element: testElement, | ||||
|                     gridSize: GRID_SIZE, | ||||
|                     getMinHeight: jasmine.createSpy('minHeight'), | ||||
|                     getMinWidth: jasmine.createSpy('minWidth') | ||||
|                 }; | ||||
|  | ||||
|                 testLine = { | ||||
|                     x: 7, | ||||
|                     y: 8, | ||||
|                     x2: 9, | ||||
|                     y2: 10, | ||||
|                     width: 11, | ||||
|                     height: 12, | ||||
|                     useGrid: true | ||||
|                 }; | ||||
|  | ||||
|                 mockLineProxy = { | ||||
|                     element: testLine, | ||||
|                     gridSize: GRID_SIZE, | ||||
|                     getMinHeight: jasmine.createSpy('minHeight'), | ||||
|                     getMinWidth: jasmine.createSpy('minWidth') | ||||
|                 }; | ||||
|  | ||||
|  | ||||
|  | ||||
|                 uAM = new UnitAccessorMutator(mockElementProxy); | ||||
|                 uAMLine = new UnitAccessorMutator(mockLineProxy); | ||||
|  | ||||
|                 mockElementProxy.getMinWidth.and.returnValue(1); | ||||
|                 mockElementProxy.getMinHeight.and.returnValue(1); | ||||
|  | ||||
|                 mockLineProxy.getMinWidth.and.returnValue(1); | ||||
|                 mockLineProxy.getMinHeight.and.returnValue(1); | ||||
|             }); | ||||
|  | ||||
|             it("allows access to useGrid", function () { | ||||
|                 expect(uAM()).toEqual(mockElementProxy.element.useGrid); | ||||
|             }); | ||||
|  | ||||
|             it("allows mutation of useGrid", function () { | ||||
|                 uAM(false); | ||||
|                 expect(mockElementProxy.element.useGrid).toEqual(false); | ||||
|             }); | ||||
|  | ||||
|             it("converts coordinates appropriately for a box", function () { | ||||
|                 uAM(false); | ||||
|                 expect(mockElementProxy.element.x).toEqual(26); | ||||
|                 expect(mockElementProxy.element.y).toEqual(51); | ||||
|                 expect(mockElementProxy.element.width).toEqual(52); | ||||
|                 expect(mockElementProxy.element.height).toEqual(85); | ||||
|                 uAM(true); | ||||
|                 expect(mockElementProxy.element.x).toEqual(2); | ||||
|                 expect(mockElementProxy.element.y).toEqual(3); | ||||
|                 expect(mockElementProxy.element.width).toEqual(4); | ||||
|                 expect(mockElementProxy.element.height).toEqual(5); | ||||
|             }); | ||||
|  | ||||
|             it("converts coordinates appropriately for a line", function () { | ||||
|                 uAMLine(false); | ||||
|                 expect(mockLineProxy.element.x).toEqual(91); | ||||
|                 expect(mockLineProxy.element.y).toEqual(136); | ||||
|                 expect(mockLineProxy.element.x2).toEqual(117); | ||||
|                 expect(mockLineProxy.element.y2).toEqual(170); | ||||
|                 expect(mockLineProxy.element.width).toEqual(143); | ||||
|                 expect(mockLineProxy.element.height).toEqual(204); | ||||
|                 uAMLine(true); | ||||
|                 expect(mockLineProxy.element.x).toEqual(7); | ||||
|                 expect(mockLineProxy.element.y).toEqual(8); | ||||
|                 expect(mockLineProxy.element.x2).toEqual(9); | ||||
|                 expect(mockLineProxy.element.y2).toEqual(10); | ||||
|                 expect(mockLineProxy.element.width).toEqual(11); | ||||
|                 expect(mockLineProxy.element.height).toEqual(12); | ||||
|             }); | ||||
|  | ||||
|             it("doesn't covert coordinates unecessarily", function () { | ||||
|                 uAM(false); | ||||
|                 expect(mockElementProxy.element.x).toEqual(26); | ||||
|                 expect(mockElementProxy.element.y).toEqual(51); | ||||
|                 expect(mockElementProxy.element.width).toEqual(52); | ||||
|                 expect(mockElementProxy.element.height).toEqual(85); | ||||
|                 uAM(false); | ||||
|                 expect(mockElementProxy.element.x).toEqual(26); | ||||
|                 expect(mockElementProxy.element.y).toEqual(51); | ||||
|                 expect(mockElementProxy.element.width).toEqual(52); | ||||
|                 expect(mockElementProxy.element.height).toEqual(85); | ||||
|             }); | ||||
|  | ||||
|             it("snaps coordinates onto the grid", function () { | ||||
|                 uAM(false); | ||||
|                 mockElementProxy.element.x += 11; | ||||
|                 mockElementProxy.element.y -= 27; | ||||
|                 mockElementProxy.element.width -= 14; | ||||
|                 mockElementProxy.element.height += 4; | ||||
|                 uAM(true); | ||||
|                 expect(mockElementProxy.element.x).toEqual(3); | ||||
|                 expect(mockElementProxy.element.y).toEqual(1); | ||||
|                 expect(mockElementProxy.element.width).toEqual(3); | ||||
|                 expect(mockElementProxy.element.height).toEqual(5); | ||||
|             }); | ||||
|  | ||||
|             it("enforces a minimum height and width", function () { | ||||
|                 uAM(false); | ||||
|                 mockElementProxy.element.width = 4; | ||||
|                 mockElementProxy.element.height = 4; | ||||
|                 uAM(true); | ||||
|                 expect(mockElementProxy.element.width).toEqual(1); | ||||
|                 expect(mockElementProxy.element.height).toEqual(1); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -45,7 +45,6 @@ define([ | ||||
|                             "key": "url", | ||||
|                             "name": "URL", | ||||
|                             "control": "textfield", | ||||
|                             "pattern": "^(ftp|https?)\\:\\/\\/", | ||||
|                             "required": true, | ||||
|                             "cssClass": "l-input-lg" | ||||
|                         }, | ||||
|   | ||||
| @@ -1,22 +1,18 @@ | ||||
| <div class="t-imagery" ng-controller="ImageryController as imagery"> | ||||
| <div class="t-imagery c-imagery" ng-controller="ImageryController as imagery"> | ||||
|     <mct-split-pane class='abs' anchor="bottom" alias="imagery"> | ||||
|     <div class="split-pane-component has-local-controls l-image-main-wrapper l-flex-col" | ||||
|         ng-mouseenter="showLocalControls = true;" | ||||
|         ng-mouseleave="showLocalControls = false;"> | ||||
|         <div class="h-local-controls h-local-controls-overlay-content h-local-controls-trans s-local-controls local-controls-hidden l-flex-row"> | ||||
|             <span class="holder flex-elem grows"> | ||||
|     <div class="split-pane-component has-local-controls l-image-main-wrapper l-flex-col"> | ||||
|         <div class="h-local-controls h-local-controls--overlay-content c-local-controls--show-on-hover l-flex-row c-imagery__lc"> | ||||
|             <span class="holder flex-elem grows c-imagery__lc__sliders"> | ||||
|                 <input class="icon-brightness" type="range" | ||||
|                        min="0" | ||||
|                        max="500" | ||||
|                        ng-model="filters.brightness"> | ||||
|                 </input> | ||||
|                        ng-model="filters.brightness" /> | ||||
|                 <input class="icon-contrast" type="range" | ||||
|                        min="0" | ||||
|                        max="500" | ||||
|                        ng-model="filters.contrast"> | ||||
|                 </input> | ||||
|                        ng-model="filters.contrast" /> | ||||
|             </span> | ||||
|             <span class="holder flex-elem t-reset-btn-holder"> | ||||
|             <span class="holder flex-elem t-reset-btn-holder c-imagery__lc__reset-btn"> | ||||
|                 <a class="s-icon-button icon-reset t-btn-reset" | ||||
|                    ng-click="filters = { brightness: 100, contrast: 100 }"></a> | ||||
|             </span> | ||||
| @@ -33,14 +29,14 @@ | ||||
|  | ||||
|         <div class="l-image-main-controlbar flex-elem l-flex-row"> | ||||
|             <div class="l-datetime-w flex-elem grows"> | ||||
|                 <a class="s-button show-thumbs sm hidden icon-thumbs-strip" | ||||
|                 <a class="c-button show-thumbs sm hidden icon-thumbs-strip" | ||||
|                     ng-click="showThumbsBubble = (showThumbsBubble) ? false:true"></a> | ||||
|                 <span class="l-time">{{imagery.getTime()}}</span> | ||||
|             </div> | ||||
|             <div class="h-local-controls flex-elem"> | ||||
|                 <a class="s-button pause-play" | ||||
|                 <a class="c-button icon-pause pause-play" | ||||
|                     ng-click="imagery.paused(!imagery.paused())" | ||||
|                     ng-class="{ paused: imagery.paused() }"></a> | ||||
|                     ng-class="{ 'is-paused': imagery.paused() }"></a> | ||||
|                 <a href="" | ||||
|                     class="s-button l-mag s-mag vsm icon-reset" | ||||
|                     ng-click="clipped = false" | ||||
|   | ||||
| @@ -47,7 +47,6 @@ define([ | ||||
|                             "key": "url", | ||||
|                             "name": "URL", | ||||
|                             "control": "textfield", | ||||
|                             "pattern": "^(ftp|https?)\\:\\/\\/", | ||||
|                             "required": true, | ||||
|                             "cssClass": "l-input-lg" | ||||
|                         } | ||||
|   | ||||
| @@ -19,13 +19,13 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <form name="mctForm" novalidate class="form l-flex-col"> | ||||
| <form name="mctForm" novalidate class="form c-form" autocomplete="off"> | ||||
|     <span ng-repeat="section in structure.sections" | ||||
|           class="l-form-section l-flex-col flex-elem {{ section.cssClass }}"> | ||||
|         <h2 class="section-header flex-elem" ng-if="section.name"> | ||||
|           class="l-form-section c-form__section {{ section.cssClass }}"> | ||||
|         <h2 class="c-form__header" ng-if="section.name"> | ||||
|             {{section.name}} | ||||
|         </h2> | ||||
|         <ng-form class="form-row validates l-flex-row flex-elem {{ section.cssClass }}" | ||||
|         <ng-form class="form-row c-form__row validates {{ section.cssClass }}" | ||||
|                  ng-class="{ | ||||
|                  first:$index < 1, | ||||
|                  req: row.required, | ||||
| @@ -37,11 +37,11 @@ | ||||
|                  }" | ||||
|                  name="mctFormInner" | ||||
|                  ng-repeat="row in section.rows"> | ||||
|             <div class='label flex-elem' title="{{row.description}}"> | ||||
|             <div class='c-form__row__label label flex-elem' title="{{row.description}}"> | ||||
|                 {{row.name}} | ||||
|             </div> | ||||
|             <div class='controls flex-elem'> | ||||
|                 <div class="wrapper" ng-if="row.control"> | ||||
|             <div class='c-form__row__controls controls flex-elem'> | ||||
|                 <div class="c-form__controls-wrapper wrapper" ng-if="row.control"> | ||||
|                     <mct-control key="row.control" | ||||
|                                  ng-model="ngModel" | ||||
|                                  ng-required="row.required" | ||||
|   | ||||
| @@ -29,13 +29,22 @@ define( | ||||
|         function SnapshotPreviewController($scope, openmct) { | ||||
|  | ||||
|             $scope.previewImage = function (imageUrl) { | ||||
|                 var image = document.createElement('img'); | ||||
|                 image.src = imageUrl; | ||||
|                 let imageDiv = document.createElement('div'); | ||||
|                 imageDiv.classList = 'image-main s-image-main'; | ||||
|                 imageDiv.style.backgroundImage = `url(${imageUrl})`; | ||||
|  | ||||
|                 openmct.overlays.overlay( | ||||
|                 let previewImageOverlay = openmct.overlays.overlay( | ||||
|                     { | ||||
|                         element: image, | ||||
|                         size: 'large' | ||||
|                         element: imageDiv, | ||||
|                         size: 'large', | ||||
|                         buttons: [ | ||||
|                             { | ||||
|                                 label: 'Done', | ||||
|                                 callback: function () { | ||||
|                                     previewImageOverlay.dismiss(); | ||||
|                                 } | ||||
|                             } | ||||
|                         ] | ||||
|                     } | ||||
|                 ); | ||||
|             }; | ||||
| @@ -43,13 +52,13 @@ define( | ||||
|             $scope.annotateImage = function (ngModel, field, imageUrl) { | ||||
|                 $scope.imageUrl = imageUrl; | ||||
|  | ||||
|                 var div = document.createElement('div'), | ||||
|                 let div = document.createElement('div'), | ||||
|                     painterroInstance = {}, | ||||
|                     save = false; | ||||
|  | ||||
|                 div.id = 'snap-annotation'; | ||||
|  | ||||
|                 openmct.overlays.overlay( | ||||
|                 let annotateImageOverlay = openmct.overlays.overlay( | ||||
|                     { | ||||
|                         element: div, | ||||
|                         size: 'large', | ||||
| @@ -59,6 +68,7 @@ define( | ||||
|                                 callback: function () { | ||||
|                                     save = false; | ||||
|                                     painterroInstance.save(); | ||||
|                                     annotateImageOverlay.dismiss(); | ||||
|                                 } | ||||
|                             }, | ||||
|                             { | ||||
| @@ -66,6 +76,7 @@ define( | ||||
|                                 callback: function () { | ||||
|                                     save = true; | ||||
|                                     painterroInstance.save(); | ||||
|                                     annotateImageOverlay.dismiss(); | ||||
|                                 } | ||||
|                             } | ||||
|                         ] | ||||
| @@ -97,7 +108,7 @@ define( | ||||
|                     }, | ||||
|                     saveHandler: function (image, done) { | ||||
|                         if (save) { | ||||
|                             var url = image.asBlob(), | ||||
|                             let url = image.asBlob(), | ||||
|                                 reader = new window.FileReader(); | ||||
|  | ||||
|                             reader.readAsDataURL(url); | ||||
|   | ||||
| @@ -37,75 +37,17 @@ define( | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle persistence failures by providing the user with a | ||||
|          * dialog summarizing these failures, and giving the option | ||||
|          * to overwrite/cancel as appropriate. | ||||
|          * Discard failures | ||||
|          * @param {Array} failures persistence failures, as prepared | ||||
|          *        by PersistenceQueueHandler | ||||
|          * @memberof platform/persistence/queue.PersistenceFailureHandler# | ||||
|          */ | ||||
|         PersistenceFailureHandler.prototype.handle = function handleFailures(failures) { | ||||
|             // Prepare dialog for display | ||||
|  | ||||
|             var dialogModel = new PersistenceFailureDialog(failures), | ||||
|                 revisionErrors = dialogModel.model.revised, | ||||
|                 $q = this.$q; | ||||
|  | ||||
|             // Refresh revision information for the domain object associated | ||||
|             // with this persistence failure | ||||
|             function refresh(failure) { | ||||
|                 // Refresh the domain object to the latest from persistence | ||||
|                 return failure.persistence.refresh(); | ||||
|             } | ||||
|  | ||||
|             // Issue a new persist call for the domain object associated with | ||||
|             // this failure. | ||||
|             function persist(failure) { | ||||
|                 // Note that we reissue the persist request here, but don't | ||||
|                 // return it, to avoid a circular wait. We trust that the | ||||
|                 // PersistenceQueue will behave correctly on the next round | ||||
|                 // of flushing. | ||||
|                 failure.requeue(); | ||||
|             } | ||||
|  | ||||
|             // Retry persistence (overwrite) for this set of failed attempts | ||||
|             function retry(failuresToRetry) { | ||||
|                 var models = {}; | ||||
|  | ||||
|                 // Cache a copy of the model | ||||
|                 function cacheModel(failure) { | ||||
|                     // Clone... | ||||
|                     models[failure.id] = JSON.parse(JSON.stringify( | ||||
|                         failure.domainObject.getModel() | ||||
|                     )); | ||||
|                 } | ||||
|  | ||||
|                 // Mutate a domain object to restore its model | ||||
|                 function remutate(failure) { | ||||
|                     var model = models[failure.id]; | ||||
|                     return failure.domainObject.useCapability( | ||||
|                         "mutation", | ||||
|                         function () { | ||||
|                             return model; | ||||
|                         }, | ||||
|                         model.modified | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 // Cache the object models we might want to save | ||||
|                 failuresToRetry.forEach(cacheModel); | ||||
|  | ||||
|                 // Strategy here: | ||||
|                 // * Cache all of the models we might want to save (above) | ||||
|                 // * Refresh all domain objects (so they are latest versions) | ||||
|                 // * Re-insert the cached domain object models | ||||
|                 // * Invoke persistence again | ||||
|                 return $q.all(failuresToRetry.map(refresh)).then(function () { | ||||
|                     return $q.all(failuresToRetry.map(remutate)); | ||||
|                 }).then(function () { | ||||
|                     return $q.all(failuresToRetry.map(persist)); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             // Discard changes for a failed refresh | ||||
|             function discard(failure) { | ||||
|                 var persistence = | ||||
| @@ -118,19 +60,7 @@ define( | ||||
|                 return $q.all(failuresToDiscard.map(discard)); | ||||
|             } | ||||
|  | ||||
|             // Handle user input (did they choose to overwrite?) | ||||
|             function handleChoice(key) { | ||||
|                 // If so, try again | ||||
|                 if (key === PersistenceFailureConstants.OVERWRITE_KEY) { | ||||
|                     return retry(revisionErrors); | ||||
|                 } else { | ||||
|                     return discardAll(revisionErrors); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Prompt for user input, the overwrite if they said so. | ||||
|             return this.dialogService.getUserChoice(dialogModel) | ||||
|                 .then(handleChoice, handleChoice); | ||||
|             return discardAll(revisionErrors); | ||||
|         }; | ||||
|  | ||||
|         return PersistenceFailureHandler; | ||||
|   | ||||
| @@ -74,43 +74,14 @@ define( | ||||
|                 handler = new PersistenceFailureHandler(mockQ, mockDialogService); | ||||
|             }); | ||||
|  | ||||
|             it("shows a dialog to handle failures", function () { | ||||
|             it("discards on handle", function () { | ||||
|                 handler.handle(mockFailures); | ||||
|                 expect(mockDialogService.getUserChoice).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("overwrites on request", function () { | ||||
|                 mockQ.all.and.returnValue(asPromise([])); | ||||
|                 handler.handle(mockFailures); | ||||
|                 // User chooses overwrite | ||||
|                 mockPromise.then.calls.mostRecent().args[0](Constants.OVERWRITE_KEY); | ||||
|                 // Should refresh, remutate, and requeue all objects | ||||
|                 mockFailures.forEach(function (mockFailure, i) { | ||||
|                     expect(mockFailure.persistence.refresh).toHaveBeenCalled(); | ||||
|                     expect(mockFailure.requeue).toHaveBeenCalled(); | ||||
|                     expect(mockFailure.domainObject.useCapability).toHaveBeenCalledWith( | ||||
|                         'mutation', | ||||
|                         jasmine.any(Function), | ||||
|                         i // timestamp | ||||
|                     ); | ||||
|                     expect(mockFailure.domainObject.useCapability.calls.mostRecent().args[1]()) | ||||
|                         .toEqual({ id: mockFailure.id, modified: i }); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("discards on request", function () { | ||||
|                 mockQ.all.and.returnValue(asPromise([])); | ||||
|                 handler.handle(mockFailures); | ||||
|                 // User chooses overwrite | ||||
|                 mockPromise.then.calls.mostRecent().args[0](false); | ||||
|                 // Should refresh, but not remutate, and requeue all objects | ||||
|                 mockFailures.forEach(function (mockFailure) { | ||||
|                     expect(mockFailure.persistence.refresh).toHaveBeenCalled(); | ||||
|                     expect(mockFailure.requeue).not.toHaveBeenCalled(); | ||||
|                     expect(mockFailure.domainObject.useCapability).not.toHaveBeenCalled(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
|   | ||||
| @@ -45,7 +45,7 @@ | ||||
|                 </mct-include> | ||||
|             </div> | ||||
|  | ||||
|             <a class="s-button c-search__btn-cancel" | ||||
|             <a class="c-button c-search__btn-cancel" | ||||
|                ng-show="!(ngModel.input === '' || ngModel.input === undefined)" | ||||
|                ng-click="ngModel.input = ''; ngModel.checkAll = true; menuController.checkAll(); controller.search()"> | ||||
|                 Cancel</a> | ||||
|   | ||||
							
								
								
									
										38
									
								
								src/MCT.js
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								src/MCT.js
									
									
									
									
									
								
							| @@ -43,6 +43,10 @@ define([ | ||||
|     './ui/layout/Layout.vue', | ||||
|     '../platform/core/src/objects/DomainObjectImpl', | ||||
|     '../platform/core/src/capabilities/ContextualDomainObject', | ||||
|     './ui/preview/plugin', | ||||
|     './api/Branding', | ||||
|     './plugins/licenses/plugin', | ||||
|     './plugins/remove/plugin', | ||||
|     'vue' | ||||
| ], function ( | ||||
|     EventEmitter, | ||||
| @@ -67,6 +71,10 @@ define([ | ||||
|     Layout, | ||||
|     DomainObjectImpl, | ||||
|     ContextualDomainObject, | ||||
|     PreviewPlugin, | ||||
|     BrandingAPI, | ||||
|     LicensesPlugin, | ||||
|     RemoveActionPlugin, | ||||
|     Vue | ||||
| ) { | ||||
|     /** | ||||
| @@ -87,6 +95,13 @@ define([ | ||||
|      */ | ||||
|     function MCT() { | ||||
|         EventEmitter.call(this); | ||||
|         this.buildInfo = { | ||||
|             version: __OPENMCT_VERSION__, | ||||
|             buildDate: __OPENMCT_BUILD_DATE__, | ||||
|             revision: __OPENMCT_REVISION__, | ||||
|             branch: __OPENMCT_BUILD_BRANCH__ | ||||
|         }; | ||||
|  | ||||
|         this.legacyBundle = { extensions: { | ||||
|             services: [ | ||||
|                 { | ||||
| @@ -226,16 +241,21 @@ define([ | ||||
|  | ||||
|         this.contextMenu = new api.ContextMenuRegistry(); | ||||
|  | ||||
|         this.router = new ApplicationRouter(); | ||||
|  | ||||
|         this.branding = BrandingAPI.default; | ||||
|  | ||||
|         this.legacyRegistry = defaultRegistry; | ||||
|         this.install(this.plugins.Plot()); | ||||
|         this.install(this.plugins.TelemetryTable()); | ||||
|         this.install(this.plugins.DisplayLayout()); | ||||
|         this.install(this.plugins.Preview()); | ||||
|         this.install(PreviewPlugin.default()); | ||||
|         this.install(LegacyIndicatorsPlugin()); | ||||
|         this.install(LicensesPlugin.default()); | ||||
|         this.install(RemoveActionPlugin.default()); | ||||
|  | ||||
|         if (typeof BUILD_CONSTANTS !== 'undefined') { | ||||
|             this.install(buildInfoPlugin(BUILD_CONSTANTS)); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     MCT.prototype = Object.create(EventEmitter.prototype); | ||||
| @@ -306,6 +326,12 @@ define([ | ||||
|      *        MCT; if undefined, MCT will be run in the body of the document | ||||
|      */ | ||||
|     MCT.prototype.start = function (domElement) { | ||||
|         if (!this.plugins.DisplayLayout._installed) { | ||||
|             this.install(this.plugins.DisplayLayout({ | ||||
|                 showAsView: ['summary-widget'] | ||||
|             })); | ||||
|         } | ||||
|  | ||||
|         if (!domElement) { | ||||
|             domElement = document.body; | ||||
|         } | ||||
| @@ -329,12 +355,8 @@ define([ | ||||
|         legacyRegistry.register('adapter', this.legacyBundle); | ||||
|         legacyRegistry.enable('adapter'); | ||||
|  | ||||
|         this.install(LegacyIndicatorsPlugin()); | ||||
|  | ||||
|         this.router = new ApplicationRouter(); | ||||
|  | ||||
|         this.router.route(/^\/$/, () => { | ||||
|             this.router.setPath('/browse/mine'); | ||||
|             this.router.setPath('/browse/'); | ||||
|         }); | ||||
|  | ||||
|         /** | ||||
|   | ||||
| @@ -33,20 +33,25 @@ export default class LegacyContextMenuAction { | ||||
|     } | ||||
|  | ||||
|     invoke(objectPath) { | ||||
|         let context = { | ||||
|             category: 'contextual', | ||||
|             domainObject: this.openmct.legacyObject(objectPath) | ||||
|         } | ||||
|         let legacyAction = new this.LegacyAction(context); | ||||
|         this.openmct.objects.getRoot().then((root) => { | ||||
|             let pathWithRoot = objectPath.slice(); | ||||
|             pathWithRoot.push(root); | ||||
|  | ||||
|         if (!legacyAction.getMetadata) { | ||||
|             let metadata = Object.create(this.LegacyAction.definition); | ||||
|             metadata.context = context; | ||||
|             legacyAction.getMetadata = function () { | ||||
|                 return metadata; | ||||
|             }.bind(legacyAction); | ||||
|         } | ||||
|         legacyAction.perform(); | ||||
|             let context = { | ||||
|                 category: 'contextual', | ||||
|                 domainObject: this.openmct.legacyObject(pathWithRoot) | ||||
|             } | ||||
|             let legacyAction = new this.LegacyAction(context); | ||||
|  | ||||
|             if (!legacyAction.getMetadata) { | ||||
|                 let metadata = Object.create(this.LegacyAction.definition); | ||||
|                 metadata.context = context; | ||||
|                 legacyAction.getMetadata = function () { | ||||
|                     return metadata; | ||||
|                 }.bind(legacyAction); | ||||
|             } | ||||
|             legacyAction.perform(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     appliesTo(objectPath) { | ||||
|   | ||||
| @@ -137,8 +137,7 @@ define([ | ||||
|         function callbackWrapper(series) { | ||||
|             callback(createDatum(domainObject, metadata, series, series.getPointCount() - 1)); | ||||
|         } | ||||
|  | ||||
|         return capability.subscribe(callbackWrapper, request); | ||||
|         return capability.subscribe(callbackWrapper, request) || function () {}; | ||||
|     }; | ||||
|  | ||||
|     LegacyTelemetryProvider.prototype.supportsLimits = function (domainObject) { | ||||
| @@ -158,7 +157,7 @@ define([ | ||||
|  | ||||
|         return { | ||||
|             evaluate: function (datum, property) { | ||||
|                 return limitEvaluator.evaluate(datum, property.key); | ||||
|                 return limitEvaluator.evaluate(datum, property && property.key); | ||||
|             } | ||||
|         }; | ||||
|     }; | ||||
|   | ||||
| @@ -57,12 +57,11 @@ define([ | ||||
|         }.bind(this); | ||||
|  | ||||
|         handleLegacyMutation = function (legacyObject) { | ||||
|             var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId()); | ||||
|             var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId()), | ||||
|                 keystring = utils.makeKeyString(newStyleObject.identifier); | ||||
|  | ||||
|             //Don't trigger self | ||||
|             this.eventEmitter.off('mutation', handleMutation); | ||||
|             this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject); | ||||
|             this.eventEmitter.on('mutation', handleMutation); | ||||
|             this.eventEmitter.emit(keystring + ":*", newStyleObject); | ||||
|             this.eventEmitter.emit('mutation', newStyleObject); | ||||
|         }.bind(this); | ||||
|  | ||||
|         this.eventEmitter.on('mutation', handleMutation); | ||||
|   | ||||
| @@ -21,7 +21,9 @@ define([ | ||||
|             name: legacyView.name, | ||||
|             cssClass: legacyView.cssClass, | ||||
|             description: legacyView.description, | ||||
|             editable: legacyView.editable, | ||||
|             canEdit: function () { | ||||
|                 return legacyView.editable === true; | ||||
|             }, | ||||
|             canView: function (domainObject) { | ||||
|                 if (!domainObject || !domainObject.identifier) { | ||||
|                     return false; | ||||
| @@ -46,12 +48,22 @@ define([ | ||||
|                 let scope = $rootScope.$new(); | ||||
|                 let legacyObject = convertToLegacyObject(domainObject); | ||||
|                 let isDestroyed = false; | ||||
|                 let unlistenToStatus; | ||||
|                 scope.domainObject = legacyObject; | ||||
|                 scope.model = legacyObject.getModel(); | ||||
|  | ||||
|  | ||||
|                 return { | ||||
|                     show: function (container) { | ||||
|                         let statusCapability = legacyObject.getCapability('status'); | ||||
|                         unlistenToStatus = statusCapability.listen((newStatus) => { | ||||
|                             container.classList.remove('s-status-timeconductor-unsynced'); | ||||
|  | ||||
|                             if (newStatus.includes('timeconductor-unsynced')) { | ||||
|                                 container.classList.add('s-status-timeconductor-unsynced'); | ||||
|                             } | ||||
|                         }); | ||||
|  | ||||
|                         // TODO: implement "gestures" support ? | ||||
|                         let uses = legacyView.uses || []; | ||||
|                         let promises = []; | ||||
| @@ -92,6 +104,7 @@ define([ | ||||
|                     }, | ||||
|                     destroy: function () { | ||||
|                         scope.$destroy(); | ||||
|                         unlistenToStatus(); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|   | ||||
| @@ -25,14 +25,20 @@ define([ | ||||
|             cssClass: representation.cssClass, | ||||
|             description: representation.description, | ||||
|             canView: function (selection) { | ||||
|                 if (!selection[0] || !selection[0].context.item) { | ||||
|                 if (selection.length === 0 || selection[0].length === 0) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 let domainObject = selection[0].context.item; | ||||
|                 return domainObject.type === typeDefinition.key; | ||||
|  | ||||
|                 let selectionContext = selection[0][0].context; | ||||
|  | ||||
|                 if (!selectionContext.item) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 return selectionContext.item.type === typeDefinition.key; | ||||
|             }, | ||||
|             view: function (selection) { | ||||
|                 let domainObject = selection[0].context.item; | ||||
|                 let domainObject = selection[0][0].context.item; | ||||
|                 let $rootScope = openmct.$injector.get('$rootScope'); | ||||
|                 let templateLinker = openmct.$injector.get('templateLinker'); | ||||
|                 let scope = $rootScope.$new(); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * Open MCT, Copyright (c) 2014-2019, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -19,46 +19,27 @@ | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| .l-splash, | ||||
| .l-splash:before, | ||||
| .l-splash:after { | ||||
|     background-position: center; | ||||
|     background-repeat: no-repeat; | ||||
|     position: absolute; | ||||
| } | ||||
| 
 | ||||
| .l-splash { | ||||
|     background-size: cover; | ||||
|     top: 0; | ||||
|     right: 0; | ||||
|     bottom: 0; | ||||
|     left: 0; | ||||
|     &:before, | ||||
|     &:after { | ||||
|         background-size: contain; | ||||
|         content: ''; | ||||
|     } | ||||
| 
 | ||||
|     &:before { | ||||
|         // NASA logo, dude
 | ||||
|         $w: 5%; | ||||
|         $m: 10px; | ||||
|         background-image: url('../images/logo-nasa.svg'); | ||||
|         top: $m; | ||||
|         right: auto; | ||||
|         bottom: auto; | ||||
|         left: $m; | ||||
|         height: auto; | ||||
|         width: $w * 2; | ||||
|         padding-bottom: $w; | ||||
|         padding-top: $w; | ||||
|     } | ||||
| 
 | ||||
|     &:after { | ||||
|         // App logo
 | ||||
|         top: 0; | ||||
|         right: 15%; | ||||
|         bottom: 0; | ||||
|         left: 15%; | ||||
|     } | ||||
| 
 | ||||
| let brandingOptions = {}; | ||||
| 
 | ||||
| /** | ||||
|  * @typedef {Object} BrandingOptions | ||||
|  * @memberOf openmct/branding | ||||
|  * @property {string} smallLogoImage URL to the image to use as the applications logo. | ||||
|  * This logo will appear on every screen and when clicked will launch the about dialog. | ||||
|  * @property {string} aboutHtml Custom content for the about screen. When defined the | ||||
|  * supplied content will be inserted at the start of the about dialog, and the default | ||||
|  * Open MCT splash logo will be suppressed. | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * Set branding options for the application. These will override certain visual elements  | ||||
|  * of the application and allow for customization of the application. | ||||
|  * @param {BrandingOptions} options | ||||
|  */ | ||||
| export default function Branding(options) { | ||||
|     if (arguments.length === 1) { | ||||
|         brandingOptions = options; | ||||
|     } | ||||
|     return brandingOptions; | ||||
| } | ||||
| @@ -34,6 +34,7 @@ export default class Editor extends EventEmitter { | ||||
|      * Initiate an editing session. This will start a transaction during | ||||
|      * which any persist operations will be deferred until either save() | ||||
|      * or finish() are called. | ||||
|      * @private | ||||
|      */ | ||||
|     edit() { | ||||
|         if (this.editing === true) { | ||||
| @@ -54,6 +55,8 @@ export default class Editor extends EventEmitter { | ||||
|     /** | ||||
|      * Save any unsaved changes from this editing session. This will | ||||
|      * end the current transaction. | ||||
|      * | ||||
|      * @private | ||||
|      */ | ||||
|     save() { | ||||
|         return this.getTransactionService().commit().then((result)=>{ | ||||
| @@ -67,11 +70,15 @@ export default class Editor extends EventEmitter { | ||||
|  | ||||
|     /** | ||||
|      * End the currently active transaction and discard unsaved changes. | ||||
|      * | ||||
|      * @private | ||||
|      */ | ||||
|     cancel() { | ||||
|         this.getTransactionService().cancel(); | ||||
|         let cancelPromise = this.getTransactionService().cancel(); | ||||
|         this.editing = false; | ||||
|         this.emit('isEditing', false); | ||||
|  | ||||
|         return cancelPromise; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -21,7 +21,11 @@ define([ | ||||
|             topicService.and.returnValue(mutationTopic); | ||||
|             publicAPI = {}; | ||||
|             publicAPI.objects = jasmine.createSpyObj('ObjectAPI', [ | ||||
|                 'get' | ||||
|                 'get', | ||||
|                 'mutate' | ||||
|             ]); | ||||
|             publicAPI.objects.eventEmitter = jasmine.createSpyObj('eventemitter', [ | ||||
|                 'on' | ||||
|             ]); | ||||
|             publicAPI.objects.get.and.callFake(function (identifier) { | ||||
|                 return Promise.resolve({identifier: identifier}); | ||||
| @@ -52,6 +56,14 @@ define([ | ||||
|                         { | ||||
|                             namespace: 'test', | ||||
|                             key: 'a' | ||||
|                         }, | ||||
|                         { | ||||
|                             namespace: 'test', | ||||
|                             key: 'b' | ||||
|                         }, | ||||
|                         { | ||||
|                             namespace: 'test', | ||||
|                             key: 'c' | ||||
|                         } | ||||
|                     ] | ||||
|                 }; | ||||
| @@ -68,12 +80,45 @@ define([ | ||||
|                 composition.on('add', listener); | ||||
|  | ||||
|                 return composition.load().then(function () { | ||||
|                     expect(listener.calls.count()).toBe(1); | ||||
|                     expect(listener.calls.count()).toBe(3); | ||||
|                     expect(listener).toHaveBeenCalledWith({ | ||||
|                         identifier: {namespace: 'test', key: 'a'} | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
|             describe('supports reordering of composition', function () { | ||||
|                 var listener; | ||||
|                 beforeEach(function () { | ||||
|                     listener = jasmine.createSpy('reorderListener'); | ||||
|                     composition.on('reorder', listener); | ||||
|                      | ||||
|                     return composition.load(); | ||||
|                 }); | ||||
|                 it('', function () { | ||||
|                     composition.reorder(1, 0); | ||||
|                     let newComposition = | ||||
|                         publicAPI.objects.mutate.calls.mostRecent().args[2]; | ||||
|                     let reorderPlan = listener.calls.mostRecent().args[0][0]; | ||||
|  | ||||
|                     expect(reorderPlan.oldIndex).toBe(1); | ||||
|                     expect(reorderPlan.newIndex).toBe(0); | ||||
|                     expect(newComposition[0].key).toEqual('b'); | ||||
|                     expect(newComposition[1].key).toEqual('a'); | ||||
|                     expect(newComposition[2].key).toEqual('c'); | ||||
|                 }); | ||||
|                 it('', function () { | ||||
|                     composition.reorder(0, 2); | ||||
|                     let newComposition = | ||||
|                         publicAPI.objects.mutate.calls.mostRecent().args[2]; | ||||
|                     let reorderPlan = listener.calls.mostRecent().args[0][0]; | ||||
|  | ||||
|                     expect(reorderPlan.oldIndex).toBe(0); | ||||
|                     expect(reorderPlan.newIndex).toBe(2); | ||||
|                     expect(newComposition[0].key).toEqual('b'); | ||||
|                     expect(newComposition[1].key).toEqual('c'); | ||||
|                     expect(newComposition[2].key).toEqual('a'); | ||||
|                 }) | ||||
|             }); | ||||
|  | ||||
|             // TODO: Implement add/removal in new default provider. | ||||
|             xit('synchronizes changes between instances', function () { | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user