datatracker/ietf/static/js/nav.js
Robert Sparks 9457e2b1e1
feat: better htmlization views (#4825)
* feat: Use bs5 for htmlized doc (#4082)

Co-authored-by: Martin Thomson <mt@lowentropy.net>

* fix: Various fixes to HTMLized document view (#4501)

* fix: Pref labels were switched

* fix: Fix ToC for htmlized docs

* Replace datatracker button with document name link to datatracker

* ui: Make fonts even larger on larger window widths

* fix: Document format buttons open new tabs

* fix: Various suggestions from Jay

* fix: Don't show "htmlized" self-link under formats

* ui: Font size fix for iOS

* ui: More little tweaks

* feat/htmlize fixes and improvements (#4506)

* fix: Don't open htmlized view in new tab

* fix: Tests were failing

* feat: Add pref settings to cap max font size

* feat: Add ability to hide side panel

* fix: And more `feat/htmlize` fixes (#4511)

* fix: Remove superfluous scrollbars

* fix: Show email links for authors

* fix: Only show "email authors" button for latest reversion

* fix: Remove duplicate code, fix nav scrolling

* feat: Add RFCs to revision lists

* feat: Add pref option to control dependency inlining

* fix: Add analytical tags

* feat: Notify user of rendering inconsistencies

* feat: Split out bootstrap-icons when not inlining dependencies

* fix: Revision list and minor other fixes

* feat: Show stream logo when possible (#4516)

* fix: Remove superfluous scrollbars

* fix: Show email links for authors

* fix: Only show "email authors" button for latest reversion

* fix: Remove duplicate code, fix nav scrolling

* feat: Add RFCs to revision lists

* feat: Add pref option to control dependency inlining

* fix: Add analytical tags

* feat: Notify user of rendering inconsistencies

* feat: Split out bootstrap-icons when not inlining dependencies

* fix: Revision list and minor other fixes

* feat: Show stream logos when possible

* fix: Pick up CSS changes from https://github.com/martinthomson/rfc-txt-html (#4520)

* fix: Remove superfluous scrollbars

* fix: Show email links for authors

* fix: Only show "email authors" button for latest reversion

* fix: Remove duplicate code, fix nav scrolling

* feat: Add RFCs to revision lists

* feat: Add pref option to control dependency inlining

* fix: Add analytical tags

* feat: Notify user of rendering inconsistencies

* feat: Split out bootstrap-icons when not inlining dependencies

* fix: Revision list and minor other fixes

* feat: Show stream logos when possible

* fix: Pick up CSS changes from https://github.com/martinthomson/rfc-txt-html

* chore: add debug script to replicate GitHub Actions test environment

* chore: cleanup from merge of main

* fix: Fix PDFixation crash due to referencing renamed CSS asset (#4665)

* fix: Rename some CSS classes to handle recent xml2rfc changes (#4791)

* Merge main

* fix: Rename some CSS classes to handle recent xml2rfc changes

Fixes #4784.

* chore: repair merge damage

* chore: more merge corrections

* chore: one more merge correction

* fix: npm dependencies

* fix: Change default font size (#4817)

* Fix dependency issues

* Cap fontsize at 12pt by default

Co-authored-by: Nicolas Giard <github@ngpixel.com>

Co-authored-by: Lars Eggert <lars@eggert.org>
Co-authored-by: Martin Thomson <mt@lowentropy.net>
Co-authored-by: Nicolas Giard <github@ngpixel.com>
2022-12-02 15:17:14 -06:00

101 lines
2.8 KiB
JavaScript

import debounce from "lodash/debounce";
function make_nav() {
const nav = document.createElement("nav");
nav.classList.add("nav-pills", "ps-3", "flex-column");
return nav;
}
function get_level(el) {
let h;
if (el.tagName.match(/^h\d/i)) {
h = el.tagName
} else {
el.classList.forEach(cl => {
if (cl.match(/^h\d/i)) {
h = cl;
return;
}
});
}
return h.charAt(h.length - 1);
}
export function populate_nav(nav, heading_selector, classes) {
// Extract section headings from document
const headings = document.querySelectorAll(heading_selector);
const min_level = Math.min(...Array.from(headings)
.map(get_level));
let nav_stack = [nav];
let cur_level = 0;
let n = 0;
headings.forEach(el => {
const level = get_level(el) - min_level;
if (level < cur_level) {
while (level < cur_level) {
let nav = nav_stack.pop();
cur_level--;
nav_stack[level].appendChild(nav);
}
} else {
while (level > cur_level) {
nav_stack.push(make_nav());
cur_level++;
}
}
const link = document.createElement("a");
link.classList.add("nav-link", "ps-1", "d-flex", "hyphenate",
classes);
if (!el.id) {
el.id = `autoid-${++n}`;
}
link.href = `#${el.id}`;
const words = el.innerText.split(/\s+/);
let nr = "";
if (words[0].includes(".")) {
nr = words.shift();
} else if (words.length > 1 && words[1].includes(".")) {
nr = words.shift() + " " + words.shift();
nr = nr.replace(/\s*Appendix\s*/, "");
}
if (nr) {
const number = document.createElement("div");
number.classList.add("pe-1");
number.textContent = nr;
link.appendChild(number);
}
const text = document.createElement("div");
text.classList.add("text-break");
text.textContent = words.join(" ");
link.appendChild(text);
nav_stack[level].appendChild(link);
});
for (var i = nav_stack.length - 1; i > 0; i--) {
nav_stack[i - 1].appendChild(nav_stack[i]);
}
// Chrome apparently wants this debounced to something >10ms,
// otherwise the main view doesn't scroll?
document.addEventListener("scroll", debounce(function () {
const items = nav.querySelectorAll(".active");
const item = [...items].pop();
console.log(item);
if (item) {
item.scrollIntoView({
block: "center",
behavior: "smooth"
});
}
}, 100));
}