mirror of
https://github.com/nasa/openmct.git
synced 2025-02-05 10:39:15 +00:00
[Code Style] Use prototypes in framework layer
WTD-1482
This commit is contained in:
parent
7fe866060b
commit
edca2a9f03
@ -40,24 +40,36 @@ define(
|
||||
*
|
||||
* @memberof platform/framework
|
||||
* @constructor
|
||||
* @param {BundleLoader} loader
|
||||
* @param {BundleResolver} resolver
|
||||
* @param {ExtensionRegistrar} registrar
|
||||
* @param {ApplicationBootstrapper} bootstrapper
|
||||
* @param {platform/framework.BundleLoader} loader
|
||||
* @param {platform/framework.BundleResolver} resolver
|
||||
* @param {platform/framework.ExtensionRegistrar} registrar
|
||||
* @param {platform/framework.ApplicationBootstrapper} bootstrapper
|
||||
*/
|
||||
function FrameworkInitializer(loader, resolver, registrar, bootstrapper) {
|
||||
|
||||
return {
|
||||
runApplication: function (bundleList) {
|
||||
return loader.loadBundles(bundleList)
|
||||
.then(resolver.resolveBundles)
|
||||
.then(registrar.registerExtensions)
|
||||
.then(bootstrapper.bootstrap);
|
||||
this.loader = loader;
|
||||
this.resolver = resolver;
|
||||
this.registrar = registrar;
|
||||
this.bootstrapper = bootstrapper;
|
||||
}
|
||||
|
||||
function bind(method, thisArg) {
|
||||
return function () {
|
||||
return method.apply(thisArg, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the application defined by this set of bundles.
|
||||
* @param bundleList
|
||||
* @returns {*}
|
||||
*/
|
||||
FrameworkInitializer.prototype.runApplication = function (bundleList) {
|
||||
return this.loader.loadBundles(bundleList)
|
||||
.then(bind(this.resolver.resolveBundles, this.resolver))
|
||||
.then(bind(this.registrar.registerExtensions, this.registrar))
|
||||
.then(bind(this.bootstrapper.bootstrap, this.bootstrapper));
|
||||
};
|
||||
|
||||
return FrameworkInitializer;
|
||||
}
|
||||
);
|
||||
|
@ -53,26 +53,14 @@ define(
|
||||
*/
|
||||
function LogLevel(level) {
|
||||
// Find the numeric level associated with the string
|
||||
var index = LOG_LEVELS.indexOf(level);
|
||||
|
||||
// Replace logging methods with no-ops, if they are
|
||||
// not of an appropriate level.
|
||||
function decorate(log) {
|
||||
LOG_LEVELS.forEach(function (m, i) {
|
||||
// Determine applicability based on index
|
||||
// (since levels are in descending order)
|
||||
if (i > index) {
|
||||
log[m] = NOOP;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.index = LOG_LEVELS.indexOf(level);
|
||||
|
||||
// Default to 'warn' level if unspecified
|
||||
if (index < 0) {
|
||||
index = 1;
|
||||
if (this.index < 0) {
|
||||
this.index = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Configure logging to suppress log output if it is
|
||||
* not of an appropriate level. Both the Angular app
|
||||
@ -86,7 +74,21 @@ define(
|
||||
* @param $log Angular's $log (also configured)
|
||||
* @memberof platform/framework.LogLevel#
|
||||
*/
|
||||
configure: function (app, $log) {
|
||||
LogLevel.prototype.configure = function (app, $log) {
|
||||
var index = this.index;
|
||||
|
||||
// Replace logging methods with no-ops, if they are
|
||||
// not of an appropriate level.
|
||||
function decorate(log) {
|
||||
LOG_LEVELS.forEach(function (m, i) {
|
||||
// Determine applicability based on index
|
||||
// (since levels are in descending order)
|
||||
if (i > index) {
|
||||
log[m] = NOOP;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
decorate($log);
|
||||
app.config(function ($provide) {
|
||||
$provide.decorator('$log', function ($delegate) {
|
||||
@ -94,9 +96,7 @@ define(
|
||||
return $delegate;
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return LogLevel;
|
||||
}
|
||||
|
@ -42,24 +42,26 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function ApplicationBootstrapper(angular, document, $log) {
|
||||
return {
|
||||
this.angular = angular;
|
||||
this.document = document;
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap the application.
|
||||
*
|
||||
* @method
|
||||
* @memberof ApplicationBootstrapper#
|
||||
* @param {angular.Module} app the Angular application to
|
||||
* bootstrap
|
||||
* @memberof platform/framework.ApplicationBootstrapper#
|
||||
*/
|
||||
bootstrap: function (app) {
|
||||
ApplicationBootstrapper.prototype.bootstrap = function (app) {
|
||||
var angular = this.angular,
|
||||
document = this.document,
|
||||
$log = this.$log;
|
||||
$log.info("Bootstrapping application " + (app || {}).name);
|
||||
angular.element(document).ready(function () {
|
||||
angular.bootstrap(document, [app.name]);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ApplicationBootstrapper;
|
||||
}
|
||||
|
@ -56,13 +56,7 @@ define(
|
||||
function Bundle(path, bundleDefinition) {
|
||||
// Start with defaults
|
||||
var definition = Object.create(Constants.DEFAULT_BUNDLE),
|
||||
logName = path,
|
||||
self;
|
||||
|
||||
// Utility function for resolving paths in this bundle
|
||||
function resolvePath(elements) {
|
||||
return [path].concat(elements || []).join(Constants.SEPARATOR);
|
||||
}
|
||||
logName = path;
|
||||
|
||||
// Override defaults with specifics from bundle definition
|
||||
Object.keys(bundleDefinition).forEach(function (k) {
|
||||
@ -81,135 +75,138 @@ define(
|
||||
logName += ")";
|
||||
}
|
||||
|
||||
self = {
|
||||
this.path = path;
|
||||
this.definition = definition;
|
||||
this.logName = logName;
|
||||
}
|
||||
|
||||
|
||||
// Utility function for resolving paths in this bundle
|
||||
Bundle.prototype.resolvePath = function (elements) {
|
||||
var path = this.path;
|
||||
return [path].concat(elements || []).join(Constants.SEPARATOR);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the path to this bundle.
|
||||
* @memberof Bundle#
|
||||
* @returns {string}
|
||||
* @memberof platform/framework.Bundle#
|
||||
* @returns {string} path to this bundle;
|
||||
*/
|
||||
getPath: function () {
|
||||
return path;
|
||||
},
|
||||
Bundle.prototype.getPath = function () {
|
||||
return this.path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the path to this bundle's source folder. If an
|
||||
* argument is provided, the path will be to the source
|
||||
* file within the bundle's source file.
|
||||
*
|
||||
* @memberof Bundle#
|
||||
* @param {string} [sourceFile] optionally, give a path to
|
||||
* a specific source file in the bundle.
|
||||
* @returns {string}
|
||||
* @memberof platform/framework.Bundle#
|
||||
* @returns {string} path to the source folder (or to the
|
||||
* source file within it)
|
||||
*/
|
||||
getSourcePath: function (sourceFile) {
|
||||
Bundle.prototype.getSourcePath = function (sourceFile) {
|
||||
var subpath = sourceFile ?
|
||||
[ definition.sources, sourceFile ] :
|
||||
[ definition.sources ];
|
||||
[ this.definition.sources, sourceFile ] :
|
||||
[ this.definition.sources ];
|
||||
|
||||
return this.resolvePath(subpath);
|
||||
};
|
||||
|
||||
return resolvePath(subpath);
|
||||
},
|
||||
/**
|
||||
* Get the path to this bundle's resource folder. If an
|
||||
* argument is provided, the path will be to the resource
|
||||
* file within the bundle's resource file.
|
||||
*
|
||||
* @memberof Bundle#
|
||||
* @param {string} [resourceFile] optionally, give a path to
|
||||
* a specific resource file in the bundle.
|
||||
* @returns {string}
|
||||
* @memberof platform/framework.Bundle#
|
||||
* @returns {string} path to the resource folder (or to the
|
||||
* resource file within it)
|
||||
*/
|
||||
getResourcePath: function (resourceFile) {
|
||||
Bundle.prototype.getResourcePath = function (resourceFile) {
|
||||
var subpath = resourceFile ?
|
||||
[ definition.resources, resourceFile ] :
|
||||
[ definition.resources ];
|
||||
[ this.definition.resources, resourceFile ] :
|
||||
[ this.definition.resources ];
|
||||
|
||||
return this.resolvePath(subpath);
|
||||
};
|
||||
|
||||
return resolvePath(subpath);
|
||||
},
|
||||
/**
|
||||
* Get the path to this bundle's library folder. If an
|
||||
* argument is provided, the path will be to the library
|
||||
* file within the bundle's resource file.
|
||||
*
|
||||
* @memberof Bundle#
|
||||
* @param {string} [libraryFile] optionally, give a path to
|
||||
* a specific library file in the bundle.
|
||||
* @returns {string}
|
||||
* @memberof platform/framework.Bundle#
|
||||
* @returns {string} path to the resource folder (or to the
|
||||
* resource file within it)
|
||||
*/
|
||||
getLibraryPath: function (libraryFile) {
|
||||
Bundle.prototype.getLibraryPath = function (libraryFile) {
|
||||
var subpath = libraryFile ?
|
||||
[ definition.libraries, libraryFile ] :
|
||||
[ definition.libraries ];
|
||||
[ this.definition.libraries, libraryFile ] :
|
||||
[ this.definition.libraries ];
|
||||
|
||||
return this.resolvePath(subpath);
|
||||
};
|
||||
|
||||
return resolvePath(subpath);
|
||||
},
|
||||
/**
|
||||
* Get library configuration for this bundle. This is read
|
||||
* from the bundle's definition; if the bundle is well-formed,
|
||||
* it will resemble a require.config object.
|
||||
* @memberof Bundle#
|
||||
* @returns {object}
|
||||
* @memberof platform/framework.Bundle#
|
||||
* @returns {object} library configuration
|
||||
*/
|
||||
getConfiguration: function () {
|
||||
return definition.configuration || {};
|
||||
},
|
||||
Bundle.prototype.getConfiguration = function () {
|
||||
return this.definition.configuration || {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a log-friendly name for this bundle; this will
|
||||
* include both the key (machine-readable name for this
|
||||
* bundle) and the name (human-readable name for this
|
||||
* bundle.)
|
||||
* @returns {string} log-friendly name for this bundle
|
||||
* @memberof platform/framework.Bundle#
|
||||
*/
|
||||
getLogName: function () {
|
||||
return logName;
|
||||
},
|
||||
Bundle.prototype.getLogName = function () {
|
||||
return this.logName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all extensions exposed by this bundle of a given
|
||||
* category.
|
||||
*
|
||||
* @param category
|
||||
* @memberof Bundle#
|
||||
* @returns {Array}
|
||||
* @memberof platform/framework.Bundle#
|
||||
* @param {string} category name of the extension category
|
||||
* @returns {Array} extension definitions of that cataegory
|
||||
*/
|
||||
getExtensions: function (category) {
|
||||
var extensions = definition.extensions[category] || [];
|
||||
Bundle.prototype.getExtensions = function (category) {
|
||||
var extensions = this.definition.extensions[category] || [],
|
||||
self = this;
|
||||
|
||||
return extensions.map(function objectify(extDefinition) {
|
||||
return new Extension(self, category, extDefinition);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a list of all categories of extension exposed by
|
||||
* this bundle.
|
||||
* Get a list of all extension categories exposed by this bundle.
|
||||
*
|
||||
* @memberof Bundle#
|
||||
* @returns {Array}
|
||||
* @memberof platform/framework.Bundle#
|
||||
* @returns {string[]} the extension categories
|
||||
*/
|
||||
getExtensionCategories: function () {
|
||||
return Object.keys(definition.extensions);
|
||||
},
|
||||
Bundle.prototype.getExtensionCategories = function () {
|
||||
return Object.keys(this.definition.extensions);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the plain definition of this bundle, as read from
|
||||
* its JSON declaration.
|
||||
*
|
||||
* @memberof Bundle#
|
||||
* @returns {BundleDefinition} the raw definition of this bundle
|
||||
* @memberof platform/framework.Bundle#
|
||||
* @returns {platform/framework.BundleDefinition} the raw
|
||||
* definition of this bundle
|
||||
*/
|
||||
getDefinition: function () {
|
||||
return definition;
|
||||
}
|
||||
Bundle.prototype.getDefinition = function () {
|
||||
return this.definition;
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
return Bundle;
|
||||
}
|
||||
);
|
||||
|
@ -41,10 +41,26 @@ define(
|
||||
*
|
||||
* @memberof platform/framework
|
||||
* @constructor
|
||||
* @param {object} $http Angular's HTTP requester
|
||||
* @param {object} $log Angular's logging service
|
||||
* @param $http Angular's HTTP requester
|
||||
* @param $log Angular's logging service
|
||||
*/
|
||||
function BundleLoader($http, $log) {
|
||||
this.$http = $http;
|
||||
this.$log = $log;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a group of bundles, to be used to constitute the
|
||||
* application by later framework initialization phases.
|
||||
*
|
||||
* @param {string|string[]} an array of bundle names to load, or
|
||||
* the name of a JSON file containing that array
|
||||
* @returns {Promise.<Bundle[]>} a promise for the loaded bundles
|
||||
*/
|
||||
BundleLoader.prototype.loadBundles = function (bundles) {
|
||||
var $http = this.$http,
|
||||
$log = this.$log;
|
||||
|
||||
// Utility function; load contents of JSON file using $http
|
||||
function getJSON(file) {
|
||||
@ -101,31 +117,10 @@ define(
|
||||
return getJSON(listFile).then(loadBundlesFromArray);
|
||||
}
|
||||
|
||||
// Load all indicated bundles. If the argument is an array,
|
||||
// this is taken to be a list of all bundles to load; if it
|
||||
// is a string, then it is treated as the name of a JSON
|
||||
// file containing the list of bundles to load.
|
||||
function loadBundles(bundles) {
|
||||
return Array.isArray(bundles) ? loadBundlesFromArray(bundles) :
|
||||
(typeof bundles === 'string') ? loadBundlesFromFile(bundles) :
|
||||
Promise.reject(new Error(INVALID_ARGUMENT_MESSAGE));
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
/**
|
||||
* Load a group of bundles, to be used to constitute the
|
||||
* application by later framework initialization phases.
|
||||
*
|
||||
* @memberof BundleLoader#
|
||||
* @param {string|string[]} an array of bundle names to load, or
|
||||
* the name of a JSON file containing that array
|
||||
* @returns {Promise.<Bundle[]>}
|
||||
* @memberof platform/framework.BundleLoader#
|
||||
*/
|
||||
loadBundles: loadBundles
|
||||
};
|
||||
}
|
||||
|
||||
return BundleLoader;
|
||||
}
|
||||
|
@ -78,37 +78,41 @@ define(
|
||||
// Attach bundle metadata
|
||||
extensionDefinition.bundle = bundle.getDefinition();
|
||||
|
||||
return {
|
||||
this.logName = logName;
|
||||
this.bundle = bundle;
|
||||
this.category = category;
|
||||
this.definition = definition;
|
||||
this.extensionDefinition = extensionDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the machine-readable identifier for this extension.
|
||||
*
|
||||
* @returns {string}
|
||||
* @memberof platform/framework.Extension#
|
||||
* @returns {string} the identifier for this extension
|
||||
*/
|
||||
getKey: function () {
|
||||
return definition.key || "undefined";
|
||||
},
|
||||
Extension.prototype.getKey = function () {
|
||||
return this.definition.key || "undefined";
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the bundle which declared this extension.
|
||||
*
|
||||
* @memberof Extension#
|
||||
* @returns {Bundle}
|
||||
* @memberof platform/framework.Extension#
|
||||
* @returns {Bundle} the declaring bundle
|
||||
*/
|
||||
getBundle: function () {
|
||||
return bundle;
|
||||
},
|
||||
Extension.prototype.getBundle = function () {
|
||||
return this.bundle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the category into which this extension falls.
|
||||
* (e.g. "directives")
|
||||
*
|
||||
* @memberof Extension#
|
||||
* @returns {string}
|
||||
* @memberof platform/framework.Extension#
|
||||
* @returns {string} the extension category
|
||||
*/
|
||||
getCategory: function () {
|
||||
return category;
|
||||
},
|
||||
Extension.prototype.getCategory = function () {
|
||||
return this.category;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether or not this extension should have an
|
||||
* associated implementation module which may need to
|
||||
@ -116,36 +120,36 @@ define(
|
||||
*
|
||||
* @returns {boolean} true if an implementation separate
|
||||
* from this definition should also be loaded
|
||||
* @memberof platform/framework.Extension#
|
||||
*/
|
||||
hasImplementation: function () {
|
||||
return definition.implementation !== undefined;
|
||||
},
|
||||
Extension.prototype.hasImplementation = function () {
|
||||
return this.definition.implementation !== undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the path to the AMD module which implements this
|
||||
* extension. Will return undefined if there is no
|
||||
* implementation associated with this extension.
|
||||
*
|
||||
* @memberof Extension#
|
||||
* @returns {string} path to implementation, or undefined
|
||||
* @memberof platform/framework.Extension#
|
||||
*/
|
||||
getImplementationPath: function () {
|
||||
return definition.implementation ?
|
||||
bundle.getSourcePath(definition.implementation) :
|
||||
Extension.prototype.getImplementationPath = function () {
|
||||
return this.definition.implementation ?
|
||||
this.bundle.getSourcePath(this.definition.implementation) :
|
||||
undefined;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a log-friendly name for this extension; this will
|
||||
* include both the key (machine-readable name for this
|
||||
* extension) and the name (human-readable name for this
|
||||
* extension.)
|
||||
*
|
||||
* @returns {string} log-friendly name for this extension
|
||||
* @memberof platform/framework.Extension#
|
||||
*/
|
||||
getLogName: function () {
|
||||
return logName;
|
||||
},
|
||||
Extension.prototype.getLogName = function () {
|
||||
return this.logName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the plain definition of the extension.
|
||||
*
|
||||
@ -153,18 +157,13 @@ define(
|
||||
* field which points back to the bundle which defined the
|
||||
* extension, as a convenience.
|
||||
*
|
||||
* @memberof Extension#
|
||||
* @returns {ExtensionDefinition} the plain definition of
|
||||
* this extension, as read from the bundle
|
||||
* declaration.
|
||||
* @memberof platform/framework.Extension#
|
||||
*/
|
||||
getDefinition: function () {
|
||||
return extensionDefinition;
|
||||
}
|
||||
|
||||
Extension.prototype.getDefinition = function () {
|
||||
return this.extensionDefinition;
|
||||
};
|
||||
}
|
||||
|
||||
return Extension;
|
||||
|
||||
|
@ -37,13 +37,25 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function CustomRegistrars(app, $log) {
|
||||
this.app = app;
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
// Utility; bind a function to a "this" pointer
|
||||
function bind(fn, thisArg) {
|
||||
return function () {
|
||||
return fn.apply(thisArg, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
// Used to create custom registration functions which map to
|
||||
// named methods on Angular modules, which follow the normal
|
||||
// app.method(key, [ deps..., function ]) pattern.
|
||||
function CustomRegistrar(angularFunction) {
|
||||
function customRegistrar(angularFunction) {
|
||||
return function (extension, index) {
|
||||
var key = extension.key,
|
||||
var app = this.app,
|
||||
$log = this.$log,
|
||||
key = extension.key,
|
||||
dependencies = extension.depends || [];
|
||||
|
||||
if (!key) {
|
||||
@ -71,7 +83,9 @@ define(
|
||||
}
|
||||
|
||||
function registerConstant(extension) {
|
||||
var key = extension.key,
|
||||
var app = this.app,
|
||||
$log = this.$log,
|
||||
key = extension.key,
|
||||
value = extension.value;
|
||||
|
||||
if (typeof key === "string" && value !== undefined) {
|
||||
@ -95,6 +109,9 @@ define(
|
||||
|
||||
// Custom registration function for extensions of category "runs"
|
||||
function registerRun(extension) {
|
||||
var app = this.app,
|
||||
$log = this.$log;
|
||||
|
||||
if (typeof extension === 'function') {
|
||||
// Prepend dependencies, and schedule to run
|
||||
app.run((extension.depends || []).concat([extension]));
|
||||
@ -110,7 +127,9 @@ define(
|
||||
|
||||
// Custom registration function for extensions of category "route"
|
||||
function registerRoute(extension) {
|
||||
var route = Object.create(extension);
|
||||
var app = this.app,
|
||||
$log = this.$log,
|
||||
route = Object.create(extension);
|
||||
|
||||
// Adjust path for bundle
|
||||
if (route.templateUrl) {
|
||||
@ -136,6 +155,8 @@ define(
|
||||
|
||||
// Handle service compositing
|
||||
function registerComponents(components) {
|
||||
var app = this.app,
|
||||
$log = this.$log;
|
||||
return new ServiceCompositor(app, $log)
|
||||
.registerCompositeServices(components);
|
||||
}
|
||||
@ -144,23 +165,62 @@ define(
|
||||
// (which acts on single objects) to one which acts upon arrays.
|
||||
function mapUpon(func) {
|
||||
return function (array) {
|
||||
return array.map(func);
|
||||
return array.map(bind(func, this));
|
||||
};
|
||||
}
|
||||
|
||||
// More like key-value pairs than methods; key is the
|
||||
// name of the extension category to be handled, and the value
|
||||
// is the function which handles it.
|
||||
return {
|
||||
constants: mapUpon(registerConstant),
|
||||
routes: mapUpon(registerRoute),
|
||||
directives: mapUpon(new CustomRegistrar("directive")),
|
||||
controllers: mapUpon(new CustomRegistrar("controller")),
|
||||
services: mapUpon(new CustomRegistrar("service")),
|
||||
runs: mapUpon(registerRun),
|
||||
components: registerComponents
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Register constant values.
|
||||
* @param {Array} extensions the resolved extensions
|
||||
*/
|
||||
CustomRegistrars.prototype.constants =
|
||||
mapUpon(registerConstant);
|
||||
|
||||
/**
|
||||
* Register Angular routes.
|
||||
* @param {Array} extensions the resolved extensions
|
||||
*/
|
||||
CustomRegistrars.prototype.routes =
|
||||
mapUpon(registerRoute);
|
||||
|
||||
/**
|
||||
* Register Angular directives.
|
||||
* @param {Array} extensions the resolved extensions
|
||||
*/
|
||||
CustomRegistrars.prototype.directives =
|
||||
mapUpon(customRegistrar("directive"));
|
||||
|
||||
/**
|
||||
* Register Angular controllers.
|
||||
* @param {Array} extensions the resolved extensions
|
||||
*/
|
||||
CustomRegistrars.prototype.controllers =
|
||||
mapUpon(customRegistrar("controller"));
|
||||
|
||||
/**
|
||||
* Register Angular services.
|
||||
* @param {Array} extensions the resolved extensions
|
||||
*/
|
||||
CustomRegistrars.prototype.services =
|
||||
mapUpon(customRegistrar("service"));
|
||||
|
||||
/**
|
||||
* Register functions which will run after bootstrapping.
|
||||
* @param {Array} extensions the resolved extensions
|
||||
*/
|
||||
CustomRegistrars.prototype.runs =
|
||||
mapUpon(registerRun);
|
||||
|
||||
/**
|
||||
* Register components of composite services.
|
||||
* @param {Array} extensions the resolved extensions
|
||||
*/
|
||||
CustomRegistrars.prototype.components =
|
||||
registerComponents;
|
||||
|
||||
return CustomRegistrars;
|
||||
}
|
||||
|
@ -47,7 +47,34 @@ define(
|
||||
// Track which extension categories have already been registered.
|
||||
// Exceptions will be thrown if the same extension category is
|
||||
// registered twice.
|
||||
var registeredCategories = {};
|
||||
this.registeredCategories = {};
|
||||
this.customRegistrars = customRegistrars || {};
|
||||
this.app = app;
|
||||
this.sorter = sorter;
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a group of resolved extensions with the Angular
|
||||
* module managed by this registrar.
|
||||
*
|
||||
* For convenient chaining (particularly from the framework
|
||||
* initializer's perspective), this returns the Angular
|
||||
* module with which extensions were registered.
|
||||
*
|
||||
* @param {Object.<string, object[]>} extensionGroup an object
|
||||
* containing key-value pairs, where keys are extension
|
||||
* categories and values are arrays of resolved
|
||||
* extensions
|
||||
* @returns {angular.Module} the application module with
|
||||
* which extensions were registered
|
||||
*/
|
||||
ExtensionRegistrar.prototype.registerExtensions = function (extensionGroup) {
|
||||
var registeredCategories = this.registeredCategories,
|
||||
customRegistrars = this.customRegistrars,
|
||||
app = this.app,
|
||||
sorter = this.sorter,
|
||||
$log = this.$log;
|
||||
|
||||
// Used to build unique identifiers for individual extensions,
|
||||
// so that these can be registered separately with Angular
|
||||
@ -179,7 +206,6 @@ define(
|
||||
});
|
||||
}
|
||||
|
||||
function registerExtensionGroup(extensionGroup) {
|
||||
// Announce we're entering a new phase
|
||||
$log.info("Registering extensions...");
|
||||
|
||||
@ -197,30 +223,7 @@ define(
|
||||
// Return the application to which these extensions
|
||||
// have been registered
|
||||
return app;
|
||||
}
|
||||
|
||||
customRegistrars = customRegistrars || {};
|
||||
|
||||
return {
|
||||
/**
|
||||
* Register a group of resolved extensions with the Angular
|
||||
* module managed by this registrar.
|
||||
*
|
||||
* For convenient chaining (particularly from the framework
|
||||
* initializer's perspective), this returns the Angular
|
||||
* module with which extensions were registered.
|
||||
*
|
||||
* @param {Object.<string, object[]>} extensionGroup an object
|
||||
* containing key-value pairs, where keys are extension
|
||||
* categories and values are arrays of resolved
|
||||
* extensions
|
||||
* @returns {angular.Module} the application module with
|
||||
* which extensions were registered
|
||||
* @memberof platform/framework.ExtensionRegistrar#
|
||||
*/
|
||||
registerExtensions: registerExtensionGroup
|
||||
};
|
||||
}
|
||||
|
||||
return ExtensionRegistrar;
|
||||
}
|
||||
|
@ -38,6 +38,17 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function ExtensionSorter($log) {
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort extensions according to priority.
|
||||
*
|
||||
* @param {object[]} extensions array of resolved extensions
|
||||
* @returns {object[]} the same extensions, in priority order
|
||||
*/
|
||||
ExtensionSorter.prototype.sort = function (extensions) {
|
||||
var $log = this.$log;
|
||||
|
||||
// Handle unknown or malformed priorities specified by extensions
|
||||
function unrecognizedPriority(extension) {
|
||||
@ -98,22 +109,11 @@ define(
|
||||
return (b.priority - a.priority) || (a.index - b.index);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Sort extensions according to priority.
|
||||
*
|
||||
* @param {object[]} extensions array of resolved extensions
|
||||
* @returns {object[]} the same extensions, in priority order
|
||||
* @memberof platform/framework.ExtensionSorter#
|
||||
*/
|
||||
sort: function (extensions) {
|
||||
return (extensions || [])
|
||||
.map(prioritize)
|
||||
.sort(compare)
|
||||
.map(deprioritize);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ExtensionSorter;
|
||||
}
|
||||
|
@ -37,8 +37,30 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function ServiceCompositor(app, $log) {
|
||||
var latest = {},
|
||||
providerLists = {}; // Track latest services registered
|
||||
this.latest = {};
|
||||
this.providerLists = {}; // Track latest services registered
|
||||
this.app = app;
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register composite services with Angular. This will build
|
||||
* up a dependency hierarchy between providers, aggregators,
|
||||
* and/or decorators, such that a dependency upon the service
|
||||
* type they expose shall be satisfied by their fully-wired
|
||||
* whole.
|
||||
*
|
||||
* Note that this method assumes that a complete set of
|
||||
* components shall be provided. Multiple calls to this
|
||||
* method may not behave as expected.
|
||||
*
|
||||
* @param {Array} components extensions of category component
|
||||
*/
|
||||
ServiceCompositor.prototype.registerCompositeServices = function (components) {
|
||||
var latest = this.latest,
|
||||
providerLists = this.providerLists,
|
||||
app = this.app,
|
||||
$log = this.$log;
|
||||
|
||||
// Log a warning; defaults to "no service provided by"
|
||||
function warn(extension, category, message) {
|
||||
@ -200,33 +222,13 @@ define(
|
||||
registerLatest();
|
||||
}
|
||||
|
||||
// Initial point of entry; just separate components by type
|
||||
function registerCompositeServices(components) {
|
||||
// Initial point of entry; split into three component types.
|
||||
registerComposites(
|
||||
components.filter(hasType("provider")),
|
||||
components.filter(hasType("aggregator")),
|
||||
components.filter(hasType("decorator"))
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Register composite services with Angular. This will build
|
||||
* up a dependency hierarchy between providers, aggregators,
|
||||
* and/or decorators, such that a dependency upon the service
|
||||
* type they expose shall be satisfied by their fully-wired
|
||||
* whole.
|
||||
*
|
||||
* Note that this method assumes that a complete set of
|
||||
* components shall be provided. Multiple calls to this
|
||||
* method may not behave as expected.
|
||||
*
|
||||
* @param {Array} components extensions of category component
|
||||
* @memberof platform/framework.ServiceCompositor#
|
||||
*/
|
||||
registerCompositeServices: registerCompositeServices
|
||||
};
|
||||
}
|
||||
|
||||
return ServiceCompositor;
|
||||
}
|
||||
|
@ -38,8 +38,27 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function BundleResolver(extensionResolver, requireConfigurator, $log) {
|
||||
this.extensionResolver = extensionResolver;
|
||||
this.requireConfigurator = requireConfigurator;
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve all extensions exposed by these bundles.
|
||||
*
|
||||
* @param {Bundle[]} bundles the bundles to resolve
|
||||
* @returns {Promise.<Object.<string, object[]>>} an promise
|
||||
* for an object containing
|
||||
* key-value pairs, where keys are extension
|
||||
* categories and values are arrays of resolved
|
||||
* extensions belonging to those categories
|
||||
*/
|
||||
BundleResolver.prototype.resolveBundles = function (bundles) {
|
||||
var extensionResolver = this.extensionResolver,
|
||||
requireConfigurator = this.requireConfigurator,
|
||||
$log = this.$log;
|
||||
|
||||
/*
|
||||
* Merge resolved bundles (where each is expressed as an
|
||||
* object containing key-value pairs, where keys are extension
|
||||
* categories and values are arrays of resolved extensions)
|
||||
@ -99,28 +118,13 @@ define(
|
||||
.then(giveResult);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Resolve all extensions exposed by these bundles.
|
||||
*
|
||||
* @param {Bundle[]} bundles the bundles to resolve
|
||||
* @returns {Promise.<Object.<string, object[]>>} an promise
|
||||
* for an object containing
|
||||
* key-value pairs, where keys are extension
|
||||
* categories and values are arrays of resolved
|
||||
* extensions belonging to those categories
|
||||
* @memberof platform/framework.BundleResolver#
|
||||
*/
|
||||
resolveBundles: function (bundles) {
|
||||
// First, make sure Require is suitably configured
|
||||
requireConfigurator.configure(bundles);
|
||||
|
||||
// Then, resolve all extension implementations.
|
||||
return Promise.all(bundles.map(resolveBundle))
|
||||
.then(mergeResolvedBundles);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return BundleResolver;
|
||||
}
|
||||
|
@ -39,6 +39,27 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function ExtensionResolver(loader, $log) {
|
||||
this.loader = loader;
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the provided extension; this will give a promise
|
||||
* for the extension's implementation, if one has been
|
||||
* specified, or for the plain definition of the extension
|
||||
* otherwise. The plain definition will also be given
|
||||
* if the implementation fails to load for some reason.
|
||||
*
|
||||
* All key-value pairs from the extension definition
|
||||
* will additionally be attached to any loaded implementation.
|
||||
*
|
||||
* @param {Extension} extension the extension to resolve
|
||||
* @returns {Promise} a promise for the resolved extension
|
||||
*/
|
||||
ExtensionResolver.prototype.resolve = function (extension) {
|
||||
var loader = this.loader,
|
||||
$log = this.$log;
|
||||
|
||||
function loadImplementation(extension) {
|
||||
var implPath = extension.getImplementationPath(),
|
||||
implPromise = loader.load(implPath),
|
||||
@ -107,21 +128,6 @@ define(
|
||||
return implPromise.then(attachDefinition, handleError);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Resolve the provided extension; this will give a promise
|
||||
* for the extension's implementation, if one has been
|
||||
* specified, or for the plain definition of the extension
|
||||
* otherwise. The plain definition will also be given
|
||||
* if the implementation fails to load for some reason.
|
||||
*
|
||||
* All key-value pairs from the extension definition
|
||||
* will additionally be attached to any loaded implementation.
|
||||
*
|
||||
* @param {Extension} extension
|
||||
* @memberof platform/framework.ExtensionResolver#
|
||||
*/
|
||||
resolve: function (extension) {
|
||||
// Log that loading has begun
|
||||
$log.info([
|
||||
"Resolving extension ",
|
||||
@ -131,9 +137,7 @@ define(
|
||||
return extension.hasImplementation() ?
|
||||
loadImplementation(extension) :
|
||||
Promise.resolve(extension.getDefinition());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ExtensionResolver;
|
||||
}
|
||||
|
@ -39,13 +39,9 @@ define(
|
||||
* @param {*} $log Angular's logging service
|
||||
*/
|
||||
function ImplementationLoader(require) {
|
||||
function loadModule(path) {
|
||||
return new Promise(function (fulfill, reject) {
|
||||
require([path], fulfill, reject);
|
||||
});
|
||||
this.require = require;
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Load an extension's implementation; or, equivalently,
|
||||
* load an AMD module. This is fundamentally similar
|
||||
@ -54,15 +50,15 @@ define(
|
||||
* with the loaded module, or rejected with the error
|
||||
* reported by Require.
|
||||
*
|
||||
* @method
|
||||
* @memberof ImplementationLoader#
|
||||
* @param {string} path the path to the module to load
|
||||
* @returns {Promise} a promise for the specified module.
|
||||
* @memberof platform/framework.ImplementationLoader#
|
||||
*/
|
||||
load: loadModule
|
||||
ImplementationLoader.prototype.load = function loadModule(path) {
|
||||
var require = this.require;
|
||||
return new Promise(function (fulfill, reject) {
|
||||
require([path], fulfill, reject);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return ImplementationLoader;
|
||||
}
|
||||
|
@ -35,6 +35,9 @@ define(
|
||||
* @param requirejs an instance of RequireJS
|
||||
*/
|
||||
function RequireConfigurator(requirejs) {
|
||||
this.requirejs = requirejs;
|
||||
}
|
||||
|
||||
// Utility function to clone part of a bundle definition
|
||||
function clone(obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
@ -93,7 +96,6 @@ define(
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Configure RequireJS to utilize any path/shim definitions
|
||||
* provided by these bundles.
|
||||
@ -102,11 +104,9 @@ define(
|
||||
* configuration
|
||||
* @memberof platform/framework.RequireConfigurator#
|
||||
*/
|
||||
configure: function (bundles) {
|
||||
return requirejs.config(buildConfiguration(bundles));
|
||||
}
|
||||
RequireConfigurator.prototype.configure = function (bundles) {
|
||||
return this.requirejs.config(buildConfiguration(bundles));
|
||||
};
|
||||
}
|
||||
|
||||
return RequireConfigurator;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user