[Code Style] Use prototypes in framework layer

WTD-1482
This commit is contained in:
Victor Woeltjen
2015-08-14 14:42:25 -07:00
parent 7fe866060b
commit edca2a9f03
14 changed files with 750 additions and 676 deletions

View File

@ -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);
// First, make sure Require is suitably configured
requireConfigurator.configure(bundles);
// Then, resolve all extension implementations.
return Promise.all(bundles.map(resolveBundle))
.then(mergeResolvedBundles);
}
};
}
// Then, resolve all extension implementations.
return Promise.all(bundles.map(resolveBundle))
.then(mergeResolvedBundles);
};
return BundleResolver;
}

View File

@ -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),
@ -57,8 +78,8 @@ define(
// loaded implementation.
function attachDefinition(impl) {
var result = (typeof impl === 'function') ?
constructorFor(impl) :
Object.create(impl);
constructorFor(impl) :
Object.create(impl);
// Copy over static properties
Object.keys(impl).forEach(function (k) {
@ -84,11 +105,11 @@ define(
function handleError(err) {
// Build up a log message from parts
var message = [
"Could not load implementation for extension ",
extension.getLogName(),
" due to ",
err.message
].join("");
"Could not load implementation for extension ",
extension.getLogName(),
" due to ",
err.message
].join("");
// Log that the extension was not loaded
$log.warn(message);
@ -107,33 +128,16 @@ 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 ",
extension.getLogName()
].join(""));
// Log that loading has begun
$log.info([
"Resolving extension ",
extension.getLogName()
].join(""));
return extension.hasImplementation() ?
loadImplementation(extension) :
Promise.resolve(extension.getDefinition());
}
};
}
return extension.hasImplementation() ?
loadImplementation(extension) :
Promise.resolve(extension.getDefinition());
};
return ExtensionResolver;
}

View File

@ -39,31 +39,27 @@ define(
* @param {*} $log Angular's logging service
*/
function ImplementationLoader(require) {
function loadModule(path) {
return new Promise(function (fulfill, reject) {
require([path], fulfill, reject);
});
}
return {
/**
* Load an extension's implementation; or, equivalently,
* load an AMD module. This is fundamentally similar
* to a call to RequireJS, except that the result is
* wrapped in a promise. The promise will be fulfilled
* 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
};
this.require = require;
}
/**
* Load an extension's implementation; or, equivalently,
* load an AMD module. This is fundamentally similar
* to a call to RequireJS, except that the result is
* wrapped in a promise. The promise will be fulfilled
* with the loaded module, or rejected with the error
* reported by Require.
*
* @param {string} path the path to the module to load
* @returns {Promise} a promise for the specified module.
*/
ImplementationLoader.prototype.load = function loadModule(path) {
var require = this.require;
return new Promise(function (fulfill, reject) {
require([path], fulfill, reject);
});
};
return ImplementationLoader;
}
);

View File

@ -35,79 +35,79 @@ define(
* @param requirejs an instance of RequireJS
*/
function RequireConfigurator(requirejs) {
// Utility function to clone part of a bundle definition
function clone(obj) {
return JSON.parse(JSON.stringify(obj));
}
// Look up module configuration from the bundle definition.
// This will adjust paths to libraries as-needed.
function getConfiguration(bundle) {
var configuration = bundle.getConfiguration();
// Adjust paths to point to libraries
if (configuration.paths) {
// Don't modify the actual bundle definition...
configuration = clone(configuration);
// ...replace values in a clone instead.
Object.keys(configuration.paths).forEach(function (path) {
configuration.paths[path] =
bundle.getLibraryPath(configuration.paths[path]);
});
}
return configuration;
}
// Build up paths and shim values from multiple bundles;
// this is sensitive to the value from baseConfiguration
// passed via reduce in buildConfiguration below, insofar
// as it assumes paths and shim will have initial empty values.
function mergeConfigurations(base, next) {
["paths", "shim"].forEach(function (k) {
Object.keys(next[k] || {}).forEach(function (p) {
base[k][p] = next[k][p];
});
});
return base;
}
// Build a configuration object, to pass to requirejs.config,
// based on the defined configurations for all bundles.
// The paths and shim properties from all bundles will be
// merged to allow one requirejs.config call.
function buildConfiguration(bundles) {
// Provide an initial requirejs configuration...
var baseConfiguration = {
baseUrl: "",
paths: {},
shim: {}
},
// ...and pull out all bundle-specific parts
bundleConfigurations = bundles.map(getConfiguration);
// Reduce this into one configuration object.
return bundleConfigurations.reduce(
mergeConfigurations,
baseConfiguration
);
}
return {
/**
* Configure RequireJS to utilize any path/shim definitions
* provided by these bundles.
*
* @param {Bundle[]} the bundles to include in this
* configuration
* @memberof platform/framework.RequireConfigurator#
*/
configure: function (bundles) {
return requirejs.config(buildConfiguration(bundles));
}
};
this.requirejs = requirejs;
}
// Utility function to clone part of a bundle definition
function clone(obj) {
return JSON.parse(JSON.stringify(obj));
}
// Look up module configuration from the bundle definition.
// This will adjust paths to libraries as-needed.
function getConfiguration(bundle) {
var configuration = bundle.getConfiguration();
// Adjust paths to point to libraries
if (configuration.paths) {
// Don't modify the actual bundle definition...
configuration = clone(configuration);
// ...replace values in a clone instead.
Object.keys(configuration.paths).forEach(function (path) {
configuration.paths[path] =
bundle.getLibraryPath(configuration.paths[path]);
});
}
return configuration;
}
// Build up paths and shim values from multiple bundles;
// this is sensitive to the value from baseConfiguration
// passed via reduce in buildConfiguration below, insofar
// as it assumes paths and shim will have initial empty values.
function mergeConfigurations(base, next) {
["paths", "shim"].forEach(function (k) {
Object.keys(next[k] || {}).forEach(function (p) {
base[k][p] = next[k][p];
});
});
return base;
}
// Build a configuration object, to pass to requirejs.config,
// based on the defined configurations for all bundles.
// The paths and shim properties from all bundles will be
// merged to allow one requirejs.config call.
function buildConfiguration(bundles) {
// Provide an initial requirejs configuration...
var baseConfiguration = {
baseUrl: "",
paths: {},
shim: {}
},
// ...and pull out all bundle-specific parts
bundleConfigurations = bundles.map(getConfiguration);
// Reduce this into one configuration object.
return bundleConfigurations.reduce(
mergeConfigurations,
baseConfiguration
);
}
/**
* Configure RequireJS to utilize any path/shim definitions
* provided by these bundles.
*
* @param {Bundle[]} the bundles to include in this
* configuration
* @memberof platform/framework.RequireConfigurator#
*/
RequireConfigurator.prototype.configure = function (bundles) {
return this.requirejs.config(buildConfiguration(bundles));
};
return RequireConfigurator;
}