Merge pull request #1212 from nasa/api-1124b

[API] Integrate new API
This commit is contained in:
Andrew Henry 2016-10-12 12:33:44 -07:00 committed by GitHub
commit 7b218c7f02
54 changed files with 4322 additions and 96 deletions

285
API.md Normal file
View 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.

View File

@ -560,3 +560,132 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Almond
* Link: https://github.com/requirejs/almond
* Version: 0.3.3
* Author: jQuery Foundation
* Description: Lightweight RequireJS replacement for builds
#### License
Copyright jQuery Foundation and other contributors, https://jquery.org/
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/requirejs/almond
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
Copyright and related rights for sample code are waived via CC0. Sample
code is defined as all source code displayed within the prose of the
documentation.
CC0: http://creativecommons.org/publicdomain/zero/1.0/
====
Files located in the node_modules directory, and certain utilities used
to build or test the software in the test and dist directories, are
externally maintained libraries used by this software which have their own
licenses; we recommend you read them, as their terms may differ from the
terms above.
### Lodash
* Link: https://lodash.com
* Version: 3.10.1
* Author: Dojo Foundation
* Description: Utility functions
#### License
Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### EventEmitter3
* Link: https://github.com/primus/eventemitter3
* Version: 1.2.0
* Author: Arnout Kazemier
* Description: Event-driven programming support
#### License
The MIT License (MIT)
Copyright (c) 2014 Arnout Kazemier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -10,9 +10,24 @@ Try Open MCT now with our [live demo](https://openmct-demo.herokuapp.com/).
![Demo](https://nasa.github.io/openmct/static/res/images/Open-MCT.Browse.Layout.Mars-Weather-1.jpg)
## New API
A new API is currently under development that will deprecate a lot of the documentation currently in the docs directory, however Open MCT will remain compatible with the currently documented API. An updated set of tutorials is being developed with the new API, and progress on this task can be followed in the [associated pull request](https://github.com/nasa/openmct/pull/999). Any code in this branch should be considered experimental, and we welcome any feedback.
Differences between the two APIs include a move away from a declarative system of JSON configuration files towards an imperative system based on function calls. Developers will be able to extend and build on Open MCT by making direct function calls to a public API. Open MCT is also being refactored to minimize the dependencies that using Open MCT imposes on developers, such as the current requirement to use Angular JS.
A simpler, [easier-to-use API](https://nasa.github.io/openmct/docs/api/)
has been added to Open MCT. Changes in this
API include a move away from a declarative system of JSON configuration files
towards an imperative system based on function calls. Developers will be able
to extend and build on Open MCT by making direct function calls to a public
API. Open MCT is also being refactored to minimize the dependencies that using
Open MCT imposes on developers, such as the current requirement to use
AngularJS.
This new API has not yet been heavily used and is likely to contain defects.
You can help by trying it out, and reporting any issues you encounter
using our GitHub issue tracker. Such issues may include bugs, suggestions,
missing documentation, or even just requests for help if you're having
trouble.
We want Open MCT to be as easy to use, install, run, and develop for as
possible, and your feedback will help us get there!
## Building and Running Open MCT Locally

View File

@ -19,6 +19,9 @@
"comma-separated-values": "^3.6.4",
"FileSaver.js": "^0.0.2",
"zepto": "^1.1.6",
"eventemitter3": "^1.2.0",
"lodash": "3.10.1",
"almond": "~0.3.2",
"html2canvas": "^0.4.1"
}
}

View File

@ -9,26 +9,30 @@
Open MCT provides functionality out of the box, but it's also a platform for
building rich mission operations applications based on modern web technology.
The platform is configured declaratively, and defines conventions for
building on the provided capabilities by creating modular 'bundles' that
extend the platform at a variety of extension points. The details of how to
The platform is configured by plugins which extend the platform at a variety
of extension points. The details of how to
extend the platform are provided in the following documentation.
## Sections
* The [Architecture Overview](architecture/) describes the concepts used
throughout Open MCT, and gives a high level overview of the platform's design.
* The [Developer's Guide](guide/) goes into more detail about how to use the
platform and the functionality that it provides.
* The [Tutorials](tutorials/) give examples of extending the platform to add
functionality,
and integrate with data sources.
* The [API](api/) document is generated from inline documentation
using [JSDoc](http://usejsdoc.org/), and describes the JavaScript objects and
functions that make up the software platform.
* Finally, the [Development Process](process/) document describes the
* The [Development Process](process/) document describes the
Open MCT software development cycle.
## Legacy Documentation
As we transition to a new API, the following documentation for the old API
(which is supported during the transtion) may be useful as well:
* The [Architecture Overview](architecture/) describes the concepts used
throughout Open MCT, and gives a high level overview of the platform's design.
* The [Developer's Guide](guide/) goes into more detail about how to use the
platform and the functionality that it provides.
* The [Tutorials](tutorials/) give examples of extending the platform to add
functionality,
and integrate with data sources.

View File

@ -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": [

View File

@ -21,41 +21,34 @@
*****************************************************************************/
/*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',
main: 'openmct.js',
dist: 'dist',
assets: 'dist/assets',
reports: 'dist/reports',
scss: ['./platform/**/*.scss', './example/**/*.scss'],
scripts: [ 'main.js', 'platform/**/*.js', 'src/**/*.js' ],
assets: [
'./{example,platform}/**/*.{css,css.map,png,svg,ico,woff,eot,ttf}'
],
scripts: [ 'openmct.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
},
@ -64,7 +57,6 @@ var gulp = require('gulp'),
singleRun: true
},
sass: {
includePaths: bourbon.includePaths,
sourceComments: true
},
replace: {
@ -78,6 +70,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))
@ -87,10 +81,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))
@ -104,6 +104,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;
}),
@ -122,6 +125,8 @@ gulp.task('lint', function () {
});
gulp.task('checkstyle', function () {
var jscs = require('gulp-jscs');
return gulp.src(paths.scripts)
.pipe(jscs())
.pipe(jscs.reporter())
@ -129,18 +134,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 () {
@ -148,9 +155,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' ]);

View File

@ -28,12 +28,12 @@
<script src="bower_components/requirejs/require.js">
</script>
<script>
require(['main'], function (mct) {
require(['openmct'], function (openmct) {
require([
'./example/imagery/bundle',
'./example/eventGenerator/bundle',
'./example/generator/bundle'
], mct.run.bind(mct));
], openmct.start.bind(openmct));
});
</script>
<link rel="stylesheet" href="platform/commonUI/general/res/css/startup-base.css">
@ -47,7 +47,5 @@
<div class="l-splash-holder s-splash-holder">
<div class="l-splash s-splash"></div>
</div>
<div ng-view></div>
</body>
</html>

View File

@ -1,9 +1,9 @@
{
"source": {
"include": [
"platform/"
"src/"
],
"includePattern": "platform/.+\\.js$",
"includePattern": "src/.+\\.js$",
"excludePattern": ".+\\Spec\\.js$|lib/.+"
},
"plugins": [

View File

@ -37,9 +37,11 @@ module.exports = function(config) {
{pattern: 'bower_components/**/*.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'example/**/*.js', included: false},
{pattern: 'example/**/*.json', included: false},
{pattern: 'platform/**/*.js', included: false},
{pattern: 'warp/**/*.js', included: false},
{pattern: 'platform/**/*.html', included: false},
{pattern: 'src/**/*.html', included: false},
'test-main.js'
],

View File

@ -27,6 +27,7 @@ requirejs.config({
"angular": "bower_components/angular/angular.min",
"angular-route": "bower_components/angular-route/angular-route.min",
"csv": "bower_components/comma-separated-values/csv.min",
"EventEmitter": "bower_components/eventemitter3/index",
"es6-promise": "bower_components/es6-promise/es6-promise.min",
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
"moment": "bower_components/moment/moment",
@ -35,7 +36,8 @@ requirejs.config({
"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": {
@ -44,6 +46,9 @@ requirejs.config({
"angular-route": {
"deps": ["angular"]
},
"EventEmitter": {
"exports": "EventEmitter"
},
"html2canvas": {
"exports": "html2canvas"
},
@ -55,54 +60,25 @@ requirejs.config({
},
"zepto": {
"exports": "Zepto"
},
"lodash": {
"exports": "lodash"
}
}
});
define([
'./platform/framework/src/Main',
'legacyRegistry',
'./src/defaultRegistry',
'./src/MCT'
], function (Main, defaultRegistry, MCT) {
var openmct = 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/fixed/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);
}
};
openmct.legacyRegistry = defaultRegistry;
openmct.on('start', function () {
return new Main().run(defaultRegistry);
});
return openmct;
});

View File

@ -48,7 +48,7 @@
"test": "karma start --single-run",
"jshint": "jshint platform example",
"watch": "karma start",
"jsdoc": "jsdoc -c jsdoc.json -r -d target/docs/api",
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
"otherdoc": "node docs/gendocs.js --in docs/src --out target/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'",
"docs": "npm run jsdoc ; npm run otherdoc",
"prepublish": "node ./node_modules/bower/bin/bower install && node ./node_modules/gulp/bin/gulp.js install"

View File

@ -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;

View File

@ -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
View 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;
});

View 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
View 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"
}
]
}
});
});

View 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;
});

View 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;
}
);

View 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;
});

View 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;
});

View 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;
});

View 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;
});

View 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;
});

View 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;
}
);

View 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
View 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;
});

View 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
View 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
View 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
};
});

View 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;
});

View 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;
});

View 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;
});

View 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;
});

View 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;
});

View 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
View 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"
]
}
]
}
});
});

View 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
};
});

View 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();
});

View 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;
});

View 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'
]
}
]
}
});
});

View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,3 @@
return require('main');
}));

View 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;
});

View 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;
});

View 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;
});

View 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
View 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
View 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;
});

View File

@ -53,6 +53,7 @@ requirejs.config({
"angular": "bower_components/angular/angular.min",
"angular-route": "bower_components/angular-route/angular-route.min",
"csv": "bower_components/comma-separated-values/csv.min",
"EventEmitter": "bower_components/eventemitter3/index",
"es6-promise": "bower_components/es6-promise/es6-promise.min",
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
"moment": "bower_components/moment/moment",
@ -61,7 +62,8 @@ requirejs.config({
"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": {
@ -71,6 +73,9 @@ requirejs.config({
"angular-route": {
"deps": [ "angular" ]
},
"EventEmitter": {
"exports": "EventEmitter"
},
"moment-duration-format": {
"deps": [ "moment" ]
},
@ -79,6 +84,9 @@ requirejs.config({
},
"zepto": {
"exports": "Zepto"
},
"lodash": {
"exports": "lodash"
}
},