diff --git a/platform/core/src/views/ViewCapability.js b/platform/core/src/views/ViewCapability.js index 40eaf7adb7..8d8d7842ab 100644 --- a/platform/core/src/views/ViewCapability.js +++ b/platform/core/src/views/ViewCapability.js @@ -9,11 +9,21 @@ define( "use strict"; /** + * A `view` capability can be used to retrieve an array of + * all views (or, more specifically, the declarative metadata + * thereabout) which are applicable to a specific domain + * object. * * @constructor */ function ViewCapability(viewService, domainObject) { return { + /** + * Get all view definitions which are applicable to + * this object. + * @returns {View[]} an array of view definitions + * which are applicable to this object. + */ invoke: function () { return viewService.getViews(domainObject); } diff --git a/platform/core/src/views/ViewProvider.js b/platform/core/src/views/ViewProvider.js index c60e46d9c5..bc6bd36348 100644 --- a/platform/core/src/views/ViewProvider.js +++ b/platform/core/src/views/ViewProvider.js @@ -9,31 +9,65 @@ define( "use strict"; /** + * A view provider allows view definitions (defined as extensions) + * to be read, and takes responsibility for filtering these down + * to a set that is applicable to specific domain objects. This + * filtering is parameterized by the extension definitions + * themselves; specifically: + * + * * Definitions with a `needs` property containing an array of + * strings are only applicable to domain objects which have + * all those capabilities. + * * If the view definition has a `delegation` property that + * is truthy, then domain objects which delegate capabilities + * from the `needs` property will be treated as having those + * capabilities for purposes of determining view applicability. + * * Definitions with a `type` property are only applicable to + * domain object's whose `type` capability matches or inherits + * from that type. + * + * Views themselves are primarily metadata, such as name, glyph, and + * description (to be shown in the UI); they do not contain any + * information directly applicable to rendering to the DOM, although + * they do contain sufficient information (such as a `templateUrl`, + * used in the representation bundle) to retrieve those details. + * The role of a view provider and of a view capability is to + * describe what views are available, not how to instantiate them. * * @constructor + * @param {View[]} an array of view definitions */ function ViewProvider(views) { + // Check if an object has all capabilities designated as `needs` + // for a view. Exposing a capability via delegation is taken to + // satisfy this filter if `allowDelegation` is true. function capabilitiesMatch(domainObject, capabilities, allowDelegation) { var delegation = domainObject.getCapability("delegation"); allowDelegation = allowDelegation && (delegation !== undefined); + // Check if an object has (or delegates, if allowed) a + // capability. function hasCapability(c) { return domainObject.hasCapability(c) || (allowDelegation && delegation.doesDelegateCapability(c)); } + // For the reduce step below. function and(a, b) { return a && b; } + // Do a bulk `and` operation over all needed capabilities. return capabilities.map(hasCapability).reduce(and, true); } function getViews(domainObject) { var type = domainObject.useCapability("type"); + // First, filter views by type (matched to domain object type.) + // Second, filter by matching capabilities. return views.filter(function (view) { return (!view.type) || type.instanceOf(view.type); }).filter(function (view) { @@ -46,6 +80,13 @@ define( } return { + /** + * Get all views which are applicable to this domain object. + * + * @param {DomainObject} domainObject the domain object to view + * @returns {View[]} all views which can be used to visualize + * this domain object. + */ getViews: getViews }; }