Dan Brown

Made page anchor hashes more relevant to the page content

This will help when adding support for new kinds of page content such as markdown as we won't be able to reference the same ID's as before thus they would break on every save.
...@@ -132,14 +132,13 @@ class PageRepo ...@@ -132,14 +132,13 @@ class PageRepo
132 $childNodes = $body->childNodes; 132 $childNodes = $body->childNodes;
133 133
134 // Ensure no duplicate ids are used 134 // Ensure no duplicate ids are used
135 - $lastId = false;
136 $idArray = []; 135 $idArray = [];
137 136
138 foreach ($childNodes as $index => $childNode) { 137 foreach ($childNodes as $index => $childNode) {
139 /** @var \DOMElement $childNode */ 138 /** @var \DOMElement $childNode */
140 if (get_class($childNode) !== 'DOMElement') continue; 139 if (get_class($childNode) !== 'DOMElement') continue;
141 140
142 - // Overwrite id if not a bookstack custom id 141 + // Overwrite id if not a BookStack custom id
143 if ($childNode->hasAttribute('id')) { 142 if ($childNode->hasAttribute('id')) {
144 $id = $childNode->getAttribute('id'); 143 $id = $childNode->getAttribute('id');
145 if (strpos($id, 'bkmrk') === 0 && array_search($id, $idArray) === false) { 144 if (strpos($id, 'bkmrk') === 0 && array_search($id, $idArray) === false) {
...@@ -149,13 +148,18 @@ class PageRepo ...@@ -149,13 +148,18 @@ class PageRepo
149 } 148 }
150 149
151 // Create an unique id for the element 150 // Create an unique id for the element
152 - do { 151 + // Uses the content as a basis to ensure output is the same every time
153 - $id = 'bkmrk-' . substr(uniqid(), -5); 152 + // the same content is passed through.
154 - } while ($id == $lastId); 153 + $contentId = 'bkmrk-' . substr(strtolower(preg_replace('/\s+/', '-', trim($childNode->nodeValue))), 0, 20);
155 - $lastId = $id; 154 + $newId = urlencode($contentId);
155 + $loopIndex = 0;
156 + while (in_array($newId, $idArray)) {
157 + $newId = urlencode($contentId . '-' . $loopIndex);
158 + $loopIndex++;
159 + }
156 160
157 - $childNode->setAttribute('id', $id); 161 + $childNode->setAttribute('id', $newId);
158 - $idArray[] = $id; 162 + $idArray[] = $newId;
159 } 163 }
160 164
161 // Generate inner html as a string 165 // Generate inner html as a string
......