/** * @ignore * setup data structure for kissy loader * @author yiminghe@gmail.com */ (function (S) { var Loader = S.Loader, Path = S.Path, IGNORE_PACKAGE_NAME_IN_URI = 'ignorePackageNameInUri', Utils = Loader.Utils; function forwardSystemPackage(self, property) { return property in self ? self[property] : self.runtime.Config[property]; } /** * @class KISSY.Loader.Package * @private * This class should not be instantiated manually. */ function Package(cfg) { S.mix(this, cfg); } S.augment(Package, { reset: function (cfg) { S.mix(this, cfg); }, /** * Tag for package. * tag can not contain ".", eg: Math.random() ! * @return {String} */ getTag: function () { return forwardSystemPackage(this, 'tag'); }, /** * Get package name. * @return {String} */ getName: function () { return this.name; }, /** * Get package base. * @return {String} */ 'getBase': function () { return forwardSystemPackage(this, 'base'); }, getPrefixUriForCombo: function () { var self = this, packageName = self.getName(); return self.getBase() + ( packageName && !self.isIgnorePackageNameInUri() ? (packageName + '/') : '' ); }, /** * get package uri */ getPackageUri: function () { var self = this; if (self.packageUri) { return self.packageUri; } return self.packageUri = new S.Uri(this.getPrefixUriForCombo()); }, /** * Get package baseUri * @return {KISSY.Uri} */ getBaseUri: function () { return forwardSystemPackage(this, 'baseUri'); }, /** * Whether is debug for this package. * @return {Boolean} */ isDebug: function () { return forwardSystemPackage(this, 'debug'); }, /** * whether request mod file without insert package name into package base * @return {Boolean} */ isIgnorePackageNameInUri: function () { return forwardSystemPackage(this, IGNORE_PACKAGE_NAME_IN_URI); }, /** * Get charset for package. * @return {String} */ getCharset: function () { return forwardSystemPackage(this, 'charset'); }, /** * Whether modules are combined for this package. * @return {Boolean} */ isCombine: function () { return forwardSystemPackage(this, 'combine'); }, /** * Get package group (for combo). * @returns {String} */ getGroup: function () { return forwardSystemPackage(this, 'group'); } }); Loader.Package = Package; /** * @class KISSY.Loader.Module * @private * This class should not be instantiated manually. */ function Module(cfg) { this.status = Loader.Status.INIT; S.mix(this, cfg); this.waitedCallbacks = []; } S.augment(Module, { wait: function (callback) { this.waitedCallbacks.push(callback); }, notifyAll: function () { var callback; var len = this.waitedCallbacks.length, i = 0; for (; i < len; i++) { callback = this.waitedCallbacks[i]; try { callback(this); } catch (e) { setTimeout(function () { throw e; }, 0); } } this.waitedCallbacks = []; }, /** * Set the value of current module * @param v value to be set */ 'setValue': function (v) { this.value = v; }, /** * Get the type if current Module * @return {String} css or js */ getType: function () { var self = this, v = self.type; if (!v) { if (Path.extname(self.name).toLowerCase() == '.css') { v = 'css'; } else { v = 'js'; } self.type = v; } return v; }, /** * Get the fullpath uri of current module if load dynamically * @return {KISSY.Uri} */ getFullPathUri: function () { var self = this, t, fullPathUri, packageBaseUri, packageInfo, packageName, path; if (!self.fullPathUri) { if (self.fullpath) { fullPathUri = new S.Uri(self.fullpath); } else { packageInfo = self.getPackage(); packageBaseUri = packageInfo.getBaseUri(); path = self.getPath(); // #262 if (packageInfo.isIgnorePackageNameInUri() && // native mod does not allow ignore package name (packageName = packageInfo.getName())) { path = Path.relative(packageName, path); } fullPathUri = packageBaseUri.resolve(path); if (t = self.getTag()) { t += '.' + self.getType(); fullPathUri.query.set('t', t); } } self.fullPathUri = fullPathUri; } return self.fullPathUri; }, /** * Get the fullpath of current module if load dynamically * @return {String} */ getFullPath: function () { var self = this, fullPathUri; if (!self.fullpath) { fullPathUri = self.getFullPathUri(); self.fullpath = Utils.getMappedPath(self.runtime, fullPathUri.toString()); } return self.fullpath; }, /** * Get the path (without package base) * @return {String} */ getPath: function () { var self = this; return self.path || (self.path = defaultComponentJsName(self)) }, /** * Get the value of current module * @return {*} */ getValue: function () { return this.value; }, /** * Get the name of current module * @return {String} */ getName: function () { return this.name; }, /** * Get the package which current module belongs to. * @return {KISSY.Loader.Package} */ getPackage: function () { var self = this; return self.packageInfo || (self.packageInfo = getPackage(self.runtime, self.name)); }, /** * Get the tag of current module. * tag can not contain ".", eg: Math.random() ! * @return {String} */ getTag: function () { var self = this; return self.tag || self.getPackage().getTag(); }, /** * Get the charset of current module * @return {String} */ getCharset: function () { var self = this; return self.charset || self.getPackage().getCharset(); }, /** * Get module objects required by this module * @return {KISSY.Loader.Module[]} */ 'getRequiredMods': function () { var self = this, runtime = self.runtime; return S.map(self.getNormalizedRequires(), function (r) { return Utils.createModuleInfo(runtime, r); }); }, getRequiresWithAlias: function () { var self = this, requiresWithAlias = self.requiresWithAlias, requires = self.requires; if (!requires || requires.length == 0) { return requires || []; } else if (!requiresWithAlias) { self.requiresWithAlias = requiresWithAlias = Utils.normalizeModNamesWithAlias(self.runtime, requires, self.name); } return requiresWithAlias; }, /** * Get module names required by this module * @return {KISSY.Loader.Module[]} */ getNormalizedRequires: function () { var self = this, normalizedRequires, normalizedRequiresStatus = self.normalizedRequiresStatus, status = self.status, requires = self.requires; if (!requires || requires.length == 0) { return requires || []; } else if ((normalizedRequires = self.normalizedRequires) && // 事先声明的依赖不能当做 loaded 状态下真正的依赖 (normalizedRequiresStatus == status)) { return normalizedRequires; } else { self.normalizedRequiresStatus = status; return self.normalizedRequires = Utils.normalizeModNames(self.runtime, requires, self.name); } } }); Loader.Module = Module; function defaultComponentJsName(m) { var name = m.name, extname = '.' + m.getType(), min = '-min'; name = Path.join(Path.dirname(name), Path.basename(name, extname)); if (m.getPackage().isDebug()) { min = ''; } return name + min + extname; } var systemPackage = new Package({ name: '', runtime: S }); function getPackage(self, modName) { var packages = self.config('packages'), modNameSlash = modName + '/', pName = '', p; for (p in packages) { if (S.startsWith(modNameSlash, p + '/') && p.length > pName.length) { pName = p; } } return packages[pName] || systemPackage; } })(KISSY);