mirror of
https://github.com/nasa/openmct.git
synced 2025-02-18 16:40:58 +00:00
[Framework] Add extension sorter
Add priority ordering to loaded extensions in each category; this allows control over the resulting order of extensions acquired and used within the application. WTD-590
This commit is contained in:
parent
2bcb6a1a6e
commit
9d8885d48f
@ -16,5 +16,13 @@ define({
|
||||
"tests": "test",
|
||||
"configuration": {},
|
||||
"extensions": {}
|
||||
}
|
||||
},
|
||||
PRIORITY_LEVELS: {
|
||||
"fallback": Number.NEGATIVE_INFINITY,
|
||||
"default": 100,
|
||||
"optional": 200,
|
||||
"preferred": 400,
|
||||
"mandatory": Number.POSITIVE_INFINITY
|
||||
},
|
||||
DEFAULT_PRIORITY: 0
|
||||
});
|
@ -26,9 +26,11 @@ define(
|
||||
'./resolve/RequireConfigurator',
|
||||
'./register/CustomRegistrars',
|
||||
'./register/ExtensionRegistrar',
|
||||
'./register/ExtensionSorter',
|
||||
'./bootstrap/ApplicationBootstrapper'
|
||||
],
|
||||
function (require,
|
||||
function (
|
||||
require,
|
||||
es6promise,
|
||||
angular,
|
||||
angularRoute,
|
||||
@ -41,6 +43,7 @@ define(
|
||||
RequireConfigurator,
|
||||
CustomRegistrars,
|
||||
ExtensionRegistrar,
|
||||
ExtensionSorter,
|
||||
ApplicationBootstrapper
|
||||
) {
|
||||
"use strict";
|
||||
@ -68,6 +71,7 @@ define(
|
||||
registrar = new ExtensionRegistrar(
|
||||
app,
|
||||
new CustomRegistrars(app, $log),
|
||||
new ExtensionSorter($log),
|
||||
$log
|
||||
),
|
||||
bootstrapper = new ApplicationBootstrapper(
|
||||
|
@ -17,9 +17,11 @@ define(
|
||||
* @param {Object.<string,function>} customRegistrars an object
|
||||
* containing custom registration functions, primarily for
|
||||
* Angular built-ins.
|
||||
* @param {ExtensionSorter} sorter the sorter which will impose
|
||||
* priority ordering upon extensions
|
||||
* @param {*} $log Angular's logging service
|
||||
*/
|
||||
function ExtensionRegistrar(app, customRegistrars, $log) {
|
||||
function ExtensionRegistrar(app, customRegistrars, sorter, $log) {
|
||||
// Track which extension categories have already been registered.
|
||||
// Exceptions will be thrown if the same extension category is
|
||||
// registered twice.
|
||||
@ -163,7 +165,7 @@ define(
|
||||
Object.keys(extensionGroup).forEach(function (category) {
|
||||
registerExtensionsForCategory(
|
||||
category,
|
||||
extensionGroup[category]
|
||||
sorter.sort(extensionGroup[category])
|
||||
);
|
||||
});
|
||||
|
||||
|
97
platform/framework/src/register/ExtensionSorter.js
Normal file
97
platform/framework/src/register/ExtensionSorter.js
Normal file
@ -0,0 +1,97 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
["../Constants"],
|
||||
function (Constants) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Responsible for applying priority order to extensions in a
|
||||
* given category. This will sort in reverse order of the numeric
|
||||
* priority given for extensions in the `priority` priority (such
|
||||
* that large values are registered first.) Extensions may also
|
||||
* specify symbolic properties as strings (instead of numbers),
|
||||
* which will be looked up from the table `Constants.PRIORITY_LEVELS`.
|
||||
* @param $log Angular's logging service
|
||||
* @constructor
|
||||
*/
|
||||
function ExtensionSorter($log) {
|
||||
|
||||
// Handle unknown or malformed priorities specified by extensions
|
||||
function unrecognizedPriority(extension) {
|
||||
// Issue a warning
|
||||
$log.warn([
|
||||
"Unrecognized priority '",
|
||||
(extension || {}).priority,
|
||||
"' specified for extension from ",
|
||||
((extension || {}).bundle || {}).path,
|
||||
"; defaulting to ",
|
||||
Constants.DEFAULT_PRIORITY
|
||||
].join(''));
|
||||
|
||||
// Provide a return value (default priority) to make this
|
||||
// useful in an expression.
|
||||
return Constants.DEFAULT_PRIORITY;
|
||||
}
|
||||
|
||||
function getPriority(extension) {
|
||||
var priority =
|
||||
(extension || {}).priority || Constants.DEFAULT_PRIORITY;
|
||||
|
||||
// If it's a symbolic priority, look it up
|
||||
if (typeof priority === 'string') {
|
||||
priority = Constants.PRIORITY_LEVELS[priority];
|
||||
}
|
||||
|
||||
// Should be a number; otherwise, issue a warning and
|
||||
// fall back to default priority level.
|
||||
return (typeof priority === 'number') ?
|
||||
priority : unrecognizedPriority(extension);
|
||||
}
|
||||
|
||||
// Attach a numeric priority to an extension; this is done in
|
||||
// one pass outside of the comparator, mainly because getPriority
|
||||
// may log warnings, and we only want this to happen once
|
||||
// (instead of the many times that might occur during a sort.)
|
||||
function prioritize(extension, index) {
|
||||
return {
|
||||
// The extension itself, for later unwrapping
|
||||
extension: extension,
|
||||
// The index, to provide a stable sort (see compare)
|
||||
index: index,
|
||||
// The numeric priority of the extension
|
||||
priority: getPriority(extension)
|
||||
};
|
||||
}
|
||||
|
||||
// Unwrap the original extension
|
||||
// (for use after ordering has been applied)
|
||||
function deprioritize(prioritized) {
|
||||
return prioritized.extension;
|
||||
}
|
||||
|
||||
// Compare two prioritized extensions
|
||||
function compare(a, b) {
|
||||
// Reverse order by numeric priority; or, original order.
|
||||
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
|
||||
*/
|
||||
sort: function (extensions) {
|
||||
return (extensions || [])
|
||||
.map(prioritize)
|
||||
.sort(compare)
|
||||
.map(deprioritize);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ExtensionSorter;
|
||||
}
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user