103 lines
2.6 KiB
JavaScript
103 lines
2.6 KiB
JavaScript
const pluginRegex = /^discourse\/plugins\/([^\/]+)\/(.*)$/;
|
|
const themeRegex = /^discourse\/theme-([^\/]+)\/(.*)$/;
|
|
|
|
function appendToCache(cache, key, value) {
|
|
let cachedValue = cache.get(key);
|
|
cachedValue ??= [];
|
|
cachedValue.push(value);
|
|
cache.set(key, cachedValue);
|
|
}
|
|
|
|
const NAMESPACES = ["discourse/", "wizard/", "admin/"];
|
|
|
|
function isInRecognisedNamespace(moduleName) {
|
|
for (const ns of NAMESPACES) {
|
|
if (moduleName.startsWith(ns)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function isTemplate(moduleName) {
|
|
return moduleName.includes("/templates/");
|
|
}
|
|
|
|
/**
|
|
* This class provides takes set of core/plugin/theme modules, finds the template modules,
|
|
* and makes an efficient lookup table for the resolver to use. It takes care of sourcing
|
|
* component/route templates from themes/plugins, and also handles template overrides.
|
|
*/
|
|
class DiscourseTemplateMap {
|
|
coreTemplates = new Map();
|
|
pluginTemplates = new Map();
|
|
themeTemplates = new Map();
|
|
prioritizedCaches = [
|
|
this.themeTemplates,
|
|
this.pluginTemplates,
|
|
this.coreTemplates,
|
|
];
|
|
|
|
/**
|
|
* Reset the TemplateMap to use the supplied module names. It is expected that the list
|
|
* will be generated using `Object.keys(requirejs.entries)`.
|
|
*/
|
|
setModuleNames(moduleNames) {
|
|
this.coreTemplates.clear();
|
|
this.pluginTemplates.clear();
|
|
this.themeTemplates.clear();
|
|
for (const moduleName of moduleNames) {
|
|
if (isInRecognisedNamespace(moduleName) && isTemplate(moduleName)) {
|
|
this.#add(moduleName);
|
|
}
|
|
}
|
|
}
|
|
|
|
#add(originalPath) {
|
|
let path = originalPath;
|
|
|
|
let pluginMatch, themeMatch, cache;
|
|
if ((pluginMatch = path.match(pluginRegex))) {
|
|
path = pluginMatch[2];
|
|
cache = this.pluginTemplates;
|
|
} else if ((themeMatch = path.match(themeRegex))) {
|
|
path = themeMatch[2];
|
|
cache = this.themeTemplates;
|
|
} else {
|
|
cache = this.coreTemplates;
|
|
}
|
|
|
|
path = path.replace(/^discourse\/templates\//, "");
|
|
|
|
appendToCache(cache, path, originalPath);
|
|
}
|
|
|
|
/**
|
|
* Resolve a template name to a module name, taking into account
|
|
* theme/plugin namespaces and overrides.
|
|
*/
|
|
resolve(name) {
|
|
for (const cache of this.prioritizedCaches) {
|
|
const val = cache.get(name);
|
|
if (val) {
|
|
return val[val.length - 1];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* List all available template keys, after theme/plugin namespaces have
|
|
* been stripped.
|
|
*/
|
|
keys() {
|
|
const uniqueKeys = new Set([
|
|
...this.coreTemplates.keys(),
|
|
...this.pluginTemplates.keys(),
|
|
...this.themeTemplates.keys(),
|
|
]);
|
|
return [...uniqueKeys];
|
|
}
|
|
}
|
|
|
|
export default new DiscourseTemplateMap();
|