diff --git a/dev/build/esbuild.js b/dev/build/esbuild.mjs similarity index 85% rename from dev/build/esbuild.js rename to dev/build/esbuild.mjs index cb9abc246..fa2231157 100644 --- a/dev/build/esbuild.js +++ b/dev/build/esbuild.mjs @@ -5,7 +5,6 @@ import * as path from 'node:path'; import * as fs from 'node:fs'; import * as process from "node:process"; - // Check if we're building for production // (Set via passing `production` as first argument) const mode = process.argv[2]; @@ -76,7 +75,13 @@ if (mode === 'watch') { }); } else { // Build with meta output for analysis - ctx.rebuild().then(result => { - fs.writeFileSync('esbuild-meta.json', JSON.stringify(result.metafile)); - }).catch(() => process.exit(1)); + const result = await ctx.rebuild(); + const outputs = result.metafile.outputs; + const files = Object.keys(outputs); + for (const file of files) { + const output = outputs[file]; + console.log(`Written: ${file} @ ${Math.round(output.bytes / 1000)}kB`); + } + fs.writeFileSync('esbuild-meta.json', JSON.stringify(result.metafile)); + process.exit(0); } diff --git a/package.json b/package.json index 1ae14e976..624ff876a 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,12 @@ { "private": true, - "type": "module", "scripts": { "build:css:dev": "sass ./resources/sass:./public/dist --embed-sources", "build:css:watch": "sass ./resources/sass:./public/dist --watch --embed-sources", "build:css:production": "sass ./resources/sass:./public/dist -s compressed", - "build:js:dev": "node dev/build/esbuild.js", - "build:js:watch": "node dev/build/esbuild.js watch", - "build:js:production": "node dev/build/esbuild.js production", + "build:js:dev": "node dev/build/esbuild.mjs", + "build:js:watch": "node dev/build/esbuild.mjs watch", + "build:js:production": "node dev/build/esbuild.mjs production", "build": "npm-run-all --parallel build:*:dev", "production": "npm-run-all --parallel build:*:production", "dev": "npm-run-all --parallel build:*:watch", diff --git a/resources/js/wysiwyg/index.ts b/resources/js/wysiwyg/index.ts index 273657c47..01964b066 100644 --- a/resources/js/wysiwyg/index.ts +++ b/resources/js/wysiwyg/index.ts @@ -151,8 +151,6 @@ export function createCommentEditorInstance(container: HTMLElement, htmlContent: theme: theme, }); - // TODO - Dedupe this with the basic editor instance - // Changed elements: namespace, registerMentions, toolbar, public event usage, mentioned decorator const context: EditorUiContext = buildEditorUI(container, editor, options); editor.setRootElement(context.editorDOM); diff --git a/resources/js/wysiwyg/services/mentions.ts b/resources/js/wysiwyg/services/mentions.ts index 59fd02b1d..ba6739f32 100644 --- a/resources/js/wysiwyg/services/mentions.ts +++ b/resources/js/wysiwyg/services/mentions.ts @@ -6,6 +6,7 @@ import {KEY_AT_COMMAND} from "lexical/LexicalCommands"; import {$createMentionNode, $isMentionNode, MentionNode} from "@lexical/link/LexicalMentionNode"; import {EditorUiContext} from "../ui/framework/core"; import {MentionDecorator} from "../ui/decorators/MentionDecorator"; +import {$selectSingleNode} from "../utils/selection"; function enterUserSelectMode(context: EditorUiContext, selection: RangeSelection) { @@ -25,10 +26,13 @@ function enterUserSelectMode(context: EditorUiContext, selection: RangeSelection } const split = textNode.splitText(offset); - const newNode = split[atStart ? 0 : 1]; + const priorTextNode = split[0]; + const afterTextNode = split[atStart ? 0 : 1]; const mention = $createMentionNode(0, '', ''); - newNode.replace(mention); + priorTextNode.insertAfter(mention); + afterTextNode.spliceText(0, 1, '', false); + $selectSingleNode(mention); requestAnimationFrame(() => { const mentionDecorator = context.manager.getDecoratorByNodeKey(mention.getKey()); diff --git a/resources/js/wysiwyg/ui/decorators/MentionDecorator.ts b/resources/js/wysiwyg/ui/decorators/MentionDecorator.ts index a2786de00..84d664885 100644 --- a/resources/js/wysiwyg/ui/decorators/MentionDecorator.ts +++ b/resources/js/wysiwyg/ui/decorators/MentionDecorator.ts @@ -170,14 +170,24 @@ export class MentionDecorator extends EditorDecorator { this.dropdownContainer?.remove(); this.abortController = null; this.dropdownContainer = null; + this.context.manager.focus(); } revertMention() { this.hideSelection(); this.context.editor.update(() => { const text = $createTextNode('@'); + const before = this.getNode().getPreviousSibling(); this.getNode().replace(text); - text.selectEnd(); + requestAnimationFrame(() => { + this.context.editor.update(() => { + if (text.isAttached()) { + text.selectEnd(); + } else if (before?.isAttached()) { + before?.selectEnd(); + } + }); + }); }); } diff --git a/resources/js/wysiwyg/ui/framework/manager.ts b/resources/js/wysiwyg/ui/framework/manager.ts index cbe3cca19..78d0cc9a2 100644 --- a/resources/js/wysiwyg/ui/framework/manager.ts +++ b/resources/js/wysiwyg/ui/framework/manager.ts @@ -206,6 +206,14 @@ export class EditorUIManager { } } + /** + * Set the UI focus to the editor. + */ + focus(): void { + this.getContext().editorDOM.focus(); + this.getContext().editor.focus(); + } + protected updateContextToolbars(update: EditorUiStateUpdate): void { for (let i = this.activeContextToolbars.length - 1; i >= 0; i--) { const toolbar = this.activeContextToolbars[i]; diff --git a/resources/sass/_components.scss b/resources/sass/_components.scss index 0f374fb80..8608427d8 100644 --- a/resources/sass/_components.scss +++ b/resources/sass/_components.scss @@ -985,6 +985,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group { font-size: 0.8rem; &:hover,&:focus { background-color: #F2F2F2; + @include mixins.lightDark(background-color, #F2F2F2, #444); text-decoration: none; } }