docyard 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -1
- data/CHANGELOG.md +34 -1
- data/lib/docyard/build/asset_bundler.rb +22 -7
- data/lib/docyard/build/file_copier.rb +49 -27
- data/lib/docyard/build/sitemap_generator.rb +6 -6
- data/lib/docyard/build/static_generator.rb +82 -50
- data/lib/docyard/builder.rb +20 -10
- data/lib/docyard/cli.rb +6 -3
- data/lib/docyard/components/aliases.rb +29 -0
- data/lib/docyard/components/processors/callout_processor.rb +124 -0
- data/lib/docyard/components/processors/code_block_diff_preprocessor.rb +106 -0
- data/lib/docyard/components/processors/code_block_focus_preprocessor.rb +79 -0
- data/lib/docyard/components/processors/code_block_options_preprocessor.rb +78 -0
- data/lib/docyard/components/processors/code_block_processor.rb +175 -0
- data/lib/docyard/components/processors/code_snippet_import_preprocessor.rb +127 -0
- data/lib/docyard/components/processors/heading_anchor_processor.rb +39 -0
- data/lib/docyard/components/processors/icon_processor.rb +53 -0
- data/lib/docyard/components/processors/table_of_contents_processor.rb +68 -0
- data/lib/docyard/components/processors/table_wrapper_processor.rb +22 -0
- data/lib/docyard/components/processors/tabs_processor.rb +48 -0
- data/lib/docyard/components/support/code_block/feature_extractor.rb +117 -0
- data/lib/docyard/components/support/code_block/icon_detector.rb +44 -0
- data/lib/docyard/components/support/code_block/line_parser.rb +84 -0
- data/lib/docyard/components/support/code_block/line_wrapper.rb +50 -0
- data/lib/docyard/components/support/code_block/patterns.rb +55 -0
- data/lib/docyard/components/support/code_detector.rb +61 -0
- data/lib/docyard/components/support/tabs/icon_detector.rb +62 -0
- data/lib/docyard/components/support/tabs/parser.rb +195 -0
- data/lib/docyard/components/support/tabs/range_finder.rb +46 -0
- data/lib/docyard/config/branding_resolver.rb +183 -0
- data/lib/docyard/{constants.rb → config/constants.rb} +7 -4
- data/lib/docyard/config/validator.rb +122 -99
- data/lib/docyard/config.rb +38 -36
- data/lib/docyard/initializer.rb +15 -76
- data/lib/docyard/navigation/breadcrumb_builder.rb +133 -0
- data/lib/docyard/{prev_next_builder.rb → navigation/prev_next_builder.rb} +6 -3
- data/lib/docyard/navigation/sidebar/children_discoverer.rb +51 -0
- data/lib/docyard/navigation/sidebar/config_parser.rb +208 -0
- data/lib/docyard/navigation/sidebar/file_resolver.rb +78 -0
- data/lib/docyard/{sidebar → navigation/sidebar}/file_system_scanner.rb +2 -1
- data/lib/docyard/navigation/sidebar/item.rb +96 -0
- data/lib/docyard/navigation/sidebar/local_config_loader.rb +51 -0
- data/lib/docyard/navigation/sidebar/metadata_extractor.rb +69 -0
- data/lib/docyard/navigation/sidebar/metadata_reader.rb +47 -0
- data/lib/docyard/navigation/sidebar/path_prefixer.rb +34 -0
- data/lib/docyard/navigation/sidebar/renderer.rb +144 -0
- data/lib/docyard/navigation/sidebar/sorter.rb +21 -0
- data/lib/docyard/navigation/sidebar/tree_builder.rb +139 -0
- data/lib/docyard/navigation/sidebar/tree_filter.rb +55 -0
- data/lib/docyard/navigation/sidebar_builder.rb +159 -0
- data/lib/docyard/rendering/icon_helpers.rb +13 -0
- data/lib/docyard/{icons → rendering/icons}/phosphor.rb +26 -1
- data/lib/docyard/{markdown.rb → rendering/markdown.rb} +19 -13
- data/lib/docyard/rendering/renderer.rb +163 -0
- data/lib/docyard/rendering/template_resolver.rb +172 -0
- data/lib/docyard/routing/fallback_resolver.rb +92 -0
- data/lib/docyard/search/build_indexer.rb +74 -0
- data/lib/docyard/search/dev_indexer.rb +155 -0
- data/lib/docyard/search/pagefind_support.rb +33 -0
- data/lib/docyard/{asset_handler.rb → server/asset_handler.rb} +24 -19
- data/lib/docyard/{server.rb → server/dev_server.rb} +32 -9
- data/lib/docyard/server/pagefind_handler.rb +63 -0
- data/lib/docyard/{preview_server.rb → server/preview_server.rb} +2 -2
- data/lib/docyard/server/rack_application.rb +192 -0
- data/lib/docyard/server/resolution_result.rb +29 -0
- data/lib/docyard/{router.rb → server/router.rb} +4 -4
- data/lib/docyard/templates/assets/css/code.css +18 -51
- data/lib/docyard/templates/assets/css/components/breadcrumbs.css +143 -0
- data/lib/docyard/templates/assets/css/components/callout.css +67 -67
- data/lib/docyard/templates/assets/css/components/code-block.css +180 -282
- data/lib/docyard/templates/assets/css/components/heading-anchor.css +28 -15
- data/lib/docyard/templates/assets/css/components/icon.css +0 -1
- data/lib/docyard/templates/assets/css/components/logo.css +0 -2
- data/lib/docyard/templates/assets/css/components/nav-menu.css +237 -0
- data/lib/docyard/templates/assets/css/components/navigation.css +186 -167
- data/lib/docyard/templates/assets/css/components/prev-next.css +76 -47
- data/lib/docyard/templates/assets/css/components/search.css +561 -0
- data/lib/docyard/templates/assets/css/components/tab-bar.css +163 -0
- data/lib/docyard/templates/assets/css/components/table-of-contents.css +127 -114
- data/lib/docyard/templates/assets/css/components/tabs.css +119 -160
- data/lib/docyard/templates/assets/css/components/theme-toggle.css +48 -44
- data/lib/docyard/templates/assets/css/landing.css +815 -0
- data/lib/docyard/templates/assets/css/layout.css +503 -87
- data/lib/docyard/templates/assets/css/main.css +1 -3
- data/lib/docyard/templates/assets/css/markdown.css +111 -93
- data/lib/docyard/templates/assets/css/reset.css +0 -3
- data/lib/docyard/templates/assets/css/typography.css +43 -41
- data/lib/docyard/templates/assets/css/variables.css +268 -208
- data/lib/docyard/templates/assets/favicon.svg +7 -8
- data/lib/docyard/templates/assets/fonts/Inter-Variable.ttf +0 -0
- data/lib/docyard/templates/assets/js/components/code-block.js +24 -42
- data/lib/docyard/templates/assets/js/components/heading-anchor.js +26 -24
- data/lib/docyard/templates/assets/js/components/navigation.js +181 -70
- data/lib/docyard/templates/assets/js/components/search.js +610 -0
- data/lib/docyard/templates/assets/js/components/sidebar-toggle.js +29 -0
- data/lib/docyard/templates/assets/js/components/tab-navigation.js +145 -0
- data/lib/docyard/templates/assets/js/components/table-of-contents.js +153 -66
- data/lib/docyard/templates/assets/js/components/tabs.js +31 -69
- data/lib/docyard/templates/assets/js/theme.js +0 -3
- data/lib/docyard/templates/assets/logo-dark.svg +8 -2
- data/lib/docyard/templates/assets/logo.svg +7 -4
- data/lib/docyard/templates/config/docyard.yml.erb +37 -34
- data/lib/docyard/templates/errors/404.html.erb +1 -1
- data/lib/docyard/templates/errors/500.html.erb +1 -1
- data/lib/docyard/templates/layouts/default.html.erb +19 -56
- data/lib/docyard/templates/layouts/splash.html.erb +176 -0
- data/lib/docyard/templates/partials/_breadcrumbs.html.erb +24 -0
- data/lib/docyard/templates/partials/_code_block.html.erb +6 -4
- data/lib/docyard/templates/partials/_doc_footer.html.erb +25 -0
- data/lib/docyard/templates/partials/_features.html.erb +15 -0
- data/lib/docyard/templates/partials/_footer.html.erb +42 -0
- data/lib/docyard/templates/partials/_head.html.erb +22 -0
- data/lib/docyard/templates/partials/_header.html.erb +49 -0
- data/lib/docyard/templates/partials/_heading_anchor.html.erb +3 -1
- data/lib/docyard/templates/partials/_hero.html.erb +27 -0
- data/lib/docyard/templates/partials/_nav_group.html.erb +25 -11
- data/lib/docyard/templates/partials/_nav_leaf.html.erb +1 -1
- data/lib/docyard/templates/partials/_nav_menu.html.erb +42 -0
- data/lib/docyard/templates/partials/_nav_nested_section.html.erb +11 -0
- data/lib/docyard/templates/partials/_nav_section.html.erb +1 -1
- data/lib/docyard/templates/partials/_prev_next.html.erb +9 -3
- data/lib/docyard/templates/partials/_scripts.html.erb +7 -0
- data/lib/docyard/templates/partials/_search_modal.html.erb +41 -0
- data/lib/docyard/templates/partials/_search_trigger.html.erb +18 -0
- data/lib/docyard/templates/partials/_sidebar.html.erb +21 -4
- data/lib/docyard/templates/partials/_tab_bar.html.erb +25 -0
- data/lib/docyard/templates/partials/_table_of_contents.html.erb +12 -12
- data/lib/docyard/templates/partials/_table_of_contents_toggle.html.erb +1 -3
- data/lib/docyard/templates/partials/_tabs.html.erb +2 -2
- data/lib/docyard/templates/partials/_theme_toggle.html.erb +2 -11
- data/lib/docyard/utils/html_helpers.rb +14 -0
- data/lib/docyard/utils/path_resolver.rb +2 -1
- data/lib/docyard/utils/url_helpers.rb +20 -0
- data/lib/docyard/version.rb +1 -1
- data/lib/docyard.rb +22 -15
- metadata +89 -50
- data/lib/docyard/components/callout_processor.rb +0 -121
- data/lib/docyard/components/code_block_diff_preprocessor.rb +0 -104
- data/lib/docyard/components/code_block_feature_extractor.rb +0 -113
- data/lib/docyard/components/code_block_focus_preprocessor.rb +0 -77
- data/lib/docyard/components/code_block_icon_detector.rb +0 -40
- data/lib/docyard/components/code_block_line_wrapper.rb +0 -46
- data/lib/docyard/components/code_block_options_preprocessor.rb +0 -76
- data/lib/docyard/components/code_block_patterns.rb +0 -51
- data/lib/docyard/components/code_block_processor.rb +0 -176
- data/lib/docyard/components/code_detector.rb +0 -59
- data/lib/docyard/components/code_line_parser.rb +0 -80
- data/lib/docyard/components/code_snippet_import_preprocessor.rb +0 -125
- data/lib/docyard/components/heading_anchor_processor.rb +0 -34
- data/lib/docyard/components/icon_detector.rb +0 -57
- data/lib/docyard/components/icon_processor.rb +0 -51
- data/lib/docyard/components/table_of_contents_processor.rb +0 -64
- data/lib/docyard/components/table_wrapper_processor.rb +0 -18
- data/lib/docyard/components/tabs_parser.rb +0 -191
- data/lib/docyard/components/tabs_processor.rb +0 -44
- data/lib/docyard/components/tabs_range_finder.rb +0 -42
- data/lib/docyard/rack_application.rb +0 -172
- data/lib/docyard/renderer.rb +0 -120
- data/lib/docyard/routing/resolution_result.rb +0 -31
- data/lib/docyard/sidebar/config_parser.rb +0 -180
- data/lib/docyard/sidebar/item.rb +0 -58
- data/lib/docyard/sidebar/renderer.rb +0 -137
- data/lib/docyard/sidebar/tree_builder.rb +0 -59
- data/lib/docyard/sidebar_builder.rb +0 -102
- data/lib/docyard/templates/markdown/getting-started/installation.md.erb +0 -77
- data/lib/docyard/templates/markdown/guides/configuration.md.erb +0 -202
- data/lib/docyard/templates/markdown/guides/markdown-features.md.erb +0 -247
- data/lib/docyard/templates/markdown/index.md.erb +0 -82
- /data/lib/docyard/{sidebar → navigation/sidebar}/title_extractor.rb +0 -0
- /data/lib/docyard/{icons → rendering/icons}/LICENSE.phosphor +0 -0
- /data/lib/docyard/{icons → rendering/icons}/file_types.rb +0 -0
- /data/lib/docyard/{icons.rb → rendering/icons.rb} +0 -0
- /data/lib/docyard/{language_mapping.rb → rendering/language_mapping.rb} +0 -0
- /data/lib/docyard/{file_watcher.rb → server/file_watcher.rb} +0 -0
- /data/lib/docyard/{errors.rb → utils/errors.rb} +0 -0
- /data/lib/docyard/{logging.rb → utils/logging.rb} +0 -0
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CodeBlockManager - Manages code block copy functionality
|
|
3
|
-
*
|
|
4
|
-
* @class CodeBlockManager
|
|
5
|
-
*/
|
|
6
1
|
class CodeBlockManager {
|
|
7
|
-
|
|
8
|
-
* Create a CodeBlockManager instance
|
|
9
|
-
* @param {HTMLElement} container - The .docyard-code-block container element
|
|
10
|
-
*/
|
|
2
|
+
|
|
11
3
|
constructor(container) {
|
|
12
4
|
if (!container) return;
|
|
13
5
|
|
|
@@ -15,7 +7,9 @@ class CodeBlockManager {
|
|
|
15
7
|
this.copyButton = container.querySelector('.docyard-code-block__copy');
|
|
16
8
|
this.codeText = this.copyButton?.getAttribute('data-code') || '';
|
|
17
9
|
|
|
18
|
-
this.
|
|
10
|
+
this.iconElement = this.copyButton?.querySelector('.docyard-code-block__copy-icon');
|
|
11
|
+
this.textElement = this.copyButton?.querySelector('.docyard-code-block__copy-text');
|
|
12
|
+
this.originalIcon = this.iconElement?.innerHTML || '';
|
|
19
13
|
|
|
20
14
|
this.checkIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256"><path d="M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z"/></svg>';
|
|
21
15
|
|
|
@@ -24,18 +18,14 @@ class CodeBlockManager {
|
|
|
24
18
|
this.init();
|
|
25
19
|
}
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
* Initialize the code block component
|
|
29
|
-
*/
|
|
21
|
+
|
|
30
22
|
init() {
|
|
31
23
|
if (!this.copyButton) return;
|
|
32
24
|
|
|
33
25
|
this.copyButton.addEventListener('click', this.handleCopy);
|
|
34
26
|
}
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
* Handle copy button click
|
|
38
|
-
*/
|
|
28
|
+
|
|
39
29
|
async handleCopy() {
|
|
40
30
|
try {
|
|
41
31
|
await this.copyToClipboard(this.codeText);
|
|
@@ -46,11 +36,7 @@ class CodeBlockManager {
|
|
|
46
36
|
}
|
|
47
37
|
}
|
|
48
38
|
|
|
49
|
-
|
|
50
|
-
* Copy text to clipboard
|
|
51
|
-
* @param {string} text - Text to copy
|
|
52
|
-
* @returns {Promise<void>}
|
|
53
|
-
*/
|
|
39
|
+
|
|
54
40
|
async copyToClipboard(text) {
|
|
55
41
|
if (navigator.clipboard && window.isSecureContext) {
|
|
56
42
|
await navigator.clipboard.writeText(text);
|
|
@@ -59,10 +45,7 @@ class CodeBlockManager {
|
|
|
59
45
|
}
|
|
60
46
|
}
|
|
61
47
|
|
|
62
|
-
|
|
63
|
-
* Fallback copy method for older browsers
|
|
64
|
-
* @param {string} text - Text to copy
|
|
65
|
-
*/
|
|
48
|
+
|
|
66
49
|
fallbackCopy(text) {
|
|
67
50
|
const textArea = document.createElement('textarea');
|
|
68
51
|
textArea.value = text;
|
|
@@ -82,14 +65,17 @@ class CodeBlockManager {
|
|
|
82
65
|
}
|
|
83
66
|
}
|
|
84
67
|
|
|
85
|
-
|
|
86
|
-
* Show success state
|
|
87
|
-
*/
|
|
68
|
+
|
|
88
69
|
showSuccess() {
|
|
89
70
|
this.copyButton.classList.add('is-success');
|
|
90
71
|
this.copyButton.setAttribute('aria-label', 'Copied to clipboard!');
|
|
91
72
|
|
|
92
|
-
this.
|
|
73
|
+
if (this.iconElement) {
|
|
74
|
+
this.iconElement.innerHTML = this.checkIcon;
|
|
75
|
+
}
|
|
76
|
+
if (this.textElement) {
|
|
77
|
+
this.textElement.textContent = 'Copied';
|
|
78
|
+
}
|
|
93
79
|
|
|
94
80
|
if (this.resetTimeout) {
|
|
95
81
|
clearTimeout(this.resetTimeout);
|
|
@@ -100,9 +86,7 @@ class CodeBlockManager {
|
|
|
100
86
|
}, 2000);
|
|
101
87
|
}
|
|
102
88
|
|
|
103
|
-
|
|
104
|
-
* Show error state
|
|
105
|
-
*/
|
|
89
|
+
|
|
106
90
|
showError() {
|
|
107
91
|
this.copyButton.classList.add('is-error');
|
|
108
92
|
this.copyButton.setAttribute('aria-label', 'Failed to copy');
|
|
@@ -116,19 +100,20 @@ class CodeBlockManager {
|
|
|
116
100
|
}, 2000);
|
|
117
101
|
}
|
|
118
102
|
|
|
119
|
-
|
|
120
|
-
* Reset button to default state
|
|
121
|
-
*/
|
|
103
|
+
|
|
122
104
|
resetState() {
|
|
123
105
|
this.copyButton.classList.remove('is-success', 'is-error');
|
|
124
106
|
this.copyButton.setAttribute('aria-label', 'Copy code to clipboard');
|
|
125
107
|
|
|
126
|
-
this.
|
|
108
|
+
if (this.iconElement) {
|
|
109
|
+
this.iconElement.innerHTML = this.originalIcon;
|
|
110
|
+
}
|
|
111
|
+
if (this.textElement) {
|
|
112
|
+
this.textElement.textContent = 'Copy';
|
|
113
|
+
}
|
|
127
114
|
}
|
|
128
115
|
|
|
129
|
-
|
|
130
|
-
* Cleanup - remove event listeners
|
|
131
|
-
*/
|
|
116
|
+
|
|
132
117
|
destroy() {
|
|
133
118
|
if (this.copyButton) {
|
|
134
119
|
this.copyButton.removeEventListener('click', this.handleCopy);
|
|
@@ -140,9 +125,6 @@ class CodeBlockManager {
|
|
|
140
125
|
}
|
|
141
126
|
}
|
|
142
127
|
|
|
143
|
-
/**
|
|
144
|
-
* Auto-initialize all code blocks on page load
|
|
145
|
-
*/
|
|
146
128
|
function initializeCodeBlocks() {
|
|
147
129
|
const codeBlocks = document.querySelectorAll('.docyard-code-block');
|
|
148
130
|
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HeadingAnchorManager handles anchor link interactions
|
|
3
|
-
* Provides copy-to-clipboard functionality with visual feedback
|
|
4
|
-
*/
|
|
5
1
|
class HeadingAnchorManager {
|
|
6
2
|
constructor() {
|
|
7
3
|
this.anchors = document.querySelectorAll('.heading-anchor');
|
|
@@ -14,11 +10,7 @@ class HeadingAnchorManager {
|
|
|
14
10
|
});
|
|
15
11
|
}
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
* Handle anchor link click
|
|
19
|
-
* @param {Event} e - Click event
|
|
20
|
-
* @param {HTMLElement} anchor - Anchor element
|
|
21
|
-
*/
|
|
13
|
+
|
|
22
14
|
handleClick(e, anchor) {
|
|
23
15
|
e.preventDefault();
|
|
24
16
|
|
|
@@ -31,15 +23,32 @@ class HeadingAnchorManager {
|
|
|
31
23
|
|
|
32
24
|
const heading = document.getElementById(headingId);
|
|
33
25
|
if (heading) {
|
|
34
|
-
heading.
|
|
26
|
+
const offsetTop = heading.getBoundingClientRect().top + window.pageYOffset - this.getScrollOffset();
|
|
27
|
+
window.scrollTo({
|
|
28
|
+
top: offsetTop,
|
|
29
|
+
behavior: 'smooth'
|
|
30
|
+
});
|
|
35
31
|
}
|
|
36
32
|
}
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
getScrollOffset() {
|
|
35
|
+
const hasTabs = document.body.classList.contains('has-tabs');
|
|
36
|
+
const headerHeight = 64;
|
|
37
|
+
const tabBarHeight = hasTabs ? 48 : 0;
|
|
38
|
+
const buffer = 24;
|
|
39
|
+
|
|
40
|
+
if (window.innerWidth > 1024 && window.innerWidth <= 1280) {
|
|
41
|
+
return headerHeight + 48 + buffer;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (window.innerWidth <= 1024) {
|
|
45
|
+
return headerHeight + 48 + buffer;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return headerHeight + tabBarHeight + buffer;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
43
52
|
async copyToClipboard(text, anchor) {
|
|
44
53
|
try {
|
|
45
54
|
await navigator.clipboard.writeText(text);
|
|
@@ -50,10 +59,7 @@ class HeadingAnchorManager {
|
|
|
50
59
|
}
|
|
51
60
|
}
|
|
52
61
|
|
|
53
|
-
|
|
54
|
-
* Fallback copy method for older browsers
|
|
55
|
-
* @param {string} text - Text to copy
|
|
56
|
-
*/
|
|
62
|
+
|
|
57
63
|
fallbackCopyToClipboard(text) {
|
|
58
64
|
const textarea = document.createElement('textarea');
|
|
59
65
|
textarea.value = text;
|
|
@@ -65,11 +71,7 @@ class HeadingAnchorManager {
|
|
|
65
71
|
document.body.removeChild(textarea);
|
|
66
72
|
}
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
* Show visual feedback on copy
|
|
70
|
-
* @param {HTMLElement} anchor - Anchor element
|
|
71
|
-
* @param {boolean} success - Whether copy succeeded
|
|
72
|
-
*/
|
|
74
|
+
|
|
73
75
|
showFeedback(anchor, success) {
|
|
74
76
|
const originalTitle = anchor.getAttribute('aria-label');
|
|
75
77
|
anchor.setAttribute('aria-label', success ? 'Link copied!' : 'Failed to copy');
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// Docyard Navigation JavaScript
|
|
2
|
-
// Handles sidebar navigation, mobile menu, accordion groups, and scroll behavior
|
|
3
|
-
|
|
4
1
|
(function() {
|
|
5
2
|
'use strict';
|
|
6
3
|
|
|
@@ -13,18 +10,36 @@
|
|
|
13
10
|
return;
|
|
14
11
|
}
|
|
15
12
|
|
|
13
|
+
var scrollPosition = 0;
|
|
14
|
+
|
|
15
|
+
function lockBodyScroll() {
|
|
16
|
+
scrollPosition = window.pageYOffset;
|
|
17
|
+
document.body.style.overflow = 'hidden';
|
|
18
|
+
document.body.style.position = 'fixed';
|
|
19
|
+
document.body.style.top = -scrollPosition + 'px';
|
|
20
|
+
document.body.style.width = '100%';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function unlockBodyScroll() {
|
|
24
|
+
document.body.style.removeProperty('overflow');
|
|
25
|
+
document.body.style.removeProperty('position');
|
|
26
|
+
document.body.style.removeProperty('top');
|
|
27
|
+
document.body.style.removeProperty('width');
|
|
28
|
+
window.scrollTo(0, scrollPosition);
|
|
29
|
+
}
|
|
30
|
+
|
|
16
31
|
function openMenu() {
|
|
32
|
+
lockBodyScroll();
|
|
17
33
|
sidebar.classList.add('is-open');
|
|
18
34
|
overlay.classList.add('is-visible');
|
|
19
35
|
toggle.setAttribute('aria-expanded', 'true');
|
|
20
|
-
document.body.style.overflow = 'hidden';
|
|
21
36
|
}
|
|
22
37
|
|
|
23
38
|
function closeMenu() {
|
|
24
39
|
sidebar.classList.remove('is-open');
|
|
25
40
|
overlay.classList.remove('is-visible');
|
|
26
41
|
toggle.setAttribute('aria-expanded', 'false');
|
|
27
|
-
|
|
42
|
+
unlockBodyScroll();
|
|
28
43
|
}
|
|
29
44
|
|
|
30
45
|
function toggleMenu() {
|
|
@@ -52,24 +67,86 @@
|
|
|
52
67
|
}
|
|
53
68
|
|
|
54
69
|
function initAccordion() {
|
|
55
|
-
|
|
70
|
+
var TOGGLE_STATE_KEY = 'docyard_toggle_states';
|
|
71
|
+
var toggles = document.querySelectorAll('[data-nav-toggle]');
|
|
72
|
+
|
|
73
|
+
function getDefaultCollapsed(navGroup) {
|
|
74
|
+
return navGroup.getAttribute('data-default-collapsed') === 'true';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function collapseGroup(navGroup, animate) {
|
|
78
|
+
var header = navGroup.querySelector('[data-nav-toggle]');
|
|
79
|
+
var children = navGroup.querySelector('.nav-group-children');
|
|
80
|
+
if (!header || !children) return;
|
|
81
|
+
|
|
82
|
+
if (animate) {
|
|
83
|
+
children.style.transition = 'max-height 0.2s cubic-bezier(0.4, 0, 1, 1)';
|
|
84
|
+
} else {
|
|
85
|
+
children.style.transition = 'none';
|
|
86
|
+
}
|
|
87
|
+
header.setAttribute('aria-expanded', 'false');
|
|
88
|
+
children.classList.add('collapsed');
|
|
89
|
+
children.style.maxHeight = '0';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function expandGroup(navGroup, animate) {
|
|
93
|
+
var header = navGroup.querySelector('[data-nav-toggle]');
|
|
94
|
+
var children = navGroup.querySelector('.nav-group-children');
|
|
95
|
+
if (!header || !children) return;
|
|
96
|
+
|
|
97
|
+
var fullHeight = children.scrollHeight;
|
|
98
|
+
if (animate) {
|
|
99
|
+
children.style.transition = 'max-height 0.35s cubic-bezier(0.34, 1.56, 0.64, 1)';
|
|
100
|
+
} else {
|
|
101
|
+
children.style.transition = 'none';
|
|
102
|
+
}
|
|
103
|
+
header.setAttribute('aria-expanded', 'true');
|
|
104
|
+
children.classList.remove('collapsed');
|
|
105
|
+
children.style.maxHeight = fullHeight + 'px';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function revertOthersToDefault(currentNavGroup) {
|
|
109
|
+
document.querySelectorAll('.nav-group').forEach(function(navGroup) {
|
|
110
|
+
if (navGroup === currentNavGroup) return;
|
|
111
|
+
|
|
112
|
+
var defaultCollapsed = getDefaultCollapsed(navGroup);
|
|
113
|
+
var children = navGroup.querySelector('.nav-group-children');
|
|
114
|
+
if (!children) return;
|
|
115
|
+
|
|
116
|
+
var isCurrentlyCollapsed = children.classList.contains('collapsed');
|
|
117
|
+
|
|
118
|
+
if (defaultCollapsed && !isCurrentlyCollapsed) {
|
|
119
|
+
collapseGroup(navGroup, true);
|
|
120
|
+
} else if (!defaultCollapsed && isCurrentlyCollapsed) {
|
|
121
|
+
expandGroup(navGroup, true);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
56
125
|
|
|
57
126
|
toggles.forEach(function(toggle) {
|
|
58
|
-
toggle.addEventListener('click', function() {
|
|
59
|
-
|
|
60
|
-
|
|
127
|
+
toggle.addEventListener('click', function(e) {
|
|
128
|
+
var expanded = toggle.getAttribute('aria-expanded') === 'true';
|
|
129
|
+
var navGroup = toggle.closest('.nav-group');
|
|
130
|
+
var children = navGroup ? navGroup.querySelector('.nav-group-children') : null;
|
|
61
131
|
|
|
62
|
-
if (!children
|
|
132
|
+
if (!children) {
|
|
63
133
|
return;
|
|
64
134
|
}
|
|
65
135
|
|
|
66
|
-
|
|
67
|
-
|
|
136
|
+
revertOthersToDefault(navGroup);
|
|
137
|
+
|
|
138
|
+
if (toggle.tagName === 'A') {
|
|
139
|
+
var href = toggle.getAttribute('href');
|
|
140
|
+
var states = {};
|
|
141
|
+
states[href] = true;
|
|
142
|
+
sessionStorage.setItem(TOGGLE_STATE_KEY, JSON.stringify(states));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
68
145
|
|
|
69
146
|
if (expanded) {
|
|
70
|
-
|
|
147
|
+
collapseGroup(navGroup, true);
|
|
71
148
|
} else {
|
|
72
|
-
|
|
149
|
+
expandGroup(navGroup, true);
|
|
73
150
|
}
|
|
74
151
|
});
|
|
75
152
|
});
|
|
@@ -80,32 +157,80 @@
|
|
|
80
157
|
}
|
|
81
158
|
|
|
82
159
|
function expandActiveGroups() {
|
|
83
|
-
|
|
160
|
+
var TOGGLE_STATE_KEY = 'docyard_toggle_states';
|
|
161
|
+
var currentUrl = window.location.pathname;
|
|
162
|
+
var lastUrl = sessionStorage.getItem('docyard_last_url') || '';
|
|
163
|
+
var toggleStates = JSON.parse(sessionStorage.getItem(TOGGLE_STATE_KEY) || '{}');
|
|
84
164
|
|
|
85
|
-
|
|
86
|
-
|
|
165
|
+
sessionStorage.setItem('docyard_last_url', currentUrl);
|
|
166
|
+
sessionStorage.removeItem(TOGGLE_STATE_KEY);
|
|
87
167
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
parent.classList.remove('collapsed');
|
|
168
|
+
document.querySelectorAll('[data-nav-toggle]').forEach(function(toggle) {
|
|
169
|
+
if (toggle.tagName !== 'A') return;
|
|
91
170
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
toggle.setAttribute('aria-expanded', 'true');
|
|
171
|
+
var href = toggle.getAttribute('href');
|
|
172
|
+
var shouldOpen = toggleStates[href] === true;
|
|
95
173
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
174
|
+
if (!shouldOpen) return;
|
|
175
|
+
|
|
176
|
+
var navGroup = toggle.closest('.nav-group');
|
|
177
|
+
var children = navGroup ? navGroup.querySelector('.nav-group-children') : null;
|
|
178
|
+
|
|
179
|
+
if (!children || !children.classList.contains('collapsed')) return;
|
|
101
180
|
|
|
102
|
-
|
|
181
|
+
var fullHeight = children.scrollHeight;
|
|
182
|
+
|
|
183
|
+
children.style.transition = 'none';
|
|
184
|
+
children.style.maxHeight = '0';
|
|
185
|
+
children.offsetHeight;
|
|
186
|
+
|
|
187
|
+
children.style.transition = 'max-height 0.35s cubic-bezier(0.34, 1.56, 0.64, 1)';
|
|
188
|
+
requestAnimationFrame(function() {
|
|
189
|
+
toggle.setAttribute('aria-expanded', 'true');
|
|
190
|
+
children.classList.remove('collapsed');
|
|
191
|
+
children.style.maxHeight = fullHeight + 'px';
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
var expandedGroups = document.querySelectorAll('.nav-group-children:not(.collapsed)');
|
|
196
|
+
|
|
197
|
+
expandedGroups.forEach(function(group) {
|
|
198
|
+
if (group.style.maxHeight) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
var navGroup = group.closest('.nav-group');
|
|
203
|
+
var header = navGroup ? navGroup.querySelector('.nav-group-header') : null;
|
|
204
|
+
var headerHref = header && header.tagName === 'A' ? header.getAttribute('href') : null;
|
|
205
|
+
|
|
206
|
+
if (headerHref && toggleStates[headerHref] === true) {
|
|
207
|
+
group.style.maxHeight = group.scrollHeight + 'px';
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
var wasInGroup = headerHref && (lastUrl === headerHref || lastUrl.startsWith(headerHref + '/'));
|
|
212
|
+
var shouldAnimate = header && header.classList.contains('active') && !wasInGroup;
|
|
213
|
+
var fullHeight = group.scrollHeight;
|
|
214
|
+
|
|
215
|
+
if (shouldAnimate) {
|
|
216
|
+
group.style.transition = 'none';
|
|
217
|
+
group.style.maxHeight = '0';
|
|
218
|
+
group.classList.add('collapsed');
|
|
219
|
+
group.offsetHeight;
|
|
220
|
+
|
|
221
|
+
group.style.transition = 'max-height 0.35s cubic-bezier(0.34, 1.56, 0.64, 1)';
|
|
222
|
+
requestAnimationFrame(function() {
|
|
223
|
+
group.classList.remove('collapsed');
|
|
224
|
+
group.style.maxHeight = fullHeight + 'px';
|
|
225
|
+
});
|
|
226
|
+
} else {
|
|
227
|
+
group.style.maxHeight = fullHeight + 'px';
|
|
103
228
|
}
|
|
104
229
|
});
|
|
105
230
|
}
|
|
106
231
|
|
|
107
232
|
function initSidebarScroll() {
|
|
108
|
-
const scrollContainer = document.querySelector('.sidebar
|
|
233
|
+
const scrollContainer = document.querySelector('.sidebar-scroll');
|
|
109
234
|
if (!scrollContainer) return;
|
|
110
235
|
|
|
111
236
|
const STORAGE_KEY = 'docyard_sidebar_scroll';
|
|
@@ -153,54 +278,38 @@
|
|
|
153
278
|
}
|
|
154
279
|
}
|
|
155
280
|
|
|
156
|
-
function
|
|
157
|
-
const
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
if (!header || !secondaryHeader) return;
|
|
161
|
-
|
|
162
|
-
let lastScrollTop = 0;
|
|
163
|
-
let ticking = false;
|
|
281
|
+
function initScrollFadeIndicators() {
|
|
282
|
+
const sidebar = document.querySelector('.sidebar');
|
|
283
|
+
const scrollContainer = document.querySelector('.sidebar-scroll');
|
|
284
|
+
if (!sidebar || !scrollContainer) return;
|
|
164
285
|
|
|
165
|
-
function
|
|
166
|
-
|
|
167
|
-
|
|
286
|
+
function updateFadeIndicators() {
|
|
287
|
+
const scrollTop = scrollContainer.scrollTop;
|
|
288
|
+
const scrollHeight = scrollContainer.scrollHeight;
|
|
289
|
+
const clientHeight = scrollContainer.clientHeight;
|
|
290
|
+
const threshold = 10;
|
|
168
291
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
ticking = false;
|
|
174
|
-
return;
|
|
292
|
+
if (scrollTop > threshold) {
|
|
293
|
+
sidebar.classList.add('can-scroll-top');
|
|
294
|
+
} else {
|
|
295
|
+
sidebar.classList.remove('can-scroll-top');
|
|
175
296
|
}
|
|
176
297
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
secondaryHeader.classList.add('shift-up');
|
|
182
|
-
} else if (scrollTop < lastScrollTop) {
|
|
183
|
-
header.classList.remove('hide-on-scroll');
|
|
184
|
-
secondaryHeader.classList.remove('shift-up');
|
|
298
|
+
if (scrollTop + clientHeight < scrollHeight - threshold) {
|
|
299
|
+
sidebar.classList.add('can-scroll-bottom');
|
|
300
|
+
} else {
|
|
301
|
+
sidebar.classList.remove('can-scroll-bottom');
|
|
185
302
|
}
|
|
186
|
-
|
|
187
|
-
lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
|
|
188
|
-
ticking = false;
|
|
189
303
|
}
|
|
190
304
|
|
|
191
|
-
|
|
192
|
-
if (!ticking) {
|
|
193
|
-
window.requestAnimationFrame(updateHeaders);
|
|
194
|
-
ticking = true;
|
|
195
|
-
}
|
|
196
|
-
});
|
|
305
|
+
updateFadeIndicators();
|
|
197
306
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
307
|
+
scrollContainer.addEventListener('scroll', updateFadeIndicators);
|
|
308
|
+
|
|
309
|
+
window.addEventListener('resize', updateFadeIndicators);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function initScrollBehavior() {
|
|
204
313
|
}
|
|
205
314
|
|
|
206
315
|
if ('scrollRestoration' in history) {
|
|
@@ -213,6 +322,7 @@
|
|
|
213
322
|
initAccordion();
|
|
214
323
|
expandActiveGroups();
|
|
215
324
|
initSidebarScroll();
|
|
325
|
+
initScrollFadeIndicators();
|
|
216
326
|
initScrollBehavior();
|
|
217
327
|
});
|
|
218
328
|
} else {
|
|
@@ -220,6 +330,7 @@
|
|
|
220
330
|
initAccordion();
|
|
221
331
|
expandActiveGroups();
|
|
222
332
|
initSidebarScroll();
|
|
333
|
+
initScrollFadeIndicators();
|
|
223
334
|
initScrollBehavior();
|
|
224
335
|
}
|
|
225
336
|
})();
|