mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-12-19 10:42:29 +03:00
Esbuild & Mentions: Updated interaction stability and build system
- Updated esbuild system to be module, and fixed build command. - Reverted module use in package.json by default as this impacted test runs/files. - Updated mention user select: - To look better in dark mode. - To not remove text after on select. - To properly revert/restore focus on enter or cancel.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
requestAnimationFrame(() => {
|
||||
this.context.editor.update(() => {
|
||||
if (text.isAttached()) {
|
||||
text.selectEnd();
|
||||
} else if (before?.isAttached()) {
|
||||
before?.selectEnd();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user