diff --git a/dev/docs/javascript-code.md b/dev/docs/javascript-code.md index e5f491839..4de6223d8 100644 --- a/dev/docs/javascript-code.md +++ b/dev/docs/javascript-code.md @@ -161,3 +161,7 @@ window.$components.firstOnElement(element, name); There are a range of available events that are emitted as part of a public & supported API for accessing or extending JavaScript libraries & components used in the system. Details on these events can be found in the [JavaScript Public Events file](javascript-public-events.md). + +## WYSIWYG Editor API + +Details on the API for our custom-built WYSIWYG editor can be found in the [WYSIWYG JavaScript API file](./wysiwyg-js-api.md). \ No newline at end of file diff --git a/dev/docs/javascript-public-events.md b/dev/docs/javascript-public-events.md index 4f68daaeb..85a4caad4 100644 --- a/dev/docs/javascript-public-events.md +++ b/dev/docs/javascript-public-events.md @@ -60,7 +60,7 @@ This event is called when the markdown editor loads, post configuration but befo #### Event Data -- `markdownIt` - A references to the [MarkdownIt](https://markdown-it.github.io/markdown-it/#MarkdownIt) instance used to render markdown to HTML (Just for the preview). +- `markdownIt` - A reference to the [MarkdownIt](https://markdown-it.github.io/markdown-it/#MarkdownIt) instance used to render markdown to HTML (Just for the preview). - `displayEl` - The IFrame Element that wraps the HTML preview display. - `cmEditorView` - The CodeMirror [EditorView](https://codemirror.net/docs/ref/#view.EditorView) instance used for the markdown input editor. @@ -79,7 +79,7 @@ window.addEventListener('editor-markdown::setup', event => { This event is called as the embedded diagrams.net drawing editor loads, to allow configuration of the diagrams.net interface. See [this diagrams.net page](https://www.diagrams.net/doc/faq/configure-diagram-editor) for details on the available options for the configure event. -If using a custom diagrams.net instance, via the `DRAWIO` option, you will need to ensure your DRAWIO option URL has the `configure=1` query parameter. +If using a custom diagrams.net instance, via the `DRAWIO` option, you will need to ensure your DRAWIO option URL has the `configure=1` query parameter. #### Event Data @@ -142,7 +142,7 @@ This event is called whenever a CodeMirror instance is loaded, as a method to co - `darkModeActive` - A boolean to indicate if the current view/page is being loaded with dark mode active. - `registerViewTheme(builder)` - A method that can be called to register a new view (CodeMirror UI) theme. - - `builder` - A function that will return an object that will be passed into the CodeMirror [EditorView.theme()](https://codemirror.net/docs/ref/#view.EditorView^theme) function as a StyleSpec. + - `builder` - A function that will return an object that will be passed into the CodeMirror [EditorView.theme()](https://codemirror.net/docs/ref/#view.EditorView^theme) function as a StyleSpec. - `registerHighlightStyle(builder)` - A method that can be called to register a new HighlightStyle (code highlighting) theme. - `builder` - A function, that receives a reference to [Tag.tags](https://lezer.codemirror.net/docs/ref/#highlight.tags) and returns an array of [TagStyle](https://codemirror.net/docs/ref/#language.TagStyle) objects. @@ -301,7 +301,7 @@ This event is called just after any CodeMirror instances are initialised so that ##### Example -The below shows how you'd prepend some default text to all content (page) code blocks. +The below example shows how you'd prepend some default text to all content (page) code blocks.
Show Example @@ -318,4 +318,42 @@ window.addEventListener('library-cm6::post-init', event => { } }); ``` +
+ +### `editor-wysiwyg::post-init` + +This is called after the (new custom-built Lexical-based) WYSIWYG editor has been initialised. + +#### Event Data + +- `usage` - A string label to identify the usage type of the WYSIWYG editor in BookStack. +- `api` - An instance to the WYSIWYG editor API, as documented in the [WYSIWYG JavaScript API file](./wysiwyg-js-api.md). + +##### Example + +The below shows how you'd use this API to create a button, with that button added to the toolbar of the page editor, which inserts bold hello text on press: + +
+Show Example + +```javascript +window.addEventListener('editor-wysiwyg::post-init', event => { + const {usage, api} = event.detail; + // Check that it's the page editor being loaded. + if (usage !== 'page-editor') { + return; + } + + // Create a custom button which inserts bold hello text on press. + const button = api.ui.createButton({ + label: 'Greet', + action: () => { + api.content.insertHtml(`Hello!`); + } + }); + + // Add the button to the start of the first section within the main toolbar. + api.ui.getMainToolbarSections()[0]?.addButton(button, 0); +}); +```
\ No newline at end of file diff --git a/dev/docs/wysiwyg-js-api.md b/dev/docs/wysiwyg-js-api.md index 44e4a52c0..7286f943f 100644 --- a/dev/docs/wysiwyg-js-api.md +++ b/dev/docs/wysiwyg-js-api.md @@ -1,6 +1,5 @@ # WYSIWYG JavaScript API -TODO - Link to this from JS code doc. TODO - Create JS events and add to the js public events doc. **Warning: This API is currently in development and may change without notice.** diff --git a/resources/js/wysiwyg/index.ts b/resources/js/wysiwyg/index.ts index c3ff37e7e..5d1762ff8 100644 --- a/resources/js/wysiwyg/index.ts +++ b/resources/js/wysiwyg/index.ts @@ -95,11 +95,10 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st registerCommonNodeMutationListeners(context); - // TODO - Emit this as a public event instead - // TODO - Add support to basic editor below - const api = new EditorApi(context); - // @ts-ignore - window.editorApi = api; + window.$events.emitPublic(container, 'editor-wysiwyg::post-init', { + usage: 'page-editor', + api: new EditorApi(context), + }); return new SimpleWysiwygEditorInterface(context); } @@ -129,6 +128,11 @@ export function createBasicEditorInstance(container: HTMLElement, htmlContent: s setEditorContentFromHtml(editor, htmlContent); + window.$events.emitPublic(container, 'editor-wysiwyg::post-init', { + usage: 'description-editor', + api: new EditorApi(context), + }); + return new SimpleWysiwygEditorInterface(context); } diff --git a/resources/js/wysiwyg/ui/defaults/toolbars.ts b/resources/js/wysiwyg/ui/defaults/toolbars.ts index 0c48f5954..9302e7bed 100644 --- a/resources/js/wysiwyg/ui/defaults/toolbars.ts +++ b/resources/js/wysiwyg/ui/defaults/toolbars.ts @@ -223,11 +223,13 @@ export function getMainEditorFullToolbar(context: EditorUiContext): EditorContai export function getBasicEditorToolbar(context: EditorUiContext): EditorContainerUiElement { return new EditorSimpleClassContainer('editor-toolbar-main', [ - new EditorButton(bold), - new EditorButton(italic), - new EditorButton(link), - new EditorButton(bulletList), - new EditorButton(numberList), + new EditorOverflowContainer('formats', 7, [ + new EditorButton(bold), + new EditorButton(italic), + new EditorButton(link), + new EditorButton(bulletList), + new EditorButton(numberList), + ]) ]); }