157 lines
6.0 KiB
JavaScript
157 lines
6.0 KiB
JavaScript
/*****************************************************************************
|
|
* 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.
|
|
*****************************************************************************/
|
|
|
|
/**
|
|
* Module defining ActionProvider. Created by vwoeltje on 11/7/14.
|
|
*/
|
|
define(
|
|
[],
|
|
function () {
|
|
|
|
/**
|
|
* An ActionProvider (implementing ActionService) provides actions
|
|
* that are applicable in specific contexts, chosen from a set
|
|
* of actions exposed via extension (specifically, the "actions"
|
|
* category of extension.)
|
|
*
|
|
* @memberof platform/core
|
|
* @imeplements {ActionService}
|
|
* @constructor
|
|
*/
|
|
function ActionProvider(actions, $log) {
|
|
var self = this;
|
|
|
|
this.$log = $log;
|
|
|
|
// Build up look-up tables
|
|
this.actions = actions;
|
|
this.actionsByKey = {};
|
|
this.actionsByCategory = {};
|
|
actions.forEach(function (Action) {
|
|
// Get an action's category or categories
|
|
var categories = Action.category || [];
|
|
|
|
// Convert to an array if necessary
|
|
categories = Array.isArray(categories) ?
|
|
categories : [categories];
|
|
|
|
// Store action under all relevant categories
|
|
categories.forEach(function (category) {
|
|
self.actionsByCategory[category] =
|
|
self.actionsByCategory[category] || [];
|
|
self.actionsByCategory[category].push(Action);
|
|
});
|
|
|
|
// Store action by ekey as well
|
|
if (Action.key) {
|
|
self.actionsByKey[Action.key] =
|
|
self.actionsByKey[Action.key] || [];
|
|
self.actionsByKey[Action.key].push(Action);
|
|
}
|
|
});
|
|
}
|
|
|
|
ActionProvider.prototype.getActions = function (actionContext) {
|
|
var context = (actionContext || {}),
|
|
category = context.category,
|
|
key = context.key,
|
|
$log = this.$log,
|
|
candidates;
|
|
|
|
// Instantiate an action; invokes the constructor and
|
|
// additionally fills in the action's getMetadata method
|
|
// with the extension definition (if no getMetadata
|
|
// method was supplied.)
|
|
function instantiateAction(Action, ctxt) {
|
|
var action = new Action(ctxt),
|
|
metadata;
|
|
|
|
// Provide a getMetadata method that echos
|
|
// declarative bindings, as well as context,
|
|
// unless the action has defined its own.
|
|
if (!action.getMetadata) {
|
|
metadata = Object.create(Action.definition || {});
|
|
metadata.context = ctxt;
|
|
action.getMetadata = function () {
|
|
return metadata;
|
|
};
|
|
}
|
|
|
|
return action;
|
|
}
|
|
|
|
// Filter the array of actions down to those which are
|
|
// applicable in a given context, according to the static
|
|
// appliesTo method of given actions (if defined), and
|
|
// instantiate those applicable actions.
|
|
function createIfApplicable(actions, ctxt) {
|
|
function isApplicable(Action) {
|
|
return Action.appliesTo ? Action.appliesTo(ctxt) : true;
|
|
}
|
|
|
|
function instantiate(Action) {
|
|
try {
|
|
return instantiateAction(Action, ctxt);
|
|
} catch (e) {
|
|
$log.error([
|
|
"Could not instantiate action",
|
|
Action.key,
|
|
"due to:",
|
|
e.message
|
|
].join(" "));
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
function isDefined(action) {
|
|
return action !== undefined;
|
|
}
|
|
|
|
return (actions || []).filter(isApplicable)
|
|
.map(instantiate)
|
|
.filter(isDefined);
|
|
}
|
|
|
|
// Match actions to the provided context by comparing "key"
|
|
// and/or "category" parameters, if specified.
|
|
candidates = this.actions;
|
|
if (key) {
|
|
candidates = this.actionsByKey[key];
|
|
if (category) {
|
|
candidates = candidates.filter(function (Action) {
|
|
return Action.category === category;
|
|
});
|
|
}
|
|
} else if (category) {
|
|
candidates = this.actionsByCategory[category];
|
|
}
|
|
|
|
// Instantiate those remaining actions, with additional
|
|
// filtering per any appliesTo methods defined on those
|
|
// actions.
|
|
return createIfApplicable(candidates, context);
|
|
};
|
|
|
|
return ActionProvider;
|
|
}
|
|
);
|