Compare commits

...

12 Commits

Author SHA1 Message Date
Dan Brown
176a0dcd59 Updated version and assets for release v22.02.2 2022-03-01 22:45:41 +00:00
Dan Brown
94b0f70bfa Merge branch 'development' into release 2022-03-01 22:45:12 +00:00
Dan Brown
36d7ff77a9 New translations editor.php (Italian) (#3301) 2022-03-01 22:32:43 +00:00
Dan Brown
fb16ac326f Reduced dynamic fade in dark mode
For #3203
2022-03-01 22:29:31 +00:00
Dan Brown
5947f59a04 Updated strategy for empty newline sections
- For some reason, TinyMCE would handle empty paragraphs with a '&nbsp'
  by default but this would be removed when the paragraph had an
  attribute. This was fine in the old editor.
- This changes the approach to use '<br>' tags within elements
  for "spaced emptiness".
- For compatbility with any existing empty paragraphs, I updated the
  styles to show default height for empty paragraph sections.
- This also makes changes to help preserve encoded &nbsp; html tags
  since they were getting converted along the journey.

Related to #3302
2022-03-01 17:26:06 +00:00
Dan Brown
1843d80fb7 Added cache breaker to tinymce loading systems
Takes the version from BookStack app.js paths instead of tinyMCE version
since things external from TinyMCE could be loaded using this.
2022-03-01 13:41:53 +00:00
Dan Brown
08b2a77d41 Updated version and assets for release v22.02.1 2022-02-27 17:46:06 +00:00
Dan Brown
3e8e9a23cf Merge branch 'development' into release 2022-02-27 17:45:49 +00:00
Dan Brown
1253711c7d New translations editor.php (Chinese Simplified) (#3291) 2022-02-27 17:44:58 +00:00
Dan Brown
963d8f4693 Updated issue templates, readme and dev version
- Updated bug report template to capture browser.
- Updated readme roadmap.
- Bumped dev version.
2022-02-27 17:26:27 +00:00
Dan Brown
0de4d6d223 Improved WYSIWYG code block behaviour via range of fixes
- Fixed issues with new code blocks breaking or acting odd due to
  misnamed contenteditable attribute.
- Helped fix issue where code blocks may show in a strage blank state
  due to timing within shadow dom loading.
- Fixed some function timing issues where some functions required their
  async predecessor to have finished.

Tested rather heavily in firefox and brave.
Fixes #3292
2022-02-27 17:21:24 +00:00
Dan Brown
06f694bad2 Updated tinymce link query to break caches
Fixes #3293
2022-02-27 16:03:18 +00:00
19 changed files with 90 additions and 49 deletions

View File

@@ -35,6 +35,15 @@ body:
description: Provide any additional context and screenshots here to help us solve this issue
validations:
required: false
- type: input
id: browserdetails
attributes:
label: Browser Details
description: |
If this is an issue that occurs when using the BookStack interface, please provide details of the browser used which presents the reported issue.
placeholder: (eg. Firefox 97 (64-bit) on Windows 11)
validations:
required: false
- type: input
id: bsversion
attributes:

View File

@@ -33,8 +33,7 @@ body:
attributes:
label: Have you searched for an existing open/closed issue?
description: |
To help us keep these issues under control, please ensure you have first [searched our issue list](https://github.com/BookStackApp/BookStack/issues?q=is%3Aissue)
for any existing issues that cover the fundemental benefit/goal of your request.
To help us keep these issues under control, please ensure you have first [searched our issue list](https://github.com/BookStackApp/BookStack/issues?q=is%3Aissue) for any existing issues that cover the fundemental benefit/goal of your request.
options:
- label: I have searched for existing issues and none cover my fundemental request
required: true

View File

@@ -239,6 +239,9 @@ class PageContent
$html .= $doc->saveHTML($childNode);
}
// Perform required string-level tweaks
$html = str_replace(' ', '&nbsp;', $html);
return $html;
}

6
public/dist/app.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -63,7 +63,7 @@ Below is a high-level road map view for BookStack to provide a sense of directio
- **Platform REST API** - *(Most actions implemented, maturing)*
- *A REST API covering, at minimum, control of core content models (Books, Chapters, Pages) for automation and platform extension.*
- **Editor Alignment & Review** - *(Started)*
- **Editor Alignment & Review** - *(In Progress)*
- *Review the page editors with goal of achieving increased interoperability & feature parity while also considering collaborative editing potential.*
- **Permission System Review**
- *Improvement in how permissions are applied and a review of the efficiency of the permission & roles system.*

View File

@@ -59,12 +59,10 @@ class CodeEditor {
this.languageInput.value = language;
this.callback = callback;
this.show();
this.updateEditorMode(language);
window.importVersioned('code').then(Code => {
Code.setContent(this.editor, code);
});
this.show()
.then(() => this.updateEditorMode(language))
.then(() => window.importVersioned('code'))
.then(Code => Code.setContent(this.editor, code));
}
async show() {

View File

@@ -221,11 +221,15 @@ export function build(options) {
// Build toolbar content
const {toolbar, groupButtons: toolBarGroupButtons} = buildToolbar(options);
// BookStack Version
const version = document.querySelector('script[src*="/dist/app.js"]').getAttribute('src').split('?version=')[1];
// Return config object
return {
width: '100%',
height: '100%',
selector: '#html-editor',
cache_suffix: '?version=' + version,
content_css: [
window.baseUrl('/dist/styles.css'),
],
@@ -239,6 +243,7 @@ export function build(options) {
remove_script_host: false,
document_base_url: window.baseUrl('/'),
end_container_on_empty_block: true,
remove_trailing_brs: false,
statusbar: false,
menubar: false,
paste_data_images: false,

View File

@@ -91,15 +91,35 @@ function defineCodeBlockCustomElement(editor) {
}
connectedCallback() {
const connectedTime = Date.now();
if (this.cm) {
return;
}
this.cleanChildContent();
const container = this.shadowRoot.querySelector('.CodeMirrorContainer');
importVersioned('code').then(Code => {
const renderCodeMirror = (Code) => {
this.cm = Code.wysiwygView(container, this.getContent(), this.getLanguage());
Code.updateLayout(this.cm);
};
window.importVersioned('code').then((Code) => {
const timeout = (Date.now() - connectedTime < 20) ? 20 : 0;
setTimeout(() => renderCodeMirror(Code), timeout);
});
}
cleanChildContent() {
const pre = this.querySelector('pre');
if (!pre) return;
for (const preChild of pre.childNodes) {
if (preChild.nodeName === '#text' && preChild.textContent === '') {
preChild.remove();
}
}
}
}
win.customElements.define('code-block', CodeBlockElement);
@@ -130,15 +150,13 @@ function register(editor, url) {
} else {
const textContent = editor.selection.getContent({format: 'text'});
showPopup(editor, textContent, '', (newCode, newLang) => {
const wrap = doc.createElement('code-block');
const pre = doc.createElement('pre');
const code = doc.createElement('code');
code.classList.add(`language-${newLang}`);
code.innerText = newCode;
pre.append(code);
wrap.append(pre);
editor.insertContent(wrap.outerHTML);
editor.insertContent(pre.outerHTML);
});
}
});
@@ -168,7 +186,7 @@ function register(editor, url) {
editor.parser.addNodeFilter('code-block', function(elms) {
for (const el of elms) {
el.attr('content-editable', 'false');
el.attr('contenteditable', 'false');
}
});

View File

@@ -131,12 +131,12 @@ return [
'open_link' => 'Apri collegamento in...',
'open_link_current' => 'Finestra corrente',
'open_link_new' => 'Nuova finestra',
'insert_collapsible' => 'Insert collapsible block',
'collapsible_unwrap' => 'Unwrap',
'edit_label' => 'Edit label',
'toggle_open_closed' => 'Toggle open/closed',
'collapsible_edit' => 'Edit collapsible block',
'toggle_label' => 'Toggle label',
'insert_collapsible' => 'Inserisci blocco collassabile',
'collapsible_unwrap' => 'Espandi',
'edit_label' => 'Modifica etichetta',
'toggle_open_closed' => 'Espandi/Comprimi',
'collapsible_edit' => 'Modifica blocco collassabile',
'toggle_label' => 'Attiva/Disattiva etichetta',
// About view
'about_title' => 'Informazioni sull\'editor di WYSIWYG',

View File

@@ -57,7 +57,7 @@ return [
'list_numbered' => '有序列表',
'indent_increase' => '增加缩进',
'indent_decrease' => '减少缩进',
'table' => '表',
'table' => '表',
'insert_image' => '插入图片',
'insert_image_title' => '插入/编辑图片',
'insert_link' => '插入/编辑链接',

View File

@@ -238,13 +238,13 @@
}
.fade-in-when-active {
opacity: 0.6;
@include lightDark(opacity, 0.6, 0.7);
transition: opacity ease-in-out 120ms;
&:hover, &:focus-within {
opacity: 1;
opacity: 1 !important;
}
@media (prefers-contrast: more) {
opacity: 1;
opacity: 1 !important;
}
}

View File

@@ -361,16 +361,13 @@ body.flexbox {
display: none;
}
.tri-layout-left-contents > *, .tri-layout-right-contents > * {
opacity: 0.6;
@include lightDark(opacity, 0.6, 0.7);
transition: opacity ease-in-out 120ms;
&:hover {
opacity: 1;
}
&:focus-within {
opacity: 1;
&:hover, &:focus-within {
opacity: 1 !important;
}
@media (prefers-contrast: more) {
opacity: 1;
opacity: 1 !important;
}
}

View File

@@ -193,7 +193,7 @@
}
}
.entity-list-item.selected {
background-color: rgba(0, 0, 0, 0.08);
@include lightDark(background-color, rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.08));
}
.entity-list-item.no-hover {
margin-top: -$-xs;

View File

@@ -164,6 +164,10 @@ body.tox-fullscreen, body.markdown-fullscreen {
clear: both;
}
p:empty {
min-height: 1.6em;
}
&.page-revision {
pre code {
white-space: pre-wrap;

View File

@@ -1,7 +1,7 @@
@extends('layouts.base')
@section('head')
<script src="{{ url('/libs/tinymce/tinymce.min.js?ver=4.9.4') }}" nonce="{{ $cspNonce }}"></script>
<script src="{{ url('/libs/tinymce/tinymce.min.js?ver=5.10.2') }}" nonce="{{ $cspNonce }}"></script>
@stop
@section('body-class', 'flexbox')

View File

@@ -692,35 +692,43 @@ class PageContentTest extends TestCase
public function test_base64_images_within_markdown_blanked_if_not_supported_extension_for_extract()
{
$this->asEditor();
$page = Page::query()->first();
$this->put($page->getUrl(), [
$this->asEditor()->put($page->getUrl(), [
'name' => $page->name, 'summary' => '',
'markdown' => 'test ![test](data:image/jiff;base64,' . $this->base64Jpeg . ')',
]);
$page->refresh();
$this->assertStringContainsString('<img src=""', $page->html);
$this->assertStringContainsString('<img src=""', $page->refresh()->html);
}
public function test_nested_headers_gets_assigned_an_id()
{
$this->asEditor();
$page = Page::query()->first();
$content = '<table><tbody><tr><td><h5>Simple Test</h5></td></tr></tbody></table>';
$this->put($page->getUrl(), [
$this->asEditor()->put($page->getUrl(), [
'name' => $page->name,
'html' => $content,
'summary' => '',
]);
$updatedPage = Page::query()->where('id', '=', $page->id)->first();
// The top level <table> node will get assign the bkmrk-simple-test id because the system will
// take the node value of h5
// So the h5 should get the bkmrk-simple-test-1 id
$this->assertStringContainsString('<h5 id="bkmrk-simple-test-1">Simple Test</h5>', $updatedPage->html);
$this->assertStringContainsString('<h5 id="bkmrk-simple-test-1">Simple Test</h5>', $page->refresh()->html);
}
public function test_non_breaking_spaces_are_preserved()
{
/** @var Page $page */
$page = Page::query()->first();
$content = '<p>&nbsp;</p>';
$this->asEditor()->put($page->getUrl(), [
'name' => $page->name,
'html' => $content,
]);
$this->assertStringContainsString('<p id="bkmrk-%C2%A0">&nbsp;</p>', $page->refresh()->html);
}
}

View File

@@ -1 +1 @@
v22.02
v22.02.2