diff --git a/public/scripts/slash-commands/SlashCommand.js b/public/scripts/slash-commands/SlashCommand.js index d83a157de..974e92fc0 100644 --- a/public/scripts/slash-commands/SlashCommand.js +++ b/public/scripts/slash-commands/SlashCommand.js @@ -63,6 +63,10 @@ export class SlashCommand { /**@type {Object.}*/ helpCache = {}; /**@type {Object.}*/ helpDetailsCache = {}; + /**@type {boolean}*/ isExtension = false; + /**@type {boolean}*/ isThirdParty = false; + /**@type {string}*/ source; + renderHelpItem(key = null) { key = key ?? this.name; if (!this.helpCache[key]) { @@ -227,12 +231,35 @@ export class SlashCommand { 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 head = document.createElement('div'); { + head.classList.add('head'); + const name = document.createElement('div'); { + name.classList.add('name'); + name.classList.add('monospace'); + name.title = 'command name'; + name.textContent = `/${key}`; + head.append(name); + } + const src = document.createElement('div'); { + src.classList.add('source'); + src.classList.add('fa-solid'); + if (this.isExtension) { + src.classList.add('isExtension'); + src.classList.add('fa-cubes'); + if (this.isThirdParty) src.classList.add('isThirdParty'); + else src.classList.add('isCore'); + } else { + src.classList.add('isCore'); + src.classList.add('fa-star-of-life'); + } + src.title = [ + this.isExtension ? 'Extension' : 'Core', + this.isThirdParty ? 'Third Party' : (this.isExtension ? 'Core' : null), + this.source, + ].filter(it=>it).join('\n'); + head.append(src); + } + specs.append(head); } const body = document.createElement('div'); { body.classList.add('body'); diff --git a/public/scripts/slash-commands/SlashCommandParser.js b/public/scripts/slash-commands/SlashCommandParser.js index a3688554b..333278c5c 100644 --- a/public/scripts/slash-commands/SlashCommandParser.js +++ b/public/scripts/slash-commands/SlashCommandParser.js @@ -73,6 +73,18 @@ export class SlashCommandParser { console.trace('WARN: Duplicate slash command registered!', [command.name, ...command.aliases]); } + const stack = new Error().stack.split('\n').map(it=>it.trim()); + command.isExtension = stack.find(it=>it.includes('/scripts/extensions/')) != null; + command.isThirdParty = stack.find(it=>it.includes('/scripts/extensions/third-party/')) != null; + if (command.isThirdParty) { + command.source = stack.find(it=>it.includes('/scripts/extensions/third-party/')).replace(/^.*?\/scripts\/extensions\/third-party\/([^/]+)\/.*$/, '$1'); + } else if (command.isExtension) { + command.source = stack.find(it=>it.includes('/scripts/extensions/')).replace(/^.*?\/scripts\/extensions\/([^/]+)\/.*$/, '$1'); + } else { + const idx = stack.findLastIndex(it=>it.includes('at SlashCommandParser\.')) + 1; + command.source = stack[idx].replace(/^.*?\/((?:scripts\/)?(?:[^/]+)\.js).*$/, '$1'); + } + this.commands[command.name] = command; if (Array.isArray(command.aliases)) { diff --git a/public/style.css b/public/style.css index c7bc6023c..d3679dc3b 100644 --- a/public/style.css +++ b/public/style.css @@ -1744,7 +1744,12 @@ body[data-stscript-style] .hljs.language-stscript { padding: 0.25em 0.25em 0.5em 0.25em; border-bottom: 1px solid var(--ac-color-border); - >.name { + > .head { + display: flex; + gap: 0.5em; + } + > .head > .name, > .name { + flex: 1 1 auto; font-weight: bold; color: var(--ac-color-text); cursor: help; @@ -1753,6 +1758,35 @@ body[data-stscript-style] .hljs.language-stscript { text-decoration: 1px dotted underline; } } + > .head > .source { + padding: 0 0.5em; + cursor: help; + display: flex; + align-items: center; + gap: 0.5em; + &.isThirdParty.isExtension { + color: #F89406; + } + &.isCore { + color: transparent; + &.isExtension { + color: #51A351; + } + &:after { + content: ''; + order: -1; + height: 14px; + aspect-ratio: 1 / 1; + background-image: url('/favicon.ico'); + background-size: contain; + background-repeat: no-repeat; + } + } + + &:hover { + text-decoration: 1px dotted underline; + } + } >.body { flex-direction: column; @@ -1840,7 +1874,7 @@ body[data-stscript-style] .hljs.language-stscript { >code { display: block; - padding: 0; + padding: 1px; } } }