Compare commits
	
		
			89 Commits
		
	
	
		
			v1.8.1
			...
			proposed-v
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3b86e02ed3 | ||
| 
						 | 
					b4dc50295c | ||
| 
						 | 
					382dde300a | ||
| 
						 | 
					02aa08a3ef | ||
| 
						 | 
					c95d9c7956 | ||
| 
						 | 
					b1b8df4d87 | ||
| 
						 | 
					bd3c6665fb | ||
| 
						 | 
					10e90519c0 | ||
| 
						 | 
					d341a8be97 | ||
| 
						 | 
					8c439d8109 | ||
| 
						 | 
					9c88b7ce1d | ||
| 
						 | 
					2463e4d59f | ||
| 
						 | 
					d73c505bea | ||
| 
						 | 
					831ecc59d9 | ||
| 
						 | 
					1de26d3c5d | ||
| 
						 | 
					11409ce509 | ||
| 
						 | 
					93872ce074 | ||
| 
						 | 
					8861644f2d | ||
| 
						 | 
					d4948f771b | ||
| 
						 | 
					8295a0bed1 | ||
| 
						 | 
					0656a298da | ||
| 
						 | 
					fe2ce91d50 | ||
| 
						 | 
					14f30b2489 | ||
| 
						 | 
					62d90a8114 | ||
| 
						 | 
					87682607a5 | ||
| 
						 | 
					7bf265b478 | ||
| 
						 | 
					1d31fe8d02 | ||
| 
						 | 
					bfdbc71e40 | ||
| 
						 | 
					1147f3aa47 | ||
| 
						 | 
					719f9f45e8 | ||
| 
						 | 
					95ef70a24c | ||
| 
						 | 
					d5aa998b4c | ||
| 
						 | 
					7890fcae69 | ||
| 
						 | 
					18843cee48 | ||
| 
						 | 
					1879c122c7 | ||
| 
						 | 
					d7ddb96c4e | ||
| 
						 | 
					b55668426d | ||
| 
						 | 
					5b656faa9d | ||
| 
						 | 
					8d2c489fa9 | ||
| 
						 | 
					4366b0870d | ||
| 
						 | 
					47a543beb7 | ||
| 
						 | 
					06f87c1472 | ||
| 
						 | 
					c9c41cdcc8 | ||
| 
						 | 
					14a56ea17e | ||
| 
						 | 
					b2e7db71cc | ||
| 
						 | 
					d51e6bfd92 | ||
| 
						 | 
					d475d767d5 | ||
| 
						 | 
					a63e053399 | ||
| 
						 | 
					370b515c23 | ||
| 
						 | 
					4a50f325cb | ||
| 
						 | 
					dbe6a4efc1 | ||
| 
						 | 
					13920d8802 | ||
| 
						 | 
					b6a8c514aa | ||
| 
						 | 
					e4a4704baa | ||
| 
						 | 
					be0029e59a | ||
| 
						 | 
					9cb273ef0a | ||
| 
						 | 
					eec9b1cf4c | ||
| 
						 | 
					1f96e84542 | ||
| 
						 | 
					c289a27305 | ||
| 
						 | 
					c944080790 | ||
| 
						 | 
					96316de6e4 | ||
| 
						 | 
					2240a87ddc | ||
| 
						 | 
					d891affe48 | ||
| 
						 | 
					21a618d1ce | ||
| 
						 | 
					5de7a96ccc | ||
| 
						 | 
					09a833f524 | ||
| 
						 | 
					580a4e52b5 | ||
| 
						 | 
					9c4e17bfab | ||
| 
						 | 
					d3e5d95d6b | ||
| 
						 | 
					c70793ac2d | ||
| 
						 | 
					a6ef1d3423 | ||
| 
						 | 
					4ca2f51d5e | ||
| 
						 | 
					86ac80ddbd | ||
| 
						 | 
					0525ba6b0b | ||
| 
						 | 
					a79e958ffc | ||
| 
						 | 
					03cb0ccb57 | ||
| 
						 | 
					7205faa6bb | ||
| 
						 | 
					136f2ae785 | ||
| 
						 | 
					a07e2fb8e5 | ||
| 
						 | 
					55b531bdeb | ||
| 
						 | 
					7ece5897e8 | ||
| 
						 | 
					a29c7a6eab | ||
| 
						 | 
					c4fec1af6a | ||
| 
						 | 
					a6996df3df | ||
| 
						 | 
					0c660238f2 | ||
| 
						 | 
					b73b824e55 | ||
| 
						 | 
					1954d98628 | ||
| 
						 | 
					7aa034ce23 | ||
| 
						 | 
					385dc5d298 | 
							
								
								
									
										285
									
								
								API.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								API.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,285 @@
 | 
			
		||||
# Open MCT API
 | 
			
		||||
 | 
			
		||||
The Open MCT framework public api can be utilized by building the application
 | 
			
		||||
(`gulp install`) and then copying the file from `dist/main.js` to your
 | 
			
		||||
directory of choice.
 | 
			
		||||
 | 
			
		||||
Open MCT supports AMD, CommonJS, and loading via a script tag; it's easy to use
 | 
			
		||||
in your project. The [`openmct`]{@link module:openmct} module is exported
 | 
			
		||||
via AMD and CommonJS, and is also exposed as `openmct` in the global scope
 | 
			
		||||
if loaded via a script tag.
 | 
			
		||||
 | 
			
		||||
## Overview
 | 
			
		||||
 | 
			
		||||
Open MCT's goal is to allow you to browse, create, edit, and visualize all of
 | 
			
		||||
the domain knowledge you need on a daily basis.
 | 
			
		||||
 | 
			
		||||
To do this, the main building block provided by Open MCT is the _domain object_.
 | 
			
		||||
The temperature sensor on the starboard solar panel,
 | 
			
		||||
an overlay plot comparing the results of all temperature sensor,
 | 
			
		||||
the command dictionary for a spacecraft,
 | 
			
		||||
the individual commands in that dictionary, your "my documents" folder:
 | 
			
		||||
All of these things are domain objects.
 | 
			
		||||
 | 
			
		||||
Domain objects have Types, so a specific instrument temperature sensor is a
 | 
			
		||||
"Telemetry Point," and turning on a drill for a certain duration of time is
 | 
			
		||||
an "Activity".  Types allow you to form an ontology of knowledge and provide
 | 
			
		||||
an abstraction for grouping, visualizing, and interpreting data.
 | 
			
		||||
 | 
			
		||||
And then we have Views. Views allow you to visualize domain objects. Views can
 | 
			
		||||
apply to specific domain objects; they may also apply to certain types of
 | 
			
		||||
domain objects, or they may apply to everything.  Views are simply a method
 | 
			
		||||
of visualizing domain objects.
 | 
			
		||||
 | 
			
		||||
Regions allow you to specify what views are displayed for specific types of
 | 
			
		||||
domain objects in response to different user actions. For instance, you may
 | 
			
		||||
want to display a different view while editing, or you may want to update the
 | 
			
		||||
toolbar display when objects are selected.  Regions allow you to map views to
 | 
			
		||||
specific user actions.
 | 
			
		||||
 | 
			
		||||
Domain objects can be mutated and persisted, developers can create custom
 | 
			
		||||
actions and apply them to domain objects, and many more things can be done.
 | 
			
		||||
For more information, read on!
 | 
			
		||||
 | 
			
		||||
## Running Open MCT
 | 
			
		||||
 | 
			
		||||
Once the [`openmct`](@link module:openmct) module has been loaded, you can
 | 
			
		||||
simply invoke [`start`]{@link module:openmct.MCT#start} to run Open MCT:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.start();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Generally, however, you will want to configure Open MCT by adding plugins
 | 
			
		||||
before starting it. It is important to install plugins and configure Open MCT
 | 
			
		||||
_before_ calling [`start`]{@link module:openmct.MCT#start}; Open MCT is not
 | 
			
		||||
designed to be reconfigured once started.
 | 
			
		||||
 | 
			
		||||
## Configuring Open MCT
 | 
			
		||||
 | 
			
		||||
The [`openmct`]{@link module:openmct} module (more specifically, the
 | 
			
		||||
[`MCT`]{@link module:openmct.MCT} class, of which `openmct` is an instance)
 | 
			
		||||
exposes a variety of methods to allow the application to be configured,
 | 
			
		||||
extended, and customized before running.
 | 
			
		||||
 | 
			
		||||
Short examples follow; see the linked documentation for further details.
 | 
			
		||||
 | 
			
		||||
### Adding Domain Object Types
 | 
			
		||||
 | 
			
		||||
Custom types may be registered via
 | 
			
		||||
[`openmct.types`]{@link module:openmct.MCT#types}:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.types.addType('my-type', new openmct.Type({
 | 
			
		||||
    label: "My Type",
 | 
			
		||||
    description: "This is a type that I added!"
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Adding Views
 | 
			
		||||
 | 
			
		||||
Custom views may be registered based on the region in the application
 | 
			
		||||
where they should appear:
 | 
			
		||||
 | 
			
		||||
* [`openmct.mainViews`]{@link module:openmct.MCT#mainViews} is a registry
 | 
			
		||||
  of views of domain objects which should appear in the main viewing area.
 | 
			
		||||
* [`openmct.inspectors`]{@link module:openmct.MCT#inspectors} is a registry
 | 
			
		||||
  of views of domain objects and/or active selections, which should appear in
 | 
			
		||||
  the Inspector.
 | 
			
		||||
* [`openmct.toolbars`]{@link module:openmct.MCT#toolbars} is a registry
 | 
			
		||||
  of views of domain objects and/or active selections, which should appear in
 | 
			
		||||
  the toolbar area while editing.
 | 
			
		||||
* [`openmct.indicators`]{@link module:openmct.MCT#inspectors} is a registry
 | 
			
		||||
  of views which should appear in the status area of the application.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.mainViews.addProvider({
 | 
			
		||||
    canView: function (domainObject) {
 | 
			
		||||
        return domainObject.type === 'my-type';
 | 
			
		||||
    },
 | 
			
		||||
    view: function (domainObject) {
 | 
			
		||||
        return new MyView(domainObject);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Adding a Root-level Object
 | 
			
		||||
 | 
			
		||||
In many cases, you'd like a certain object (or a certain hierarchy of
 | 
			
		||||
objects) to be accessible from the top level of the application (the
 | 
			
		||||
tree on the left-hand side of Open MCT.) It is typical to expose a telemetry
 | 
			
		||||
dictionary as a hierarchy of telemetry-providing domain objects in this
 | 
			
		||||
fashion.
 | 
			
		||||
 | 
			
		||||
To do so, use the [`addRoot`]{@link module:openmct.ObjectAPI#addRoot} method
 | 
			
		||||
of the [object API]{@link module:openmct.ObjectAPI}:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.objects.addRoot({
 | 
			
		||||
    identifier: { key: "my-key", namespace: "my-namespace" }
 | 
			
		||||
    name: "My Root-level Object",
 | 
			
		||||
    type: "my-type"
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You can also remove this root-level object via its identifier:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.objects.removeRoot({ key: "my-key", namespace: "my-namespace" });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Adding Composition Providers
 | 
			
		||||
 | 
			
		||||
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 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:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.composition.addProvider({
 | 
			
		||||
    appliesTo: function (domainObject) {
 | 
			
		||||
        return domainObject.type === 'my-type';
 | 
			
		||||
    },
 | 
			
		||||
    load: function (domainObject) {
 | 
			
		||||
        return Promise.resolve(myDomainObjects);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Adding Telemetry Providers
 | 
			
		||||
 | 
			
		||||
When connecting to a new telemetry source, you will want to register a new
 | 
			
		||||
[telemetry provider]{@link module:openmct.TelemetryAPI~TelemetryProvider}
 | 
			
		||||
with the [telemetry API]{@link module:openmct.TelemetryAPI#addProvider}:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.telemetry.addProvider({
 | 
			
		||||
    canProvideTelemetry: function (domainObject) {
 | 
			
		||||
        return domainObject.type === 'my-type';
 | 
			
		||||
    },
 | 
			
		||||
    properties: function (domainObject) {
 | 
			
		||||
        return [
 | 
			
		||||
            { key: 'value', name: "Temperature", units: "degC" },
 | 
			
		||||
            { key: 'time', name: "UTC" }
 | 
			
		||||
        ];
 | 
			
		||||
    },
 | 
			
		||||
    request: function (domainObject, options) {
 | 
			
		||||
        var telemetryId = domainObject.myTelemetryId;
 | 
			
		||||
        return myAdapter.request(telemetryId, options.start, options.end);
 | 
			
		||||
    },
 | 
			
		||||
    subscribe: function (domainObject, callback) {
 | 
			
		||||
        var telemetryId = domainObject.myTelemetryId;
 | 
			
		||||
        myAdapter.subscribe(telemetryId, callback);
 | 
			
		||||
        return myAdapter.unsubscribe.bind(myAdapter, telemetryId, callback);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The implementations for `request` and `subscribe` can vary depending on the
 | 
			
		||||
nature of the endpoint which will provide telemetry. In the example above,
 | 
			
		||||
it is assumed that `myAdapter` contains the specific implementations
 | 
			
		||||
(HTTP requests, WebSocket connections, etc.) associated with some telemetry
 | 
			
		||||
source.
 | 
			
		||||
 | 
			
		||||
## Using Open MCT
 | 
			
		||||
 | 
			
		||||
When implementing new features, it is useful and sometimes necessary to
 | 
			
		||||
utilize functionality exposed by Open MCT.
 | 
			
		||||
 | 
			
		||||
### Retrieving Composition
 | 
			
		||||
 | 
			
		||||
To limit which objects are loaded at any given time, the composition of
 | 
			
		||||
a domain object must be requested asynchronously:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.composition(myObject).load().then(function (childObjects) {
 | 
			
		||||
    childObjects.forEach(doSomething);
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Support Common Gestures
 | 
			
		||||
 | 
			
		||||
Custom views may also want to support common gestures using the
 | 
			
		||||
[gesture API]{@link module:openmct.GestureAPI}. For instance, to make
 | 
			
		||||
a view (or part of a view) selectable:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.gestures.selectable(myHtmlElement, myDomainObject);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Working with Domain Objects
 | 
			
		||||
 | 
			
		||||
The [object API]{@link module:openmct.ObjectAPI} provides useful methods
 | 
			
		||||
for working with domain objects.
 | 
			
		||||
 | 
			
		||||
To make changes to a domain object, use the
 | 
			
		||||
[`mutate`]{@link module:openmct.ObjectAPI#mutate} method:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.objects.mutate(myDomainObject, "name", "New name!");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Making modifications in this fashion allows other usages of the domain
 | 
			
		||||
object to remain up to date using the
 | 
			
		||||
[`observe`]{@link module:openmct.ObjectAPI#observe} method:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.objects.observe(myDomainObject, "name", function (newName) {
 | 
			
		||||
    myLabel.textContent = newName;
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Using Telemetry
 | 
			
		||||
 | 
			
		||||
Very often in Open MCT, you wish to work with telemetry data (for instance,
 | 
			
		||||
to display it in a custom visualization.)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Synchronizing with the Time Conductor
 | 
			
		||||
 | 
			
		||||
Views which wish to remain synchronized with the state of Open MCT's
 | 
			
		||||
time conductor should utilize
 | 
			
		||||
[`openmct.conductor`]{@link module:openmct.TimeConductor}:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.conductor.on('bounds', function (newBounds) {
 | 
			
		||||
    requestTelemetry(newBounds.start, newBounds.end).then(displayTelemetry);
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Plugins
 | 
			
		||||
 | 
			
		||||
While you can register new features with Open MCT directly, it is generally
 | 
			
		||||
more useful to package these as a plugin. A plugin is a function that takes
 | 
			
		||||
[`openmct`]{@link module:openmct} as an argument, and performs configuration
 | 
			
		||||
upon `openmct` when invoked.
 | 
			
		||||
 | 
			
		||||
### Installing Plugins
 | 
			
		||||
 | 
			
		||||
To install plugins, use the [`install`]{@link module:openmct.MCT#install}
 | 
			
		||||
method:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
openmct.install(myPlugin);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The plugin will be invoked to configure Open MCT before it is started.
 | 
			
		||||
 | 
			
		||||
### Writing Plugins
 | 
			
		||||
 | 
			
		||||
Plugins configure Open MCT, and should utilize the
 | 
			
		||||
[`openmct`]{@link module:openmct} module to do so, as summarized above in
 | 
			
		||||
"Configuring Open MCT" and "Using Open MCT" above.
 | 
			
		||||
 | 
			
		||||
### Distributing Plugins
 | 
			
		||||
 | 
			
		||||
Hosting or downloading plugins is outside of the scope of this documentation.
 | 
			
		||||
We recommend distributing plugins as UMD modules which export a single
 | 
			
		||||
function.
 | 
			
		||||
 | 
			
		||||
@@ -18,6 +18,9 @@
 | 
			
		||||
    "node-uuid": "^1.4.7",
 | 
			
		||||
    "comma-separated-values": "^3.6.4",
 | 
			
		||||
    "FileSaver.js": "^0.0.2",
 | 
			
		||||
    "zepto": "^1.1.6"
 | 
			
		||||
    "zepto": "^1.1.6",
 | 
			
		||||
    "eventemitter3": "^1.2.0",
 | 
			
		||||
    "lodash": "3.10.1",
 | 
			
		||||
    "almond": "~0.3.2"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								composition-test.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								composition-test.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
 | 
			
		||||
  <title>Implementing a composition provider</title>
 | 
			
		||||
  <script src="dist/main.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
    var widgetParts = ['foo', 'bar', 'baz', 'bing', 'frobnak']
 | 
			
		||||
 | 
			
		||||
    function fabricateName() {
 | 
			
		||||
        return [
 | 
			
		||||
            widgetParts[Math.floor(Math.random() * widgetParts.length)],
 | 
			
		||||
            widgetParts[Math.floor(Math.random() * widgetParts.length)],
 | 
			
		||||
            Math.floor(Math.random() * 1000)
 | 
			
		||||
        ].join('_');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MCT.type('example.widget-factory', new MCT.Type({
 | 
			
		||||
        metadata: {
 | 
			
		||||
            label: "Widget Factory",
 | 
			
		||||
            glyph: "s",
 | 
			
		||||
            description: "A factory for making widgets"
 | 
			
		||||
        },
 | 
			
		||||
        initialize: function (object) {
 | 
			
		||||
            object.widgetCount = 5;
 | 
			
		||||
            object.composition = [];
 | 
			
		||||
        },
 | 
			
		||||
        creatable: true,
 | 
			
		||||
        form: [
 | 
			
		||||
            {
 | 
			
		||||
                name: "Widget Count",
 | 
			
		||||
                control: "textfield",
 | 
			
		||||
                key: "widgetCount",
 | 
			
		||||
                property: "widgetCount",
 | 
			
		||||
                required: true
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    MCT.Composition.addProvider({
 | 
			
		||||
        appliesTo: function (domainObject) {
 | 
			
		||||
            return domainObject.type === 'example.widget-factory';
 | 
			
		||||
        },
 | 
			
		||||
        load: function (domainObject) {
 | 
			
		||||
            var widgets = [];
 | 
			
		||||
            while (widgets.length < domainObject.widgetCount) {
 | 
			
		||||
                widgets.push({
 | 
			
		||||
                    name: fabricateName(),
 | 
			
		||||
                    key: {
 | 
			
		||||
                        namespace: 'widget-factory',
 | 
			
		||||
                        identifier: '' + widgets.length
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            return Promise.resolve(widgets);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    MCT.run();
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										144
									
								
								custom-view-react.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								custom-view-react.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
 | 
			
		||||
  <title>Implementing a Custom Type and View </title>
 | 
			
		||||
  <script src="dist/main.js"></script>
 | 
			
		||||
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react.js"></script>
 | 
			
		||||
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react-dom.js"></script>
 | 
			
		||||
      <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<script type="text/babel">
 | 
			
		||||
 | 
			
		||||
    // First, we're going to create the Todo List type, so that users can create
 | 
			
		||||
    // todo lists.
 | 
			
		||||
 | 
			
		||||
    MCT.type('example.todo', new MCT.Type({
 | 
			
		||||
        metadata: {
 | 
			
		||||
            label: "To-Do List",
 | 
			
		||||
            glyph: "2",
 | 
			
		||||
            description: "A list of things that need to be done."
 | 
			
		||||
        },
 | 
			
		||||
        initialize: function (object) {
 | 
			
		||||
            object.tasks = [
 | 
			
		||||
                { description: "This is a task." }
 | 
			
		||||
            ];
 | 
			
		||||
        },
 | 
			
		||||
        creatable: true
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    Refresh the page, and you should be able to create new Todo Lists.
 | 
			
		||||
    unfortunately, when you navigate to a Todo list, you see a blank page. let's
 | 
			
		||||
    fix that by adding a main view for that todo list.
 | 
			
		||||
 | 
			
		||||
    If you're wondering why this is commented out, well, it's because we'll
 | 
			
		||||
    write a new version later.
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    var Task = React.createClass({
 | 
			
		||||
      render: function() {
 | 
			
		||||
        return (
 | 
			
		||||
            <li>
 | 
			
		||||
                <input type="checkbox"
 | 
			
		||||
                       checked={this.props.checked}/>
 | 
			
		||||
                <span>{this.props.description}</span>
 | 
			
		||||
            </li>
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var TaskList = React.createClass({
 | 
			
		||||
        render: function () {
 | 
			
		||||
            var taskNodes = this.props.tasks.map(function(task) {
 | 
			
		||||
                return (
 | 
			
		||||
                    <Task checked={task.checked}
 | 
			
		||||
                          description={task.description}/>
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
            return (
 | 
			
		||||
              <ul>
 | 
			
		||||
                {taskNodes}
 | 
			
		||||
              </ul>
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    MCT.view(MCT.regions.main, {
 | 
			
		||||
        canView: function (domainObject) {
 | 
			
		||||
            return domainObject.type === 'example.todo';
 | 
			
		||||
        },
 | 
			
		||||
        view: function (domainObject) {
 | 
			
		||||
            var mutableObject = MCT.Objects.getMutable(domainObject);
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                show: function (container) {
 | 
			
		||||
                    ReactDOM.render(
 | 
			
		||||
                        <TaskList tasks={domainObject.tasks}/>,
 | 
			
		||||
                        container
 | 
			
		||||
                    );
 | 
			
		||||
                    mutableObject.on('tasks', function (tasks) {
 | 
			
		||||
                        ReactDOM.render(
 | 
			
		||||
                            <TaskList tasks={tasks}/>,
 | 
			
		||||
                            container
 | 
			
		||||
                        );
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     Refresh the page and you should see a todo list with checkboxes!  Now let's
 | 
			
		||||
     Allow you to add tasks by mutating the object.  We'll add a toolbar view to
 | 
			
		||||
     do this.
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    var TaskToolbar = React.createClass({
 | 
			
		||||
        render: function () {
 | 
			
		||||
            return (
 | 
			
		||||
                <button onClick={this.props.addTask}>Add Task</button>
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    MCT.view(MCT.regions.toolbar, {
 | 
			
		||||
        canView: function (domainObject) {
 | 
			
		||||
            return domainObject.type === 'example.todo';
 | 
			
		||||
        },
 | 
			
		||||
        view: function (domainObject) {
 | 
			
		||||
            var mutableObject = MCT.Objects.getMutable(domainObject);
 | 
			
		||||
 | 
			
		||||
            function addTask(event) {
 | 
			
		||||
                var description = prompt('Task description');
 | 
			
		||||
                var tasks = mutableObject.get('tasks');
 | 
			
		||||
                tasks.push({
 | 
			
		||||
                    description: description,
 | 
			
		||||
                    complete: false
 | 
			
		||||
                });
 | 
			
		||||
                mutableObject.set('tasks', tasks);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                show: function (container) {
 | 
			
		||||
                    ReactDOM.render(
 | 
			
		||||
                        <TaskToolbar addTask={addTask}/>,
 | 
			
		||||
                        container
 | 
			
		||||
                    );
 | 
			
		||||
                },
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     Refresh the page, edit the todo list, and you'll have a button that allows
 | 
			
		||||
     you to add tasks!  Unfortunately, new tasks don't show in the list.  Why?
 | 
			
		||||
     Well, if your view should update on mutation, you need to set up the correct
 | 
			
		||||
     listeners.  Let's update the TodoView we made earlier:
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    MCT.run();
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										160
									
								
								custom-view.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								custom-view.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
 | 
			
		||||
  <title>Implementing a Custom Type and View </title>
 | 
			
		||||
  <script src="dist/main.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
    // First, we're going to create the Todo List type, so that users can create
 | 
			
		||||
    // todo lists.
 | 
			
		||||
 | 
			
		||||
    MCT.type('example.todo', new MCT.Type({
 | 
			
		||||
        metadata: {
 | 
			
		||||
            label: "To-Do List",
 | 
			
		||||
            glyph: "2",
 | 
			
		||||
            description: "A list of things that need to be done."
 | 
			
		||||
        },
 | 
			
		||||
        initialize: function (object) {
 | 
			
		||||
            object.tasks = [
 | 
			
		||||
                { description: "This is a task." }
 | 
			
		||||
            ];
 | 
			
		||||
        },
 | 
			
		||||
        creatable: true
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    Refresh the page, and you should be able to create new Todo Lists.
 | 
			
		||||
    unfortunately, when you navigate to a Todo list, you see a blank page. let's
 | 
			
		||||
    fix that by adding a main view for that todo list.
 | 
			
		||||
 | 
			
		||||
    If you're wondering why this is commented out, well, it's because we'll
 | 
			
		||||
    write a new version later.
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    // MCT.view(MCT.regions.main, {
 | 
			
		||||
    //     canView: function (domainObject) {
 | 
			
		||||
    //         return domainObject.type === 'example.todo';
 | 
			
		||||
    //     },
 | 
			
		||||
    //     view: function (domainObject) {
 | 
			
		||||
    //         function renderTask(task) {
 | 
			
		||||
    //             return [
 | 
			
		||||
    //                 '<li>',
 | 
			
		||||
    //                 '<input type="checkbox"' + (task.complete ? ' checked="true"' : '') + '>',
 | 
			
		||||
    //                 '<span>' + task.description + '</span>',
 | 
			
		||||
    //                 '</li>'
 | 
			
		||||
    //             ].join('');
 | 
			
		||||
    //         };
 | 
			
		||||
    //
 | 
			
		||||
    //         function renderTaskList() {
 | 
			
		||||
    //             return [
 | 
			
		||||
    //                 '<ul>',
 | 
			
		||||
    //                 domainObject.tasks.map(renderTask).join(''),
 | 
			
		||||
    //                 '</ul>'
 | 
			
		||||
    //             ].join('');
 | 
			
		||||
    //         };
 | 
			
		||||
    //
 | 
			
		||||
    //         return {
 | 
			
		||||
    //             show: function (container) {
 | 
			
		||||
    //                 container.innerHTML = renderTaskList();
 | 
			
		||||
    //             }
 | 
			
		||||
    //         };
 | 
			
		||||
    //     }
 | 
			
		||||
    // });
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     Refresh the page and you should see a todo list with checkboxes!  Now let's
 | 
			
		||||
     Allow you to add tasks by mutating the object.  We'll add a toolbar view to
 | 
			
		||||
     do this.
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    MCT.view(MCT.regions.toolbar, {
 | 
			
		||||
        canView: function (domainObject) {
 | 
			
		||||
            return domainObject.type === 'example.todo';
 | 
			
		||||
        },
 | 
			
		||||
        view: function (domainObject) {
 | 
			
		||||
            var mutableObject = MCT.Objects.getMutable(domainObject);
 | 
			
		||||
 | 
			
		||||
            function addTask(event) {
 | 
			
		||||
                var description = prompt('Task description');
 | 
			
		||||
                var tasks = mutableObject.get('tasks');
 | 
			
		||||
                tasks.push({
 | 
			
		||||
                    description: description,
 | 
			
		||||
                    complete: false
 | 
			
		||||
                });
 | 
			
		||||
                mutableObject.set('tasks', tasks);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                show: function (container) {
 | 
			
		||||
                    container.addEventListener('click', addTask);
 | 
			
		||||
                    container.innerHTML = '<button>Add Task</button>';
 | 
			
		||||
                },
 | 
			
		||||
                destroy: function (container) {
 | 
			
		||||
                    container.removeEventListener('click', addTask);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     Refresh the page, edit the todo list, and you'll have a button that allows
 | 
			
		||||
     you to add tasks!  Unfortunately, new tasks don't show in the list.  Why?
 | 
			
		||||
     Well, if your view should update on mutation, you need to set up the correct
 | 
			
		||||
     listeners.  Let's update the TodoView we made earlier:
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    MCT.view(MCT.regions.main, {
 | 
			
		||||
        canView: function(domainObject) {
 | 
			
		||||
            return domainObject.type === 'example.todo'
 | 
			
		||||
        },
 | 
			
		||||
        view: function (domainObject) {
 | 
			
		||||
 | 
			
		||||
            var mutableObject = MCT.Objects.getMutable(domainObject);
 | 
			
		||||
 | 
			
		||||
            function renderTask(task) {
 | 
			
		||||
                return [
 | 
			
		||||
                    '<li>',
 | 
			
		||||
                    '<input type="checkbox"' + (task.complete ? ' checked="true"' : '') + '>',
 | 
			
		||||
                    '<span>' + task.description + '</span>',
 | 
			
		||||
                    '</li>'
 | 
			
		||||
                ].join('');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function renderTaskList(tasks) {
 | 
			
		||||
                return [
 | 
			
		||||
                    '<ul>',
 | 
			
		||||
                    tasks.map(renderTask).join(''),
 | 
			
		||||
                    '</ul>'
 | 
			
		||||
                ].join('');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function onCheckboxChange(event) {
 | 
			
		||||
                var checkbox = event.target;
 | 
			
		||||
                var taskEl = checkbox.parentNode;
 | 
			
		||||
                var taskList = taskEl.parentNode;
 | 
			
		||||
                var taskIndex = [].slice.apply(taskList.children).indexOf(taskEl);
 | 
			
		||||
                mutableObject.set('tasks[' + taskIndex + '].complete', checkbox.checked);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                show: function (container) {
 | 
			
		||||
                    container.innerHTML = renderTaskList(domainObject.tasks);
 | 
			
		||||
                    mutableObject.on('tasks', function (tasks) {
 | 
			
		||||
                        container.innerHTML = renderTaskList(tasks);
 | 
			
		||||
                    });
 | 
			
		||||
                    container.addEventListener('change', onCheckboxChange);
 | 
			
		||||
                },
 | 
			
		||||
                destroy: function () {
 | 
			
		||||
                    mutableObject.stopListening();
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    MCT.run();
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -36,7 +36,7 @@ define([
 | 
			
		||||
    legacyRegistry
 | 
			
		||||
) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    legacyRegistry.register("example/notifications", {
 | 
			
		||||
    legacyRegistry.register("example/msl-adapter", {
 | 
			
		||||
        "name" : "Mars Science Laboratory Data Adapter",
 | 
			
		||||
        "extensions" : {
 | 
			
		||||
        "types": [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								gulpfile.js
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								gulpfile.js
									
									
									
									
									
								
							@@ -21,40 +21,33 @@
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
/*global require,__dirname*/
 | 
			
		||||
 | 
			
		||||
var gulp = require('gulp'),
 | 
			
		||||
    requirejsOptimize = require('gulp-requirejs-optimize'),
 | 
			
		||||
    sourcemaps = require('gulp-sourcemaps'),
 | 
			
		||||
    rename = require('gulp-rename'),
 | 
			
		||||
    sass = require('gulp-sass'),
 | 
			
		||||
    bourbon = require('node-bourbon'),
 | 
			
		||||
    jshint = require('gulp-jshint'),
 | 
			
		||||
    jscs = require('gulp-jscs'),
 | 
			
		||||
    replace = require('gulp-replace-task'),
 | 
			
		||||
    karma = require('karma'),
 | 
			
		||||
    path = require('path'),
 | 
			
		||||
    fs = require('fs'),
 | 
			
		||||
    git = require('git-rev-sync'),
 | 
			
		||||
    moment = require('moment'),
 | 
			
		||||
    merge = require('merge-stream'),
 | 
			
		||||
    project = require('./package.json'),
 | 
			
		||||
    _ = require('lodash'),
 | 
			
		||||
    paths = {
 | 
			
		||||
        main: 'main.js',
 | 
			
		||||
        dist: 'dist',
 | 
			
		||||
        assets: 'dist/assets',
 | 
			
		||||
        scss: ['./platform/**/*.scss', './example/**/*.scss'],
 | 
			
		||||
        assets: [
 | 
			
		||||
            './{example,platform}/**/*.{css,css.map,png,svg,ico,woff,eot,ttf}'
 | 
			
		||||
        ],
 | 
			
		||||
        scripts: [ 'main.js', 'platform/**/*.js', 'src/**/*.js' ],
 | 
			
		||||
        specs: [ 'platform/**/*Spec.js', 'src/**/*Spec.js' ],
 | 
			
		||||
        static: [
 | 
			
		||||
            'index.html',
 | 
			
		||||
            'platform/**/*',
 | 
			
		||||
            'example/**/*',
 | 
			
		||||
            'bower_components/**/*'
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    options = {
 | 
			
		||||
        requirejsOptimize: {
 | 
			
		||||
            name: paths.main.replace(/\.js$/, ''),
 | 
			
		||||
            name: 'bower_components/almond/almond.js',
 | 
			
		||||
            include: paths.main.replace('.js', ''),
 | 
			
		||||
            wrap: {
 | 
			
		||||
                startFile: "src/start.frag",
 | 
			
		||||
                endFile: "src/end.frag"
 | 
			
		||||
            },
 | 
			
		||||
            mainConfigFile: paths.main,
 | 
			
		||||
            wrapShim: true
 | 
			
		||||
        },
 | 
			
		||||
@@ -63,7 +56,6 @@ var gulp = require('gulp'),
 | 
			
		||||
            singleRun: true
 | 
			
		||||
        },
 | 
			
		||||
        sass: {
 | 
			
		||||
            includePaths: bourbon.includePaths,
 | 
			
		||||
            sourceComments: true
 | 
			
		||||
        },
 | 
			
		||||
        replace: {
 | 
			
		||||
@@ -77,6 +69,8 @@ var gulp = require('gulp'),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
gulp.task('scripts', function () {
 | 
			
		||||
    var requirejsOptimize = require('gulp-requirejs-optimize');
 | 
			
		||||
    var replace = require('gulp-replace-task');
 | 
			
		||||
    return gulp.src(paths.main)
 | 
			
		||||
        .pipe(sourcemaps.init())
 | 
			
		||||
        .pipe(requirejsOptimize(options.requirejsOptimize))
 | 
			
		||||
@@ -86,10 +80,16 @@ gulp.task('scripts', function () {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('test', function (done) {
 | 
			
		||||
    var karma = require('karma');
 | 
			
		||||
    new karma.Server(options.karma, done).start();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('stylesheets', function () {
 | 
			
		||||
    var sass = require('gulp-sass');
 | 
			
		||||
    var rename = require('gulp-rename');
 | 
			
		||||
    var bourbon = require('node-bourbon');
 | 
			
		||||
    options.sass.includePaths = bourbon.includePaths;
 | 
			
		||||
 | 
			
		||||
    return gulp.src(paths.scss, {base: '.'})
 | 
			
		||||
        .pipe(sourcemaps.init())
 | 
			
		||||
        .pipe(sass(options.sass).on('error', sass.logError))
 | 
			
		||||
@@ -103,6 +103,9 @@ gulp.task('stylesheets', function () {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('lint', function () {
 | 
			
		||||
    var jshint = require('gulp-jshint');
 | 
			
		||||
    var merge = require('merge-stream');
 | 
			
		||||
 | 
			
		||||
    var nonspecs = paths.specs.map(function (glob) {
 | 
			
		||||
            return "!" + glob;
 | 
			
		||||
        }),
 | 
			
		||||
@@ -117,6 +120,8 @@ gulp.task('lint', function () {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('checkstyle', function () {
 | 
			
		||||
    var jscs = require('gulp-jscs');
 | 
			
		||||
 | 
			
		||||
    return gulp.src(paths.scripts)
 | 
			
		||||
        .pipe(jscs())
 | 
			
		||||
        .pipe(jscs.reporter())
 | 
			
		||||
@@ -124,18 +129,20 @@ gulp.task('checkstyle', function () {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('fixstyle', function () {
 | 
			
		||||
    var jscs = require('gulp-jscs');
 | 
			
		||||
 | 
			
		||||
    return gulp.src(paths.scripts, { base: '.' })
 | 
			
		||||
        .pipe(jscs({ fix: true }))
 | 
			
		||||
        .pipe(gulp.dest('.'));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('static', ['stylesheets'], function () {
 | 
			
		||||
    return gulp.src(paths.static, { base: '.' })
 | 
			
		||||
gulp.task('assets', ['stylesheets'], function () {
 | 
			
		||||
    return gulp.src(paths.assets)
 | 
			
		||||
        .pipe(gulp.dest(paths.dist));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('watch', function () {
 | 
			
		||||
    gulp.watch(paths.scss, ['stylesheets']);
 | 
			
		||||
    return gulp.watch(paths.scss, ['stylesheets', 'assets']);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('serve', function () {
 | 
			
		||||
@@ -143,9 +150,9 @@ gulp.task('serve', function () {
 | 
			
		||||
    var app = require('./app.js');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
gulp.task('develop', ['serve', 'stylesheets', 'watch']);
 | 
			
		||||
gulp.task('develop', ['serve', 'install', 'watch']);
 | 
			
		||||
 | 
			
		||||
gulp.task('install', [ 'static', 'scripts' ]);
 | 
			
		||||
gulp.task('install', [ 'assets', 'scripts' ]);
 | 
			
		||||
 | 
			
		||||
gulp.task('verify', [ 'lint', 'test', 'checkstyle' ]);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,14 @@
 | 
			
		||||
    <script type="text/javascript">
 | 
			
		||||
        require(['main'], function (mct) {
 | 
			
		||||
            require([
 | 
			
		||||
                './tutorials/todo/todo',
 | 
			
		||||
                './example/imagery/bundle',
 | 
			
		||||
                './example/eventGenerator/bundle',
 | 
			
		||||
                './example/generator/bundle'
 | 
			
		||||
            ], mct.run.bind(mct));
 | 
			
		||||
            ], function (todoPlugin) {
 | 
			
		||||
                mct.install(todoPlugin);
 | 
			
		||||
                mct.run();
 | 
			
		||||
            })
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
    <link rel="stylesheet" href="platform/commonUI/general/res/css/startup-base.css">
 | 
			
		||||
@@ -48,7 +52,5 @@
 | 
			
		||||
    <div class="l-splash-holder s-splash-holder">
 | 
			
		||||
        <div class="l-splash s-splash"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div ng-view></div>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								main.js
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								main.js
									
									
									
									
									
								
							@@ -28,13 +28,15 @@ requirejs.config({
 | 
			
		||||
        "angular-route": "bower_components/angular-route/angular-route.min",
 | 
			
		||||
        "csv": "bower_components/comma-separated-values/csv.min",
 | 
			
		||||
        "es6-promise": "bower_components/es6-promise/promise.min",
 | 
			
		||||
        "EventEmitter": "bower_components/eventemitter3/index",
 | 
			
		||||
        "moment": "bower_components/moment/moment",
 | 
			
		||||
        "moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
 | 
			
		||||
        "saveAs": "bower_components/FileSaver.js/FileSaver.min",
 | 
			
		||||
        "screenfull": "bower_components/screenfull/dist/screenfull.min",
 | 
			
		||||
        "text": "bower_components/text/text",
 | 
			
		||||
        "uuid": "bower_components/node-uuid/uuid",
 | 
			
		||||
        "zepto": "bower_components/zepto/zepto.min"
 | 
			
		||||
        "zepto": "bower_components/zepto/zepto.min",
 | 
			
		||||
        "lodash": "bower_components/lodash/lodash"
 | 
			
		||||
    },
 | 
			
		||||
    "shim": {
 | 
			
		||||
        "angular": {
 | 
			
		||||
@@ -43,6 +45,9 @@ requirejs.config({
 | 
			
		||||
        "angular-route": {
 | 
			
		||||
            "deps": ["angular"]
 | 
			
		||||
        },
 | 
			
		||||
        "EventEmitter": {
 | 
			
		||||
            "exports": "EventEmitter"
 | 
			
		||||
        },
 | 
			
		||||
        "moment-duration-format": {
 | 
			
		||||
            "deps": ["moment"]
 | 
			
		||||
        },
 | 
			
		||||
@@ -51,53 +56,32 @@ requirejs.config({
 | 
			
		||||
        },
 | 
			
		||||
        "zepto": {
 | 
			
		||||
            "exports": "Zepto"
 | 
			
		||||
        },
 | 
			
		||||
        "lodash": {
 | 
			
		||||
            "exports": "lodash"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
define([
 | 
			
		||||
    './platform/framework/src/Main',
 | 
			
		||||
    'legacyRegistry',
 | 
			
		||||
    './src/defaultRegistry',
 | 
			
		||||
    './src/MCT'
 | 
			
		||||
], function (Main, defaultRegistry, MCT) {
 | 
			
		||||
    var mct = new MCT();
 | 
			
		||||
 | 
			
		||||
    './platform/framework/bundle',
 | 
			
		||||
    './platform/core/bundle',
 | 
			
		||||
    './platform/representation/bundle',
 | 
			
		||||
    './platform/commonUI/about/bundle',
 | 
			
		||||
    './platform/commonUI/browse/bundle',
 | 
			
		||||
    './platform/commonUI/edit/bundle',
 | 
			
		||||
    './platform/commonUI/dialog/bundle',
 | 
			
		||||
    './platform/commonUI/formats/bundle',
 | 
			
		||||
    './platform/commonUI/general/bundle',
 | 
			
		||||
    './platform/commonUI/inspect/bundle',
 | 
			
		||||
    './platform/commonUI/mobile/bundle',
 | 
			
		||||
    './platform/commonUI/themes/espresso/bundle',
 | 
			
		||||
    './platform/commonUI/notification/bundle',
 | 
			
		||||
    './platform/containment/bundle',
 | 
			
		||||
    './platform/execution/bundle',
 | 
			
		||||
    './platform/exporters/bundle',
 | 
			
		||||
    './platform/telemetry/bundle',
 | 
			
		||||
    './platform/features/clock/bundle',
 | 
			
		||||
    './platform/features/imagery/bundle',
 | 
			
		||||
    './platform/features/layout/bundle',
 | 
			
		||||
    './platform/features/pages/bundle',
 | 
			
		||||
    './platform/features/plot/bundle',
 | 
			
		||||
    './platform/features/timeline/bundle',
 | 
			
		||||
    './platform/features/table/bundle',
 | 
			
		||||
    './platform/forms/bundle',
 | 
			
		||||
    './platform/identity/bundle',
 | 
			
		||||
    './platform/persistence/aggregator/bundle',
 | 
			
		||||
    './platform/persistence/local/bundle',
 | 
			
		||||
    './platform/persistence/queue/bundle',
 | 
			
		||||
    './platform/policy/bundle',
 | 
			
		||||
    './platform/entanglement/bundle',
 | 
			
		||||
    './platform/search/bundle',
 | 
			
		||||
    './platform/status/bundle',
 | 
			
		||||
    './platform/commonUI/regions/bundle'
 | 
			
		||||
], function (Main, legacyRegistry) {
 | 
			
		||||
    return {
 | 
			
		||||
        legacyRegistry: legacyRegistry,
 | 
			
		||||
        run: function () {
 | 
			
		||||
            return new Main().run(legacyRegistry);
 | 
			
		||||
        }
 | 
			
		||||
    mct.legacyRegistry = defaultRegistry;
 | 
			
		||||
    mct.run = function (domElement) {
 | 
			
		||||
        if (!domElement) { domElement = document.body; }
 | 
			
		||||
        var appDiv = document.createElement('div');
 | 
			
		||||
        appDiv.setAttribute('ng-view', '');
 | 
			
		||||
        appDiv.className = 'user-environ';
 | 
			
		||||
        domElement.appendChild(appDiv);
 | 
			
		||||
        mct.start();
 | 
			
		||||
    };
 | 
			
		||||
    mct.on('start', function () {
 | 
			
		||||
        return new Main().run(defaultRegistry);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return mct;
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								object-provider.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								object-provider.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
 | 
			
		||||
  <title>Groot Tutorial</title>
 | 
			
		||||
  <script src="dist/main.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
    // First, we need a source of objects, so we're going to define a few
 | 
			
		||||
    // objects that we wish to expose.  The first object is a folder which
 | 
			
		||||
    // contains the other objects.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    var GROOT_ROOT = {
 | 
			
		||||
        name: 'I am groot',
 | 
			
		||||
        type: 'folder',
 | 
			
		||||
        composition: [
 | 
			
		||||
            {
 | 
			
		||||
                namespace: 'groot',
 | 
			
		||||
                identifier: 'arms'
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                namespace: 'groot',
 | 
			
		||||
                identifier: 'legs'
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                namespace: 'groot',
 | 
			
		||||
                identifier: 'torso'
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Now, we will define an object provider.  This will allow us to fetch the
 | 
			
		||||
    // GROOT_ROOT object, plus any other objects in the `groot` namespace.
 | 
			
		||||
    // For more info, see the Object API documentation.
 | 
			
		||||
 | 
			
		||||
    MCT.Objects.addProvider('groot', {
 | 
			
		||||
        // we'll only define a get function, objects from this provider will
 | 
			
		||||
        // not be mutable.
 | 
			
		||||
        get: function (key) {
 | 
			
		||||
            if (key.identifier === 'groot') {
 | 
			
		||||
                return Promise.resolve(GROOT_ROOT);
 | 
			
		||||
            }
 | 
			
		||||
            return Promise.resolve({
 | 
			
		||||
                name: 'Groot\'s ' + key.identifier
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Finally, we need to add a "ROOT."  This is an identifier for an object
 | 
			
		||||
    // that Open MCT will load at run time and show at the top-level of the
 | 
			
		||||
    // navigation tree.
 | 
			
		||||
 | 
			
		||||
    MCT.Objects.addRoot({
 | 
			
		||||
        namespace: 'groot',
 | 
			
		||||
        identifier: 'groot'
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    MCT.run();
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -39,6 +39,7 @@ define([
 | 
			
		||||
    "text!./res/templates/items/items.html",
 | 
			
		||||
    "text!./res/templates/browse/object-properties.html",
 | 
			
		||||
    "text!./res/templates/browse/inspector-region.html",
 | 
			
		||||
    "text!./res/templates/view-object.html",
 | 
			
		||||
    'legacyRegistry'
 | 
			
		||||
], function (
 | 
			
		||||
    BrowseController,
 | 
			
		||||
@@ -59,6 +60,7 @@ define([
 | 
			
		||||
    itemsTemplate,
 | 
			
		||||
    objectPropertiesTemplate,
 | 
			
		||||
    inspectorRegionTemplate,
 | 
			
		||||
    viewObjectTemplate,
 | 
			
		||||
    legacyRegistry
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
@@ -129,7 +131,7 @@ define([
 | 
			
		||||
            "representations": [
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "view-object",
 | 
			
		||||
                    "templateUrl": "templates/view-object.html"
 | 
			
		||||
                    "template": viewObjectTemplate
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "browse-object",
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,7 @@ define([
 | 
			
		||||
    "./src/directives/MCTSplitPane",
 | 
			
		||||
    "./src/directives/MCTSplitter",
 | 
			
		||||
    "./src/directives/MCTTree",
 | 
			
		||||
    "./src/filters/ReverseFilter.js",
 | 
			
		||||
    "text!./res/templates/bottombar.html",
 | 
			
		||||
    "text!./res/templates/controls/action-button.html",
 | 
			
		||||
    "text!./res/templates/controls/input-filter.html",
 | 
			
		||||
@@ -96,6 +97,7 @@ define([
 | 
			
		||||
    MCTSplitPane,
 | 
			
		||||
    MCTSplitter,
 | 
			
		||||
    MCTTree,
 | 
			
		||||
    ReverseFilter,
 | 
			
		||||
    bottombarTemplate,
 | 
			
		||||
    actionButtonTemplate,
 | 
			
		||||
    inputFilterTemplate,
 | 
			
		||||
@@ -146,7 +148,8 @@ define([
 | 
			
		||||
                    "depends": [
 | 
			
		||||
                        "stylesheets[]",
 | 
			
		||||
                        "$document",
 | 
			
		||||
                        "THEME"
 | 
			
		||||
                        "THEME",
 | 
			
		||||
                        "ASSETS_PATH"
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
@@ -158,7 +161,7 @@ define([
 | 
			
		||||
            ],
 | 
			
		||||
            "filters": [
 | 
			
		||||
                {
 | 
			
		||||
                    "implementation": "filters/ReverseFilter.js",
 | 
			
		||||
                    "implementation": ReverseFilter,
 | 
			
		||||
                    "key": "reverse"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
@@ -404,6 +407,11 @@ define([
 | 
			
		||||
                    "key": "THEME",
 | 
			
		||||
                    "value": "unspecified",
 | 
			
		||||
                    "priority": "fallback"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "ASSETS_PATH",
 | 
			
		||||
                    "value": ".",
 | 
			
		||||
                    "priority": "fallback"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "containers": [
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ define(
 | 
			
		||||
         * @param $document Angular's jqLite-wrapped document element
 | 
			
		||||
         * @param {string} activeTheme the theme in use
 | 
			
		||||
         */
 | 
			
		||||
        function StyleSheetLoader(stylesheets, $document, activeTheme) {
 | 
			
		||||
        function StyleSheetLoader(stylesheets, $document, activeTheme, assetPath) {
 | 
			
		||||
            var head = $document.find('head'),
 | 
			
		||||
                document = $document[0];
 | 
			
		||||
 | 
			
		||||
@@ -47,6 +47,7 @@ define(
 | 
			
		||||
                // Create a link element, and construct full path
 | 
			
		||||
                var link = document.createElement('link'),
 | 
			
		||||
                    path = [
 | 
			
		||||
                        assetPath,
 | 
			
		||||
                        stylesheet.bundle.path,
 | 
			
		||||
                        stylesheet.bundle.resources,
 | 
			
		||||
                        stylesheet.stylesheetUrl
 | 
			
		||||
 
 | 
			
		||||
@@ -42,11 +42,19 @@ define(
 | 
			
		||||
            function addWorker(worker) {
 | 
			
		||||
                var key = worker.key;
 | 
			
		||||
                if (!workerUrls[key]) {
 | 
			
		||||
                    workerUrls[key] = [
 | 
			
		||||
                        worker.bundle.path,
 | 
			
		||||
                        worker.bundle.sources,
 | 
			
		||||
                        worker.scriptUrl
 | 
			
		||||
                    ].join("/");
 | 
			
		||||
                    if (worker.scriptUrl) {
 | 
			
		||||
                        workerUrls[key] = [
 | 
			
		||||
                            worker.bundle.path,
 | 
			
		||||
                            worker.bundle.sources,
 | 
			
		||||
                            worker.scriptUrl
 | 
			
		||||
                        ].join("/");
 | 
			
		||||
                    } else if (worker.scriptText) {
 | 
			
		||||
                        var blob = new Blob(
 | 
			
		||||
                            [worker.scriptText],
 | 
			
		||||
                            {type: 'application/javascript'}
 | 
			
		||||
                        );
 | 
			
		||||
                        workerUrls[key] = URL.createObjectURL(blob);
 | 
			
		||||
                    }
 | 
			
		||||
                    sharedWorkers[key] = worker.shared;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,9 @@ define([
 | 
			
		||||
    "./src/controllers/TableOptionsController",
 | 
			
		||||
    '../../commonUI/regions/src/Region',
 | 
			
		||||
    '../../commonUI/browse/src/InspectorRegion',
 | 
			
		||||
    "text!./res/templates/table-options-edit.html",
 | 
			
		||||
    "text!./res/templates/rt-table.html",
 | 
			
		||||
    "text!./res/templates/historical-table.html",
 | 
			
		||||
    "legacyRegistry"
 | 
			
		||||
], function (
 | 
			
		||||
    MCTTable,
 | 
			
		||||
@@ -35,6 +38,9 @@ define([
 | 
			
		||||
    TableOptionsController,
 | 
			
		||||
    Region,
 | 
			
		||||
    InspectorRegion,
 | 
			
		||||
    tableOptionsEditTemplate,
 | 
			
		||||
    rtTableTemplate,
 | 
			
		||||
    historicalTableTemplate,
 | 
			
		||||
    legacyRegistry
 | 
			
		||||
) {
 | 
			
		||||
    /**
 | 
			
		||||
@@ -128,7 +134,7 @@ define([
 | 
			
		||||
                    "name": "Historical Table",
 | 
			
		||||
                    "key": "table",
 | 
			
		||||
                    "glyph": "\ue604",
 | 
			
		||||
                    "templateUrl": "templates/historical-table.html",
 | 
			
		||||
                    "template": historicalTableTemplate,
 | 
			
		||||
                    "needs": [
 | 
			
		||||
                        "telemetry"
 | 
			
		||||
                    ],
 | 
			
		||||
@@ -139,7 +145,7 @@ define([
 | 
			
		||||
                    "name": "Real-time Table",
 | 
			
		||||
                    "key": "rt-table",
 | 
			
		||||
                    "glyph": "\ue620",
 | 
			
		||||
                    "templateUrl": "templates/rt-table.html",
 | 
			
		||||
                    "template": rtTableTemplate,
 | 
			
		||||
                    "needs": [
 | 
			
		||||
                        "telemetry"
 | 
			
		||||
                    ],
 | 
			
		||||
@@ -157,7 +163,7 @@ define([
 | 
			
		||||
            "representations": [
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "table-options-edit",
 | 
			
		||||
                    "templateUrl": "templates/table-options-edit.html"
 | 
			
		||||
                    "template": tableOptionsEditTemplate
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "stylesheets": [
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@ define([
 | 
			
		||||
    "text!./res/templates/search-item.html",
 | 
			
		||||
    "text!./res/templates/search.html",
 | 
			
		||||
    "text!./res/templates/search-menu.html",
 | 
			
		||||
    "text!./src/services/GenericSearchWorker.js",
 | 
			
		||||
    'legacyRegistry'
 | 
			
		||||
], function (
 | 
			
		||||
    SearchController,
 | 
			
		||||
@@ -37,6 +38,7 @@ define([
 | 
			
		||||
    searchItemTemplate,
 | 
			
		||||
    searchTemplate,
 | 
			
		||||
    searchMenuTemplate,
 | 
			
		||||
    searchWorkerText,
 | 
			
		||||
    legacyRegistry
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
@@ -114,7 +116,7 @@ define([
 | 
			
		||||
            "workers": [
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "genericSearchWorker",
 | 
			
		||||
                    "scriptUrl": "services/GenericSearchWorker.js"
 | 
			
		||||
                    "scriptText": searchWorkerText
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								plugin-example.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								plugin-example.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
 | 
			
		||||
  <title>Implementing a basic plugin</title>
 | 
			
		||||
  <script src="dist/main.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
    function WebPlugin(websites) {
 | 
			
		||||
        this.websites = websites;
 | 
			
		||||
 | 
			
		||||
        var ROOTS = websites.reduce(function (rootMap, website) {
 | 
			
		||||
            rootMap[website] = {
 | 
			
		||||
                namespace: website,
 | 
			
		||||
                identifier: 'page'
 | 
			
		||||
            };
 | 
			
		||||
            return rootMap;
 | 
			
		||||
        }, {});
 | 
			
		||||
 | 
			
		||||
        function installPlugin(MCT) {
 | 
			
		||||
            Object.keys(ROOTS).forEach(function (rootUrl) {
 | 
			
		||||
                MCT.Objects.addRoot(ROOTS[rootUrl]);
 | 
			
		||||
                MCT.Objects.addProvider(rootUrl, {
 | 
			
		||||
                    get: function () {
 | 
			
		||||
                        return Promise.resolve({
 | 
			
		||||
                            type: 'example.page',
 | 
			
		||||
                            url: rootUrl,
 | 
			
		||||
                            name: rootUrl
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return installPlugin;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var myWebPlugin = WebPlugin([
 | 
			
		||||
        'http://www.wikipedia.org/',
 | 
			
		||||
        'http://nasa.github.io/openmct'
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    MCT.install(myWebPlugin);
 | 
			
		||||
 | 
			
		||||
    MCT.run();
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * 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 Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * 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.
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * 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.
 | 
			
		||||
@@ -24,10 +24,28 @@ define(function () {
 | 
			
		||||
 | 
			
		||||
    function BundleRegistry() {
 | 
			
		||||
        this.bundles = {};
 | 
			
		||||
        this.knownBundles = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BundleRegistry.prototype.register = function (path, definition) {
 | 
			
		||||
        this.bundles[path] = definition;
 | 
			
		||||
        if (this.knownBundles.hasOwnProperty(path)) {
 | 
			
		||||
            throw new Error('Cannot register bundle with duplicate path', path);
 | 
			
		||||
        }
 | 
			
		||||
        this.knownBundles[path] = definition;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    BundleRegistry.prototype.enable = function (path) {
 | 
			
		||||
        if (!this.knownBundles[path]) {
 | 
			
		||||
            throw new Error('Unknown bundle ' + path);
 | 
			
		||||
        }
 | 
			
		||||
        this.bundles[path] = this.knownBundles[path];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    BundleRegistry.prototype.disable = function (path) {
 | 
			
		||||
        if (!this.bundles[path]) {
 | 
			
		||||
            throw new Error('Tried to disable inactive bundle ' + path);
 | 
			
		||||
        }
 | 
			
		||||
        delete this.bundles[path];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    BundleRegistry.prototype.contains = function (path) {
 | 
			
		||||
@@ -42,8 +60,14 @@ define(function () {
 | 
			
		||||
        return Object.keys(this.bundles);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    BundleRegistry.prototype.remove = function (path) {
 | 
			
		||||
    BundleRegistry.prototype.remove = BundleRegistry.prototype.disable;
 | 
			
		||||
 | 
			
		||||
    BundleRegistry.prototype.delete = function (path) {
 | 
			
		||||
        if (!this.knownBundles[path]) {
 | 
			
		||||
            throw new Error('Cannot remove Unknown Bundle ' + path);
 | 
			
		||||
        }
 | 
			
		||||
        delete this.bundles[path];
 | 
			
		||||
        delete this.knownBundles[path];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return BundleRegistry;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * 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 Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * 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.
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * 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.
 | 
			
		||||
@@ -51,6 +51,7 @@ define(['./BundleRegistry'], function (BundleRegistry) {
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                testBundleDef = { someKey: "some value" };
 | 
			
		||||
                bundleRegistry.register(testPath, testBundleDef);
 | 
			
		||||
                bundleRegistry.enable(testPath);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("lists registered bundles", function () {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										275
									
								
								src/MCT.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								src/MCT.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,275 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'EventEmitter',
 | 
			
		||||
    'legacyRegistry',
 | 
			
		||||
    'uuid',
 | 
			
		||||
    './api/api',
 | 
			
		||||
    'text!./adapter/templates/edit-object-replacement.html',
 | 
			
		||||
    './selection/Selection',
 | 
			
		||||
    './api/objects/object-utils',
 | 
			
		||||
    './ui/ViewRegistry'
 | 
			
		||||
], function (
 | 
			
		||||
    EventEmitter,
 | 
			
		||||
    legacyRegistry,
 | 
			
		||||
    uuid,
 | 
			
		||||
    api,
 | 
			
		||||
    editObjectTemplate,
 | 
			
		||||
    Selection,
 | 
			
		||||
    objectUtils,
 | 
			
		||||
    ViewRegistry
 | 
			
		||||
) {
 | 
			
		||||
    /**
 | 
			
		||||
     * Open MCT is an extensible web application for building mission
 | 
			
		||||
     * control user interfaces. This module is itself an instance of
 | 
			
		||||
     * [MCT]{@link module:openmct.MCT}, which provides an interface for
 | 
			
		||||
     * configuring and executing the application.
 | 
			
		||||
     *
 | 
			
		||||
     * @exports openmct
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The Open MCT application. This may be configured by installing plugins
 | 
			
		||||
     * or registering extensions before the application is started.
 | 
			
		||||
     * @class MCT
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     * @augments {EventEmitter}
 | 
			
		||||
     */
 | 
			
		||||
    function MCT() {
 | 
			
		||||
        EventEmitter.call(this);
 | 
			
		||||
        this.legacyBundle = { extensions: {
 | 
			
		||||
            services: [
 | 
			
		||||
                {
 | 
			
		||||
                    key: "openmct",
 | 
			
		||||
                    implementation: function () {
 | 
			
		||||
                        return this;
 | 
			
		||||
                    }.bind(this)
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        } };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Tracks current selection state of the application.
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        this.selection = new Selection();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * MCT's time conductor, which may be used to synchronize view contents
 | 
			
		||||
         * for telemetry- or time-based views.
 | 
			
		||||
         * @type {module:openmct.TimeConductor}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name conductor
 | 
			
		||||
         */
 | 
			
		||||
        this.conductor = new api.TimeConductor();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An interface for interacting with the composition of domain objects.
 | 
			
		||||
         * The composition of a domain object is the list of other domain
 | 
			
		||||
         * objects it "contains" (for instance, that should be displayed
 | 
			
		||||
         * beneath it in the tree.)
 | 
			
		||||
         *
 | 
			
		||||
         * `composition` may be called as a function, in which case it acts
 | 
			
		||||
         * as [`composition.get`]{@link module:openmct.CompositionAPI#get}.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.CompositionAPI}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name composition
 | 
			
		||||
         */
 | 
			
		||||
        this.composition = new api.CompositionAPI();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Registry for views of domain objects which should appear in the
 | 
			
		||||
         * main viewing area.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.ViewRegistry}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name mainViews
 | 
			
		||||
         */
 | 
			
		||||
        this.mainViews = new ViewRegistry();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Registry for views which should appear in the Inspector area.
 | 
			
		||||
         * These views will be chosen based on selection state, so
 | 
			
		||||
         * providers should be prepared to test arbitrary objects for
 | 
			
		||||
         * viewability.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.ViewRegistry}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name inspectors
 | 
			
		||||
         */
 | 
			
		||||
        this.inspectors = new ViewRegistry();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Registry for views which should appear in Edit Properties
 | 
			
		||||
         * dialogs, and similar user interface elements used for
 | 
			
		||||
         * modifying domain objects external to its regular views.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.ViewRegistry}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name propertyEditors
 | 
			
		||||
         */
 | 
			
		||||
        this.propertyEditors = new ViewRegistry();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Registry for views which should appear in the status indicator area.
 | 
			
		||||
         * @type {module:openmct.ViewRegistry}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name indicators
 | 
			
		||||
         */
 | 
			
		||||
        this.indicators = new ViewRegistry();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Registry for views which should appear in the toolbar area while
 | 
			
		||||
         * editing.
 | 
			
		||||
         *
 | 
			
		||||
         * These views will be chosen based on selection state, so
 | 
			
		||||
         * providers should be prepared to test arbitrary objects for
 | 
			
		||||
         * viewability.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.ViewRegistry}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name toolbars
 | 
			
		||||
         */
 | 
			
		||||
        this.toolbars = new ViewRegistry();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Registry for domain object types which may exist within this
 | 
			
		||||
         * instance of Open MCT.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.TypeRegistry}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name types
 | 
			
		||||
         */
 | 
			
		||||
        this.types = new api.TypeRegistry();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Utilities for attaching common behaviors to views.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.GestureAPI}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name gestures
 | 
			
		||||
         */
 | 
			
		||||
        this.gestures = new api.GestureAPI();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An interface for interacting with domain objects and the domain
 | 
			
		||||
         * object hierarchy.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.ObjectAPI}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name objects
 | 
			
		||||
         */
 | 
			
		||||
        this.objects = new api.ObjectAPI();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An interface for retrieving and interpreting telemetry data associated
 | 
			
		||||
         * with a domain object.
 | 
			
		||||
         *
 | 
			
		||||
         * @type {module:openmct.TelemetryAPI}
 | 
			
		||||
         * @memberof module:openmct.MCT#
 | 
			
		||||
         * @name telemetry
 | 
			
		||||
         */
 | 
			
		||||
        this.telemetry = new api.TelemetryAPI();
 | 
			
		||||
 | 
			
		||||
        this.TimeConductor = this.conductor; // compatibility for prototype
 | 
			
		||||
        this.on('navigation', this.selection.clear.bind(this.selection));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MCT.prototype = Object.create(EventEmitter.prototype);
 | 
			
		||||
 | 
			
		||||
    Object.keys(api).forEach(function (k) {
 | 
			
		||||
        MCT.prototype[k] = api[k];
 | 
			
		||||
    });
 | 
			
		||||
    MCT.prototype.MCT = MCT;
 | 
			
		||||
 | 
			
		||||
    MCT.prototype.legacyExtension = function (category, extension) {
 | 
			
		||||
        this.legacyBundle.extensions[category] =
 | 
			
		||||
            this.legacyBundle.extensions[category] || [];
 | 
			
		||||
        this.legacyBundle.extensions[category].push(extension);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set path to where assets are hosted.  This should be the path to main.js.
 | 
			
		||||
     * @memberof module:openmct.MCT#
 | 
			
		||||
     * @method setAssetPath
 | 
			
		||||
     */
 | 
			
		||||
    MCT.prototype.setAssetPath = function (path) {
 | 
			
		||||
        this.legacyExtension('constants', {
 | 
			
		||||
            key: "ASSETS_PATH",
 | 
			
		||||
            value: path
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start running Open MCT. This should be called only after any plugins
 | 
			
		||||
     * have been installed.
 | 
			
		||||
     * @fires module:openmct.MCT~start
 | 
			
		||||
     * @memberof module:openmct.MCT#
 | 
			
		||||
     * @method start
 | 
			
		||||
     * @param {HTMLElement} [domElement] the DOM element in which to run
 | 
			
		||||
     *        MCT; if undefined, MCT will be run in the body of the document
 | 
			
		||||
     */
 | 
			
		||||
    MCT.prototype.start = function (domElement) {
 | 
			
		||||
        if (!domElement) {
 | 
			
		||||
            domElement = document.body;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var appDiv = document.createElement('div');
 | 
			
		||||
        appDiv.setAttribute('ng-view', '');
 | 
			
		||||
        appDiv.className = 'user-environ';
 | 
			
		||||
        domElement.appendChild(appDiv);
 | 
			
		||||
 | 
			
		||||
        this.legacyExtension('runs', {
 | 
			
		||||
            depends: ['navigationService'],
 | 
			
		||||
            implementation: function (navigationService) {
 | 
			
		||||
                navigationService
 | 
			
		||||
                    .addListener(this.emit.bind(this, 'navigation'));
 | 
			
		||||
            }.bind(this)
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        legacyRegistry.register('adapter', this.legacyBundle);
 | 
			
		||||
        legacyRegistry.enable('adapter');
 | 
			
		||||
        /**
 | 
			
		||||
         * Fired by [MCT]{@link module:openmct.MCT} when the application
 | 
			
		||||
         * is started.
 | 
			
		||||
         * @event start
 | 
			
		||||
         * @memberof module:openmct.MCT~
 | 
			
		||||
         */
 | 
			
		||||
        this.emit('start');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Install a plugin in MCT.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {Function} plugin a plugin install function which will be
 | 
			
		||||
     *     invoked with the mct instance.
 | 
			
		||||
     * @memberof module:openmct.MCT#
 | 
			
		||||
     */
 | 
			
		||||
    MCT.prototype.install = function (plugin) {
 | 
			
		||||
        plugin(this);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return MCT;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										57
									
								
								src/adapter/actions/ActionDialogDecorator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/adapter/actions/ActionDialogDecorator.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    '../../api/objects/object-utils'
 | 
			
		||||
], function (objectUtils) {
 | 
			
		||||
    function ActionDialogDecorator(mct, actionService) {
 | 
			
		||||
        this.mct = mct;
 | 
			
		||||
        this.actionService = actionService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ActionDialogDecorator.prototype.getActions = function (context) {
 | 
			
		||||
        var mct = this.mct;
 | 
			
		||||
 | 
			
		||||
        return this.actionService.getActions(context).map(function (action) {
 | 
			
		||||
            if (action.dialogService) {
 | 
			
		||||
                var domainObject = objectUtils.toNewFormat(
 | 
			
		||||
                    context.domainObject.getModel(),
 | 
			
		||||
                    objectUtils.parseKeyString(context.domainObject.getId())
 | 
			
		||||
                );
 | 
			
		||||
                var providers = mct.propertyEditors.get(domainObject);
 | 
			
		||||
 | 
			
		||||
                if (providers.length > 0) {
 | 
			
		||||
                    action.dialogService = Object.create(action.dialogService);
 | 
			
		||||
                    action.dialogService.getUserInput = function (form, value) {
 | 
			
		||||
                        return new mct.Dialog(
 | 
			
		||||
                            providers[0].view(context.domainObject),
 | 
			
		||||
                            form.title
 | 
			
		||||
                        ).show();
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return action;
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return ActionDialogDecorator;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										127
									
								
								src/adapter/bundle.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								src/adapter/bundle.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'legacyRegistry',
 | 
			
		||||
    './actions/ActionDialogDecorator',
 | 
			
		||||
    './directives/MCTView',
 | 
			
		||||
    './services/Instantiate',
 | 
			
		||||
    './capabilities/APICapabilityDecorator',
 | 
			
		||||
    './policies/AdapterCompositionPolicy',
 | 
			
		||||
    './runs/AlternateCompositionInitializer'
 | 
			
		||||
], function (
 | 
			
		||||
    legacyRegistry,
 | 
			
		||||
    ActionDialogDecorator,
 | 
			
		||||
    MCTView,
 | 
			
		||||
    Instantiate,
 | 
			
		||||
    APICapabilityDecorator,
 | 
			
		||||
    AdapterCompositionPolicy,
 | 
			
		||||
    AlternateCompositionInitializer
 | 
			
		||||
) {
 | 
			
		||||
    legacyRegistry.register('src/adapter', {
 | 
			
		||||
        "extensions": {
 | 
			
		||||
            "directives": [
 | 
			
		||||
                {
 | 
			
		||||
                    key: "mctView",
 | 
			
		||||
                    implementation: MCTView,
 | 
			
		||||
                    depends: [
 | 
			
		||||
                        "newViews[]",
 | 
			
		||||
                        "openmct"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            services: [
 | 
			
		||||
                {
 | 
			
		||||
                    key: "instantiate",
 | 
			
		||||
                    priority: "mandatory",
 | 
			
		||||
                    implementation: Instantiate,
 | 
			
		||||
                    depends: [
 | 
			
		||||
                        "capabilityService",
 | 
			
		||||
                        "identifierService",
 | 
			
		||||
                        "cacheService"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            components: [
 | 
			
		||||
                {
 | 
			
		||||
                    type: "decorator",
 | 
			
		||||
                    provides: "capabilityService",
 | 
			
		||||
                    implementation: APICapabilityDecorator,
 | 
			
		||||
                    depends: [
 | 
			
		||||
                        "$injector"
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    type: "decorator",
 | 
			
		||||
                    provides: "actionService",
 | 
			
		||||
                    implementation: ActionDialogDecorator,
 | 
			
		||||
                    depends: ["openmct"]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            policies: [
 | 
			
		||||
                {
 | 
			
		||||
                    category: "composition",
 | 
			
		||||
                    implementation: AdapterCompositionPolicy,
 | 
			
		||||
                    depends: ["openmct"]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            runs: [
 | 
			
		||||
                {
 | 
			
		||||
                    implementation: AlternateCompositionInitializer,
 | 
			
		||||
                    depends: ["openmct"]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            licenses: [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "almond",
 | 
			
		||||
                    "version": "0.3.3",
 | 
			
		||||
                    "description": "Lightweight RequireJS replacement for builds",
 | 
			
		||||
                    "author": "jQuery Foundation",
 | 
			
		||||
                    "website": "https://github.com/requirejs/almond",
 | 
			
		||||
                    "copyright": "Copyright jQuery Foundation and other contributors, https://jquery.org/",
 | 
			
		||||
                    "license": "license-mit",
 | 
			
		||||
                    "link": "https://github.com/requirejs/almond/blob/master/LICENSE"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "lodash",
 | 
			
		||||
                    "version": "3.10.1",
 | 
			
		||||
                    "description": "Utility functions",
 | 
			
		||||
                    "author": "Dojo Foundation",
 | 
			
		||||
                    "website": "https://lodash.com",
 | 
			
		||||
                    "copyright": "Copyright 2012-2015 The Dojo Foundation",
 | 
			
		||||
                    "license": "license-mit",
 | 
			
		||||
                    "link": "https://raw.githubusercontent.com/lodash/lodash/3.10.1/LICENSE"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "EventEmitter3",
 | 
			
		||||
                    "version": "1.2.0",
 | 
			
		||||
                    "description": "Event-driven programming support",
 | 
			
		||||
                    "author": "Arnout Kazemier",
 | 
			
		||||
                    "website": "https://github.com/primus/eventemitter3",
 | 
			
		||||
                    "copyright": "Copyright (c) 2014 Arnout Kazemier",
 | 
			
		||||
                    "license": "license-mit",
 | 
			
		||||
                    "link": "https://github.com/primus/eventemitter3/blob/1.2.0/LICENSE"
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										59
									
								
								src/adapter/capabilities/APICapabilityDecorator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/adapter/capabilities/APICapabilityDecorator.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    './synchronizeMutationCapability',
 | 
			
		||||
    './AlternateCompositionCapability'
 | 
			
		||||
], function (
 | 
			
		||||
    synchronizeMutationCapability,
 | 
			
		||||
    AlternateCompositionCapability
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Overrides certain capabilities to keep consistency between old API
 | 
			
		||||
     * and new API.
 | 
			
		||||
     */
 | 
			
		||||
    function APICapabilityDecorator($injector, capabilityService) {
 | 
			
		||||
        this.$injector = $injector;
 | 
			
		||||
        this.capabilityService = capabilityService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    APICapabilityDecorator.prototype.getCapabilities = function (
 | 
			
		||||
        model
 | 
			
		||||
    ) {
 | 
			
		||||
        var capabilities = this.capabilityService.getCapabilities(model);
 | 
			
		||||
        if (capabilities.mutation) {
 | 
			
		||||
            capabilities.mutation =
 | 
			
		||||
                synchronizeMutationCapability(capabilities.mutation);
 | 
			
		||||
        }
 | 
			
		||||
        if (AlternateCompositionCapability.appliesTo(model)) {
 | 
			
		||||
            capabilities.composition = function (domainObject) {
 | 
			
		||||
                return new AlternateCompositionCapability(this.$injector, domainObject);
 | 
			
		||||
            }.bind(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return capabilities;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return APICapabilityDecorator;
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										107
									
								
								src/adapter/capabilities/AlternateCompositionCapability.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/adapter/capabilities/AlternateCompositionCapability.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 Web 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 AlternateCompositionCapability. Created by vwoeltje on 11/7/14.
 | 
			
		||||
 */
 | 
			
		||||
define([
 | 
			
		||||
    '../../api/objects/object-utils'
 | 
			
		||||
], function (objectUtils) {
 | 
			
		||||
        function AlternateCompositionCapability($injector, domainObject) {
 | 
			
		||||
            this.domainObject = domainObject;
 | 
			
		||||
            this.getDependencies = function () {
 | 
			
		||||
                this.instantiate = $injector.get("instantiate");
 | 
			
		||||
                this.contextualize = $injector.get("contextualize");
 | 
			
		||||
                this.getDependencies = undefined;
 | 
			
		||||
                this.openmct = $injector.get("openmct");
 | 
			
		||||
            }.bind(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AlternateCompositionCapability.prototype.add = function (child, index) {
 | 
			
		||||
            if (typeof index !== 'undefined') {
 | 
			
		||||
                // At first glance I don't see a location in the existing
 | 
			
		||||
                // codebase where add is called with an index.  Won't support.
 | 
			
		||||
                throw new Error(
 | 
			
		||||
                    'Composition Capability does not support adding at index'
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function addChildToComposition(model) {
 | 
			
		||||
                var existingIndex = model.composition.indexOf(child.getId());
 | 
			
		||||
                if (existingIndex === -1) {
 | 
			
		||||
                    model.composition.push(child.getId());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return this.domainObject.useCapability(
 | 
			
		||||
                    'mutation',
 | 
			
		||||
                    addChildToComposition
 | 
			
		||||
                )
 | 
			
		||||
                .then(this.invoke.bind(this))
 | 
			
		||||
                .then(function (children) {
 | 
			
		||||
                    return children.filter(function (c) {
 | 
			
		||||
                        return c.getId() === child.getId();
 | 
			
		||||
                    })[0];
 | 
			
		||||
                });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        AlternateCompositionCapability.prototype.contextualizeChild = function (
 | 
			
		||||
            child
 | 
			
		||||
        ) {
 | 
			
		||||
            if (this.getDependencies) {
 | 
			
		||||
                this.getDependencies();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var keyString = objectUtils.makeKeyString(child.key);
 | 
			
		||||
            var oldModel = objectUtils.toOldFormat(child);
 | 
			
		||||
            var newDO = this.instantiate(oldModel, keyString);
 | 
			
		||||
            return this.contextualize(newDO, this.domainObject);
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        AlternateCompositionCapability.prototype.invoke = function () {
 | 
			
		||||
            var newFormatDO = objectUtils.toNewFormat(
 | 
			
		||||
                this.domainObject.getModel(),
 | 
			
		||||
                this.domainObject.getId()
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (this.getDependencies) {
 | 
			
		||||
                this.getDependencies();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var collection = this.openmct.composition.get(newFormatDO);
 | 
			
		||||
            return collection.load()
 | 
			
		||||
                .then(function (children) {
 | 
			
		||||
                    collection.destroy();
 | 
			
		||||
                    return children.map(this.contextualizeChild, this);
 | 
			
		||||
                }.bind(this));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        AlternateCompositionCapability.appliesTo = function (model) {
 | 
			
		||||
            // Will get replaced by a runs exception to properly
 | 
			
		||||
            // bind to running openmct instance
 | 
			
		||||
            return false;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return AlternateCompositionCapability;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										49
									
								
								src/adapter/capabilities/synchronizeMutationCapability.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/adapter/capabilities/synchronizeMutationCapability.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 (
 | 
			
		||||
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Wraps the mutation capability and synchronizes the mutation
 | 
			
		||||
     */
 | 
			
		||||
    function synchronizeMutationCapability(mutationConstructor) {
 | 
			
		||||
 | 
			
		||||
        return function makeCapability(domainObject) {
 | 
			
		||||
            var capability = mutationConstructor(domainObject);
 | 
			
		||||
            var oldListen = capability.listen.bind(capability);
 | 
			
		||||
            capability.listen = function (listener) {
 | 
			
		||||
                return oldListen(function (newModel) {
 | 
			
		||||
                    capability.domainObject.model =
 | 
			
		||||
                        JSON.parse(JSON.stringify(newModel));
 | 
			
		||||
                    listener(newModel);
 | 
			
		||||
                });
 | 
			
		||||
            };
 | 
			
		||||
            return capability;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return synchronizeMutationCapability;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										87
									
								
								src/adapter/directives/MCTView.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/adapter/directives/MCTView.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'angular',
 | 
			
		||||
    './Region',
 | 
			
		||||
    '../../api/objects/object-utils'
 | 
			
		||||
], function (
 | 
			
		||||
    angular,
 | 
			
		||||
    Region,
 | 
			
		||||
    objectUtils
 | 
			
		||||
) {
 | 
			
		||||
    function MCTView(newViews, PublicAPI) {
 | 
			
		||||
        var definitions = {};
 | 
			
		||||
 | 
			
		||||
        newViews.forEach(function (newView) {
 | 
			
		||||
            definitions[newView.region] = definitions[newView.region] || {};
 | 
			
		||||
            definitions[newView.region][newView.key] = newView.factory;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            restrict: 'E',
 | 
			
		||||
            link: function (scope, element, attrs) {
 | 
			
		||||
                var key, mctObject, regionId, region;
 | 
			
		||||
 | 
			
		||||
                function maybeShow() {
 | 
			
		||||
                    if (!definitions[regionId] || !definitions[regionId][key] || !mctObject) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    region.show(definitions[regionId][key].view(mctObject));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                function setKey(k) {
 | 
			
		||||
                    key = k;
 | 
			
		||||
                    maybeShow();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                function setObject(obj) {
 | 
			
		||||
                    mctObject = undefined;
 | 
			
		||||
                    PublicAPI.Objects.get(objectUtils.parseKeyString(obj.getId()))
 | 
			
		||||
                        .then(function (mobj) {
 | 
			
		||||
                            mctObject = mobj;
 | 
			
		||||
                            maybeShow();
 | 
			
		||||
                        });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                function setRegionId(r) {
 | 
			
		||||
                    regionId = r;
 | 
			
		||||
                    maybeShow();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                region = new Region(element[0]);
 | 
			
		||||
 | 
			
		||||
                scope.$watch('key', setKey);
 | 
			
		||||
                scope.$watch('region', setRegionId);
 | 
			
		||||
                scope.$watch('mctObject', setObject);
 | 
			
		||||
            },
 | 
			
		||||
            scope: {
 | 
			
		||||
                key: "=",
 | 
			
		||||
                region: "=",
 | 
			
		||||
                mctObject: "="
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return MCTView;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										45
									
								
								src/adapter/directives/Region.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/adapter/directives/Region.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 () {
 | 
			
		||||
    function Region(element) {
 | 
			
		||||
        this.activeView = undefined;
 | 
			
		||||
        this.element = element;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Region.prototype.clear = function () {
 | 
			
		||||
        if (this.activeView) {
 | 
			
		||||
            this.activeView.destroy();
 | 
			
		||||
            this.activeView = undefined;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Region.prototype.show = function (view) {
 | 
			
		||||
        this.clear();
 | 
			
		||||
        this.activeView = view;
 | 
			
		||||
        if (this.activeView) {
 | 
			
		||||
            this.activeView.show(this.element);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return Region;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										48
									
								
								src/adapter/policies/AdapterCompositionPolicy.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/adapter/policies/AdapterCompositionPolicy.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 () {
 | 
			
		||||
    function AdapterCompositionPolicy(mct) {
 | 
			
		||||
        this.mct = mct;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AdapterCompositionPolicy.prototype.allow = function (
 | 
			
		||||
        containerType,
 | 
			
		||||
        childType
 | 
			
		||||
    ) {
 | 
			
		||||
        var containerObject = containerType.getInitialModel();
 | 
			
		||||
        var childObject = childType.getInitialModel();
 | 
			
		||||
 | 
			
		||||
        containerObject.type = containerType.getKey();
 | 
			
		||||
        childObject.type = childType.getKey();
 | 
			
		||||
 | 
			
		||||
        var composition = this.mct.Composition(containerObject);
 | 
			
		||||
 | 
			
		||||
        if (composition) {
 | 
			
		||||
            return composition.canContain(childObject);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return AdapterCompositionPolicy;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										36
									
								
								src/adapter/runs/AlternateCompositionInitializer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/adapter/runs/AlternateCompositionInitializer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 Web 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([
 | 
			
		||||
    '../capabilities/AlternateCompositionCapability'
 | 
			
		||||
], function (AlternateCompositionCapability) {
 | 
			
		||||
    // Present to work around the need for openmct to be used
 | 
			
		||||
    // from AlternateCompositionCapability.appliesTo, even though it
 | 
			
		||||
    // cannot be injected.
 | 
			
		||||
    function AlternateCompositionInitializer(openmct) {
 | 
			
		||||
        AlternateCompositionCapability.appliesTo = function (model) {
 | 
			
		||||
            return !model.composition && !!openmct.composition.get(model);
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return AlternateCompositionInitializer;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										49
									
								
								src/adapter/services/Instantiate.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/adapter/services/Instantiate.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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(
 | 
			
		||||
    ['../../../platform/core/src/objects/DomainObjectImpl'],
 | 
			
		||||
    function (DomainObjectImpl) {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Overrides platform version of instantiate, passes Id with model such
 | 
			
		||||
         * that capability detection can utilize new format domain objects.
 | 
			
		||||
         */
 | 
			
		||||
        function Instantiate(
 | 
			
		||||
            capabilityService,
 | 
			
		||||
            identifierService,
 | 
			
		||||
            cacheService
 | 
			
		||||
        ) {
 | 
			
		||||
            return function (model, id) {
 | 
			
		||||
                id = id || identifierService.generate();
 | 
			
		||||
                var old_id = model.id;
 | 
			
		||||
                model.id = id;
 | 
			
		||||
                var capabilities = capabilityService.getCapabilities(model);
 | 
			
		||||
                model.id = old_id;
 | 
			
		||||
                cacheService.put(id, model);
 | 
			
		||||
                return new DomainObjectImpl(id, model, capabilities);
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Instantiate;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										46
									
								
								src/adapter/templates/edit-object-replacement.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/adapter/templates/edit-object-replacement.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
<div class="abs l-flex-col" ng-controller="EditObjectController as EditObjectController">
 | 
			
		||||
    <div mct-before-unload="EditObjectController.getUnloadWarning()"
 | 
			
		||||
         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"
 | 
			
		||||
                                class="flex-elem l-back"></mct-representation>
 | 
			
		||||
            <mct-representation key="'object-header'"
 | 
			
		||||
                                mct-object="domainObject"
 | 
			
		||||
                                class="l-flex-row flex-elem grows object-header">
 | 
			
		||||
            </mct-representation>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
 | 
			
		||||
            <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">
 | 
			
		||||
        <div class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
 | 
			
		||||
            <!-- Toolbar and Save/Cancel buttons -->
 | 
			
		||||
            <div class="l-edit-controls flex-elem l-flex-row flex-align-end">
 | 
			
		||||
                <mct-representation key="'adapted-view-TOOLBAR'"
 | 
			
		||||
                                    mct-object="domainObject"
 | 
			
		||||
                                    class="flex-elem grows">
 | 
			
		||||
                </mct-representation>
 | 
			
		||||
                <mct-representation key="'edit-action-buttons'"
 | 
			
		||||
                                    mct-object="domainObject"
 | 
			
		||||
                                    class='flex-elem conclude-editing'>
 | 
			
		||||
                </mct-representation>
 | 
			
		||||
            </div>
 | 
			
		||||
            <mct-representation key="representation.selected.key"
 | 
			
		||||
                                mct-object="representation.selected.key && domainObject"
 | 
			
		||||
                                class="abs flex-elem grows object-holder-main scroll"
 | 
			
		||||
                                toolbar="toolbar">
 | 
			
		||||
            </mct-representation>
 | 
			
		||||
        </div><!--/ l-object-wrapper-inner -->
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										202
									
								
								src/api/TimeConductor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								src/api/TimeConductor.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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(['EventEmitter'], function (EventEmitter) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The public API for setting and querying time conductor state. The
 | 
			
		||||
     * time conductor is the means by which the temporal bounds of a view
 | 
			
		||||
     * are controlled. Time-sensitive views will typically respond to
 | 
			
		||||
     * changes to bounds or other properties of the time conductor and
 | 
			
		||||
     * update the data displayed based on the time conductor state.
 | 
			
		||||
     *
 | 
			
		||||
     * The TimeConductor extends the EventEmitter class. A number of events are
 | 
			
		||||
     * fired when properties of the time conductor change, which are
 | 
			
		||||
     * documented below.
 | 
			
		||||
     * @interface
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
    function TimeConductor() {
 | 
			
		||||
        EventEmitter.call(this);
 | 
			
		||||
 | 
			
		||||
        //The Time System
 | 
			
		||||
        this.system = undefined;
 | 
			
		||||
        //The Time Of Interest
 | 
			
		||||
        this.toi = undefined;
 | 
			
		||||
 | 
			
		||||
        this.boundsVal = {
 | 
			
		||||
            start: undefined,
 | 
			
		||||
            end: undefined
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        //Default to fixed mode
 | 
			
		||||
        this.followMode = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    TimeConductor.prototype = Object.create(EventEmitter.prototype);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Validate the given bounds. This can be used for pre-validation of
 | 
			
		||||
     * bounds, for example by views validating user inputs.
 | 
			
		||||
     * @param bounds The start and end time of the conductor.
 | 
			
		||||
     * @returns {string | true} A validation error, or true if valid
 | 
			
		||||
     * @memberof module:openmct.TimeConductor#
 | 
			
		||||
     * @method validateBounds
 | 
			
		||||
     */
 | 
			
		||||
    TimeConductor.prototype.validateBounds = function (bounds) {
 | 
			
		||||
        if ((bounds.start === undefined) ||
 | 
			
		||||
            (bounds.end === undefined) ||
 | 
			
		||||
            isNaN(bounds.start) ||
 | 
			
		||||
            isNaN(bounds.end)
 | 
			
		||||
        ) {
 | 
			
		||||
            return "Start and end must be specified as integer values";
 | 
			
		||||
        } else if (bounds.start > bounds.end) {
 | 
			
		||||
            return "Specified start date exceeds end bound";
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    function throwOnError(validationResult) {
 | 
			
		||||
        if (validationResult !== true) {
 | 
			
		||||
            throw new Error(validationResult);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get or set the follow mode of the time conductor. In follow mode the
 | 
			
		||||
     * time conductor ticks, regularly updating the bounds from a timing
 | 
			
		||||
     * source appropriate to the selected time system and mode of the time
 | 
			
		||||
     * conductor.
 | 
			
		||||
     * @fires module:openmct.TimeConductor~follow
 | 
			
		||||
     * @param {boolean} followMode
 | 
			
		||||
     * @returns {boolean}
 | 
			
		||||
     * @memberof module:openmct.TimeConductor#
 | 
			
		||||
     * @method follow
 | 
			
		||||
     */
 | 
			
		||||
    TimeConductor.prototype.follow = function (followMode) {
 | 
			
		||||
        if (arguments.length > 0) {
 | 
			
		||||
            this.followMode = followMode;
 | 
			
		||||
            /**
 | 
			
		||||
             * The TimeConductor has toggled into or out of follow mode.
 | 
			
		||||
             * @event follow
 | 
			
		||||
             * @memberof module:openmct.TimeConductor~
 | 
			
		||||
             * @property {boolean} followMode true if follow mode is
 | 
			
		||||
             *           enabled, otherwise false.
 | 
			
		||||
             */
 | 
			
		||||
            this.emit('follow', this.followMode);
 | 
			
		||||
        }
 | 
			
		||||
        return this.followMode;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @typedef {Object} TimeConductorBounds
 | 
			
		||||
     * @property {number} start The start time displayed by the time conductor in ms since epoch. Epoch determined by current time system
 | 
			
		||||
     * @property {number} end The end time displayed by the time conductor in ms since epoch.
 | 
			
		||||
     * @memberof module:openmct.TimeConductor~
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get or set the start and end time of the time conductor. Basic validation
 | 
			
		||||
     * of bounds is performed.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.TimeConductorBounds~TimeConductorBounds} newBounds
 | 
			
		||||
     * @throws {Error} Validation error
 | 
			
		||||
     * @fires module:openmct.TimeConductor~bounds
 | 
			
		||||
     * @returns {module:openmct.TimeConductorBounds~TimeConductorBounds}
 | 
			
		||||
     * @memberof module:openmct.TimeConductor#
 | 
			
		||||
     * @method bounds
 | 
			
		||||
     */
 | 
			
		||||
    TimeConductor.prototype.bounds = function (newBounds) {
 | 
			
		||||
        if (arguments.length > 0) {
 | 
			
		||||
            throwOnError(this.validateBounds(newBounds));
 | 
			
		||||
            this.boundsVal = newBounds;
 | 
			
		||||
            /**
 | 
			
		||||
             * The start time, end time, or both have been updated.
 | 
			
		||||
             * @event bounds
 | 
			
		||||
             * @memberof module:openmct.TimeConductor~
 | 
			
		||||
             * @property {TimeConductorBounds} bounds
 | 
			
		||||
             */
 | 
			
		||||
            this.emit('bounds', this.boundsVal);
 | 
			
		||||
        }
 | 
			
		||||
        return this.boundsVal;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get or set the time system of the TimeConductor. Time systems determine
 | 
			
		||||
     * units, epoch, and other aspects of time representation. When changing
 | 
			
		||||
     * the time system in use, new valid bounds must also be provided.
 | 
			
		||||
     * @param {TimeSystem} newTimeSystem
 | 
			
		||||
     * @param {module:openmct.TimeConductor~TimeConductorBounds} bounds
 | 
			
		||||
     * @fires module:openmct.TimeConductor~timeSystem
 | 
			
		||||
     * @returns {TimeSystem} The currently applied time system
 | 
			
		||||
     * @memberof module:openmct.TimeConductor#
 | 
			
		||||
     * @method timeSystem
 | 
			
		||||
     */
 | 
			
		||||
    TimeConductor.prototype.timeSystem = function (newTimeSystem, bounds) {
 | 
			
		||||
        if (arguments.length >= 2) {
 | 
			
		||||
            this.system = newTimeSystem;
 | 
			
		||||
            /**
 | 
			
		||||
             * The time system used by the time
 | 
			
		||||
             * conductor has changed. A change in Time System will always be
 | 
			
		||||
             * followed by a bounds event specifying new query bounds.
 | 
			
		||||
             *
 | 
			
		||||
             * @event module:openmct.TimeConductor~timeSystem
 | 
			
		||||
             * @property {TimeSystem} The value of the currently applied
 | 
			
		||||
             * Time System
 | 
			
		||||
             * */
 | 
			
		||||
            this.emit('timeSystem', this.system);
 | 
			
		||||
            // Do something with bounds here. Try and convert between
 | 
			
		||||
            // time systems? Or just set defaults when time system changes?
 | 
			
		||||
            // eg.
 | 
			
		||||
            this.bounds(bounds);
 | 
			
		||||
        } else if (arguments.length === 1) {
 | 
			
		||||
            throw new Error('Must set bounds when changing time system');
 | 
			
		||||
        }
 | 
			
		||||
        return this.system;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get or set the Time of Interest. The Time of Interest is the temporal
 | 
			
		||||
     * focus of the current view. It can be manipulated by the user from the
 | 
			
		||||
     * time conductor or from other views.
 | 
			
		||||
     * @fires module:openmct.TimeConductor~timeOfInterest
 | 
			
		||||
     * @param newTOI
 | 
			
		||||
     * @returns {number} the current time of interest
 | 
			
		||||
     * @memberof module:openmct.TimeConductor#
 | 
			
		||||
     * @method timeOfInterest
 | 
			
		||||
     */
 | 
			
		||||
    TimeConductor.prototype.timeOfInterest = function (newTOI) {
 | 
			
		||||
        if (arguments.length > 0) {
 | 
			
		||||
            this.toi = newTOI;
 | 
			
		||||
            /**
 | 
			
		||||
             * The Time of Interest has moved.
 | 
			
		||||
             * @event timeOfInterest
 | 
			
		||||
             * @memberof module:openmct.TimeConductor~
 | 
			
		||||
             * @property {number} Current time of interest
 | 
			
		||||
             */
 | 
			
		||||
            this.emit('timeOfInterest', this.toi);
 | 
			
		||||
        }
 | 
			
		||||
        return this.toi;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return TimeConductor;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										110
									
								
								src/api/TimeConductorSpec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/api/TimeConductorSpec.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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(['./TimeConductor'], function (TimeConductor) {
 | 
			
		||||
    describe("The Time Conductor", function () {
 | 
			
		||||
        var tc,
 | 
			
		||||
            timeSystem,
 | 
			
		||||
            bounds,
 | 
			
		||||
            eventListener,
 | 
			
		||||
            toi,
 | 
			
		||||
            follow;
 | 
			
		||||
 | 
			
		||||
        beforeEach(function () {
 | 
			
		||||
            tc = new TimeConductor();
 | 
			
		||||
            timeSystem = {};
 | 
			
		||||
            bounds = {start: 0, end: 0};
 | 
			
		||||
            eventListener = jasmine.createSpy("eventListener");
 | 
			
		||||
            toi = 111;
 | 
			
		||||
            follow = true;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Supports setting and querying of time of interest and and follow mode", function () {
 | 
			
		||||
            expect(tc.timeOfInterest()).not.toBe(toi);
 | 
			
		||||
            tc.timeOfInterest(toi);
 | 
			
		||||
            expect(tc.timeOfInterest()).toBe(toi);
 | 
			
		||||
 | 
			
		||||
            expect(tc.follow()).not.toBe(follow);
 | 
			
		||||
            tc.follow(follow);
 | 
			
		||||
            expect(tc.follow()).toBe(follow);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Allows setting of valid bounds", function () {
 | 
			
		||||
            bounds = {start: 0, end: 1};
 | 
			
		||||
            expect(tc.bounds()).not.toBe(bounds);
 | 
			
		||||
            expect(tc.bounds.bind(tc, bounds)).not.toThrow();
 | 
			
		||||
            expect(tc.bounds()).toBe(bounds);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Disallows setting of invalid bounds", function () {
 | 
			
		||||
            bounds = {start: 1, end: 0};
 | 
			
		||||
            expect(tc.bounds()).not.toBe(bounds);
 | 
			
		||||
            expect(tc.bounds.bind(tc, bounds)).toThrow();
 | 
			
		||||
            expect(tc.bounds()).not.toBe(bounds);
 | 
			
		||||
 | 
			
		||||
            bounds = {start: 1};
 | 
			
		||||
            expect(tc.bounds()).not.toBe(bounds);
 | 
			
		||||
            expect(tc.bounds.bind(tc, bounds)).toThrow();
 | 
			
		||||
            expect(tc.bounds()).not.toBe(bounds);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Allows setting of time system with bounds", function () {
 | 
			
		||||
            expect(tc.timeSystem()).not.toBe(timeSystem);
 | 
			
		||||
            expect(tc.timeSystem.bind(tc, timeSystem, bounds)).not.toThrow();
 | 
			
		||||
            expect(tc.timeSystem()).toBe(timeSystem);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Disallows setting of time system without bounds", function () {
 | 
			
		||||
            expect(tc.timeSystem()).not.toBe(timeSystem);
 | 
			
		||||
            expect(tc.timeSystem.bind(tc, timeSystem)).toThrow();
 | 
			
		||||
            expect(tc.timeSystem()).not.toBe(timeSystem);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Emits an event when time system changes", function () {
 | 
			
		||||
            expect(eventListener).not.toHaveBeenCalled();
 | 
			
		||||
            tc.on("timeSystem", eventListener);
 | 
			
		||||
            tc.timeSystem(timeSystem, bounds);
 | 
			
		||||
            expect(eventListener).toHaveBeenCalledWith(timeSystem);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Emits an event when time of interest changes", function () {
 | 
			
		||||
            expect(eventListener).not.toHaveBeenCalled();
 | 
			
		||||
            tc.on("timeOfInterest", eventListener);
 | 
			
		||||
            tc.timeOfInterest(toi);
 | 
			
		||||
            expect(eventListener).toHaveBeenCalledWith(toi);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Emits an event when bounds change", function () {
 | 
			
		||||
            expect(eventListener).not.toHaveBeenCalled();
 | 
			
		||||
            tc.on("bounds", eventListener);
 | 
			
		||||
            tc.bounds(bounds);
 | 
			
		||||
            expect(eventListener).toHaveBeenCalledWith(bounds);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("Emits an event when follow mode changes", function () {
 | 
			
		||||
            expect(eventListener).not.toHaveBeenCalled();
 | 
			
		||||
            tc.on("follow", eventListener);
 | 
			
		||||
            tc.follow(follow);
 | 
			
		||||
            expect(eventListener).toHaveBeenCalledWith(follow);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										59
									
								
								src/api/Type.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/api/Type.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 () {
 | 
			
		||||
    /**
 | 
			
		||||
     * @typedef TypeDefinition
 | 
			
		||||
     * @memberof module:openmct.Type~
 | 
			
		||||
     * @property {Metadata} metadata displayable metadata about this type
 | 
			
		||||
     * @property {function (object)} [initialize] a function which initializes
 | 
			
		||||
     *           the model for new domain objects of this type
 | 
			
		||||
     * @property {boolean} [creatable] true if users should be allowed to
 | 
			
		||||
     *           create this type (default: false)
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A Type describes a kind of domain object that may appear or be
 | 
			
		||||
     * created within Open MCT.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:opemct.Type~TypeDefinition} definition
 | 
			
		||||
     * @class Type
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
    function Type(definition) {
 | 
			
		||||
        this.definition = definition;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if a domain object is an instance of this type.
 | 
			
		||||
     * @param domainObject
 | 
			
		||||
     * @returns {boolean} true if the domain object is of this type
 | 
			
		||||
     * @memberof module:openmct.Type#
 | 
			
		||||
     * @method check
 | 
			
		||||
     */
 | 
			
		||||
    Type.prototype.check = function (domainObject) {
 | 
			
		||||
        // Depends on assignment from MCT.
 | 
			
		||||
        return domainObject.type === this.key;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return Type;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										52
									
								
								src/api/api.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/api/api.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    './Type',
 | 
			
		||||
    './TimeConductor',
 | 
			
		||||
    './objects/ObjectAPI',
 | 
			
		||||
    './composition/CompositionAPI',
 | 
			
		||||
    './types/TypeRegistry',
 | 
			
		||||
    './ui/Dialog',
 | 
			
		||||
    './ui/GestureAPI',
 | 
			
		||||
    './telemetry/TelemetryAPI'
 | 
			
		||||
], function (
 | 
			
		||||
    Type,
 | 
			
		||||
    TimeConductor,
 | 
			
		||||
    ObjectAPI,
 | 
			
		||||
    CompositionAPI,
 | 
			
		||||
    TypeRegistry,
 | 
			
		||||
    Dialog,
 | 
			
		||||
    GestureAPI,
 | 
			
		||||
    TelemetryAPI
 | 
			
		||||
) {
 | 
			
		||||
    return {
 | 
			
		||||
        Type: Type,
 | 
			
		||||
        TimeConductor: TimeConductor,
 | 
			
		||||
        ObjectAPI: ObjectAPI,
 | 
			
		||||
        CompositionAPI: CompositionAPI,
 | 
			
		||||
        Dialog: Dialog,
 | 
			
		||||
        TypeRegistry: TypeRegistry,
 | 
			
		||||
        GestureAPI: GestureAPI,
 | 
			
		||||
        TelemetryAPI: TelemetryAPI
 | 
			
		||||
    };
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										136
									
								
								src/api/composition/CompositionAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/api/composition/CompositionAPI.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'lodash',
 | 
			
		||||
    'EventEmitter',
 | 
			
		||||
    './DefaultCompositionProvider',
 | 
			
		||||
    './CompositionCollection'
 | 
			
		||||
], function (
 | 
			
		||||
    _,
 | 
			
		||||
    EventEmitter,
 | 
			
		||||
    DefaultCompositionProvider,
 | 
			
		||||
    CompositionCollection
 | 
			
		||||
) {
 | 
			
		||||
    /**
 | 
			
		||||
     * An interface for interacting with the composition of domain objects.
 | 
			
		||||
     * The composition of a domain object is the list of other domain objects
 | 
			
		||||
     * it "contains" (for instance, that should be displayed beneath it
 | 
			
		||||
     * in the tree.)
 | 
			
		||||
     *
 | 
			
		||||
     * @interface CompositionAPI
 | 
			
		||||
     * @returns {module:openmct.CompositionCollection}
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
    function CompositionAPI() {
 | 
			
		||||
        this.registry = [];
 | 
			
		||||
        this.policies = [];
 | 
			
		||||
        this.addProvider(new DefaultCompositionProvider());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a composition provider.
 | 
			
		||||
     *
 | 
			
		||||
     * Plugins can add new composition providers to change the loading
 | 
			
		||||
     * behavior for certain domain objects.
 | 
			
		||||
     *
 | 
			
		||||
     * @method addProvider
 | 
			
		||||
     * @param {module:openmct.CompositionProvider} provider the provider to add
 | 
			
		||||
     * @memberof module:openmct.CompositionAPI#
 | 
			
		||||
     */
 | 
			
		||||
    CompositionAPI.prototype.addProvider = function (provider) {
 | 
			
		||||
        this.registry.unshift(provider);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieve the composition (if any) of this domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @method get
 | 
			
		||||
     * @returns {module:openmct.CompositionCollection}
 | 
			
		||||
     * @memberof module:openmct.CompositionAPI#
 | 
			
		||||
     */
 | 
			
		||||
    CompositionAPI.prototype.get = function (domainObject) {
 | 
			
		||||
        var provider = _.find(this.registry, function (p) {
 | 
			
		||||
            return p.appliesTo(domainObject);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (!provider) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new CompositionCollection(domainObject, provider);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A composition policy is a function which either allows or disallows
 | 
			
		||||
     * placing one object in another's composition.
 | 
			
		||||
     *
 | 
			
		||||
     * Open MCT's policy model requires consensus, so any one policy may
 | 
			
		||||
     * reject composition by returning false. As such, policies should
 | 
			
		||||
     * generally be written to return true in the default case.
 | 
			
		||||
     *
 | 
			
		||||
     * @callback CompositionPolicy
 | 
			
		||||
     * @memberof module:openmct.CompositionAPI~
 | 
			
		||||
     * @param {module:openmct.DomainObject} containingObject the object which
 | 
			
		||||
     *        would act as a container
 | 
			
		||||
     * @param {module:openmct.DomainObject} containedObject the object which
 | 
			
		||||
     *        would be contained
 | 
			
		||||
     * @returns {boolean} false if this composition should be disallowed
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a composition policy. Composition policies may disallow domain
 | 
			
		||||
     * objects from containing other domain objects.
 | 
			
		||||
     *
 | 
			
		||||
     * @method addPolicy
 | 
			
		||||
     * @param {module:openmct.CompositionAPI~CompositionPolicy} policy
 | 
			
		||||
     *        the policy to add
 | 
			
		||||
     * @memberof module:openmct.CompositionAPI#
 | 
			
		||||
     */
 | 
			
		||||
    CompositionAPI.prototype.addPolicy = function (policy) {
 | 
			
		||||
        this.policies.push(policy);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check whether or not a domain object is allowed to contain another
 | 
			
		||||
     * domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @private
 | 
			
		||||
     * @method checkPolicy
 | 
			
		||||
     * @param {module:openmct.DomainObject} containingObject the object which
 | 
			
		||||
     *        would act as a container
 | 
			
		||||
     * @param {module:openmct.DomainObject} containedObject the object which
 | 
			
		||||
     *        would be contained
 | 
			
		||||
     * @returns {boolean} false if this composition should be disallowed
 | 
			
		||||
 | 
			
		||||
     * @param {module:openmct.CompositionAPI~CompositionPolicy} policy
 | 
			
		||||
     *        the policy to add
 | 
			
		||||
     * @memberof module:openmct.CompositionAPI#
 | 
			
		||||
     */
 | 
			
		||||
    CompositionAPI.prototype.checkPolicy = function (container, containee) {
 | 
			
		||||
        return this.policies.every(function (policy) {
 | 
			
		||||
            return policy(container, containee);
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return CompositionAPI;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										231
									
								
								src/api/composition/CompositionCollection.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								src/api/composition/CompositionCollection.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,231 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'EventEmitter',
 | 
			
		||||
    'lodash',
 | 
			
		||||
    '../objects/object-utils'
 | 
			
		||||
], function (
 | 
			
		||||
    EventEmitter,
 | 
			
		||||
    _,
 | 
			
		||||
    objectUtils
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A CompositionCollection represents the list of domain objects contained
 | 
			
		||||
     * by another domain object. It provides methods for loading this
 | 
			
		||||
     * list asynchronously, and for modifying this list.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface CompositionCollection
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain object
 | 
			
		||||
     *        whose composition will be contained
 | 
			
		||||
     * @param {module:openmct.CompositionProvider} provider the provider
 | 
			
		||||
     *        to use to retrieve other domain objects
 | 
			
		||||
     * @param {module:openmct.CompositionAPI} api the composition API, for
 | 
			
		||||
     *        policy checks
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     * @augments EventEmitter
 | 
			
		||||
     */
 | 
			
		||||
    function CompositionCollection(domainObject, provider, api) {
 | 
			
		||||
        EventEmitter.call(this);
 | 
			
		||||
        this.domainObject = domainObject;
 | 
			
		||||
        this.provider = provider;
 | 
			
		||||
        this.api = api;
 | 
			
		||||
        if (this.provider.on) {
 | 
			
		||||
            this.provider.on(
 | 
			
		||||
                this.domainObject,
 | 
			
		||||
                'add',
 | 
			
		||||
                this.onProviderAdd,
 | 
			
		||||
                this
 | 
			
		||||
            );
 | 
			
		||||
            this.provider.on(
 | 
			
		||||
                this.domainObject,
 | 
			
		||||
                'remove',
 | 
			
		||||
                this.onProviderRemove,
 | 
			
		||||
                this
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CompositionCollection.prototype = Object.create(EventEmitter.prototype);
 | 
			
		||||
 | 
			
		||||
    CompositionCollection.prototype.onProviderAdd = function (child) {
 | 
			
		||||
        this.add(child, true);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    CompositionCollection.prototype.onProviderRemove = function (child) {
 | 
			
		||||
        this.remove(child, true);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the index of a domain object within this composition. If the
 | 
			
		||||
     * domain object is not contained here, -1 will be returned.
 | 
			
		||||
     *
 | 
			
		||||
     * A call to [load]{@link module:openmct.CompositionCollection#load}
 | 
			
		||||
     * must have resolved before using this method.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} child the domain object for which
 | 
			
		||||
     *        an index should be retrieved
 | 
			
		||||
     * @returns {number} the index of that domain object
 | 
			
		||||
     * @memberof module:openmct.CompositionCollection#
 | 
			
		||||
     * @name indexOf
 | 
			
		||||
     */
 | 
			
		||||
    CompositionCollection.prototype.indexOf = function (child) {
 | 
			
		||||
        return _.findIndex(this.loadedChildren, function (other) {
 | 
			
		||||
            return objectUtils.equals(child, other);
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the index of a domain object within this composition.
 | 
			
		||||
     *
 | 
			
		||||
     * A call to [load]{@link module:openmct.CompositionCollection#load}
 | 
			
		||||
     * must have resolved before using this method.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} child the domain object for which
 | 
			
		||||
     *        containment should be checked
 | 
			
		||||
     * @returns {boolean} true if the domain object is contained here
 | 
			
		||||
     * @memberof module:openmct.CompositionCollection#
 | 
			
		||||
     * @name contains
 | 
			
		||||
     */
 | 
			
		||||
    CompositionCollection.prototype.contains = function (child) {
 | 
			
		||||
        return this.indexOf(child) !== -1;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if a domain object can be added to this composition.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} child the domain object to add
 | 
			
		||||
     * @memberof module:openmct.CompositionCollection#
 | 
			
		||||
     * @name canContain
 | 
			
		||||
     */
 | 
			
		||||
    CompositionCollection.prototype.canContain = function (domainObject) {
 | 
			
		||||
        return this.api.checkPolicy(this.domainObject, domainObject);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a domain object to this composition.
 | 
			
		||||
     *
 | 
			
		||||
     * A call to [load]{@link module:openmct.CompositionCollection#load}
 | 
			
		||||
     * must have resolved before using this method.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} child the domain object to add
 | 
			
		||||
     * @param {boolean} skipMutate true if the underlying provider should
 | 
			
		||||
     *        not be updated
 | 
			
		||||
     * @memberof module:openmct.CompositionCollection#
 | 
			
		||||
     * @name add
 | 
			
		||||
     */
 | 
			
		||||
    CompositionCollection.prototype.add = function (child, skipMutate) {
 | 
			
		||||
        if (!this.loadedChildren) {
 | 
			
		||||
            throw new Error("Must load composition before you can add!");
 | 
			
		||||
        }
 | 
			
		||||
        if (!this.canContain(child)) {
 | 
			
		||||
            throw new Error("This object cannot contain that object.");
 | 
			
		||||
        }
 | 
			
		||||
        if (this.contains(child)) {
 | 
			
		||||
            if (skipMutate) {
 | 
			
		||||
                return; // don't add twice, don't error.
 | 
			
		||||
            }
 | 
			
		||||
            throw new Error("Unable to add child: already in composition");
 | 
			
		||||
        }
 | 
			
		||||
        this.loadedChildren.push(child);
 | 
			
		||||
        this.emit('add', child);
 | 
			
		||||
        if (!skipMutate) {
 | 
			
		||||
            // add after we have added.
 | 
			
		||||
            this.provider.add(this.domainObject, child);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Load the domain objects in this composition.
 | 
			
		||||
     *
 | 
			
		||||
     * @returns {Promise.<Array.<module:openmct.DomainObject>>} a promise for
 | 
			
		||||
     *          the domain objects in this composition
 | 
			
		||||
     * @memberof {module:openmct.CompositionCollection#}
 | 
			
		||||
     * @name load
 | 
			
		||||
     */
 | 
			
		||||
    CompositionCollection.prototype.load = function () {
 | 
			
		||||
        return this.provider.load(this.domainObject)
 | 
			
		||||
            .then(function (children) {
 | 
			
		||||
                this.loadedChildren = [];
 | 
			
		||||
                children.map(function (c) {
 | 
			
		||||
                    this.add(c, true);
 | 
			
		||||
                }, this);
 | 
			
		||||
                this.emit('load');
 | 
			
		||||
                return this.loadedChildren.slice();
 | 
			
		||||
            }.bind(this));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove a domain object from this composition.
 | 
			
		||||
     *
 | 
			
		||||
     * A call to [load]{@link module:openmct.CompositionCollection#load}
 | 
			
		||||
     * must have resolved before using this method.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} child the domain object to remove
 | 
			
		||||
     * @param {boolean} skipMutate true if the underlying provider should
 | 
			
		||||
     *        not be updated
 | 
			
		||||
     * @memberof module:openmct.CompositionCollection#
 | 
			
		||||
     * @name remove
 | 
			
		||||
     */
 | 
			
		||||
    CompositionCollection.prototype.remove = function (child, skipMutate) {
 | 
			
		||||
        if (!this.contains(child)) {
 | 
			
		||||
            if (skipMutate) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Error("Unable to remove child: not found in composition");
 | 
			
		||||
        }
 | 
			
		||||
        var index = this.indexOf(child);
 | 
			
		||||
        var removed = this.loadedChildren.splice(index, 1)[0];
 | 
			
		||||
        this.emit('remove', index, child);
 | 
			
		||||
        if (!skipMutate) {
 | 
			
		||||
            // trigger removal after we have internally removed it.
 | 
			
		||||
            this.provider.remove(this.domainObject, removed);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Stop using this composition collection. This will release any resources
 | 
			
		||||
     * associated with this collection.
 | 
			
		||||
     * @name destroy
 | 
			
		||||
     * @memberof module:openmct.CompositionCollection#
 | 
			
		||||
     */
 | 
			
		||||
    CompositionCollection.prototype.destroy = function () {
 | 
			
		||||
        if (this.provider.off) {
 | 
			
		||||
            this.provider.off(
 | 
			
		||||
                this.domainObject,
 | 
			
		||||
                'add',
 | 
			
		||||
                this.onProviderAdd,
 | 
			
		||||
                this
 | 
			
		||||
            );
 | 
			
		||||
            this.provider.off(
 | 
			
		||||
                this.domainObject,
 | 
			
		||||
                'remove',
 | 
			
		||||
                this.onProviderRemove,
 | 
			
		||||
                this
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return CompositionCollection;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										150
									
								
								src/api/composition/DefaultCompositionProvider.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								src/api/composition/DefaultCompositionProvider.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'lodash',
 | 
			
		||||
    'EventEmitter',
 | 
			
		||||
    '../objects/ObjectAPI',
 | 
			
		||||
    '../objects/object-utils'
 | 
			
		||||
], function (
 | 
			
		||||
    _,
 | 
			
		||||
    EventEmitter,
 | 
			
		||||
    ObjectAPI,
 | 
			
		||||
    objectUtils
 | 
			
		||||
) {
 | 
			
		||||
    /**
 | 
			
		||||
     * A CompositionProvider provides the underlying implementation of
 | 
			
		||||
     * composition-related behavior for certain types of domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface CompositionProvider
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     * @augments EventEmitter
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    function makeEventName(domainObject, event) {
 | 
			
		||||
        return event + ':' + objectUtils.makeKeyString(domainObject.key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function DefaultCompositionProvider() {
 | 
			
		||||
        EventEmitter.call(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DefaultCompositionProvider.prototype =
 | 
			
		||||
        Object.create(EventEmitter.prototype);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if this provider should be used to load composition for a
 | 
			
		||||
     * particular domain object.
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain object
 | 
			
		||||
     *        to check
 | 
			
		||||
     * @returns {boolean} true if this provider can provide
 | 
			
		||||
     *          composition for a given domain object
 | 
			
		||||
     * @memberof module:openmct.CompositionProvider#
 | 
			
		||||
     * @method appliesTo
 | 
			
		||||
     */
 | 
			
		||||
    DefaultCompositionProvider.prototype.appliesTo = function (domainObject) {
 | 
			
		||||
        return !!domainObject.composition;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Load any domain objects contained in the composition of this domain
 | 
			
		||||
     * object.
 | 
			
		||||
     * @param {module:openmct.DomainObjcet} domainObject the domain object
 | 
			
		||||
     *        for which to load composition
 | 
			
		||||
     * @returns {Promise.<Array.<module:openmct.DomainObject>>} a promise for
 | 
			
		||||
     *          the domain objects in this composition
 | 
			
		||||
     * @memberof module:openmct.CompositionProvider#
 | 
			
		||||
     * @method load
 | 
			
		||||
     */
 | 
			
		||||
    DefaultCompositionProvider.prototype.load = function (domainObject) {
 | 
			
		||||
        return Promise.all(domainObject.composition.map(ObjectAPI.get));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    DefaultCompositionProvider.prototype.on = function (
 | 
			
		||||
        domainObject,
 | 
			
		||||
        event,
 | 
			
		||||
        listener,
 | 
			
		||||
        context
 | 
			
		||||
    ) {
 | 
			
		||||
        // these can likely be passed through to the mutation service instead
 | 
			
		||||
        // of using an eventemitter.
 | 
			
		||||
        this.addListener(
 | 
			
		||||
            makeEventName(domainObject, event),
 | 
			
		||||
            listener,
 | 
			
		||||
            context
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    DefaultCompositionProvider.prototype.off = function (
 | 
			
		||||
        domainObject,
 | 
			
		||||
        event,
 | 
			
		||||
        listener,
 | 
			
		||||
        context
 | 
			
		||||
    ) {
 | 
			
		||||
        // these can likely be passed through to the mutation service instead
 | 
			
		||||
        // of using an eventemitter.
 | 
			
		||||
        this.removeListener(
 | 
			
		||||
            makeEventName(domainObject, event),
 | 
			
		||||
            listener,
 | 
			
		||||
            context
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove a domain object from another domain object's composition.
 | 
			
		||||
     *
 | 
			
		||||
     * This method is optional; if not present, adding to a domain object's
 | 
			
		||||
     * composition using this provider will be disallowed.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain object
 | 
			
		||||
     *        which should have its composition modified
 | 
			
		||||
     * @param {module:openmct.DomainObject} child the domain object to remove
 | 
			
		||||
     * @memberof module:openmct.CompositionProvider#
 | 
			
		||||
     * @method remove
 | 
			
		||||
     */
 | 
			
		||||
    DefaultCompositionProvider.prototype.remove = function (domainObject, child) {
 | 
			
		||||
        // TODO: this needs to be synchronized via mutation
 | 
			
		||||
        var index = domainObject.composition.indexOf(child);
 | 
			
		||||
        domainObject.composition.splice(index, 1);
 | 
			
		||||
        this.emit(makeEventName(domainObject, 'remove'), child);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a domain object to another domain object's composition.
 | 
			
		||||
     *
 | 
			
		||||
     * This method is optional; if not present, adding to a domain object's
 | 
			
		||||
     * composition using this provider will be disallowed.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain object
 | 
			
		||||
     *        which should have its composition modified
 | 
			
		||||
     * @param {module:openmct.DomainObject} child the domain object to add
 | 
			
		||||
     * @memberof module:openmct.CompositionProvider#
 | 
			
		||||
     * @method add
 | 
			
		||||
     */
 | 
			
		||||
    DefaultCompositionProvider.prototype.add = function (domainObject, child) {
 | 
			
		||||
        // TODO: this needs to be synchronized via mutation
 | 
			
		||||
        domainObject.composition.push(child.key);
 | 
			
		||||
        this.emit(makeEventName(domainObject, 'add'), child);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return DefaultCompositionProvider;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										128
									
								
								src/api/objects/LegacyObjectAPIInterceptor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/api/objects/LegacyObjectAPIInterceptor.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    './object-utils',
 | 
			
		||||
    './objectEventEmitter'
 | 
			
		||||
], function (
 | 
			
		||||
    utils,
 | 
			
		||||
    objectEventEmitter
 | 
			
		||||
) {
 | 
			
		||||
    function ObjectServiceProvider(objectService, instantiate, topic) {
 | 
			
		||||
        this.objectService = objectService;
 | 
			
		||||
        this.instantiate = instantiate;
 | 
			
		||||
 | 
			
		||||
        this.generalTopic = topic('mutation');
 | 
			
		||||
        this.bridgeEventBuses();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Bridges old and new style mutation events to provide compatibility between the two APIs
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    ObjectServiceProvider.prototype.bridgeEventBuses = function () {
 | 
			
		||||
        var removeGeneralTopicListener;
 | 
			
		||||
        var handleLegacyMutation;
 | 
			
		||||
 | 
			
		||||
        var handleMutation = function (newStyleObject) {
 | 
			
		||||
            var keyString = utils.makeKeyString(newStyleObject.key);
 | 
			
		||||
            var oldStyleObject = this.instantiate(utils.toOldFormat(newStyleObject), keyString);
 | 
			
		||||
 | 
			
		||||
            // Don't trigger self
 | 
			
		||||
            removeGeneralTopicListener();
 | 
			
		||||
 | 
			
		||||
            oldStyleObject.getCapability('mutation').mutate(function () {
 | 
			
		||||
                return utils.toOldFormat(newStyleObject);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            removeGeneralTopicListener = this.generalTopic.listen(handleLegacyMutation);
 | 
			
		||||
        }.bind(this);
 | 
			
		||||
 | 
			
		||||
        handleLegacyMutation = function (legacyObject) {
 | 
			
		||||
            var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
 | 
			
		||||
 | 
			
		||||
            //Don't trigger self
 | 
			
		||||
            objectEventEmitter.off('mutation', handleMutation);
 | 
			
		||||
            objectEventEmitter.emit(newStyleObject.key.identifier + ":*", newStyleObject);
 | 
			
		||||
            objectEventEmitter.on('mutation', handleMutation);
 | 
			
		||||
        }.bind(this);
 | 
			
		||||
 | 
			
		||||
        objectEventEmitter.on('mutation', handleMutation);
 | 
			
		||||
        removeGeneralTopicListener = this.generalTopic.listen(handleLegacyMutation);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ObjectServiceProvider.prototype.save = function (object) {
 | 
			
		||||
        var key = object.key;
 | 
			
		||||
 | 
			
		||||
        return object.getCapability('persistence')
 | 
			
		||||
                .persist()
 | 
			
		||||
                .then(function () {
 | 
			
		||||
                    return utils.toNewFormat(object, key);
 | 
			
		||||
                });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ObjectServiceProvider.prototype.delete = function (object) {
 | 
			
		||||
        // TODO!
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ObjectServiceProvider.prototype.get = function (key) {
 | 
			
		||||
        var keyString = utils.makeKeyString(key);
 | 
			
		||||
        return this.objectService.getObjects([keyString])
 | 
			
		||||
            .then(function (results) {
 | 
			
		||||
                var model = results[keyString].getModel();
 | 
			
		||||
                return utils.toNewFormat(model, key);
 | 
			
		||||
            });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // 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) {
 | 
			
		||||
        this.getObjects = function (keys) {
 | 
			
		||||
            var results = {},
 | 
			
		||||
                promises = keys.map(function (keyString) {
 | 
			
		||||
                    var key = utils.parseKeyString(keyString);
 | 
			
		||||
                    return openmct.objects.get(key)
 | 
			
		||||
                        .then(function (object) {
 | 
			
		||||
                            object = utils.toOldFormat(object);
 | 
			
		||||
                            results[keyString] = instantiate(object, keyString);
 | 
			
		||||
                        });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            return Promise.all(promises)
 | 
			
		||||
                .then(function () {
 | 
			
		||||
                    return results;
 | 
			
		||||
                });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        openmct.objects.supersecretSetFallbackProvider(
 | 
			
		||||
            new ObjectServiceProvider(objectService, instantiate, topic)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        ROOTS.forEach(function (r) {
 | 
			
		||||
            openmct.objects.addRoot(utils.parseKeyString(r.id));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return LegacyObjectAPIInterceptor;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										90
									
								
								src/api/objects/MutableObject.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/api/objects/MutableObject.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'lodash',
 | 
			
		||||
    './objectEventEmitter'
 | 
			
		||||
], function (
 | 
			
		||||
    _,
 | 
			
		||||
    objectEventEmitter
 | 
			
		||||
) {
 | 
			
		||||
    var ANY_OBJECT_EVENT = "mutation";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The MutableObject wraps a DomainObject and provides getters and
 | 
			
		||||
     * setters for
 | 
			
		||||
     * @param eventEmitter
 | 
			
		||||
     * @param object
 | 
			
		||||
     * @interface MutableObject
 | 
			
		||||
     */
 | 
			
		||||
    function MutableObject(object) {
 | 
			
		||||
        this.object = object;
 | 
			
		||||
        this.unlisteners = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function qualifiedEventName(object, eventName) {
 | 
			
		||||
        return [object.key.identifier, eventName].join(':');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MutableObject.prototype.stopListening = function () {
 | 
			
		||||
        this.unlisteners.forEach(function (unlisten) {
 | 
			
		||||
            unlisten();
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Observe changes to this domain object.
 | 
			
		||||
     * @param {string} path the property to observe
 | 
			
		||||
     * @param {Function} callback a callback to invoke when new values for
 | 
			
		||||
     *        this property are observed
 | 
			
		||||
     * @method on
 | 
			
		||||
     * @memberof module:openmct.MutableObject#
 | 
			
		||||
     */
 | 
			
		||||
    MutableObject.prototype.on = function (path, callback) {
 | 
			
		||||
        var fullPath = qualifiedEventName(this.object, path);
 | 
			
		||||
        objectEventEmitter.on(fullPath, callback);
 | 
			
		||||
        this.unlisteners.push(objectEventEmitter.off.bind(objectEventEmitter, fullPath, callback));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Modify this domain object.
 | 
			
		||||
     * @param {string} path the property to modify
 | 
			
		||||
     * @param {*} value the new value for this property
 | 
			
		||||
     * @method set
 | 
			
		||||
     * @memberof module:openmct.MutableObject#
 | 
			
		||||
     */
 | 
			
		||||
    MutableObject.prototype.set = function (path, value) {
 | 
			
		||||
 | 
			
		||||
        _.set(this.object, path, value);
 | 
			
		||||
        _.set(this.object, 'modified', Date.now());
 | 
			
		||||
 | 
			
		||||
        //Emit event specific to property
 | 
			
		||||
        objectEventEmitter.emit(qualifiedEventName(this.object, path), value);
 | 
			
		||||
        //Emit wildcare event
 | 
			
		||||
        objectEventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
 | 
			
		||||
 | 
			
		||||
        //Emit a general "any object" event
 | 
			
		||||
        objectEventEmitter.emit(ANY_OBJECT_EVENT, this.object);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return MutableObject;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										234
									
								
								src/api/objects/ObjectAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								src/api/objects/ObjectAPI.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,234 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'lodash',
 | 
			
		||||
    './object-utils',
 | 
			
		||||
    './MutableObject'
 | 
			
		||||
], function (
 | 
			
		||||
    _,
 | 
			
		||||
    utils,
 | 
			
		||||
    MutableObject
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Utilities for loading, saving, and manipulating domain objects.
 | 
			
		||||
     * @interface ObjectAPI
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     * @implements {module:openmct.ObjectProvider}
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    function ObjectAPI() {
 | 
			
		||||
        this.providers = {};
 | 
			
		||||
        this.rootRegistry = [];
 | 
			
		||||
        this.rootProvider = {
 | 
			
		||||
            'get': function () {
 | 
			
		||||
                return Promise.resolve({
 | 
			
		||||
                    name: 'The root object',
 | 
			
		||||
                    type: 'root',
 | 
			
		||||
                    composition: this.rootRegistry
 | 
			
		||||
                });
 | 
			
		||||
            }.bind(this)
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ObjectAPI.prototype.supersecretSetFallbackProvider = function (p) {
 | 
			
		||||
        this.fallbackProvider = p;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Retrieve the provider for a given key.
 | 
			
		||||
    ObjectAPI.prototype.getProvider = function (key) {
 | 
			
		||||
        if (key.identifier === 'ROOT') {
 | 
			
		||||
            return this.rootProvider;
 | 
			
		||||
        }
 | 
			
		||||
        return this.providers[key.namespace] || this.fallbackProvider;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register a new object provider for a particular namespace.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {string} namespace the namespace for which to provide objects
 | 
			
		||||
     * @param {module:openmct.ObjectProvider} provider the provider which
 | 
			
		||||
     *        will handle loading domain objects from this namespace
 | 
			
		||||
     * @memberof {module:openmct.ObjectAPI#}
 | 
			
		||||
     * @name addProvider
 | 
			
		||||
     */
 | 
			
		||||
    ObjectAPI.prototype.addProvider = function (namespace, provider) {
 | 
			
		||||
        this.providers[namespace] = provider;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Provides the ability to read, write, and delete domain objects.
 | 
			
		||||
     *
 | 
			
		||||
     * When registering a new object provider, all methods on this interface
 | 
			
		||||
     * are optional.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface ObjectProvider
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Save this domain object in its current state.
 | 
			
		||||
     *
 | 
			
		||||
     * @method save
 | 
			
		||||
     * @memberof module:openmct.ObjectProvider#
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain object to
 | 
			
		||||
     *        save
 | 
			
		||||
     * @returns {Promise} a promise which will resolve when the domain object
 | 
			
		||||
     *          has been saved, or be rejected if it cannot be saved
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete this domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @method delete
 | 
			
		||||
     * @memberof module:openmct.ObjectProvider#
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain object to
 | 
			
		||||
     *        delete
 | 
			
		||||
     * @returns {Promise} a promise which will resolve when the domain object
 | 
			
		||||
     *          has been deleted, or be rejected if it cannot be deleted
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @method get
 | 
			
		||||
     * @memberof module:openmct.ObjectProvider#
 | 
			
		||||
     * @param {string} key the key for the domain object to load
 | 
			
		||||
     * @returns {Promise} a promise which will resolve when the domain object
 | 
			
		||||
     *          has been saved, or be rejected if it cannot be saved
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    [
 | 
			
		||||
        'save',
 | 
			
		||||
        'delete',
 | 
			
		||||
        'get'
 | 
			
		||||
    ].forEach(function (method) {
 | 
			
		||||
        ObjectAPI.prototype[method] = function () {
 | 
			
		||||
            var key = arguments[0],
 | 
			
		||||
                provider = this.getProvider(key);
 | 
			
		||||
 | 
			
		||||
            if (!provider) {
 | 
			
		||||
                throw new Error('No Provider Matched');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!provider[method]) {
 | 
			
		||||
                throw new Error('Provider does not support [' + method + '].');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return provider[method].apply(provider, arguments);
 | 
			
		||||
        };
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a root-level object.
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the root-level object
 | 
			
		||||
     *        to add.
 | 
			
		||||
     * @method addRoot
 | 
			
		||||
     * @memberof module:openmct.ObjectAPI#
 | 
			
		||||
     */
 | 
			
		||||
    ObjectAPI.prototype.addRoot = function (key) {
 | 
			
		||||
        this.rootRegistry.unshift(key);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove a root-level object.
 | 
			
		||||
     * @param {module:openmct.ObjectAPI~Identifier} id the identifier of the
 | 
			
		||||
     *        root-level object to remove.
 | 
			
		||||
     * @method removeRoot
 | 
			
		||||
     * @memberof module:openmct.ObjectAPI#
 | 
			
		||||
     */
 | 
			
		||||
    ObjectAPI.prototype.removeRoot = function (key) {
 | 
			
		||||
        this.rootRegistry = this.rootRegistry.filter(function (k) {
 | 
			
		||||
            return (
 | 
			
		||||
                k.identifier !== key.identifier ||
 | 
			
		||||
                k.namespace !== key.namespace
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Modify a domain object.
 | 
			
		||||
     * @param {module:openmct.DomainObject} object the object to mutate
 | 
			
		||||
     * @param {string} path the property to modify
 | 
			
		||||
     * @param {*} value the new value for this property
 | 
			
		||||
     * @method mutate
 | 
			
		||||
     * @memberof module:openmct.ObjectAPI#
 | 
			
		||||
     */
 | 
			
		||||
    ObjectAPI.prototype.mutate = function (domainObject, path, value) {
 | 
			
		||||
        return new MutableObject(domainObject).set(path, value);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Observe changes to a domain object.
 | 
			
		||||
     * @param {module:openmct.DomainObject} object the object to observe
 | 
			
		||||
     * @param {string} path the property to observe
 | 
			
		||||
     * @param {Function} callback a callback to invoke when new values for
 | 
			
		||||
     *        this property are observed
 | 
			
		||||
     * @method observe
 | 
			
		||||
     * @memberof module:openmct.ObjectAPI#
 | 
			
		||||
     */
 | 
			
		||||
    ObjectAPI.prototype.observe = function (domainObject, path, callback) {
 | 
			
		||||
        var mutableObject = new MutableObject(domainObject);
 | 
			
		||||
        mutableObject.on(path, callback);
 | 
			
		||||
        return mutableObject.stopListening.bind(mutableObject);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Uniquely identifies a domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @typedef Identifier
 | 
			
		||||
     * @memberof module:openmct.ObjectAPI~
 | 
			
		||||
     * @property {string} namespace the namespace to/from which this domain
 | 
			
		||||
     *           object should be loaded/stored.
 | 
			
		||||
     * @property {string} key a unique identifier for the domain object
 | 
			
		||||
     *           within that namespace
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A domain object is an entity of relevance to a user's workflow, that
 | 
			
		||||
     * should appear as a distinct and meaningful object within the user
 | 
			
		||||
     * interface. Examples of domain objects are folders, telemetry sensors,
 | 
			
		||||
     * and so forth.
 | 
			
		||||
     *
 | 
			
		||||
     * A few common properties are defined for domain objects. Beyond these,
 | 
			
		||||
     * individual types of domain objects may add more as they see fit.
 | 
			
		||||
     *
 | 
			
		||||
     * @property {module:openmct.ObjectAPI~Identifier} identifier a key/namespace pair which
 | 
			
		||||
     *           uniquely identifies this domain object
 | 
			
		||||
     * @property {string} type the type of domain object
 | 
			
		||||
     * @property {string} name the human-readable name for this domain object
 | 
			
		||||
     * @property {string} [creator] the user name of the creator of this domain
 | 
			
		||||
     *           object
 | 
			
		||||
     * @property {number} [modified] the time, in milliseconds since the UNIX
 | 
			
		||||
     *           epoch, at which this domain object was last modified
 | 
			
		||||
     * @property {module:openmct.ObjectAPI~Identifier[]} [composition] if
 | 
			
		||||
     *           present, this will be used by the default composition provider
 | 
			
		||||
     *           to load domain objects
 | 
			
		||||
     * @typedef DomainObject
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    return ObjectAPI;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										51
									
								
								src/api/objects/bundle.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/api/objects/bundle.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
define([
 | 
			
		||||
    './LegacyObjectAPIInterceptor',
 | 
			
		||||
    'legacyRegistry'
 | 
			
		||||
], function (
 | 
			
		||||
    LegacyObjectAPIInterceptor,
 | 
			
		||||
    legacyRegistry
 | 
			
		||||
) {
 | 
			
		||||
    legacyRegistry.register('src/api/objects', {
 | 
			
		||||
        name: 'Object API',
 | 
			
		||||
        description: 'The public Objects API',
 | 
			
		||||
        extensions: {
 | 
			
		||||
            components: [
 | 
			
		||||
                {
 | 
			
		||||
                    provides: "objectService",
 | 
			
		||||
                    type: "decorator",
 | 
			
		||||
                    priority: "mandatory",
 | 
			
		||||
                    implementation: LegacyObjectAPIInterceptor,
 | 
			
		||||
                    depends: [
 | 
			
		||||
                        "openmct",
 | 
			
		||||
                        "roots[]",
 | 
			
		||||
                        "instantiate",
 | 
			
		||||
                        "topic"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										109
									
								
								src/api/objects/object-utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/api/objects/object-utils.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 (
 | 
			
		||||
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    // take a key string and turn it into a key object
 | 
			
		||||
    // 'scratch:root' ==> {namespace: 'scratch', identifier: 'root'}
 | 
			
		||||
    var parseKeyString = function (key) {
 | 
			
		||||
        if (typeof key === 'object') {
 | 
			
		||||
            return key;
 | 
			
		||||
        }
 | 
			
		||||
        var namespace = '',
 | 
			
		||||
            identifier = key;
 | 
			
		||||
        for (var i = 0, escaped = false; i < key.length; i++) {
 | 
			
		||||
            if (escaped) {
 | 
			
		||||
                escaped = false;
 | 
			
		||||
                namespace += key[i];
 | 
			
		||||
            } else {
 | 
			
		||||
                if (key[i] === "\\") {
 | 
			
		||||
                    escaped = true;
 | 
			
		||||
                } else if (key[i] === ":") {
 | 
			
		||||
                    // namespace = key.slice(0, i);
 | 
			
		||||
                    identifier = key.slice(i + 1);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                namespace += key[i];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (key === namespace) {
 | 
			
		||||
            namespace = '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            namespace: namespace,
 | 
			
		||||
            identifier: identifier
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // take a key and turn it into a key string
 | 
			
		||||
    // {namespace: 'scratch', identifier: 'root'} ==> 'scratch:root'
 | 
			
		||||
    var makeKeyString = function (key) {
 | 
			
		||||
        if (typeof key === 'string') {
 | 
			
		||||
            return key;
 | 
			
		||||
        }
 | 
			
		||||
        if (!key.namespace) {
 | 
			
		||||
            return key.identifier;
 | 
			
		||||
        }
 | 
			
		||||
        return [
 | 
			
		||||
            key.namespace.replace(':', '\\:'),
 | 
			
		||||
            key.identifier.replace(':', '\\:')
 | 
			
		||||
        ].join(':');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Converts composition to use key strings instead of keys
 | 
			
		||||
    var toOldFormat = function (model) {
 | 
			
		||||
        model = JSON.parse(JSON.stringify(model));
 | 
			
		||||
        delete model.key;
 | 
			
		||||
        if (model.composition) {
 | 
			
		||||
            model.composition = model.composition.map(makeKeyString);
 | 
			
		||||
        }
 | 
			
		||||
        return model;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // converts composition to use keys instead of key strings
 | 
			
		||||
    var toNewFormat = function (model, key) {
 | 
			
		||||
        model = JSON.parse(JSON.stringify(model));
 | 
			
		||||
        model.key = key;
 | 
			
		||||
        if (model.composition) {
 | 
			
		||||
            model.composition = model.composition.map(parseKeyString);
 | 
			
		||||
        }
 | 
			
		||||
        return model;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var equals = function (a, b) {
 | 
			
		||||
        return makeKeyString(a.key) === makeKeyString(b.key);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        toOldFormat: toOldFormat,
 | 
			
		||||
        toNewFormat: toNewFormat,
 | 
			
		||||
        makeKeyString: makeKeyString,
 | 
			
		||||
        parseKeyString: parseKeyString,
 | 
			
		||||
        equals: equals
 | 
			
		||||
    };
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										32
									
								
								src/api/objects/objectEventEmitter.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/api/objects/objectEventEmitter.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    "EventEmitter"
 | 
			
		||||
], function (
 | 
			
		||||
    EventEmitter
 | 
			
		||||
) {
 | 
			
		||||
    /**
 | 
			
		||||
     * Provides a singleton event bus for sharing between objects.
 | 
			
		||||
     */
 | 
			
		||||
    return new EventEmitter();
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										319
									
								
								src/api/telemetry/TelemetryAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								src/api/telemetry/TelemetryAPI.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,319 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'lodash',
 | 
			
		||||
    'EventEmitter'
 | 
			
		||||
], function (
 | 
			
		||||
    _,
 | 
			
		||||
    EventEmitter
 | 
			
		||||
) {
 | 
			
		||||
    /**
 | 
			
		||||
     * A LimitEvaluator may be used to detect when telemetry values
 | 
			
		||||
     * have exceeded nominal conditions.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface LimitEvaluator
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check for any limit violations associated with a telemetry datum.
 | 
			
		||||
     * @method evaluate
 | 
			
		||||
     * @param {*} datum the telemetry datum to evaluate
 | 
			
		||||
     * @param {TelemetryProperty} the property to check for limit violations
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~LimitEvaluator
 | 
			
		||||
     * @returns {module:openmct.TelemetryAPI~LimitViolation} metadata about
 | 
			
		||||
     *          the limit violation, or undefined if a value is within limits
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A violation of limits defined for a telemetry property.
 | 
			
		||||
     * @typedef LimitViolation
 | 
			
		||||
     * @memberof {module:openmct.TelemetryAPI~}
 | 
			
		||||
     * @property {string} cssclass the class (or space-separated classes) to
 | 
			
		||||
     *           apply to display elements for values which violate this limit
 | 
			
		||||
     * @property {string} name the human-readable name for the limit violation
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A TelemetryFormatter converts telemetry values for purposes of
 | 
			
		||||
     * display as text.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface TelemetryFormatter
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieve the 'key' from the datum and format it accordingly to
 | 
			
		||||
     * telemetry metadata in domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @method format
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~TelemetryFormatter#
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // format map is a placeholder until we figure out format service.
 | 
			
		||||
    var FORMAT_MAP = {
 | 
			
		||||
        generic: function (range) {
 | 
			
		||||
            return function (datum) {
 | 
			
		||||
                return datum[range.key];
 | 
			
		||||
            };
 | 
			
		||||
        },
 | 
			
		||||
        enum: function (range) {
 | 
			
		||||
            var enumMap = _.indexBy(range.enumerations, 'value');
 | 
			
		||||
            return function (datum) {
 | 
			
		||||
                try {
 | 
			
		||||
                    return enumMap[datum[range.valueKey]].text;
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    return datum[range.valueKey];
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    FORMAT_MAP.number =
 | 
			
		||||
        FORMAT_MAP.float =
 | 
			
		||||
        FORMAT_MAP.integer =
 | 
			
		||||
        FORMAT_MAP.ascii =
 | 
			
		||||
        FORMAT_MAP.generic;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Describes a property which would be found in a datum of telemetry
 | 
			
		||||
     * associated with a particular domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @typedef TelemetryProperty
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~
 | 
			
		||||
     * @property {string} key the name of the property in the datum which
 | 
			
		||||
     *           contains this telemetry value
 | 
			
		||||
     * @property {string} name the human-readable name for this property
 | 
			
		||||
     * @property {string} [units] the units associated with this property
 | 
			
		||||
     * @property {boolean} [temporal] true if this property is a timestamp, or
 | 
			
		||||
     *           may be otherwise used to order telemetry in a time-like
 | 
			
		||||
     *           fashion; default is false
 | 
			
		||||
     * @property {boolean} [numeric] true if the values for this property
 | 
			
		||||
     *           can be interpreted plainly as numbers; default is true
 | 
			
		||||
     * @property {boolean} [enumerated] true if this property may have only
 | 
			
		||||
     *           certain specific values; default is false
 | 
			
		||||
     * @property {string} [values] for enumerated states, an ordered list
 | 
			
		||||
     *           of possible values
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Describes and bounds requests for telemetry data.
 | 
			
		||||
     *
 | 
			
		||||
     * @typedef TelemetryRequest
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~
 | 
			
		||||
     * @property {string} sort the key of the property to sort by. This may
 | 
			
		||||
     *           be prefixed with a "+" or a "-" sign to sort in ascending
 | 
			
		||||
     *           or descending order respectively. If no prefix is present,
 | 
			
		||||
     *           ascending order will be used.
 | 
			
		||||
     * @property {*} start the lower bound for values of the sorting property
 | 
			
		||||
     * @property {*} end the upper bound for values of the sorting property
 | 
			
		||||
     * @property {string[]} strategies symbolic identifiers for strategies
 | 
			
		||||
     *           (such as `minmax`) which may be recognized by providers;
 | 
			
		||||
     *           these will be tried in order until an appropriate provider
 | 
			
		||||
     *           is found
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Provides telemetry data. To connect to new data sources, new
 | 
			
		||||
     * TelemetryProvider implementations should be
 | 
			
		||||
     * [registered]{@link module:openmct.TelemetryAPI#addProvider}.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface TelemetryProvider
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An interface for retrieving telemetry data associated with a domain
 | 
			
		||||
     * object.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface TelemetryAPI
 | 
			
		||||
     * @augments module:openmct.TelemetryAPI~TelemetryProvider
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
    function TelemetryAPI() {
 | 
			
		||||
        this.providersByStrategy = {};
 | 
			
		||||
        this.defaultProviders = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if this provider can supply telemetry data associated with
 | 
			
		||||
     * this domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @method canProvideTelemetry
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the object for
 | 
			
		||||
     *        which telemetry would be provided
 | 
			
		||||
     * @returns {boolean} true if telemetry can be provided
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~TelemetryProvider#
 | 
			
		||||
     */
 | 
			
		||||
    TelemetryAPI.prototype.canProvideTelemetry = function (domainObject) {
 | 
			
		||||
        return this.defaultProviders.some(function (provider) {
 | 
			
		||||
            return provider.canProvideTelemetry(domainObject);
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register a telemetry provider with the telemetry service. This
 | 
			
		||||
     * allows you to connect alternative telemetry sources.
 | 
			
		||||
     * @method addProvider
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI#
 | 
			
		||||
     * @param {module:openmct.TelemetryAPI~TelemetryProvider} provider the new
 | 
			
		||||
     *        telemetry provider
 | 
			
		||||
     * @param {string} [strategy] the request strategy supported by
 | 
			
		||||
     *        this provider. If omitted, this will be used as a
 | 
			
		||||
     *        default provider (when no strategy is requested or no
 | 
			
		||||
     *        matching strategy is found.)
 | 
			
		||||
     */
 | 
			
		||||
    TelemetryAPI.prototype.addProvider = function (provider, strategy) {
 | 
			
		||||
        if (!strategy) {
 | 
			
		||||
            this.defaultProviders.push(provider);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.providersByStrategy[strategy] =
 | 
			
		||||
                this.providersByStrategy[strategy] || [];
 | 
			
		||||
            this.providersByStrategy[strategy].push(provider);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    TelemetryAPI.prototype.findProvider = function (domainObject, strategy) {
 | 
			
		||||
        function supportsDomainObject(provider) {
 | 
			
		||||
            return provider.canProvideTelemetry(domainObject);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (strategy) {
 | 
			
		||||
            var eligibleProviders =
 | 
			
		||||
                (this.providersByStrategy[strategy] || [])
 | 
			
		||||
                    .filter(supportsDomainObject);
 | 
			
		||||
            if (eligibleProviders.length > 0) {
 | 
			
		||||
                return eligibleProviders[0];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return this.defaultProviders.filter(supportsDomainObject)[0];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Request historical telemetry for a domain object.
 | 
			
		||||
     * The `options` argument allows you to specify filters
 | 
			
		||||
     * (start, end, etc.), sort order, and strategies for retrieving
 | 
			
		||||
     * telemetry (aggregation, latest available, etc.).
 | 
			
		||||
     *
 | 
			
		||||
     * @method request
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~TelemetryProvider#
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the object
 | 
			
		||||
     *        which has associated telemetry
 | 
			
		||||
     * @param {module:openmct.TelemetryAPI~TelemetryRequest} options
 | 
			
		||||
     *        options for this historical request
 | 
			
		||||
     * @returns {Promise.<object[]>} a promise for an array of
 | 
			
		||||
     *          telemetry data
 | 
			
		||||
     */
 | 
			
		||||
    TelemetryAPI.prototype.request = function (domainObject, options) {
 | 
			
		||||
        var provider = this.findProvider(domainObject, options.strategy);
 | 
			
		||||
        return provider ?
 | 
			
		||||
            provider.request(domainObject, options) :
 | 
			
		||||
            Promise.reject([]);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscribe to realtime telemetry for a specific domain object.
 | 
			
		||||
     * The callback will be called whenever data is received from a
 | 
			
		||||
     * realtime provider.
 | 
			
		||||
     *
 | 
			
		||||
     * @method subscribe
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~TelemetryProvider#
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the object
 | 
			
		||||
     *        which has associated telemetry
 | 
			
		||||
     * @param {Function} callback the callback to invoke with new data, as
 | 
			
		||||
     *        it becomes available
 | 
			
		||||
     * @param {module:openmct.TelemetryAPI~TelemetryRequest} options
 | 
			
		||||
     *        options for this request
 | 
			
		||||
     * @returns {Function} a function which may be called to terminate
 | 
			
		||||
     *          the subscription
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a list of all telemetry properties defined for this
 | 
			
		||||
     * domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain
 | 
			
		||||
     *        object for which to request telemetry
 | 
			
		||||
     * @returns {module:openmct.TelemetryAPI~TelemetryProperty[]}
 | 
			
		||||
     *          telemetry metadata
 | 
			
		||||
     * @method properties
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~TelemetryProvider#
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Telemetry formatters help you format telemetry values for
 | 
			
		||||
     * display. Under the covers, they use telemetry metadata to
 | 
			
		||||
     * interpret your telemetry data, and then they use the format API
 | 
			
		||||
     * to format that data for display.
 | 
			
		||||
     *
 | 
			
		||||
     * This method is optional.
 | 
			
		||||
     * If a provider does not implement this method, it is presumed
 | 
			
		||||
     * that all telemetry associated with this domain object can
 | 
			
		||||
     * be formatted correctly by string coercion.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain
 | 
			
		||||
     *        object for which to format telemetry
 | 
			
		||||
     * @returns {module:openmct.TelemetryAPI~TelemetryFormatter}
 | 
			
		||||
     * @method formatter
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~TelemetryProvider#
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a limit evaluator for this domain object.
 | 
			
		||||
     * Limit Evaluators help you evaluate limit and alarm status of individual telemetry datums for display purposes without having to interact directly with the Limit API.
 | 
			
		||||
     *
 | 
			
		||||
     * This method is optional.
 | 
			
		||||
     * If a provider does not implement this method, it is presumed
 | 
			
		||||
     * that no limits are defined for this domain object's telemetry.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain
 | 
			
		||||
     *        object for which to evaluate limits
 | 
			
		||||
     * @returns {module:openmct.TelemetryAPI~LimitEvaluator}
 | 
			
		||||
     * @method limitEvaluator
 | 
			
		||||
     * @memberof module:openmct.TelemetryAPI~TelemetryProvider#
 | 
			
		||||
     */
 | 
			
		||||
    _.forEach({
 | 
			
		||||
        subscribe: undefined,
 | 
			
		||||
        properties: [],
 | 
			
		||||
        formatter: undefined,
 | 
			
		||||
        limitEvaluator: undefined
 | 
			
		||||
    }, function (defaultValue, method) {
 | 
			
		||||
        TelemetryAPI.prototype[method] = function (domainObject) {
 | 
			
		||||
            var provider = this.findProvider(domainObject);
 | 
			
		||||
            return provider ?
 | 
			
		||||
                provider[method].apply(provider, arguments) :
 | 
			
		||||
                defaultValue;
 | 
			
		||||
        };
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return TelemetryAPI;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										45
									
								
								src/api/telemetry/bundle.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/api/telemetry/bundle.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    './TelemetryAPI',
 | 
			
		||||
    'legacyRegistry'
 | 
			
		||||
], function (
 | 
			
		||||
    TelemetryAPI,
 | 
			
		||||
    legacyRegistry
 | 
			
		||||
) {
 | 
			
		||||
    legacyRegistry.register('api/telemetry-api', {
 | 
			
		||||
        name: 'Telemetry API',
 | 
			
		||||
        description: 'The public Telemetry API',
 | 
			
		||||
        extensions: {
 | 
			
		||||
            runs: [
 | 
			
		||||
                {
 | 
			
		||||
                    key: "TelemetryAPI",
 | 
			
		||||
                    implementation: TelemetryAPI,
 | 
			
		||||
                    depends: [
 | 
			
		||||
                        'formatService'
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										51
									
								
								src/api/types/TypeRegistry.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/api/types/TypeRegistry.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 () {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A TypeRegistry maintains the definitions for different types
 | 
			
		||||
     * that domain objects may have.
 | 
			
		||||
     * @interface TypeRegistry
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
    function TypeRegistry() {
 | 
			
		||||
        this.types = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register a new type of view.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {string} typeKey a string identifier for this type
 | 
			
		||||
     * @param {module:openmct.Type} type the type to add
 | 
			
		||||
     * @method addProvider
 | 
			
		||||
     * @memberof module:openmct.TypeRegistry#
 | 
			
		||||
     */
 | 
			
		||||
    TypeRegistry.prototype.addType = function (typeKey, type) {
 | 
			
		||||
        this.types[typeKey] = type;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return TypeRegistry;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										107
									
								
								src/api/ui/Dialog.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/api/ui/Dialog.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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(['text!./dialog.html', 'zepto'], function (dialogTemplate, $) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A dialog may be displayed to show blocking content to users.
 | 
			
		||||
     * @param {module:openmct.View} view the view to show in the dialog
 | 
			
		||||
     * @param {string} [title] the title for this dialog
 | 
			
		||||
     * @constructor
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
    function Dialog(view, title) {
 | 
			
		||||
        this.view = view;
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.showing = false;
 | 
			
		||||
        this.enabledState = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Display this dialog.
 | 
			
		||||
     * @returns {Promise} a promise that will be resolved if the user
 | 
			
		||||
     *          chooses "OK", an rejected if the user chooses "cancel"
 | 
			
		||||
     * @method show
 | 
			
		||||
     * @memberof module:openmct.Dialog#
 | 
			
		||||
     */
 | 
			
		||||
    Dialog.prototype.show = function () {
 | 
			
		||||
        if (this.showing) {
 | 
			
		||||
            throw new Error("Dialog already showing.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var $body = $('body');
 | 
			
		||||
        var $dialog = $(dialogTemplate);
 | 
			
		||||
        var $contents = $dialog.find('.contents .editor');
 | 
			
		||||
        var $close = $dialog.find('.close');
 | 
			
		||||
 | 
			
		||||
        var $ok = $dialog.find('.ok');
 | 
			
		||||
        var $cancel = $dialog.find('.cancel');
 | 
			
		||||
 | 
			
		||||
        if (this.title) {
 | 
			
		||||
            $dialog.find('.title').text(this.title);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $body.append($dialog);
 | 
			
		||||
        this.view.show($contents[0]);
 | 
			
		||||
        this.$dialog = $dialog;
 | 
			
		||||
        this.$ok = $ok;
 | 
			
		||||
        this.showing = true;
 | 
			
		||||
 | 
			
		||||
        [$ok, $cancel, $close].forEach(function ($button) {
 | 
			
		||||
            $button.on('click', this.hide.bind(this));
 | 
			
		||||
        }.bind(this));
 | 
			
		||||
 | 
			
		||||
        return new Promise(function (resolve, reject) {
 | 
			
		||||
            $ok.on('click', resolve);
 | 
			
		||||
            $cancel.on('click', reject);
 | 
			
		||||
            $close.on('click', reject);
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Dialog.prototype.hide = function () {
 | 
			
		||||
        if (!this.showing) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        this.$dialog.remove();
 | 
			
		||||
        this.view.destroy();
 | 
			
		||||
        this.showing = false;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get or set the "enabled" state of the OK button for this dialog.
 | 
			
		||||
     * @param {boolean} [state] true to enable, false to disable
 | 
			
		||||
     * @returns {boolean} true if enabled, false if disabled
 | 
			
		||||
     * @method enabled
 | 
			
		||||
     * @memberof module:openmct.Dialog#
 | 
			
		||||
     */
 | 
			
		||||
    Dialog.prototype.enabled = function (state) {
 | 
			
		||||
        if (state !== undefined) {
 | 
			
		||||
            this.enabledState = state;
 | 
			
		||||
            if (this.showing) {
 | 
			
		||||
                this.$ok.toggleClass('disabled', !state);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return this.enabledState;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return Dialog;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										68
									
								
								src/api/ui/GestureAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/api/ui/GestureAPI.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 () {
 | 
			
		||||
    /**
 | 
			
		||||
     * Allows support for common user actions to be attached to views.
 | 
			
		||||
     * @interface GestureAPI
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
    function GestureAPI(selectGesture, contextMenuGesture) {
 | 
			
		||||
        this.selectGesture = selectGesture;
 | 
			
		||||
        this.contextMenuGesture = contextMenuGesture;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Designate an HTML element as selectable, and associated with a
 | 
			
		||||
     * particular object.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {HTMLElement} htmlElement the element to make selectable
 | 
			
		||||
     * @param {*} item the object which should become selected when this
 | 
			
		||||
     *        element is clicked.
 | 
			
		||||
     * @returns {Function} a function to remove selectability from this
 | 
			
		||||
     *          HTML element.
 | 
			
		||||
     * @method selectable
 | 
			
		||||
     * @memberof module:openmct.GestureAPI#
 | 
			
		||||
     */
 | 
			
		||||
    GestureAPI.prototype.selectable = function (htmlElement, item) {
 | 
			
		||||
        return this.selectGesture.apply(htmlElement, item);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Designate an HTML element as having a context menu associated with
 | 
			
		||||
     * the provided item.
 | 
			
		||||
     *
 | 
			
		||||
     * @private
 | 
			
		||||
     * @param {HTMLElement} htmlElement the element to make selectable
 | 
			
		||||
     * @param {*} item the object for which a context menu should appear
 | 
			
		||||
     * @returns {Function} a function to remove this geture from this
 | 
			
		||||
     *          HTML element.
 | 
			
		||||
     * @method selectable
 | 
			
		||||
     * @memberof module:openmct.GestureAPI#
 | 
			
		||||
     */
 | 
			
		||||
    GestureAPI.prototype.contextMenu = function (htmlElement, item) {
 | 
			
		||||
        return this.contextMenuGesture.apply(htmlElement, item);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return GestureAPI;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										21
									
								
								src/api/ui/dialog.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/api/ui/dialog.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
<div class="abs overlay">
 | 
			
		||||
    <div class="abs blocker"></div>
 | 
			
		||||
    <div class="abs holder">
 | 
			
		||||
        <a class="clk-icon icon ui-symbol close">x</a>
 | 
			
		||||
        <div class="abs contents">
 | 
			
		||||
            <div class="abs top-bar">
 | 
			
		||||
                <div class="title"></div>
 | 
			
		||||
                <div class="hint"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class='abs editor'>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="abs bottom-bar">
 | 
			
		||||
                <a class='s-btn major ok'>OK</a>
 | 
			
		||||
                <a class='s-btn cancel'>Cancel</a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										135
									
								
								src/defaultRegistry.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								src/defaultRegistry.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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([
 | 
			
		||||
    'legacyRegistry',
 | 
			
		||||
 | 
			
		||||
    '../src/adapter/bundle',
 | 
			
		||||
    '../src/api/objects/bundle',
 | 
			
		||||
 | 
			
		||||
    '../example/builtins/bundle',
 | 
			
		||||
    '../example/composite/bundle',
 | 
			
		||||
    '../example/eventGenerator/bundle',
 | 
			
		||||
    '../example/export/bundle',
 | 
			
		||||
    '../example/extensions/bundle',
 | 
			
		||||
    '../example/forms/bundle',
 | 
			
		||||
    '../example/generator/bundle',
 | 
			
		||||
    '../example/identity/bundle',
 | 
			
		||||
    '../example/imagery/bundle',
 | 
			
		||||
    '../example/mobile/bundle',
 | 
			
		||||
    '../example/msl/bundle',
 | 
			
		||||
    '../example/notifications/bundle',
 | 
			
		||||
    '../example/persistence/bundle',
 | 
			
		||||
    '../example/plotOptions/bundle',
 | 
			
		||||
    '../example/policy/bundle',
 | 
			
		||||
    '../example/profiling/bundle',
 | 
			
		||||
    '../example/scratchpad/bundle',
 | 
			
		||||
    '../example/taxonomy/bundle',
 | 
			
		||||
    '../example/worker/bundle',
 | 
			
		||||
 | 
			
		||||
    '../platform/commonUI/about/bundle',
 | 
			
		||||
    '../platform/commonUI/browse/bundle',
 | 
			
		||||
    '../platform/commonUI/dialog/bundle',
 | 
			
		||||
    '../platform/commonUI/edit/bundle',
 | 
			
		||||
    '../platform/commonUI/formats/bundle',
 | 
			
		||||
    '../platform/commonUI/general/bundle',
 | 
			
		||||
    '../platform/commonUI/inspect/bundle',
 | 
			
		||||
    '../platform/commonUI/mobile/bundle',
 | 
			
		||||
    '../platform/commonUI/notification/bundle',
 | 
			
		||||
    '../platform/commonUI/regions/bundle',
 | 
			
		||||
    '../platform/commonUI/themes/espresso/bundle',
 | 
			
		||||
    '../platform/commonUI/themes/snow/bundle',
 | 
			
		||||
    '../platform/containment/bundle',
 | 
			
		||||
    '../platform/core/bundle',
 | 
			
		||||
    '../platform/entanglement/bundle',
 | 
			
		||||
    '../platform/execution/bundle',
 | 
			
		||||
    '../platform/exporters/bundle',
 | 
			
		||||
    '../platform/features/clock/bundle',
 | 
			
		||||
    '../platform/features/conductor/bundle',
 | 
			
		||||
    '../platform/features/imagery/bundle',
 | 
			
		||||
    '../platform/features/layout/bundle',
 | 
			
		||||
    '../platform/features/pages/bundle',
 | 
			
		||||
    '../platform/features/plot/bundle',
 | 
			
		||||
    '../platform/features/static-markup/bundle',
 | 
			
		||||
    '../platform/features/table/bundle',
 | 
			
		||||
    '../platform/features/timeline/bundle',
 | 
			
		||||
    '../platform/forms/bundle',
 | 
			
		||||
    '../platform/framework/bundle',
 | 
			
		||||
    '../platform/framework/src/load/Bundle',
 | 
			
		||||
    '../platform/identity/bundle',
 | 
			
		||||
    '../platform/persistence/aggregator/bundle',
 | 
			
		||||
    '../platform/persistence/couch/bundle',
 | 
			
		||||
    '../platform/persistence/elastic/bundle',
 | 
			
		||||
    '../platform/persistence/local/bundle',
 | 
			
		||||
    '../platform/persistence/queue/bundle',
 | 
			
		||||
    '../platform/policy/bundle',
 | 
			
		||||
    '../platform/representation/bundle',
 | 
			
		||||
    '../platform/search/bundle',
 | 
			
		||||
    '../platform/status/bundle',
 | 
			
		||||
    '../platform/telemetry/bundle'
 | 
			
		||||
], function (legacyRegistry) {
 | 
			
		||||
 | 
			
		||||
    var DEFAULTS = [
 | 
			
		||||
        'src/adapter',
 | 
			
		||||
        'src/api/objects',
 | 
			
		||||
        'platform/framework',
 | 
			
		||||
        'platform/core',
 | 
			
		||||
        'platform/representation',
 | 
			
		||||
        'platform/commonUI/about',
 | 
			
		||||
        'platform/commonUI/browse',
 | 
			
		||||
        'platform/commonUI/edit',
 | 
			
		||||
        'platform/commonUI/dialog',
 | 
			
		||||
        'platform/commonUI/formats',
 | 
			
		||||
        'platform/commonUI/general',
 | 
			
		||||
        'platform/commonUI/inspect',
 | 
			
		||||
        'platform/commonUI/mobile',
 | 
			
		||||
        'platform/commonUI/themes/espresso',
 | 
			
		||||
        'platform/commonUI/notification',
 | 
			
		||||
        'platform/containment',
 | 
			
		||||
        'platform/execution',
 | 
			
		||||
        'platform/exporters',
 | 
			
		||||
        'platform/telemetry',
 | 
			
		||||
        'platform/features/clock',
 | 
			
		||||
        'platform/features/imagery',
 | 
			
		||||
        'platform/features/layout',
 | 
			
		||||
        'platform/features/pages',
 | 
			
		||||
        'platform/features/plot',
 | 
			
		||||
        'platform/features/timeline',
 | 
			
		||||
        'platform/features/table',
 | 
			
		||||
        'platform/forms',
 | 
			
		||||
        'platform/identity',
 | 
			
		||||
        'platform/persistence/aggregator',
 | 
			
		||||
        'platform/persistence/local',
 | 
			
		||||
        'platform/persistence/queue',
 | 
			
		||||
        'platform/policy',
 | 
			
		||||
        'platform/entanglement',
 | 
			
		||||
        'platform/search',
 | 
			
		||||
        'platform/status',
 | 
			
		||||
        'platform/commonUI/regions'
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    DEFAULTS.forEach(function (bundlePath) {
 | 
			
		||||
        legacyRegistry.enable(bundlePath);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return legacyRegistry;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										3
									
								
								src/end.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/end.frag
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
 | 
			
		||||
   return require('main'); 
 | 
			
		||||
}));
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * 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 Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * 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.
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * 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.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * 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 Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * 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.
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * 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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										78
									
								
								src/selection/ContextManager.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/selection/ContextManager.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2016, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(['zepto'], function ($) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @typedef Context
 | 
			
		||||
     * @property {*} item
 | 
			
		||||
     * @property {HTMLElement} element
 | 
			
		||||
     * @property {Context} parent the containing context (may be undefined)
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function ContextManager() {
 | 
			
		||||
        this.counter = 0;
 | 
			
		||||
        this.contexts = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ContextManager.prototype.nextId = function () {
 | 
			
		||||
        this.counter += 1;
 | 
			
		||||
        return "context-" + this.counter;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ContextManager.prototype.context = function (item, htmlElement) {
 | 
			
		||||
        var $element = $(htmlElement);
 | 
			
		||||
        var id = $element.attr('data-context') || this.nextId();
 | 
			
		||||
 | 
			
		||||
        $element.attr('data-context', id);
 | 
			
		||||
 | 
			
		||||
        if (this.contexts[id] && this.contexts[id].item !== item) {
 | 
			
		||||
            this.release(htmlElement);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this.contexts[id]) {
 | 
			
		||||
            var $parent = $element.closest('[data-context]');
 | 
			
		||||
            var parentId = $parent.attr('data-context');
 | 
			
		||||
            var parentContext = parentId ? this.contexts[parentId] : undefined;
 | 
			
		||||
            this.contexts[id] = {
 | 
			
		||||
                item: item,
 | 
			
		||||
                element: htmlElement,
 | 
			
		||||
                parent: parentContext
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return this.contexts[id];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ContextManager.prototype.release = function (htmlElement) {
 | 
			
		||||
        var $element = $(htmlElement);
 | 
			
		||||
        var id = $element.attr('data-context');
 | 
			
		||||
 | 
			
		||||
        if (id) {
 | 
			
		||||
            delete this.contexts[id];
 | 
			
		||||
            $element.removeAttr('data-context');
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return ContextManager;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										58
									
								
								src/selection/HoverGesture.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/selection/HoverGesture.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2016, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(['zepto'], function ($) {
 | 
			
		||||
    function HoverGesture(hoverManager) {
 | 
			
		||||
        this.hoverManager = hoverManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    HoverGesture.prototype.apply = function (htmlElement) {
 | 
			
		||||
        var $element = $(htmlElement);
 | 
			
		||||
        var hoverManager = this.hoverManager;
 | 
			
		||||
 | 
			
		||||
        function update() {
 | 
			
		||||
            $(hoverManager.all()).removeClass('hovering');
 | 
			
		||||
            $(hoverManager.top()).addClass('hovering');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function enter() {
 | 
			
		||||
            hoverManager.add(htmlElement);
 | 
			
		||||
            update();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function leave() {
 | 
			
		||||
            hoverManager.remove(htmlElement);
 | 
			
		||||
            update();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $element.on('mouseenter', enter);
 | 
			
		||||
        $element.on('mouseleave', leave);
 | 
			
		||||
 | 
			
		||||
        return function () {
 | 
			
		||||
            leave();
 | 
			
		||||
            $element.off('mouseenter', enter);
 | 
			
		||||
            $element.off('mouseleave', leave);
 | 
			
		||||
        }.bind(this);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return HoverGesture;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										60
									
								
								src/selection/SelectGesture.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/selection/SelectGesture.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2016, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(['zepto'], function ($) {
 | 
			
		||||
    function SelectGesture(selection, contextManager) {
 | 
			
		||||
        this.selection = selection;
 | 
			
		||||
        this.contextManager = contextManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SelectGesture.prototype.apply = function (htmlElement, item) {
 | 
			
		||||
        var $element = $(htmlElement);
 | 
			
		||||
        var contextManager = this.contextManager;
 | 
			
		||||
        var selection = this.selection;
 | 
			
		||||
        var path = contextManager.path(item, htmlElement);
 | 
			
		||||
 | 
			
		||||
        function select() {
 | 
			
		||||
            selection.add(path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function change() {
 | 
			
		||||
            var selected = selection.primary();
 | 
			
		||||
            $element.toggleClass(
 | 
			
		||||
                'selected',
 | 
			
		||||
                selected && path.matches(selected)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $element.addClass('selectable');
 | 
			
		||||
        $element.on('click', select);
 | 
			
		||||
        selection.on('change', change);
 | 
			
		||||
        change(); // Initialize
 | 
			
		||||
 | 
			
		||||
        return function () {
 | 
			
		||||
            contextManager.release(htmlElement);
 | 
			
		||||
            $element.off('click', select);
 | 
			
		||||
            selection.off('change', change);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return SelectGesture;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										69
									
								
								src/selection/Selection.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/selection/Selection.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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(['EventEmitter'], function (EventEmitter) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Manages selection state for Open MCT
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    function Selection() {
 | 
			
		||||
        EventEmitter.call(this);
 | 
			
		||||
        this.selected = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Selection.prototype = Object.create(EventEmitter.prototype);
 | 
			
		||||
 | 
			
		||||
    Selection.prototype.add = function (context) {
 | 
			
		||||
        this.clear(); // Only allow single select as initial simplification
 | 
			
		||||
        this.selected.push(context);
 | 
			
		||||
        this.emit('change');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Selection.prototype.remove = function (path) {
 | 
			
		||||
        this.selected = this.selected.filter(function (otherPath) {
 | 
			
		||||
            return !path.matches(otherPath);
 | 
			
		||||
        });
 | 
			
		||||
        this.emit('change');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Selection.prototype.contains = function (path) {
 | 
			
		||||
        return this.selected.some(function (otherPath) {
 | 
			
		||||
            return path.matches(otherPath);
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Selection.prototype.clear = function () {
 | 
			
		||||
        this.selected = [];
 | 
			
		||||
        this.emit('change');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Selection.prototype.primary = function () {
 | 
			
		||||
        return this.selected[this.selected.length - 1];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Selection.prototype.all = function () {
 | 
			
		||||
        return this.selected;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return Selection;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										39
									
								
								src/start.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/start.frag
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Open MCT https://nasa.github.io/openmct/
 | 
			
		||||
 * Version @@version
 | 
			
		||||
 * Built @@timestamp
 | 
			
		||||
 * Revision @@revision
 | 
			
		||||
 * Branch @@branch
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
(function (root, factory) {
 | 
			
		||||
    if (typeof define === 'function' && define.amd) {
 | 
			
		||||
        define([], factory);
 | 
			
		||||
    } else if (typeof exports === 'object') {
 | 
			
		||||
        module.exports = factory();
 | 
			
		||||
    } else {
 | 
			
		||||
        root.MCT = factory();
 | 
			
		||||
    }
 | 
			
		||||
}(this, function() {
 | 
			
		||||
							
								
								
									
										152
									
								
								src/ui/ViewRegistry.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								src/ui/ViewRegistry.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * 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 () {
 | 
			
		||||
    /**
 | 
			
		||||
     * A ViewRegistry maintains the definitions for different kinds of views
 | 
			
		||||
     * that may occur in different places in the user interface.
 | 
			
		||||
     * @interface ViewRegistry
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
    function ViewRegistry() {
 | 
			
		||||
        this.providers = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @private for platform-internal use
 | 
			
		||||
     * @param {*} item the object to be viewed
 | 
			
		||||
     * @returns {module:openmct.ViewProvider[]} any providers
 | 
			
		||||
     *          which can provide views of this object
 | 
			
		||||
     */
 | 
			
		||||
    ViewRegistry.prototype.get = function (item) {
 | 
			
		||||
        return this.providers.filter(function (provider) {
 | 
			
		||||
            return provider.canView(item);
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register a new type of view.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {module:openmct.ViewProvider} provider the provider for this view
 | 
			
		||||
     * @method addProvider
 | 
			
		||||
     * @memberof module:openmct.ViewRegistry#
 | 
			
		||||
     */
 | 
			
		||||
    ViewRegistry.prototype.addProvider = function (provider) {
 | 
			
		||||
        this.providers.push(provider);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A View is used to provide displayable content, and to react to
 | 
			
		||||
     * associated life cycle events.
 | 
			
		||||
     *
 | 
			
		||||
     * @name View
 | 
			
		||||
     * @interface
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Populate the supplied DOM element with the contents of this view.
 | 
			
		||||
     *
 | 
			
		||||
     * View implementations should use this method to attach any
 | 
			
		||||
     * listeners or acquire other resources that are necessary to keep
 | 
			
		||||
     * the contents of this view up-to-date.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {HTMLElement} container the DOM element to populate
 | 
			
		||||
     * @method show
 | 
			
		||||
     * @memberof module:openmct.View#
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Release any resources associated with this view.
 | 
			
		||||
     *
 | 
			
		||||
     * View implementations should use this method to detach any
 | 
			
		||||
     * listeners or release other resources that are no longer necessary
 | 
			
		||||
     * once a view is no longer used.
 | 
			
		||||
     *
 | 
			
		||||
     * @method destroy
 | 
			
		||||
     * @memberof module:openmct.View#
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Exposes types of views in Open MCT.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface ViewProvider
 | 
			
		||||
     * @memberof module:openmct
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if this provider can supply views for a domain object.
 | 
			
		||||
     *
 | 
			
		||||
     * When called by Open MCT, this may include additional arguments
 | 
			
		||||
     * which are on the path to the object to be viewed; for instance,
 | 
			
		||||
     * when viewing "A Folder" within "My Items", this method will be
 | 
			
		||||
     * invoked with "A Folder" (as a domain object) as the first argument,
 | 
			
		||||
     * and "My Items" as the second argument.
 | 
			
		||||
     *
 | 
			
		||||
     * @method canView
 | 
			
		||||
     * @memberof module:openmct.ViewProvider#
 | 
			
		||||
     * @param {module:openmct.DomainObject} domainObject the domain object
 | 
			
		||||
     *        to be viewed
 | 
			
		||||
     * @returns {boolean} true if this domain object can be viewed using
 | 
			
		||||
     *          this provider
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Provide a view of this object.
 | 
			
		||||
     *
 | 
			
		||||
     * When called by Open MCT, this may include additional arguments
 | 
			
		||||
     * which are on the path to the object to be viewed; for instance,
 | 
			
		||||
     * when viewing "A Folder" within "My Items", this method will be
 | 
			
		||||
     * invoked with "A Folder" (as a domain object) as the first argument,
 | 
			
		||||
     * and "My Items" as the second argument.
 | 
			
		||||
     *
 | 
			
		||||
     * @method view
 | 
			
		||||
     * @memberof module:openmct.ViewProvider#
 | 
			
		||||
     * @param {*} object the object to be viewed
 | 
			
		||||
     * @returns {module:openmct.View} a view of this domain object
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get metadata associated with this view provider. This may be used
 | 
			
		||||
     * to populate the user interface with options associated with this
 | 
			
		||||
     * view provider.
 | 
			
		||||
     *
 | 
			
		||||
     * @method metadata
 | 
			
		||||
     * @memberof module:openmct.ViewProvider#
 | 
			
		||||
     * @returns {module:openmct.ViewProvider~ViewMetadata} view metadata
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @typedef ViewMetadata
 | 
			
		||||
     * @memberof module:openmct.ViewProvider~
 | 
			
		||||
     * @property {string} name the human-readable name of this view
 | 
			
		||||
     * @property {string} key a machine-readable name for this view
 | 
			
		||||
     * @property {string} [description] a longer-form description (typically
 | 
			
		||||
     *           a single sentence or short paragraph) of this kind of view
 | 
			
		||||
     * @property {string} cssclass the CSS class to apply to labels for this
 | 
			
		||||
     *           view (to add icons, for instance)
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    return ViewRegistry;
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										10
									
								
								test-main.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								test-main.js
									
									
									
									
									
								
							@@ -48,13 +48,15 @@ requirejs.config({
 | 
			
		||||
        "angular-route": "bower_components/angular-route/angular-route.min",
 | 
			
		||||
        "csv": "bower_components/comma-separated-values/csv.min",
 | 
			
		||||
        "es6-promise": "bower_components/es6-promise/promise.min",
 | 
			
		||||
        "EventEmitter": "bower_components/eventemitter3/index",
 | 
			
		||||
        "moment": "bower_components/moment/moment",
 | 
			
		||||
        "moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
 | 
			
		||||
        "saveAs": "bower_components/FileSaver.js/FileSaver.min",
 | 
			
		||||
        "screenfull": "bower_components/screenfull/dist/screenfull.min",
 | 
			
		||||
        "text": "bower_components/text/text",
 | 
			
		||||
        "uuid": "bower_components/node-uuid/uuid",
 | 
			
		||||
        "zepto": "bower_components/zepto/zepto.min"
 | 
			
		||||
        "zepto": "bower_components/zepto/zepto.min",
 | 
			
		||||
        "lodash": "bower_components/lodash/lodash"
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "shim": {
 | 
			
		||||
@@ -64,6 +66,9 @@ requirejs.config({
 | 
			
		||||
        "angular-route": {
 | 
			
		||||
            "deps": [ "angular" ]
 | 
			
		||||
        },
 | 
			
		||||
        "EventEmitter": {
 | 
			
		||||
            "exports": "EventEmitter"
 | 
			
		||||
        },
 | 
			
		||||
        "moment-duration-format": {
 | 
			
		||||
            "deps": [ "moment" ]
 | 
			
		||||
        },
 | 
			
		||||
@@ -72,6 +77,9 @@ requirejs.config({
 | 
			
		||||
        },
 | 
			
		||||
        "zepto": {
 | 
			
		||||
            "exports": "Zepto"
 | 
			
		||||
        },
 | 
			
		||||
        "lodash": {
 | 
			
		||||
            "exports": "lodash"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										127
									
								
								tutorial-server/app.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								tutorial-server/app.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
			
		||||
/*global require,process,console*/
 | 
			
		||||
 | 
			
		||||
var CONFIG = {
 | 
			
		||||
    port: 8081,
 | 
			
		||||
    dictionary: "dictionary.json",
 | 
			
		||||
    interval: 1000
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
(function () {
 | 
			
		||||
    "use strict";
 | 
			
		||||
 | 
			
		||||
    var WebSocketServer = require('ws').Server,
 | 
			
		||||
        fs = require('fs'),
 | 
			
		||||
        wss = new WebSocketServer({ port: CONFIG.port }),
 | 
			
		||||
        dictionary = JSON.parse(fs.readFileSync(CONFIG.dictionary, "utf8")),
 | 
			
		||||
        spacecraft = {
 | 
			
		||||
            "prop.fuel": 77,
 | 
			
		||||
            "prop.thrusters": "OFF",
 | 
			
		||||
            "comms.recd": 0,
 | 
			
		||||
            "comms.sent": 0,
 | 
			
		||||
            "pwr.temp": 245,
 | 
			
		||||
            "pwr.c": 8.15,
 | 
			
		||||
            "pwr.v": 30
 | 
			
		||||
        },
 | 
			
		||||
        histories = {},
 | 
			
		||||
        listeners = [];
 | 
			
		||||
 | 
			
		||||
    function updateSpacecraft() {
 | 
			
		||||
        spacecraft["prop.fuel"] = Math.max(
 | 
			
		||||
            0,
 | 
			
		||||
            spacecraft["prop.fuel"] -
 | 
			
		||||
            (spacecraft["prop.thrusters"] === "ON" ? 0.5 : 0)
 | 
			
		||||
        );
 | 
			
		||||
        spacecraft["pwr.temp"] = spacecraft["pwr.temp"] * 0.985
 | 
			
		||||
        + Math.random() * 0.25 + Math.sin(Date.now());
 | 
			
		||||
        spacecraft["pwr.c"] = spacecraft["pwr.c"] * 0.985;
 | 
			
		||||
        spacecraft["pwr.v"] = 30 + Math.pow(Math.random(), 3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function generateTelemetry() {
 | 
			
		||||
        var timestamp = Date.now(), sent = 0;
 | 
			
		||||
        Object.keys(spacecraft).forEach(function (id) {
 | 
			
		||||
            var state = { timestamp: timestamp, value: spacecraft[id] };
 | 
			
		||||
            histories[id] = histories[id] || []; // Initialize
 | 
			
		||||
            histories[id].push(state);
 | 
			
		||||
            spacecraft["comms.sent"] += JSON.stringify(state).length;
 | 
			
		||||
        });
 | 
			
		||||
        listeners.forEach(function (listener) {
 | 
			
		||||
            listener();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function update() {
 | 
			
		||||
        updateSpacecraft();
 | 
			
		||||
        generateTelemetry();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function handleConnection(ws) {
 | 
			
		||||
        var subscriptions = {}, // Active subscriptions for this connection
 | 
			
		||||
            handlers = {        // Handlers for specific requests
 | 
			
		||||
                dictionary: function () {
 | 
			
		||||
                    ws.send(JSON.stringify({
 | 
			
		||||
                        type: "dictionary",
 | 
			
		||||
                        value: dictionary
 | 
			
		||||
                    }));
 | 
			
		||||
                },
 | 
			
		||||
                subscribe: function (id) {
 | 
			
		||||
                    subscriptions[id] = true;
 | 
			
		||||
                },
 | 
			
		||||
                unsubscribe: function (id) {
 | 
			
		||||
                    delete subscriptions[id];
 | 
			
		||||
                },
 | 
			
		||||
                history: function (id) {
 | 
			
		||||
                    ws.send(JSON.stringify({
 | 
			
		||||
                        type: "history",
 | 
			
		||||
                        id: id,
 | 
			
		||||
                        value: histories[id]
 | 
			
		||||
                    }));
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        function notifySubscribers() {
 | 
			
		||||
            Object.keys(subscriptions).forEach(function (id) {
 | 
			
		||||
                var history = histories[id];
 | 
			
		||||
                if (history) {
 | 
			
		||||
                    ws.send(JSON.stringify({
 | 
			
		||||
                        type: "data",
 | 
			
		||||
                        id: id,
 | 
			
		||||
                        value: history[history.length - 1]
 | 
			
		||||
                    }));
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Listen for requests
 | 
			
		||||
        ws.on('message', function (message) {
 | 
			
		||||
            var parts = message.split(' '),
 | 
			
		||||
                handler = handlers[parts[0]];
 | 
			
		||||
            if (handler) {
 | 
			
		||||
                handler.apply(handlers, parts.slice(1));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Stop sending telemetry updates for this connection when closed
 | 
			
		||||
        ws.on('close', function () {
 | 
			
		||||
            listeners = listeners.filter(function (listener) {
 | 
			
		||||
                return listener !== notifySubscribers;
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Notify subscribers when telemetry is updated
 | 
			
		||||
        listeners.push(notifySubscribers);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update();
 | 
			
		||||
    setInterval(update, CONFIG.interval);
 | 
			
		||||
 | 
			
		||||
    wss.on('connection', handleConnection);
 | 
			
		||||
 | 
			
		||||
    console.log("Example spacecraft running on port ");
 | 
			
		||||
    console.log("Press Enter to toggle thruster state.");
 | 
			
		||||
    process.stdin.on('data', function (data) {
 | 
			
		||||
        spacecraft['prop.thrusters'] =
 | 
			
		||||
            (spacecraft['prop.thrusters'] === "OFF") ? "ON" : "OFF";
 | 
			
		||||
        console.log("Thrusters " + spacecraft["prop.thrusters"]);
 | 
			
		||||
    });
 | 
			
		||||
}());
 | 
			
		||||
							
								
								
									
										66
									
								
								tutorial-server/dictionary.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								tutorial-server/dictionary.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "Example Spacecraft",
 | 
			
		||||
    "identifier": "sc",
 | 
			
		||||
    "subsystems": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Propulsion",
 | 
			
		||||
            "identifier": "prop",
 | 
			
		||||
            "measurements": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Fuel",
 | 
			
		||||
                    "identifier": "prop.fuel",
 | 
			
		||||
                    "units": "kilograms",
 | 
			
		||||
                    "type": "float"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Thrusters",
 | 
			
		||||
                    "identifier": "prop.thrusters",
 | 
			
		||||
                    "units": "None",
 | 
			
		||||
                    "type": "string"
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Communications",
 | 
			
		||||
            "identifier": "comms",
 | 
			
		||||
            "measurements": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Received",
 | 
			
		||||
                    "identifier": "comms.recd",
 | 
			
		||||
                    "units": "bytes",
 | 
			
		||||
                    "type": "integer"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Sent",
 | 
			
		||||
                    "identifier": "comms.sent",
 | 
			
		||||
                    "units": "bytes",
 | 
			
		||||
                    "type": "integer"
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Power",
 | 
			
		||||
            "identifier": "pwr",
 | 
			
		||||
            "measurements": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Generator Temperature",
 | 
			
		||||
                    "identifier": "pwr.temp",
 | 
			
		||||
                    "units": "\u0080C",
 | 
			
		||||
                    "type": "float"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Generator Current",
 | 
			
		||||
                    "identifier": "pwr.c",
 | 
			
		||||
                    "units": "A",
 | 
			
		||||
                    "type": "float"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Generator Voltage",
 | 
			
		||||
                    "identifier": "pwr.v",
 | 
			
		||||
                    "units": "V",
 | 
			
		||||
                    "type": "float"
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								tutorials/bargraph/bundle.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								tutorials/bargraph/bundle.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
define([
 | 
			
		||||
    'legacyRegistry',
 | 
			
		||||
    './src/controllers/BarGraphController'
 | 
			
		||||
], function (
 | 
			
		||||
    legacyRegistry,
 | 
			
		||||
    BarGraphController
 | 
			
		||||
    ) {
 | 
			
		||||
    legacyRegistry.register("tutorials/bargraph", {
 | 
			
		||||
        "name": "Bar Graph",
 | 
			
		||||
        "description": "Provides the Bar Graph view of telemetry elements.",
 | 
			
		||||
        "extensions": {
 | 
			
		||||
            "views": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Bar Graph",
 | 
			
		||||
                    "key": "example.bargraph",
 | 
			
		||||
                    "glyph": "H",
 | 
			
		||||
                    "templateUrl": "templates/bargraph.html",
 | 
			
		||||
                    "needs": [ "telemetry" ],
 | 
			
		||||
                    "delegation": true,
 | 
			
		||||
                    "editable": true,
 | 
			
		||||
                    "toolbar": {
 | 
			
		||||
                        "sections": [
 | 
			
		||||
                            {
 | 
			
		||||
                                "items": [
 | 
			
		||||
                                    {
 | 
			
		||||
                                        "name": "Low",
 | 
			
		||||
                                        "property": "low",
 | 
			
		||||
                                        "required": true,
 | 
			
		||||
                                        "control": "textfield",
 | 
			
		||||
                                        "size": 4
 | 
			
		||||
                                    },
 | 
			
		||||
                                    {
 | 
			
		||||
                                        "name": "Middle",
 | 
			
		||||
                                        "property": "middle",
 | 
			
		||||
                                        "required": true,
 | 
			
		||||
                                        "control": "textfield",
 | 
			
		||||
                                        "size": 4
 | 
			
		||||
                                    },
 | 
			
		||||
                                    {
 | 
			
		||||
                                        "name": "High",
 | 
			
		||||
                                        "property": "high",
 | 
			
		||||
                                        "required": true,
 | 
			
		||||
                                        "control": "textfield",
 | 
			
		||||
                                        "size": 4
 | 
			
		||||
                                    }
 | 
			
		||||
                                ]
 | 
			
		||||
                            }
 | 
			
		||||
                        ]
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "stylesheets": [
 | 
			
		||||
                {
 | 
			
		||||
                    "stylesheetUrl": "css/bargraph.css"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "controllers": [
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "BarGraphController",
 | 
			
		||||
                    "implementation": BarGraphController,
 | 
			
		||||
                    "depends": [ "$scope", "telemetryHandler" ]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										35
									
								
								tutorials/bargraph/res/templates/bargraph.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								tutorials/bargraph/res/templates/bargraph.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
<div class="example-bargraph" ng-controller="BarGraphController">
 | 
			
		||||
    <div class="example-tick-labels">
 | 
			
		||||
        <div ng-repeat="value in [low, middle, high] track by $index"
 | 
			
		||||
             class="example-tick-label"
 | 
			
		||||
             style="bottom: {{ toPercent(value) }}%">
 | 
			
		||||
            {{value}}
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="example-graph-area">
 | 
			
		||||
        <div ng-repeat="telemetryObject in telemetryObjects"
 | 
			
		||||
             style="left: {{barWidth * $index}}%; width: {{barWidth}}%"
 | 
			
		||||
             class="example-bar-holder">
 | 
			
		||||
            <div class="example-bar"
 | 
			
		||||
                 ng-style="{
 | 
			
		||||
                     bottom: getBottom(telemetryObject) + '%',
 | 
			
		||||
                     top: getTop(telemetryObject) + '%'
 | 
			
		||||
                 }">
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div style="bottom: {{ toPercent(middle) }}%"
 | 
			
		||||
             class="example-graph-tick">
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="example-bar-labels">
 | 
			
		||||
        <div ng-repeat="telemetryObject in telemetryObjects"
 | 
			
		||||
             style="left: {{barWidth * $index}}%; width: {{barWidth}}%"
 | 
			
		||||
             class="example-bar-holder example-label">
 | 
			
		||||
            <mct-representation key="'label'"
 | 
			
		||||
                                mct-object="telemetryObject">
 | 
			
		||||
            </mct-representation>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										75
									
								
								tutorials/bargraph/src/controllers/BarGraphController.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								tutorials/bargraph/src/controllers/BarGraphController.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
define(function () {
 | 
			
		||||
    function BarGraphController($scope, telemetryHandler) {
 | 
			
		||||
        var handle;
 | 
			
		||||
 | 
			
		||||
        // Expose configuration constants directly in scope
 | 
			
		||||
        function exposeConfiguration() {
 | 
			
		||||
            $scope.low = $scope.configuration.low;
 | 
			
		||||
            $scope.middle = $scope.configuration.middle;
 | 
			
		||||
            $scope.high = $scope.configuration.high;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Populate a default value in the configuration
 | 
			
		||||
        function setDefault(key, value) {
 | 
			
		||||
            if ($scope.configuration[key] === undefined) {
 | 
			
		||||
                $scope.configuration[key] = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Getter-setter for configuration properties (for view proxy)
 | 
			
		||||
        function getterSetter(property) {
 | 
			
		||||
            return function (value) {
 | 
			
		||||
                value = parseFloat(value);
 | 
			
		||||
                if (!isNaN(value)) {
 | 
			
		||||
                    $scope.configuration[property] = value;
 | 
			
		||||
                    exposeConfiguration();
 | 
			
		||||
                }
 | 
			
		||||
                return $scope.configuration[property];
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Add min/max defaults
 | 
			
		||||
        setDefault('low', -1);
 | 
			
		||||
        setDefault('middle', 0);
 | 
			
		||||
        setDefault('high', 1);
 | 
			
		||||
        exposeConfiguration($scope.configuration);
 | 
			
		||||
 | 
			
		||||
        // Expose view configuration options
 | 
			
		||||
        if ($scope.selection) {
 | 
			
		||||
            $scope.selection.proxy({
 | 
			
		||||
                low: getterSetter('low'),
 | 
			
		||||
                middle: getterSetter('middle'),
 | 
			
		||||
                high: getterSetter('high')
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Convert value to a percent between 0-100
 | 
			
		||||
        $scope.toPercent = function (value) {
 | 
			
		||||
            var pct = 100 * (value - $scope.low) /
 | 
			
		||||
                ($scope.high - $scope.low);
 | 
			
		||||
            return Math.min(100, Math.max(0, pct));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Get bottom and top (as percentages) for current value
 | 
			
		||||
        $scope.getBottom = function (telemetryObject) {
 | 
			
		||||
            var value = handle.getRangeValue(telemetryObject);
 | 
			
		||||
            return $scope.toPercent(Math.min($scope.middle, value));
 | 
			
		||||
        };
 | 
			
		||||
        $scope.getTop = function (telemetryObject) {
 | 
			
		||||
            var value = handle.getRangeValue(telemetryObject);
 | 
			
		||||
            return 100 - $scope.toPercent(Math.max($scope.middle, value));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Use the telemetryHandler to get telemetry objects here
 | 
			
		||||
        handle = telemetryHandler.handle($scope.domainObject, function () {
 | 
			
		||||
            $scope.telemetryObjects = handle.getTelemetryObjects();
 | 
			
		||||
            $scope.barWidth =
 | 
			
		||||
                100 / Math.max(($scope.telemetryObjects).length, 1);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Release subscriptions when scope is destroyed
 | 
			
		||||
        $scope.$on('$destroy', handle.unsubscribe);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return BarGraphController;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										90
									
								
								tutorials/telemetry/bundle.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								tutorials/telemetry/bundle.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
define([
 | 
			
		||||
    'legacyRegistry',
 | 
			
		||||
    './src/ExampleTelemetryServerAdapter',
 | 
			
		||||
    './src/ExampleTelemetryInitializer',
 | 
			
		||||
    './src/ExampleTelemetryModelProvider'
 | 
			
		||||
], function (
 | 
			
		||||
    legacyRegistry,
 | 
			
		||||
    ExampleTelemetryServerAdapter,
 | 
			
		||||
    ExampleTelemetryInitializer,
 | 
			
		||||
    ExampleTelemetryModelProvider
 | 
			
		||||
) {
 | 
			
		||||
    legacyRegistry.register("tutorials/telemetry", {
 | 
			
		||||
        "name": "Example Telemetry Adapter",
 | 
			
		||||
        "extensions": {
 | 
			
		||||
            "types": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Spacecraft",
 | 
			
		||||
                    "key": "example.spacecraft",
 | 
			
		||||
                    "glyph": "o"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Subsystem",
 | 
			
		||||
                    "key": "example.subsystem",
 | 
			
		||||
                    "glyph": "o",
 | 
			
		||||
                    "model": { "composition": [] }
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Measurement",
 | 
			
		||||
                    "key": "example.measurement",
 | 
			
		||||
                    "glyph": "T",
 | 
			
		||||
                    "model": { "telemetry": {} },
 | 
			
		||||
                    "telemetry": {
 | 
			
		||||
                        "source": "example.source",
 | 
			
		||||
                        "domains": [
 | 
			
		||||
                            {
 | 
			
		||||
                                "name": "Time",
 | 
			
		||||
                                "key": "timestamp"
 | 
			
		||||
                            }
 | 
			
		||||
                        ]
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "roots": [
 | 
			
		||||
                {
 | 
			
		||||
                    "id": "example:sc",
 | 
			
		||||
                    "priority": "preferred",
 | 
			
		||||
                    "model": {
 | 
			
		||||
                        "type": "example.spacecraft",
 | 
			
		||||
                        "name": "My Spacecraft",
 | 
			
		||||
                        "composition": []
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "services": [
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "example.adapter",
 | 
			
		||||
                    "implementation": "ExampleTelemetryServerAdapter.js",
 | 
			
		||||
                    "depends": [ "$q", "EXAMPLE_WS_URL" ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "constants": [
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "EXAMPLE_WS_URL",
 | 
			
		||||
                    "priority": "fallback",
 | 
			
		||||
                    "value": "ws://localhost:8081"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "runs": [
 | 
			
		||||
                {
 | 
			
		||||
                    "implementation": "ExampleTelemetryInitializer.js",
 | 
			
		||||
                    "depends": [ "example.adapter", "objectService" ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "components": [
 | 
			
		||||
                {
 | 
			
		||||
                    "provides": "modelService",
 | 
			
		||||
                    "type": "provider",
 | 
			
		||||
                    "implementation": "ExampleTelemetryModelProvider.js",
 | 
			
		||||
                    "depends": [ "example.adapter", "$q" ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "provides": "telemetryService",
 | 
			
		||||
                    "type": "provider",
 | 
			
		||||
                    "implementation": "ExampleTelemetryProvider.js",
 | 
			
		||||
                    "depends": [ "example.adapter", "$q" ]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										47
									
								
								tutorials/telemetry/src/ExampleTelemetryInitializer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								tutorials/telemetry/src/ExampleTelemetryInitializer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
define(
 | 
			
		||||
    function () {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        var TAXONOMY_ID = "example:sc",
 | 
			
		||||
            PREFIX = "example_tlm:";
 | 
			
		||||
 | 
			
		||||
        function ExampleTelemetryInitializer(adapter, objectService) {
 | 
			
		||||
            // Generate a domain object identifier for a dictionary element
 | 
			
		||||
            function makeId(element) {
 | 
			
		||||
                return PREFIX + element.identifier;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // When the dictionary is available, add all subsystems
 | 
			
		||||
            // to the composition of My Spacecraft
 | 
			
		||||
            function initializeTaxonomy(dictionary) {
 | 
			
		||||
                // Get the top-level container for dictionary objects
 | 
			
		||||
                // from a group of domain objects.
 | 
			
		||||
                function getTaxonomyObject(domainObjects) {
 | 
			
		||||
                    return domainObjects[TAXONOMY_ID];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Populate
 | 
			
		||||
                function populateModel(taxonomyObject) {
 | 
			
		||||
                    return taxonomyObject.useCapability(
 | 
			
		||||
                        "mutation",
 | 
			
		||||
                        function (model) {
 | 
			
		||||
                            model.name =
 | 
			
		||||
                                dictionary.name;
 | 
			
		||||
                            model.composition =
 | 
			
		||||
                                dictionary.subsystems.map(makeId);
 | 
			
		||||
                        }
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Look up My Spacecraft, and populate it accordingly.
 | 
			
		||||
                objectService.getObjects([TAXONOMY_ID])
 | 
			
		||||
                    .then(getTaxonomyObject)
 | 
			
		||||
                    .then(populateModel);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            adapter.dictionary().then(initializeTaxonomy);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ExampleTelemetryInitializer;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										78
									
								
								tutorials/telemetry/src/ExampleTelemetryModelProvider.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								tutorials/telemetry/src/ExampleTelemetryModelProvider.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
define(
 | 
			
		||||
    function () {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        var PREFIX = "example_tlm:",
 | 
			
		||||
            FORMAT_MAPPINGS = {
 | 
			
		||||
                float: "number",
 | 
			
		||||
                integer: "number",
 | 
			
		||||
                string: "string"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        function ExampleTelemetryModelProvider(adapter, $q) {
 | 
			
		||||
            var modelPromise, empty = $q.when({});
 | 
			
		||||
 | 
			
		||||
            // Check if this model is in our dictionary (by prefix)
 | 
			
		||||
            function isRelevant(id) {
 | 
			
		||||
                return id.indexOf(PREFIX) === 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Build a domain object identifier by adding a prefix
 | 
			
		||||
            function makeId(element) {
 | 
			
		||||
                return PREFIX + element.identifier;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Create domain object models from this dictionary
 | 
			
		||||
            function buildTaxonomy(dictionary) {
 | 
			
		||||
                var models = {};
 | 
			
		||||
 | 
			
		||||
                // Create & store a domain object model for a measurement
 | 
			
		||||
                function addMeasurement(measurement) {
 | 
			
		||||
                    var format = FORMAT_MAPPINGS[measurement.type];
 | 
			
		||||
                    models[makeId(measurement)] = {
 | 
			
		||||
                        type: "example.measurement",
 | 
			
		||||
                        name: measurement.name,
 | 
			
		||||
                        telemetry: {
 | 
			
		||||
                            key: measurement.identifier,
 | 
			
		||||
                            ranges: [{
 | 
			
		||||
                                key: "value",
 | 
			
		||||
                                name: "Value",
 | 
			
		||||
                                units: measurement.units,
 | 
			
		||||
                                format: format
 | 
			
		||||
                            }]
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Create & store a domain object model for a subsystem
 | 
			
		||||
                function addSubsystem(subsystem) {
 | 
			
		||||
                    var measurements =
 | 
			
		||||
                        (subsystem.measurements || []);
 | 
			
		||||
                    models[makeId(subsystem)] = {
 | 
			
		||||
                        type: "example.subsystem",
 | 
			
		||||
                        name: subsystem.name,
 | 
			
		||||
                        composition: measurements.map(makeId)
 | 
			
		||||
                    };
 | 
			
		||||
                    measurements.forEach(addMeasurement);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                (dictionary.subsystems || []).forEach(addSubsystem);
 | 
			
		||||
 | 
			
		||||
                return models;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Begin generating models once the dictionary is available
 | 
			
		||||
            modelPromise = adapter.dictionary().then(buildTaxonomy);
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                getModels: function (ids) {
 | 
			
		||||
                    // Return models for the dictionary only when they
 | 
			
		||||
                    // are relevant to the request.
 | 
			
		||||
                    return ids.some(isRelevant) ? modelPromise : empty;
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ExampleTelemetryModelProvider;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										80
									
								
								tutorials/telemetry/src/ExampleTelemetryProvider.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								tutorials/telemetry/src/ExampleTelemetryProvider.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
define(
 | 
			
		||||
    ['./ExampleTelemetrySeries'],
 | 
			
		||||
    function (ExampleTelemetrySeries) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        var SOURCE = "example.source";
 | 
			
		||||
 | 
			
		||||
        function ExampleTelemetryProvider(adapter, $q) {
 | 
			
		||||
            var subscribers = {};
 | 
			
		||||
 | 
			
		||||
            // Used to filter out requests for telemetry
 | 
			
		||||
            // from some other source
 | 
			
		||||
            function matchesSource(request) {
 | 
			
		||||
                return (request.source === SOURCE);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Listen for data, notify subscribers
 | 
			
		||||
            adapter.listen(function (message) {
 | 
			
		||||
                var packaged = {};
 | 
			
		||||
                packaged[SOURCE] = {};
 | 
			
		||||
                packaged[SOURCE][message.id] =
 | 
			
		||||
                    new ExampleTelemetrySeries([message.value]);
 | 
			
		||||
                (subscribers[message.id] || []).forEach(function (cb) {
 | 
			
		||||
                    cb(packaged);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                requestTelemetry: function (requests) {
 | 
			
		||||
                    var packaged = {},
 | 
			
		||||
                        relevantReqs = requests.filter(matchesSource);
 | 
			
		||||
 | 
			
		||||
                    // Package historical telemetry that has been received
 | 
			
		||||
                    function addToPackage(history) {
 | 
			
		||||
                        packaged[SOURCE][history.id] =
 | 
			
		||||
                            new ExampleTelemetrySeries(history.value);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Retrieve telemetry for a specific measurement
 | 
			
		||||
                    function handleRequest(request) {
 | 
			
		||||
                        var key = request.key;
 | 
			
		||||
                        return adapter.history(key).then(addToPackage);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    packaged[SOURCE] = {};
 | 
			
		||||
                    return $q.all(relevantReqs.map(handleRequest))
 | 
			
		||||
                        .then(function () { return packaged; });
 | 
			
		||||
                },
 | 
			
		||||
                subscribe: function (callback, requests) {
 | 
			
		||||
                    var keys = requests.filter(matchesSource)
 | 
			
		||||
                        .map(function (req) { return req.key; });
 | 
			
		||||
 | 
			
		||||
                    function notCallback(cb) {
 | 
			
		||||
                        return cb !== callback;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    function unsubscribe(key) {
 | 
			
		||||
                        subscribers[key] =
 | 
			
		||||
                            (subscribers[key] || []).filter(notCallback);
 | 
			
		||||
                        if (subscribers[key].length < 1) {
 | 
			
		||||
                            adapter.unsubscribe(key);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    keys.forEach(function (key) {
 | 
			
		||||
                        subscribers[key] = subscribers[key] || [];
 | 
			
		||||
                        adapter.subscribe(key);
 | 
			
		||||
                        subscribers[key].push(callback);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    return function () {
 | 
			
		||||
                        keys.forEach(unsubscribe);
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ExampleTelemetryProvider;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										23
									
								
								tutorials/telemetry/src/ExampleTelemetrySeries.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tutorials/telemetry/src/ExampleTelemetrySeries.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    function () {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        function ExampleTelemetrySeries(data) {
 | 
			
		||||
            return {
 | 
			
		||||
                getPointCount: function () {
 | 
			
		||||
                    return data.length;
 | 
			
		||||
                },
 | 
			
		||||
                getDomainValue: function (index) {
 | 
			
		||||
                    return (data[index] || {}).timestamp;
 | 
			
		||||
                },
 | 
			
		||||
                getRangeValue: function (index) {
 | 
			
		||||
                    return (data[index] || {}).value;
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ExampleTelemetrySeries;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										60
									
								
								tutorials/telemetry/src/ExampleTelemetryServerAdapter.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								tutorials/telemetry/src/ExampleTelemetryServerAdapter.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
define(
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        function ExampleTelemetryServerAdapter($q, wsUrl) {
 | 
			
		||||
            var ws = new WebSocket(wsUrl),
 | 
			
		||||
                histories = {},
 | 
			
		||||
                listeners = [],
 | 
			
		||||
                dictionary = $q.defer();
 | 
			
		||||
 | 
			
		||||
            // Handle an incoming message from the server
 | 
			
		||||
            ws.onmessage = function (event) {
 | 
			
		||||
                var message = JSON.parse(event.data);
 | 
			
		||||
 | 
			
		||||
                switch (message.type) {
 | 
			
		||||
                case "dictionary":
 | 
			
		||||
                    dictionary.resolve(message.value);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "history":
 | 
			
		||||
                    histories[message.id].resolve(message);
 | 
			
		||||
                    delete histories[message.id];
 | 
			
		||||
                    break;
 | 
			
		||||
                case "data":
 | 
			
		||||
                    listeners.forEach(function (listener) {
 | 
			
		||||
                        listener(message);
 | 
			
		||||
                    });
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Request dictionary once connection is established
 | 
			
		||||
            ws.onopen = function () {
 | 
			
		||||
                ws.send("dictionary");
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                dictionary: function () {
 | 
			
		||||
                    return dictionary.promise;
 | 
			
		||||
                },
 | 
			
		||||
                history: function (id) {
 | 
			
		||||
                    histories[id] = histories[id] || $q.defer();
 | 
			
		||||
                    ws.send("history " + id);
 | 
			
		||||
                    return histories[id].promise;
 | 
			
		||||
                },
 | 
			
		||||
                subscribe: function (id) {
 | 
			
		||||
                    ws.send("subscribe " + id);
 | 
			
		||||
                },
 | 
			
		||||
                unsubscribe: function (id) {
 | 
			
		||||
                    ws.send("unsubscribe " + id);
 | 
			
		||||
                },
 | 
			
		||||
                listen: function (callback) {
 | 
			
		||||
                    listeners.push(callback);
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ExampleTelemetryServerAdapter;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										3
									
								
								tutorials/todo/todo-dialog.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tutorials/todo/todo-dialog.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
<label>Description:
 | 
			
		||||
    <input type="text" class="description">
 | 
			
		||||
</label>
 | 
			
		||||
							
								
								
									
										5
									
								
								tutorials/todo/todo-task.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tutorials/todo/todo-task.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
<li>
 | 
			
		||||
    <input type="checkbox" class="example-task-checked">
 | 
			
		||||
    <span class="example-task-description">
 | 
			
		||||
    </span>
 | 
			
		||||
</li>
 | 
			
		||||
							
								
								
									
										9
									
								
								tutorials/todo/todo-toolbar.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tutorials/todo/todo-toolbar.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<div class="tool-bar btn-bar contents abs">
 | 
			
		||||
    <a class="s-btn labeled example-add">
 | 
			
		||||
        <span class="ui-symbol icon">+</span>
 | 
			
		||||
        <span class="title-label">Add Task</span>
 | 
			
		||||
    </a>
 | 
			
		||||
    <a class="s-btn example-remove">
 | 
			
		||||
        <span class="ui-symbol icon">Z</span>
 | 
			
		||||
    </a>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										29
									
								
								tutorials/todo/todo.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tutorials/todo/todo.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
.example-todo div.example-button-group {
 | 
			
		||||
    margin-top: 12px;
 | 
			
		||||
    margin-bottom: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.example-todo .example-button-group a {
 | 
			
		||||
    padding: 3px;
 | 
			
		||||
    margin: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.example-todo .example-button-group a.selected {
 | 
			
		||||
    border: 1px gray solid;
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
    background: #444;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.example-todo .example-task-completed .example-task-description {
 | 
			
		||||
    text-decoration: line-through;
 | 
			
		||||
    opacity: 0.75;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.example-todo .example-task-description.selected {
 | 
			
		||||
    background: #46A;
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.example-todo .example-message {
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								tutorials/todo/todo.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tutorials/todo/todo.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
<div class="example-todo">
 | 
			
		||||
    <div class="example-button-group">
 | 
			
		||||
        <a class="example-todo-button" data-filter="all">All</a>
 | 
			
		||||
        <a class="example-todo-button" data-filter="incomplete">Incomplete</a>
 | 
			
		||||
        <a class="example-todo-button" data-filter="complete">Complete</a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <ul class="example-todo-task-list">
 | 
			
		||||
    </ul>
 | 
			
		||||
 | 
			
		||||
    <div class="example-no-tasks">
 | 
			
		||||
        There are no tasks to show.
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										273
									
								
								tutorials/todo/todo.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								tutorials/todo/todo.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,273 @@
 | 
			
		||||
define([
 | 
			
		||||
    "text!./todo.html",
 | 
			
		||||
    "text!./todo-task.html",
 | 
			
		||||
    "text!./todo-toolbar.html",
 | 
			
		||||
    "text!./todo-dialog.html",
 | 
			
		||||
    "../../src/api/objects/object-utils",
 | 
			
		||||
    "zepto"
 | 
			
		||||
], function (todoTemplate, taskTemplate, toolbarTemplate, dialogTemplate, utils, $) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {mct.MCT} mct
 | 
			
		||||
     */
 | 
			
		||||
    return function todoPlugin(mct) {
 | 
			
		||||
        var todoType = new mct.Type({
 | 
			
		||||
            metadata: {
 | 
			
		||||
                label: "To-Do List",
 | 
			
		||||
                glyph: "2",
 | 
			
		||||
                description: "A list of things that need to be done."
 | 
			
		||||
            },
 | 
			
		||||
            initialize: function (model) {
 | 
			
		||||
                model.tasks = [
 | 
			
		||||
                    { description: "This is a task." }
 | 
			
		||||
                ];
 | 
			
		||||
            },
 | 
			
		||||
            creatable: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        function TodoView(domainObject) {
 | 
			
		||||
            this.tasks = domainObject.tasks;
 | 
			
		||||
            this.filterValue = "all";
 | 
			
		||||
 | 
			
		||||
            this.setTaskStatus = this.setTaskStatus.bind(this);
 | 
			
		||||
            this.selectTask = this.selectTask.bind(this);
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            this.mutableObject = mct.Objects.getMutable(domainObject);
 | 
			
		||||
            this.mutableObject.on('tasks', this.updateTasks.bind(this));
 | 
			
		||||
=======
 | 
			
		||||
            //If anything on object changes, re-render view
 | 
			
		||||
            this.mutableObject.on("*", this.objectChanged);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.show = function (container) {
 | 
			
		||||
            var self = this;
 | 
			
		||||
            this.destroy();
 | 
			
		||||
 | 
			
		||||
            self.$els = $(todoTemplate);
 | 
			
		||||
            self.$buttons = {
 | 
			
		||||
                all: self.$els.find('.example-todo-button-all'),
 | 
			
		||||
                incomplete: self.$els.find('.example-todo-button-incomplete'),
 | 
			
		||||
                complete: self.$els.find('.example-todo-button-complete')
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            $(container).empty().append(self.$els);
 | 
			
		||||
>>>>>>> origin/api-tutorials
 | 
			
		||||
 | 
			
		||||
            this.$el = $(todoTemplate);
 | 
			
		||||
            this.$emptyMessage = this.$el.find('.example-no-tasks');
 | 
			
		||||
            this.$taskList = this.$el.find('.example-todo-task-list');
 | 
			
		||||
            this.$el.on('click', '[data-filter]', this.updateFilter.bind(this));
 | 
			
		||||
            this.$el.on('change', 'li', this.setTaskStatus.bind(this));
 | 
			
		||||
            this.$el.on('click', '.example-task-description', this.selectTask.bind(this));
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            this.updateSelection = this.updateSelection.bind(this);
 | 
			
		||||
            mct.selection.on('change', this.updateSelection);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.show = function (container) {
 | 
			
		||||
            $(container).empty().append(this.$el);
 | 
			
		||||
            this.render();
 | 
			
		||||
=======
 | 
			
		||||
            self.initialize();
 | 
			
		||||
            self.objectChanged(this.domainObject);
 | 
			
		||||
 | 
			
		||||
            mct.selection.on('change', self.render);
 | 
			
		||||
>>>>>>> origin/api-tutorials
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.destroy = function () {
 | 
			
		||||
            this.mutableObject.stopListening();
 | 
			
		||||
            mct.selection.off('change', this.updateSelection);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.updateSelection = function (selection) {
 | 
			
		||||
            if (selection && selection.length) {
 | 
			
		||||
                this.selection = selection[0].index;
 | 
			
		||||
            } else {
 | 
			
		||||
                this.selection = -1;
 | 
			
		||||
            }
 | 
			
		||||
            this.render();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.updateTasks = function (tasks) {
 | 
			
		||||
            this.tasks = tasks;
 | 
			
		||||
            this.render();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.updateFilter = function (e) {
 | 
			
		||||
            this.filterValue = $(e.target).data('filter');
 | 
			
		||||
            this.render();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.setTaskStatus = function (e) {
 | 
			
		||||
            var $checkbox = $(e.target);
 | 
			
		||||
            var taskIndex = $checkbox.data('taskIndex');
 | 
			
		||||
            var completed = !!$checkbox.prop('checked');
 | 
			
		||||
            this.tasks[taskIndex].completed = completed;
 | 
			
		||||
            this.mutableObject.set('tasks[' + taskIndex + '].checked', completed);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.selectTask = function (e) {
 | 
			
		||||
            var taskIndex = $(e.target).data('taskIndex');
 | 
			
		||||
            mct.selection.clear();
 | 
			
		||||
            mct.selection.select({index: taskIndex});
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.getFilteredTasks = function () {
 | 
			
		||||
            return this.tasks.filter({
 | 
			
		||||
                all: function () {
 | 
			
		||||
                    return true;
 | 
			
		||||
                },
 | 
			
		||||
                incomplete: function (task) {
 | 
			
		||||
                    return !task.completed;
 | 
			
		||||
                },
 | 
			
		||||
                complete: function (task) {
 | 
			
		||||
                    return task.completed;
 | 
			
		||||
                }
 | 
			
		||||
            }[this.filterValue]);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoView.prototype.render = function () {
 | 
			
		||||
            var filteredTasks = this.getFilteredTasks();
 | 
			
		||||
            this.$emptyMessage.toggle(filteredTasks.length === 0);
 | 
			
		||||
            this.$taskList.empty();
 | 
			
		||||
            filteredTasks
 | 
			
		||||
                .forEach(function (task) {
 | 
			
		||||
                    var $taskEl = $(taskTemplate),
 | 
			
		||||
                        taskIndex = this.tasks.indexOf(task);
 | 
			
		||||
                    $taskEl.find('.example-task-checked')
 | 
			
		||||
                        .prop('checked', task.completed)
 | 
			
		||||
                        .attr('data-task-index', taskIndex);
 | 
			
		||||
                    $taskEl.find('.example-task-description')
 | 
			
		||||
                        .text(task.description)
 | 
			
		||||
                        .toggleClass('selected', taskIndex === this.selection)
 | 
			
		||||
                        .attr('data-task-index', taskIndex);
 | 
			
		||||
 | 
			
		||||
                    this.$taskList.append($taskEl);
 | 
			
		||||
                }, this);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        function TodoToolbarView(domainObject) {
 | 
			
		||||
            this.tasks = domainObject.tasks;
 | 
			
		||||
            this.mutableObject = mct.Objects.getMutable(domainObject);
 | 
			
		||||
 | 
			
		||||
            this.handleSelectionChange = this.handleSelectionChange.bind(this);
 | 
			
		||||
 | 
			
		||||
            this.mutableObject.on('tasks', this.updateTasks.bind(this));
 | 
			
		||||
            mct.selection.on('change', this.handleSelectionChange);
 | 
			
		||||
            this.$el = $(toolbarTemplate);
 | 
			
		||||
            this.$remove = this.$el.find('.example-remove');
 | 
			
		||||
            this.$el.on('click', '.example-add', this.addTask.bind(this));
 | 
			
		||||
            this.$el.on('click', '.example-remove', this.removeTask.bind(this));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TodoToolbarView.prototype.updateTasks = function (tasks) {
 | 
			
		||||
            this.tasks = tasks;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoToolbarView.prototype.addTask = function () {
 | 
			
		||||
            var $dialog = $(dialogTemplate),
 | 
			
		||||
                view = {
 | 
			
		||||
                    show: function (container) {
 | 
			
		||||
                        $(container).append($dialog);
 | 
			
		||||
                    },
 | 
			
		||||
                    destroy: function () {}
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
            mct.dialog(view, "Add a Task").then(function () {
 | 
			
		||||
                var description = $dialog.find('input').val();
 | 
			
		||||
                this.tasks.push({description: description});
 | 
			
		||||
                this.mutableObject.set('tasks', this.tasks);
 | 
			
		||||
            }.bind(this));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoToolbarView.prototype.removeTask = function () {
 | 
			
		||||
            if (this.selection >= 0) {
 | 
			
		||||
                this.tasks.splice(this.selection, 1);
 | 
			
		||||
                this.mutableObject.set('tasks', this.tasks);
 | 
			
		||||
                mct.selection.clear();
 | 
			
		||||
                this.render();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoToolbarView.prototype.show = function (container) {
 | 
			
		||||
            var self = this;
 | 
			
		||||
            this.destroy();
 | 
			
		||||
            this.$els = $(toolbarTemplate);
 | 
			
		||||
            this.render();
 | 
			
		||||
            $(container).append(this.$els);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoToolbarView.prototype.render = function () {
 | 
			
		||||
            var self = this;
 | 
			
		||||
            var $els = this.$els;
 | 
			
		||||
 | 
			
		||||
            self.mutableObject = mct.Objects.getMutable(this.domainObject);
 | 
			
		||||
 | 
			
		||||
            var $add = $els.find('a.example-add');
 | 
			
		||||
            var $remove = $els.find('a.example-remove');
 | 
			
		||||
 | 
			
		||||
            $add.on('click', function () {
 | 
			
		||||
                var $dialog = $(dialogTemplate),
 | 
			
		||||
                    view = {
 | 
			
		||||
                        show: function (container) {
 | 
			
		||||
                            $(container).append($dialog);
 | 
			
		||||
                        },
 | 
			
		||||
                        destroy: function () {}
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                new mct.Dialog(view, "Add a Task").show().then(function () {
 | 
			
		||||
                    var description = $dialog.find('input').val();
 | 
			
		||||
                    var tasks = self.mutableObject.get('tasks');
 | 
			
		||||
                    tasks.push({ description: description });
 | 
			
		||||
                    self.mutableObject.set('tasks', tasks);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
            $remove.on('click', function () {
 | 
			
		||||
                var index = mct.selection.selected()[0].index;
 | 
			
		||||
                if (index !== undefined) {
 | 
			
		||||
                    var tasks = self.mutableObject.get('tasks').filter(function (t, i) {
 | 
			
		||||
                        return i !== index;
 | 
			
		||||
                    });
 | 
			
		||||
                    self.mutableObject.set("tasks", tasks);
 | 
			
		||||
                    self.mutableObject.set("selected", undefined);
 | 
			
		||||
                    mct.selection.clear();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            self.$remove = $remove;
 | 
			
		||||
            self.handleSelectionChange();
 | 
			
		||||
            mct.selection.on('change', self.handleSelectionChange);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoToolbarView.prototype.handleSelectionChange = function () {
 | 
			
		||||
            var selected = mct.selection.selected();
 | 
			
		||||
            if (this.$remove) {
 | 
			
		||||
                this.$remove.toggle(selected.length > 0);
 | 
			
		||||
            }
 | 
			
		||||
            this.render();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TodoToolbarView.prototype.destroy = function () {
 | 
			
		||||
            mct.selection.off('change', this.handleSelectionChange);
 | 
			
		||||
            this.mutableObject.stopListening();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        mct.type('example.todo', todoType);
 | 
			
		||||
        mct.view(mct.regions.main, {
 | 
			
		||||
            view: function (domainObject) {
 | 
			
		||||
                return new TodoView(domainObject);
 | 
			
		||||
            },
 | 
			
		||||
            canView: todoType.check.bind(todoType)
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        mct.view(mct.regions.toolbar, {
 | 
			
		||||
            view: function (domainObject) {
 | 
			
		||||
                return new TodoToolbarView(domainObject);
 | 
			
		||||
            },
 | 
			
		||||
            canView: todoType.check.bind(todoType)
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return mct;
 | 
			
		||||
    };
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user