Files
Zos/Skills/@be/node_modules/jibo-loader/lib/jibo-loader.js

1515 lines
48 KiB
JavaScript

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jiboLoader = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const AssetToken_1 = require("./AssetToken");
const log_1 = require("./log");
const log = log_1.default.createChild('AssetCache');
class CacheItem {
constructor(key) {
this.key = key;
this.pendingCallbacks = new Map();
this.tokens = new Set();
this.contentIsError = false;
this.content = null;
this.subAssets = null;
}
get isPending() {
return !this.content;
}
addPending(token, callback) {
this.pendingCallbacks.set(token, callback);
}
removePending(token) {
if (!this.pendingCallbacks) {
return;
}
if (this.pendingCallbacks.has(token)) {
this.pendingCallbacks.delete(token);
}
if (this.tokens.has(token)) {
this.tokens.delete(token);
}
}
completeLoad(err, content, subAssets) {
this.content = content;
this.subAssets = subAssets || null;
this.contentIsError = !!err;
const callbacks = Array.from(this.pendingCallbacks.values());
this.pendingCallbacks.clear();
for (let callback of callbacks) {
callback(err, content);
}
}
destroy(cache) {
if (this.content && this.content.destroy) {
this.content.destroy(true);
}
if (this.content && this.content.tagName === 'IMG') {
this.content.src = '';
}
this.content = null;
this.key = null;
if (this.subAssets) {
for (let i = 0; i < this.subAssets.length; ++i) {
cache.delete(this.subAssets[i]);
}
this.subAssets = null;
}
this.pendingCallbacks = null;
}
}
exports.CacheItem = CacheItem;
class NamedCache {
constructor(name) {
this.name = name;
this.idMap = new Map();
this.tokens = new Set();
}
load(token) {
const { id, key } = token;
if (this.idMap.has(id) && this.idMap.get(id) !== key) {
log.info(`In cache ${this.name} overwriting asset ${id} with key of ${this.idMap.get(id)} with new key of ${key}`);
}
this.idMap.set(id, key);
this.tokens.add(token);
}
unload(token) {
this.tokens.delete(token);
const { id } = token;
const otherTokens = this.tokens.values();
let otherId = false;
for (let item of otherTokens) {
if (item.id === id) {
otherId = true;
break;
}
}
if (!otherId) {
this.idMap.delete(id);
}
}
}
class AssetCache {
constructor(manager) {
this._manager = manager;
this._cache = new Map();
this._cachesMap = new Map();
}
addCache(id) {
if (this._cachesMap.has(id)) {
return;
}
this._cachesMap.set(id, new NamedCache(id));
}
read(id, cacheId) {
if (!cacheId) {
const item = this._cache.get(id);
return item ? item.content : null;
}
const cache = this._cachesMap.get(cacheId);
if (!cache) {
throw new Error(`AssetCache.read(): unable to find cache: '${cacheId}'`);
}
const item = this._cache.get(cache.idMap.get(id));
return item ? item.content : null;
}
isLoaded(id, cacheId) {
if (!cacheId) {
const item = this._cache.get(id);
return item ? !item.isPending : false;
}
const cache = this._cachesMap.get(cacheId);
if (!cache) {
throw new Error(`AssetCache.isLoaded(): unable to find cache: '${cacheId}'`);
}
const item = this._cache.get(cache.idMap.get(id));
return item ? !item.isPending : false;
}
wasError(id, cacheId) {
if (!cacheId) {
const item = this._cache.get(id);
return item ? item.contentIsError : false;
}
const cache = this._cachesMap.get(cacheId);
if (!cache) {
throw new Error(`AssetCache.wasError(): unable to find cache: '${cacheId}'`);
}
const item = this._cache.get(cache.idMap.get(id));
return item ? item.contentIsError : false;
}
prepare(key, cacheName, id) {
const cache = this._cachesMap.get(cacheName);
if (!cache) {
throw new Error(`AssetCache.prepare(): unable to find cache: '${cacheName}'`);
}
const token = new AssetToken_1.default(this, key, cacheName, id);
cache.load(token);
let cacheItem = this._cache.get(key);
if (!cacheItem) {
cacheItem = new CacheItem(key);
this._cache.set(key, cacheItem);
}
cacheItem.tokens.add(token);
return token;
}
addPending(token, callback) {
let cacheItem = this._cache.get(token.key);
if (!cacheItem) {
throw new Error(`AssetCache.addPending(): unable to find item: '${token.key}'`);
}
let isFirst = cacheItem.pendingCallbacks.size === 0;
cacheItem.addPending(token, callback);
return isFirst;
}
cancelPending(token) {
let cacheItem = this._cache.get(token.key);
if (!cacheItem) {
return;
}
cacheItem.removePending(token);
if (cacheItem.tokens.size === 0) {
this._cache.delete(token.key);
}
}
completePending(err, result) {
const { token } = result;
if (!token.isValid) {
return;
}
const cache = this._cachesMap.get(token.cache);
if (!cache) {
throw new Error(`AssetCache.completePending(): unable to find cache: '${token.cache}'`);
}
let cacheItem = this._cache.get(token.key);
if (cacheItem) {
cacheItem.completeLoad(err, result.result, result.subAssets);
}
else {
log.warn(`completePending() - unable to complete load for ${token.key} because no item was found`);
}
}
delete(token) {
const cacheId = token.cache;
const cache = this._cachesMap.get(cacheId);
if (cache) {
cache.unload(token);
}
this.unloadItem(token);
}
empty(cacheId) {
const cache = this._cachesMap.get(cacheId);
if (!cache) {
return;
}
for (let entry of cache.tokens.values()) {
entry.unload();
}
cache.idMap.clear();
cache.tokens.clear();
}
destroy() {
for (let id in this._cachesMap) {
this.empty(id);
}
this._cache = null;
this._cachesMap = null;
}
unloadItem(token) {
const item = this._cache.get(token.key);
if (item) {
item.tokens.delete(token);
if (item.tokens.size < 1) {
item.destroy(this);
this._cache.delete(token.key);
}
}
}
}
exports.default = AssetCache;
},{"./AssetToken":4,"./log":16}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const Task_1 = require("./tasks/Task");
const AssetUtils_1 = require("./AssetUtils");
const log_1 = require("./log");
const log = log_1.default.createChild('AssetLoad');
class AssetLoad extends events_1.EventEmitter {
constructor(manager) {
super();
this.manager = manager;
this.id = AssetLoad.ID++;
this.mode = MAP_MODE;
this.maxLoads = 0;
this.cacheAll = null;
this.remoteAll = false;
this.timeoutAll = 0;
this.loadedTokens = [];
this.tasks = [];
this.results = null;
this.running = false;
this.numLoaded = 0;
this.numLoading = 0;
this.total = 0;
}
get tokens() {
const output = [];
if (this.tasks) {
this.tasks.forEach((task) => {
if (task.token) {
output.push(task.token);
}
});
}
if (this.loadedTokens) {
output.push(...this.loadedTokens);
}
return output.filter(item => !!item);
}
toString() {
return "[AssetLoad (index: " + this.id + ")]";
}
setup(assets, options) {
this.maxLoads = options.maxLoads;
this.cacheAll = options.cacheAll;
this.remoteAll = options.remoteAll;
this.timeoutAll = options.timeoutAll;
this.mode = this.addTasks(assets);
this.results = this.getAssetsContainer(this.mode);
if (options.autoStart) {
this.start();
}
}
cancel() {
this.loadedTokens.forEach((token) => {
this.manager.cache.delete(token);
});
this.manager.cancel(this);
}
cancelToken(token) {
let index = this.loadedTokens.indexOf(token);
if (index !== -1) {
this.loadedTokens.splice(index, 1);
}
index = this.tasks.findIndex((item) => {
return item.token === token;
});
if (index !== -1) {
this.tasks.splice(index, 1);
}
if (this.tasks.length === 0) {
if (this.loadedTokens.length === 0) {
this.cancel();
}
else {
this.emit('complete', null, this.results);
}
}
}
start() {
this.emit('progress', 0);
this.running = true;
this.nextTask();
}
reset() {
this.removeAllListeners('complete');
this.removeAllListeners('progress');
this.removeAllListeners('taskDone');
this.tasks.forEach((task) => {
if (task.pending) {
this.manager.cache.cancelPending(task.token);
}
task.status = Task_1.default.FINISHED;
task.destroy();
});
this.total = 0;
this.numLoaded = 0;
this.numLoading = 0;
this.mode = MAP_MODE;
this.tasks.length = 0;
this.results = null;
this.maxLoads = 0;
this.cacheAll = null;
this.remoteAll = false;
this.timeoutAll = 0;
this.running = false;
this.loadedTokens.length = 0;
}
addAssets(assets) {
const output = [];
this.addTasks(assets, output);
return output;
}
addTasks(assets, tokenOut) {
let asset;
let mode = MAP_MODE;
assets = this.applyDefaults(assets);
let isSingle = !!this.getTaskByAsset(assets);
if (isSingle) {
const task = this.addTask(assets);
if (tokenOut && task.token) {
tokenOut.push(task.token);
}
return SINGLE_MODE;
}
else {
let task;
if (Array.isArray(assets)) {
for (let i = 0; i < assets.length; i++) {
asset = this.applyDefaults(assets[i]);
task = this.addTask(asset);
if (tokenOut && task.token) {
tokenOut.push(task.token);
}
if (!task.id) {
mode = LIST_MODE;
}
}
}
else if (AssetUtils_1.default.isPlain(assets)) {
for (let id in assets) {
asset = this.applyDefaults(assets[id]);
asset.id = id;
task = this.addTask(asset);
if (tokenOut && task.token) {
tokenOut.push(task.token);
}
}
}
else {
log.debug("Asset type unsupported", asset);
}
}
return mode;
}
applyDefaults(asset) {
if (isString(asset)) {
return {
src: asset
};
}
else if (isFunction(asset)) {
return {
async: asset
};
}
return asset;
}
addTask(asset) {
let TaskClass = this.getTaskByAsset(asset);
let task;
if (TaskClass) {
if (asset.cache === undefined && this.cacheAll) {
asset.cache = this.cacheAll;
}
if (asset.remote === undefined && this.remoteAll) {
asset.remote = true;
}
if (asset.timeout === undefined && this.timeoutAll) {
asset.timeout = this.timeoutAll;
}
task = new TaskClass(this.manager, asset);
this.tasks.push(task);
++this.total;
if (!task.cache && task.needsCache) {
console.error('Trying to load %o but it needs to be cached!', task.original);
}
else if (task.cache) {
task.token = this.manager.cache.prepare(task.cacheKey, task.cache, task.id);
task.token.loader = this;
}
}
else {
log.debug("Unable to find a task definition for asset", asset);
}
return task;
}
getTaskByAsset(asset) {
let TaskClass;
let taskDefs = this.manager.taskDefs;
for (let i = 0, len = taskDefs.length; i < len; i++) {
TaskClass = taskDefs[i];
if (TaskClass.test(asset)) {
return TaskClass;
}
}
return null;
}
nextTask() {
let task;
for (let i = 0; i < this.tasks.length; i++) {
if (this.tasks[i].status === Task_1.default.WAITING) {
task = this.tasks[i];
break;
}
}
if (!task) {
return;
}
task.status = Task_1.default.RUNNING;
this.numLoading++;
if (task.cache && this.manager.cache.isLoaded(task.cacheKey)) {
process.nextTick(() => {
const result = this.manager.cache.read(task.cacheKey);
if (this.manager.cache.wasError(task.cacheKey)) {
this.taskDone(task, result, null);
}
else {
this.taskDone(task, null, result);
}
});
}
else {
if (task.cache) {
task.pending = this.taskDone.bind(this, task);
const assetData = {
token: task.token
};
const needsStart = this.manager.cache.addPending(task.token, task.pending);
if (needsStart) {
task.start((err, result) => {
if (task.status !== Task_1.default.RUNNING) {
if (result && result.destroy) {
result.destroy();
}
return;
}
assetData.result = result;
assetData.subAssets = task.subAssets;
this.manager.cache.completePending(err, assetData);
});
}
assetData.token = task.token;
}
else {
task.start(this.taskDone.bind(this, task));
}
}
if (this.maxLoads === 0 || this.numLoading < this.maxLoads) {
this.nextTask();
}
}
taskDone(task, err, result = null) {
if (!this.running) {
return;
}
let index = this.tasks.indexOf(task);
if (index === -1) {
return;
}
if (task.cache) {
this.loadedTokens.push(task.token);
}
this.tasks.splice(index, 1);
let assets = [];
log.iferr(err, 'error executing task');
if (result) {
switch (this.mode) {
case SINGLE_MODE:
this.results = result;
break;
case LIST_MODE:
this.results.push(result);
break;
case MAP_MODE:
this.results[task.id] = result;
break;
}
}
if (task.complete) {
task.complete(err, result, task.original, this);
}
if (!err) {
this.emit('taskDone', result, task.original, this);
}
task.destroy();
let mode = this.addTasks(assets);
this.emit('progress', ++this.numLoaded / this.total);
--this.numLoading;
if (this.mode === MAP_MODE && mode !== this.mode) {
log.error("Load assets require IDs to return mapped results", assets);
return;
}
if (err) {
this.emit('complete', err, null);
return;
}
if (this.tasks.length) {
this.nextTask();
}
else {
this.emit('complete', err, this.results);
}
}
getAssetsContainer(mode) {
switch (mode) {
case SINGLE_MODE:
return null;
case LIST_MODE:
return [];
case MAP_MODE:
return {};
}
}
destroy() {
this.removeAllListeners();
this.reset();
this.tasks = null;
this.manager = null;
}
}
const SINGLE_MODE = 0;
const MAP_MODE = 1;
const LIST_MODE = 2;
function isString(obj) {
return typeof obj === "string";
}
function isFunction(obj) {
return typeof obj === "function";
}
exports.default = AssetLoad;
},{"./AssetUtils":5,"./log":16,"./tasks/Task":20,"events":undefined}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const AssetCache_1 = require("./AssetCache");
const Task_1 = require("./tasks/Task");
const AssetLoad_1 = require("./AssetLoad");
const RemoteLoader_1 = require("./loaders/RemoteLoader");
const LocalLoader_1 = require("./loaders/LocalLoader");
const jibo_plugins_1 = require("jibo-plugins");
const log_1 = require("./log");
const log = log_1.default.createChild('AssetManager');
function getCacheKeyFromAsset(asset, manager) {
if (asset.src) {
return manager.prepare(asset.src);
}
return asset.id;
}
exports.getCacheKeyFromAsset = getCacheKeyFromAsset;
class AssetManager {
constructor() {
this.loads = [];
this.loadPool = [];
this.taskDefs = [];
this.cache = new AssetCache_1.default(this);
this.remoteLoader = new RemoteLoader_1.default();
this.localLoader = new LocalLoader_1.default();
this.maxDefaultLoads = 4;
}
register(TaskClass, priority = 0) {
TaskClass.priority = priority;
if (!(TaskClass.prototype instanceof Task_1.default)) {
log.error("Registering task - must extend Task", TaskClass);
}
else if (!TaskClass.test) {
log.error("Registering task - must have test method");
}
this.taskDefs.push(TaskClass);
this.taskDefs.sort(function (a, b) {
return b.priority - a.priority;
});
}
load(assets, options) {
options = Object.assign({
complete: null,
progress: null,
taskDone: null,
cacheAll: false,
maxLoads: this.maxDefaultLoads,
remoteAll: false,
timeoutAll: 0,
autoStart: true
}, options);
const startAll = options.startAll;
if (startAll !== undefined) {
options.maxLoads = startAll ? 0 : 1;
}
const load = this._getLoad();
this.loads.push(load);
options.complete = this._onLoaded.bind(this, options.complete, load);
load.once('complete', options.complete);
if (options.taskDone) {
load.on('taskDone', options.taskDone);
}
load.setup(assets, options);
return load;
}
simpleLoad(uri, callback, options = {}) {
let currentLoader;
if (options.remote || jibo_plugins_1.PathUtils.isURL(uri)) {
currentLoader = this.remoteLoader;
}
else {
currentLoader = this.localLoader;
}
currentLoader.load(uri, callback, options);
}
prepare(uri, remote = false) {
let currentLoader;
if (remote || jibo_plugins_1.PathUtils.isURL(uri)) {
currentLoader = this.remoteLoader;
}
else {
currentLoader = this.localLoader;
}
return currentLoader.prepare(uri);
}
cancelAll() {
for (let i = this.loads.length - 1; i >= 0; i--) {
this.loads[i].cancel();
}
}
destroy() {
this.remoteLoader = null;
this.localLoader = null;
this.cache.destroy();
this.cache = null;
this.loadPool = null;
this.loads = null;
this.taskDefs = null;
}
cancel(load) {
const i = this.loads.indexOf(load);
if (i >= 0) {
this.loads.splice(i, 1);
load.reset();
this.loadPool.push(load);
}
}
_getLoad() {
if (this.loadPool.length > 0) {
return this.loadPool.pop();
}
return new AssetLoad_1.default(this);
}
_onLoaded(complete, load, err, results) {
let index = this.loads.indexOf(load);
if (index > -1) {
this.loads.splice(index, 1);
}
if (complete) {
complete(err, results);
}
this.cancel(load);
}
}
exports.default = AssetManager;
},{"./AssetCache":1,"./AssetLoad":2,"./loaders/LocalLoader":10,"./loaders/RemoteLoader":11,"./log":16,"./tasks/Task":20,"jibo-plugins":undefined}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class AssetToken {
get isValid() {
return !!this.owner;
}
constructor(owner, key, cache, id) {
if (!owner || !owner.delete) {
throw new Error('AssetTokens must be instantiated with an owner!');
}
this.key = key;
this.cache = cache;
this.id = id;
this.owner = owner;
this.loader = null;
}
unload() {
if (this.loader) {
this.loader.cancelToken(this);
}
if (this.owner) {
this.owner.delete(this);
}
this.loader = null;
this.owner = null;
}
cancel() {
this.unload();
}
}
exports.default = AssetToken;
},{}],5:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class AssetUtils {
static isPlain(obj) {
if (typeof obj === 'object' && obj !== null) {
const proto = Object.getPrototypeOf(obj);
return proto === Object.prototype || proto === null;
}
return false;
}
}
exports.default = AssetUtils;
},{}],6:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const AssetManager_1 = require("./AssetManager");
const AssetToken_1 = require("./AssetToken");
const AssetUtils_1 = require("./AssetUtils");
const Task_1 = require("./tasks/Task");
const LoadTask_1 = require("./tasks/LoadTask");
const ListTask_1 = require("./tasks/ListTask");
const FunctionTask_1 = require("./tasks/FunctionTask");
const LoaderError_1 = require("./errors/LoaderError");
class LoaderPlugin {
constructor() {
this.AssetToken = AssetToken_1.default;
this.AssetUtils = AssetUtils_1.default;
this.Task = Task_1.default;
this.LoadTask = LoadTask_1.default;
this.ListTask = ListTask_1.default;
this.FunctionTask = FunctionTask_1.default;
this.LoaderError = LoaderError_1.default;
this.DEFAULT_CACHE = 'load-default';
this.assetManager = new AssetManager_1.default();
this._activeCache = this.DEFAULT_CACHE;
this.addCache(this.DEFAULT_CACHE);
this.register(LoadTask_1.default, 0)
.register(ListTask_1.default, 5)
.register(FunctionTask_1.default, 10);
}
init(done) {
done();
}
register(TaskDefinition, priority = 0) {
this.assetManager.register(TaskDefinition, priority);
return this;
}
load(source, complete, progress, cache, data, remote = false, timeout = 0, format) {
let options;
if (typeof source === "string") {
source = {
src: source,
progress: progress || null,
complete: complete || null,
cache: cache || null,
remote: remote,
timeout: timeout,
format: format,
data: data || null
};
}
else {
options = complete;
if (typeof complete === "function") {
options = {
complete: complete
};
}
}
return this.assetManager.load(source, options);
}
set basePath(basePath) {
this.assetManager.localLoader.basePath = basePath;
}
get basePath() {
return this.assetManager.localLoader.basePath;
}
set baseUrl(baseUrl) {
this.assetManager.remoteLoader.baseUrl = baseUrl;
}
get baseUrl() {
return this.assetManager.remoteLoader.baseUrl;
}
unload(assets) {
if (!assets) {
return this;
}
if (Array.isArray(assets)) {
for (let i = 0; i < assets.length; i++) {
assets[i].unload();
}
return this;
}
assets.unload();
return this;
}
unloadAll(cacheId) {
this.assetManager.cache.empty(cacheId || this.activeCache);
return this;
}
cancelAll() {
this.assetManager.cancelAll();
return this;
}
addCache(cacheId) {
this.assetManager.cache.addCache(cacheId);
return this;
}
set activeCache(cacheId) {
this._activeCache = cacheId;
}
get activeCache() {
return this._activeCache;
}
set maxDefaultLoads(num) {
this.assetManager.maxDefaultLoads = num;
}
get maxDefaultLoads() {
return this.assetManager.maxDefaultLoads;
}
deleteCache(cacheId) {
this.assetManager.cache.empty(cacheId);
return this;
}
cached(id, cacheId = this._activeCache) {
return this.assetManager.cache.read(id, cacheId);
}
}
exports.default = LoaderPlugin;
},{"./AssetManager":3,"./AssetToken":4,"./AssetUtils":5,"./errors/LoaderError":7,"./tasks/FunctionTask":17,"./tasks/ListTask":18,"./tasks/LoadTask":19,"./tasks/Task":20}],7:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class LoaderError extends Error {
constructor(originalError, request, message) {
message = message ? message + ': ' + originalError.message : originalError.message;
super(message);
this.originalError = originalError;
this.request = request;
Object.setPrototypeOf(this, LoaderError.prototype);
this.name = 'LoaderError';
this.message = message || 'load error';
this.stack = new Error().stack;
}
toString() {
return this.name + ': ' + this.message;
}
}
exports.default = LoaderError;
},{}],8:[function(require,module,exports){
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./LoaderError"));
var LoaderError_1 = require("./LoaderError");
exports.LoaderError = LoaderError_1.default;
},{"./LoaderError":7}],9:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const LoaderError_1 = require("../errors/LoaderError");
const path = require("path");
var FILETYPE;
(function (FILETYPE) {
FILETYPE.IMAGE = 'image';
FILETYPE.BINARY = 'binary';
FILETYPE.JSON = 'json';
FILETYPE.XML = 'xml';
FILETYPE.CSS = 'css';
FILETYPE.JAVASCRIPT = 'js';
FILETYPE.SVG = 'svg';
FILETYPE.TEXT = 'text';
FILETYPE.HTML = 'html';
})(FILETYPE = exports.FILETYPE || (exports.FILETYPE = {}));
class AbstractLoader {
prepare(url) {
return url;
}
load(uri, callback, options) {
let type = this.getFileType(uri);
if (options && options.format) {
type = options.format;
}
this.internalLoad(type, uri, callback, options);
}
internalLoad(type, uri, callback, options) {
}
createError(err, uri, message) {
return new LoaderError_1.default(typeof err === 'string' ? new Error(err) : err, uri, message);
}
internalDone(type, uri, data, callback) {
switch (type) {
case FILETYPE.SVG:
this.parseDOM('image/svg+xml', uri, data, callback);
break;
case FILETYPE.XML:
this.parseDOM('application/xml', uri, data, callback);
break;
case FILETYPE.HTML:
this.parseDOM('text/html', uri, data, callback);
break;
case FILETYPE.CSS:
this.parseStyle(data, callback);
break;
case FILETYPE.JSON:
this.parseJSON(uri, data, callback);
break;
default:
callback(null, data);
break;
}
}
parseDOM(parseType, uri, data, callback) {
try {
const parser = new DOMParser();
const object = parser.parseFromString(data, parseType);
callback(null, object);
}
catch (e) {
callback(this.createError(e, uri));
}
}
parseStyle(data, callback) {
const style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = data;
callback(null, style);
}
parseJSON(uri, data, callback) {
try {
data = JSON.parse(data);
}
catch (e) {
return callback(this.createError(e, uri, 'Failed to parse JSON'));
}
callback(null, data);
}
getFileType(uri) {
const extension = path.extname(uri).toLowerCase();
switch (extension) {
case '.jpeg':
case '.jpg':
case '.gif':
case '.png':
case '.webp':
case '.bmp':
return FILETYPE.IMAGE;
case '.json':
case '.keys':
case '.bt':
case '.assets':
case '.anim':
return FILETYPE.JSON;
case '.xml':
return FILETYPE.XML;
case '.css':
return FILETYPE.CSS;
case '.js':
return FILETYPE.JAVASCRIPT;
case '.svg':
return FILETYPE.SVG;
case '.xml':
return FILETYPE.XML;
case '.html':
case '.htm':
case '.xhtml':
return FILETYPE.HTML;
default:
return FILETYPE.TEXT;
}
}
}
exports.default = AbstractLoader;
},{"../errors/LoaderError":7,"path":undefined}],10:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jibo_plugins_1 = require("jibo-plugins");
const AbstractLoader_1 = require("./AbstractLoader");
const path = require("path");
const fs = require("fs");
var MIMETYPE;
(function (MIMETYPE) {
MIMETYPE.jpg = 'image/jpeg';
MIMETYPE.jpeg = 'image/jpeg';
MIMETYPE.gif = 'image/gif';
MIMETYPE.png = 'image/png';
MIMETYPE.bmp = 'image/bmp';
MIMETYPE.webp = 'image/webp';
})(MIMETYPE || (MIMETYPE = {}));
class LocalLoader extends AbstractLoader_1.default {
constructor() {
super(...arguments);
this.basePath = '';
}
prepare(uri) {
if (!path.isAbsolute(uri) && !/^(https?|file)\:\/\//.test(uri)) {
uri = jibo_plugins_1.PathUtils.getAssetUri(uri, undefined, this.basePath);
uri = path.resolve(uri);
}
return uri;
}
internalLoad(type, uri, callback, options) {
if (!path.isAbsolute(uri)) {
uri = jibo_plugins_1.PathUtils.getAssetUri(uri, undefined, this.basePath);
uri = path.resolve(uri);
}
fs.readFile(uri, this.getEncodingType(type), (err, data) => {
if (err) {
return callback(this.createError(err, uri, `Unable to read ${type} file at ${uri}`));
}
switch (type) {
case AbstractLoader_1.FILETYPE.IMAGE:
const mimeType = this.getImageMimeType(uri);
const result = new Image();
result.src = `data:${mimeType};base64,${data}`;
callback(null, result);
break;
case AbstractLoader_1.FILETYPE.JAVASCRIPT:
try {
const result = require(uri);
callback(null, result);
}
catch (e) {
callback(this.createError(e, uri, 'Unable to read JavaScript file'));
}
break;
default:
this.internalDone(type, uri, data, callback);
break;
}
});
}
getEncodingType(type) {
switch (type) {
case AbstractLoader_1.FILETYPE.IMAGE:
return 'base64';
case AbstractLoader_1.FILETYPE.JSON:
case AbstractLoader_1.FILETYPE.CSS:
case AbstractLoader_1.FILETYPE.XML:
case AbstractLoader_1.FILETYPE.SVG:
case AbstractLoader_1.FILETYPE.HTML:
case AbstractLoader_1.FILETYPE.TEXT:
default:
return 'utf8';
}
}
getImageMimeType(uri) {
let extension = path.extname(uri).toLowerCase();
if (extension) {
extension = extension.substr(1);
}
return MIMETYPE[extension] || null;
}
}
exports.default = LocalLoader;
},{"./AbstractLoader":9,"fs":undefined,"jibo-plugins":undefined,"path":undefined}],11:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const AbstractLoader_1 = require("./AbstractLoader");
const ImageResource_1 = require("./remote/ImageResource");
const TextResource_1 = require("./remote/TextResource");
const BinaryResource_1 = require("./remote/BinaryResource");
class RemoteLoader extends AbstractLoader_1.default {
constructor() {
super(...arguments);
this.baseUrl = '';
}
prepare(url) {
if (this.baseUrl.length
&& this.baseUrl.lastIndexOf('/') !== this.baseUrl.length - 1
&& url.charAt(0) !== '/') {
return this.baseUrl + '/' + url;
}
return this.baseUrl + url;
}
internalLoad(type, url, callback, options) {
options = options || {};
let resource;
if (type === AbstractLoader_1.FILETYPE.IMAGE) {
resource = new ImageResource_1.default(type, url, callback, options);
}
else if (type === AbstractLoader_1.FILETYPE.BINARY) {
resource = new BinaryResource_1.default(type, url, callback, options);
}
else {
resource = new TextResource_1.default(type, url, callback, options);
}
resource.onComplete = (err, resource) => {
if (err) {
return resource.callback(this.createError(err, url));
}
if (resource.type === AbstractLoader_1.FILETYPE.JAVASCRIPT) {
const script = document.createElement('script');
script.innerHTML = String(resource.result);
script.dataset['url'] = resource.url;
resource.callback(null, script);
}
else if (resource.type === AbstractLoader_1.FILETYPE.IMAGE) {
resource.callback(null, resource.result);
}
else {
this.internalDone(resource.type, resource.url, resource.result, resource.callback);
}
};
resource.start();
}
}
exports.default = RemoteLoader;
},{"./AbstractLoader":9,"./remote/BinaryResource":12,"./remote/ImageResource":13,"./remote/TextResource":15}],12:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const http = require("http");
const Resource_1 = require("./Resource");
class BinaryResource extends Resource_1.default {
start() {
http.get(this.url, (res) => {
const data = [];
res.on('data', (chunk) => {
data.push(chunk);
}).on('end', () => {
this.result = Buffer.concat(data);
this.complete();
}).on('error', (e) => {
this.complete(e);
});
});
}
}
exports.default = BinaryResource;
},{"./Resource":14,"http":undefined}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Resource_1 = require("./Resource");
class ImageResource extends Resource_1.default {
constructor(type, url, callback, options) {
super(type, url, callback, options);
this.onError = this.onError.bind(this);
this.onLoad = this.onLoad.bind(this);
this.onTimeout = this.onTimeout.bind(this);
const result = this.result = new Image();
options = options || {};
if (options.crossOrigin) {
result.crossOrigin = options.crossOrigin;
}
result.addEventListener('error', this.onError, false);
result.addEventListener('load', this.onLoad, false);
if (options.timeout) {
this.timeoutId = setTimeout(this.onTimeout, options.timeout);
}
}
destroy() {
if (this.timeoutId) {
clearTimeout(this.timeoutId);
this.timeoutId = null;
}
if (this.result) {
this.result.removeEventListener('error', this.onError);
this.result.removeEventListener('load', this.onLoad);
}
this.onError = null;
this.onLoad = null;
this.onTimeout = null;
this.result = null;
super.destroy();
}
start() {
this.result.src = this.url;
}
onError() {
this.complete('Failed to load element using <IMG>');
}
onLoad() {
this.complete();
}
}
exports.default = ImageResource;
},{"./Resource":14}],14:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Resource {
constructor(type, url, callback, options) {
this.type = type;
this.url = url;
this.callback = callback;
this.options = options;
this.options = options || {};
}
start() {
}
complete(err) {
this.onComplete(err, this);
this.destroy();
}
onTimeout() {
this.complete('Request timed out.');
}
destroy() {
this.onComplete = null;
this.callback = null;
this.result = null;
this.options = null;
this.url = null;
this.type = null;
}
}
exports.default = Resource;
},{}],15:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Resource_1 = require("./Resource");
const STATUS_NONE = 0;
const STATUS_OK = 200;
const STATUS_EMPTY = 204;
class TextResource extends Resource_1.default {
constructor(type, url, callback, options) {
super(type, url, callback, options);
this.onError = this.onError.bind(this);
this.onAbort = this.onAbort.bind(this);
this.onLoad = this.onLoad.bind(this);
this.onTimeout = this.onTimeout.bind(this);
const request = new XMLHttpRequest();
request.responseType = 'text';
options = options || {};
if (options.timeout) {
request.timeout = options.timeout;
request.addEventListener('timeout', this.onTimeout, false);
}
request.addEventListener('error', this.onError, false);
request.addEventListener('abort', this.onAbort, false);
request.addEventListener('load', this.onLoad, false);
this.request = request;
}
start() {
this.request.open('GET', this.url, true);
this.request.send();
}
destroy() {
super.destroy();
if (this.request) {
this.request.removeEventListener('error', this.onError);
this.request.removeEventListener('abort', this.onAbort);
this.request.removeEventListener('load', this.onLoad);
this.request.removeEventListener('timeout', this.onTimeout);
}
this.onError = null;
this.onAbort = null;
this.onLoad = null;
this.onTimeout = null;
this.request = null;
}
onLoad() {
const request = this.request;
const status = request.status;
if (status === STATUS_OK || status === STATUS_EMPTY || (status === STATUS_NONE && request.responseText.length > 0)) {
this.result = request.response || request.responseText;
}
else {
return this.complete('[' + request.status + ']' + request.statusText + ':' + request.responseURL);
}
this.complete();
}
onError() {
this.complete(this.reqType() + ' Request failed. '
+ 'Status: ' + this.request.status + ', text: "' + this.request.statusText + '"');
}
onAbort() {
this.complete(this.reqType() + ' Request was aborted by the user.');
}
reqType() {
return this.request.toString().replace('object ', '');
}
}
exports.default = TextResource;
},{"./Resource":14}],16:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jibo_log_1 = require("jibo-log");
exports.default = new jibo_log_1.Log('Jibo.Loader');
},{"jibo-log":undefined}],17:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Task_1 = require("./Task");
class FunctionTask extends Task_1.default {
static test(asset) {
return !!asset.async;
}
constructor(manager, asset) {
super(manager, asset);
this.async = asset.async;
}
start(callback) {
this.async(callback);
}
destroy() {
super.destroy();
this.async = null;
}
}
exports.default = FunctionTask;
},{"./Task":20}],18:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Task_1 = require("./Task");
const AssetUtils_1 = require("../AssetUtils");
class ListTask extends Task_1.default {
static test(asset) {
return !!asset.assets && (Array.isArray(asset.assets) || AssetUtils_1.default.isPlain(asset.assets));
}
constructor(manager, asset) {
super(manager, asset);
this.assets = asset.assets;
this.cacheAll = asset.cacheAll;
this.remoteAll = asset.remoteAll;
this.progress = asset.progress;
}
start(callback) {
this.load(this.assets, {
complete: callback,
progress: this.progress,
cacheAll: this.cacheAll,
remoteAll: this.remoteAll
});
}
destroy() {
super.destroy();
this.assets = null;
}
}
exports.default = ListTask;
},{"../AssetUtils":5,"./Task":20}],19:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Task_1 = require("./Task");
class LoadTask extends Task_1.default {
static test(asset) {
return !!asset.src;
}
constructor(manager, asset) {
super(manager, asset, asset.src);
this.src = this.prepare(asset.src);
}
start(callback) {
this.simpleLoad(this.src, callback, {
remote: this.remote,
timeout: this.timeout,
format: this.format
});
}
}
exports.default = LoadTask;
},{"./Task":20}],20:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const AssetManager_1 = require("../AssetManager");
const path = require("path");
const log_1 = require("../log");
const log = log_1.default.createChild('Task');
class Task {
constructor(manager, asset, fallbackId) {
this.manager = manager;
this.pending = null;
this.status = Task.WAITING;
this.complete = asset.complete || null;
this.cache = asset.cache === undefined ? null : asset.cache;
this.id = asset.id || null;
this.remote = asset.remote === undefined ? false : asset.remote;
this.timeout = asset.timeout || 0;
this.format = asset.format || null;
this.original = asset;
if (this.cache && !this.id) {
if (fallbackId && typeof fallbackId === "string") {
asset.id = this.id = path.parse(fallbackId).name;
}
if (!this.id) {
log.debug("Caching an asset requires an id, none set", asset);
this.cache = null;
}
}
this.cacheKey = AssetManager_1.getCacheKeyFromAsset(asset, this.manager);
this.needsCache = false;
this.subAssets = [];
this.token = null;
}
start(callback) {
}
load(source, options) {
if (typeof options === "function") {
options = { complete: options };
}
const load = this.manager.load(source, options);
if (this.cache) {
this.subAssets.push(...load.tokens);
}
return load;
}
simpleLoad(url, complete, options) {
this.manager.simpleLoad(url, complete, options || {
remote: this.remote,
timeout: this.timeout,
format: this.format
});
}
prepare(uri) {
return this.manager.prepare(uri, this.remote);
}
destroy() {
this.pending = null;
this.manager = null;
this.status = Task.FINISHED;
this.id = null;
this.complete = null;
this.original = null;
}
}
Task.WAITING = 0;
Task.RUNNING = 1;
Task.FINISHED = 2;
exports.default = Task;
},{"../AssetManager":3,"../log":16,"path":undefined}],21:[function(require,module,exports){
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./FunctionTask"));
__export(require("./ListTask"));
__export(require("./LoadTask"));
__export(require("./Task"));
var FunctionTask_1 = require("./FunctionTask");
exports.FunctionTask = FunctionTask_1.default;
var ListTask_1 = require("./ListTask");
exports.ListTask = ListTask_1.default;
var LoadTask_1 = require("./LoadTask");
exports.LoadTask = LoadTask_1.default;
var Task_1 = require("./Task");
exports.Task = Task_1.default;
},{"./FunctionTask":17,"./ListTask":18,"./LoadTask":19,"./Task":20}],22:[function(require,module,exports){
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./tasks"));
__export(require("./errors"));
__export(require("./AssetCache"));
__export(require("./AssetLoad"));
__export(require("./AssetManager"));
__export(require("./AssetUtils"));
__export(require("./LoaderPlugin"));
var AssetLoad_1 = require("./AssetLoad");
exports.AssetLoad = AssetLoad_1.default;
var AssetToken_1 = require("./AssetToken");
exports.AssetToken = AssetToken_1.default;
var AssetManager_1 = require("./AssetManager");
exports.AssetManager = AssetManager_1.default;
var AssetUtils_1 = require("./AssetUtils");
exports.AssetUtils = AssetUtils_1.default;
var LoaderPlugin_1 = require("./LoaderPlugin");
exports.LoaderPlugin = LoaderPlugin_1.default;
},{"./AssetCache":1,"./AssetLoad":2,"./AssetManager":3,"./AssetToken":4,"./AssetUtils":5,"./LoaderPlugin":6,"./errors":8,"./tasks":21}]},{},[22])(22)
});
//# sourceMappingURL=jibo-loader.js.map