(function privateDependencyClosure () { /** * This primitive class represents Dependency, * just to make the work a bit more structured * */ class Dependency { constructor (name, contentType) { this.name = name; this.contentType = contentType; } /** * This function goes through an array of strings and number to make sense of it * * @param {Array} deps - an array of strings and numbers * * @returns Array * */ static refineDependencies (deps) { const result = []; const collection = Object.create(null); for (let i = 0; i < deps.length; ++i) { let element = deps[i]; const elementType = typeof element if (!collection[element] && elementType === "string") { result.push(new Dependency(element)); collection[element] = true; } else if (result.length > 0 && elementType === "number" && ReverseType[element] !== undefined) { let prevResult = result[result.length - 1]; if (deps[i - 1] === prevResult.name) prevResult.contentType = element; } } return result } /** * Checks one type against another and writes a warning if they don't match * * @param {Type} original * @param {Type} current * @param {String} path * */ static checkContentType (original, current, path) { if (original !== current) { const originalType = ReverseType[original]; const currentType = ReverseType[current]; console.warn("Mimicry error: file " + path + " was originally requested as " + originalType + " but next time it was requested as " + currentType + " ignoring second request type and treating file as " + originalType ); } } /** * Refines path turning all meta information into a path to query * * @typedef Mimicry.Type Type * * @param {String} path - a source path * @param {Type} type - type of the content * @param {String} baseUrl - path to all project files * @param {Map} types - collection of paths to specific content types * @param {Map} libs - collection of paths to libraries * * @returns {String} * */ static refinePath (path, type, baseUrl, types, libs) { const suffix = suffixes[type]; const typePath = types.get(type) || ""; if (!path.endsWith(suffix)) path += suffix; switch (type) { case Type.js: if (path[0] === "@") { const hops = path.split("/"); const libName = hops[0].slice(1); let libPath = libs.get(libName); if (libPath === undefined) libPath = libName; path = baseUrl + libPath + path.slice(libName.length + 1); } else { path = baseUrl + typePath + path; } break; default: path = baseUrl + typePath + path; break; } return path; } /** * @param {Array} dependencies - list of module names that this module depends on * @param {Function} [callback] - module body that will be executed as soon all dependencies are resolved * */ static refineModuleArguments (dependencies, callback) { let deps, body; if (dependencies instanceof Function) { body = dependencies; deps = []; } else { deps = dependencies; body = callback; } deps = this.refineDependencies(deps); return {deps, body}; } /** * @param {String} href - script DOM element that launched this function * @param {String} baseUrl - path to all project files * @param {Map} types - collection of paths to specific content types * @param {Map} libs - collection of paths to libraries * */ static nameFromHref (href, baseUrl, types, libs) { const suffix = suffixes[Type.js]; const typePath = types.get(Type.js) || ""; if (href.endsWith(suffix)) href = href.slice(0, -suffix.length); if (baseUrl.length) { const baseIndex = href.indexOf(baseUrl); if (baseIndex !== 0) console.warn("Module path " + href + " doesn't start with baseUrl " + baseUrl + ", this is probably an error"); else href = href.slice(baseUrl.length); } let foundAmongLibs = false; for (const [libName, libPath] of libs) { const index = href.indexOf(libPath); if (index === 0) { href = "@" + libName + href.slice(libPath.length); foundAmongLibs = true; break; } } if (!foundAmongLibs && typePath.length) { const typeIndex = href.indexOf(typePath); if (typeIndex !== 0) console.warn("Module path " + href + " doesn't start with a proper type path " + typePath + ", this is probably an error"); else href = href.slice(typePath.length + 1); } return href; } static get Type () {return Type;} static getTypeTitle (/*Type*/type) {return ReverseType[type];} } const Type = { none: 0, //just to prevent implicit situations, DON'T USE IT! js: 1, css: 2, json: 3, binary: 4, text: 5 }; const suffixes = ["", ".js", ".css", ".json", "", ""]; const ReverseType = ["None", "JavaScript", "CSS", "JSON", "Binary", "Text"]; Object.freeze(Type); Object.freeze(suffixes); Object.freeze(ReverseType); if (typeof module === 'object' && module.exports) module.exports = Dependency; else window.__MimicryDependency__ = Dependency; })();