Skip to content

Commit f9c1389

Browse files
committed
Refactor and fix
1 parent 6dce031 commit f9c1389

File tree

4 files changed

+106
-88
lines changed

4 files changed

+106
-88
lines changed

Diff for: src/Elastic.Markdown/Assets/hljs.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {mergeHTMLPlugin} from "./hljs-merge-html-plugin";
2+
import hljs from "highlight.js";
3+
4+
hljs.registerLanguage('apiheader', function() {
5+
return {
6+
case_insensitive: true, // language is case-insensitive
7+
keywords: 'GET POST PUT DELETE HEAD OPTIONS PATCH',
8+
contains: [
9+
hljs.HASH_COMMENT_MODE,
10+
{
11+
className: "subst", // (pathname: path1/path2/dothis) color #ab5656
12+
begin: /(?<=(?:\/|GET |POST |PUT |DELETE |HEAD |OPTIONS |PATH))[^?\n\r\/]+/,
13+
}
14+
], }
15+
})
16+
17+
hljs.addPlugin(mergeHTMLPlugin);
18+
19+
export function initHighlight() {
20+
hljs.highlightAll();
21+
}

Diff for: src/Elastic.Markdown/Assets/main.ts

+4-85
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,5 @@
1-
import hljs from "highlight.js";
2-
import {mergeHTMLPlugin} from "./hljs-merge-html-plugin";
3-
import {$, $$} from 'select-dom/strict.js'
1+
import {initNav} from "./pages-nav";
2+
import {initHighlight} from "./hljs";
43

5-
hljs.registerLanguage('apiheader', function() {
6-
return {
7-
case_insensitive: true, // language is case-insensitive
8-
keywords: 'GET POST PUT DELETE HEAD OPTIONS PATCH',
9-
contains: [
10-
hljs.HASH_COMMENT_MODE,
11-
{
12-
className: "subst", // (pathname: path1/path2/dothis) color #ab5656
13-
begin: /(?<=(?:\/|GET |POST |PUT |DELETE |HEAD |OPTIONS |PATH))[^?\n\r\/]+/,
14-
}
15-
], }
16-
})
17-
18-
hljs.addPlugin(mergeHTMLPlugin);
19-
hljs.highlightAll();
20-
21-
type NavExpandState = { [key: string]: boolean };
22-
const PAGE_NAV_EXPAND_STATE_KEY = 'pagesNavState';
23-
const navState = JSON.parse(sessionStorage.getItem(PAGE_NAV_EXPAND_STATE_KEY)) as NavExpandState
24-
25-
function keepNavState(nav: HTMLElement) {
26-
const inputs = $$('input[type="checkbox"]', nav);
27-
if (navState) {
28-
inputs.forEach(input => {
29-
const key = input.id;
30-
if (input.dataset['shouldExpand'] === 'true') {
31-
input.checked = true;
32-
} else {
33-
input.checked = navState[key];
34-
}
35-
});
36-
}
37-
window.addEventListener('beforeunload', () => {
38-
const inputs = $$('input[type="checkbox"]', nav);
39-
const state: NavExpandState = inputs.reduce((state: NavExpandState, input) => {
40-
const key = input.id;
41-
const value = input.checked;
42-
return { ...state, [key]: value};
43-
}, {});
44-
sessionStorage.setItem(PAGE_NAV_EXPAND_STATE_KEY, JSON.stringify(state));
45-
});
46-
}
47-
48-
type NavScrollPosition = number;
49-
const PAGE_NAV_SCROLL_POSITION_KEY = 'pagesNavScrollPosition';
50-
const pagesNavScrollPosition: NavScrollPosition = parseInt(
51-
sessionStorage.getItem(PAGE_NAV_SCROLL_POSITION_KEY)
52-
);
53-
54-
function keepNavPosition(nav: HTMLElement) {
55-
if (pagesNavScrollPosition) {
56-
nav.scrollTop = pagesNavScrollPosition;
57-
}
58-
window.addEventListener('beforeunload', () => {
59-
sessionStorage.setItem(PAGE_NAV_SCROLL_POSITION_KEY, nav.scrollTop.toString());
60-
});
61-
}
62-
63-
function scrollCurrentNaviItemIntoView(nav: HTMLElement, delay: number) {
64-
setTimeout(() => {
65-
const currentNavItem = $('.current');
66-
if (currentNavItem && !isElementInViewport(currentNavItem)) {
67-
currentNavItem.scrollIntoView({ behavior: 'smooth', block: 'center' });
68-
}
69-
}, delay);
70-
}
71-
function isElementInViewport(el: HTMLElement): boolean {
72-
const rect = el.getBoundingClientRect();
73-
return (
74-
rect.top >= 0 &&
75-
rect.left >= 0 &&
76-
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
77-
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
78-
);
79-
}
80-
81-
const pagesNav = $('#pages-nav');
82-
keepNavState(pagesNav);
83-
keepNavPosition(pagesNav);
84-
pagesNav.style.opacity = '1';
85-
scrollCurrentNaviItemIntoView(pagesNav, 100);
86-
// $('.current a', pagesNav).focus();
4+
initNav();
5+
initHighlight();

Diff for: src/Elastic.Markdown/Assets/pages-nav.ts

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import {$, $$} from "select-dom/strict";
2+
3+
type NavExpandState = { [key: string]: boolean };
4+
const PAGE_NAV_EXPAND_STATE_KEY = 'pagesNavState';
5+
const navState = JSON.parse(sessionStorage.getItem(PAGE_NAV_EXPAND_STATE_KEY)) as NavExpandState
6+
7+
// Initialize the nav state from the session storage
8+
// Return a function to keep the nav state in the session storage that should be called before the page is unloaded
9+
function keepNavState(nav: HTMLElement): () => void {
10+
const inputs = $$('input[type="checkbox"]', nav);
11+
if (navState) {
12+
inputs.forEach(input => {
13+
const key = input.id;
14+
if ('shouldExpand' in input.dataset && input.dataset['shouldExpand'] === 'true') {
15+
input.checked = true;
16+
} else {
17+
input.checked = navState[key];
18+
}
19+
});
20+
}
21+
22+
return () => {
23+
const inputs = $$('input[type="checkbox"]', nav);
24+
const state: NavExpandState = inputs.reduce((state: NavExpandState, input) => {
25+
const key = input.id;
26+
const value = input.checked;
27+
return { ...state, [key]: value};
28+
}, {});
29+
sessionStorage.setItem(PAGE_NAV_EXPAND_STATE_KEY, JSON.stringify(state));
30+
}
31+
}
32+
33+
type NavScrollPosition = number;
34+
const PAGE_NAV_SCROLL_POSITION_KEY = 'pagesNavScrollPosition';
35+
const pagesNavScrollPosition: NavScrollPosition = parseInt(
36+
sessionStorage.getItem(PAGE_NAV_SCROLL_POSITION_KEY) ?? '0'
37+
);
38+
39+
40+
// Initialize the nav scroll position from the session storage
41+
// Return a function to keep the nav scroll position in the session storage that should be called before the page is unloaded
42+
function keepNavPosition(nav: HTMLElement): () => void {
43+
if (pagesNavScrollPosition) {
44+
nav.scrollTop = pagesNavScrollPosition;
45+
}
46+
return () => {
47+
sessionStorage.setItem(PAGE_NAV_SCROLL_POSITION_KEY, nav.scrollTop.toString());
48+
}
49+
}
50+
51+
function scrollCurrentNaviItemIntoView(nav: HTMLElement, delay: number) {
52+
setTimeout(() => {
53+
const currentNavItem = $('.current', nav);
54+
if (currentNavItem && !isElementInViewport(currentNavItem)) {
55+
currentNavItem.scrollIntoView({ behavior: 'smooth', block: 'center' });
56+
}
57+
}, delay);
58+
}
59+
function isElementInViewport(el: HTMLElement): boolean {
60+
const rect = el.getBoundingClientRect();
61+
return (
62+
rect.top >= 0 &&
63+
rect.left >= 0 &&
64+
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
65+
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
66+
);
67+
}
68+
69+
export function initNav() {
70+
const pagesNav = $('#pages-nav');
71+
const keepNavStateCallback = keepNavState(pagesNav);
72+
const keepNavPositionCallback = keepNavPosition(pagesNav);
73+
scrollCurrentNaviItemIntoView(pagesNav, 100);
74+
window.addEventListener('beforeunload', () => {
75+
keepNavStateCallback();
76+
keepNavPositionCallback();
77+
}, true);
78+
}

Diff for: src/Elastic.Markdown/Slices/Layout/_TocTreeNav.cshtml

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
{
1010
var f = file.File;
1111
var isCurrent = f == Model.CurrentDocument;
12-
<li class="block ml-2 pl-2 w-full border-l-1 border-l-gray-200 group/li @(isCurrent ? "current" : string.Empty)">
12+
<li class="block ml-2 pl-2 border-l-1 border-l-gray-200 group/li @(isCurrent ? "current" : string.Empty)">
1313
<div class="flex">
1414
<div class="w-5">
1515
</div>
@@ -32,7 +32,7 @@
3232
var containsCurrent = g.HoldsCurrent(Model.CurrentDocument) || g.ContainsCurrentPage(Model.CurrentDocument);
3333
var shouldInitiallyExpand = containsCurrent || g.Depth <= initialExpandLevel;
3434
<li class="flex flex-wrap ml-2 pl-2 @(g.Depth > 1 ? "border-l-1 border-l-gray-200" : string.Empty)">
35-
<label for="@slug" class="peer group/label flex items-center mr-1">
35+
<label for="@slug" class="peer group/label flex items-center mr-1 overflow-hidden">
3636
<svg
3737
xmlns="http://www.w3.org/2000/svg"
3838
fill="none"
@@ -58,7 +58,7 @@
5858
</label>
5959
@if (g.NavigationItems.Count > 0)
6060
{
61-
<ul class="h-0 grow overflow-hidden peer-has-checked:h-auto w-full overflow-hidden" data-has-current="@g.ContainsCurrentPage(Model.CurrentDocument)">
61+
<ul class="h-0 w-full overflow-y-hidden peer-has-checked:h-auto" data-has-current="@g.ContainsCurrentPage(Model.CurrentDocument)">
6262
@await RenderPartialAsync(_TocTreeNav.Create(new NavigationTreeItem
6363
{
6464
Level = g.Depth,

0 commit comments

Comments
 (0)