mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Merge branch 'master' into patch-5
This commit is contained in:
commit
60013f776a
@ -422,25 +422,29 @@ class PageRepo extends EntityRepo
|
||||
return [];
|
||||
}
|
||||
|
||||
$tree = collect([]);
|
||||
foreach ($headers as $header) {
|
||||
$text = $header->nodeValue;
|
||||
$tree->push([
|
||||
$tree = collect($headers)->map(function($header) {
|
||||
$text = trim(str_replace("\xc2\xa0", '', $header->nodeValue));
|
||||
if (strlen($text) > 30) {
|
||||
$text = substr($text, 0, 27) . '...';
|
||||
}
|
||||
|
||||
return [
|
||||
'nodeName' => strtolower($header->nodeName),
|
||||
'level' => intval(str_replace('h', '', $header->nodeName)),
|
||||
'link' => '#' . $header->getAttribute('id'),
|
||||
'text' => strlen($text) > 30 ? substr($text, 0, 27) . '...' : $text
|
||||
]);
|
||||
}
|
||||
'text' => $text,
|
||||
];
|
||||
})->filter(function($header) {
|
||||
return strlen($header['text']) > 0;
|
||||
});
|
||||
|
||||
// Normalise headers if only smaller headers have been used
|
||||
if (count($tree) > 0) {
|
||||
$minLevel = $tree->pluck('level')->min();
|
||||
$tree = $tree->map(function ($header) use ($minLevel) {
|
||||
$header['level'] -= ($minLevel - 2);
|
||||
return $header;
|
||||
});
|
||||
}
|
||||
|
||||
return $tree->toArray();
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ class ImageRepo
|
||||
{
|
||||
$image->thumbs = [
|
||||
'gallery' => $this->getThumbnail($image, 150, 150, false),
|
||||
'display' => $this->getThumbnail($image, 840, null, true)
|
||||
'display' => $this->getThumbnail($image, 1680, null, true)
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -180,9 +180,20 @@ class MarkdownEditor {
|
||||
|
||||
// Handle image paste
|
||||
cm.on('paste', (cm, event) => {
|
||||
if (!event.clipboardData || !event.clipboardData.items) return;
|
||||
for (let i = 0; i < event.clipboardData.items.length; i++) {
|
||||
uploadImage(event.clipboardData.items[i].getAsFile());
|
||||
const clipboardItems = event.clipboardData.items;
|
||||
if (!event.clipboardData || !clipboardItems) return;
|
||||
|
||||
// Don't handle if clipboard includes text content
|
||||
for (let clipboardItem of clipboardItems) {
|
||||
if (clipboardItem.type.includes('text/')) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (let clipboardItem of clipboardItems) {
|
||||
if (clipboardItem.type.includes("image")) {
|
||||
uploadImage(clipboardItem.getAsFile());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -8,11 +8,20 @@ import DrawIO from "../services/drawio";
|
||||
* @param editor
|
||||
*/
|
||||
function editorPaste(event, editor, wysiwygComponent) {
|
||||
if (!event.clipboardData || !event.clipboardData.items) return;
|
||||
const clipboardItems = event.clipboardData.items;
|
||||
if (!event.clipboardData || !clipboardItems) return;
|
||||
|
||||
for (let clipboardItem of event.clipboardData.items) {
|
||||
if (clipboardItem.type.indexOf("image") === -1) continue;
|
||||
event.preventDefault();
|
||||
// Don't handle if clipboard includes text content
|
||||
for (let clipboardItem of clipboardItems) {
|
||||
if (clipboardItem.type.includes('text/')) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (let clipboardItem of clipboardItems) {
|
||||
if (!clipboardItem.type.includes("image")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const id = "image-" + Math.random().toString(16).slice(2);
|
||||
const loadingImage = window.baseUrl('/loading.gif');
|
||||
|
@ -59,7 +59,7 @@
|
||||
}
|
||||
|
||||
@include smaller-than($m) {
|
||||
.grid.third {
|
||||
.grid.third:not(.no-break) {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
.grid.half:not(.no-break), .grid.left-focus:not(.no-break), .grid.right-focus:not(.no-break) {
|
||||
@ -81,7 +81,7 @@
|
||||
}
|
||||
|
||||
@include smaller-than($s) {
|
||||
.grid.third {
|
||||
.grid.third:not(.no-break) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
@include smaller-than($m) {
|
||||
@include smaller-than($s) {
|
||||
.page-edit-toolbar {
|
||||
overflow-x: scroll;
|
||||
overflow-y: visible;
|
||||
z-index: 12;
|
||||
}
|
||||
.page-edit-toolbar .grid.third {
|
||||
display: block;
|
||||
@ -35,8 +34,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@include smaller-than($m) {
|
||||
.page-edit-toolbar #save-button {
|
||||
.page-save-mobile-button {
|
||||
position: fixed;
|
||||
z-index: 30;
|
||||
border-radius: 50%;
|
||||
@ -47,12 +45,10 @@
|
||||
bottom: $-s;
|
||||
box-shadow: $bs-hover;
|
||||
background-color: currentColor;
|
||||
text-align: center;
|
||||
svg {
|
||||
fill: #FFF;
|
||||
}
|
||||
span {
|
||||
display: none;
|
||||
}
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,14 @@ return [
|
||||
'book_sort' => 'sorteerde boek',
|
||||
'book_sort_notification' => 'Boek Succesvol Gesorteerd',
|
||||
|
||||
// Bookshelves
|
||||
'bookshelf_create' => 'maakte Boekenplank',
|
||||
'bookshelf_create_notification' => 'Boekenplank Succesvol Aangemaakt',
|
||||
'bookshelf_update' => 'veranderde boekenplank',
|
||||
'bookshelf_update_notification' => 'Boekenplank Succesvol Bijgewerkt',
|
||||
'bookshelf_delete' => 'verwijderde boekenplank',
|
||||
'bookshelf_delete_notification' => 'Boekenplank Succesvol Verwijderd',
|
||||
|
||||
// Other
|
||||
'commented_on' => 'reactie op',
|
||||
];
|
||||
|
@ -1,35 +1,35 @@
|
||||
<?php
|
||||
return [
|
||||
|
||||
/**
|
||||
* Buttons
|
||||
*/
|
||||
|
||||
// Buttons
|
||||
'cancel' => 'Annuleren',
|
||||
'confirm' => 'Bevestigen',
|
||||
'back' => 'Terug',
|
||||
'save' => 'Opslaan',
|
||||
'continue' => 'Doorgaan',
|
||||
'select' => 'Kies',
|
||||
'toggle_all' => 'Toggle Alles',
|
||||
'more' => 'Meer',
|
||||
|
||||
/**
|
||||
* Form Labels
|
||||
*/
|
||||
// Form Labels
|
||||
'name' => 'Naam',
|
||||
'description' => 'Beschrijving',
|
||||
'role' => 'Rol',
|
||||
'cover_image' => 'Omslagfoto',
|
||||
'cover_image_description' => 'Deze afbeelding moet ongeveer 300x170px zijn.',
|
||||
/**
|
||||
* Actions
|
||||
*/
|
||||
|
||||
// Actions
|
||||
'actions' => 'Acties',
|
||||
'view' => 'Bekijk',
|
||||
'view_all' => 'Bekijk Alle',
|
||||
'create' => 'Aanmaken',
|
||||
'update' => 'Update',
|
||||
'edit' => 'Bewerk',
|
||||
'sort' => 'Sorteer',
|
||||
'move' => 'Verplaats',
|
||||
'copy' => 'Kopiëren',
|
||||
'reply' => 'Beantwoorden',
|
||||
'delete' => 'Verwijder',
|
||||
'search' => 'Zoek',
|
||||
'search_clear' => 'Zoekopdracht wissen',
|
||||
@ -37,15 +37,22 @@ return [
|
||||
'remove' => 'Verwijderen',
|
||||
'add' => 'Toevoegen',
|
||||
|
||||
/**
|
||||
* Misc
|
||||
*/
|
||||
// Sort Options
|
||||
'sort_name' => 'Naam',
|
||||
'sort_created_at' => 'Aanmaakdatum',
|
||||
'sort_updated_at' => 'Gewijzigd op',
|
||||
|
||||
// Misc
|
||||
'deleted_user' => 'Verwijderde gebruiker',
|
||||
'no_activity' => 'Geen activiteiten',
|
||||
'no_items' => 'Geen items beschikbaar',
|
||||
'back_to_top' => 'Terug naar boven',
|
||||
'toggle_details' => 'Details Weergeven',
|
||||
'toggle_thumbnails' => 'Thumbnails Weergeven',
|
||||
'details' => 'Details',
|
||||
'grid_view' => 'Grid weergave',
|
||||
'list_view' => 'Lijst weergave',
|
||||
'default' => 'Standaard',
|
||||
|
||||
/**
|
||||
* Header
|
||||
@ -53,6 +60,10 @@ return [
|
||||
'view_profile' => 'Profiel Weergeven',
|
||||
'edit_profile' => 'Profiel Bewerken',
|
||||
|
||||
// Layout tabs
|
||||
'tab_info' => 'Info',
|
||||
'tab_content' => 'Inhoud',
|
||||
|
||||
/**
|
||||
* Email Content
|
||||
*/
|
||||
|
@ -65,9 +65,38 @@ return [
|
||||
'search_set_date' => 'Zet datum',
|
||||
'search_update' => 'Update zoekresultaten',
|
||||
|
||||
/**
|
||||
* Books
|
||||
*/
|
||||
// Shelves
|
||||
'shelf' => 'Boekenplank',
|
||||
'shelves' => 'Boekenplanken',
|
||||
'x_shelves' => ':count Boekenplank|:count Boekenplanken',
|
||||
'shelves_long' => 'Boekenplanken',
|
||||
'shelves_empty' => 'Er zijn geen boekenplanken aangemaakt',
|
||||
'shelves_create' => 'Nieuwe Boekenplank Aanmaken',
|
||||
'shelves_popular' => 'Populaire Boekenplanken',
|
||||
'shelves_new' => 'Nieuwe Boekenplanken',
|
||||
'shelves_popular_empty' => 'De meest populaire boekenplanken worden hier weergegeven.',
|
||||
'shelves_new_empty' => 'De meest recent aangemaakt boekenplanken worden hier weergeven.',
|
||||
'shelves_save' => 'Boekenplanken Opslaan',
|
||||
'shelves_books' => 'Boeken op deze plank',
|
||||
'shelves_add_books' => 'Toevoegen boeken aan deze plank',
|
||||
'shelves_drag_books' => 'Sleep boeken hier naartoe om deze toe te voegen aan deze plank',
|
||||
'shelves_empty_contents' => 'Er zijn geen boeken aan deze plank toegekend',
|
||||
'shelves_edit_and_assign' => 'Bewerk boekenplank om boeken toe te kennen.',
|
||||
'shelves_edit_named' => 'Bewerk Boekenplank :name',
|
||||
'shelves_edit' => 'Bewerk Boekenplank',
|
||||
'shelves_delete' => 'Verwijder Boekenplank',
|
||||
'shelves_delete_named' => 'Verwijder Boekenplank :name',
|
||||
'shelves_delete_explain' => "Deze actie verwijdert de boekenplank met naam ':name'. De boeken op deze plank worden niet verwijderd.",
|
||||
'shelves_delete_confirmation' => 'Weet je zeker dat je deze boekenplank wilt verwijderen?',
|
||||
'shelves_permissions' => 'Boekenplank Permissies',
|
||||
'shelves_permissions_updated' => 'Boekenplank Permissies Opgeslagen',
|
||||
'shelves_permissions_active' => 'Boekenplank Permissies Actief',
|
||||
'shelves_copy_permissions_to_books' => 'Kopieer Permissies naar Boeken',
|
||||
'shelves_copy_permissions' => 'Kopieer Permissies',
|
||||
'shelves_copy_permissions_explain' => 'Met deze actie worden de permissies van deze boekenplank gekopieerd naar alle boeken op de plank. Voordat deze actie wordt uitgevoerd, zorg dat de wijzigingen in de permissies van deze boekenplank zijn opgeslagen.',
|
||||
'shelves_copy_permission_success' => 'Boekenplank permissies gekopieerd naar :count boeken',
|
||||
|
||||
// Books
|
||||
'book' => 'Boek',
|
||||
'books' => 'Boeken',
|
||||
'x_books' => ':count Boek|:count Boeken',
|
||||
|
@ -26,7 +26,7 @@ return [
|
||||
*/
|
||||
'actions' => 'Действия',
|
||||
'view' => 'Просмотр',
|
||||
'view_all' => 'View All',
|
||||
'view_all' => 'Показать все',
|
||||
'create' => 'Создание',
|
||||
'update' => 'Обновление',
|
||||
'edit' => 'Редактировать',
|
||||
|
@ -105,11 +105,13 @@ return [
|
||||
*/
|
||||
'shelf' => 'Полка',
|
||||
'shelves' => 'Полки',
|
||||
'x_shelves' => ':count полок|:count полок',
|
||||
'shelves_long' => 'Книжные полки',
|
||||
'shelves_empty' => 'Полки не созданы',
|
||||
'shelves_create' => 'Создать новую полку',
|
||||
'shelves_popular' => 'Популярные полки',
|
||||
'shelves_new' => 'Новые полки',
|
||||
'shelves_new_action' => 'Новая полка',
|
||||
'shelves_popular_empty' => 'Популярные полки появятся здесь.',
|
||||
'shelves_new_empty' => 'Последние созданные полки появятся здесь.',
|
||||
'shelves_save' => 'Сохранить полку',
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
{{--Header Bar--}}
|
||||
<div class="primary-background-light toolbar page-edit-toolbar">
|
||||
<div class="grid third v-center">
|
||||
<div class="grid third no-break v-center">
|
||||
|
||||
<div class="action-buttons text-left px-m py-xs">
|
||||
<a href="{{ back()->getTargetUrl() }}" class="text-button text-primary">@icon('back')<span class="hide-under-l">{{ trans('common.back') }}</span></a>
|
||||
@ -49,7 +49,7 @@
|
||||
<span>{{-- Prevents button jumping on menu show --}}</span>
|
||||
</div>
|
||||
|
||||
<button type="submit" id="save-button" class="float-left text-primary text-button text-pos-hover">@icon('save')<span>{{ trans('entities.pages_save') }}</span></button>
|
||||
<button type="submit" id="save-button" class="float-left text-primary text-button text-pos-hover hide-under-m">@icon('save')<span>{{ trans('entities.pages_save') }}</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -120,4 +120,6 @@
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
<button type="submit" id="save-button-mobile" title="{{ trans('entities.pages_save') }}" class="text-primary text-button hide-over-m page-save-mobile-button">@icon('save')</button>
|
||||
</div>
|
@ -190,6 +190,11 @@
|
||||
<div>
|
||||
<div v-pre class="card content-wrap">
|
||||
<h1 class="list-heading">{{ trans('entities.search_results') }}</h1>
|
||||
<form action="{{ baseUrl('/search') }}" method="GET" class="search-box flexible hide-over-l">
|
||||
<input value="{{$searchTerm}}" type="text" name="term" placeholder="{{ trans('common.search') }}">
|
||||
<button type="submit">@icon('search')</button>
|
||||
<button v-if="searching" v-cloak class="search-box-cancel text-neg" v-on:click="clearSearch" type="button">@icon('close')</button>
|
||||
</form>
|
||||
<h6 class="text-muted">{{ trans_choice('entities.search_total_results_found', $totalResults, ['count' => $totalResults]) }}</h6>
|
||||
<div class="book-contents">
|
||||
@include('partials.entity-list', ['entities' => $entities, 'showPath' => true])
|
||||
|
32
tests/Unit/PageRepoTest.php
Normal file
32
tests/Unit/PageRepoTest.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Tests;
|
||||
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
|
||||
class PageRepoTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var PageRepo $pageRepo
|
||||
*/
|
||||
protected $pageRepo;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->pageRepo = app()->make(PageRepo::class);
|
||||
}
|
||||
|
||||
public function test_get_page_nav_does_not_show_empty_titles()
|
||||
{
|
||||
$content = '<h1 id="testa">Hello</h1><h2 id="testb"> </h2><h3 id="testc"></h3>';
|
||||
$navMap = $this->pageRepo->getPageNav($content);
|
||||
|
||||
$this->assertCount(1, $navMap);
|
||||
$this->assertArraySubset([
|
||||
'nodeName' => 'h1',
|
||||
'link' => '#testa',
|
||||
'text' => 'Hello'
|
||||
], $navMap[0]);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user