Skip to content

Commit 76e3086

Browse files
committed
Merge branch 'master' into release
2 parents 3edc9fe + f3ee8f2 commit 76e3086

15 files changed

Lines changed: 80 additions & 58 deletions

File tree

.env.example.complete

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,9 @@ DISABLE_EXTERNAL_SERVICES=false
238238
# Example: AVATAR_URL=https://seccdn.libravatar.org/avatar/${hash}?s=${size}&d=identicon
239239
AVATAR_URL=
240240

241-
# Enable draw.io integration
241+
# Enable diagrams.net integration
242242
# Can simply be true/false to enable/disable the integration.
243-
# Alternatively, It can be URL to the draw.io instance you want to use.
243+
# Alternatively, It can be URL to the diagrams.net instance you want to use.
244244
# For URLs, The following URL parameters should be included: embed=1&proto=json&spin=1
245245
DRAWIO=true
246246

app/Entities/Managers/PageContent.php

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
use BookStack\Entities\Page;
44
use DOMDocument;
5-
use DOMElement;
65
use DOMNodeList;
76
use DOMXPath;
87

@@ -44,18 +43,24 @@ protected function formatHtml(string $htmlText): string
4443
$container = $doc->documentElement;
4544
$body = $container->childNodes->item(0);
4645
$childNodes = $body->childNodes;
46+
$xPath = new DOMXPath($doc);
4747

4848
// Set ids on top-level nodes
4949
$idMap = [];
5050
foreach ($childNodes as $index => $childNode) {
51-
$this->setUniqueId($childNode, $idMap);
51+
[$oldId, $newId] = $this->setUniqueId($childNode, $idMap);
52+
if ($newId && $newId !== $oldId) {
53+
$this->updateLinks($xPath, '#' . $oldId, '#' . $newId);
54+
}
5255
}
5356

5457
// Ensure no duplicate ids within child items
55-
$xPath = new DOMXPath($doc);
5658
$idElems = $xPath->query('//body//*//*[@id]');
5759
foreach ($idElems as $domElem) {
58-
$this->setUniqueId($domElem, $idMap);
60+
[$oldId, $newId] = $this->setUniqueId($domElem, $idMap);
61+
if ($newId && $newId !== $oldId) {
62+
$this->updateLinks($xPath, '#' . $oldId, '#' . $newId);
63+
}
5964
}
6065

6166
// Generate inner html as a string
@@ -67,23 +72,34 @@ protected function formatHtml(string $htmlText): string
6772
return $html;
6873
}
6974

75+
/**
76+
* Update the all links to the $old location to instead point to $new.
77+
*/
78+
protected function updateLinks(DOMXPath $xpath, string $old, string $new)
79+
{
80+
$old = str_replace('"', '', $old);
81+
$matchingLinks = $xpath->query('//body//*//*[@href="'.$old.'"]');
82+
foreach ($matchingLinks as $domElem) {
83+
$domElem->setAttribute('href', $new);
84+
}
85+
}
86+
7087
/**
7188
* Set a unique id on the given DOMElement.
7289
* A map for existing ID's should be passed in to check for current existence.
73-
* @param DOMElement $element
74-
* @param array $idMap
90+
* Returns a pair of strings in the format [old_id, new_id]
7591
*/
76-
protected function setUniqueId($element, array &$idMap)
92+
protected function setUniqueId(\DOMNode $element, array &$idMap): array
7793
{
7894
if (get_class($element) !== 'DOMElement') {
79-
return;
95+
return ['', ''];
8096
}
8197

82-
// Overwrite id if not a BookStack custom id
98+
// Stop if there's an existing valid id that has not already been used.
8399
$existingId = $element->getAttribute('id');
84100
if (strpos($existingId, 'bkmrk') === 0 && !isset($idMap[$existingId])) {
85101
$idMap[$existingId] = true;
86-
return;
102+
return [$existingId, $existingId];
87103
}
88104

89105
// Create an unique id for the element
@@ -100,6 +116,7 @@ protected function setUniqueId($element, array &$idMap)
100116

101117
$element->setAttribute('id', $newId);
102118
$idMap[$newId] = true;
119+
return [$existingId, $newId];
103120
}
104121

105122
/**

package-lock.json

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"build:css:dev": "sass ./resources/sass:./public/dist",
55
"build:css:watch": "sass ./resources/sass:./public/dist --watch",
66
"build:css:production": "sass ./resources/sass:./public/dist -s compressed",
7-
"build:js:dev": "esbuild --bundle ./resources/js/index.js --outfile=public/dist/app.js --sourcemap --target=es2020",
7+
"build:js:dev": "esbuild --bundle ./resources/js/index.js --outfile=public/dist/app.js --sourcemap --target=es2019 --main-fields=module,main",
88
"build:js:watch": "chokidar \"./resources/**/*.js\" -c \"npm run build:js:dev\"",
9-
"build:js:production": "NODE_ENV=production esbuild --bundle ./resources/js/index.js --outfile=public/dist/app.js --sourcemap --minify",
9+
"build:js:production": "NODE_ENV=production esbuild --bundle ./resources/js/index.js --outfile=public/dist/app.js --sourcemap --target=es2019 --main-fields=module,main --minify",
1010
"build": "npm-run-all --parallel build:*:dev",
1111
"production": "npm-run-all --parallel build:*:production",
1212
"dev": "npm-run-all --parallel watch livereload",
@@ -16,18 +16,18 @@
1616
},
1717
"devDependencies": {
1818
"chokidar-cli": "^2.1.0",
19-
"esbuild": "0.6.30",
19+
"esbuild": "0.7.8",
2020
"livereload": "^0.9.1",
2121
"npm-run-all": "^4.1.5",
2222
"punycode": "^2.1.1",
23-
"sass": "^1.26.10"
23+
"sass": "^1.26.11"
2424
},
2525
"dependencies": {
2626
"clipboard": "^2.0.6",
2727
"codemirror": "^5.58.1",
2828
"dropzone": "^5.7.2",
29-
"markdown-it": "^11.0.0",
29+
"markdown-it": "^11.0.1",
3030
"markdown-it-task-lists": "^2.1.1",
31-
"sortablejs": "^1.10.2"
31+
"sortablejs": "^1.12.0"
3232
}
3333
}

public/.htaccess

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111

1212
# Redirect Trailing Slashes If Not A Folder...
1313
RewriteCond %{REQUEST_FILENAME} !-d
14-
RewriteRule ^(.*)/$ /$1 [L,R=301]
14+
RewriteCond %{REQUEST_URI} (.+)/$
15+
RewriteRule ^ %1 [L,R=301]
1516

16-
# Handle Front Controller...
17+
# Send Requests To Front Controller...
1718
RewriteCond %{REQUEST_FILENAME} !-d
1819
RewriteCond %{REQUEST_FILENAME} !-f
1920
RewriteRule ^ index.php [L]

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,6 @@ These are the great open-source projects used to help build BookStack:
168168
* [Snappy (WKHTML2PDF)](https://github.com/barryvdh/laravel-snappy)
169169
* [Laravel IDE helper](https://github.com/barryvdh/laravel-ide-helper)
170170
* [WKHTMLtoPDF](http://wkhtmltopdf.org/index.html)
171-
* [Draw.io](https://github.com/jgraph/drawio)
171+
* [diagrams.net](https://github.com/jgraph/drawio)
172172
* [Laravel Stats](https://github.com/stefanzweifel/laravel-stats)
173173
* [OneLogin's SAML PHP Toolkit](https://github.com/onelogin/php-saml)

resources/js/components/book-sort.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Sortable, MultiDrag} from "sortablejs";
1+
import Sortable from "sortablejs";
22

33
// Auto sort control
44
const sortOperations = {
@@ -43,7 +43,6 @@ class BookSort {
4343
this.input = elem.querySelector('[book-sort-input]');
4444

4545
const initialSortBox = elem.querySelector('.sort-box');
46-
Sortable.mount(new MultiDrag());
4746
this.setupBookSortable(initialSortBox);
4847
this.setupSortPresets();
4948

resources/js/services/http.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,14 @@ async function request(url, options = {}) {
141141
/**
142142
* Get the content from a fetch response.
143143
* Checks the content-type header to determine the format.
144-
* @param response
144+
* @param {Response} response
145145
* @returns {Promise<Object|String>}
146146
*/
147147
async function getResponseContent(response) {
148+
if (response.status === 204) {
149+
return null;
150+
}
151+
148152
const responseContentType = response.headers.get('Content-Type');
149153
const subType = responseContentType.split('/').pop();
150154

resources/views/attachments/manager-edit-form.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<div component="ajax-form"
22
option:ajax-form:url="/attachments/{{ $attachment->id }}"
33
option:ajax-form:method="put"
4+
option:ajax-form:response-container=".attachment-edit-container"
45
option:ajax-form:success-message="{{ trans('entities.attachments_updated_success') }}">
56
<h5>{{ trans('entities.attachments_edit_file') }}</h5>
67

resources/views/attachments/manager-link-form.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<div component="ajax-form"
55
option:ajax-form:url="/attachments/link"
66
option:ajax-form:method="post"
7+
option:ajax-form:response-container=".link-form-container"
78
option:ajax-form:success-message="{{ trans('entities.attachments_link_attached') }}">
89
<input type="hidden" name="attachment_link_uploaded_to" value="{{ $pageId }}">
910
<p class="text-muted small">{{ trans('entities.attachments_explain_link') }}</p>

0 commit comments

Comments
 (0)