Compare commits

...

8 Commits

Author SHA1 Message Date
Dan Brown
26e93dc8c1 Updated assets and version for release v0.17.2 2017-07-22 16:49:07 +01:00
Dan Brown
a4c9a8491b Merge branch 'master' into release 2017-07-22 16:46:57 +01:00
Dan Brown
2704962277 Updated utfmb4 upgrade command 2017-07-22 16:19:17 +01:00
Dan Brown
6bcd89acf7 Moved utf8mb4 migration to command instead of migration
To prevent errors upon migration.
Command generates out the SQL syntax to make the change instead
so the upgrade can be done manually.

In reference to #425
2017-07-22 15:54:17 +01:00
Dan Brown
433cb9b3b2 Improved breadcrumb responsiveness
Closes #426
2017-07-22 15:20:36 +01:00
Dan Brown
7f43372dd4 Fixed broken code block rendering when using DOMPDF
Fixes #427
2017-07-22 14:34:17 +01:00
Dan Brown
b12e2ceada Added included content into page's text view
Allows rendered content to be shown in listings and used in searches.
Also prevented angular tags in content being parsed in listings.

Fixes #442
2017-07-22 14:21:56 +01:00
Dan Brown
bc067e9ad4 Updated dropdowns to hide after option click
Fixes #429
2017-07-22 14:03:06 +01:00
15 changed files with 145 additions and 60 deletions

View File

@@ -0,0 +1,57 @@
<?php
namespace BookStack\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class UpgradeDatabaseEncoding extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'bookstack:db-utf8mb4 {--database= : The database connection to use.}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate SQL commands to upgrade the database to UTF8mb4';
/**
* Create a new command instance.
*
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$connection = DB::getDefaultConnection();
if ($this->option('database') !== null) {
DB::setDefaultConnection($this->option('database'));
}
$database = DB::getDatabaseName();
$tables = DB::select('SHOW TABLES');
$this->line('ALTER DATABASE `'.$database.'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;');
$this->line('USE `'.$database.'`;');
$key = 'Tables_in_' . $database;
foreach ($tables as $table) {
$tableName = $table->$key;
$this->line('ALTER TABLE `'.$tableName.'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;');
}
DB::setDefaultConnection($connection);
}
}

View File

@@ -15,7 +15,8 @@ class Kernel extends ConsoleKernel
Commands\ClearActivity::class,
Commands\ClearRevisions::class,
Commands\RegeneratePermissions::class,
Commands\RegenerateSearch::class
Commands\RegenerateSearch::class,
Commands\UpgradeDatabaseEncoding::class
];
/**

View File

@@ -571,7 +571,7 @@ class EntityRepo
$draftPage->slug = $this->findSuitableSlug('page', $draftPage->name, false, $draftPage->book->id);
$draftPage->html = $this->formatHtml($input['html']);
$draftPage->text = strip_tags($draftPage->html);
$draftPage->text = $this->pageToPlainText($draftPage->html);
$draftPage->draft = false;
$draftPage->revision_count = 1;
@@ -713,6 +713,17 @@ class EntityRepo
return $content;
}
/**
* Get the plain text version of a page's content.
* @param Page $page
* @return string
*/
public function pageToPlainText(Page $page)
{
$html = $this->renderPage($page);
return strip_tags($html);
}
/**
* Get a new draft page instance.
* @param Book $book
@@ -816,7 +827,7 @@ class EntityRepo
$userId = user()->id;
$page->fill($input);
$page->html = $this->formatHtml($input['html']);
$page->text = strip_tags($page->html);
$page->text = $this->pageToPlainText($page);
if (setting('app-editor') !== 'markdown') $page->markdown = '';
$page->updated_by = $userId;
$page->revision_count++;
@@ -933,7 +944,7 @@ class EntityRepo
$revision = $page->revisions()->where('id', '=', $revisionId)->first();
$page->fill($revision->toArray());
$page->slug = $this->findSuitableSlug('page', $page->name, $page->id, $book->id);
$page->text = strip_tags($page->html);
$page->text = $this->pageToPlainText($page->html);
$page->updated_by = user()->id;
$page->save();
$this->searchService->indexEntity($page);
@@ -953,7 +964,7 @@ class EntityRepo
if ($page->draft) {
$page->fill($data);
if (isset($data['html'])) {
$page->text = strip_tags($data['html']);
$page->text = $this->pageToPlainText($data['html']);
}
$page->save();
return $page;

View File

@@ -1,7 +1,5 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class UpdateDbEncodingToUt8mb4 extends Migration
@@ -13,16 +11,9 @@ class UpdateDbEncodingToUt8mb4 extends Migration
*/
public function up()
{
$database = DB::getDatabaseName();
$tables = DB::select('SHOW TABLES');
$pdo = DB::getPdo();
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$pdo->exec('ALTER DATABASE `'.$database.'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
$key = 'Tables_in_' . $database;
foreach ($tables as $table) {
$tableName = $table->$key;
$pdo->exec('ALTER TABLE `'.$tableName.'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
}
// Migration removed due to issues during live migration.
// Instead you can run the command `artisan bookstack:db-utf8mb4`
// which will generate out the SQL request to upgrade your DB to utf8mb4.
}
/**
@@ -32,15 +23,6 @@ class UpdateDbEncodingToUt8mb4 extends Migration
*/
public function down()
{
$database = DB::getDatabaseName();
$tables = DB::select('SHOW TABLES');
$pdo = DB::getPdo();
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$pdo->exec('ALTER DATABASE `'.$database.'` CHARACTER SET utf8 COLLATE utf8_unicode_ci');
$key = 'Tables_in_' . $database;
foreach ($tables as $table) {
$tableName = $table->$key;
$pdo->exec('ALTER TABLE `'.$tableName.'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci');
}
//
}
}

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

@@ -379,7 +379,7 @@ module.exports = function (ngApp, events) {
*/
$scope.discardDraft = function () {
let url = window.baseUrl('/ajax/page/' + pageId);
$http.get(url).then((responseData) => {
$http.get(url).then(responseData => {
if (autoSave) $interval.cancel(autoSave);
$scope.draftText = trans('entities.pages_editing_page');
$scope.isUpdateDraft = false;

View File

@@ -123,25 +123,31 @@ module.exports = function (ngApp, events) {
restrict: 'A',
link: function (scope, element, attrs) {
const menu = element.find('ul');
element.find('[dropdown-toggle]').on('click', function () {
function hide() {
menu.hide();
menu.removeClass('anim menuIn');
}
function show() {
menu.show().addClass('anim menuIn');
element.mouseleave(hide);
// Focus on input if exist in dropdown and hide on enter press
let inputs = menu.find('input');
let hasInput = inputs.length > 0;
if (hasInput) {
inputs.first().focus();
element.on('keypress', 'input', event => {
if (event.keyCode === 13) {
event.preventDefault();
menu.hide();
menu.removeClass('anim menuIn');
return false;
}
});
}
element.mouseleave(function () {
menu.hide();
menu.removeClass('anim menuIn');
});
if (inputs.length > 0) inputs.first().focus();
}
// Hide menu on option click
element.on('click', '> ul a', hide);
// Show dropdown on toggle click.
element.find('[dropdown-toggle]').on('click', show);
// Hide menu on enter press in inputs
element.on('keypress', 'input', event => {
if (event.keyCode !== 13) return true;
event.preventDefault();
hide();
return false;
});
}
};

View File

@@ -142,7 +142,6 @@ form.search-box {
color: #aaa;
padding: 0 $-xs;
}
.faded {
a, button, span, span > div {
color: #666;
@@ -178,6 +177,8 @@ form.search-box {
padding-left: 0;
}
}
.action-buttons .dropdown-container:last-child a {
padding-right: 0;
padding-left: $-s;
@@ -196,6 +197,25 @@ form.search-box {
}
}
@include smaller-than($m) {
.breadcrumbs .text-button, .action-buttons .text-button {
padding: $-s $-xs;
}
.action-buttons .dropdown-container:last-child a {
padding-left: $-xs;
}
.breadcrumbs .text-button {
font-size: 0;
}
.breadcrumbs a i {
font-size: $fs-m;
padding-right: 0;
}
.breadcrumbs span.sep {
padding: 0 $-xxs;
}
}
.nav-tabs {
text-align: center;
a, .tab-item {

View File

@@ -152,6 +152,14 @@ pre {
}
}
@media print {
pre {
padding-left: 12px;
}
pre:after {
display: none;
}
}
blockquote {
display: block;

View File

@@ -5,10 +5,10 @@
<div class="faded-small toolbar">
<div class="container">
<div class="row">
<div class="col-sm-6 faded">
<div class="col-sm-6 col-xs-1 faded">
@include('books._breadcrumbs', ['book' => $book])
</div>
<div class="col-sm-6">
<div class="col-sm-6 col-xs-11">
<div class="action-buttons faded">
<span dropdown class="dropdown-container">
<div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>{{ trans('entities.export') }}</div>
@@ -50,7 +50,7 @@
</div>
<div class="container" id="entity-dashboard" entity-id="{{ $book->id }}" entity-type="book">
<div ng-non-bindable class="container" id="entity-dashboard" entity-id="{{ $book->id }}" entity-type="book">
<div class="row">
<div class="col-md-7">
@@ -112,7 +112,7 @@
@endif
<div class="search-box">
<form v-on:submit="searchBook">
<form v-on:submit.prevent="searchBook">
<input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.books_search_this') }}">
<button type="submit"><i class="zmdi zmdi-search"></i></button>
<button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>

View File

@@ -5,10 +5,10 @@
<div class="faded-small toolbar">
<div class="container">
<div class="row">
<div class="col-sm-8 faded" ng-non-bindable>
<div class="col-sm-6 col-xs-3 faded" ng-non-bindable>
@include('chapters._breadcrumbs', ['chapter' => $chapter])
</div>
<div class="col-sm-4 faded">
<div class="col-sm-6 col-xs-9 faded">
<div class="action-buttons">
<span dropdown class="dropdown-container">
<div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>{{ trans('entities.export') }}</div>
@@ -47,7 +47,7 @@
</div>
<div class="container" id="entity-dashboard" entity-id="{{ $chapter->id }}" entity-type="chapter">
<div class="container" id="entity-dashboard" ng-non-bindable entity-id="{{ $chapter->id }}" entity-type="chapter">
<div class="row">
<div class="col-md-7">
<h1>{{ $chapter->name }}</h1>
@@ -116,7 +116,7 @@
@endif
<div class="search-box">
<form v-on:submit="searchBook">
<form v-on:submit.prevent="searchBook">
<input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.chapters_search_this') }}">
<button type="submit"><i class="zmdi zmdi-search"></i></button>
<button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>

View File

@@ -5,10 +5,10 @@
<div class="faded-small toolbar">
<div class="container">
<div class="row">
<div class="col-sm-6 faded">
<div class="col-sm-8 col-xs-5 faded">
@include('pages._breadcrumbs', ['page' => $page])
</div>
<div class="col-sm-6 faded">
<div class="col-sm-4 col-xs-7 faded">
<div class="action-buttons">
<span dropdown class="dropdown-container">
<div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>{{ trans('entities.export') }}</div>

View File

@@ -1 +1 @@
v0.17.1
v0.17.2