mirror of
https://github.com/discourse/discourse.git
synced 2025-01-07 16:02:29 +08:00
f5d391a48a
AppEvents was always a service object in disguise, so we should move it to the correct place in the application. Doing this allows other service objects to inject it easily without container access. In the future we should also deprecate `this.appEvents` without an explicit injection too.
262 lines
7.8 KiB
JavaScript
262 lines
7.8 KiB
JavaScript
import { findHelper } from "discourse-common/lib/helpers";
|
|
import deprecated from "discourse-common/lib/deprecated";
|
|
|
|
/* 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) {
|
|
if (fullName === "app-events:main") {
|
|
deprecated(
|
|
"`app-events:main` has been replaced with `service:app-events`",
|
|
{ since: "2.4.0" }
|
|
);
|
|
return "service:app-events";
|
|
}
|
|
|
|
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/")]
|
|
);
|
|
}
|
|
}
|
|
});
|
|
}
|