diff --git a/crates/mdbook-html/front-end/css/chrome.css b/crates/mdbook-html/front-end/css/chrome.css
index c9ed00c2b7..45bbd5ed12 100644
--- a/crates/mdbook-html/front-end/css/chrome.css
+++ b/crates/mdbook-html/front-end/css/chrome.css
@@ -571,17 +571,18 @@ html:not(.sidebar-resizing) .sidebar {
line-height: 2.2em;
}
-.chapter ol {
- width: 100%;
+.chapter li {
+ color: var(--sidebar-non-existant);
}
-.chapter li {
+/* This is a span wrapping the chapter link and the fold chevron. */
+.chapter-link-wrapper {
+ /* Used to position the chevron to the right, allowing the text to wrap before it. */
display: flex;
- color: var(--sidebar-non-existant);
}
+
.chapter li a {
- display: block;
- padding: 0;
+ /* Remove underlines. */
text-decoration: none;
color: var(--sidebar-fg);
}
@@ -594,21 +595,22 @@ html:not(.sidebar-resizing) .sidebar {
color: var(--sidebar-active);
}
-.chapter li > a.toggle {
+/* This is the toggle chevron. */
+.chapter-fold-toggle {
cursor: pointer;
- display: block;
+ /* Positions the chevron to the side. */
margin-inline-start: auto;
padding: 0 10px;
user-select: none;
opacity: 0.68;
}
-.chapter li > a.toggle div {
+.chapter-fold-toggle div {
transition: transform 0.5s;
}
/* collapse the section */
-.chapter li:not(.expanded) + li > ol {
+.chapter li:not(.expanded) > ol {
display: none;
}
@@ -617,10 +619,12 @@ html:not(.sidebar-resizing) .sidebar {
margin-block-start: 0.6em;
}
-.chapter li.expanded > a.toggle div {
+/* When expanded, rotate the chevron to point down. */
+.chapter li.expanded > span > .chapter-fold-toggle div {
transform: rotate(90deg);
}
+/* Horizontal line in chapter list. */
.spacer {
width: 100%;
height: 3px;
@@ -630,6 +634,7 @@ html:not(.sidebar-resizing) .sidebar {
background-color: var(--sidebar-spacer);
}
+/* On touch devices, add more vertical spacing to make it easier to tap links. */
@media (-moz-touch-enabled: 1), (pointer: coarse) {
.chapter li a { padding: 5px 0; }
.spacer { margin: 10px 0; }
@@ -741,7 +746,6 @@ html:not(.sidebar-resizing) .sidebar {
content: '';
position: absolute;
left: -16px;
- top: 0;
margin-top: 10px;
width: 8px;
height: 8px;
diff --git a/crates/mdbook-html/front-end/templates/toc.js.hbs b/crates/mdbook-html/front-end/templates/toc.js.hbs
index 9d26f3daa8..48af642b0a 100644
--- a/crates/mdbook-html/front-end/templates/toc.js.hbs
+++ b/crates/mdbook-html/front-end/templates/toc.js.hbs
@@ -29,14 +29,9 @@ class MDBookSidebarScrollbox extends HTMLElement {
&& current_page.endsWith('/index.html')) {
link.classList.add('active');
let parent = link.parentElement;
- if (parent && parent.classList.contains('chapter-item')) {
- parent.classList.add('expanded');
- }
while (parent) {
- if (parent.tagName === 'LI' && parent.previousElementSibling) {
- if (parent.previousElementSibling.classList.contains('chapter-item')) {
- parent.previousElementSibling.classList.add('expanded');
- }
+ if (parent.tagName === 'LI' && parent.classList.contains('chapter-item')) {
+ parent.classList.add('expanded');
}
parent = parent.parentElement;
}
@@ -62,9 +57,9 @@ class MDBookSidebarScrollbox extends HTMLElement {
}
}
// Toggle buttons
- const sidebarAnchorToggles = document.querySelectorAll('#mdbook-sidebar a.toggle');
+ const sidebarAnchorToggles = document.querySelectorAll('.chapter-fold-toggle');
function toggleSection(ev) {
- ev.currentTarget.parentElement.classList.toggle('expanded');
+ ev.currentTarget.parentElement.parentElement.classList.toggle('expanded');
}
Array.from(sidebarAnchorToggles).forEach(el => {
el.addEventListener('click', toggleSection);
@@ -237,17 +232,12 @@ window.customElements.define('mdbook-sidebar-scrollbox', MDBookSidebarScrollbox)
// be expanded.
function updateHeaderExpanded(currentA) {
// Add expanded to all header-item li ancestors.
- let current = currentA.parentElement.parentElement.parentElement;
- while (current.tagName === 'LI') {
- const prevSibling = current.previousElementSibling;
- if (prevSibling !== null
- && prevSibling.tagName === 'LI'
- && prevSibling.classList.contains('header-item')) {
- prevSibling.classList.add('expanded');
- current = prevSibling.parentElement.parentElement;
- } else {
- break;
+ let current = currentA.parentElement;
+ while (current) {
+ if (current.tagName === 'LI' && current.classList.contains('header-item')) {
+ current.classList.add('expanded');
}
+ current = current.parentElement;
}
}
@@ -343,19 +333,6 @@ window.customElements.define('mdbook-sidebar-scrollbox', MDBookSidebarScrollbox)
if (activeSection === null) {
return;
}
- const activeItem = activeSection.parentElement;
- const activeList = activeItem.parentElement;
-
- // Build a tree of headers in the sidebar.
- const rootLi = document.createElement('li');
- rootLi.classList.add('header-item');
- rootLi.classList.add('expanded');
- const rootOl = document.createElement('ol');
- rootOl.classList.add('section');
- rootLi.appendChild(rootOl);
- const stack = [{ level: 0, ol: rootOl }];
- // The level where it will start folding deeply nested headers.
- const foldLevel = 3;
const main = document.getElementsByTagName('main')[0];
headers = Array.from(main.querySelectorAll('h2, h3, h4, h5, h6'))
@@ -365,57 +342,90 @@ window.customElements.define('mdbook-sidebar-scrollbox', MDBookSidebarScrollbox)
return;
}
+ // Build a tree of headers in the sidebar.
+
+ const stack = [];
+
+ const firstLevel = parseInt(headers[0].tagName.charAt(1));
+ for (let i = 1; i < firstLevel; i++) {
+ const ol = document.createElement('ol');
+ ol.classList.add('section');
+ if (stack.length > 0) {
+ stack[stack.length - 1].ol.appendChild(ol);
+ }
+ stack.push({level: i + 1, ol: ol});
+ }
+
+ // The level where it will start folding deeply nested headers.
+ const foldLevel = 3;
+
for (let i = 0; i < headers.length; i++) {
const header = headers[i];
const level = parseInt(header.tagName.charAt(1));
+
+ const currentLevel = stack[stack.length - 1].level;
+ if (level > currentLevel) {
+ // Begin nesting to this level.
+ for (let nextLevel = currentLevel + 1; nextLevel <= level; nextLevel++) {
+ const ol = document.createElement('ol');
+ ol.classList.add('section');
+ const last = stack[stack.length - 1];
+ const lastChild = last.ol.lastChild;
+ // Handle the case where jumping more than one nesting
+ // level, which doesn't have a list item to place this new
+ // list inside of.
+ if (lastChild) {
+ lastChild.appendChild(ol);
+ } else {
+ last.ol.appendChild(ol);
+ }
+ stack.push({level: nextLevel, ol: ol});
+ }
+ } else if (level < currentLevel) {
+ while (stack.length > 1 && stack[stack.length - 1].level >= level) {
+ stack.pop();
+ }
+ }
+
const li = document.createElement('li');
li.classList.add('header-item');
li.classList.add('expanded');
if (level < foldLevel) {
li.classList.add('expanded');
}
+ const span = document.createElement('span');
+ span.classList.add('chapter-link-wrapper');
const a = document.createElement('a');
+ span.appendChild(a);
a.href = '#' + header.id;
a.classList.add('header-in-summary');
a.innerHTML = header.children[0].innerHTML;
a.addEventListener('click', headerThresholdClick);
- li.appendChild(a);
const nextHeader = headers[i + 1];
if (nextHeader !== undefined) {
const nextLevel = parseInt(nextHeader.tagName.charAt(1));
if (nextLevel > level && level >= foldLevel) {
- const div = document.createElement('div');
- div.textContent = '❱';
const toggle = document.createElement('a');
- toggle.classList.add('toggle');
+ toggle.classList.add('chapter-fold-toggle');
toggle.classList.add('header-toggle');
- toggle.appendChild(div);
toggle.addEventListener('click', () => {
li.classList.toggle('expanded');
});
- li.appendChild(toggle);
+ const toggleDiv = document.createElement('div');
+ toggleDiv.textContent = '❱';
+ toggle.appendChild(toggleDiv);
+ span.appendChild(toggle);
headerToggles.push(li);
}
}
-
- // Find the appropriate parent level.
- while (stack.length > 1 && stack[stack.length - 1].level >= level) {
- stack.pop();
- }
+ li.appendChild(span);
const currentParent = stack[stack.length - 1];
currentParent.ol.appendChild(li);
-
- // Create new nested ol for potential children.
- const nestedOl = document.createElement('ol');
- nestedOl.classList.add('section');
- const nestedLi = document.createElement('li');
- nestedLi.appendChild(nestedOl);
- currentParent.ol.appendChild(nestedLi);
- stack.push({ level: level, ol: nestedOl });
}
- activeList.insertBefore(rootLi, activeItem.nextSibling);
+ const activeItemSpan = activeSection.parentElement;
+ activeItemSpan.after(stack[0].ol);
});
document.addEventListener('DOMContentLoaded', reloadCurrentHeader);
diff --git a/crates/mdbook-html/src/html_handlebars/helpers/toc.rs b/crates/mdbook-html/src/html_handlebars/helpers/toc.rs
index 36972d24c6..baee73f6d3 100644
--- a/crates/mdbook-html/src/html_handlebars/helpers/toc.rs
+++ b/crates/mdbook-html/src/html_handlebars/helpers/toc.rs
@@ -57,13 +57,13 @@ impl HelperDef for RenderToc {
out.write("
")?;
let mut current_level = 1;
+ let mut first = true;
for item in chapters {
- let (_section, level) = if let Some(s) = item.get("section") {
- (s.as_str(), s.matches('.').count())
- } else {
- ("", 1)
- };
+ let level = item
+ .get("section")
+ .map(|s| s.matches('.').count())
+ .unwrap_or(1);
// Expand if folding is disabled, or if levels that are larger than this would not
// be folded.
@@ -71,25 +71,31 @@ impl HelperDef for RenderToc {
match level.cmp(¤t_level) {
Ordering::Greater => {
- while level > current_level {
- out.write("- ")?;
- out.write("
")?;
- current_level += 1;
- }
- write_li_open_tag(out, is_expanded, false)?;
+ // There is an assumption that when descending, it can
+ // only go one level down at a time. This should be
+ // enforced by the nature of markdown lists and the
+ // summary parser.
+ assert_eq!(level, current_level + 1);
+ current_level += 1;
+ out.write("")?;
+ write_li_open_tag(out, is_expanded)?;
}
Ordering::Less => {
while level < current_level {
- out.write("
")?;
out.write("
")?;
+ out.write("
")?;
current_level -= 1;
}
- write_li_open_tag(out, is_expanded, false)?;
+ write_li_open_tag(out, is_expanded)?;
}
Ordering::Equal => {
- write_li_open_tag(out, is_expanded, !item.contains_key("section"))?;
+ if !first {
+ out.write("")?;
+ }
+ write_li_open_tag(out, is_expanded)?;
}
}
+ first = false;
// Spacer
if item.contains_key("spacer") {
@@ -105,6 +111,8 @@ impl HelperDef for RenderToc {
continue;
}
+ out.write("")?;
+
// Link
let path_exists = match item.get("path") {
Some(path) if !path.is_empty() => {
@@ -121,7 +129,7 @@ impl HelperDef for RenderToc {
true
}
_ => {
- out.write("")?;
+ out.write("")?;
false
}
};
@@ -142,41 +150,35 @@ impl HelperDef for RenderToc {
if path_exists {
out.write("")?;
} else {
- out.write("
")?;
+ out.write("")?;
}
// Render expand/collapse toggle
if let Some(flag) = item.get("has_sub_items") {
let has_sub_items = flag.parse::().unwrap_or_default();
if fold_enable && has_sub_items {
- out.write("❱
")?;
+ // The here is to manage rotating the element when
+ // the chapter title is long and word-wraps.
+ out.write("
❱
")?;
}
}
- out.write("")?;
+ out.write("")?;
}
- while current_level > 1 {
- out.write("")?;
+ while current_level > 0 {
out.write("")?;
+ out.write("")?;
current_level -= 1;
}
- out.write("")?;
Ok(())
}
}
-fn write_li_open_tag(
- out: &mut dyn Output,
- is_expanded: bool,
- is_affix: bool,
-) -> Result<(), std::io::Error> {
+fn write_li_open_tag(out: &mut dyn Output, is_expanded: bool) -> Result<(), std::io::Error> {
let mut li = String::from("
");
out.write(&li)
}
diff --git a/tests/gui/books/heading-nav-folded/book.toml b/tests/gui/books/heading-nav-folded/book.toml
new file mode 100644
index 0000000000..7dcb38f8f4
--- /dev/null
+++ b/tests/gui/books/heading-nav-folded/book.toml
@@ -0,0 +1,6 @@
+[book]
+title = "heading-nav-folded"
+
+[output.html.fold]
+enable = true
+level = 0
diff --git a/tests/gui/books/heading-nav-folded/src/SUMMARY.md b/tests/gui/books/heading-nav-folded/src/SUMMARY.md
new file mode 100644
index 0000000000..db2f44a2cd
--- /dev/null
+++ b/tests/gui/books/heading-nav-folded/src/SUMMARY.md
@@ -0,0 +1,7 @@
+# Summary
+
+- [Introduction](./intro.md)
+ - [Sub chapter](./sub/index.md)
+ - [Sub inner](./sub/inner/index.md)
+ - [Sub second chapter](./sub/second.md)
+- [Next main chapter](./next-main.md)
diff --git a/tests/gui/books/heading-nav-folded/src/intro.md b/tests/gui/books/heading-nav-folded/src/intro.md
new file mode 100644
index 0000000000..8067174f5c
--- /dev/null
+++ b/tests/gui/books/heading-nav-folded/src/intro.md
@@ -0,0 +1,9 @@
+# Introduction
+
+## Heading A
+
+### Heading A2
+
+### Heading A3
+
+## Heading B
diff --git a/tests/gui/books/heading-nav-folded/src/next-main.md b/tests/gui/books/heading-nav-folded/src/next-main.md
new file mode 100644
index 0000000000..7d8c4947af
--- /dev/null
+++ b/tests/gui/books/heading-nav-folded/src/next-main.md
@@ -0,0 +1 @@
+# Next main chapter
diff --git a/tests/gui/books/heading-nav-folded/src/sub/index.md b/tests/gui/books/heading-nav-folded/src/sub/index.md
new file mode 100644
index 0000000000..e4a4b82698
--- /dev/null
+++ b/tests/gui/books/heading-nav-folded/src/sub/index.md
@@ -0,0 +1,3 @@
+# Sub chapter
+
+## Sub-chapter heading
diff --git a/tests/gui/books/heading-nav-folded/src/sub/inner/index.md b/tests/gui/books/heading-nav-folded/src/sub/inner/index.md
new file mode 100644
index 0000000000..3c84e7122f
--- /dev/null
+++ b/tests/gui/books/heading-nav-folded/src/sub/inner/index.md
@@ -0,0 +1,3 @@
+# Sub inner
+
+## Inner chapter heading
diff --git a/tests/gui/books/heading-nav-folded/src/sub/second.md b/tests/gui/books/heading-nav-folded/src/sub/second.md
new file mode 100644
index 0000000000..49c6adb462
--- /dev/null
+++ b/tests/gui/books/heading-nav-folded/src/sub/second.md
@@ -0,0 +1,3 @@
+# Sub second chapter
+
+## Second chapter heading
diff --git a/tests/gui/books/heading-nav/src/SUMMARY.md b/tests/gui/books/heading-nav/src/SUMMARY.md
index a7f68ee013..bf84824b70 100644
--- a/tests/gui/books/heading-nav/src/SUMMARY.md
+++ b/tests/gui/books/heading-nav/src/SUMMARY.md
@@ -6,3 +6,4 @@
- [Collapsed headings](collapsed.md)
- [Headings with markup](markup.md)
- [Current scrolls to bottom](current-to-bottom.md)
+- [Unusual heading levels](unusual-heading-levels.md)
diff --git a/tests/gui/books/heading-nav/src/unusual-heading-levels.md b/tests/gui/books/heading-nav/src/unusual-heading-levels.md
new file mode 100644
index 0000000000..8fc65a2118
--- /dev/null
+++ b/tests/gui/books/heading-nav/src/unusual-heading-levels.md
@@ -0,0 +1,9 @@
+# Unusual heading levels
+
+### Heading 3
+
+## Heading 2
+
+#### Heading 5
+
+#### Heading 5.1
diff --git a/tests/gui/heading-nav-collapsed.goml b/tests/gui/heading-nav-collapsed.goml
index 0985bfb609..003d7e68fc 100644
--- a/tests/gui/heading-nav-collapsed.goml
+++ b/tests/gui/heading-nav-collapsed.goml
@@ -3,49 +3,54 @@
set-window-size: (1400, 800)
go-to: |DOC_PATH| + "heading-nav/collapsed.html"
-assert-count: (".header-item", 12)
+assert-count: (".header-item", 11)
assert-count: (".current-header", 1)
assert-text: (".current-header", "Heading 1")
// Collapsed elements do not have "expanded" class.
-assert-attribute: ("li:has(> a[href='#heading-12'])", {"class": "header-item"})
-assert-attribute: ("li:has(> a[href='#heading-21'])", {"class": "header-item"})
+assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"})
+assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"})
-// Click 1.2, doesn't change expanded.
+// Click 1.2, expands it.
click: "a.header-in-summary[href='#heading-12']"
-assert-attribute: ("li:has(> a[href='#heading-12'])", {"class": "header-item"})
-assert-attribute: ("li:has(> a[href='#heading-21'])", {"class": "header-item"})
-assert-css: ("//li[preceding-sibling::li[1][a[@href='#heading-12']]]/ol", {"display": "none"})
-// Click expand chevron.
-// 1.2.1 and 1.2.2 should be visible
+assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item expanded"})
+assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"})
+assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "block"})
+
+// Click 1.1, should collapse it.
+click: "a.header-in-summary[href='#heading-11']"
+assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"})
+assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"})
+assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"})
+
+// Click the chevron, should expand it.
click: "a.header-in-summary[href='#heading-12'] ~ a.header-toggle"
-assert-attribute: ("li:has(> a[href='#heading-12'])", {"class": "header-item expanded"})
-assert-attribute: ("li:has(> a[href='#heading-21'])", {"class": "header-item"})
-assert-css: ("//li[preceding-sibling::li[1][a[@href='#heading-12']]]/ol", {"display": "block"})
+assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item expanded"})
+assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"})
+assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "block"})
// Click 1.3
click: "a.header-in-summary[href='#heading-13']"
// Everything should be collapsed
-assert-attribute: ("li:has(> a[href='#heading-12'])", {"class": "header-item"})
-assert-attribute: ("li:has(> a[href='#heading-21'])", {"class": "header-item"})
-assert-css: ("//li[preceding-sibling::li[1][a[@href='#heading-12']]]/ol", {"display": "none"})
-assert-css: ("//li[preceding-sibling::li[1][a[@href='#heading-21']]]/ol", {"display": "none"})
-
+assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"})
+assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"})
+assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"})
+assert-css: ("//a[@href='#heading-21']/../following-sibling::ol", {"display": "none"})
+assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"})
+assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"})
+assert-attribute: ("li:has(> span > a[href='#heading-211'])", {"class": "header-item"})
+assert-attribute: ("li:has(> span > a[href='#heading-2111'])", {"class": "header-item"})
-assert-attribute: ("li:has(> a[href='#heading-12'])", {"class": "header-item"})
-assert-attribute: ("li:has(> a[href='#heading-21'])", {"class": "header-item"})
-assert-attribute: ("li:has(> a[href='#heading-211'])", {"class": "header-item"})
-assert-attribute: ("li:has(> a[href='#heading-2111'])", {"class": "header-item"})
// Scroll to bottom of page
press-key: 'PageDown'
press-key: 'PageDown'
press-key: 'PageDown'
press-key: 'PageDown'
// 2.1.1.1.1 should be visible, and all the chevrons should be open, and expanded should be on each one
-assert-attribute: ("li:has(> a[href='#heading-12'])", {"class": "header-item"})
-assert-attribute: ("li:has(> a[href='#heading-21'])", {"class": "header-item expanded"})
-assert-attribute: ("li:has(> a[href='#heading-211'])", {"class": "header-item expanded"})
-assert-attribute: ("li:has(> a[href='#heading-2111'])", {"class": "header-item expanded"})
-assert-css: ("//li[preceding-sibling::li[1][a[@href='#heading-12']]]/ol", {"display": "none"})
-assert-css: ("//li[preceding-sibling::li[1][a[@href='#heading-21']]]/ol", {"display": "block"})
-assert-css: ("//li[preceding-sibling::li[1][a[@href='#heading-211']]]/ol", {"display": "block"})
-assert-css: ("//li[preceding-sibling::li[1][a[@href='#heading-2111']]]/ol", {"display": "block"})
+assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"})
+assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item expanded"})
+assert-attribute: ("li:has(> span > a[href='#heading-211'])", {"class": "header-item expanded"})
+assert-attribute: ("li:has(> span > a[href='#heading-2111'])", {"class": "header-item expanded"})
+assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"})
+assert-css: ("//a[@href='#heading-21']/../following-sibling::ol", {"display": "block"})
+assert-css: ("//a[@href='#heading-211']/../following-sibling::ol", {"display": "block"})
+assert-css: ("//a[@href='#heading-2111']/../following-sibling::ol", {"display": "block"})
diff --git a/tests/gui/heading-nav-folded.goml b/tests/gui/heading-nav-folded.goml
new file mode 100644
index 0000000000..eeb3aa27ca
--- /dev/null
+++ b/tests/gui/heading-nav-folded.goml
@@ -0,0 +1,3 @@
+// Tests when chapter folding is enabled.
+
+go-to: |DOC_PATH| + "heading-nav-folded/index.html"
diff --git a/tests/gui/heading-nav-large-intro.goml b/tests/gui/heading-nav-large-intro.goml
index cb93c6175f..916e5700d9 100644
--- a/tests/gui/heading-nav-large-intro.goml
+++ b/tests/gui/heading-nav-large-intro.goml
@@ -3,7 +3,7 @@
set-window-size: (1400, 800)
go-to: |DOC_PATH| + "heading-nav/large-intro.html"
-assert-count: (".header-item", 2)
+assert-count: (".header-item", 1)
assert-count: (".current-header", 0)
scroll-to: "#first-header"
diff --git a/tests/gui/heading-nav-markup.goml b/tests/gui/heading-nav-markup.goml
index c37d98d946..6da8f936aa 100644
--- a/tests/gui/heading-nav-markup.goml
+++ b/tests/gui/heading-nav-markup.goml
@@ -3,7 +3,7 @@
set-window-size: (1400, 800)
go-to: |DOC_PATH| + "heading-nav/markup.html"
-assert-count: (".header-item", 5)
+assert-count: (".header-item", 4)
assert-count: (".current-header", 1)
assert-text: (".current-header", "Heading with code or italic or bold or strike")
assert-property: (".current-header", {"innerHTML": "Heading with code or italic or bold or strike"})
diff --git a/tests/gui/heading-nav-normal-intro.goml b/tests/gui/heading-nav-normal-intro.goml
index 4a50c99df1..8ef542dc88 100644
--- a/tests/gui/heading-nav-normal-intro.goml
+++ b/tests/gui/heading-nav-normal-intro.goml
@@ -3,7 +3,7 @@
set-window-size: (1400, 800)
go-to: |DOC_PATH| + "heading-nav/normal-intro.html"
-assert-count: (".header-item", 4)
+assert-count: (".header-item", 3)
assert-count: (".current-header", 1)
assert-text: (".current-header", "The first heading")
diff --git a/tests/gui/heading-nav-unusual-levels.goml b/tests/gui/heading-nav-unusual-levels.goml
new file mode 100644
index 0000000000..db58f3e563
--- /dev/null
+++ b/tests/gui/heading-nav-unusual-levels.goml
@@ -0,0 +1,7 @@
+// Tests for unusual heading levels
+
+set-window-size: (1400, 800)
+go-to: |DOC_PATH| + "heading-nav/unusual-heading-levels.html"
+
+assert-property: ("//a[@href='unusual-heading-levels.html']/../following-sibling::ol", {"innerHTML": '
'})
+
diff --git a/tests/testsuite/index.rs b/tests/testsuite/index.rs
index 0555cc6308..c6c9c762a7 100644
--- a/tests/testsuite/index.rs
+++ b/tests/testsuite/index.rs
@@ -20,16 +20,22 @@ fn readme_to_index() {
)
.check_toc_js(str![[r#"
--
+
-
+
Intro
+
-
+
1. First
+
-
+
2. Second
+
"#]]);
diff --git a/tests/testsuite/toc.rs b/tests/testsuite/toc.rs
index b7e5629b40..40bb0001e2 100644
--- a/tests/testsuite/toc.rs
+++ b/tests/testsuite/toc.rs
@@ -148,16 +148,22 @@ fn summary_with_markdown_formatting() {
.check_toc_js(str![[r#"
-
+
1. Italic code *escape* `escape2`
+
-
+
2. Soft line break
+
-
+
3. <escaped tag>
+
"#]])