Compare commits
	
		
			1 Commits
		
	
	
		
			view-large
			...
			tutorial-s
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | b3ea6612bc | 
							
								
								
									
										44
									
								
								API.md
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								API.md
									
									
									
									
									
								
							| @@ -129,10 +129,8 @@ provider. | ||||
|  | ||||
| The "composition" of a domain object is the list of objects it contains, | ||||
| as shown (for example) in the tree for browsing. Open MCT provides a | ||||
| [default solution](#default-composition-provider) for composition, but there | ||||
| may be cases where you want to provide the composition of a certain object | ||||
| (or type of object) dynamically. | ||||
|  | ||||
| default solution for composition, but there may be cases where you want | ||||
| to provide the composition of a certain object (or type of object) dynamically. | ||||
| For instance, you may want to populate a hierarchy under a custom root-level | ||||
| object based on the contents of a telemetry dictionary. | ||||
| To do this, you can add a new CompositionProvider: | ||||
| @@ -148,29 +146,6 @@ openmct.composition.addProvider({ | ||||
| }); | ||||
| ``` | ||||
|  | ||||
| #### Default Composition Provider | ||||
|  | ||||
| The default composition provider applies to any domain object with | ||||
| a `composition` property. The value of `composition` should be an | ||||
| array of identifiers, e.g.: | ||||
|  | ||||
| ```js | ||||
| var domainObject = { | ||||
|     name: "My Object", | ||||
|     type: 'folder', | ||||
|     composition: [ | ||||
|         { | ||||
|             key: '412229c3-922c-444b-8624-736d85516247', | ||||
|             namespace: 'foo' | ||||
|         }, | ||||
|         { | ||||
|             key: 'd6e0ce02-5b85-4e55-8006-a8a505b64c75', | ||||
|             namespace: 'foo' | ||||
|         } | ||||
|     ] | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| ### Adding Telemetry Providers | ||||
|  | ||||
| When connecting to a new telemetry source, you will want to register a new | ||||
| @@ -294,27 +269,12 @@ The plugin will be invoked to configure Open MCT before it is started. | ||||
|  | ||||
| Open MCT is packaged along with a few general-purpose plugins: | ||||
|  | ||||
| * `openmct.plugins.CouchDB` is an adapter for using CouchDB for persistence | ||||
|   of user-created objects. This is a constructor that takes the URL for the | ||||
|   CouchDB database as a parameter, e.g. | ||||
|   `openmct.install(new openmct.plugins.CouchDB('http://localhost:5984/openmct'))` | ||||
| * `openmct.plugins.Elasticsearch` is an adapter for using Elasticsearch for | ||||
|   persistence of user-created objects. This is a | ||||
|   constructor that takes the URL for the Elasticsearch instance as a | ||||
|   parameter, e.g. | ||||
|   `openmct.install(new openmct.plugins.CouchDB('http://localhost:9200'))`. | ||||
|   Domain objects will be indexed at `/mct/domain_object`. | ||||
| * `openmct.plugins.espresso` and `openmct.plugins.snow` are two different | ||||
|   themes (dark and light) available for Open MCT. Note that at least one | ||||
|   of these themes must be installed for Open MCT to appear correctly. | ||||
| * `openmct.plugins.localStorage` provides persistence of user-created | ||||
|   objects in browser-local storage. This is particularly useful in | ||||
|   development environments. | ||||
| * `openmct.plugins.myItems` adds a top-level folder named "My Items" | ||||
|   when the application is first started, providing a place for a | ||||
|   user to store created items. | ||||
| * `openmct.plugins.utcTimeSystem` provides support for using the time | ||||
|   conductor with UTC time. | ||||
|  | ||||
| Generally, you will want to either install these plugins, or install | ||||
| different plugins that provide persistence and an initial folder | ||||
|   | ||||
| @@ -1339,6 +1339,41 @@ are supported: | ||||
| Open MCT defines several Angular directives that are intended for use both  | ||||
| internally within the platform, and by plugins.  | ||||
|   | ||||
| ## Chart  | ||||
|  | ||||
| The `mct-chart` directive is used to support drawing of simple charts. It is  | ||||
| present to support the Plot view, and its functionality is limited to the  | ||||
| functionality that is relevant for that view. | ||||
|  | ||||
| This directive is used at the element level and takes one attribute, `draw`  | ||||
| which is an Angular expression which will should evaluate to a drawing object.  | ||||
| This drawing object should contain the following properties: | ||||
|  | ||||
| * `dimensions`: The size, in logical coordinates, of the chart area. A  | ||||
| two-element array or numbers.  | ||||
| * `origin`: The position, in logical coordinates, of the lower-left corner of  | ||||
| the chart area. A two-element array or numbers.  | ||||
| * `lines`: An array of lines (e.g. as a plot line) to draw, where each line is  | ||||
| expressed as an object containing:  | ||||
|     * `buffer`: A Float32Array containing points in the line, in logical  | ||||
|     coordinates, in sequential x,y pairs.  | ||||
|     * `color`: The color of the line, as a four-element RGBA array, where  | ||||
|     each element is a number in the range of 0.0-1.0.  | ||||
|     * `points`: The number of points in the line.  | ||||
| * `boxes`: An array of rectangles to draw in the chart area. Each is an object  | ||||
| containing:  | ||||
|     * `start`: The first corner of the rectangle, as a two-element array of  | ||||
|     numbers, in logical coordinates.  | ||||
|     * `end`: The opposite corner of the rectangle, as a two-element array of  | ||||
|     numbers, in logical coordinates. color : The color of the line, as a  | ||||
|     four-element RGBA array, where each element is a number in the range of  | ||||
|     0.0-1.0.  | ||||
|  | ||||
| While `mct-chart` is intended to support plots specifically, it does perform  | ||||
| some useful management of canvas objects (e.g. choosing between WebGL and Canvas  | ||||
| 2D APIs for drawing based on browser support) so its usage is recommended when  | ||||
| its supported drawing primitives are sufficient for other charting tasks.  | ||||
|   | ||||
| ## Container  | ||||
|  | ||||
| The `mct-container` is similar to the `mct-include` directive insofar as it allows  | ||||
|   | ||||
							
								
								
									
										13
									
								
								docs/src/tutorials/hello.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docs/src/tutorials/hello.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|     <head> | ||||
|         <script src="openmct.js"></script> | ||||
|     </head> | ||||
|     <body> | ||||
|         <script type="text/javascript"> | ||||
|             openmct.install(openmct.plugins.localStorage); | ||||
|             openmct.install(openmct.plugins.myItems); | ||||
|             openmct.start(); | ||||
|         </script> | ||||
|     </body> | ||||
| </html> | ||||
| @@ -129,7 +129,7 @@ We will create this file in the directory tutorials/todo (we can hereafter refer | ||||
| to this plugin as tutorials/todo as well.) We will start with an "empty bundle",  | ||||
| one which exposes no extensions - which looks like: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct' | ||||
| ], function ( | ||||
| @@ -154,7 +154,7 @@ The tutorials will be updated with the new bundle registration mechanism once it | ||||
| has been finalized.  | ||||
|  | ||||
| #### Before | ||||
| ```html | ||||
| ```diff | ||||
| <!-- | ||||
|  Open MCT, Copyright (c) 2014-2016, United States Government | ||||
|  as represented by the Administrator of the National Aeronautics and Space | ||||
| @@ -219,7 +219,7 @@ __index.html__ | ||||
|  | ||||
| #### After | ||||
|  | ||||
| ```html | ||||
| ```diff | ||||
| <!-- | ||||
|  Open MCT, Copyright (c) 2014-2016, United States Government | ||||
|  as represented by the Administrator of the National Aeronautics and Space | ||||
| @@ -305,7 +305,7 @@ In the case of our to-do list feature, the to-do list itself is the thing we'll | ||||
| want users to be able to create and edit. So, we will add that as a new type in  | ||||
| our bundle definition: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct' | ||||
| ], function ( | ||||
| @@ -340,9 +340,8 @@ Going through the properties we've defined: | ||||
| domain objects of this type. | ||||
| * The `name` of "To-Do List" is the human-readable name for this type, and will  | ||||
| be shown to users. | ||||
| * The `cssclass` maps to an icon that will be shown for each To-Do List. The icons  | ||||
| are defined in our [custom open MCT icon set](https://github.com/nasa/openmct/blob/master/platform/commonUI/general/res/sass/_glyphs.scss).  | ||||
| A complete list of available icons will be provided in the future. | ||||
| * The `glyph` refers to a special character in Open MCT's custom font set;  | ||||
| this will be used as an icon. | ||||
| * The `description` is also human-readable, and will be used whenever a longer  | ||||
| explanation of what this type is should be shown. | ||||
| * Finally, the `features` property describes some special features of objects of  | ||||
| @@ -370,7 +369,7 @@ directory `tutorials/todo/res/templates` (`res` is, by default, the directory | ||||
| where bundle-related resources are kept, and `templates` is where HTML templates  | ||||
| are stored by convention.) | ||||
|  | ||||
| ```html | ||||
| ```diff | ||||
| <div> | ||||
|     <a href="">All</a> | ||||
|     <a href="">Incomplete</a> | ||||
| @@ -402,7 +401,7 @@ boolean `completed` flag. | ||||
| To expose this view in Open MCT, we need to declare it in our bundle  | ||||
| definition: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct' | ||||
| ], function ( | ||||
| @@ -447,7 +446,7 @@ the domain object type, but could have chosen any unique name. | ||||
| domain objects of that type. This means that we'll see this view for To-do Lists  | ||||
| that we create, but not for other domain objects (such as Folders.) | ||||
|  | ||||
| * The `cssclass` and `name` properties describe the icon and human-readable name  | ||||
| * The `glyph` and `name` properties describe the icon and human-readable name  | ||||
| for this view to display in the UI where needed (if multiple views are available  | ||||
| for To-do Lists, the user will be able to choose one.) | ||||
|  | ||||
| @@ -459,7 +458,7 @@ the user to create these yet. As a temporary workaround to test the view, we | ||||
| will specify an initial state for To-do List domain object models in the  | ||||
| definition of that type. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct' | ||||
| ], function ( | ||||
| @@ -530,7 +529,7 @@ in the directory `tutorials/todo/src/controllers` (`src` is, by default, the | ||||
| directory where bundle-related source code is kept, and controllers is where  | ||||
| Angular controllers are stored by convention.) | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define(function () { | ||||
|     function TodoController($scope) { | ||||
|         var showAll = true, | ||||
| @@ -595,7 +594,7 @@ prior to our template being utilized. | ||||
| On its own, this controller merely exposes these functions; the next step is to  | ||||
| use them from our template: | ||||
|  | ||||
| ```html | ||||
| ```diff | ||||
| +  <div ng-controller="TodoController"> | ||||
|         <div> | ||||
| +          <a ng-click="setVisibility(true)">All</a> | ||||
| @@ -631,7 +630,7 @@ If we were to try to run at this point, we'd run into problems because the | ||||
| `TodoController` has not been registered with Angular. We need to first declare  | ||||
| it in our bundle definition, as an extension of category `controllers`: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct', | ||||
| +    './src/controllers/TodoController' | ||||
| @@ -725,7 +724,7 @@ An Editing user interface is typically handled in a tool bar associated with a | ||||
| view. The contents of this tool bar are defined declaratively in a view's  | ||||
| extension definition. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct', | ||||
|     './src/controllers/TodoController' | ||||
| @@ -814,7 +813,7 @@ all the applicable controls, which means no controls at all. | ||||
|  | ||||
| To support selection, we will need to make some changes to our controller: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define(function () { | ||||
| +    // Form to display when adding new tasks | ||||
| +    var NEW_TASK_FORM = { | ||||
| @@ -929,7 +928,7 @@ Additionally, we need to make changes to our template to select specific tasks | ||||
| in response to some user gesture. Here, we will select tasks when a user clicks  | ||||
| the description. | ||||
|  | ||||
| ```html | ||||
| ```diff | ||||
| <div ng-controller="TodoController"> | ||||
|     <div> | ||||
|         <a ng-click="setVisibility(true)">All</a> | ||||
| @@ -955,7 +954,7 @@ __tutorials/todo/res/templates/todo.html__ | ||||
| Finally, the `TodoController` uses the `dialogService` now, so we need to  | ||||
| declare that dependency in its extension definition: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct', | ||||
|     './src/controllers/TodoController' | ||||
| @@ -1059,7 +1058,7 @@ In this section, our goal is to: | ||||
| To support the first two, we'll need to expose some methods for checking these  | ||||
| states in the controller: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define(function () { | ||||
|     // Form to display when adding new tasks | ||||
|     var NEW_TASK_FORM = { | ||||
| @@ -1176,7 +1175,7 @@ states visually, and to generally improve the appearance of our view. We add | ||||
| another file to the res directory of our bundle; this time, it is `css/todo.css`  | ||||
| (with the `css` directory again being a convention.) | ||||
|  | ||||
| ```css | ||||
| ```diff | ||||
| .example-todo div.example-button-group { | ||||
|     margin-top: 12px; | ||||
|     margin-bottom: 12px; | ||||
| @@ -1220,7 +1219,7 @@ To include this CSS file in our running instance of Open MCT, we need to | ||||
| declare it in our bundle definition, this time as an extension of category  | ||||
| `stylesheets`: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct', | ||||
|     './src/controllers/TodoController' | ||||
| @@ -1300,7 +1299,7 @@ To-Do List's type above; now To-Do Lists will start off empty. | ||||
|  | ||||
| Finally, let's utilize these changes from our view's template: | ||||
|  | ||||
| ```html | ||||
| ```diff | ||||
| + <div ng-controller="TodoController" class="example-todo"> | ||||
| +     <div class="example-button-group"> | ||||
| +         <a ng-class="{ selected: checkVisibility(true) }" | ||||
| @@ -1360,7 +1359,7 @@ We'll also be defining some custom styles, so we'll include that extension as | ||||
| well. We'll be creating this plugin in `tutorials/bargraph`, so our initial  | ||||
| bundle definition looks like: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct' | ||||
| ], function ( | ||||
| @@ -1407,7 +1406,7 @@ For this tutorial, we'll assume that we've sketched out our template and CSS | ||||
| file ahead of time to describe the general look we want for the view. These  | ||||
| look like: | ||||
|  | ||||
| ```html | ||||
| ```diff | ||||
| <div class="example-bargraph"> | ||||
|     <div class="example-tick-labels"> | ||||
|         <div class="example-tick-label" style="bottom: 0%">High</div> | ||||
| @@ -1458,7 +1457,7 @@ bar corresponds to which telemetry point. Inline `style` attributes are used | ||||
| wherever dynamic positioning (handled by a script) is anticipated. | ||||
| The corresponding CSS file which styles and positions these elements: | ||||
|  | ||||
| ```css | ||||
| ```diff | ||||
| .example-bargraph { | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
| @@ -1556,7 +1555,7 @@ Notably, we will not try to show telemetry data after this step. | ||||
|  | ||||
| To support this, we will add a new controller which supports our Bar Graph view: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define(function () { | ||||
|     function BarGraphController($scope, telemetryHandler) { | ||||
|         var handle; | ||||
| @@ -1608,7 +1607,7 @@ telemetry objects in view, as well as the width for each bar. | ||||
|  | ||||
| We will also utilize this from our template: | ||||
|  | ||||
| ```html | ||||
| ```diff | ||||
| + <div class="example-bargraph" ng-controller="BarGraphController"> | ||||
|     <div class="example-tick-labels"> | ||||
| +       <div ng-repeat="value in [low, middle, high] track by $index" | ||||
| @@ -1661,7 +1660,7 @@ Finally, we expose our controller from our bundle definition. Note that the | ||||
| depends declaration includes both `$scope` as well as the `telemetryHandler`  | ||||
| service we made use of. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct', | ||||
|     './src/controllers/BarGraphController' | ||||
| @@ -1716,7 +1715,7 @@ First, let's add expose some more functionality from our controller. To make it | ||||
| simple, we'll expose the top and bottom for a bar graph for a given  | ||||
| telemetry-providing domain object, as percentages. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define(function () { | ||||
|     function BarGraphController($scope, telemetryHandler) { | ||||
|         var handle; | ||||
| @@ -1768,7 +1767,7 @@ decide this. | ||||
|  | ||||
| Next, we utilize this functionality from the template: | ||||
|  | ||||
| ```html | ||||
| ```diff | ||||
| <div class="example-bargraph" ng-controller="BarGraphController"> | ||||
|     <div class="example-tick-labels"> | ||||
|         <div ng-repeat="value in [low, middle, high] track by $index" | ||||
| @@ -1827,7 +1826,7 @@ when we return to our view later, those changes will be persisted. | ||||
|  | ||||
| First, let's add a tool bar for changing these three values in Edit mode: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct', | ||||
|     './src/controllers/BarGraphController' | ||||
| @@ -1901,7 +1900,7 @@ a view proxy to work from. We will add this to our controller, and additionally | ||||
| will start reading/writing those properties to the view's `configuration`  | ||||
| object. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define(function () { | ||||
|     function BarGraphController($scope, telemetryHandler) { | ||||
|         var handle; | ||||
| @@ -2024,7 +2023,7 @@ For purposes of this tutorial, a simple node server is provided to stand | ||||
| in place of this existing telemetry system. It generates real-time data  | ||||
| and exposes it over a WebSocket connection. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global require,process,console*/ | ||||
|  | ||||
| var CONFIG = { | ||||
| @@ -2206,7 +2205,7 @@ used by the server. It uses a custom format and, for purposes of example, | ||||
| contains three "subsystems" containing a mix of numeric and string-based  | ||||
| telemetry. | ||||
|  | ||||
| ```json | ||||
| ```diff | ||||
| { | ||||
|     "name": "Example Spacecraft", | ||||
|     "identifier": "sc", | ||||
| @@ -2433,7 +2432,7 @@ server. Our first step will be to add a service that will handle interactions | ||||
| with the server; this will not be used by Open MCT directly, but will be  | ||||
| used by subsequent components we add. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global define,WebSocket*/ | ||||
|  | ||||
| define( | ||||
| @@ -2488,7 +2487,7 @@ subsystems. This means that we need to convert the data from the dictionary | ||||
| into domain object models, and expose these to Open MCT via a  | ||||
| `modelService`. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global define*/ | ||||
|  | ||||
| define( | ||||
| @@ -2622,7 +2621,7 @@ This allows our telemetry dictionary to be expressed as domain object models | ||||
| fix this, we will need another script which will add these subsystems to the  | ||||
| root-level object we added in Step 1. | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global define*/ | ||||
|  | ||||
| define( | ||||
| @@ -2687,7 +2686,7 @@ Finally, we wire in these changes by modifying our plugin's `bundle.js` to | ||||
| provide metadata about how these pieces interact (both with each other, and  | ||||
| with the platform): | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct', | ||||
| +   './src/ExampleTelemetryServerAdapter', | ||||
| @@ -2835,7 +2834,7 @@ will do so for the server's historical telemetry. | ||||
| Our first step will be to add a method to our server adapter which allows us to  | ||||
| send history requests to the server: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global define,WebSocket*/ | ||||
|  | ||||
| define( | ||||
| @@ -2894,7 +2893,7 @@ identifier, the pending promise is resolved. | ||||
| This `history` method will be used by a `telemetryService` provider which we  | ||||
| will implement: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global define*/ | ||||
|  | ||||
| define( | ||||
| @@ -2980,7 +2979,7 @@ Finally, note that we also have a `subscribe` method, to satisfy the interface o | ||||
|  | ||||
| This script uses an `ExampleTelemetrySeries` class, which looks like: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global define*/ | ||||
|  | ||||
| define( | ||||
| @@ -3012,7 +3011,7 @@ it with the interface expected by the platform (the methods shown.) | ||||
|  | ||||
| Finally, we expose this `telemetryService` provider declaratively: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| define([ | ||||
|     'openmct', | ||||
|     './src/ExampleTelemetryServerAdapter', | ||||
| @@ -3127,7 +3126,7 @@ Finally, we want to utilize the server's ability to subscribe to telemetry | ||||
| from Open MCT. To do this, first we want to expose some new methods for  | ||||
| this from our server adapter: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global define,WebSocket*/ | ||||
|  | ||||
| define( | ||||
| @@ -3200,7 +3199,7 @@ with these subscriptions. | ||||
|  | ||||
| We then need only to utilize these methods from our `telemetryService`: | ||||
|  | ||||
| ```js | ||||
| ```diff | ||||
| /*global define*/ | ||||
|  | ||||
| define( | ||||
| @@ -3306,4 +3305,4 @@ server can handle this.) | ||||
| Running Open MCT again, we can still plot our historical telemetry - but  | ||||
| now we also see that it updates in real-time as more data comes in from the  | ||||
| server. | ||||
|   | ||||
|   | ||||
| @@ -37,79 +37,74 @@ define([ | ||||
|     legacyRegistry.register("example/msl", { | ||||
|         "name" : "Mars Science Laboratory Data Adapter", | ||||
|         "extensions" : { | ||||
|             "types": [ | ||||
|                 { | ||||
|                     "name":"Mars Science Laboratory", | ||||
|                     "key": "msl.curiosity", | ||||
|                     "cssclass": "icon-object" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Instrument", | ||||
|                     "key": "msl.instrument", | ||||
|                     "cssclass": "icon-object", | ||||
|                     "model": {"composition": []} | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Measurement", | ||||
|                     "key": "msl.measurement", | ||||
|                     "cssclass": "icon-telemetry", | ||||
|                     "model": {"telemetry": {}}, | ||||
|                     "telemetry": { | ||||
|                         "source": "rems.source", | ||||
|                         "domains": [ | ||||
|                             { | ||||
|                                 "name": "Time", | ||||
|                                 "key": "utc", | ||||
|                                 "format": "utc" | ||||
|                             } | ||||
|                         ] | ||||
|                     } | ||||
|         "types": [ | ||||
|             { | ||||
|                 "name":"Mars Science Laboratory", | ||||
|                 "key": "msl.curiosity", | ||||
|                 "cssclass": "icon-object" | ||||
|             }, | ||||
|             { | ||||
|                 "name": "Instrument", | ||||
|                 "key": "msl.instrument", | ||||
|                 "cssclass": "icon-object", | ||||
|                 "model": {"composition": []} | ||||
|             }, | ||||
|             { | ||||
|                 "name": "Measurement", | ||||
|                 "key": "msl.measurement", | ||||
|                 "cssclass": "icon-telemetry", | ||||
|                 "model": {"telemetry": {}}, | ||||
|                 "telemetry": { | ||||
|                     "source": "rems.source", | ||||
|                     "domains": [ | ||||
|                         { | ||||
|                             "name": "Time", | ||||
|                             "key": "utc", | ||||
|                             "format": "utc" | ||||
|                         } | ||||
|                     ] | ||||
|                 } | ||||
|             ], | ||||
|             "constants": [ | ||||
|                 { | ||||
|                     "key": "REMS_WS_URL", | ||||
|                     "value": "/proxyUrl?url=http://cab.inta-csic.es/rems/wp-content/plugins/marsweather-widget/api.php" | ||||
|             } | ||||
|         ], | ||||
|         "constants": [ | ||||
|             { | ||||
|                 "key": "REMS_WS_URL", | ||||
|                 "value": "/proxyUrl?url=http://cab.inta-csic.es/rems/wp-content/plugins/marsweather-widget/api.php" | ||||
|             } | ||||
|         ], | ||||
|         "roots": [ | ||||
|             { | ||||
|                 "id": "msl:curiosity", | ||||
|                 "priority" : "preferred", | ||||
|                 "model": { | ||||
|                     "type": "msl.curiosity", | ||||
|                     "name": "Mars Science Laboratory", | ||||
|                     "composition": ["msl_tlm:rems"] | ||||
|                 } | ||||
|             ], | ||||
|             "roots": [ | ||||
|                 { | ||||
|                     "id": "msl:curiosity" | ||||
|                 } | ||||
|             ], | ||||
|             "models": [ | ||||
|                 { | ||||
|                     "id": "msl:curiosity", | ||||
|                     "priority": "preferred", | ||||
|                     "model": { | ||||
|                         "type": "msl.curiosity", | ||||
|                         "name": "Mars Science Laboratory", | ||||
|                         "composition": ["msl_tlm:rems"] | ||||
|                     } | ||||
|                 } | ||||
|             ], | ||||
|             "services": [ | ||||
|                 { | ||||
|                     "key":"rems.adapter", | ||||
|                     "implementation": RemsTelemetryServerAdapter, | ||||
|                     "depends": ["$q", "$http", "$log", "REMS_WS_URL"] | ||||
|                 } | ||||
|             ], | ||||
|             "components": [ | ||||
|                 { | ||||
|                     "provides": "modelService", | ||||
|                     "type": "provider", | ||||
|                     "implementation": RemsTelemetryModelProvider, | ||||
|                     "depends": ["rems.adapter"] | ||||
|                 }, | ||||
|                 { | ||||
|                     "provides": "telemetryService", | ||||
|                     "type": "provider", | ||||
|                     "implementation": RemsTelemetryProvider, | ||||
|                     "depends": ["rems.adapter", "$q"] | ||||
|                 } | ||||
|             ] | ||||
|         } | ||||
|             } | ||||
|         ], | ||||
|         "services": [ | ||||
|             { | ||||
|                 "key":"rems.adapter", | ||||
|                 "implementation": RemsTelemetryServerAdapter, | ||||
|                 "depends": ["$q", "$http", "$log", "REMS_WS_URL"] | ||||
|             } | ||||
|         ], | ||||
|         "components": [ | ||||
|             { | ||||
|                 "provides": "modelService", | ||||
|                 "type": "provider", | ||||
|                 "implementation": RemsTelemetryModelProvider, | ||||
|                 "depends": ["rems.adapter"] | ||||
|             }, | ||||
|             { | ||||
|                 "provides": "telemetryService", | ||||
|                 "type": "provider", | ||||
|                 "implementation": RemsTelemetryProvider, | ||||
|                 "depends": ["rems.adapter", "$q"] | ||||
|             } | ||||
|         ] | ||||
|     } | ||||
|     }); | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -33,11 +33,6 @@ define([ | ||||
|     legacyRegistry.register("example/scratchpad", { | ||||
|         "extensions": { | ||||
|             "roots": [ | ||||
|                 { | ||||
|                     "id": "scratch:root" | ||||
|                 } | ||||
|             ], | ||||
|             "models": [ | ||||
|                 { | ||||
|                     "id": "scratch:root", | ||||
|                     "model": { | ||||
|   | ||||
| @@ -35,11 +35,6 @@ define([ | ||||
|         "description": "Example illustrating the addition of a static top-level hierarchy", | ||||
|         "extensions": { | ||||
|             "roots": [ | ||||
|                 { | ||||
|                     "id": "exampleTaxonomy" | ||||
|                 } | ||||
|             ], | ||||
|             "models": [ | ||||
|                 { | ||||
|                     "id": "exampleTaxonomy", | ||||
|                     "model": { | ||||
|   | ||||
| @@ -32,13 +32,12 @@ | ||||
|             [ | ||||
|                 'example/imagery', | ||||
|                 'example/eventGenerator', | ||||
|                 'example/generator' | ||||
|                 'example/generator', | ||||
|                 'platform/features/my-items', | ||||
|                 'platform/persistence/local' | ||||
|             ].forEach( | ||||
|                 openmct.legacyRegistry.enable.bind(openmct.legacyRegistry) | ||||
|             ); | ||||
|             openmct.install(openmct.plugins.myItems); | ||||
|             openmct.install(openmct.plugins.localStorage); | ||||
|             openmct.install(openmct.plugins.espresso); | ||||
|             openmct.start(); | ||||
|         }); | ||||
|     </script> | ||||
|   | ||||
| @@ -76,7 +76,7 @@ module.exports = function(config) { | ||||
|         // Specify browsers to run tests in. | ||||
|         // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher | ||||
|         browsers: [ | ||||
|             'Chrome' | ||||
|             'PhantomJS' | ||||
|         ], | ||||
|  | ||||
|         // Code coverage reporting. | ||||
|   | ||||
| @@ -25,12 +25,13 @@ | ||||
|     "jsdoc": "^3.3.2", | ||||
|     "jshint": "^2.7.0", | ||||
|     "karma": "^0.13.3", | ||||
|     "karma-chrome-launcher": "^0.1.12", | ||||
|     "karma-chrome-launcher": "^0.1.8", | ||||
|     "karma-cli": "0.0.4", | ||||
|     "karma-coverage": "^0.5.3", | ||||
|     "karma-html-reporter": "^0.2.7", | ||||
|     "karma-jasmine": "^0.1.5", | ||||
|     "karma-junit-reporter": "^0.3.8", | ||||
|     "karma-phantomjs-launcher": "^1.0.0", | ||||
|     "karma-requirejs": "^0.2.2", | ||||
|     "lodash": "^3.10.1", | ||||
|     "markdown-toc": "^0.11.7", | ||||
| @@ -39,6 +40,7 @@ | ||||
|     "mkdirp": "^0.5.1", | ||||
|     "moment": "^2.11.1", | ||||
|     "node-bourbon": "^4.2.3", | ||||
|     "phantomjs-prebuilt": "2.1.11 || >2.1.12 <3.0.0", | ||||
|     "requirejs": "2.1.x", | ||||
|     "split": "^1.0.0" | ||||
|   }, | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <div ng-controller="BrowseObjectController" class="abs l-flex-col"> | ||||
|     <div class="holder flex-elem l-flex-row object-browse-bar"> | ||||
|     <div class="holder flex-elem l-flex-row object-browse-bar "> | ||||
|         <div class="items-select left flex-elem l-flex-row grows"> | ||||
|             <mct-representation key="'back-arrow'" | ||||
|                                 mct-object="domainObject" | ||||
| @@ -31,18 +31,16 @@ | ||||
|             </mct-representation> | ||||
|         </div> | ||||
|         <div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed"> | ||||
|             <span class="l-object-action-buttons"> | ||||
|                 <mct-representation key="'switcher'" | ||||
|                                     mct-object="domainObject" | ||||
|                                     ng-model="representation"> | ||||
|                 </mct-representation> | ||||
|                 <!-- Temporarily, on mobile, the action buttons are hidden--> | ||||
|                 <mct-representation key="'action-group'" | ||||
|                                     mct-object="domainObject" | ||||
|                                     parameters="{ category: 'view-control' }" | ||||
|                                     class="mobile-hide l-object-action-buttons"> | ||||
|                 </mct-representation> | ||||
|             </span> | ||||
|             <mct-representation key="'switcher'" | ||||
|                                 mct-object="domainObject" | ||||
|                                 ng-model="representation"> | ||||
|             </mct-representation> | ||||
|             <!-- Temporarily, on mobile, the action buttons are hidden--> | ||||
|             <mct-representation key="'action-group'" | ||||
|                                 mct-object="domainObject" | ||||
|                                 parameters="{ category: 'view-control' }" | ||||
|                                 class="mobile-hide"> | ||||
|             </mct-representation> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="holder l-flex-col flex-elem grows l-object-wrapper l-controls-visible l-time-controller-visible"> | ||||
|   | ||||
| @@ -28,8 +28,4 @@ | ||||
|         key="'menu-arrow'" | ||||
|         mct-object='domainObject' | ||||
|         class="flex-elem context-available-w"></mct-representation> | ||||
| </span> | ||||
| <a class="s-button icon-expand t-btn-view-large" | ||||
|    title="View large" | ||||
|    mct-trigger-modal> | ||||
| </a> | ||||
| </span> | ||||
| @@ -53,8 +53,7 @@ define([ | ||||
|                     "depends": [ | ||||
|                         "overlayService", | ||||
|                         "$q", | ||||
|                         "$log", | ||||
|                         "$document" | ||||
|                         "$log" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|   | ||||
| @@ -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="abs overlay l-dialog" ng-class="{'delayEntry100ms' : ngModel.delay}"> | ||||
| <div class="abs overlay" ng-class="{'delayEntry100ms' : ngModel.delay}"> | ||||
|     <div class="abs blocker"></div> | ||||
|     <div class="abs holder"> | ||||
|         <a ng-click="ngModel.cancel()" | ||||
|   | ||||
| @@ -35,15 +35,11 @@ define( | ||||
|          * @memberof platform/commonUI/dialog | ||||
|          * @constructor | ||||
|          */ | ||||
|         function DialogService(overlayService, $q, $log, $document) { | ||||
|         function DialogService(overlayService, $q, $log) { | ||||
|             this.overlayService = overlayService; | ||||
|             this.$q = $q; | ||||
|             this.$log = $log; | ||||
|             this.activeOverlay = undefined; | ||||
|  | ||||
|             this.findBody = function () { | ||||
|                 return $document.find('body'); | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
| @@ -64,8 +60,7 @@ define( | ||||
|             // input is asynchronous. | ||||
|             var deferred = this.$q.defer(), | ||||
|                 self = this, | ||||
|                 overlay, | ||||
|                 handleEscKeydown; | ||||
|                 overlay; | ||||
|  | ||||
|             // Confirm function; this will be passed in to the | ||||
|             // overlay-dialog template and associated with a | ||||
| @@ -81,22 +76,13 @@ define( | ||||
|             // Cancel or X button click | ||||
|             function cancel() { | ||||
|                 deferred.reject(); | ||||
|                 self.findBody().off('keydown', handleEscKeydown); | ||||
|                 self.dismissOverlay(overlay); | ||||
|             } | ||||
|  | ||||
|             handleEscKeydown = function (event) { | ||||
|                 if (event.keyCode === 27) { | ||||
|                     cancel(); | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             // Add confirm/cancel callbacks | ||||
|             model.confirm = confirm; | ||||
|             model.cancel = cancel; | ||||
|  | ||||
|             this.findBody().on('keydown', handleEscKeydown); | ||||
|  | ||||
|             if (this.canShowDialog(model)) { | ||||
|                 // Add the overlay using the OverlayService, which | ||||
|                 // will handle actual insertion into the DOM | ||||
|   | ||||
| @@ -33,8 +33,6 @@ define( | ||||
|                 mockLog, | ||||
|                 mockOverlay, | ||||
|                 mockDeferred, | ||||
|                 mockDocument, | ||||
|                 mockBody, | ||||
|                 dialogService; | ||||
|  | ||||
|             beforeEach(function () { | ||||
| @@ -58,13 +56,6 @@ define( | ||||
|                     "deferred", | ||||
|                     ["resolve", "reject"] | ||||
|                 ); | ||||
|                 mockDocument = jasmine.createSpyObj( | ||||
|                   "$document", | ||||
|                   ["find"] | ||||
|                 ); | ||||
|                 mockBody = jasmine.createSpyObj('body', ['on', 'off']); | ||||
|                 mockDocument.find.andReturn(mockBody); | ||||
|  | ||||
|                 mockDeferred.promise = "mock promise"; | ||||
|  | ||||
|                 mockQ.defer.andReturn(mockDeferred); | ||||
| @@ -73,8 +64,7 @@ define( | ||||
|                 dialogService = new DialogService( | ||||
|                     mockOverlayService, | ||||
|                     mockQ, | ||||
|                     mockLog, | ||||
|                     mockDocument | ||||
|                     mockLog | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
| @@ -140,36 +130,6 @@ define( | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("adds a keydown event listener to the body", function () { | ||||
|                 dialogService.getUserInput({}, {}); | ||||
|                 expect(mockDocument.find).toHaveBeenCalledWith("body"); | ||||
|                 expect(mockBody.on).toHaveBeenCalledWith("keydown", jasmine.any(Function)); | ||||
|             }); | ||||
|  | ||||
|             it("destroys the event listener when the dialog is cancelled", function () { | ||||
|                 dialogService.getUserInput({}, {}); | ||||
|                 mockOverlayService.createOverlay.mostRecentCall.args[1].cancel(); | ||||
|                 expect(mockBody.off).toHaveBeenCalledWith("keydown", jasmine.any(Function)); | ||||
|             }); | ||||
|  | ||||
|             it("cancels the dialog when an escape keydown event is triggered", function () { | ||||
|                 dialogService.getUserInput({}, {}); | ||||
|                 mockBody.on.mostRecentCall.args[1]({ | ||||
|                     keyCode: 27 | ||||
|                 }); | ||||
|                 expect(mockDeferred.reject).toHaveBeenCalled(); | ||||
|                 expect(mockDeferred.resolve).not.toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("ignores non escape keydown events", function () { | ||||
|                 dialogService.getUserInput({}, {}); | ||||
|                 mockBody.on.mostRecentCall.args[1]({ | ||||
|                     keyCode: 13 | ||||
|                 }); | ||||
|                 expect(mockDeferred.reject).not.toHaveBeenCalled(); | ||||
|                 expect(mockDeferred.resolve).not.toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             describe("the blocking message dialog", function () { | ||||
|                 var dialogModel = {}; | ||||
|                 var dialogHandle; | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| { | ||||
|   "metadata": { | ||||
|     "name": "openmct-symbols-16px", | ||||
|     "lastOpened": 1487197651675, | ||||
|     "created": 1487194069058 | ||||
|     "lastOpened": 1481575258437, | ||||
|     "created": 1481575255265 | ||||
|   }, | ||||
|   "iconSets": [ | ||||
|     { | ||||
| @@ -540,21 +540,13 @@ | ||||
|           "code": 921654, | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 120, | ||||
|           "id": 105, | ||||
|           "name": "icon-reset", | ||||
|           "prevSize": 24, | ||||
|           "code": 921655, | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 121, | ||||
|           "id": 103, | ||||
|           "name": "icon-x-in-circle", | ||||
|           "prevSize": 24, | ||||
|           "code": 921656, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 118, | ||||
| @@ -562,7 +554,7 @@ | ||||
|           "name": "icon-brightness", | ||||
|           "prevSize": 24, | ||||
|           "code": 921657, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 119, | ||||
| @@ -570,15 +562,15 @@ | ||||
|           "name": "icon-contrast", | ||||
|           "prevSize": 24, | ||||
|           "code": 921664, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 122, | ||||
|           "id": 106, | ||||
|           "name": "icon-expand", | ||||
|           "order": 120, | ||||
|           "id": 105, | ||||
|           "name": "icon-reset", | ||||
|           "prevSize": 24, | ||||
|           "code": 921665, | ||||
|           "tempChar": "" | ||||
|           "code": 921655, | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 37, | ||||
| @@ -586,7 +578,7 @@ | ||||
|           "name": "icon-activity", | ||||
|           "id": 32, | ||||
|           "code": 921856, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 36, | ||||
| @@ -594,7 +586,7 @@ | ||||
|           "name": "icon-activity-mode", | ||||
|           "id": 31, | ||||
|           "code": 921857, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 52, | ||||
| @@ -602,7 +594,7 @@ | ||||
|           "name": "icon-autoflow-tabular", | ||||
|           "id": 47, | ||||
|           "code": 921858, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 55, | ||||
| @@ -610,7 +602,7 @@ | ||||
|           "name": "icon-clock", | ||||
|           "id": 50, | ||||
|           "code": 921859, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 58, | ||||
| @@ -618,7 +610,7 @@ | ||||
|           "name": "icon-database", | ||||
|           "id": 53, | ||||
|           "code": 921860, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 57, | ||||
| @@ -626,7 +618,7 @@ | ||||
|           "name": "icon-database-query", | ||||
|           "id": 52, | ||||
|           "code": 921861, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 17, | ||||
| @@ -634,7 +626,7 @@ | ||||
|           "name": "icon-dataset", | ||||
|           "id": 12, | ||||
|           "code": 921862, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 22, | ||||
| @@ -642,7 +634,7 @@ | ||||
|           "name": "icon-datatable", | ||||
|           "id": 17, | ||||
|           "code": 921863, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 59, | ||||
| @@ -650,7 +642,7 @@ | ||||
|           "name": "icon-dictionary", | ||||
|           "id": 54, | ||||
|           "code": 921864, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 62, | ||||
| @@ -658,7 +650,7 @@ | ||||
|           "name": "icon-folder", | ||||
|           "id": 57, | ||||
|           "code": 921865, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 66, | ||||
| @@ -666,7 +658,7 @@ | ||||
|           "name": "icon-image", | ||||
|           "id": 61, | ||||
|           "code": 921872, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 68, | ||||
| @@ -674,7 +666,7 @@ | ||||
|           "name": "icon-layout", | ||||
|           "id": 63, | ||||
|           "code": 921873, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 77, | ||||
| @@ -682,7 +674,7 @@ | ||||
|           "name": "icon-object", | ||||
|           "id": 72, | ||||
|           "code": 921874, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 78, | ||||
| @@ -690,7 +682,7 @@ | ||||
|           "name": "icon-object-unknown", | ||||
|           "id": 73, | ||||
|           "code": 921875, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 79, | ||||
| @@ -698,7 +690,7 @@ | ||||
|           "name": "icon-packet", | ||||
|           "id": 74, | ||||
|           "code": 921876, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 80, | ||||
| @@ -706,7 +698,7 @@ | ||||
|           "name": "icon-page", | ||||
|           "id": 75, | ||||
|           "code": 921877, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 114, | ||||
| @@ -714,7 +706,7 @@ | ||||
|           "name": "icon-plot-overlay", | ||||
|           "prevSize": 24, | ||||
|           "code": 921878, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 113, | ||||
| @@ -722,7 +714,7 @@ | ||||
|           "name": "icon-plot-stacked", | ||||
|           "prevSize": 24, | ||||
|           "code": 921879, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 10, | ||||
| @@ -730,7 +722,7 @@ | ||||
|           "name": "icon-session", | ||||
|           "id": 5, | ||||
|           "code": 921880, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 24, | ||||
| @@ -738,7 +730,7 @@ | ||||
|           "name": "icon-tabular", | ||||
|           "id": 19, | ||||
|           "code": 921881, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 7, | ||||
| @@ -746,7 +738,7 @@ | ||||
|           "name": "icon-tabular-lad", | ||||
|           "id": 2, | ||||
|           "code": 921888, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 6, | ||||
| @@ -754,7 +746,7 @@ | ||||
|           "name": "icon-tabular-lad-set", | ||||
|           "id": 1, | ||||
|           "code": 921889, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 8, | ||||
| @@ -762,7 +754,7 @@ | ||||
|           "name": "icon-tabular-realtime", | ||||
|           "id": 3, | ||||
|           "code": 921890, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 23, | ||||
| @@ -770,7 +762,7 @@ | ||||
|           "name": "icon-tabular-scrolling", | ||||
|           "id": 18, | ||||
|           "code": 921891, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 112, | ||||
| @@ -778,7 +770,7 @@ | ||||
|           "name": "icon-telemetry", | ||||
|           "id": 86, | ||||
|           "code": 921892, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 90, | ||||
| @@ -786,7 +778,7 @@ | ||||
|           "name": "icon-telemetry-panel", | ||||
|           "id": 85, | ||||
|           "code": 921893, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 93, | ||||
| @@ -794,7 +786,7 @@ | ||||
|           "name": "icon-timeline", | ||||
|           "id": 88, | ||||
|           "code": 921894, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 116, | ||||
| @@ -802,7 +794,7 @@ | ||||
|           "name": "icon-timer-v1.5", | ||||
|           "prevSize": 24, | ||||
|           "code": 921895, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 11, | ||||
| @@ -810,7 +802,7 @@ | ||||
|           "name": "icon-topic", | ||||
|           "id": 6, | ||||
|           "code": 921896, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 115, | ||||
| @@ -818,7 +810,7 @@ | ||||
|           "name": "icon-box-with-dashed-lines", | ||||
|           "id": 29, | ||||
|           "code": 921897, | ||||
|           "tempChar": "" | ||||
|           "tempChar": "" | ||||
|         } | ||||
|       ], | ||||
|       "metadata": { | ||||
| @@ -2191,30 +2183,6 @@ | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "id": 104, | ||||
|           "paths": [ | ||||
|             "M460.8 460.8l-187.8-187.8c57.2-42.8 128-68.2 204.8-68.2 188.2 0 341.6 153.2 341.6 341.4s-153.2 341.2-341.4 341.2c-165 0-302.8-117.6-334.6-273h-138.4c14.2 101.8 61 195.6 135 269.6 90.2 90.2 210.4 140 338 140s247.6-49.8 338-140 140-210.4 140-338-49.8-247.6-140-338-210.4-140-338-140c-111.4 0-217 38-302 107.6l-176-175.6v460.8h460.8z" | ||||
|           ], | ||||
|           "attrs": [ | ||||
|             { | ||||
|               "fill": "rgb(0, 161, 75)" | ||||
|             } | ||||
|           ], | ||||
|           "isMulticolor": false, | ||||
|           "isMulticolor2": false, | ||||
|           "grid": 16, | ||||
|           "tags": [ | ||||
|             "icon-reset" | ||||
|           ], | ||||
|           "colorPermutations": { | ||||
|             "1161751207457516161751": [ | ||||
|               { | ||||
|                 "f": 1 | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "paths": [ | ||||
|             "M512 0c-282.8 0-512 229.2-512 512s229.2 512 512 512 512-229.2 512-512-229.2-512-512-512zM832 704l-128 128-192-192-192 192-128-128 192-192-192-192 128-128 192 192 192-192 128 128-192 192 192 192z" | ||||
| @@ -2335,31 +2303,26 @@ | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "id": 106, | ||||
|           "id": 104, | ||||
|           "paths": [ | ||||
|             "M960 0c0 0 0 0 0 0h-320v128h165.4l-210.6 210.8c-25 25-25 65.6 0 90.6 12.4 12.4 28.8 18.8 45.2 18.8s32.8-6.2 45.2-18.8l210.8-210.8v165.4h128v-384h-64z", | ||||
|             "M896 805.4l-210.8-210.6c-25-25-65.6-25-90.6 0s-25 65.6 0 90.6l210.8 210.6h-165.4v128h384v-384h-128v165.4z", | ||||
|             "M218.6 128h165.4v-128h-320c0 0 0 0 0 0h-64v384h128v-165.4l210.8 210.8c12.4 12.4 28.8 18.8 45.2 18.8s32.8-6.2 45.2-18.8c25-25 25-65.6 0-90.6l-210.6-210.8z", | ||||
|             "M338.8 594.8l-210.8 210.6v-165.4h-128v384h384v-128h-165.4l210.8-210.8c25-25 25-65.6 0-90.6-25.2-24.8-65.6-24.8-90.6 0.2z" | ||||
|             "M460.8 460.8l-187.8-187.8c57.2-42.8 128-68.2 204.8-68.2 188.2 0 341.6 153.2 341.6 341.4s-153.2 341.2-341.4 341.2c-165 0-302.8-117.6-334.6-273h-138.4c14.2 101.8 61 195.6 135 269.6 90.2 90.2 210.4 140 338 140s247.6-49.8 338-140 140-210.4 140-338-49.8-247.6-140-338-210.4-140-338-140c-111.4 0-217 38-302 107.6l-176-175.6v460.8h460.8z" | ||||
|           ], | ||||
|           "attrs": [ | ||||
|             {}, | ||||
|             {}, | ||||
|             {}, | ||||
|             {} | ||||
|           ], | ||||
|           "grid": 16, | ||||
|           "tags": [ | ||||
|             "icon-expand" | ||||
|             { | ||||
|               "fill": "rgb(0, 161, 75)" | ||||
|             } | ||||
|           ], | ||||
|           "isMulticolor": false, | ||||
|           "isMulticolor2": false, | ||||
|           "grid": 16, | ||||
|           "tags": [ | ||||
|             "icon-reset" | ||||
|           ], | ||||
|           "colorPermutations": { | ||||
|             "1161751207457516161751": [ | ||||
|               {}, | ||||
|               {}, | ||||
|               {}, | ||||
|               {} | ||||
|               { | ||||
|                 "f": 1 | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| @@ -77,7 +77,6 @@ | ||||
| <glyph unicode="󡀸" glyph-name="icon-x-in-circle" d="M512 960c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM832 256l-128-128-192 192-192-192-128 128 192 192-192 192 128 128 192-192 192 192 128-128-192-192 192-192z" /> | ||||
| <glyph unicode="󡀹" glyph-name="icon-brightness" d="M253.414 641.939l-155.172 116.384c-50.233-66.209-85.127-146.713-97.91-234.39l191.586-30.216c8.145 56.552 29.998 106.879 62.068 149.006zM191.98 402.283l-191.919-27.434c13.115-90.459 48.009-170.963 99.174-238.453l154.18 117.665c-31.476 41.347-53.309 91.675-61.231 146.504zM466.283 768.020l-27.434 191.919c-90.459-13.115-170.963-48.009-238.453-99.174l117.665-154.18c41.347 31.476 91.675 53.309 146.504 61.231zM822.323 861.758c-66.209 50.233-146.713 85.127-234.39 97.91l-30.216-191.586c56.552-8.145 106.879-29.998 149.006-62.068zM832.020 493.717l191.919 27.434c-13.115 90.459-48.009 170.963-99.174 238.453l-154.18-117.665c31.476-41.347 53.309-91.675 61.231-146.504zM201.677 34.242c66.209-50.233 146.713-85.127 234.39-97.91l30.216 191.586c-56.552 8.145-106.879 29.998-149.006 62.068zM770.586 254.061l155.131-116.343c50.233 66.209 85.127 146.713 97.91 234.39l-191.586 30.216c-8.125-56.564-29.966-106.906-62.028-149.049zM557.717 127.98l27.434-191.919c90.459 13.115 170.963 48.009 238.453 99.174l-117.665 154.18c-41.347-31.476-91.675-53.309-146.504-61.231zM770.586 448c0-142.813-115.773-258.586-258.586-258.586s-258.586 115.773-258.586 258.586c0 142.813 115.773 258.586 258.586 258.586s258.586-115.773 258.586-258.586z" /> | ||||
| <glyph unicode="󡁀" glyph-name="icon-contrast" d="M512 960c-282.78 0-512-229.24-512-512s229.22-512 512-512 512 229.24 512 512-229.22 512-512 512zM783.52 176.48c-69.111-69.481-164.785-112.481-270.502-112.481-0.358 0-0.716 0-1.074 0.001l0.055 768c212.070-0.010 383.982-171.929 383.982-384 0-106.034-42.977-202.031-112.462-271.52z" /> | ||||
| <glyph unicode="󡁁" glyph-name="icon-expand" d="M960 960c0 0 0 0 0 0h-320v-128h165.4l-210.6-210.8c-25-25-25-65.6 0-90.6 12.4-12.4 28.8-18.8 45.2-18.8s32.8 6.2 45.2 18.8l210.8 210.8v-165.4h128v384h-64zM896 154.6l-210.8 210.6c-25 25-65.6 25-90.6 0s-25-65.6 0-90.6l210.8-210.6h-165.4v-128h384v384h-128v-165.4zM218.6 832h165.4v128h-320c0 0 0 0 0 0h-64v-384h128v165.4l210.8-210.8c12.4-12.4 28.8-18.8 45.2-18.8s32.8 6.2 45.2 18.8c25 25 25 65.6 0 90.6l-210.6 210.8zM338.8 365.2l-210.8-210.6v165.4h-128v-384h384v128h-165.4l210.8 210.8c25 25 25 65.6 0 90.6-25.2 24.8-65.6 24.8-90.6-0.2z" /> | ||||
| <glyph unicode="󡄀" glyph-name="icon-activity" d="M576 896h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" /> | ||||
| <glyph unicode="󡄁" glyph-name="icon-activity-mode" d="M512 960c-214.866 0-398.786-132.372-474.744-320h90.744c56.86 0 107.938-24.724 143.094-64h240.906l-192 192h256l320-320-320-320h-256l192 192h-240.906c-35.156-39.276-86.234-64-143.094-64h-90.744c75.958-187.628 259.878-320 474.744-320 282.77 0 512 229.23 512 512s-229.23 512-512 512z" /> | ||||
| <glyph unicode="󡄂" glyph-name="icon-autoflow-tabular" d="M192 960c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 960h256v-1024h-256v1024zM832 960h-64v-704h256v512c0 105.6-86.4 192-192 192z" /> | ||||
|   | ||||
| Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 39 KiB | 
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -66,7 +66,7 @@ body, html { | ||||
|     color: $colorBodyFg; | ||||
|     font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | ||||
|     font-size: 100%; | ||||
|     font-weight: normal; | ||||
|     font-weight: 200; | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
| } | ||||
|   | ||||
| @@ -73,11 +73,10 @@ $glyph-icon-thumbs-strip: '\e1033'; | ||||
| $glyph-icon-two-parts-both: '\e1034'; | ||||
| $glyph-icon-two-parts-one-only: '\e1035'; | ||||
| $glyph-icon-resync: '\e1036'; | ||||
| $glyph-icon-reset: '\e1037'; | ||||
| $glyph-icon-x-in-circle: '\e1038'; | ||||
| $glyph-icon-brightness: '\e1039'; | ||||
| $glyph-icon-contrast: '\e1040'; | ||||
| $glyph-icon-expand: '\e1041'; | ||||
| $glyph-icon-reset: '\e1037'; | ||||
| $glyph-icon-activity: '\e1100'; | ||||
| $glyph-icon-activity-mode: '\e1101'; | ||||
| $glyph-icon-autoflow-tabular: '\e1102'; | ||||
| @@ -176,12 +175,11 @@ $glyph-icon-box-with-dashed-lines: '\e1129'; | ||||
| .icon-thumbs-strip {  @include glyph($glyph-icon-thumbs-strip); } | ||||
| .icon-two-parts-both {  @include glyph($glyph-icon-two-parts-both); } | ||||
| .icon-two-parts-one-only {  @include glyph($glyph-icon-two-parts-one-only); } | ||||
| .icon-resync {  @include glyph($glyph-icon-resync); } | ||||
| .icon-reset {  @include glyph($glyph-icon-reset); } | ||||
| .icon-x-in-circle {  @include glyph($glyph-icon-x-in-circle); } | ||||
| .icon-brightness {  @include glyph($glyph-icon-brightness); } | ||||
| .icon-contrast {  @include glyph($glyph-icon-contrast); } | ||||
| .icon-expand {  @include glyph($glyph-icon-expand); } | ||||
| .icon-reset {  @include glyph($glyph-icon-reset); } | ||||
| .icon-resync {  @include glyph($glyph-icon-resync); } | ||||
| .icon-activity {  @include glyph($glyph-icon-activity); } | ||||
| .icon-activity-mode {  @include glyph($glyph-icon-activity-mode); } | ||||
| .icon-autoflow-tabular {  @include glyph($glyph-icon-autoflow-tabular); } | ||||
|   | ||||
| @@ -631,8 +631,7 @@ textarea { | ||||
|     } | ||||
| } | ||||
|  | ||||
| .view-switcher, | ||||
| .t-btn-view-large { | ||||
| .view-switcher { | ||||
|     @include trans-prop-nice-fade($controlFadeMs); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -249,7 +249,7 @@ | ||||
| .context-menu-holder, | ||||
| .menu-holder { | ||||
| 	position: absolute; | ||||
| 	z-index: 120; | ||||
| 	z-index: 70; | ||||
| 	.context-menu-wrapper { | ||||
| 		position: absolute; | ||||
| 		height: 100%; | ||||
| @@ -273,7 +273,7 @@ | ||||
|  | ||||
| .btn-bar.right .menu, | ||||
| .menus-to-left .menu { | ||||
|     z-index: 79; | ||||
|         z-index: 79; | ||||
| 	left: auto; | ||||
| 	right: 0; | ||||
| 	width: auto; | ||||
|   | ||||
| @@ -21,16 +21,11 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| .overlay { | ||||
|     font-size: 90%; | ||||
|     &.delayEntry100ms { | ||||
|         @include keyframes(fadeInFromNone) { | ||||
|             0% { | ||||
|                 display: none; | ||||
|                 opacity: 0; | ||||
|             } | ||||
|             100% { | ||||
|                 display: block; | ||||
|                 opacity: 1; | ||||
|             } | ||||
|             0% { display: none; opacity: 0; } | ||||
|             100% { display: block; opacity: 1; } | ||||
|         } | ||||
|         @include animation-delay($delayEntryMs); | ||||
|         @include animation(fadeInFromNone $durEntryMs ease-in); | ||||
| @@ -48,15 +43,21 @@ | ||||
|         left: auto; | ||||
|         z-index: 100; | ||||
|     } | ||||
|  | ||||
|     > .holder { | ||||
|         @include containerSubtle($colorOvrBg, $colorOvrFg); | ||||
|         border-radius: $basicCr * 3; | ||||
|         color: $colorOvrFg; | ||||
|         top: 50%; | ||||
|         right: auto; | ||||
|         bottom: auto; | ||||
|         left: 50%; | ||||
|         @include transform(translateX(-50%) translateY(-50%)); | ||||
|         height: 70%; | ||||
|         width: 50%; | ||||
|         min-height: 300px; | ||||
|         max-height: 800px; | ||||
|         min-width: 600px; | ||||
|         max-width: 1000px; | ||||
|         z-index: 101; | ||||
|         > .contents { | ||||
|             $m: $overlayMargin; | ||||
| @@ -66,106 +67,72 @@ | ||||
|             left: $m; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|     .title { | ||||
|         @include ellipsize(); | ||||
|         font-size: 1.2em; | ||||
|         line-height: 120%; | ||||
|         margin-bottom: $interiorMargin; | ||||
|     } | ||||
|  | ||||
| .overlay { | ||||
|     &.l-dialog { | ||||
|         .s-button { | ||||
|             &:not(.major) { | ||||
|                 @include btnSubtle($bg: $colorOvrBtnBg, $bgHov: pullForward($colorOvrBtnBg, 10%), $fg: $colorOvrBtnFg, $fgHov: $colorOvrBtnFg, $ic: $colorOvrBtnFg, $icHov: $colorOvrBtnFg); | ||||
|     .hint, .field-hints { color: $colorFieldHintOverlay !important;  } | ||||
|  | ||||
|     .abs.top-bar { | ||||
|         height: $ovrTopBarH; | ||||
|     } | ||||
|  | ||||
|     .abs.editor, | ||||
|     .abs.message-body { | ||||
|         top: $ovrTopBarH + $interiorMarginLg; | ||||
|         bottom: $ovrFooterH + $interiorMarginLg; | ||||
|         left: 0; | ||||
|         right: 0; | ||||
|         overflow: auto; | ||||
|         .field.l-input-med { | ||||
|             input[type='text'] { | ||||
|                 width: 100%; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         > .holder { | ||||
|             @include containerSubtle($colorOvrBg, $colorOvrFg); | ||||
|             border-radius: $basicCr * 2; | ||||
|             //color: $colorOvrFg; | ||||
|             height: 70%; | ||||
|             width: 50%; | ||||
|         } | ||||
|  | ||||
|         .title { | ||||
|             @include ellipsize(); | ||||
|             font-size: 1.2em; | ||||
|             line-height: 120%; | ||||
|             margin-bottom: $interiorMargin; | ||||
|         } | ||||
|  | ||||
|         .hint, .field-hints { | ||||
|             color: $colorFieldHintOverlay !important; | ||||
|         } | ||||
|  | ||||
|         .abs.top-bar { | ||||
|             height: $ovrTopBarH; | ||||
|         } | ||||
|  | ||||
|         .abs.bottom-bar { | ||||
|             top: auto; | ||||
|             right: 0; | ||||
|             bottom: 0; | ||||
|             left: 0; | ||||
|             overflow: visible; | ||||
|             height: $ovrFooterH; | ||||
|         } | ||||
|  | ||||
|         .abs.editor, | ||||
|         .abs.message-body { | ||||
|             top: $ovrTopBarH + $interiorMarginLg; | ||||
|             bottom: $ovrFooterH + $interiorMarginLg; | ||||
|             left: 0; | ||||
|             right: 0; | ||||
|             overflow: auto; | ||||
|             .field.l-input-med { | ||||
|                 input[type='text'] { | ||||
|                     width: 100%; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         .bottom-bar { | ||||
|             text-align: right; | ||||
|             .s-button { | ||||
|                 font-size: 95%; | ||||
|                 height: $ovrFooterH; | ||||
|                 line-height: $ovrFooterH; | ||||
|                 margin-left: $interiorMargin; | ||||
|                 padding: 0 $interiorMargin * 3; | ||||
|                 &:first-child { | ||||
|                     margin-left: 0; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         .l-progress-bar { | ||||
|             $h: $progressBarHOverlay; | ||||
|             display: block; | ||||
|             height: $h; | ||||
|             line-height: $h; | ||||
|             margin: .5em 0; | ||||
|             width: 100%; | ||||
|         } | ||||
|  | ||||
|         .select { | ||||
|             box-shadow: $shdwBtnsOverlay; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     &.l-large-view { | ||||
|         > .holder { | ||||
|             @include keyframes(overlayIn) { | ||||
|                 from { opacity: 0; width: 1%; height: 1%; } | ||||
|                 to { opacity: 1; width: 90%; height: 90%; } | ||||
|     .bottom-bar { | ||||
|         text-align: right; | ||||
|         .s-button { | ||||
|             $bg: $colorOvrBtnBg; | ||||
|             &:not(.major) { | ||||
|                 @include btnSubtle($bg, pullForward($bg, 10%), $colorOvrBtnFg, $colorOvrBtnFg); | ||||
|             } | ||||
|             @include animToParams(overlayIn, $dur: 1s, $delay: 0); | ||||
|             background: $colorBodyBg; | ||||
|             border-radius: $basicCr * 2; | ||||
|             //height: 90%; | ||||
|             //width: 90%; | ||||
|  | ||||
|             .t-btn-view-large { | ||||
|                 display: none; | ||||
|             font-size: 95%; | ||||
|             height: $ovrFooterH; | ||||
|             line-height: $ovrFooterH; | ||||
|             margin-left: $interiorMargin; | ||||
|             padding: 0 $interiorMargin * 3; | ||||
|             &:first-child { | ||||
|                 margin-left: 0; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     .abs.bottom-bar { | ||||
|         top: auto; | ||||
|         right: 0; | ||||
|         bottom: 0; | ||||
|         left: 0; | ||||
|         overflow: visible; | ||||
|         height: $ovrFooterH; | ||||
|     } | ||||
|  | ||||
|     .l-progress-bar { | ||||
|         $h: $progressBarHOverlay; | ||||
|         display: block; | ||||
|         height: $h; | ||||
|         line-height: $h; | ||||
|         margin: .5em 0; | ||||
|         width: 100%; | ||||
|     } | ||||
|  | ||||
|     .select { | ||||
|         box-shadow: $shdwBtnsOverlay; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -174,4 +141,4 @@ | ||||
|     $h: 225px; | ||||
|     min-height: $h; | ||||
|     height: $h; | ||||
| } | ||||
| } | ||||
| @@ -20,77 +20,69 @@ | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| .frame { | ||||
|     $ohH: $btnFrameH; | ||||
|     $bc: $colorInteriorBorder; | ||||
|     &.child-frame.panel { | ||||
|         background: $colorBodyBg; | ||||
|         border: 1px solid $bc; | ||||
| 	$ohH: $btnFrameH; | ||||
| 	$bc: $colorInteriorBorder; | ||||
| 	&.child-frame.panel { | ||||
| 		background: $colorBodyBg; | ||||
| 		border: 1px solid $bc; | ||||
|         z-index: 0; // Needed to prevent child-frame controls from showing through when another child-frame is above | ||||
|         &:hover { | ||||
|             border-color: lighten($bc, 10%); | ||||
| 		&:hover { | ||||
| 			border-color: lighten($bc, 10%); | ||||
| 		} | ||||
| 	} | ||||
| 	.object-top-bar { | ||||
| 		font-size: 0.75em; | ||||
| 		height: $ohH; | ||||
| 		line-height: $ohH; | ||||
|         .left { | ||||
|             padding-right: $interiorMarginLg; | ||||
|         } | ||||
|     } | ||||
|     .object-browse-bar { | ||||
|         font-size: 0.75em; | ||||
|         height: $ohH; | ||||
|         line-height: $ohH; | ||||
|     } | ||||
|  | ||||
|     > .object-holder.abs { | ||||
|         top: $ohH + $interiorMargin; | ||||
|     } | ||||
|     .contents { | ||||
|         $myM: $interiorMargin; | ||||
|         top: $myM; | ||||
|         right: $myM; | ||||
|         bottom: $myM; | ||||
|         left: $myM; | ||||
|     } | ||||
|     &.frame-template { | ||||
|         .s-button, | ||||
|         .s-menu-button { | ||||
|             height: $ohH; | ||||
|             line-height: $ohH; | ||||
|             padding: 0 $interiorMargin; | ||||
|             > span, | ||||
| 	} | ||||
| 	>.object-holder.abs { | ||||
| 		top: $ohH + $interiorMargin; | ||||
| 	} | ||||
| 	.contents { | ||||
| 		$myM: $interiorMargin; | ||||
| 		top: $myM; | ||||
| 		right: $myM; | ||||
| 		bottom: $myM; | ||||
| 		left: $myM; | ||||
| 	} | ||||
| 	&.frame-template { | ||||
| 		.s-button, | ||||
| 		.s-menu-button { | ||||
| 			height: $ohH; | ||||
| 			line-height: $ohH; | ||||
| 			padding: 0 $interiorMargin; | ||||
| 			> span, | ||||
|             &:before { | ||||
|                 font-size: 0.65rem; | ||||
|             } | ||||
|         } | ||||
| 				font-size: 0.65rem; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|         .s-menu-button:after { | ||||
|             font-size: 8px; | ||||
|         } | ||||
| 		.s-menu-button:after { | ||||
| 			font-size: 8px; | ||||
| 		} | ||||
|  | ||||
|         .view-switcher { | ||||
|             z-index: 10; | ||||
|         } | ||||
|     } | ||||
|     .view-switcher { | ||||
|         margin-left: $interiorMargin; // Kick other top bar elements away when I'm present. | ||||
|         // Hide the name when the view switcher is in a frame context | ||||
|         .title-label { | ||||
|             display: none; | ||||
|         } | ||||
|     } | ||||
| 		.view-switcher { | ||||
| 			z-index: 10; | ||||
| 		} | ||||
| 	} | ||||
| 	.view-switcher { | ||||
| 		// Hide the name when the view switcher is in a frame context | ||||
| 		.title-label { | ||||
| 			display: none; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| body.desktop .frame { | ||||
|     // Hide local controls initially and show it them on hover when they're in an element that's in a frame context | ||||
|     // Frame template is used because we need to target the lowest nested frame | ||||
|     .view-switcher, | ||||
|     .t-btn-view-large { | ||||
|         opacity: 0; | ||||
|         pointer-events: none; | ||||
|     } | ||||
|  | ||||
|     // Target the first descendant so that we only show the elements in the outermost container. | ||||
|     // Handles the case where we have layouts in layouts. | ||||
|     &:hover > .object-browse-bar { | ||||
|         .view-switcher, | ||||
|         .t-btn-view-large { | ||||
|             opacity: 1; | ||||
|             pointer-events: inherit; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  body.desktop .frame.frame-template { | ||||
|      // Hide the view switcher by default when it's in an element that's in a frame context | ||||
|      // Frame template is used because we need to target the lowest nested frame | ||||
|      .view-switcher { | ||||
|          opacity: 0; | ||||
|      } | ||||
|      &:hover .view-switcher { | ||||
|          // Show the view switcher on frame hover | ||||
|          opacity: 1; | ||||
|      } | ||||
|  } | ||||
| @@ -136,6 +136,14 @@ | ||||
|     .mini-tab-icon.toggle-pane { | ||||
|         z-index: 5; | ||||
|     } | ||||
|     &.items { | ||||
|         .object-browse-bar { | ||||
|             .left.abs, | ||||
|             .right.abs { | ||||
|                 top: auto; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| body.desktop .pane .mini-tab-icon.toggle-pane { | ||||
| @@ -242,9 +250,10 @@ body.desktop .pane .mini-tab-icon.toggle-pane { | ||||
|     vertical-align: top; | ||||
| } | ||||
|  | ||||
| .object-browse-bar { | ||||
|     .l-object-action-buttons { | ||||
|         margin-left: $interiorMarginLg; // Kick the view switcher and other elements away | ||||
| .object-browse-bar, | ||||
| .top-bar { | ||||
|     .view-switcher { | ||||
|         margin-right: $interiorMarginLg * 2; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -256,6 +265,7 @@ body.desktop .pane .mini-tab-icon.toggle-pane { | ||||
|     white-space: nowrap; | ||||
|  | ||||
|     .left { | ||||
|         padding-right: $interiorMarginLg; | ||||
|         .l-back { | ||||
|             margin-right: $interiorMarginLg; | ||||
|             &.s-status-editing { display: none; } | ||||
| @@ -338,7 +348,7 @@ body.desktop { | ||||
|     .pane:not(.resizing) { | ||||
|         @include trans-prop-nice-resize-w(250ms); | ||||
|     } | ||||
|     .pane.primary-pane > .object-browse-bar { | ||||
|     .pane.primary-pane .object-browse-bar { | ||||
|         min-width: 200px; // Needed for nice display when primary pane is constrained severely via splitters | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -24,7 +24,6 @@ define([ | ||||
|     "./src/LayoutController", | ||||
|     "./src/FixedController", | ||||
|     "./src/LayoutCompositionPolicy", | ||||
|     './src/MCTTriggerModal', | ||||
|     "text!./res/templates/layout.html", | ||||
|     "text!./res/templates/fixed.html", | ||||
|     "text!./res/templates/frame.html", | ||||
| @@ -38,7 +37,6 @@ define([ | ||||
|     LayoutController, | ||||
|     FixedController, | ||||
|     LayoutCompositionPolicy, | ||||
|     MCTTriggerModal, | ||||
|     layoutTemplate, | ||||
|     fixedTemplate, | ||||
|     frameTemplate, | ||||
| @@ -224,15 +222,6 @@ define([ | ||||
|                     "template": frameTemplate | ||||
|                 } | ||||
|             ], | ||||
|             "directives": [ | ||||
|                 { | ||||
|                     "key": "mctTriggerModal", | ||||
|                     "implementation": MCTTriggerModal, | ||||
|                     "depends": [ | ||||
|                         "$document" | ||||
|                     ] | ||||
|                 } | ||||
|             ], | ||||
|             "controllers": [ | ||||
|                 { | ||||
|                     "key": "LayoutController", | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <div class="frame frame-template abs"> | ||||
|     <div class="abs object-browse-bar l-flex-row"> | ||||
|     <div class="abs object-top-bar l-flex-row"> | ||||
|         <div class="left flex-elem l-flex-row grows"> | ||||
|             <mct-representation | ||||
|                 key="'object-header'" | ||||
|   | ||||
| @@ -1,106 +0,0 @@ | ||||
| define([ | ||||
|  | ||||
| ], function () { | ||||
|  | ||||
|     var OVERLAY_TEMPLATE = '' + | ||||
| '<div class="abs overlay l-large-view">' + | ||||
| '    <div class="abs blocker"></div>' + | ||||
| '    <div class="abs holder">' + | ||||
| '        <a class="close icon-x"></a>' + | ||||
| '        <div class="abs contents"></div>' + | ||||
| '    </div>' + | ||||
| '</div>'; | ||||
|  | ||||
|     /** | ||||
|      * 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() { | ||||
|  | ||||
|         function link($scope, $element) { | ||||
|             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, | ||||
|                 isOpen = false, | ||||
|                 overlay, | ||||
|                 closeButton, | ||||
|                 blocker, | ||||
|                 overlayContainer; | ||||
|  | ||||
|             function openOverlay() { | ||||
|                 // Remove frame classes from being applied in a non-frame context | ||||
|                 $(frame).removeClass('frame frame-template'); | ||||
|                 overlayContainer = overlay.querySelector('.abs.contents'); | ||||
|                 closeButton = overlay.querySelector('a.close'); | ||||
|                 closeButton.addEventListener('click', toggleOverlay); | ||||
|                 blocker = overlay.querySelector('.abs.blocker'); | ||||
|                 blocker.addEventListener('click', toggleOverlay); | ||||
|                 document.body.appendChild(overlay); | ||||
|                 layoutContainer.removeChild(frame); | ||||
|                 overlayContainer.appendChild(frame); | ||||
|             } | ||||
|  | ||||
|             function closeOverlay() { | ||||
|                 $(frame).addClass('frame frame-template'); | ||||
|                 overlayContainer.removeChild(frame); | ||||
|                 layoutContainer.appendChild(frame); | ||||
|                 document.body.removeChild(overlay); | ||||
|                 closeButton.removeEventListener('click', toggleOverlay); | ||||
|                 closeButton = undefined; | ||||
|                 blocker.removeEventListener('click', toggleOverlay); | ||||
|                 blocker = undefined; | ||||
|                 overlayContainer = undefined; | ||||
|                 overlay = undefined; | ||||
|             } | ||||
|  | ||||
|             function initOpenOverlay() { | ||||
|                 overlay = document.createElement('span'); | ||||
|                 overlay.innerHTML = OVERLAY_TEMPLATE; | ||||
|                 // Give expand anim time to run before populating | ||||
|                 setTimeout(openOverlay(), 5000); | ||||
|             } | ||||
|  | ||||
|             function toggleOverlay() { | ||||
|                 if (!isOpen) { | ||||
|                     initOpenOverlay(); | ||||
|                     isOpen = true; | ||||
|                 } else { | ||||
|                     closeOverlay(); | ||||
|                     isOpen = false; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             $element.on('click', toggleOverlay); | ||||
|             $scope.$on('$destroy', function () { | ||||
|                 $element.off('click'); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             restrict: 'A', | ||||
|             link: link | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     return MCTTriggerModal; | ||||
|  | ||||
| }); | ||||
| @@ -1,37 +0,0 @@ | ||||
| # Plot README | ||||
|  | ||||
| ## Chart  | ||||
|  | ||||
| The `mct-chart` directive is used to support drawing of simple charts. It is  | ||||
| present to support the Plot view, and its functionality is limited to the  | ||||
| functionality that is relevant for that view. | ||||
|  | ||||
| This directive is used at the element level and takes one attribute, `draw`  | ||||
| which is an Angular expression which will should evaluate to a drawing object.  | ||||
| This drawing object should contain the following properties: | ||||
|  | ||||
| * `dimensions`: The size, in logical coordinates, of the chart area. A  | ||||
| two-element array or numbers.  | ||||
| * `origin`: The position, in logical coordinates, of the lower-left corner of  | ||||
| the chart area. A two-element array or numbers.  | ||||
| * `lines`: An array of lines (e.g. as a plot line) to draw, where each line is  | ||||
| expressed as an object containing:  | ||||
|     * `buffer`: A Float32Array containing points in the line, in logical  | ||||
|     coordinates, in sequential x,y pairs.  | ||||
|     * `color`: The color of the line, as a four-element RGBA array, where  | ||||
|     each element is a number in the range of 0.0-1.0.  | ||||
|     * `points`: The number of points in the line.  | ||||
| * `boxes`: An array of rectangles to draw in the chart area. Each is an object  | ||||
| containing:  | ||||
|     * `start`: The first corner of the rectangle, as a two-element array of  | ||||
|     numbers, in logical coordinates.  | ||||
|     * `end`: The opposite corner of the rectangle, as a two-element array of  | ||||
|     numbers, in logical coordinates. color : The color of the line, as a  | ||||
|     four-element RGBA array, where each element is a number in the range of  | ||||
|     0.0-1.0.  | ||||
|  | ||||
| While `mct-chart` is intended to support plots specifically, it does perform  | ||||
| some useful management of canvas objects (e.g. choosing between WebGL and Canvas  | ||||
| 2D APIs for drawing based on browser support) so its usage is recommended when  | ||||
| its supported drawing primitives are sufficient for other charting tasks.  | ||||
|   | ||||
| @@ -38,7 +38,6 @@ define([ | ||||
|     "./src/directives/MCTSwimlaneDrop", | ||||
|     "./src/directives/MCTSwimlaneDrag", | ||||
|     "./src/services/ObjectLoader", | ||||
|     "./src/chart/MCTTimelineChart", | ||||
|     "text!./res/templates/values.html", | ||||
|     "text!./res/templates/timeline.html", | ||||
|     "text!./res/templates/activity-gantt.html", | ||||
| @@ -68,7 +67,6 @@ define([ | ||||
|     MCTSwimlaneDrop, | ||||
|     MCTSwimlaneDrag, | ||||
|     ObjectLoader, | ||||
|     MCTTimelineChart, | ||||
|     valuesTemplate, | ||||
|     timelineTemplate, | ||||
|     activityGanttTemplate, | ||||
| @@ -558,14 +556,6 @@ define([ | ||||
|                     "depends": [ | ||||
|                         "dndService" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "mctTimelineChart", | ||||
|                     "implementation": MCTTimelineChart, | ||||
|                     "depends": [ | ||||
|                         "$interval", | ||||
|                         "$log" | ||||
|                     ] | ||||
|                 } | ||||
|             ], | ||||
|             "services": [ | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
| <span ng-controller="TimelineGraphController as graphController"> | ||||
|     <div class="t-graph l-graph" ng-repeat="graph in parameters.graphs"> | ||||
|         <div class="l-graph-area l-canvas-holder"> | ||||
|             <mct-timeline-chart draw="graph.drawingObject"></mct-timeline-chart> | ||||
|             <mct-chart draw="graph.drawingObject"></mct-chart> | ||||
|         </div> | ||||
|         <div class="t-graph-labels l-graph-labels"> | ||||
|             <mct-include key="'timeline-resource-graph-labels'" | ||||
| @@ -31,4 +31,4 @@ | ||||
|             </mct-include> | ||||
|         </div> | ||||
|     </div> | ||||
| </span> | ||||
| </span> | ||||
| @@ -1,117 +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( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         /** | ||||
|          * Create a new chart which uses Canvas's 2D API for rendering. | ||||
|          * | ||||
|          * @memberof platform/features/plot | ||||
|          * @constructor | ||||
|          * @implements {platform/features/plot.Chart} | ||||
|          * @param {CanvasElement} canvas the canvas object to render upon | ||||
|          * @throws {Error} an error is thrown if Canvas's 2D API is unavailable. | ||||
|          */ | ||||
|         function Canvas2DChart(canvas) { | ||||
|             this.canvas = canvas; | ||||
|             this.c2d = canvas.getContext('2d'); | ||||
|             this.width = canvas.width; | ||||
|             this.height = canvas.height; | ||||
|             this.dimensions = [this.width, this.height]; | ||||
|             this.origin = [0, 0]; | ||||
|  | ||||
|             if (!this.c2d) { | ||||
|                 throw new Error("Canvas 2d API unavailable."); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Convert from logical to physical x coordinates | ||||
|         Canvas2DChart.prototype.x = function (v) { | ||||
|             return ((v - this.origin[0]) / this.dimensions[0]) * this.width; | ||||
|         }; | ||||
|  | ||||
|         // Convert from logical to physical y coordinates | ||||
|         Canvas2DChart.prototype.y = function (v) { | ||||
|             return this.height - | ||||
|                 ((v - this.origin[1]) / this.dimensions[1]) * this.height; | ||||
|         }; | ||||
|  | ||||
|         // Set the color to be used for drawing operations | ||||
|         Canvas2DChart.prototype.setColor = function (color) { | ||||
|             var mappedColor = color.map(function (c, i) { | ||||
|                 return i < 3 ? Math.floor(c * 255) : (c); | ||||
|             }).join(','); | ||||
|             this.c2d.strokeStyle = "rgba(" + mappedColor + ")"; | ||||
|             this.c2d.fillStyle = "rgba(" + mappedColor + ")"; | ||||
|         }; | ||||
|  | ||||
|  | ||||
|         Canvas2DChart.prototype.clear = function () { | ||||
|             var canvas = this.canvas; | ||||
|             this.width = canvas.width; | ||||
|             this.height = canvas.height; | ||||
|             this.c2d.clearRect(0, 0, this.width, this.height); | ||||
|         }; | ||||
|  | ||||
|         Canvas2DChart.prototype.setDimensions = function (newDimensions, newOrigin) { | ||||
|             this.dimensions = newDimensions; | ||||
|             this.origin = newOrigin; | ||||
|         }; | ||||
|  | ||||
|         Canvas2DChart.prototype.drawLine = function (buf, color, points) { | ||||
|             var i; | ||||
|  | ||||
|             this.setColor(color); | ||||
|  | ||||
|             // Configure context to draw two-pixel-thick lines | ||||
|             this.c2d.lineWidth = 2; | ||||
|  | ||||
|             // Start a new path... | ||||
|             if (buf.length > 1) { | ||||
|                 this.c2d.beginPath(); | ||||
|                 this.c2d.moveTo(this.x(buf[0]), this.y(buf[1])); | ||||
|             } | ||||
|  | ||||
|             // ...and add points to it... | ||||
|             for (i = 2; i < points * 2; i = i + 2) { | ||||
|                 this.c2d.lineTo(this.x(buf[i]), this.y(buf[i + 1])); | ||||
|             } | ||||
|  | ||||
|             // ...before finally drawing it. | ||||
|             this.c2d.stroke(); | ||||
|         }; | ||||
|  | ||||
|         Canvas2DChart.prototype.drawSquare = function (min, max, color) { | ||||
|             var x1 = this.x(min[0]), | ||||
|                 y1 = this.y(min[1]), | ||||
|                 w = this.x(max[0]) - x1, | ||||
|                 h = this.y(max[1]) - y1; | ||||
|  | ||||
|             this.setColor(color); | ||||
|             this.c2d.fillRect(x1, y1, w, h); | ||||
|         }; | ||||
|  | ||||
|         return Canvas2DChart; | ||||
|     } | ||||
| ); | ||||
| @@ -1,160 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /** | ||||
|  * Module defining GLPlot. Created by vwoeltje on 11/12/14. | ||||
|  */ | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|         // WebGL shader sources (for drawing plain colors) | ||||
|         var FRAGMENT_SHADER = [ | ||||
|                 "precision mediump float;", | ||||
|                 "uniform vec4 uColor;", | ||||
|                 "void main(void) {", | ||||
|                 "gl_FragColor = uColor;", | ||||
|                 "}" | ||||
|             ].join('\n'), | ||||
|             VERTEX_SHADER = [ | ||||
|                 "attribute vec2 aVertexPosition;", | ||||
|                 "uniform vec2 uDimensions;", | ||||
|                 "uniform vec2 uOrigin;", | ||||
|                 "void main(void) {", | ||||
|                 "gl_Position = vec4(2.0 * ((aVertexPosition - uOrigin) / uDimensions) - vec2(1,1), 0, 1);", | ||||
|                 "}" | ||||
|             ].join('\n'); | ||||
|  | ||||
|         /** | ||||
|          * Create a new chart which uses WebGL for rendering. | ||||
|          * | ||||
|          * @memberof platform/features/plot | ||||
|          * @constructor | ||||
|          * @implements {platform/features/plot.Chart} | ||||
|          * @param {CanvasElement} canvas the canvas object to render upon | ||||
|          * @throws {Error} an error is thrown if WebGL is unavailable. | ||||
|          */ | ||||
|         function GLChart(canvas) { | ||||
|             var gl = canvas.getContext("webgl", { preserveDrawingBuffer: true }) || | ||||
|                     canvas.getContext("experimental-webgl", { preserveDrawingBuffer: true }), | ||||
|                 vertexShader, | ||||
|                 fragmentShader, | ||||
|                 program, | ||||
|                 aVertexPosition, | ||||
|                 uColor, | ||||
|                 uDimensions, | ||||
|                 uOrigin; | ||||
|  | ||||
|             // Ensure a context was actually available before proceeding | ||||
|             if (!gl) { | ||||
|                 throw new Error("WebGL unavailable."); | ||||
|             } | ||||
|  | ||||
|             // Initialize shaders | ||||
|             vertexShader = gl.createShader(gl.VERTEX_SHADER); | ||||
|             gl.shaderSource(vertexShader, VERTEX_SHADER); | ||||
|             gl.compileShader(vertexShader); | ||||
|             fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); | ||||
|             gl.shaderSource(fragmentShader, FRAGMENT_SHADER); | ||||
|             gl.compileShader(fragmentShader); | ||||
|  | ||||
|             // Assemble vertex/fragment shaders into programs | ||||
|             program = gl.createProgram(); | ||||
|             gl.attachShader(program, vertexShader); | ||||
|             gl.attachShader(program, fragmentShader); | ||||
|             gl.linkProgram(program); | ||||
|             gl.useProgram(program); | ||||
|  | ||||
|             // Get locations for attribs/uniforms from the | ||||
|             // shader programs (to pass values into shaders at draw-time) | ||||
|             aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); | ||||
|             uColor = gl.getUniformLocation(program, "uColor"); | ||||
|             uDimensions = gl.getUniformLocation(program, "uDimensions"); | ||||
|             uOrigin = gl.getUniformLocation(program, "uOrigin"); | ||||
|             gl.enableVertexAttribArray(aVertexPosition); | ||||
|  | ||||
|             // Create a buffer to holds points which will be drawn | ||||
|             this.buffer = gl.createBuffer(); | ||||
|  | ||||
|             // Use a line width of 2.0 for legibility | ||||
|             gl.lineWidth(2.0); | ||||
|  | ||||
|             // Enable blending, for smoothness | ||||
|             gl.enable(gl.BLEND); | ||||
|             gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); | ||||
|  | ||||
|             this.gl = gl; | ||||
|             this.aVertexPosition = aVertexPosition; | ||||
|             this.uColor = uColor; | ||||
|             this.uDimensions = uDimensions; | ||||
|             this.uOrigin = uOrigin; | ||||
|         } | ||||
|  | ||||
|         // Utility function to handle drawing of a buffer; | ||||
|         // drawType will determine whether this is a box, line, etc. | ||||
|         GLChart.prototype.doDraw = function (drawType, buf, color, points) { | ||||
|             var gl = this.gl; | ||||
|             gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); | ||||
|             gl.bufferData(gl.ARRAY_BUFFER, buf, gl.DYNAMIC_DRAW); | ||||
|             gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, 0, 0); | ||||
|             gl.uniform4fv(this.uColor, color); | ||||
|             gl.drawArrays(drawType, 0, points); | ||||
|         }; | ||||
|  | ||||
|         GLChart.prototype.clear = function () { | ||||
|             var gl = this.gl; | ||||
|  | ||||
|             // Set the viewport size; note that we use the width/height | ||||
|             // that our WebGL context reports, which may be lower | ||||
|             // resolution than the canvas we requested. | ||||
|             gl.viewport( | ||||
|                 0, | ||||
|                 0, | ||||
|                 gl.drawingBufferWidth, | ||||
|                 gl.drawingBufferHeight | ||||
|             ); | ||||
|             gl.clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT); | ||||
|         }; | ||||
|  | ||||
|  | ||||
|         GLChart.prototype.setDimensions = function (dimensions, origin) { | ||||
|             var gl = this.gl; | ||||
|             if (dimensions && dimensions.length > 0 && | ||||
|                 origin && origin.length > 0) { | ||||
|                 gl.uniform2fv(this.uDimensions, dimensions); | ||||
|                 gl.uniform2fv(this.uOrigin, origin); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         GLChart.prototype.drawLine = function (buf, color, points) { | ||||
|             this.doDraw(this.gl.LINE_STRIP, buf, color, points); | ||||
|         }; | ||||
|  | ||||
|         GLChart.prototype.drawSquare = function (min, max, color) { | ||||
|             this.doDraw(this.gl.TRIANGLE_FAN, new Float32Array( | ||||
|                 min.concat([min[0], max[1]]).concat(max).concat([max[0], min[1]]) | ||||
|             ), color, 4); | ||||
|         }; | ||||
|  | ||||
|         return GLChart; | ||||
|     } | ||||
| ); | ||||
| @@ -1,250 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /** | ||||
|  * Module defining MCTTimelineChart. Created by vwoeltje on 11/12/14. | ||||
|  */ | ||||
| define( | ||||
|     ["./GLChart", "./Canvas2DChart"], | ||||
|     function (GLChart, Canvas2DChart) { | ||||
|  | ||||
|         var TEMPLATE = "<canvas style='position: absolute; background: none; width: 100%; height: 100%;'></canvas>"; | ||||
|  | ||||
|         /** | ||||
|          * The mct-timeline-chart directive provides a canvas element which can be | ||||
|          * drawn upon, to support Plot view and similar visualizations. | ||||
|          * | ||||
|          * This directive takes one attribute, "draw", which is an Angular | ||||
|          * expression which will be two-way bound to a drawing object. This | ||||
|          * drawing object should contain: | ||||
|          * | ||||
|          * * `dimensions`: An object describing the logical bounds of the | ||||
|          *   drawable area, containing two fields: | ||||
|          *   * `origin`: The position, in logical coordinates, of the | ||||
|          *     lower-left corner of the chart area. A two-element array. | ||||
|          *   * `dimensions`: A two-element array containing the width | ||||
|          *     and height of the chart area, in logical coordinates. | ||||
|          * * `lines`: An array of lines to be drawn, where each line is | ||||
|          *   expressed as an object containing: | ||||
|          *   * `buffer`: A Float32Array containing points in the line, | ||||
|          *     in logical coordinate, in sequential x/y pairs. | ||||
|          *   * `color`: The color of the line, as a four-element RGBA | ||||
|          *     array, where each element is in the range of 0.0-1.0 | ||||
|          *   * `points`: The number of points in the line. | ||||
|          * * `boxes`: An array of rectangles to draw in the chart area | ||||
|          *   (used for marquee zoom). Each is an object containing: | ||||
|          *   * `start`: The first corner of the rectangle (as a two-element | ||||
|          *      array, logical coordinates) | ||||
|          *   * `end`: The opposite corner of the rectangle (again, as a | ||||
|          *      two-element array) | ||||
|          *   * `color`: The color of the box, as a four-element RGBA | ||||
|          *     array, where each element is in the range of 0.0-1.0 | ||||
|          * | ||||
|          * @memberof platform/features/plot | ||||
|          * @constructor | ||||
|          */ | ||||
|         function MCTTimelineChart($interval, $log) { | ||||
|             // Get an underlying chart implementation | ||||
|             function getChart(Charts, canvas) { | ||||
|                 // Try the first available option... | ||||
|                 var Chart = Charts[0]; | ||||
|  | ||||
|                 // This function recursively try-catches all options; | ||||
|                 // if these all fail, issue a warning. | ||||
|                 if (!Chart) { | ||||
|                     $log.warn("Cannot initialize mct-timeline-chart."); | ||||
|                     return undefined; | ||||
|                 } | ||||
|  | ||||
|                 // Try first option; if it fails, try remaining options | ||||
|                 try { | ||||
|                     return new Chart(canvas); | ||||
|                 } catch (e) { | ||||
|                     $log.warn([ | ||||
|                         "Could not instantiate chart", | ||||
|                         Chart.name, | ||||
|                         ";", | ||||
|                         e.message | ||||
|                     ].join(" ")); | ||||
|  | ||||
|                     return getChart(Charts.slice(1), canvas); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             function linkChart(scope, element) { | ||||
|                 var canvas = element.find("canvas")[0], | ||||
|                     activeInterval, | ||||
|                     chart; | ||||
|  | ||||
|                 // Handle drawing, based on contents of the "draw" object | ||||
|                 // in scope | ||||
|                 function doDraw(draw) { | ||||
|                     // Ensure canvas context has same resolution | ||||
|                     // as canvas element | ||||
|                     canvas.width = canvas.offsetWidth; | ||||
|                     canvas.height = canvas.offsetHeight; | ||||
|  | ||||
|                     // Clear previous contents | ||||
|                     chart.clear(); | ||||
|  | ||||
|                     // Nothing to draw if no draw object defined | ||||
|                     if (!draw) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     // Set logical boundaries for the chart | ||||
|                     chart.setDimensions( | ||||
|                         draw.dimensions || [1, 1], | ||||
|                         draw.origin || [0, 0] | ||||
|                     ); | ||||
|  | ||||
|                     // Draw line segments | ||||
|                     (draw.lines || []).forEach(function (line) { | ||||
|                         chart.drawLine( | ||||
|                             line.buffer, | ||||
|                             line.color, | ||||
|                             line.points | ||||
|                         ); | ||||
|                     }); | ||||
|  | ||||
|                     // Draw boxes (e.g. marquee zoom rect) | ||||
|                     (draw.boxes || []).forEach(function (box) { | ||||
|                         chart.drawSquare( | ||||
|                             box.start, | ||||
|                             box.end, | ||||
|                             box.color | ||||
|                         ); | ||||
|                     }); | ||||
|  | ||||
|                 } | ||||
|  | ||||
|                 // Issue a drawing call, if-and-only-if canvas size | ||||
|                 // has changed. This will be called on a timer, since | ||||
|                 // there is no event to depend on. | ||||
|                 function drawIfResized() { | ||||
|                     if (canvas.width !== canvas.offsetWidth || | ||||
|                             canvas.height !== canvas.offsetHeight) { | ||||
|                         doDraw(scope.draw); | ||||
|                         scope.$apply(); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // Stop watching for changes to size (scope destroyed) | ||||
|                 function releaseInterval() { | ||||
|                     if (activeInterval) { | ||||
|                         $interval.cancel(activeInterval); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // Switch from WebGL to plain 2D if context is lost | ||||
|                 function fallbackFromWebGL() { | ||||
|                     element.html(TEMPLATE); | ||||
|                     canvas = element.find("canvas")[0]; | ||||
|                     chart = getChart([Canvas2DChart], canvas); | ||||
|                     if (chart) { | ||||
|                         doDraw(scope.draw); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // Try to initialize a chart. | ||||
|                 chart = getChart([GLChart, Canvas2DChart], canvas); | ||||
|  | ||||
|                 // If that failed, there's nothing more we can do here. | ||||
|                 // (A warning will already have been issued) | ||||
|                 if (!chart) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // WebGL is a bit of a special case; it may work, then fail | ||||
|                 // later for various reasons, so we need to listen for this | ||||
|                 // and fall back to plain canvas drawing when it occurs. | ||||
|                 canvas.addEventListener("webglcontextlost", fallbackFromWebGL); | ||||
|  | ||||
|                 // Check for resize, on a timer | ||||
|                 activeInterval = $interval(drawIfResized, 1000, 0, false); | ||||
|  | ||||
|                 // Watch "draw" for external changes to the set of | ||||
|                 // things to be drawn. | ||||
|                 scope.$watchCollection("draw", doDraw); | ||||
|  | ||||
|                 // Stop checking for resize when scope is destroyed | ||||
|                 scope.$on("$destroy", releaseInterval); | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|                 // Apply directive only to elements | ||||
|                 restrict: "E", | ||||
|  | ||||
|                 // Template to use (a canvas element) | ||||
|                 template: TEMPLATE, | ||||
|  | ||||
|                 // Link function; set up scope | ||||
|                 link: linkChart, | ||||
|  | ||||
|                 // Initial, isolate scope for the directive | ||||
|                 scope: { draw: "=" } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * @interface platform/features/plot.Chart | ||||
|          * @private | ||||
|          */ | ||||
|  | ||||
|         /** | ||||
|          * Clear the chart. | ||||
|          * @method platform/features/plot.Chart#clear | ||||
|          */ | ||||
|         /** | ||||
|          * Set the logical boundaries of the chart. | ||||
|          * @param {number[]} dimensions the horizontal and | ||||
|          *        vertical dimensions of the chart | ||||
|          * @param {number[]} origin the horizontal/vertical | ||||
|          *        origin of the chart | ||||
|          * @memberof platform/features/plot.Chart#setDimensions | ||||
|          */ | ||||
|         /** | ||||
|          * Draw the supplied buffer as a line strip (a sequence | ||||
|          * of line segments), in the chosen color. | ||||
|          * @param {Float32Array} buf the line strip to draw, | ||||
|          *        in alternating x/y positions | ||||
|          * @param {number[]} color the color to use when drawing | ||||
|          *        the line, as an RGBA color where each element | ||||
|          *        is in the range of 0.0-1.0 | ||||
|          * @param {number} points the number of points to draw | ||||
|          * @memberof platform/features/plot.Chart#drawLine | ||||
|          */ | ||||
|         /** | ||||
|          * Draw a rectangle extending from one corner to another, | ||||
|          * in the chosen color. | ||||
|          * @param {number[]} min the first corner of the rectangle | ||||
|          * @param {number[]} max the opposite corner | ||||
|          * @param {number[]} color the color to use when drawing | ||||
|          *        the rectangle, as an RGBA color where each element | ||||
|          *        is in the range of 0.0-1.0 | ||||
|          * @memberof platform/features/plot.Chart#drawSquare | ||||
|          */ | ||||
|  | ||||
|         return MCTTimelineChart; | ||||
|     } | ||||
| ); | ||||
|  | ||||
| @@ -167,7 +167,7 @@ define( | ||||
|                  */ | ||||
|                 setBounds: function (offset, duration) { | ||||
|                     // We don't update in-place, because we need the change | ||||
|                     // to trigger a watch in mct-timeline-chart. | ||||
|                     // to trigger a watch in mct-chart. | ||||
|                     drawingObject.origin = [offset, drawingObject.origin[1]]; | ||||
|                     drawingObject.dimensions = [duration, drawingObject.dimensions[1]]; | ||||
|                 }, | ||||
|   | ||||
| @@ -26,7 +26,7 @@ define( | ||||
|  | ||||
|         /** | ||||
|          * Responsible for preparing data for display by | ||||
|          * `mct-timeline-chart` in a timeline's resource graph. | ||||
|          * `mct-chart` in a timeline's resource graph. | ||||
|          * @constructor | ||||
|          */ | ||||
|         function TimelineGraphRenderer() { | ||||
| @@ -54,7 +54,7 @@ define( | ||||
|                  * Convert an HTML color (in #-prefixed 6-digit hexadecimal) | ||||
|                  * to an array of floating point values in a range of 0.0-1.0. | ||||
|                  * An alpha element is included to facilitate display in an | ||||
|                  * `mct-timeline-chart` (which uses WebGL.) | ||||
|                  * `mct-chart` (which uses WebGL.) | ||||
|                  * @param {string} the color | ||||
|                  * @returns {number[]} the same color, in floating-point format | ||||
|                  */ | ||||
|   | ||||
| @@ -1,95 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /** | ||||
|  * MergeModelsSpec. Created by vwoeltje on 11/6/14. | ||||
|  */ | ||||
| define( | ||||
|     ["../../src/chart/Canvas2DChart"], | ||||
|     function (Canvas2DChart) { | ||||
|  | ||||
|         describe("A canvas 2d chart", function () { | ||||
|             var mockCanvas, | ||||
|                 mock2d, | ||||
|                 chart; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockCanvas = jasmine.createSpyObj("canvas", ["getContext"]); | ||||
|                 mock2d = jasmine.createSpyObj( | ||||
|                     "2d", | ||||
|                     [ | ||||
|                         "clearRect", | ||||
|                         "beginPath", | ||||
|                         "moveTo", | ||||
|                         "lineTo", | ||||
|                         "stroke", | ||||
|                         "fillRect" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockCanvas.getContext.andReturn(mock2d); | ||||
|  | ||||
|                 chart = new Canvas2DChart(mockCanvas); | ||||
|             }); | ||||
|  | ||||
|             // Note that tests below are less specific than they | ||||
|             // could be, esp. w.r.t. arguments to drawing calls; | ||||
|             // this is a fallback option so is a lower test priority. | ||||
|  | ||||
|             it("allows the canvas to be cleared", function () { | ||||
|                 chart.clear(); | ||||
|                 expect(mock2d.clearRect).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("does not construct if 2D is unavailable", function () { | ||||
|                 mockCanvas.getContext.andReturn(undefined); | ||||
|                 expect(function () { | ||||
|                     return new Canvas2DChart(mockCanvas); | ||||
|                 }).toThrow(); | ||||
|             }); | ||||
|  | ||||
|             it("allows dimensions to be set", function () { | ||||
|                 // No return value, just verify API is present | ||||
|                 chart.setDimensions([120, 120], [0, 10]); | ||||
|             }); | ||||
|  | ||||
|             it("allows lines to be drawn", function () { | ||||
|                 var testBuffer = [0, 1, 3, 8], | ||||
|                     testColor = [0.25, 0.33, 0.66, 1.0], | ||||
|                     testPoints = 2; | ||||
|                 chart.drawLine(testBuffer, testColor, testPoints); | ||||
|                 expect(mock2d.beginPath).toHaveBeenCalled(); | ||||
|                 expect(mock2d.lineTo.calls.length).toEqual(1); | ||||
|                 expect(mock2d.stroke).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("allows squares to be drawn", function () { | ||||
|                 var testMin = [0, 1], | ||||
|                     testMax = [10, 10], | ||||
|                     testColor = [0.25, 0.33, 0.66, 1.0]; | ||||
|  | ||||
|                 chart.drawSquare(testMin, testMax, testColor); | ||||
|                 expect(mock2d.fillRect).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,143 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /** | ||||
|  * MergeModelsSpec. Created by vwoeltje on 11/6/14. | ||||
|  */ | ||||
| define( | ||||
|     ["../../src/chart/GLChart"], | ||||
|     function (GLChart) { | ||||
|  | ||||
|         describe("A WebGL chart", function () { | ||||
|             var mockCanvas, | ||||
|                 mockGL, | ||||
|                 glChart; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockCanvas = jasmine.createSpyObj("canvas", ["getContext"]); | ||||
|                 mockGL = jasmine.createSpyObj( | ||||
|                     "gl", | ||||
|                     [ | ||||
|                         "createShader", | ||||
|                         "compileShader", | ||||
|                         "shaderSource", | ||||
|                         "attachShader", | ||||
|                         "createProgram", | ||||
|                         "linkProgram", | ||||
|                         "useProgram", | ||||
|                         "enableVertexAttribArray", | ||||
|                         "getAttribLocation", | ||||
|                         "getUniformLocation", | ||||
|                         "createBuffer", | ||||
|                         "lineWidth", | ||||
|                         "enable", | ||||
|                         "blendFunc", | ||||
|                         "viewport", | ||||
|                         "clear", | ||||
|                         "uniform2fv", | ||||
|                         "uniform4fv", | ||||
|                         "bufferData", | ||||
|                         "bindBuffer", | ||||
|                         "vertexAttribPointer", | ||||
|                         "drawArrays" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockGL.ARRAY_BUFFER = "ARRAY_BUFFER"; | ||||
|                 mockGL.DYNAMIC_DRAW = "DYNAMIC_DRAW"; | ||||
|                 mockGL.TRIANGLE_FAN = "TRIANGLE_FAN"; | ||||
|                 mockGL.LINE_STRIP = "LINE_STRIP"; | ||||
|  | ||||
|                 // Echo back names for uniform locations, so we can | ||||
|                 // test which of these are set for certain operations. | ||||
|                 mockGL.getUniformLocation.andCallFake(function (a, name) { | ||||
|                     return name; | ||||
|                 }); | ||||
|  | ||||
|                 mockCanvas.getContext.andReturn(mockGL); | ||||
|  | ||||
|                 glChart = new GLChart(mockCanvas); | ||||
|             }); | ||||
|  | ||||
|             it("allows the canvas to be cleared", function () { | ||||
|                 glChart.clear(); | ||||
|                 expect(mockGL.clear).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("does not construct if WebGL is unavailable", function () { | ||||
|                 mockCanvas.getContext.andReturn(undefined); | ||||
|                 expect(function () { | ||||
|                     return new GLChart(mockCanvas); | ||||
|                 }).toThrow(); | ||||
|             }); | ||||
|  | ||||
|             it("allows dimensions to be set", function () { | ||||
|                 glChart.setDimensions([120, 120], [0, 10]); | ||||
|                 expect(mockGL.uniform2fv) | ||||
|                     .toHaveBeenCalledWith("uDimensions", [120, 120]); | ||||
|                 expect(mockGL.uniform2fv) | ||||
|                     .toHaveBeenCalledWith("uOrigin", [0, 10]); | ||||
|             }); | ||||
|  | ||||
|             it("allows lines to be drawn", function () { | ||||
|                 var testBuffer = [0, 1, 3, 8], | ||||
|                     testColor = [0.25, 0.33, 0.66, 1.0], | ||||
|                     testPoints = 2; | ||||
|                 glChart.drawLine(testBuffer, testColor, testPoints); | ||||
|                 expect(mockGL.bufferData).toHaveBeenCalledWith( | ||||
|                     mockGL.ARRAY_BUFFER, | ||||
|                     testBuffer, | ||||
|                     mockGL.DYNAMIC_DRAW | ||||
|                 ); | ||||
|                 expect(mockGL.uniform4fv) | ||||
|                     .toHaveBeenCalledWith("uColor", testColor); | ||||
|                 expect(mockGL.drawArrays) | ||||
|                     .toHaveBeenCalledWith("LINE_STRIP", 0, testPoints); | ||||
|             }); | ||||
|  | ||||
|             it("allows squares to be drawn", function () { | ||||
|                 var testMin = [0, 1], | ||||
|                     testMax = [10, 10], | ||||
|                     testColor = [0.25, 0.33, 0.66, 1.0]; | ||||
|  | ||||
|                 glChart.drawSquare(testMin, testMax, testColor); | ||||
|  | ||||
|                 expect(mockGL.uniform4fv) | ||||
|                     .toHaveBeenCalledWith("uColor", testColor); | ||||
|                 expect(mockGL.drawArrays) | ||||
|                     .toHaveBeenCalledWith("TRIANGLE_FAN", 0, 4); | ||||
|             }); | ||||
|  | ||||
|             it("uses buffer sizes reported by WebGL", function () { | ||||
|                 // Make sure that GLChart uses the GL buffer size, which may | ||||
|                 // differ from what canvas requested. WTD-852 | ||||
|                 mockCanvas.width = 300; | ||||
|                 mockCanvas.height = 150; | ||||
|                 mockGL.drawingBufferWidth = 200; | ||||
|                 mockGL.drawingBufferHeight = 175; | ||||
|  | ||||
|                 glChart.clear(); | ||||
|  | ||||
|                 expect(mockGL.viewport).toHaveBeenCalledWith(0, 0, 200, 175); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,216 +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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /** | ||||
|  * MCTTimelineChart. Created by vwoeltje on 11/6/14. | ||||
|  */ | ||||
| define( | ||||
|     ["../../src/chart/MCTTimelineChart"], | ||||
|     function (MCTTimelineChart) { | ||||
|  | ||||
|         describe("The mct-timeline-chart directive", function () { | ||||
|             var mockInterval, | ||||
|                 mockLog, | ||||
|                 mockScope, | ||||
|                 mockElement, | ||||
|                 mockCanvas, | ||||
|                 mockGL, | ||||
|                 mockC2d, | ||||
|                 mockPromise, | ||||
|                 mctChart; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockInterval = | ||||
|                     jasmine.createSpy("$interval"); | ||||
|                 mockLog = | ||||
|                     jasmine.createSpyObj("$log", ["warn", "info", "debug"]); | ||||
|                 mockScope = jasmine.createSpyObj( | ||||
|                     "$scope", | ||||
|                     ["$watchCollection", "$on", "$apply"] | ||||
|                 ); | ||||
|                 mockElement = | ||||
|                     jasmine.createSpyObj("element", ["find", "html"]); | ||||
|                 mockInterval.cancel = jasmine.createSpy("cancelInterval"); | ||||
|                 mockPromise = jasmine.createSpyObj("promise", ["then"]); | ||||
|  | ||||
|  | ||||
|                 // mct-timeline-chart uses GLChart, so it needs WebGL API | ||||
|                 mockCanvas = | ||||
|                     jasmine.createSpyObj("canvas", ["getContext", "addEventListener"]); | ||||
|                 mockGL = jasmine.createSpyObj( | ||||
|                     "gl", | ||||
|                     [ | ||||
|                         "createShader", | ||||
|                         "compileShader", | ||||
|                         "shaderSource", | ||||
|                         "attachShader", | ||||
|                         "createProgram", | ||||
|                         "linkProgram", | ||||
|                         "useProgram", | ||||
|                         "enableVertexAttribArray", | ||||
|                         "getAttribLocation", | ||||
|                         "getUniformLocation", | ||||
|                         "createBuffer", | ||||
|                         "lineWidth", | ||||
|                         "enable", | ||||
|                         "blendFunc", | ||||
|                         "viewport", | ||||
|                         "clear", | ||||
|                         "uniform2fv", | ||||
|                         "uniform4fv", | ||||
|                         "bufferData", | ||||
|                         "bindBuffer", | ||||
|                         "vertexAttribPointer", | ||||
|                         "drawArrays" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockC2d = jasmine.createSpyObj('c2d', ['clearRect']); | ||||
|                 mockGL.ARRAY_BUFFER = "ARRAY_BUFFER"; | ||||
|                 mockGL.DYNAMIC_DRAW = "DYNAMIC_DRAW"; | ||||
|                 mockGL.TRIANGLE_FAN = "TRIANGLE_FAN"; | ||||
|                 mockGL.LINE_STRIP = "LINE_STRIP"; | ||||
|  | ||||
|                 // Echo back names for uniform locations, so we can | ||||
|                 // test which of these are set for certain operations. | ||||
|                 mockGL.getUniformLocation.andCallFake(function (a, name) { | ||||
|                     return name; | ||||
|                 }); | ||||
|  | ||||
|                 mockElement.find.andReturn([mockCanvas]); | ||||
|                 mockCanvas.getContext.andCallFake(function (type) { | ||||
|                     return { webgl: mockGL, '2d': mockC2d }[type]; | ||||
|                 }); | ||||
|                 mockInterval.andReturn(mockPromise); | ||||
|  | ||||
|                 mctChart = new MCTTimelineChart(mockInterval, mockLog); | ||||
|             }); | ||||
|  | ||||
|             it("is applicable at the element level", function () { | ||||
|                 expect(mctChart.restrict).toEqual("E"); | ||||
|             }); | ||||
|  | ||||
|             it("places a 'draw' attribute in-scope", function () { | ||||
|                 // Should ask Angular for the draw attribute | ||||
|                 expect(mctChart.scope.draw).toEqual("="); | ||||
|             }); | ||||
|  | ||||
|             it("watches for changes in the drawn object", function () { | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|                 expect(mockScope.$watchCollection) | ||||
|                     .toHaveBeenCalledWith("draw", jasmine.any(Function)); | ||||
|             }); | ||||
|  | ||||
|             it("issues one draw call per line", function () { | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|                 mockScope.$watchCollection.mostRecentCall.args[1]({ | ||||
|                     lines: [{}, {}, {}] | ||||
|                 }); | ||||
|                 expect(mockGL.drawArrays.calls.length).toEqual(3); | ||||
|             }); | ||||
|  | ||||
|             it("issues one draw call per box", function () { | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|                 mockScope.$watchCollection.mostRecentCall.args[1]({ | ||||
|                     boxes: [ | ||||
|                         { start: [0, 0], end: [1, 1] }, | ||||
|                         { start: [0, 0], end: [1, 1] }, | ||||
|                         { start: [0, 0], end: [1, 1] }, | ||||
|                         { start: [0, 0], end: [1, 1] } | ||||
|                     ] | ||||
|                 }); | ||||
|                 expect(mockGL.drawArrays.calls.length).toEqual(4); | ||||
|             }); | ||||
|  | ||||
|             it("does not fail if no draw object is in scope", function () { | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|                 expect(mockScope.$watchCollection.mostRecentCall.args[1]) | ||||
|                     .not.toThrow(); | ||||
|             }); | ||||
|  | ||||
|             it("draws on canvas resize", function () { | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|  | ||||
|                 // Should track canvas size in an interval | ||||
|                 expect(mockInterval).toHaveBeenCalledWith( | ||||
|                     jasmine.any(Function), | ||||
|                     jasmine.any(Number), | ||||
|                     0, | ||||
|                     false | ||||
|                 ); | ||||
|  | ||||
|                 // Verify pre-condition | ||||
|                 expect(mockGL.clear).not.toHaveBeenCalled(); | ||||
|  | ||||
|                 mockCanvas.width = 100; | ||||
|                 mockCanvas.offsetWidth = 150; | ||||
|                 mockCanvas.height = 200; | ||||
|                 mockCanvas.offsetHeight = 200; | ||||
|                 mockInterval.mostRecentCall.args[0](); | ||||
|  | ||||
|                 // Use clear as an indication that drawing has occurred | ||||
|                 expect(mockGL.clear).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("warns if no WebGL context is available", function () { | ||||
|                 mockCanvas.getContext.andReturn(undefined); | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|                 expect(mockLog.warn).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("falls back to Canvas 2d API if WebGL context is lost", function () { | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|                 expect(mockCanvas.addEventListener) | ||||
|                     .toHaveBeenCalledWith("webglcontextlost", jasmine.any(Function)); | ||||
|                 expect(mockCanvas.getContext).not.toHaveBeenCalledWith('2d'); | ||||
|                 mockCanvas.addEventListener.mostRecentCall.args[1](); | ||||
|                 expect(mockCanvas.getContext).toHaveBeenCalledWith('2d'); | ||||
|             }); | ||||
|  | ||||
|             it("logs nothing in nominal situations (WebGL available)", function () { | ||||
|                 // Complement the previous test | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|                 expect(mockLog.warn).not.toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             // Avoid resource leaks | ||||
|             it("stops polling for size changes on destroy", function () { | ||||
|                 mctChart.link(mockScope, mockElement); | ||||
|  | ||||
|                 // Should be listening for a destroy event | ||||
|                 expect(mockScope.$on).toHaveBeenCalledWith( | ||||
|                     "$destroy", | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|  | ||||
|                 // Precondition - interval still active | ||||
|                 expect(mockInterval.cancel).not.toHaveBeenCalled(); | ||||
|  | ||||
|                 // Broadcast a $destroy | ||||
|                 mockScope.$on.mostRecentCall.args[1](); | ||||
|  | ||||
|                 // Should have stopped the interval | ||||
|                 expect(mockInterval.cancel).toHaveBeenCalledWith(mockPromise); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -122,12 +122,9 @@ define( | ||||
|              */ | ||||
|             self.getDatum = function (telemetryObject, index) { | ||||
|                 function makeNewDatum(series) { | ||||
|                     if (series) { | ||||
|                         if (series.getDatum) { | ||||
|                             return series.getDatum(index); | ||||
|                         } | ||||
|                         return subscription.makeDatum(telemetryObject, series, index); | ||||
|                     } | ||||
|                     return series ? | ||||
|                         subscription.makeDatum(telemetryObject, series, index) : | ||||
|                         undefined; | ||||
|                 } | ||||
|  | ||||
|                 return typeof index !== 'number' ? | ||||
|   | ||||
| @@ -21,12 +21,13 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     './object-utils' | ||||
|     './object-utils', | ||||
|     './objectEventEmitter' | ||||
| ], function ( | ||||
|     utils | ||||
|     utils, | ||||
|     objectEventEmitter | ||||
| ) { | ||||
|     function ObjectServiceProvider(eventEmitter, objectService, instantiate, topic) { | ||||
|         this.eventEmitter = eventEmitter; | ||||
|     function ObjectServiceProvider(objectService, instantiate, topic) { | ||||
|         this.objectService = objectService; | ||||
|         this.instantiate = instantiate; | ||||
|  | ||||
| @@ -60,12 +61,12 @@ define([ | ||||
|             var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId()); | ||||
|  | ||||
|             //Don't trigger self | ||||
|             this.eventEmitter.off('mutation', handleMutation); | ||||
|             this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject); | ||||
|             this.eventEmitter.on('mutation', handleMutation); | ||||
|             objectEventEmitter.off('mutation', handleMutation); | ||||
|             objectEventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject); | ||||
|             objectEventEmitter.on('mutation', handleMutation); | ||||
|         }.bind(this); | ||||
|  | ||||
|         this.eventEmitter.on('mutation', handleMutation); | ||||
|         objectEventEmitter.on('mutation', handleMutation); | ||||
|         removeGeneralTopicListener = this.generalTopic.listen(handleLegacyMutation); | ||||
|     }; | ||||
|  | ||||
| @@ -95,8 +96,6 @@ define([ | ||||
|     // Injects new object API as a decorator so that it hijacks all requests. | ||||
|     // Object providers implemented on new API should just work, old API should just work, many things may break. | ||||
|     function LegacyObjectAPIInterceptor(openmct, ROOTS, instantiate, topic, objectService) { | ||||
|         var eventEmitter = openmct.objects.eventEmitter; | ||||
|  | ||||
|         this.getObjects = function (keys) { | ||||
|             var results = {}, | ||||
|                 promises = keys.map(function (keyString) { | ||||
| @@ -115,12 +114,7 @@ define([ | ||||
|         }; | ||||
|  | ||||
|         openmct.objects.supersecretSetFallbackProvider( | ||||
|             new ObjectServiceProvider( | ||||
|                 eventEmitter, | ||||
|                 objectService, | ||||
|                 instantiate, | ||||
|                 topic | ||||
|             ) | ||||
|             new ObjectServiceProvider(objectService, instantiate, topic) | ||||
|         ); | ||||
|  | ||||
|         ROOTS.forEach(function (r) { | ||||
|   | ||||
| @@ -21,9 +21,11 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     'lodash' | ||||
|     'lodash', | ||||
|     './objectEventEmitter' | ||||
| ], function ( | ||||
|     _ | ||||
|     _, | ||||
|     objectEventEmitter | ||||
| ) { | ||||
|     var ANY_OBJECT_EVENT = "mutation"; | ||||
|  | ||||
| @@ -34,8 +36,7 @@ define([ | ||||
|      * @param object | ||||
|      * @interface MutableObject | ||||
|      */ | ||||
|     function MutableObject(eventEmitter, object) { | ||||
|         this.eventEmitter = eventEmitter; | ||||
|     function MutableObject(object) { | ||||
|         this.object = object; | ||||
|         this.unlisteners = []; | ||||
|     } | ||||
| @@ -60,11 +61,8 @@ define([ | ||||
|      */ | ||||
|     MutableObject.prototype.on = function (path, callback) { | ||||
|         var fullPath = qualifiedEventName(this.object, path); | ||||
|         var eventOff = | ||||
|             this.eventEmitter.off.bind(this.eventEmitter, fullPath, callback); | ||||
|  | ||||
|         this.eventEmitter.on(fullPath, callback); | ||||
|         this.unlisteners.push(eventOff); | ||||
|         objectEventEmitter.on(fullPath, callback); | ||||
|         this.unlisteners.push(objectEventEmitter.off.bind(objectEventEmitter, fullPath, callback)); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
| @@ -80,12 +78,12 @@ define([ | ||||
|         _.set(this.object, 'modified', Date.now()); | ||||
|  | ||||
|         //Emit event specific to property | ||||
|         this.eventEmitter.emit(qualifiedEventName(this.object, path), value); | ||||
|         objectEventEmitter.emit(qualifiedEventName(this.object, path), value); | ||||
|         //Emit wildcare event | ||||
|         this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object); | ||||
|         objectEventEmitter.emit(qualifiedEventName(this.object, '*'), this.object); | ||||
|  | ||||
|         //Emit a general "any object" event | ||||
|         this.eventEmitter.emit(ANY_OBJECT_EVENT, this.object); | ||||
|         objectEventEmitter.emit(ANY_OBJECT_EVENT, this.object); | ||||
|     }; | ||||
|  | ||||
|     return MutableObject; | ||||
|   | ||||
| @@ -25,15 +25,13 @@ define([ | ||||
|     './object-utils', | ||||
|     './MutableObject', | ||||
|     './RootRegistry', | ||||
|     './RootObjectProvider', | ||||
|     'EventEmitter' | ||||
|     './RootObjectProvider' | ||||
| ], function ( | ||||
|     _, | ||||
|     utils, | ||||
|     MutableObject, | ||||
|     RootRegistry, | ||||
|     RootObjectProvider, | ||||
|     EventEmitter | ||||
|     RootObjectProvider | ||||
| ) { | ||||
|  | ||||
|  | ||||
| @@ -44,7 +42,6 @@ define([ | ||||
|      */ | ||||
|  | ||||
|     function ObjectAPI() { | ||||
|         this.eventEmitter = new EventEmitter(); | ||||
|         this.providers = {}; | ||||
|         this.rootRegistry = new RootRegistry(); | ||||
|         this.rootProvider = new RootObjectProvider(this.rootRegistry); | ||||
| @@ -178,9 +175,7 @@ define([ | ||||
|      * @memberof module:openmct.ObjectAPI# | ||||
|      */ | ||||
|     ObjectAPI.prototype.mutate = function (domainObject, path, value) { | ||||
|         var mutableObject = | ||||
|             new MutableObject(this.eventEmitter, domainObject); | ||||
|         return mutableObject.set(path, value); | ||||
|         return new MutableObject(domainObject).set(path, value); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
| @@ -193,8 +188,7 @@ define([ | ||||
|      * @memberof module:openmct.ObjectAPI# | ||||
|      */ | ||||
|     ObjectAPI.prototype.observe = function (domainObject, path, callback) { | ||||
|         var mutableObject = | ||||
|             new MutableObject(this.eventEmitter, domainObject); | ||||
|         var mutableObject = new MutableObject(domainObject); | ||||
|         mutableObject.on(path, callback); | ||||
|         return mutableObject.stopListening.bind(mutableObject); | ||||
|     }; | ||||
|   | ||||
| @@ -45,9 +45,6 @@ define([ | ||||
|     }; | ||||
|  | ||||
|     function createDatum(domainObject, metadata, legacySeries, i) { | ||||
|         if (legacySeries.getDatum) { | ||||
|             return legacySeries.getDatum(i); | ||||
|         } | ||||
|         var datum = {}; | ||||
|  | ||||
|         metadata.domains.reduce(function (d, domain) { | ||||
|   | ||||
| @@ -109,6 +109,7 @@ define([ | ||||
|         'platform/commonUI/general', | ||||
|         'platform/commonUI/inspect', | ||||
|         'platform/commonUI/mobile', | ||||
|         'platform/commonUI/themes/espresso', | ||||
|         'platform/commonUI/notification', | ||||
|         'platform/containment', | ||||
|         'platform/execution', | ||||
|   | ||||
| @@ -21,67 +21,13 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     'lodash' | ||||
| ], function (_) { | ||||
|     var bundleMap = { | ||||
|         couchDB: 'platform/persistence/couch', | ||||
|         elasticsearch: 'platform/persistence/elastic', | ||||
|         espresso: 'platform/commonUI/themes/espresso', | ||||
|         localStorage: 'platform/persistence/local', | ||||
|         myItems: 'platform/features/my-items', | ||||
|         snow: 'platform/commonUI/themes/snow', | ||||
|         utcTimeSystem: 'platform/features/conductor/utcTimeSystem' | ||||
| ], function () { | ||||
|     return { | ||||
|         localStorage: function (openmct) { | ||||
|             openmct.legacyRegistry.enable('platform/persistence/local'); | ||||
|         }, | ||||
|         myItems: function (openmct) { | ||||
|             openmct.legacyRegistry.enable('platform/features/my-items'); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     var plugins = _.mapValues(bundleMap, function (bundleName, pluginName) { | ||||
|         return function (openmct) { | ||||
|             openmct.legacyRegistry.enable(bundleName); | ||||
|         }; | ||||
|     }); | ||||
|  | ||||
|     plugins.CouchDB = function (url) { | ||||
|         return function (openmct) { | ||||
|             if (url) { | ||||
|                 var bundleName = "config/couch"; | ||||
|                 openmct.legacyRegistry.register(bundleName, { | ||||
|                     "extensions": { | ||||
|                         "constants": [ | ||||
|                             { | ||||
|                                 "key": "COUCHDB_PATH", | ||||
|                                 "value": url, | ||||
|                                 "priority": "mandatory" | ||||
|                             } | ||||
|                         ] | ||||
|                     } | ||||
|                 }); | ||||
|                 openmct.legacyRegistry.enable(bundleName); | ||||
|             } | ||||
|  | ||||
|             openmct.legacyRegistry.enable(bundleMap.couchDB); | ||||
|         }; | ||||
|     }; | ||||
|  | ||||
|     plugins.Elasticsearch = function (url) { | ||||
|         return function (openmct) { | ||||
|             if (url) { | ||||
|                 var bundleName = "config/elastic"; | ||||
|                 openmct.legacyRegistry.register(bundleName, { | ||||
|                     "extensions": { | ||||
|                         "constants": [ | ||||
|                             { | ||||
|                                 "key": "ELASTIC_ROOT", | ||||
|                                 "value": url, | ||||
|                                 "priority": "mandatory" | ||||
|                             } | ||||
|                         ] | ||||
|                     } | ||||
|                 }); | ||||
|                 openmct.legacyRegistry.enable(bundleName); | ||||
|             } | ||||
|  | ||||
|             openmct.legacyRegistry.enable(bundleMap.elasticsearch); | ||||
|         }; | ||||
|     }; | ||||
|  | ||||
|     return plugins; | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user