Spaces:
Running
Running
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; | |
} | |
} | |