157 lines
6.1 KiB
JavaScript
157 lines
6.1 KiB
JavaScript
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; under version 2
|
|
* of the License (non-upgradable).
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright (c) 2016 (original work) Open Assessment Technologies SA;
|
|
*
|
|
*/
|
|
define(['lodash', 'context', 'core/promise'], function(_, context, Promise){
|
|
'use strict';
|
|
|
|
var _portableElementManifests = {};
|
|
var _registry = {};
|
|
var _moduleName = 'taoQtiItem/portableElementRegistry/provider/localManifestProvider';
|
|
|
|
/**
|
|
* Recursively set the prefix of portable element path
|
|
* e.g. transform a relative local path "./runtime/entrypoint.js" to "prefix/runtime/entrypoint.js"
|
|
*
|
|
* @param {Object|String|Array} obj
|
|
* @param {String} prefix
|
|
* @returns {Object|String|Array}
|
|
*/
|
|
function setPortableElementPrefix(obj, prefix){
|
|
var ret;
|
|
if(_.isArray(obj)){
|
|
ret = _.map(obj, function(v){
|
|
return setPortableElementPrefix(v, prefix);
|
|
});
|
|
}else if(_.isPlainObject(obj)){
|
|
ret = {};
|
|
_.forIn(obj, function(v, k){
|
|
ret[k] = setPortableElementPrefix(v, prefix);
|
|
});
|
|
}else if(_.isString(obj)){
|
|
ret = obj.replace('./', prefix+'/');
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Use portable element source if exists
|
|
*
|
|
* @param {Object} manifest - the manifest of the pci to be modified
|
|
* @returns {Object} the modified manifest
|
|
*/
|
|
function useSource(manifest){
|
|
var runtimeModules,
|
|
runtimeSrc,
|
|
typeIdentifier;
|
|
|
|
// Make sure that we use the unbundled runtime
|
|
if (manifest.model === "IMSPCI") {
|
|
runtimeModules = (manifest.runtime || {}).modules;
|
|
runtimeSrc = (manifest.runtime || {}).src || [];
|
|
|
|
// in case of a TAO bundled PCI (= we have a "src" entry),
|
|
// we redirect the module to the entry point of the PCI instead of its minified version
|
|
if (runtimeSrc.length) {
|
|
_.forOwn(runtimeModules, function(allModulesFiles, moduleKey) {
|
|
if (moduleKey.indexOf('.min') === (moduleKey.length - '.min'.length)) {
|
|
runtimeModules[moduleKey] = allModulesFiles.map(function(filePath) {
|
|
return filePath.replace('.min.js', '.js');
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
} else {
|
|
if(manifest.runtime && _.isArray(manifest.runtime.src)){
|
|
delete manifest.runtime.hook;//hook is going to be removed with the support of IMS PCI v1
|
|
manifest.runtime.libraries = manifest.runtime.src;
|
|
}
|
|
if(manifest.creator && _.isArray(manifest.creator.src)){
|
|
delete manifest.creator.hook;//hook is going to be removed with the support of IMS PCI v1
|
|
manifest.creator.libraries = manifest.creator.src;
|
|
}
|
|
}
|
|
return manifest;
|
|
}
|
|
|
|
/**
|
|
* Generic portable element provider than loads portable elements from their manifest.
|
|
* It is useful for testing if the portable element source location is easily accessible.
|
|
*
|
|
* Sample usage :
|
|
*
|
|
* localManifestProvider.addManifestPath('pci_A', 'qtiItemPci/pciCreator/dev/pci_A/pciCreator.json');
|
|
* localManifestProvider.addManifestPath('pci_B', 'taoExtB/pciCreator/dev/pci_B/pciCreator.json');
|
|
* localManifestProvider.addManifestPath('pci_C', 'qtiSamples/some/path/pci_C/pciCreator.json');
|
|
* ciRegistry.registerProvider(pciTestProvider.getModuleName());
|
|
*
|
|
*/
|
|
return {
|
|
/**
|
|
* Add testing
|
|
* @param id
|
|
* @param pathToManifest
|
|
*/
|
|
addManifestPath : function addManifestPath(id, pathToManifest){
|
|
_portableElementManifests[id] = pathToManifest;
|
|
return this;
|
|
},
|
|
/**
|
|
* Get the amd module name
|
|
* @returns {string}
|
|
*/
|
|
getModuleName : function getModuleName(){
|
|
return _moduleName;
|
|
},
|
|
/**
|
|
* Implementation of the mandatory method load() of a portable element provider
|
|
*
|
|
* @returns {Promise} resolved when the added pci registered through their manifest are loaded
|
|
*/
|
|
load : function load(){
|
|
return new Promise(function(resolve, reject){
|
|
var _requiredManifests = _.map(_portableElementManifests, function(manifest){
|
|
return 'json!'+manifest;
|
|
});
|
|
require(_requiredManifests, function(){
|
|
var ok = true;
|
|
_.each([].slice.call(arguments), function(manifest){
|
|
var id;
|
|
if(manifest && manifest.typeIdentifier){
|
|
id = manifest.typeIdentifier;
|
|
if(!_portableElementManifests[id]){
|
|
reject('typeIdentifier mismatch');
|
|
ok = false;
|
|
return false;
|
|
}
|
|
|
|
manifest = useSource(manifest);
|
|
|
|
manifest.baseUrl = window.location.origin + '/' +
|
|
_portableElementManifests[id].replace(/^([a-zA-Z]*)\/(.*)\/([a-zA-Z]*)(Creator.json$)/, '$1/views/js/$2');
|
|
_registry[id] = [setPortableElementPrefix(manifest, id)];
|
|
}
|
|
});
|
|
if(ok){
|
|
resolve(_registry);
|
|
}
|
|
}, reject);
|
|
});
|
|
}
|
|
};
|
|
}); |