Merge remote-tracking branch 'github/master' into open477

Resolve conflicts to complete merge of #477

Conflicts:
	platform/commonUI/general/bundle.json
	platform/commonUI/themes/espresso/res/css/theme-espresso.css
	platform/commonUI/themes/snow/res/css/theme-snow.css
This commit is contained in:
Victor Woeltjen
2016-01-27 12:53:46 -08:00
225 changed files with 10800 additions and 5816 deletions

View File

@ -0,0 +1,105 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "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.
*****************************************************************************/
/*global define, window, requirejs*/
define([
'require',
'./Constants',
'./FrameworkInitializer',
'./LogLevel',
'./load/BundleLoader',
'./resolve/ImplementationLoader',
'./resolve/ExtensionResolver',
'./resolve/BundleResolver',
'./resolve/RequireConfigurator',
'./register/CustomRegistrars',
'./register/ExtensionRegistrar',
'./register/ExtensionSorter',
'./bootstrap/ApplicationBootstrapper'
], function (
require,
Constants,
FrameworkInitializer,
LogLevel,
BundleLoader,
ImplementationLoader,
ExtensionResolver,
BundleResolver,
RequireConfigurator,
CustomRegistrars,
ExtensionRegistrar,
ExtensionSorter,
ApplicationBootstrapper
) {
'use strict';
function FrameworkLayer($http, $log) {
this.$http = $http;
this.$log = $log;
}
FrameworkLayer.prototype.initializeApplication = function (
angular,
legacyRegistry,
logLevel
) {
var $http = this.$http,
$log = this.$log,
app = angular.module(Constants.MODULE_NAME, ["ngRoute"]),
loader = new BundleLoader($http, $log, legacyRegistry),
resolver = new BundleResolver(
new ExtensionResolver(
new ImplementationLoader(require),
$log
),
new RequireConfigurator(requirejs),
$log
),
registrar = new ExtensionRegistrar(
app,
new CustomRegistrars(app, $log),
new ExtensionSorter($log),
$log
),
bootstrapper = new ApplicationBootstrapper(
angular,
window.document,
$log
),
initializer = new FrameworkInitializer(
loader,
resolver,
registrar,
bootstrapper
);
// Apply logging levels; this must be done now, before the
// first log statement.
new LogLevel(logLevel).configure(app, $log);
// Initialize the application
$log.info("Initializing application.");
initializer.runApplication(Constants.BUNDLE_LISTING_FILE);
};
return FrameworkLayer;
});

View File

@ -90,12 +90,10 @@ define(
}
decorate($log);
app.config(function ($provide) {
$provide.decorator('$log', function ($delegate) {
decorate($delegate);
return $delegate;
});
});
app.decorator('$log', ['$delegate', function ($delegate) {
decorate($delegate);
return $delegate;
}]);
};
return LogLevel;

View File

@ -22,12 +22,9 @@
/*global define, window, requirejs*/
requirejs.config({
"shim": {
"../lib/angular.min": {
"exports": "angular"
},
"../lib/angular-route.min": {
"deps": [ "../lib/angular.min" ]
shim: {
'platform/framework/lib/angular-route.min': {
deps: [ 'angular' ]
}
}
});
@ -41,97 +38,42 @@ define(
[
'require',
'../lib/es6-promise-2.0.0.min',
'../lib/angular.min',
'../lib/angular-route.min',
'./Constants',
'./FrameworkInitializer',
'./LogLevel',
'./load/BundleLoader',
'./resolve/ImplementationLoader',
'./resolve/ExtensionResolver',
'./resolve/BundleResolver',
'./resolve/RequireConfigurator',
'./register/CustomRegistrars',
'./register/ExtensionRegistrar',
'./register/ExtensionSorter',
'./bootstrap/ApplicationBootstrapper'
'./FrameworkLayer',
'angular',
'../lib/angular-route.min'
],
function (
require,
es6promise,
angular,
angularRoute,
Constants,
FrameworkInitializer,
LogLevel,
BundleLoader,
ImplementationLoader,
ExtensionResolver,
BundleResolver,
RequireConfigurator,
CustomRegistrars,
ExtensionRegistrar,
ExtensionSorter,
ApplicationBootstrapper
FrameworkLayer,
angular
) {
"use strict";
// Get a reference to Angular's injector, so we can get $http and $log
// services, which are useful to the framework layer.
var injector = angular.injector(['ng']);
// Look up log level from query string
function logLevel() {
var match = /[?&]log=([a-z]+)/.exec(window.location.search);
return match ? match[1] : "";
function Main() {
}
// Polyfill Promise, in case browser does not natively provide Promise
window.Promise = window.Promise || es6promise.Promise;
Main.prototype.run = function (legacyRegistry) {
// Get a reference to Angular's injector, so we can get $http and $log
// services, which are useful to the framework layer.
var injector = angular.injector(['ng']);
// Wire up framework layer components necessary to complete framework
// initialization phases.
function initializeApplication($http, $log) {
var app = angular.module(Constants.MODULE_NAME, ["ngRoute"]),
loader = new BundleLoader($http, $log),
resolver = new BundleResolver(
new ExtensionResolver(
new ImplementationLoader(require),
$log
),
new RequireConfigurator(requirejs),
$log
),
registrar = new ExtensionRegistrar(
app,
new CustomRegistrars(app, $log),
new ExtensionSorter($log),
$log
),
bootstrapper = new ApplicationBootstrapper(
angular,
window.document,
$log
),
initializer = new FrameworkInitializer(
loader,
resolver,
registrar,
bootstrapper
);
// Look up log level from query string
function logLevel() {
var match = /[?&]log=([a-z]+)/.exec(window.location.search);
return match ? match[1] : "";
}
// Apply logging levels; this must be done now, before the
// first log statement.
new LogLevel(logLevel()).configure(app, $log);
// Polyfill Promise, in case browser does not natively provide Promise
window.Promise = window.Promise || es6promise.Promise;
// Initialize the application
$log.info("Initializing application.");
initializer.runApplication(Constants.BUNDLE_LISTING_FILE);
}
// Reconfigure base url, since bundle paths will all be relative
// to the root now.
requirejs.config({"baseUrl": ""});
injector.instantiate(['$http', '$log', FrameworkLayer])
.initializeApplication(angular, legacyRegistry, logLevel());
};
// Reconfigure base url, since bundle paths will all be relative
// to the root now.
requirejs.config({ "baseUrl": "" });
injector.invoke(['$http', '$log', initializeApplication]);
return Main;
}
);

View File

@ -59,7 +59,7 @@ define(
$log = this.$log;
$log.info("Bootstrapping application " + (app || {}).name);
angular.element(document).ready(function () {
angular.bootstrap(document, [app.name]);
angular.bootstrap(document, [app.name], { strictDi: true });
});
};

View File

@ -44,10 +44,10 @@ define(
* @param $http Angular's HTTP requester
* @param $log Angular's logging service
*/
function BundleLoader($http, $log) {
function BundleLoader($http, $log, legacyRegistry) {
this.$http = $http;
this.$log = $log;
this.legacyRegistry = legacyRegistry;
}
/**
@ -60,7 +60,8 @@ define(
*/
BundleLoader.prototype.loadBundles = function (bundles) {
var $http = this.$http,
$log = this.$log;
$log = this.$log,
legacyRegistry = this.legacyRegistry;
// Utility function; load contents of JSON file using $http
function getJSON(file) {
@ -97,15 +98,30 @@ define(
// Load an individual bundle, as a Bundle object.
// Returns undefined if the definition could not be loaded.
function loadBundle(bundlePath) {
if (legacyRegistry.contains(bundlePath)) {
return Promise.resolve(new Bundle(
bundlePath,
legacyRegistry.get(bundlePath)
));
}
return loadBundleDefinition(bundlePath).then(function (definition) {
return definition && (new Bundle(bundlePath, definition));
});
}
// Used to filter out redundant bundles
function unique(element, index, array) {
return array.indexOf(element) === index;
}
// Load all named bundles from the array, returned as an array
// of Bundle objects.
function loadBundlesFromArray(bundleArray) {
var bundlePromises = bundleArray.map(loadBundle);
var bundlePromises = legacyRegistry.list()
.concat(bundleArray)
.filter(unique)
.map(loadBundle);
return Promise.all(bundlePromises)
.then(filterBundles);
@ -114,12 +130,25 @@ define(
// Load all bundles named in the referenced file. The file is
// presumed to be a JSON file
function loadBundlesFromFile(listFile) {
return getJSON(listFile).then(loadBundlesFromArray);
function handleError(err) {
$log.info([
"No external bundles loaded;",
"could not load bundle listing in",
listFile,
"due to error",
err.status,
err.statusText
].join(' '));
return loadBundlesFromArray([]);
}
return getJSON(listFile)
.then(loadBundlesFromArray, handleError);
}
return Array.isArray(bundles) ? loadBundlesFromArray(bundles) :
(typeof bundles === 'string') ? loadBundlesFromFile(bundles) :
Promise.reject(new Error(INVALID_ARGUMENT_MESSAGE));
(typeof bundles === 'string') ? loadBundlesFromFile(bundles) :
Promise.reject(new Error(INVALID_ARGUMENT_MESSAGE));
};
return BundleLoader;

View File

@ -133,9 +133,29 @@ define(
* @returns {string} path to implementation, or undefined
*/
Extension.prototype.getImplementationPath = function () {
return this.definition.implementation ?
this.bundle.getSourcePath(this.definition.implementation) :
undefined;
return (this.hasImplementation() && !this.hasImplementationValue()) ?
this.bundle.getSourcePath(this.definition.implementation) :
undefined;
};
/**
* Check if an extension has an actual implementation value
* (and not just a path to an implementation) defined.
* @returns {function} the constructor for this extension instance
*/
Extension.prototype.getImplementationValue = function () {
return typeof this.definition.implementation === 'function' ?
this.definition.implementation :
undefined;
};
/**
* Check if an extension has an actual implementation value
* (and not just a path to an implementation) defined.
* @returns {boolean} true if a value is available
*/
Extension.prototype.hasImplementationValue = function () {
return typeof this.definition.implementation === 'function';
};
/**

View File

@ -61,8 +61,9 @@ define(
$log = this.$log;
function loadImplementation(extension) {
var implPath = extension.getImplementationPath(),
implPromise = loader.load(implPath),
var implPromise = extension.hasImplementationValue() ?
Promise.resolve(extension.getImplementationValue()) :
loader.load(extension.getImplementationPath()),
definition = extension.getDefinition();
// Wrap a constructor function (to avoid modifying the original)
@ -117,13 +118,15 @@ define(
return extension.getDefinition();
}
// Log that loading has begun
$log.info([
"Loading implementation ",
implPath,
" for extension ",
extension.getLogName()
].join(""));
if (!extension.hasImplementationValue()) {
// Log that loading has begun
$log.info([
"Loading implementation ",
extension.getImplementationPath(),
" for extension ",
extension.getLogName()
].join(""));
}
return implPromise.then(attachDefinition, handleError);
}