mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			225 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			10 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;
 | |
|     /**@type {(input:string)=>boolean}*/ matchProvider;
 | |
|     /**@type {(input:string)=>string}*/ valueProvider;
 | |
|     /**@type {boolean}*/ makeSelectable = false;
 | |
| 
 | |
| 
 | |
|     /**
 | |
|      * Used as a comparison value when removing duplicates (e.g., when a SlashCommand has aliases).
 | |
|      * @type {any}
 | |
|      * */
 | |
|     get value() {
 | |
|         return this.name;
 | |
|     }
 | |
| 
 | |
|     get isSelectable() {
 | |
|         return this.makeSelectable || !this.valueProvider;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     /**
 | |
|      * @param {string} name
 | |
|      */
 | |
|     constructor(name, typeIcon = ' ', type = '', matchProvider = null, valueProvider = null, makeSelectable = false) {
 | |
|         this.name = name;
 | |
|         this.typeIcon = typeIcon;
 | |
|         this.type = type;
 | |
|         this.matchProvider = matchProvider;
 | |
|         this.valueProvider = valueProvider;
 | |
|         this.makeSelectable = makeSelectable;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     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 stopgap = document.createElement('span'); {
 | |
|                 stopgap.classList.add('stopgap');
 | |
|                 stopgap.textContent = '';
 | |
|                 li.append(stopgap);
 | |
|             }
 | |
|             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;
 | |
|     }
 | |
| }
 |