mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-19 19:13:21 +00:00
Added help/about box to wysiwyg editor
- To display license info along with shortcuts. - Extracted out plain layout from 503 error page. - Added tests to ensure license references are as expected.
This commit is contained in:
parent
ef211a76ae
commit
c8b6f622f4
8 changed files with 223 additions and 23 deletions
resources
js/wysiwyg
lang/en
views
routes
tests
|
@ -7,6 +7,7 @@ import {getPlugin as getCodeeditorPlugin} from "./plugin-codeeditor";
|
||||||
import {getPlugin as getDrawioPlugin} from "./plugin-drawio";
|
import {getPlugin as getDrawioPlugin} from "./plugin-drawio";
|
||||||
import {getPlugin as getCustomhrPlugin} from "./plugins-customhr";
|
import {getPlugin as getCustomhrPlugin} from "./plugins-customhr";
|
||||||
import {getPlugin as getImagemanagerPlugin} from "./plugins-imagemanager";
|
import {getPlugin as getImagemanagerPlugin} from "./plugins-imagemanager";
|
||||||
|
import {getPlugin as getAboutPlugin} from "./plugins-about";
|
||||||
|
|
||||||
const style_formats = [
|
const style_formats = [
|
||||||
{title: "Large Header", format: "h2", preview: 'color: blue;'},
|
{title: "Large Header", format: "h2", preview: 'color: blue;'},
|
||||||
|
@ -74,7 +75,7 @@ function buildToolbar(options) {
|
||||||
'bullist numlist outdent indent',
|
'bullist numlist outdent indent',
|
||||||
textDirPlugins,
|
textDirPlugins,
|
||||||
'table imagemanager-insert link hr codeeditor drawio media',
|
'table imagemanager-insert link hr codeeditor drawio media',
|
||||||
'removeformat code ${textDirPlugins} fullscreen'
|
'removeformat code about fullscreen'
|
||||||
];
|
];
|
||||||
|
|
||||||
return toolbar.filter(row => Boolean(row)).join(' | ');
|
return toolbar.filter(row => Boolean(row)).join(' | ');
|
||||||
|
@ -100,12 +101,14 @@ function gatherPlugins(options) {
|
||||||
"codeeditor",
|
"codeeditor",
|
||||||
"media",
|
"media",
|
||||||
"imagemanager",
|
"imagemanager",
|
||||||
|
"about",
|
||||||
options.textDirection === 'rtl' ? 'directionality' : '',
|
options.textDirection === 'rtl' ? 'directionality' : '',
|
||||||
];
|
];
|
||||||
|
|
||||||
window.tinymce.PluginManager.add('codeeditor', getCodeeditorPlugin(options));
|
window.tinymce.PluginManager.add('codeeditor', getCodeeditorPlugin(options));
|
||||||
window.tinymce.PluginManager.add('customhr', getCustomhrPlugin(options));
|
window.tinymce.PluginManager.add('customhr', getCustomhrPlugin(options));
|
||||||
window.tinymce.PluginManager.add('imagemanager', getImagemanagerPlugin(options));
|
window.tinymce.PluginManager.add('imagemanager', getImagemanagerPlugin(options));
|
||||||
|
window.tinymce.PluginManager.add('about', getAboutPlugin(options));
|
||||||
|
|
||||||
if (options.drawioUrl) {
|
if (options.drawioUrl) {
|
||||||
window.tinymce.PluginManager.add('drawio', getDrawioPlugin(options));
|
window.tinymce.PluginManager.add('drawio', getDrawioPlugin(options));
|
||||||
|
|
29
resources/js/wysiwyg/plugins-about.js
Normal file
29
resources/js/wysiwyg/plugins-about.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* @param {Editor} editor
|
||||||
|
* @param {String} url
|
||||||
|
*/
|
||||||
|
function register(editor, url) {
|
||||||
|
|
||||||
|
const aboutDialog = {
|
||||||
|
title: 'About the WYSIWYG Editor',
|
||||||
|
url: window.baseUrl('/help/wysiwyg'),
|
||||||
|
};
|
||||||
|
|
||||||
|
editor.ui.registry.addButton('about', {
|
||||||
|
icon: 'help',
|
||||||
|
tooltip: 'About the editor',
|
||||||
|
onAction() {
|
||||||
|
tinymce.activeEditor.windowManager.openUrl(aboutDialog);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {WysiwygConfigOptions} options
|
||||||
|
* @return {register}
|
||||||
|
*/
|
||||||
|
export function getPlugin(options) {
|
||||||
|
return register;
|
||||||
|
}
|
|
@ -130,4 +130,17 @@ return [
|
||||||
'open_link' => 'Open link in...',
|
'open_link' => 'Open link in...',
|
||||||
'open_link_current' => 'Current window',
|
'open_link_current' => 'Current window',
|
||||||
'open_link_new' => 'New window',
|
'open_link_new' => 'New window',
|
||||||
|
|
||||||
|
// About view
|
||||||
|
'editor_license' => 'Editor License & Copyright',
|
||||||
|
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under an LGPLv2.1 license.',
|
||||||
|
'editor_tiny_license_link' => 'The copyright and license details of TinyMCE can be found here.',
|
||||||
|
'save_continue' => 'Save Page & Continue',
|
||||||
|
'callouts_cycle' => '(Keep pressing to toggle through types)',
|
||||||
|
'shortcuts' => 'Shortcuts',
|
||||||
|
'shortcut' => 'Shortcut',
|
||||||
|
'shortcuts_intro' => 'The following shortcuts are available in the editor:',
|
||||||
|
'windows_linux' => '(Windows/Linux)',
|
||||||
|
'mac' => '(Mac)',
|
||||||
|
'description' => 'Description',
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,22 +1,6 @@
|
||||||
<!DOCTYPE html>
|
@extends('layouts.plain')
|
||||||
<html lang="{{ config('app.lang') }}"
|
|
||||||
dir="{{ config('app.rtl') ? 'rtl' : 'ltr' }}">
|
|
||||||
<head>
|
|
||||||
<title>{{ isset($pageTitle) ? $pageTitle . ' | ' : '' }}{{ setting('app-name') }}</title>
|
|
||||||
|
|
||||||
<!-- Meta -->
|
@section('content')
|
||||||
<meta name="viewport" content="width=device-width">
|
|
||||||
<meta charset="utf-8">
|
|
||||||
|
|
||||||
<!-- Styles and Fonts -->
|
|
||||||
<link rel="stylesheet" href="{{ versioned_asset('dist/styles.css') }}">
|
|
||||||
<link rel="stylesheet" media="print" href="{{ versioned_asset('dist/print-styles.css') }}">
|
|
||||||
|
|
||||||
<!-- Custom Styles & Head Content -->
|
|
||||||
@include('common.custom-styles')
|
|
||||||
@include('common.custom-head')
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="content" class="block">
|
<div id="content" class="block">
|
||||||
<div class="container small mt-xl">
|
<div class="container small mt-xl">
|
||||||
<div class="card content-wrap auto-height">
|
<div class="card content-wrap auto-height">
|
||||||
|
@ -25,5 +9,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
@endsection
|
||||||
</html>
|
|
122
resources/views/help/wysiwyg.blade.php
Normal file
122
resources/views/help/wysiwyg.blade.php
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
@extends('layouts.plain')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="px-l pb-m m-s card">
|
||||||
|
|
||||||
|
<h4>{{ 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>Shift</code>+<code>8</code><br>
|
||||||
|
<code>Ctrl</code>+<code>Shift</code>+<code>E</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<code>Cmd</code>+<code>Shift</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>
|
||||||
|
{{ trans('editor.callouts_cycle') }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
22
resources/views/layouts/plain.blade.php
Normal file
22
resources/views/layouts/plain.blade.php
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ config('app.lang') }}"
|
||||||
|
dir="{{ config('app.rtl') ? 'rtl' : 'ltr' }}">
|
||||||
|
<head>
|
||||||
|
<title>{{ isset($pageTitle) ? $pageTitle . ' | ' : '' }}{{ setting('app-name') }}</title>
|
||||||
|
|
||||||
|
<!-- Meta -->
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<!-- Styles and Fonts -->
|
||||||
|
<link rel="stylesheet" href="{{ versioned_asset('dist/styles.css') }}">
|
||||||
|
<link rel="stylesheet" media="print" href="{{ versioned_asset('dist/print-styles.css') }}">
|
||||||
|
|
||||||
|
<!-- Custom Styles & Head Content -->
|
||||||
|
@include('common.custom-styles')
|
||||||
|
@include('common.custom-head')
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
@yield('content')
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -322,12 +322,15 @@ Route::get('/oidc/callback', [Auth\OidcController::class, 'callback']);
|
||||||
Route::get('/register/invite/{token}', [Auth\UserInviteController::class, 'showSetPassword']);
|
Route::get('/register/invite/{token}', [Auth\UserInviteController::class, 'showSetPassword']);
|
||||||
Route::post('/register/invite/{token}', [Auth\UserInviteController::class, 'setPassword']);
|
Route::post('/register/invite/{token}', [Auth\UserInviteController::class, 'setPassword']);
|
||||||
|
|
||||||
// Password reset link request routes...
|
// Password reset link request routes
|
||||||
Route::get('/password/email', [Auth\ForgotPasswordController::class, 'showLinkRequestForm']);
|
Route::get('/password/email', [Auth\ForgotPasswordController::class, 'showLinkRequestForm']);
|
||||||
Route::post('/password/email', [Auth\ForgotPasswordController::class, 'sendResetLinkEmail']);
|
Route::post('/password/email', [Auth\ForgotPasswordController::class, 'sendResetLinkEmail']);
|
||||||
|
|
||||||
// Password reset routes...
|
// Password reset routes
|
||||||
Route::get('/password/reset/{token}', [Auth\ResetPasswordController::class, 'showResetForm']);
|
Route::get('/password/reset/{token}', [Auth\ResetPasswordController::class, 'showResetForm']);
|
||||||
Route::post('/password/reset', [Auth\ResetPasswordController::class, 'reset']);
|
Route::post('/password/reset', [Auth\ResetPasswordController::class, 'reset']);
|
||||||
|
|
||||||
|
// Metadata routes
|
||||||
|
Route::view('/help/wysiwyg', 'help.wysiwyg');
|
||||||
|
|
||||||
Route::fallback([HomeController::class, 'notFound'])->name('fallback');
|
Route::fallback([HomeController::class, 'notFound'])->name('fallback');
|
||||||
|
|
25
tests/HelpTest.php
Normal file
25
tests/HelpTest.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests;
|
||||||
|
|
||||||
|
class HelpTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
public function test_wysiwyg_help_shows_tiny_and_tiny_license_link()
|
||||||
|
{
|
||||||
|
$resp = $this->get('/help/wysiwyg');
|
||||||
|
$resp->assertOk();
|
||||||
|
$resp->assertElementExists('a[href="https://www.tiny.cloud/"]');
|
||||||
|
$resp->assertElementExists('a[href="' . url('/libs/tinymce/license.txt') . '"]');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_tiny_license_exists_where_expected()
|
||||||
|
{
|
||||||
|
$expectedPath = public_path('/libs/tinymce/license.txt');
|
||||||
|
$this->assertTrue(file_exists($expectedPath));
|
||||||
|
|
||||||
|
$contents = file_get_contents($expectedPath);
|
||||||
|
$this->assertStringContainsString('GNU LESSER GENERAL PUBLIC LICENSE', $contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue