Skip to content

Commit bb89096

Browse files
authored
Add exdoc:loaded event (#2069)
1 parent 6145d95 commit bb89096

File tree

13 files changed

+50
-37
lines changed

13 files changed

+50
-37
lines changed

README.md

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ docs: [
370370
]
371371
```
372372

373+
On the JavaScript side, ExDoc emits the `"exdoc:loaded"` event. This event may be called multiple times, as you navigate across pages, so initialization that should happen only once must be conditional. We recommend external scripts to use `defer`, not `async`, as shown in the examples below.
374+
373375
### Rendering Math
374376

375377
If you write TeX-style math in your Markdown, such as `$\sum_{i}^{N} x_i$`, it ends up as raw text on the generated pages. To render expressions, we recommend using [KaTeX](https://katex.org/), a JavaScript library that turns expressions into graphics. To load and trigger KaTeX on every documentation page, we can insert the following HTML:
@@ -381,13 +383,17 @@ If you write TeX-style math in your Markdown, such as `$\sum_{i}^{N} x_i$`, it e
381383
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex-copytex.min.css" rel="stylesheet" type="text/css">
382384
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex-copytex.min.js" crossorigin="anonymous"></script>
383385

384-
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"
385-
onload="renderMathInElement(document.body, {
386-
delimiters: [
387-
{left: '$$', right: '$$', display: true},
388-
{left: '$', right: '$', display: false},
389-
]
390-
});"></script>
386+
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script>
387+
388+
<script>
389+
window.addEventListener("exdoc:loaded", () => {
390+
renderMathInElement(document.body, {
391+
delimiters: [
392+
{left: '$$', right: '$$', display: true},
393+
{left: '$', right: '$', display: false},
394+
]
395+
})
396+
})
391397
</script>
392398
```
393399

@@ -402,7 +408,7 @@ Snippets are also objects you may want to render in a special manner. For exampl
402408
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
403409
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
404410
<script>
405-
document.addEventListener("DOMContentLoaded", function () {
411+
window.addEventListener("exdoc:loaded", () => {
406412
for (const codeEl of document.querySelectorAll("pre code.vega-lite")) {
407413
try {
408414
const preEl = codeEl.parentElement;
@@ -426,12 +432,19 @@ For more details and configuration options, see [vega/vega-embed](https://github
426432
Similarly to the example above, if your Markdown includes Mermaid graph specification in `mermaid` code snippets:
427433

428434
```html
435+
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/mermaid.min.js"></script>
429436
<script>
430-
function mermaidLoaded() {
431-
mermaid.initialize({
432-
startOnLoad: false,
433-
theme: document.body.className.includes("dark") ? "dark" : "default"
434-
});
437+
let initialized = false;
438+
439+
window.addEventListener("exdoc:loaded", () => {
440+
if (!initialized) {
441+
mermaid.initialize({
442+
startOnLoad: false,
443+
theme: document.body.className.includes("dark") ? "dark" : "default"
444+
});
445+
initialized = true;
446+
}
447+
435448
let id = 0;
436449
for (const codeEl of document.querySelectorAll("pre code.mermaid")) {
437450
const preEl = codeEl.parentElement;
@@ -445,9 +458,8 @@ Similarly to the example above, if your Markdown includes Mermaid graph specific
445458
preEl.remove();
446459
});
447460
}
448-
}
461+
});
449462
</script>
450-
<script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/mermaid.min.js" onload="mermaidLoaded();"></script>
451463
```
452464
453465
For more details and configuration options, see the [Mermaid usage docs](https://mermaid-js.github.io/mermaid/#/usage).

assets/js/content.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import { settingsStore } from './settings-store'
66
* corresponding to the current documentation page.
77
*/
88

9-
window.addEventListener('swup:page:view', initialize)
10-
initialize()
9+
window.addEventListener('exdoc:loaded', initialize)
1110

1211
function initialize () {
1312
const notebookPath = window.location.pathname.replace(/(\.html)?$/, '.livemd')

assets/js/copy-button.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ let buttonTemplate
88
* Initializes copy buttons.
99
*/
1010

11-
window.addEventListener('swup:page:view', initialize)
12-
initialize()
11+
window.addEventListener('exdoc:loaded', initialize)
1312

1413
function initialize () {
1514
if (!('clipboard' in navigator)) return

assets/js/makeup.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ const HIGHLIGHT_CLASS = 'hll'
66
* Sets up dynamic behaviour for code blocks processed with *makeup*.
77
*/
88

9-
window.addEventListener('swup:page:view', initialize)
10-
initialize()
9+
window.addEventListener('exdoc:loaded', initialize)
1110

1211
export function initialize () {
1312
// Hovering over a delimiter (bracket, parenthesis, do/end)

assets/js/quick-switch.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ const state = {
7474
*/
7575

7676
if (!isEmbedded) {
77-
window.addEventListener('swup:page:view', initialize)
78-
initialize()
77+
window.addEventListener('exdoc:loaded', initialize)
7978
}
8079

8180
function initialize () {

assets/js/search-bar.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ const SEARCH_CLOSE_BUTTON_SELECTOR = 'form.search-bar .search-close-button'
2121
*/
2222

2323
if (!isEmbedded) {
24-
window.addEventListener('swup:page:view', initialize)
25-
initialize()
24+
window.addEventListener('exdoc:loaded', initialize)
2625
}
2726

2827
function initialize () {

assets/js/search-page.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ lunr.Pipeline.registerFunction(docTrimmerFunction, 'docTrimmer')
2020
* Activates only on the `/search.html` page.
2121
*/
2222

23-
window.addEventListener('swup:page:view', initialize)
24-
initialize()
23+
window.addEventListener('exdoc:loaded', initialize)
2524

2625
function initialize () {
2726
const pathname = window.location.pathname

assets/js/settings.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ const modalTabs = [
2626
* Sets up the settings modal.
2727
*/
2828

29-
window.addEventListener('swup:page:view', initialize)
30-
initialize()
29+
window.addEventListener('exdoc:loaded', initialize)
3130

3231
function initialize () {
3332
qsAll(SETTINGS_LINK_SELECTOR).forEach(element => {

assets/js/sidebar/sidebar-drawer.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ const SIDEBAR_TOGGLE_SELECTOR = '.sidebar-toggle'
1111
const smallScreenQuery = window.matchMedia(`screen and (max-width: ${SMALL_SCREEN_BREAKPOINT}px)`)
1212

1313
if (!isEmbedded) {
14-
setDefaultSidebarState()
15-
16-
window.addEventListener('swup:page:view', setDefaultSidebarState)
14+
window.addEventListener('exdoc:loaded', setDefaultSidebarState)
1715

1816
const sidebar = document.getElementById('sidebar')
1917
const sidebarToggle = qs(SIDEBAR_TOGGLE_SELECTOR)
@@ -49,6 +47,7 @@ if (!isEmbedded) {
4947
sessionStorage.setItem(SIDEBAR_WIDTH_KEY, width)
5048
document.body.style.setProperty('--sidebarWidth', `${width}px`)
5149
})
50+
5251
// We observe on mousedown because we only care about user resize.
5352
sidebar.addEventListener('mousedown', () => resizeObserver.observe(sidebar))
5453
sidebar.addEventListener('mouseup', () => resizeObserver.unobserve(sidebar))

assets/js/sidebar/sidebar-list.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,12 @@ export function initialize () {
8989
})
9090

9191
window.addEventListener('hashchange', markCurrentHashInSidebar)
92-
window.addEventListener('swup:page:view', markCurrentHashInSidebar)
9392

93+
// We listen to swup:page:view event because we need to trigger
94+
// markCurrentHashInSidebar() before scollNodeListToCurrentCategory.
95+
window.addEventListener('swup:page:view', markCurrentHashInSidebar)
9496
markCurrentHashInSidebar()
97+
9598
// Triggers layout, defer.
9699
requestAnimationFrame(scrollNodeListToCurrentCategory)
97100
}

0 commit comments

Comments
 (0)