From ebe2ca7faff580ccb8064920a24fb2fad6412105 Mon Sep 17 00:00:00 2001 From: Dan Brown <ssddanbrown@googlemail.com> Date: Tue, 17 Dec 2024 22:40:28 +0000 Subject: [PATCH] Lexical: Added about button/view Re-used existing route and moved tinymce help to its own different route. Added test to cover. Added new external-content block to support in editor UI. --- lang/en/editor.php | 2 + .../icons/editor/{help.svg => about.svg} | 0 resources/js/wysiwyg-tinymce/plugins-about.js | 2 +- .../wysiwyg/ui/defaults/buttons/controls.ts | 15 +- .../js/wysiwyg/ui/defaults/forms/controls.ts | 17 +- resources/js/wysiwyg/ui/defaults/modals.ts | 6 +- .../js/wysiwyg/ui/{ => defaults}/toolbars.ts | 39 +-- .../ui/framework/blocks/external-content.ts | 29 ++ resources/js/wysiwyg/ui/index.ts | 2 +- resources/sass/_editor.scss | 7 + resources/views/help/tinymce.blade.php | 146 +++++++++ resources/views/help/wysiwyg.blade.php | 280 +++++++++--------- routes/web.php | 1 + tests/Meta/HelpTest.php | 12 +- 14 files changed, 388 insertions(+), 170 deletions(-) rename resources/icons/editor/{help.svg => about.svg} (100%) rename resources/js/wysiwyg/ui/{ => defaults}/toolbars.ts (88%) create mode 100644 resources/js/wysiwyg/ui/framework/blocks/external-content.ts create mode 100644 resources/views/help/tinymce.blade.php diff --git a/lang/en/editor.php b/lang/en/editor.php index de9aa0ece..a61b46042 100644 --- a/lang/en/editor.php +++ b/lang/en/editor.php @@ -163,6 +163,8 @@ return [ 'about' => 'About the editor', 'about_title' => 'About the WYSIWYG Editor', 'editor_license' => 'Editor License & Copyright', + 'editor_lexical_license' => 'This editor is built as a fork of :lexicalLink which is distributed under the MIT license.', + 'editor_lexical_license_link' => 'Full license details can be found here.', 'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.', 'editor_tiny_license_link' => 'The copyright and license details of TinyMCE can be found here.', 'save_continue' => 'Save Page & Continue', diff --git a/resources/icons/editor/help.svg b/resources/icons/editor/about.svg similarity index 100% rename from resources/icons/editor/help.svg rename to resources/icons/editor/about.svg diff --git a/resources/js/wysiwyg-tinymce/plugins-about.js b/resources/js/wysiwyg-tinymce/plugins-about.js index 096b4f968..75cf476cf 100644 --- a/resources/js/wysiwyg-tinymce/plugins-about.js +++ b/resources/js/wysiwyg-tinymce/plugins-about.js @@ -4,7 +4,7 @@ function register(editor) { const aboutDialog = { title: 'About the WYSIWYG Editor', - url: window.baseUrl('/help/wysiwyg'), + url: window.baseUrl('/help/tinymce'), }; editor.ui.registry.addButton('about', { diff --git a/resources/js/wysiwyg/ui/defaults/buttons/controls.ts b/resources/js/wysiwyg/ui/defaults/buttons/controls.ts index 77223dac3..5e3200539 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/controls.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/controls.ts @@ -11,8 +11,9 @@ import { } from "lexical"; import redoIcon from "@icons/editor/redo.svg"; import sourceIcon from "@icons/editor/source-view.svg"; -import {getEditorContentAsHtml} from "../../../utils/actions"; import fullscreenIcon from "@icons/editor/fullscreen.svg"; +import aboutIcon from "@icons/editor/about.svg"; +import {getEditorContentAsHtml} from "../../../utils/actions"; export const undo: EditorButtonDefinition = { label: 'Undo', @@ -80,4 +81,16 @@ export const fullscreen: EditorButtonDefinition = { isActive(selection, context: EditorUiContext) { return context.containerDOM.classList.contains('fullscreen'); } +}; + +export const about: EditorButtonDefinition = { + label: 'About the editor', + icon: aboutIcon, + async action(context: EditorUiContext, button: EditorButton) { + const modal = context.manager.createModal('about'); + modal.show({}); + }, + isActive(selection, context: EditorUiContext) { + return false; + } }; \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/defaults/forms/controls.ts b/resources/js/wysiwyg/ui/defaults/forms/controls.ts index fc461f662..8e7219d67 100644 --- a/resources/js/wysiwyg/ui/defaults/forms/controls.ts +++ b/resources/js/wysiwyg/ui/defaults/forms/controls.ts @@ -1,6 +1,7 @@ import {EditorFormDefinition} from "../../framework/forms"; -import {EditorUiContext} from "../../framework/core"; +import {EditorUiContext, EditorUiElement} from "../../framework/core"; import {setEditorContentFromHtml} from "../../../utils/actions"; +import {ExternalContent} from "../../framework/blocks/external-content"; export const source: EditorFormDefinition = { submitText: 'Save', @@ -15,4 +16,18 @@ export const source: EditorFormDefinition = { type: 'textarea', }, ], +}; + +export const about: EditorFormDefinition = { + submitText: 'Close', + async action() { + return true; + }, + fields: [ + { + build(): EditorUiElement { + return new ExternalContent('/help/wysiwyg'); + } + } + ], }; \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/defaults/modals.ts b/resources/js/wysiwyg/ui/defaults/modals.ts index da3859266..830a42935 100644 --- a/resources/js/wysiwyg/ui/defaults/modals.ts +++ b/resources/js/wysiwyg/ui/defaults/modals.ts @@ -1,6 +1,6 @@ import {EditorFormModalDefinition} from "../framework/modals"; import {details, image, link, media} from "./forms/objects"; -import {source} from "./forms/controls"; +import {about, source} from "./forms/controls"; import {cellProperties, rowProperties, tableProperties} from "./forms/tables"; export const modals: Record<string, EditorFormModalDefinition> = { @@ -35,5 +35,9 @@ export const modals: Record<string, EditorFormModalDefinition> = { details: { title: 'Edit collapsible block', form: details, + }, + about: { + title: 'About the WYSIWYG Editor', + form: about, } }; \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/toolbars.ts b/resources/js/wysiwyg/ui/defaults/toolbars.ts similarity index 88% rename from resources/js/wysiwyg/ui/toolbars.ts rename to resources/js/wysiwyg/ui/defaults/toolbars.ts index 1230cbdd2..61baa3c32 100644 --- a/resources/js/wysiwyg/ui/toolbars.ts +++ b/resources/js/wysiwyg/ui/defaults/toolbars.ts @@ -1,12 +1,12 @@ -import {EditorButton} from "./framework/buttons"; -import {EditorContainerUiElement, EditorSimpleClassContainer, EditorUiContext, EditorUiElement} from "./framework/core"; -import {EditorFormatMenu} from "./framework/blocks/format-menu"; -import {FormatPreviewButton} from "./framework/blocks/format-preview-button"; -import {EditorDropdownButton} from "./framework/blocks/dropdown-button"; -import {EditorColorPicker} from "./framework/blocks/color-picker"; -import {EditorTableCreator} from "./framework/blocks/table-creator"; -import {EditorColorButton} from "./framework/blocks/color-button"; -import {EditorOverflowContainer} from "./framework/blocks/overflow-container"; +import {EditorButton} from "../framework/buttons"; +import {EditorContainerUiElement, EditorSimpleClassContainer, EditorUiContext, EditorUiElement} from "../framework/core"; +import {EditorFormatMenu} from "../framework/blocks/format-menu"; +import {FormatPreviewButton} from "../framework/blocks/format-preview-button"; +import {EditorDropdownButton} from "../framework/blocks/dropdown-button"; +import {EditorColorPicker} from "../framework/blocks/color-picker"; +import {EditorTableCreator} from "../framework/blocks/table-creator"; +import {EditorColorButton} from "../framework/blocks/color-button"; +import {EditorOverflowContainer} from "../framework/blocks/overflow-container"; import { cellProperties, clearTableFormatting, copyColumn, @@ -29,8 +29,8 @@ import { rowProperties, splitCell, table, tableProperties -} from "./defaults/buttons/tables"; -import {fullscreen, redo, source, undo} from "./defaults/buttons/controls"; +} from "./buttons/tables"; +import {about, fullscreen, redo, source, undo} from "./buttons/controls"; import { blockquote, dangerCallout, h2, @@ -41,7 +41,7 @@ import { paragraph, successCallout, warningCallout -} from "./defaults/buttons/block-formats"; +} from "./buttons/block-formats"; import { bold, clearFormating, code, highlightColor, @@ -50,7 +50,7 @@ import { superscript, textColor, underline -} from "./defaults/buttons/inline-formats"; +} from "./buttons/inline-formats"; import { alignCenter, alignJustify, @@ -58,14 +58,14 @@ import { alignRight, directionLTR, directionRTL -} from "./defaults/buttons/alignments"; +} from "./buttons/alignments"; import { bulletList, indentDecrease, indentIncrease, numberList, taskList -} from "./defaults/buttons/lists"; +} from "./buttons/lists"; import { codeBlock, details, detailsEditLabel, detailsToggle, detailsUnwrap, @@ -75,10 +75,10 @@ import { image, link, media, unlink -} from "./defaults/buttons/objects"; -import {el} from "../utils/dom"; -import {EditorButtonWithMenu} from "./framework/blocks/button-with-menu"; -import {EditorSeparator} from "./framework/blocks/separator"; +} from "./buttons/objects"; +import {el} from "../../utils/dom"; +import {EditorButtonWithMenu} from "../framework/blocks/button-with-menu"; +import {EditorSeparator} from "../framework/blocks/separator"; export function getMainEditorFullToolbar(context: EditorUiContext): EditorContainerUiElement { @@ -201,6 +201,7 @@ export function getMainEditorFullToolbar(context: EditorUiContext): EditorContai // Meta elements new EditorOverflowContainer(3, [ new EditorButton(source), + new EditorButton(about), new EditorButton(fullscreen), // Test diff --git a/resources/js/wysiwyg/ui/framework/blocks/external-content.ts b/resources/js/wysiwyg/ui/framework/blocks/external-content.ts new file mode 100644 index 000000000..b53c43e55 --- /dev/null +++ b/resources/js/wysiwyg/ui/framework/blocks/external-content.ts @@ -0,0 +1,29 @@ +import {EditorUiElement} from "../core"; +import {el} from "../../../utils/dom"; + +export class ExternalContent extends EditorUiElement { + + /** + * The URL for HTML to be loaded from. + */ + protected url: string = ''; + + constructor(url: string) { + super(); + this.url = url; + } + + buildDOM(): HTMLElement { + const wrapper = el('div', { + class: 'editor-external-content', + }); + + window.$http.get(this.url).then(resp => { + if (typeof resp.data === 'string') { + wrapper.innerHTML = resp.data; + } + }); + + return wrapper; + } +} diff --git a/resources/js/wysiwyg/ui/index.ts b/resources/js/wysiwyg/ui/index.ts index 40df43347..fda37085e 100644 --- a/resources/js/wysiwyg/ui/index.ts +++ b/resources/js/wysiwyg/ui/index.ts @@ -4,7 +4,7 @@ import { getImageToolbarContent, getLinkToolbarContent, getMainEditorFullToolbar, getTableToolbarContent -} from "./toolbars"; +} from "./defaults/toolbars"; import {EditorUIManager} from "./framework/manager"; import {EditorUiContext} from "./framework/core"; import {CodeBlockDecorator} from "./decorators/code-block"; diff --git a/resources/sass/_editor.scss b/resources/sass/_editor.scss index 3eef4c2c6..2446c1416 100644 --- a/resources/sass/_editor.scss +++ b/resources/sass/_editor.scss @@ -350,6 +350,13 @@ body.editor-is-fullscreen { text-align: center; padding: 0.2em; } +.editor-external-content { + min-width: 500px; + min-height: 500px; + h4:first-child { + margin-top: 0; + } +} // In-editor elements .editor-image-wrap { diff --git a/resources/views/help/tinymce.blade.php b/resources/views/help/tinymce.blade.php new file mode 100644 index 000000000..8ff59c8d6 --- /dev/null +++ b/resources/views/help/tinymce.blade.php @@ -0,0 +1,146 @@ +@extends('layouts.plain') +@section('document-class', 'bg-white ' . (setting()->getForCurrentUser('dark-mode-enabled') ? 'dark-mode ' : '')) + +@section('content') + <div class="p-m"> + + <h4 class="mt-s">{{ trans('editor.editor_license') }}</h4> + <p> + {!! trans('editor.editor_tiny_license', ['tinyLink' => '<a href="https://www.tiny.cloud/" target="_blank" rel="noopener noreferrer">TinyMCE</a>']) !!} + <br> + <a href="{{ url('/libs/tinymce/license.txt') }}" target="_blank">{{ trans('editor.editor_tiny_license_link') }}</a> + </p> + + <h4>{{ trans('editor.shortcuts') }}</h4> + + <p>{{ trans('editor.shortcuts_intro') }}</p> + <table> + <thead> + <tr> + <th>{{ trans('editor.shortcut') }} {{ trans('editor.windows_linux') }}</th> + <th>{{ trans('editor.shortcut') }} {{ trans('editor.mac') }}</th> + <th>{{ trans('editor.description') }}</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>Ctrl</code>+<code>S</code></td> + <td><code>Cmd</code>+<code>S</code></td> + <td>{{ trans('entities.pages_edit_save_draft') }}</td> + </tr> + <tr> + <td><code>Ctrl</code>+<code>Enter</code></td> + <td><code>Cmd</code>+<code>Enter</code></td> + <td>{{ trans('editor.save_continue') }}</td> + </tr> + <tr> + <td><code>Ctrl</code>+<code>B</code></td> + <td><code>Cmd</code>+<code>B</code></td> + <td>{{ trans('editor.bold') }}</td> + </tr> + <tr> + <td><code>Ctrl</code>+<code>I</code></td> + <td><code>Cmd</code>+<code>I</code></td> + <td>{{ trans('editor.italic') }}</td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>1</code><br> + <code>Ctrl</code>+<code>2</code><br> + <code>Ctrl</code>+<code>3</code><br> + <code>Ctrl</code>+<code>4</code> + </td> + <td> + <code>Cmd</code>+<code>1</code><br> + <code>Cmd</code>+<code>2</code><br> + <code>Cmd</code>+<code>3</code><br> + <code>Cmd</code>+<code>4</code> + </td> + <td> + {{ trans('editor.header_large') }} <br> + {{ trans('editor.header_medium') }} <br> + {{ trans('editor.header_small') }} <br> + {{ trans('editor.header_tiny') }} + </td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>5</code><br> + <code>Ctrl</code>+<code>D</code> + </td> + <td> + <code>Cmd</code>+<code>5</code><br> + <code>Cmd</code>+<code>D</code> + </td> + <td>{{ trans('editor.paragraph') }}</td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>6</code><br> + <code>Ctrl</code>+<code>Q</code> + </td> + <td> + <code>Cmd</code>+<code>6</code><br> + <code>Cmd</code>+<code>Q</code> + </td> + <td>{{ trans('editor.blockquote') }}</td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>7</code><br> + <code>Ctrl</code>+<code>E</code> + </td> + <td> + <code>Cmd</code>+<code>7</code><br> + <code>Cmd</code>+<code>E</code> + </td> + <td>{{ trans('editor.insert_code_block') }}</td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>8</code><br> + <code>Ctrl</code>+<code>Shift</code>+<code>E</code> + </td> + <td> + <code>Cmd</code>+<code>8</code><br> + <code>Cmd</code>+<code>Shift</code>+<code>E</code> + </td> + <td>{{ trans('editor.inline_code') }}</td> + </tr> + <tr> + <td><code>Ctrl</code>+<code>9</code></td> + <td><code>Cmd</code>+<code>9</code></td> + <td> + {{ trans('editor.callouts') }} <br> + <small>{{ trans('editor.callouts_cycle') }}</small> + </td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>O</code> <br> + <code>Ctrl</code>+<code>P</code> + </td> + <td> + <code>Cmd</code>+<code>O</code> <br> + <code>Cmd</code>+<code>P</code> + </td> + <td> + {{ trans('editor.list_numbered') }} <br> + {{ trans('editor.list_bullet') }} + </td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>Shift</code>+<code>K</code> + </td> + <td> + <code>Cmd</code>+<code>Shift</code>+<code>K</code> + </td> + <td>{{ trans('editor.link_selector') }}</td> + </tr> + </tbody> + </table> + + </div> +@endsection + diff --git a/resources/views/help/wysiwyg.blade.php b/resources/views/help/wysiwyg.blade.php index 8ff59c8d6..4fc00b0e1 100644 --- a/resources/views/help/wysiwyg.blade.php +++ b/resources/views/help/wysiwyg.blade.php @@ -1,146 +1,138 @@ -@extends('layouts.plain') -@section('document-class', 'bg-white ' . (setting()->getForCurrentUser('dark-mode-enabled') ? 'dark-mode ' : '')) +<h4>{{ trans('editor.shortcuts') }}</h4> -@section('content') - <div class="p-m"> - - <h4 class="mt-s">{{ trans('editor.editor_license') }}</h4> - <p> - {!! trans('editor.editor_tiny_license', ['tinyLink' => '<a href="https://www.tiny.cloud/" target="_blank" rel="noopener noreferrer">TinyMCE</a>']) !!} - <br> - <a href="{{ url('/libs/tinymce/license.txt') }}" target="_blank">{{ trans('editor.editor_tiny_license_link') }}</a> - </p> - - <h4>{{ trans('editor.shortcuts') }}</h4> - - <p>{{ trans('editor.shortcuts_intro') }}</p> - <table> - <thead> - <tr> - <th>{{ trans('editor.shortcut') }} {{ trans('editor.windows_linux') }}</th> - <th>{{ trans('editor.shortcut') }} {{ trans('editor.mac') }}</th> - <th>{{ trans('editor.description') }}</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>Ctrl</code>+<code>S</code></td> - <td><code>Cmd</code>+<code>S</code></td> - <td>{{ trans('entities.pages_edit_save_draft') }}</td> - </tr> - <tr> - <td><code>Ctrl</code>+<code>Enter</code></td> - <td><code>Cmd</code>+<code>Enter</code></td> - <td>{{ trans('editor.save_continue') }}</td> - </tr> - <tr> - <td><code>Ctrl</code>+<code>B</code></td> - <td><code>Cmd</code>+<code>B</code></td> - <td>{{ trans('editor.bold') }}</td> - </tr> - <tr> - <td><code>Ctrl</code>+<code>I</code></td> - <td><code>Cmd</code>+<code>I</code></td> - <td>{{ trans('editor.italic') }}</td> - </tr> - <tr> - <td> - <code>Ctrl</code>+<code>1</code><br> - <code>Ctrl</code>+<code>2</code><br> - <code>Ctrl</code>+<code>3</code><br> - <code>Ctrl</code>+<code>4</code> - </td> - <td> - <code>Cmd</code>+<code>1</code><br> - <code>Cmd</code>+<code>2</code><br> - <code>Cmd</code>+<code>3</code><br> - <code>Cmd</code>+<code>4</code> - </td> - <td> - {{ trans('editor.header_large') }} <br> - {{ trans('editor.header_medium') }} <br> - {{ trans('editor.header_small') }} <br> - {{ trans('editor.header_tiny') }} - </td> - </tr> - <tr> - <td> - <code>Ctrl</code>+<code>5</code><br> - <code>Ctrl</code>+<code>D</code> - </td> - <td> - <code>Cmd</code>+<code>5</code><br> - <code>Cmd</code>+<code>D</code> - </td> - <td>{{ trans('editor.paragraph') }}</td> - </tr> - <tr> - <td> - <code>Ctrl</code>+<code>6</code><br> - <code>Ctrl</code>+<code>Q</code> - </td> - <td> - <code>Cmd</code>+<code>6</code><br> - <code>Cmd</code>+<code>Q</code> - </td> - <td>{{ trans('editor.blockquote') }}</td> - </tr> - <tr> - <td> - <code>Ctrl</code>+<code>7</code><br> - <code>Ctrl</code>+<code>E</code> - </td> - <td> - <code>Cmd</code>+<code>7</code><br> - <code>Cmd</code>+<code>E</code> - </td> - <td>{{ trans('editor.insert_code_block') }}</td> - </tr> - <tr> - <td> - <code>Ctrl</code>+<code>8</code><br> - <code>Ctrl</code>+<code>Shift</code>+<code>E</code> - </td> - <td> - <code>Cmd</code>+<code>8</code><br> - <code>Cmd</code>+<code>Shift</code>+<code>E</code> - </td> - <td>{{ trans('editor.inline_code') }}</td> - </tr> - <tr> - <td><code>Ctrl</code>+<code>9</code></td> - <td><code>Cmd</code>+<code>9</code></td> - <td> - {{ trans('editor.callouts') }} <br> - <small>{{ trans('editor.callouts_cycle') }}</small> - </td> - </tr> - <tr> - <td> - <code>Ctrl</code>+<code>O</code> <br> - <code>Ctrl</code>+<code>P</code> - </td> - <td> - <code>Cmd</code>+<code>O</code> <br> - <code>Cmd</code>+<code>P</code> - </td> - <td> - {{ trans('editor.list_numbered') }} <br> - {{ trans('editor.list_bullet') }} - </td> - </tr> - <tr> - <td> - <code>Ctrl</code>+<code>Shift</code>+<code>K</code> - </td> - <td> - <code>Cmd</code>+<code>Shift</code>+<code>K</code> - </td> - <td>{{ trans('editor.link_selector') }}</td> - </tr> - </tbody> - </table> - - </div> -@endsection +<p>{{ trans('editor.shortcuts_intro') }}</p> +<table> + <thead> + <tr> + <th>{{ trans('editor.shortcut') }} {{ trans('editor.windows_linux') }}</th> + <th>{{ trans('editor.shortcut') }} {{ trans('editor.mac') }}</th> + <th>{{ trans('editor.description') }}</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>Ctrl</code>+<code>S</code></td> + <td><code>Cmd</code>+<code>S</code></td> + <td>{{ trans('entities.pages_edit_save_draft') }}</td> + </tr> + <tr> + <td><code>Ctrl</code>+<code>Enter</code></td> + <td><code>Cmd</code>+<code>Enter</code></td> + <td>{{ trans('editor.save_continue') }}</td> + </tr> + <tr> + <td><code>Ctrl</code>+<code>B</code></td> + <td><code>Cmd</code>+<code>B</code></td> + <td>{{ trans('editor.bold') }}</td> + </tr> + <tr> + <td><code>Ctrl</code>+<code>I</code></td> + <td><code>Cmd</code>+<code>I</code></td> + <td>{{ trans('editor.italic') }}</td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>1</code><br> + <code>Ctrl</code>+<code>2</code><br> + <code>Ctrl</code>+<code>3</code><br> + <code>Ctrl</code>+<code>4</code> + </td> + <td> + <code>Cmd</code>+<code>1</code><br> + <code>Cmd</code>+<code>2</code><br> + <code>Cmd</code>+<code>3</code><br> + <code>Cmd</code>+<code>4</code> + </td> + <td> + {{ trans('editor.header_large') }} <br> + {{ trans('editor.header_medium') }} <br> + {{ trans('editor.header_small') }} <br> + {{ trans('editor.header_tiny') }} + </td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>5</code><br> + <code>Ctrl</code>+<code>D</code> + </td> + <td> + <code>Cmd</code>+<code>5</code><br> + <code>Cmd</code>+<code>D</code> + </td> + <td>{{ trans('editor.paragraph') }}</td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>6</code><br> + <code>Ctrl</code>+<code>Q</code> + </td> + <td> + <code>Cmd</code>+<code>6</code><br> + <code>Cmd</code>+<code>Q</code> + </td> + <td>{{ trans('editor.blockquote') }}</td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>7</code><br> + <code>Ctrl</code>+<code>E</code> + </td> + <td> + <code>Cmd</code>+<code>7</code><br> + <code>Cmd</code>+<code>E</code> + </td> + <td>{{ trans('editor.insert_code_block') }}</td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>8</code><br> + <code>Ctrl</code>+<code>Shift</code>+<code>E</code> + </td> + <td> + <code>Cmd</code>+<code>8</code><br> + <code>Cmd</code>+<code>Shift</code>+<code>E</code> + </td> + <td>{{ trans('editor.inline_code') }}</td> + </tr> + <tr> + <td><code>Ctrl</code>+<code>9</code></td> + <td><code>Cmd</code>+<code>9</code></td> + <td> + {{ trans('editor.callouts') }} <br> + <small>{{ trans('editor.callouts_cycle') }}</small> + </td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>O</code> <br> + <code>Ctrl</code>+<code>P</code> + </td> + <td> + <code>Cmd</code>+<code>O</code> <br> + <code>Cmd</code>+<code>P</code> + </td> + <td> + {{ trans('editor.list_numbered') }} <br> + {{ trans('editor.list_bullet') }} + </td> + </tr> + <tr> + <td> + <code>Ctrl</code>+<code>Shift</code>+<code>K</code> + </td> + <td> + <code>Cmd</code>+<code>Shift</code>+<code>K</code> + </td> + <td>{{ trans('editor.link_selector') }}</td> + </tr> + </tbody> +</table> +<h4 class="mt-s">{{ trans('editor.editor_license') }}</h4> +<p> + {!! trans('editor.editor_lexical_license', ['lexicalLink' => '<a href="https://lexical.dev/" target="_blank" rel="noopener noreferrer">Lexical</a>']) !!} + <br> + <em class="text-muted">Copyright (c) Meta Platforms, Inc. and affiliates.</em> + <br> + <a href="{{ url('/licenses') }}" target="_blank">{{ trans('editor.editor_lexical_license_link') }}</a> +</p> \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 85f833528..318147ef5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -361,6 +361,7 @@ Route::get('/password/reset/{token}', [AccessControllers\ResetPasswordController Route::post('/password/reset', [AccessControllers\ResetPasswordController::class, 'reset'])->middleware('throttle:public'); // Metadata routes +Route::view('/help/tinymce', 'help.tinymce'); Route::view('/help/wysiwyg', 'help.wysiwyg'); Route::fallback([MetaController::class, 'notFound'])->name('fallback'); diff --git a/tests/Meta/HelpTest.php b/tests/Meta/HelpTest.php index e1de96bc8..acce65394 100644 --- a/tests/Meta/HelpTest.php +++ b/tests/Meta/HelpTest.php @@ -6,9 +6,9 @@ use Tests\TestCase; class HelpTest extends TestCase { - public function test_wysiwyg_help_shows_tiny_and_tiny_license_link() + public function test_tinymce_help_shows_tiny_and_tiny_license_link() { - $resp = $this->get('/help/wysiwyg'); + $resp = $this->get('/help/tinymce'); $resp->assertOk(); $this->withHtml($resp)->assertElementExists('a[href="https://www.tiny.cloud/"]'); $this->withHtml($resp)->assertElementExists('a[href="' . url('/libs/tinymce/license.txt') . '"]'); @@ -22,4 +22,12 @@ class HelpTest extends TestCase $contents = file_get_contents($expectedPath); $this->assertStringContainsString('MIT License', $contents); } + + public function test_wysiwyg_help_shows_lexical_and_licenses_link() + { + $resp = $this->get('/help/wysiwyg'); + $resp->assertOk(); + $this->withHtml($resp)->assertElementExists('a[href="https://lexical.dev/"]'); + $this->withHtml($resp)->assertElementExists('a[href="' . url('/licenses') . '"]'); + } }