import { findHelper } from 'discourse-common/lib/helpers'; /* global requirejs, require */ var classify = Ember.String.classify; var get = Ember.get; const _options = {}; export function setResolverOption(name, value) { _options[name] = value; } export function getResolverOption(name) { return _options[name]; } function parseName(fullName) { const nameParts = fullName.split(":"); const type = nameParts[0]; let fullNameWithoutType = nameParts[1]; const namespace = get(this, 'namespace'); const root = namespace; return { fullName, type, fullNameWithoutType, name: fullNameWithoutType, root, resolveMethodName: "resolve" + classify(type) }; } export function buildResolver(baseName) { return Ember.DefaultResolver.extend({ parseName, resolveRouter(parsedName) { const routerPath = `${baseName}/router`; if (requirejs.entries[routerPath]) { const module = requirejs(routerPath, null, null, true); return module.default; } return this._super(parsedName); }, normalize(fullName) { const split = fullName.split(':'); if (split.length > 1) { const appBase = `${baseName}/${split[0]}s/`; const adminBase = 'admin/' + split[0] + 's/'; // Allow render 'admin/templates/xyz' too split[1] = split[1].replace('.templates', '').replace('/templates', ''); // Try slashes let dashed = Ember.String.dasherize(split[1].replace(/\./g, '/')); if (requirejs.entries[appBase + dashed] || requirejs.entries[adminBase + dashed]) { return split[0] + ":" + dashed; } // Try with dashes instead of slashes dashed = Ember.String.dasherize(split[1].replace(/\./g, '-')); if (requirejs.entries[appBase + dashed] || requirejs.entries[adminBase + dashed]) { return split[0] + ":" + dashed; } } return this._super(fullName); }, customResolve(parsedName) { // If we end with the name we want, use it. This allows us to define components within plugins. const suffix = parsedName.type + 's/' + parsedName.fullNameWithoutType, dashed = Ember.String.dasherize(suffix), moduleName = Object.keys(requirejs.entries).find(function(e) { return (e.indexOf(suffix, e.length - suffix.length) !== -1) || (e.indexOf(dashed, e.length - dashed.length) !== -1); }); var module; if (moduleName) { module = requirejs(moduleName, null, null, true /* force sync */); if (module && module['default']) { module = module['default']; } } return module; }, resolveWidget(parsedName) { return this.customResolve(parsedName) || this._super(parsedName); }, resolveAdapter(parsedName) { return this.customResolve(parsedName) || this._super(parsedName); }, resolveModel(parsedName) { return this.customResolve(parsedName) || this._super(parsedName); }, resolveView(parsedName) { return this.customResolve(parsedName) || this._super(parsedName); }, resolveHelper(parsedName) { return findHelper(parsedName.fullNameWithoutType) || this.customResolve(parsedName) || this._super(parsedName); }, resolveController(parsedName) { return this.customResolve(parsedName) || this._super(parsedName); }, resolveComponent(parsedName) { return this.customResolve(parsedName) || this._super(parsedName); }, resolveService(parsedName) { return this.customResolve(parsedName) || this._super(parsedName); }, resolveRoute(parsedName) { return this.customResolve(parsedName) || this._super(parsedName); }, findLoadingTemplate(parsedName) { if (parsedName.fullNameWithoutType.match(/loading$/)) { return Ember.TEMPLATES.loading; } }, findConnectorTemplate(parsedName) { const full = parsedName.fullNameWithoutType.replace('components/', ''); if (full.indexOf('connectors') === 0) { return Ember.TEMPLATES[`javascripts/${full}`]; } }, resolveTemplate(parsedName) { return this.findPluginMobileTemplate(parsedName) || this.findPluginTemplate(parsedName) || this.findMobileTemplate(parsedName) || this.findTemplate(parsedName) || this.findLoadingTemplate(parsedName) || this.findConnectorTemplate(parsedName) || Ember.TEMPLATES.not_found; }, findPluginTemplate(parsedName) { const pluginParsedName = this.parseName(parsedName.fullName.replace("template:", "template:javascripts/")); return this.findTemplate(pluginParsedName); }, findPluginMobileTemplate(parsedName) { if (_options.mobileView) { var pluginParsedName = this.parseName(parsedName.fullName.replace("template:", "template:javascripts/mobile/")); return this.findTemplate(pluginParsedName); } }, findMobileTemplate(parsedName) { if (_options.mobileView) { var mobileParsedName = this.parseName(parsedName.fullName.replace("template:", "template:mobile/")); return this.findTemplate(mobileParsedName); } }, findTemplate(parsedName) { const withoutType = parsedName.fullNameWithoutType, slashedType = withoutType.replace(/\./g, '/'), decamelized = withoutType.decamelize(), dashed = decamelized.replace(/\./g, '-').replace(/\_/g, '-'), templates = Ember.TEMPLATES; return this._super(parsedName) || templates[slashedType] || templates[withoutType] || templates[withoutType.replace(/\.raw$/, '')] || templates[dashed] || templates[decamelized.replace(/\./, '/')] || templates[decamelized.replace(/\_/, '/')] || templates[`${baseName}/templates/${withoutType}`] || this.findAdminTemplate(parsedName) || this.findUnderscoredTemplate(parsedName); }, findUnderscoredTemplate(parsedName) { var decamelized = parsedName.fullNameWithoutType.decamelize(); var underscored = decamelized.replace(/\-/g, "_"); return Ember.TEMPLATES[underscored]; }, // Try to find a template within a special admin namespace, e.g. adminEmail => admin/templates/email // (similar to how discourse lays out templates) findAdminTemplate(parsedName) { var decamelized = parsedName.fullNameWithoutType.decamelize(); if (decamelized.indexOf('components') === 0) { let comPath = `admin/templates/${decamelized}`; const compTemplate = Ember.TEMPLATES[`javascripts/${comPath}`] || Ember.TEMPLATES[comPath]; if (compTemplate) { return compTemplate; } } if (decamelized === "javascripts/admin") { return Ember.TEMPLATES['admin/templates/admin']; } if (decamelized.indexOf('admin') === 0 || decamelized.indexOf('javascripts/admin') === 0) { decamelized = decamelized.replace(/^admin\_/, 'admin/templates/'); decamelized = decamelized.replace(/^admin\./, 'admin/templates/'); decamelized = decamelized.replace(/\./g, '_'); const dashed = decamelized.replace(/_/g, '-'); return Ember.TEMPLATES[decamelized] || Ember.TEMPLATES[dashed] || Ember.TEMPLATES[dashed.replace('admin-', 'admin/')]; } } }); }