diff --git a/public/scripts/slash-commands/SlashCommand.js b/public/scripts/slash-commands/SlashCommand.js
index 249c950b7..e5094095a 100644
--- a/public/scripts/slash-commands/SlashCommand.js
+++ b/public/scripts/slash-commands/SlashCommand.js
@@ -35,202 +35,252 @@ export class SlashCommand {
/**@type {SlashCommandNamedArgument[]}*/ namedArgumentList = [];
/**@type {SlashCommandArgument[]}*/ unnamedArgumentList = [];
- get helpStringFormatted() {
- let aliases = '';
- if (this.aliases?.length > 0) {
- aliases = ' (alias: ';
- aliases += this.aliases
- .map(it=>`/${it}`)
- .join(', ')
- ;
- aliases += ')';
- }
- return `/${this.name} ${this.helpString}${aliases}`;
- }
+ /**@type {Object.}*/ helpCache = {};
+ /**@type {Object.}*/ helpDetailsCache = {};
renderHelpItem(key = null) {
key = key ?? this.name;
- const typeIcon = '/';
- const li = document.createElement('li'); {
- li.classList.add('item');
- const type = document.createElement('span'); {
- type.classList.add('type');
- type.classList.add('monospace');
- type.textContent = typeIcon;
- li.append(type);
- }
- const specs = document.createElement('span'); {
- specs.classList.add('specs');
- const name = document.createElement('span'); {
- name.classList.add('name');
- name.classList.add('monospace');
- name.textContent = '/';
- key.split('').forEach(char=>{
- const span = document.createElement('span'); {
- span.textContent = char;
- name.append(span);
- }
- });
- specs.append(name);
+ if (!this.helpCache[key]) {
+ const typeIcon = '/';
+ const li = document.createElement('li'); {
+ li.classList.add('item');
+ const type = document.createElement('span'); {
+ type.classList.add('type');
+ type.classList.add('monospace');
+ type.textContent = typeIcon;
+ li.append(type);
}
- const body = document.createElement('span'); {
- body.classList.add('body');
- const args = document.createElement('span'); {
- args.classList.add('arguments');
- for (const arg of this.namedArgumentList) {
- const argItem = document.createElement('span'); {
- argItem.classList.add('argument');
- argItem.classList.add('namedArgument');
- if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
- if (arg.acceptsMultiple) argItem.classList.add('multiple');
- const name = document.createElement('span'); {
- name.classList.add('argument-name');
- name.textContent = arg.name;
- argItem.append(name);
- }
- if (arg.enumList.length > 0) {
- const enums = document.createElement('span'); {
- enums.classList.add('argument-enums');
- for (const e of arg.enumList) {
- const enumItem = document.createElement('span'); {
- enumItem.classList.add('argument-enum');
- enumItem.textContent = e;
- enums.append(enumItem);
- }
- }
- argItem.append(enums);
- }
- } else {
- const types = document.createElement('span'); {
- types.classList.add('argument-types');
- for (const t of arg.typeList) {
- const type = document.createElement('span'); {
- type.classList.add('argument-type');
- type.textContent = t;
- types.append(type);
- }
- }
- argItem.append(types);
- }
- }
- args.append(argItem);
+ const specs = document.createElement('span'); {
+ specs.classList.add('specs');
+ const name = document.createElement('span'); {
+ name.classList.add('name');
+ name.classList.add('monospace');
+ name.textContent = '/';
+ key.split('').forEach(char=>{
+ const span = document.createElement('span'); {
+ span.textContent = char;
+ name.append(span);
}
- }
- for (const arg of this.unnamedArgumentList) {
- const argItem = document.createElement('span'); {
- argItem.classList.add('argument');
- argItem.classList.add('unnamedArgument');
- if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
- if (arg.acceptsMultiple) argItem.classList.add('multiple');
- if (arg.enumList.length > 0) {
- const enums = document.createElement('span'); {
- enums.classList.add('argument-enums');
- for (const e of arg.enumList) {
- const enumItem = document.createElement('span'); {
- enumItem.classList.add('argument-enum');
- enumItem.textContent = e;
- enums.append(enumItem);
- }
- }
- argItem.append(enums);
- }
- } else {
- const types = document.createElement('span'); {
- types.classList.add('argument-types');
- for (const t of arg.typeList) {
- const type = document.createElement('span'); {
- type.classList.add('argument-type');
- type.textContent = t;
- types.append(type);
- }
- }
- argItem.append(types);
- }
- }
- args.append(argItem);
- }
- }
- body.append(args);
+ });
+ specs.append(name);
}
- const returns = document.createElement('span'); {
- returns.classList.add('returns');
- returns.textContent = this.returns ?? 'void';
- body.append(returns);
- }
- specs.append(body);
- }
- li.append(specs);
- }
- const help = document.createElement('span'); {
- help.classList.add('help');
- const content = document.createElement('span'); {
- content.classList.add('helpContent');
- content.innerHTML = this.helpString;
- const text = content.textContent;
- content.innerHTML = '';
- content.textContent = text;
- help.append(content);
- }
- li.append(help);
- }
- if (this.aliases.length > 0) {
- const aliases = document.createElement('span'); {
- aliases.classList.add('aliases');
- aliases.append(' (alias: ');
- for (const aliasName of this.aliases) {
- const alias = document.createElement('span'); {
- alias.classList.add('monospace');
- alias.textContent = `/${aliasName}`;
- aliases.append(alias);
- }
- }
- aliases.append(')');
- // li.append(aliases);
- }
- }
- }
- return li;
- }
-
- renderHelpDetails(key = null) {
- const frag = document.createDocumentFragment();
- key = key ?? this.name;
- const cmd = this;
- const namedArguments = cmd.namedArgumentList ?? [];
- const unnamedArguments = cmd.unnamedArgumentList ?? [];
- const returnType = cmd.returns ?? 'void';
- const helpString = cmd.helpString ?? 'NO DETAILS';
- const aliasList = [cmd.name, ...(cmd.aliases ?? [])].filter(it=>it != key);
- const specs = document.createElement('div'); {
- specs.classList.add('specs');
- const name = document.createElement('div'); {
- name.classList.add('name');
- name.classList.add('monospace');
- name.title = 'command name';
- name.textContent = `/${key}`;
- specs.append(name);
- }
- const body = document.createElement('div'); {
- body.classList.add('body');
- const args = document.createElement('ul'); {
- args.classList.add('arguments');
- for (const arg of namedArguments) {
- const listItem = document.createElement('li'); {
- listItem.classList.add('argumentItem');
- const argSpec = document.createElement('div'); {
- argSpec.classList.add('argumentSpec');
- const argItem = document.createElement('div'); {
+ const body = document.createElement('span'); {
+ body.classList.add('body');
+ const args = document.createElement('span'); {
+ args.classList.add('arguments');
+ for (const arg of this.namedArgumentList) {
+ const argItem = document.createElement('span'); {
argItem.classList.add('argument');
argItem.classList.add('namedArgument');
- argItem.title = `${arg.isRequired ? '' : 'optional '}named argument`;
if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
if (arg.acceptsMultiple) argItem.classList.add('multiple');
const name = document.createElement('span'); {
name.classList.add('argument-name');
- name.title = `${argItem.title} - name`;
name.textContent = arg.name;
argItem.append(name);
}
+ if (arg.enumList.length > 0) {
+ const enums = document.createElement('span'); {
+ enums.classList.add('argument-enums');
+ for (const e of arg.enumList) {
+ const enumItem = document.createElement('span'); {
+ enumItem.classList.add('argument-enum');
+ enumItem.textContent = e;
+ enums.append(enumItem);
+ }
+ }
+ argItem.append(enums);
+ }
+ } else {
+ const types = document.createElement('span'); {
+ types.classList.add('argument-types');
+ for (const t of arg.typeList) {
+ const type = document.createElement('span'); {
+ type.classList.add('argument-type');
+ type.textContent = t;
+ types.append(type);
+ }
+ }
+ argItem.append(types);
+ }
+ }
+ args.append(argItem);
+ }
+ }
+ for (const arg of this.unnamedArgumentList) {
+ const argItem = document.createElement('span'); {
+ argItem.classList.add('argument');
+ argItem.classList.add('unnamedArgument');
+ if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
+ if (arg.acceptsMultiple) argItem.classList.add('multiple');
+ if (arg.enumList.length > 0) {
+ const enums = document.createElement('span'); {
+ enums.classList.add('argument-enums');
+ for (const e of arg.enumList) {
+ const enumItem = document.createElement('span'); {
+ enumItem.classList.add('argument-enum');
+ enumItem.textContent = e;
+ enums.append(enumItem);
+ }
+ }
+ argItem.append(enums);
+ }
+ } else {
+ const types = document.createElement('span'); {
+ types.classList.add('argument-types');
+ for (const t of arg.typeList) {
+ const type = document.createElement('span'); {
+ type.classList.add('argument-type');
+ type.textContent = t;
+ types.append(type);
+ }
+ }
+ argItem.append(types);
+ }
+ }
+ args.append(argItem);
+ }
+ }
+ body.append(args);
+ }
+ const returns = document.createElement('span'); {
+ returns.classList.add('returns');
+ returns.textContent = this.returns ?? 'void';
+ body.append(returns);
+ }
+ specs.append(body);
+ }
+ li.append(specs);
+ }
+ const help = document.createElement('span'); {
+ help.classList.add('help');
+ const content = document.createElement('span'); {
+ content.classList.add('helpContent');
+ content.innerHTML = this.helpString;
+ const text = content.textContent;
+ content.innerHTML = '';
+ content.textContent = text;
+ help.append(content);
+ }
+ li.append(help);
+ }
+ if (this.aliases.length > 0) {
+ const aliases = document.createElement('span'); {
+ aliases.classList.add('aliases');
+ aliases.append(' (alias: ');
+ for (const aliasName of this.aliases) {
+ const alias = document.createElement('span'); {
+ alias.classList.add('monospace');
+ alias.textContent = `/${aliasName}`;
+ aliases.append(alias);
+ }
+ }
+ aliases.append(')');
+ // li.append(aliases);
+ }
+ }
+ }
+ this.helpCache[key] = li;
+ }
+ return this.helpCache[key];
+ }
+
+ renderHelpDetails(key = null) {
+ key = key ?? this.name;
+ if (!this.helpDetailsCache[key]) {
+ const frag = document.createDocumentFragment();
+ const cmd = this;
+ const namedArguments = cmd.namedArgumentList ?? [];
+ const unnamedArguments = cmd.unnamedArgumentList ?? [];
+ const returnType = cmd.returns ?? 'void';
+ const helpString = cmd.helpString ?? 'NO DETAILS';
+ const aliasList = [cmd.name, ...(cmd.aliases ?? [])].filter(it=>it != key);
+ const specs = document.createElement('div'); {
+ specs.classList.add('specs');
+ const name = document.createElement('div'); {
+ name.classList.add('name');
+ name.classList.add('monospace');
+ name.title = 'command name';
+ name.textContent = `/${key}`;
+ specs.append(name);
+ }
+ const body = document.createElement('div'); {
+ body.classList.add('body');
+ const args = document.createElement('ul'); {
+ args.classList.add('arguments');
+ for (const arg of namedArguments) {
+ const listItem = document.createElement('li'); {
+ listItem.classList.add('argumentItem');
+ const argSpec = document.createElement('div'); {
+ argSpec.classList.add('argumentSpec');
+ const argItem = document.createElement('div'); {
+ argItem.classList.add('argument');
+ argItem.classList.add('namedArgument');
+ argItem.title = `${arg.isRequired ? '' : 'optional '}named argument`;
+ if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
+ if (arg.acceptsMultiple) argItem.classList.add('multiple');
+ const name = document.createElement('span'); {
+ name.classList.add('argument-name');
+ name.title = `${argItem.title} - name`;
+ name.textContent = arg.name;
+ argItem.append(name);
+ }
+ if (arg.enumList.length > 0) {
+ const enums = document.createElement('span'); {
+ enums.classList.add('argument-enums');
+ enums.title = `${argItem.title} - accepted values`;
+ for (const e of arg.enumList) {
+ const enumItem = document.createElement('span'); {
+ enumItem.classList.add('argument-enum');
+ enumItem.textContent = e;
+ enums.append(enumItem);
+ }
+ }
+ argItem.append(enums);
+ }
+ } else {
+ const types = document.createElement('span'); {
+ types.classList.add('argument-types');
+ types.title = `${argItem.title} - accepted types`;
+ for (const t of arg.typeList) {
+ const type = document.createElement('span'); {
+ type.classList.add('argument-type');
+ type.textContent = t;
+ types.append(type);
+ }
+ }
+ argItem.append(types);
+ }
+ }
+ argSpec.append(argItem);
+ }
+ if (arg.defaultValue !== null) {
+ const argDefault = document.createElement('div'); {
+ argDefault.classList.add('argument-default');
+ argDefault.title = 'default value';
+ argDefault.textContent = arg.defaultValue.toString();
+ argSpec.append(argDefault);
+ }
+ }
+ listItem.append(argSpec);
+ }
+ const desc = document.createElement('div'); {
+ desc.classList.add('argument-description');
+ desc.innerHTML = arg.description;
+ listItem.append(desc);
+ }
+ args.append(listItem);
+ }
+ }
+ for (const arg of unnamedArguments) {
+ const listItem = document.createElement('li'); {
+ listItem.classList.add('argumentItem');
+ const argItem = document.createElement('div'); {
+ argItem.classList.add('argument');
+ argItem.classList.add('unnamedArgument');
+ argItem.title = `${arg.isRequired ? '' : 'optional '}unnamed argument`;
+ if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
+ if (arg.acceptsMultiple) argItem.classList.add('multiple');
if (arg.enumList.length > 0) {
const enums = document.createElement('span'); {
enums.classList.add('argument-enums');
@@ -258,106 +308,52 @@ export class SlashCommand {
argItem.append(types);
}
}
- argSpec.append(argItem);
+ listItem.append(argItem);
}
- if (arg.defaultValue !== null) {
- const argDefault = document.createElement('div'); {
- argDefault.classList.add('argument-default');
- argDefault.title = 'default value';
- argDefault.textContent = arg.defaultValue.toString();
- argSpec.append(argDefault);
- }
+ const desc = document.createElement('div'); {
+ desc.classList.add('argument-description');
+ desc.innerHTML = arg.description;
+ listItem.append(desc);
}
- listItem.append(argSpec);
+ args.append(listItem);
}
- const desc = document.createElement('div'); {
- desc.classList.add('argument-description');
- desc.innerHTML = arg.description;
- listItem.append(desc);
- }
- args.append(listItem);
+ }
+ body.append(args);
+ }
+ const returns = document.createElement('span'); {
+ returns.classList.add('returns');
+ returns.title = [null, undefined, 'void'].includes(returnType) ? 'command does not return anything' : 'return value';
+ returns.textContent = returnType ?? 'void';
+ body.append(returns);
+ }
+ specs.append(body);
+ }
+ frag.append(specs);
+ }
+ const help = document.createElement('span'); {
+ help.classList.add('help');
+ help.innerHTML = helpString;
+ for (const code of help.querySelectorAll('pre > code')) {
+ code.classList.add('language-stscript');
+ hljs.highlightElement(code);
+ }
+ frag.append(help);
+ }
+ if (aliasList.length > 0) {
+ const aliases = document.createElement('span'); {
+ aliases.classList.add('aliases');
+ for (const aliasName of aliasList) {
+ const alias = document.createElement('span'); {
+ alias.classList.add('alias');
+ alias.textContent = `/${aliasName}`;
+ aliases.append(alias);
}
}
- for (const arg of unnamedArguments) {
- const listItem = document.createElement('li'); {
- listItem.classList.add('argumentItem');
- const argItem = document.createElement('div'); {
- argItem.classList.add('argument');
- argItem.classList.add('unnamedArgument');
- argItem.title = `${arg.isRequired ? '' : 'optional '}unnamed argument`;
- if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
- if (arg.acceptsMultiple) argItem.classList.add('multiple');
- if (arg.enumList.length > 0) {
- const enums = document.createElement('span'); {
- enums.classList.add('argument-enums');
- enums.title = `${argItem.title} - accepted values`;
- for (const e of arg.enumList) {
- const enumItem = document.createElement('span'); {
- enumItem.classList.add('argument-enum');
- enumItem.textContent = e;
- enums.append(enumItem);
- }
- }
- argItem.append(enums);
- }
- } else {
- const types = document.createElement('span'); {
- types.classList.add('argument-types');
- types.title = `${argItem.title} - accepted types`;
- for (const t of arg.typeList) {
- const type = document.createElement('span'); {
- type.classList.add('argument-type');
- type.textContent = t;
- types.append(type);
- }
- }
- argItem.append(types);
- }
- }
- listItem.append(argItem);
- }
- const desc = document.createElement('div'); {
- desc.classList.add('argument-description');
- desc.innerHTML = arg.description;
- listItem.append(desc);
- }
- args.append(listItem);
- }
- }
- body.append(args);
+ frag.append(aliases);
}
- const returns = document.createElement('span'); {
- returns.classList.add('returns');
- returns.title = [null, undefined, 'void'].includes(returnType) ? 'command does not return anything' : 'return value';
- returns.textContent = returnType ?? 'void';
- body.append(returns);
- }
- specs.append(body);
}
- frag.append(specs);
+ this.helpDetailsCache[key] = frag;
}
- const help = document.createElement('span'); {
- help.classList.add('help');
- help.innerHTML = helpString;
- for (const code of help.querySelectorAll('pre > code')) {
- code.classList.add('language-stscript');
- hljs.highlightElement(code);
- }
- frag.append(help);
- }
- if (aliasList.length > 0) {
- const aliases = document.createElement('span'); {
- aliases.classList.add('aliases');
- for (const aliasName of aliasList) {
- const alias = document.createElement('span'); {
- alias.classList.add('alias');
- alias.textContent = `/${aliasName}`;
- aliases.append(alias);
- }
- }
- frag.append(aliases);
- }
- }
- return frag;
+ return this.helpDetailsCache[key].cloneNode(true);
}
}