mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2024-12-15 02:47:16 +01:00
5cb319771d
* set pipe to empty string on empty closure * fix missing parser flags and scope * add closure serializing * add enum provider function to slash command arguments * add enum providers for /bg, /ask, and /go * fix index out of bounds returning undefined * keep whitespace as is in mixed unnamed args (string+closure) * add _hasUnnamedArgument to named arguments dictionary * allow /var key=x retrieval * add enum provider to /tag-add * fix typo (case) * add option to make enum matching optional * add executor to enum provider * change /tag-add enum provider to only show tags not already assigned * add enum provider to /tag-remove * fix name enum provider excluding groups * remove void from slash command callback return types * Lint undefined and null pipes * enable pointer events in chat autocomplete * fix type hint --------- Co-authored-by: LenAnderson <Anderson.Len@outlook.com> Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
210 lines
9.4 KiB
JavaScript
210 lines
9.4 KiB
JavaScript
import { SlashCommand } from '../slash-commands/SlashCommand.js';
|
|
import { AutoCompleteFuzzyScore } from './AutoCompleteFuzzyScore.js';
|
|
|
|
|
|
|
|
export class AutoCompleteOption {
|
|
/**@type {string}*/ name;
|
|
/**@type {string}*/ typeIcon;
|
|
/**@type {string}*/ type;
|
|
/**@type {number}*/ nameOffset = 0;
|
|
/**@type {AutoCompleteFuzzyScore}*/ score;
|
|
/**@type {string}*/ replacer;
|
|
/**@type {HTMLElement}*/ dom;
|
|
|
|
|
|
/**
|
|
* Used as a comparison value when removing duplicates (e.g., when a SlashCommand has aliases).
|
|
* @type {any}
|
|
* */
|
|
get value() {
|
|
return this.name;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param {string} name
|
|
*/
|
|
constructor(name, typeIcon = ' ', type = '') {
|
|
this.name = name;
|
|
this.typeIcon = typeIcon;
|
|
this.type = type;
|
|
}
|
|
|
|
|
|
makeItem(key, typeIcon, noSlash, namedArguments = [], unnamedArguments = [], returnType = 'void', helpString = '', aliasList = []) {
|
|
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 = noSlash ? '' : '/';
|
|
key.split('').forEach(char=>{
|
|
const span = document.createElement('span'); {
|
|
span.textContent = char;
|
|
name.append(span);
|
|
}
|
|
});
|
|
specs.append(name);
|
|
}
|
|
const body = document.createElement('span'); {
|
|
body.classList.add('body');
|
|
const args = document.createElement('span'); {
|
|
args.classList.add('arguments');
|
|
for (const arg of namedArguments) {
|
|
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);
|
|
}
|
|
}
|
|
for (const arg of unnamedArguments) {
|
|
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 = returnType ?? '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 = helpString;
|
|
const text = content.textContent;
|
|
content.innerHTML = '';
|
|
content.textContent = text;
|
|
help.append(content);
|
|
}
|
|
li.append(help);
|
|
}
|
|
if (aliasList.length > 0) {
|
|
const aliases = document.createElement('span'); {
|
|
aliases.classList.add('aliases');
|
|
aliases.append(' (alias: ');
|
|
for (const aliasName of aliasList) {
|
|
const alias = document.createElement('span'); {
|
|
alias.classList.add('monospace');
|
|
alias.textContent = `/${aliasName}`;
|
|
aliases.append(alias);
|
|
}
|
|
}
|
|
aliases.append(')');
|
|
// li.append(aliases);
|
|
}
|
|
}
|
|
}
|
|
return li;
|
|
}
|
|
|
|
|
|
/**
|
|
* @returns {HTMLElement}
|
|
*/
|
|
renderItem() {
|
|
// throw new Error(`${this.constructor.name}.renderItem() is not implemented`);
|
|
let li;
|
|
li = this.makeItem(this.name, this.typeIcon, true);
|
|
li.setAttribute('data-name', this.name);
|
|
li.setAttribute('data-option-type', this.type);
|
|
return li;
|
|
}
|
|
|
|
|
|
/**
|
|
* @returns {DocumentFragment}
|
|
*/
|
|
renderDetails() {
|
|
// throw new Error(`${this.constructor.name}.renderDetails() is not implemented`);
|
|
const frag = document.createDocumentFragment();
|
|
const specs = document.createElement('div'); {
|
|
specs.classList.add('specs');
|
|
const name = document.createElement('div'); {
|
|
name.classList.add('name');
|
|
name.classList.add('monospace');
|
|
name.textContent = this.name;
|
|
specs.append(name);
|
|
}
|
|
frag.append(specs);
|
|
}
|
|
return frag;
|
|
}
|
|
}
|