pict-section-inlinedocumentation 0.0.4 → 0.0.5
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.
- package/package.json +2 -1
- package/source/providers/Pict-Provider-InlineDocumentation.js +290 -6
- package/source/views/Pict-View-InlineDocumentation-Content.js +69 -0
- package/source/views/Pict-View-InlineDocumentation-Layout.js +1 -48
- package/source/views/Pict-View-InlineDocumentation-Nav.js +649 -113
|
@@ -11,17 +11,74 @@ const _ViewConfiguration =
|
|
|
11
11
|
|
|
12
12
|
CSS: /*css*/`
|
|
13
13
|
.pict-inline-doc-nav {
|
|
14
|
-
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
height: 100%;
|
|
17
|
+
}
|
|
18
|
+
.pict-inline-doc-nav-collapsed-header {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
padding: 0.5em 0.8em;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
border-bottom: 1px solid #EAE3D8;
|
|
24
|
+
background: #F7F5F0;
|
|
25
|
+
user-select: none;
|
|
26
|
+
}
|
|
27
|
+
.pict-inline-doc-nav-collapsed-header:hover {
|
|
28
|
+
background: #EDE8DF;
|
|
29
|
+
}
|
|
30
|
+
.pict-inline-doc-nav-chevron {
|
|
31
|
+
font-size: 0.6em;
|
|
32
|
+
transition: transform 0.2s ease;
|
|
33
|
+
color: #8A7F72;
|
|
34
|
+
display: inline-flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
margin-right: 0.5em;
|
|
37
|
+
}
|
|
38
|
+
.pict-inline-doc-nav-chevron.expanded {
|
|
39
|
+
transform: rotate(90deg);
|
|
40
|
+
}
|
|
41
|
+
.pict-inline-doc-nav-current-title {
|
|
42
|
+
font-size: 0.9em;
|
|
43
|
+
font-weight: 500;
|
|
44
|
+
color: #3D3229;
|
|
45
|
+
overflow: hidden;
|
|
46
|
+
text-overflow: ellipsis;
|
|
47
|
+
white-space: nowrap;
|
|
48
|
+
flex: 1;
|
|
49
|
+
}
|
|
50
|
+
.pict-inline-doc-nav-outline {
|
|
51
|
+
display: none;
|
|
52
|
+
overflow-y: auto;
|
|
53
|
+
}
|
|
54
|
+
.pict-inline-doc-nav-outline.expanded {
|
|
55
|
+
display: block;
|
|
56
|
+
}
|
|
57
|
+
.pict-inline-doc-nav-filter {
|
|
58
|
+
padding: 0.3em 0.6em;
|
|
59
|
+
border-bottom: 1px solid #EAE3D8;
|
|
60
|
+
}
|
|
61
|
+
.pict-inline-doc-nav-filter input {
|
|
62
|
+
width: 100%;
|
|
63
|
+
box-sizing: border-box;
|
|
64
|
+
padding: 0.3em 0.5em;
|
|
65
|
+
border: 1px solid #DDD6CA;
|
|
66
|
+
border-radius: 3px;
|
|
67
|
+
font-size: 0.85em;
|
|
68
|
+
outline: none;
|
|
69
|
+
}
|
|
70
|
+
.pict-inline-doc-nav-filter input:focus {
|
|
71
|
+
border-color: #2E7D74;
|
|
15
72
|
}
|
|
16
73
|
.pict-inline-doc-nav-group {
|
|
17
|
-
margin-bottom: 0
|
|
74
|
+
margin-bottom: 0;
|
|
18
75
|
}
|
|
19
76
|
.pict-inline-doc-nav-group-header {
|
|
20
77
|
display: flex;
|
|
21
78
|
align-items: center;
|
|
22
|
-
padding: 0.4em
|
|
79
|
+
padding: 0.4em 0.8em;
|
|
23
80
|
font-weight: 600;
|
|
24
|
-
font-size: 0.
|
|
81
|
+
font-size: 0.7em;
|
|
25
82
|
color: #5E5549;
|
|
26
83
|
text-transform: uppercase;
|
|
27
84
|
letter-spacing: 0.03em;
|
|
@@ -30,13 +87,16 @@ const _ViewConfiguration =
|
|
|
30
87
|
}
|
|
31
88
|
.pict-inline-doc-nav-group-header:hover {
|
|
32
89
|
color: #3D3229;
|
|
90
|
+
background: #F0ECE4;
|
|
33
91
|
}
|
|
34
92
|
.pict-inline-doc-nav-group-toggle {
|
|
35
|
-
margin-right: 0.
|
|
36
|
-
font-size: 0.
|
|
93
|
+
margin-right: 0.35em;
|
|
94
|
+
font-size: 0.65em;
|
|
37
95
|
transition: transform 0.15s ease;
|
|
96
|
+
display: inline-flex;
|
|
97
|
+
align-items: center;
|
|
38
98
|
}
|
|
39
|
-
.pict-inline-doc-nav-group.collapsed
|
|
99
|
+
.pict-inline-doc-nav-group-toggle.collapsed {
|
|
40
100
|
transform: rotate(-90deg);
|
|
41
101
|
}
|
|
42
102
|
.pict-inline-doc-nav-group.collapsed .pict-inline-doc-nav-group-items {
|
|
@@ -44,17 +104,16 @@ const _ViewConfiguration =
|
|
|
44
104
|
}
|
|
45
105
|
.pict-inline-doc-nav-item {
|
|
46
106
|
display: block;
|
|
47
|
-
padding: 0.
|
|
107
|
+
padding: 0.25em 0.8em 0.25em 1.6em;
|
|
48
108
|
color: #5E5549;
|
|
49
109
|
text-decoration: none;
|
|
50
|
-
font-size: 0.
|
|
110
|
+
font-size: 0.85em;
|
|
51
111
|
cursor: pointer;
|
|
52
112
|
border-left: 3px solid transparent;
|
|
53
113
|
transition: background 0.1s ease, border-color 0.1s ease;
|
|
54
114
|
}
|
|
55
115
|
.pict-inline-doc-nav-item:hover {
|
|
56
116
|
background: #EDE8DF;
|
|
57
|
-
color: #3D3229;
|
|
58
117
|
}
|
|
59
118
|
.pict-inline-doc-nav-item.active {
|
|
60
119
|
background: #E8E3D8;
|
|
@@ -62,6 +121,87 @@ const _ViewConfiguration =
|
|
|
62
121
|
border-left-color: #2E7D74;
|
|
63
122
|
font-weight: 500;
|
|
64
123
|
}
|
|
124
|
+
.pict-inline-doc-nav-heading {
|
|
125
|
+
display: block;
|
|
126
|
+
padding: 0.15em 0.8em 0.15em 2.4em;
|
|
127
|
+
color: #8A7F72;
|
|
128
|
+
font-size: 0.78em;
|
|
129
|
+
cursor: pointer;
|
|
130
|
+
border-left: 3px solid transparent;
|
|
131
|
+
transition: background 0.1s ease, color 0.1s ease;
|
|
132
|
+
}
|
|
133
|
+
.pict-inline-doc-nav-heading:hover {
|
|
134
|
+
background: #EDE8DF;
|
|
135
|
+
color: #5E5549;
|
|
136
|
+
}
|
|
137
|
+
.pict-inline-doc-nav-heading.h3 {
|
|
138
|
+
padding-left: 3.2em;
|
|
139
|
+
font-size: 0.72em;
|
|
140
|
+
}
|
|
141
|
+
/* Search icon in collapsed header */
|
|
142
|
+
.pict-inline-doc-nav-search-icon {
|
|
143
|
+
display: inline-flex;
|
|
144
|
+
align-items: center;
|
|
145
|
+
color: #8A7F72;
|
|
146
|
+
opacity: 0.5;
|
|
147
|
+
transition: opacity 0.2s;
|
|
148
|
+
flex-shrink: 0;
|
|
149
|
+
margin-left: 0.3em;
|
|
150
|
+
}
|
|
151
|
+
.pict-inline-doc-nav-search-icon:hover {
|
|
152
|
+
opacity: 1;
|
|
153
|
+
color: #2E7D74;
|
|
154
|
+
}
|
|
155
|
+
/* Search results section */
|
|
156
|
+
.pict-inline-doc-nav-search-results {
|
|
157
|
+
border-bottom: 1px solid #EAE3D8;
|
|
158
|
+
padding: 0.3em 0;
|
|
159
|
+
}
|
|
160
|
+
.pict-inline-doc-nav-search-status {
|
|
161
|
+
padding: 0.2em 0.8em;
|
|
162
|
+
font-size: 0.7em;
|
|
163
|
+
color: #8A7F72;
|
|
164
|
+
text-transform: uppercase;
|
|
165
|
+
letter-spacing: 0.03em;
|
|
166
|
+
}
|
|
167
|
+
.pict-inline-doc-nav-search-result {
|
|
168
|
+
display: flex;
|
|
169
|
+
align-items: baseline;
|
|
170
|
+
padding: 0.25em 0.8em 0.25em 1.2em;
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
font-size: 0.82em;
|
|
173
|
+
color: #3D3229;
|
|
174
|
+
text-decoration: none;
|
|
175
|
+
transition: background 0.1s ease;
|
|
176
|
+
gap: 0.5em;
|
|
177
|
+
}
|
|
178
|
+
.pict-inline-doc-nav-search-result:hover {
|
|
179
|
+
background: #EDE8DF;
|
|
180
|
+
}
|
|
181
|
+
.pict-inline-doc-nav-search-result-title {
|
|
182
|
+
flex: 1;
|
|
183
|
+
overflow: hidden;
|
|
184
|
+
text-overflow: ellipsis;
|
|
185
|
+
white-space: nowrap;
|
|
186
|
+
}
|
|
187
|
+
.pict-inline-doc-nav-search-result-group {
|
|
188
|
+
font-size: 0.75em;
|
|
189
|
+
color: #8A7F72;
|
|
190
|
+
white-space: nowrap;
|
|
191
|
+
}
|
|
192
|
+
/* External link indicator */
|
|
193
|
+
.pict-inline-doc-nav-item-external {
|
|
194
|
+
color: #8A7F72;
|
|
195
|
+
}
|
|
196
|
+
.pict-inline-doc-nav-item-external:hover {
|
|
197
|
+
color: #2E7D74;
|
|
198
|
+
}
|
|
199
|
+
.pict-inline-doc-nav-external-icon {
|
|
200
|
+
display: inline;
|
|
201
|
+
margin-left: 0.3em;
|
|
202
|
+
opacity: 0.5;
|
|
203
|
+
vertical-align: -0.05em;
|
|
204
|
+
}
|
|
65
205
|
.pict-inline-doc-nav-topic-badge {
|
|
66
206
|
display: inline-block;
|
|
67
207
|
margin: 0.5em 1em;
|
|
@@ -123,57 +263,6 @@ const _ViewConfiguration =
|
|
|
123
263
|
.pict-inline-doc-nav-toolbar-spacer {
|
|
124
264
|
flex: 1;
|
|
125
265
|
}
|
|
126
|
-
/* Compact (horizontal) nav mode */
|
|
127
|
-
.pict-inline-doc-compact .pict-inline-doc-nav {
|
|
128
|
-
display: flex;
|
|
129
|
-
flex-wrap: wrap;
|
|
130
|
-
align-items: center;
|
|
131
|
-
padding: 0.4em 0.5em;
|
|
132
|
-
gap: 0.2em 0;
|
|
133
|
-
}
|
|
134
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-group {
|
|
135
|
-
margin-bottom: 0;
|
|
136
|
-
display: flex;
|
|
137
|
-
align-items: center;
|
|
138
|
-
}
|
|
139
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-group-header {
|
|
140
|
-
padding: 0.25em 0.5em;
|
|
141
|
-
font-size: 0.75em;
|
|
142
|
-
}
|
|
143
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-group-toggle {
|
|
144
|
-
display: none;
|
|
145
|
-
}
|
|
146
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-group-items {
|
|
147
|
-
display: flex !important;
|
|
148
|
-
flex-wrap: wrap;
|
|
149
|
-
gap: 0;
|
|
150
|
-
}
|
|
151
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-item {
|
|
152
|
-
padding: 0.25em 0.6em;
|
|
153
|
-
font-size: 0.8em;
|
|
154
|
-
border-left: none;
|
|
155
|
-
border-bottom: 2px solid transparent;
|
|
156
|
-
white-space: nowrap;
|
|
157
|
-
}
|
|
158
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-item.active {
|
|
159
|
-
border-left: none;
|
|
160
|
-
border-bottom-color: #2E7D74;
|
|
161
|
-
}
|
|
162
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-topic-badge {
|
|
163
|
-
margin: 0 0.5em;
|
|
164
|
-
padding: 0.2em 0.5em;
|
|
165
|
-
font-size: 0.75em;
|
|
166
|
-
}
|
|
167
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-toolbar {
|
|
168
|
-
padding: 0.2em 0.5em;
|
|
169
|
-
border-bottom: none;
|
|
170
|
-
border-right: 1px solid #EAE3D8;
|
|
171
|
-
}
|
|
172
|
-
.pict-inline-doc-compact .pict-inline-doc-nav-toolbar-btn {
|
|
173
|
-
width: 24px;
|
|
174
|
-
height: 24px;
|
|
175
|
-
font-size: 0.8em;
|
|
176
|
-
}
|
|
177
266
|
`,
|
|
178
267
|
|
|
179
268
|
Templates:
|
|
@@ -230,68 +319,234 @@ class InlineDocumentationNavView extends libPictView
|
|
|
230
319
|
return;
|
|
231
320
|
}
|
|
232
321
|
|
|
233
|
-
let
|
|
322
|
+
let tmpProvider = this.pict.providers['Pict-InlineDocumentation'];
|
|
323
|
+
let tmpHeadings = [];
|
|
324
|
+
if (tmpProvider && typeof tmpProvider._extractHeadings === 'function')
|
|
325
|
+
{
|
|
326
|
+
tmpHeadings = tmpProvider._extractHeadings();
|
|
327
|
+
}
|
|
328
|
+
|
|
234
329
|
let tmpCurrentPath = tmpState.CurrentPath || '';
|
|
235
|
-
let
|
|
236
|
-
let
|
|
237
|
-
let
|
|
330
|
+
let tmpIsCollapsed = tmpState.NavCollapsed !== false;
|
|
331
|
+
let tmpFilterText = tmpState.NavFilterText || '';
|
|
332
|
+
let tmpCurrentDocName = this._resolveCurrentDocName(tmpState, tmpCurrentPath);
|
|
333
|
+
|
|
334
|
+
let tmpHTML = '';
|
|
335
|
+
|
|
336
|
+
let tmpSearchQuery = tmpState.SearchQuery || '';
|
|
337
|
+
let tmpSearchResults = tmpState.SearchResults || [];
|
|
338
|
+
|
|
339
|
+
// 1. Collapsed header with search icon
|
|
340
|
+
let tmpChevronClass = 'pict-inline-doc-nav-chevron' + (tmpIsCollapsed ? '' : ' expanded');
|
|
341
|
+
tmpHTML += '<div class="pict-inline-doc-nav-collapsed-header">';
|
|
342
|
+
tmpHTML += '<span class="' + tmpChevronClass + '" id="InlineDoc-Nav-CollapseToggle">';
|
|
343
|
+
tmpHTML += '<svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6,3 11,8 6,13"/></svg>';
|
|
344
|
+
tmpHTML += '</span>';
|
|
345
|
+
tmpHTML += '<span class="pict-inline-doc-nav-current-title" id="InlineDoc-Nav-TitleToggle">' + this._escapeHTML(tmpCurrentDocName) + '</span>';
|
|
346
|
+
tmpHTML += '<span class="pict-inline-doc-nav-search-icon" id="InlineDoc-Nav-SearchBtn" title="Search documentation">';
|
|
347
|
+
tmpHTML += '<svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="7" cy="7" r="4.5"/><line x1="10.5" y1="10.5" x2="14" y2="14"/></svg>';
|
|
348
|
+
tmpHTML += '</span>';
|
|
349
|
+
tmpHTML += '</div>';
|
|
350
|
+
|
|
351
|
+
// 2. Outline body
|
|
352
|
+
let tmpOutlineClass = 'pict-inline-doc-nav-outline' + (tmpIsCollapsed ? '' : ' expanded');
|
|
353
|
+
tmpHTML += '<div class="' + tmpOutlineClass + '" id="InlineDoc-Nav-Outline">';
|
|
354
|
+
|
|
355
|
+
// Search / filter input
|
|
356
|
+
let tmpPlaceholder = tmpState.SearchIndexLoaded ? 'Search documentation...' : 'Filter...';
|
|
357
|
+
tmpHTML += '<div class="pict-inline-doc-nav-filter">';
|
|
358
|
+
tmpHTML += '<input type="text" id="InlineDoc-Nav-FilterInput" placeholder="' + tmpPlaceholder + '" value="' + this._escapeHTML(tmpSearchQuery || tmpFilterText) + '" />';
|
|
359
|
+
tmpHTML += '</div>';
|
|
360
|
+
|
|
361
|
+
// Search results (when full-text search is active)
|
|
362
|
+
if (tmpSearchResults.length > 0 && tmpSearchQuery)
|
|
363
|
+
{
|
|
364
|
+
tmpHTML += '<div class="pict-inline-doc-nav-search-results">';
|
|
365
|
+
tmpHTML += '<div class="pict-inline-doc-nav-search-status">' + tmpSearchResults.length + ' result' + (tmpSearchResults.length !== 1 ? 's' : '') + '</div>';
|
|
366
|
+
for (let i = 0; i < tmpSearchResults.length && i < 15; i++)
|
|
367
|
+
{
|
|
368
|
+
let tmpResult = tmpSearchResults[i];
|
|
369
|
+
tmpHTML += '<a class="pict-inline-doc-nav-search-result" data-search-path="' + this._escapeHTML(tmpResult.DocPath) + '">';
|
|
370
|
+
tmpHTML += '<span class="pict-inline-doc-nav-search-result-title">' + this._escapeHTML(tmpResult.Title) + '</span>';
|
|
371
|
+
if (tmpResult.Group)
|
|
372
|
+
{
|
|
373
|
+
tmpHTML += '<span class="pict-inline-doc-nav-search-result-group">' + this._escapeHTML(tmpResult.Group) + '</span>';
|
|
374
|
+
}
|
|
375
|
+
tmpHTML += '</a>';
|
|
376
|
+
}
|
|
377
|
+
tmpHTML += '</div>';
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Topic badge
|
|
381
|
+
tmpHTML += this._renderTopicBadge(tmpState);
|
|
382
|
+
|
|
383
|
+
// Toolbar
|
|
384
|
+
tmpHTML += this._renderToolbar(tmpState);
|
|
385
|
+
|
|
386
|
+
// Group tree
|
|
387
|
+
tmpHTML += this._renderGroupTree(tmpState, tmpCurrentPath, tmpHeadings, tmpFilterText);
|
|
388
|
+
|
|
389
|
+
tmpHTML += '</div>';
|
|
390
|
+
|
|
391
|
+
tmpContainer.innerHTML = tmpHTML;
|
|
392
|
+
|
|
393
|
+
// Wire up click handlers
|
|
394
|
+
this._wireClickHandlers(tmpContainer);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Resolve the display name for the currently loaded document.
|
|
399
|
+
*
|
|
400
|
+
* Searches SidebarGroups for a matching item name; falls back to the path.
|
|
401
|
+
*
|
|
402
|
+
* @param {object} pState - The InlineDocumentation state
|
|
403
|
+
* @param {string} pCurrentPath - The current document path
|
|
404
|
+
* @returns {string} The resolved document name
|
|
405
|
+
*/
|
|
406
|
+
_resolveCurrentDocName(pState, pCurrentPath)
|
|
407
|
+
{
|
|
408
|
+
if (!pCurrentPath)
|
|
409
|
+
{
|
|
410
|
+
return 'Documentation';
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
let tmpGroups = pState.SidebarGroups || [];
|
|
414
|
+
|
|
415
|
+
for (let i = 0; i < tmpGroups.length; i++)
|
|
416
|
+
{
|
|
417
|
+
let tmpGroup = tmpGroups[i];
|
|
418
|
+
|
|
419
|
+
// Check if the group itself matches
|
|
420
|
+
if (tmpGroup.Path && tmpGroup.Path === pCurrentPath)
|
|
421
|
+
{
|
|
422
|
+
return tmpGroup.Name || pCurrentPath;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
let tmpItems = tmpGroup.Items || [];
|
|
426
|
+
for (let j = 0; j < tmpItems.length; j++)
|
|
427
|
+
{
|
|
428
|
+
if (tmpItems[j].Path === pCurrentPath)
|
|
429
|
+
{
|
|
430
|
+
return tmpItems[j].Name || pCurrentPath;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return pCurrentPath;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Render the topic badge HTML if a topic is active.
|
|
440
|
+
*
|
|
441
|
+
* @param {object} pState - The InlineDocumentation state
|
|
442
|
+
* @returns {string} HTML string for the topic badge, or empty string
|
|
443
|
+
*/
|
|
444
|
+
_renderTopicBadge(pState)
|
|
445
|
+
{
|
|
446
|
+
let tmpActiveTopic = pState.Topic;
|
|
447
|
+
|
|
448
|
+
if (!tmpActiveTopic || !pState.Topics || !pState.Topics[tmpActiveTopic])
|
|
449
|
+
{
|
|
450
|
+
return '';
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
let tmpTopicDef = pState.Topics[tmpActiveTopic];
|
|
454
|
+
let tmpTopicName = tmpTopicDef.TopicTitle || tmpTopicDef.Name || tmpActiveTopic;
|
|
455
|
+
|
|
456
|
+
let tmpHTML = '<div class="pict-inline-doc-nav-topic-badge">'
|
|
457
|
+
+ this._escapeHTML(tmpTopicName)
|
|
458
|
+
+ '<span class="pict-inline-doc-nav-topic-clear" id="InlineDoc-Nav-ClearTopic">'
|
|
459
|
+
+ '<svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">'
|
|
460
|
+
+ '<line x1="4" y1="4" x2="12" y2="12"/><line x1="12" y1="4" x2="4" y2="12"/>'
|
|
461
|
+
+ '</svg></span>'
|
|
462
|
+
+ '</div>';
|
|
463
|
+
|
|
464
|
+
return tmpHTML;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Render the topic management toolbar HTML.
|
|
469
|
+
*
|
|
470
|
+
* @param {object} pState - The InlineDocumentation state
|
|
471
|
+
* @returns {string} HTML string for the toolbar, or empty string
|
|
472
|
+
*/
|
|
473
|
+
_renderToolbar(pState)
|
|
474
|
+
{
|
|
475
|
+
if (!pState.TopicManagerEnabled)
|
|
476
|
+
{
|
|
477
|
+
return '';
|
|
478
|
+
}
|
|
238
479
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
480
|
+
let tmpHTML = '<div class="pict-inline-doc-nav-toolbar">';
|
|
481
|
+
tmpHTML += '<button class="pict-inline-doc-nav-toolbar-btn" id="InlineDoc-Nav-ManageTopics" title="Manage Topics">'
|
|
482
|
+
+ '<svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">'
|
|
483
|
+
+ '<circle cx="8" cy="8" r="2.5"/>'
|
|
484
|
+
+ '<path d="M8 1v2M8 13v2M1 8h2M13 8h2M3.05 3.05l1.41 1.41M11.54 11.54l1.41 1.41M3.05 12.95l1.41-1.41M11.54 4.46l1.41-1.41"/>'
|
|
485
|
+
+ '</svg></button>';
|
|
486
|
+
|
|
487
|
+
if (pState.CurrentRoute)
|
|
244
488
|
{
|
|
245
|
-
|
|
489
|
+
tmpHTML += '<button class="pict-inline-doc-nav-toolbar-btn accent" id="InlineDoc-Nav-BindTopic" title="Bind topic to current route">'
|
|
490
|
+
+ '<svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">'
|
|
491
|
+
+ '<path d="M6.5 9.5a3.5 3.5 0 005 0l2-2a3.5 3.5 0 00-5-5l-1 1"/>'
|
|
492
|
+
+ '<path d="M9.5 6.5a3.5 3.5 0 00-5 0l-2 2a3.5 3.5 0 005 5l1-1"/>'
|
|
493
|
+
+ '</svg></button>';
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
let tmpTooltipEditActive = pState.TooltipEditMode ? ' active' : '';
|
|
497
|
+
tmpHTML += '<button class="pict-inline-doc-nav-toolbar-btn' + tmpTooltipEditActive + '" id="InlineDoc-Nav-TooltipEditMode" title="Toggle tooltip edit mode">'
|
|
498
|
+
+ '<svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">'
|
|
499
|
+
+ '<path d="M14 10a1.5 1.5 0 01-1.5 1.5H4l-3 3V3A1.5 1.5 0 012.5 1.5h10A1.5 1.5 0 0114 3z"/>'
|
|
500
|
+
+ '</svg></button>';
|
|
246
501
|
|
|
247
|
-
|
|
248
|
-
|
|
502
|
+
tmpHTML += '<span class="pict-inline-doc-nav-toolbar-spacer"></span>';
|
|
503
|
+
tmpHTML += '</div>';
|
|
504
|
+
|
|
505
|
+
return tmpHTML;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Build the group/item/heading tree HTML.
|
|
510
|
+
*
|
|
511
|
+
* @param {object} pState - The InlineDocumentation state
|
|
512
|
+
* @param {string} pCurrentPath - The current document path
|
|
513
|
+
* @param {Array} pHeadings - Array of { Text, Slug, Level } from _extractHeadings
|
|
514
|
+
* @param {string} pFilterText - The current filter text
|
|
515
|
+
* @returns {string} HTML string for the group tree
|
|
516
|
+
*/
|
|
517
|
+
_renderGroupTree(pState, pCurrentPath, pHeadings, pFilterText)
|
|
518
|
+
{
|
|
519
|
+
let tmpHTML = '';
|
|
520
|
+
let tmpGroups = pState.SidebarGroups || [];
|
|
521
|
+
let tmpActiveTopic = pState.Topic;
|
|
522
|
+
let tmpTopicDocuments = null;
|
|
523
|
+
let tmpFilterLower = (pFilterText || '').toLowerCase();
|
|
524
|
+
|
|
525
|
+
// Resolve topic document filter
|
|
526
|
+
if (tmpActiveTopic && pState.Topics && pState.Topics[tmpActiveTopic])
|
|
527
|
+
{
|
|
528
|
+
let tmpTopicDef = pState.Topics[tmpActiveTopic];
|
|
249
529
|
|
|
250
|
-
// Determine matching documents
|
|
251
530
|
if (tmpTopicDef.TopicHelpFilePath)
|
|
252
531
|
{
|
|
253
|
-
// pict_documentation_topics.json format — single file per topic
|
|
254
532
|
tmpTopicDocuments = [tmpTopicDef.TopicHelpFilePath];
|
|
255
533
|
}
|
|
256
534
|
else if (tmpTopicDef.Documents)
|
|
257
535
|
{
|
|
258
|
-
// Legacy format — array of document paths
|
|
259
536
|
tmpTopicDocuments = tmpTopicDef.Documents;
|
|
260
537
|
}
|
|
261
538
|
else
|
|
262
539
|
{
|
|
263
540
|
tmpTopicDocuments = [];
|
|
264
541
|
}
|
|
265
|
-
|
|
266
|
-
tmpHTML += '<div class="pict-inline-doc-nav-topic-badge">'
|
|
267
|
-
+ this._escapeHTML(tmpTopicName)
|
|
268
|
-
+ '<span class="pict-inline-doc-nav-topic-clear" id="InlineDoc-Nav-ClearTopic"><svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><line x1="4" y1="4" x2="12" y2="12"/><line x1="12" y1="4" x2="4" y2="12"/></svg></span>'
|
|
269
|
-
+ '</div>';
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Topic management toolbar
|
|
273
|
-
if (tmpState.TopicManagerEnabled)
|
|
274
|
-
{
|
|
275
|
-
tmpHTML += '<div class="pict-inline-doc-nav-toolbar">';
|
|
276
|
-
tmpHTML += '<button class="pict-inline-doc-nav-toolbar-btn" id="InlineDoc-Nav-ManageTopics" title="Manage Topics"><svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="2.5"/><path d="M8 1v2M8 13v2M1 8h2M13 8h2M3.05 3.05l1.41 1.41M11.54 11.54l1.41 1.41M3.05 12.95l1.41-1.41M11.54 4.46l1.41-1.41"/></svg></button>';
|
|
277
|
-
if (tmpState.CurrentRoute)
|
|
278
|
-
{
|
|
279
|
-
tmpHTML += '<button class="pict-inline-doc-nav-toolbar-btn accent" id="InlineDoc-Nav-BindTopic" title="Bind topic to current route"><svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 9.5a3.5 3.5 0 005 0l2-2a3.5 3.5 0 00-5-5l-1 1"/><path d="M9.5 6.5a3.5 3.5 0 00-5 0l-2 2a3.5 3.5 0 005 5l1-1"/></svg></button>';
|
|
280
|
-
}
|
|
281
|
-
let tmpTooltipEditActive = tmpState.TooltipEditMode ? ' active' : '';
|
|
282
|
-
tmpHTML += '<button class="pict-inline-doc-nav-toolbar-btn' + tmpTooltipEditActive + '" id="InlineDoc-Nav-TooltipEditMode" title="Toggle tooltip edit mode"><svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 10a1.5 1.5 0 01-1.5 1.5H4l-3 3V3A1.5 1.5 0 012.5 1.5h10A1.5 1.5 0 0114 3z"/></svg></button>';
|
|
283
|
-
tmpHTML += '<span class="pict-inline-doc-nav-toolbar-spacer"></span>';
|
|
284
|
-
tmpHTML += '</div>';
|
|
285
542
|
}
|
|
286
543
|
|
|
287
|
-
let tmpGroups = tmpState.SidebarGroups || [];
|
|
288
|
-
|
|
289
544
|
for (let i = 0; i < tmpGroups.length; i++)
|
|
290
545
|
{
|
|
291
546
|
let tmpGroup = tmpGroups[i];
|
|
292
547
|
let tmpGroupItems = tmpGroup.Items || [];
|
|
293
548
|
|
|
294
|
-
//
|
|
549
|
+
// Apply topic filter
|
|
295
550
|
if (tmpTopicDocuments)
|
|
296
551
|
{
|
|
297
552
|
tmpGroupItems = tmpGroupItems.filter((pItem) =>
|
|
@@ -299,7 +554,6 @@ class InlineDocumentationNavView extends libPictView
|
|
|
299
554
|
return tmpTopicDocuments.indexOf(pItem.Path) >= 0;
|
|
300
555
|
});
|
|
301
556
|
|
|
302
|
-
// Also check if the group-level path matches
|
|
303
557
|
let tmpGroupMatches = tmpTopicDocuments.indexOf(tmpGroup.Path) >= 0;
|
|
304
558
|
|
|
305
559
|
if (tmpGroupItems.length < 1 && !tmpGroupMatches)
|
|
@@ -308,22 +562,64 @@ class InlineDocumentationNavView extends libPictView
|
|
|
308
562
|
}
|
|
309
563
|
}
|
|
310
564
|
|
|
311
|
-
|
|
565
|
+
// Apply text filter — match item names AND headings of the active document
|
|
566
|
+
if (tmpFilterLower)
|
|
567
|
+
{
|
|
568
|
+
tmpGroupItems = tmpGroupItems.filter((pItem) =>
|
|
569
|
+
{
|
|
570
|
+
if ((pItem.Name || '').toLowerCase().indexOf(tmpFilterLower) >= 0)
|
|
571
|
+
{
|
|
572
|
+
return true;
|
|
573
|
+
}
|
|
574
|
+
// For the active document, also check heading text
|
|
575
|
+
if (pItem.Path === pCurrentPath && pHeadings.length > 0)
|
|
576
|
+
{
|
|
577
|
+
for (let h = 0; h < pHeadings.length; h++)
|
|
578
|
+
{
|
|
579
|
+
if ((pHeadings[h].Text || '').toLowerCase().indexOf(tmpFilterLower) >= 0)
|
|
580
|
+
{
|
|
581
|
+
return true;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return false;
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
let tmpGroupNameMatches = (tmpGroup.Name || '').toLowerCase().indexOf(tmpFilterLower) >= 0;
|
|
589
|
+
|
|
590
|
+
if (tmpGroupItems.length < 1 && !tmpGroupNameMatches)
|
|
591
|
+
{
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
let tmpGroupKey = tmpGroup.Key || tmpGroup.Name || ('group-' + i);
|
|
597
|
+
let tmpIsGroupCollapsed = pState.CollapsedGroups && pState.CollapsedGroups[tmpGroupKey];
|
|
598
|
+
let tmpGroupClass = 'pict-inline-doc-nav-group' + (tmpIsGroupCollapsed ? ' collapsed' : '');
|
|
599
|
+
let tmpToggleClass = 'pict-inline-doc-nav-group-toggle' + (tmpIsGroupCollapsed ? ' collapsed' : '');
|
|
600
|
+
|
|
601
|
+
tmpHTML += '<div class="' + tmpGroupClass + '" data-group="' + this._escapeHTML(tmpGroupKey) + '">';
|
|
312
602
|
tmpHTML += '<div class="pict-inline-doc-nav-group-header">';
|
|
313
|
-
tmpHTML += '<span class="
|
|
603
|
+
tmpHTML += '<span class="' + tmpToggleClass + '">▼</span>';
|
|
314
604
|
tmpHTML += this._escapeHTML(tmpGroup.Name);
|
|
315
605
|
tmpHTML += '</div>';
|
|
316
606
|
|
|
317
607
|
tmpHTML += '<div class="pict-inline-doc-nav-group-items">';
|
|
318
608
|
|
|
319
|
-
// If the group itself has a path
|
|
609
|
+
// If the group itself has a path, show it as the first item
|
|
320
610
|
if (tmpGroup.Path)
|
|
321
611
|
{
|
|
322
|
-
let tmpActive = (
|
|
612
|
+
let tmpActive = (pCurrentPath === tmpGroup.Path) ? ' active' : '';
|
|
323
613
|
tmpHTML += '<a class="pict-inline-doc-nav-item' + tmpActive
|
|
324
614
|
+ '" data-doc-path="' + this._escapeHTML(tmpGroup.Path) + '">'
|
|
325
615
|
+ this._escapeHTML(tmpGroup.Name)
|
|
326
616
|
+ '</a>';
|
|
617
|
+
|
|
618
|
+
// If this is the active item, render heading sub-items
|
|
619
|
+
if (pCurrentPath === tmpGroup.Path)
|
|
620
|
+
{
|
|
621
|
+
tmpHTML += this._renderHeadingSubItems(pHeadings, tmpFilterLower);
|
|
622
|
+
}
|
|
327
623
|
}
|
|
328
624
|
|
|
329
625
|
for (let j = 0; j < tmpGroupItems.length; j++)
|
|
@@ -335,31 +631,223 @@ class InlineDocumentationNavView extends libPictView
|
|
|
335
631
|
continue;
|
|
336
632
|
}
|
|
337
633
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
634
|
+
if (tmpItem.External && tmpItem.ExternalURL)
|
|
635
|
+
{
|
|
636
|
+
// External link — opens in a new tab
|
|
637
|
+
tmpHTML += '<a class="pict-inline-doc-nav-item pict-inline-doc-nav-item-external'
|
|
638
|
+
+ '" data-external-url="' + this._escapeHTML(tmpItem.ExternalURL) + '">'
|
|
639
|
+
+ this._escapeHTML(tmpItem.Name)
|
|
640
|
+
+ '<svg class="pict-inline-doc-nav-external-icon" width="0.75em" height="0.75em" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 9v4a1 1 0 01-1 1H3a1 1 0 01-1-1V5a1 1 0 011-1h4"/><polyline points="8,2 14,2 14,8"/><line x1="14" y1="2" x2="7" y2="9"/></svg>'
|
|
641
|
+
+ '</a>';
|
|
642
|
+
}
|
|
643
|
+
else
|
|
644
|
+
{
|
|
645
|
+
let tmpActive = (pCurrentPath === tmpItem.Path) ? ' active' : '';
|
|
646
|
+
tmpHTML += '<a class="pict-inline-doc-nav-item' + tmpActive
|
|
647
|
+
+ '" data-doc-path="' + this._escapeHTML(tmpItem.Path) + '">'
|
|
648
|
+
+ this._escapeHTML(tmpItem.Name)
|
|
649
|
+
+ '</a>';
|
|
650
|
+
|
|
651
|
+
// If this is the active item, render heading sub-items
|
|
652
|
+
if (pCurrentPath === tmpItem.Path)
|
|
653
|
+
{
|
|
654
|
+
tmpHTML += this._renderHeadingSubItems(pHeadings, tmpFilterLower);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
343
657
|
}
|
|
344
658
|
|
|
345
659
|
tmpHTML += '</div>';
|
|
346
660
|
tmpHTML += '</div>';
|
|
347
661
|
}
|
|
348
662
|
|
|
349
|
-
|
|
663
|
+
return tmpHTML;
|
|
664
|
+
}
|
|
350
665
|
|
|
351
|
-
|
|
352
|
-
|
|
666
|
+
/**
|
|
667
|
+
* Render heading sub-items (h2 and h3) beneath the active nav item.
|
|
668
|
+
*
|
|
669
|
+
* @param {Array} pHeadings - Array of { Text, Slug, Level }
|
|
670
|
+
* @param {string} pFilterText - Lowercase filter text
|
|
671
|
+
* @returns {string} HTML string for heading sub-items
|
|
672
|
+
*/
|
|
673
|
+
_renderHeadingSubItems(pHeadings, pFilterText)
|
|
674
|
+
{
|
|
675
|
+
if (!pHeadings || pHeadings.length < 1)
|
|
676
|
+
{
|
|
677
|
+
return '';
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
let tmpHTML = '';
|
|
681
|
+
|
|
682
|
+
for (let i = 0; i < pHeadings.length; i++)
|
|
683
|
+
{
|
|
684
|
+
let tmpHeading = pHeadings[i];
|
|
685
|
+
let tmpText = tmpHeading.Text || '';
|
|
686
|
+
|
|
687
|
+
// Apply filter
|
|
688
|
+
if (pFilterText && tmpText.toLowerCase().indexOf(pFilterText) < 0)
|
|
689
|
+
{
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
let tmpLevelClass = (tmpHeading.Level === 3) ? ' h3' : '';
|
|
694
|
+
tmpHTML += '<a class="pict-inline-doc-nav-heading' + tmpLevelClass
|
|
695
|
+
+ '" data-heading-slug="' + this._escapeHTML(tmpHeading.Slug) + '">'
|
|
696
|
+
+ this._escapeHTML(tmpText)
|
|
697
|
+
+ '</a>';
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
return tmpHTML;
|
|
353
701
|
}
|
|
354
702
|
|
|
355
703
|
/**
|
|
356
|
-
* Wire click handlers on navigation items
|
|
704
|
+
* Wire click handlers on navigation items, group headers, and controls.
|
|
357
705
|
*
|
|
358
706
|
* @param {HTMLElement} pContainer - The nav container element
|
|
359
707
|
*/
|
|
360
708
|
_wireClickHandlers(pContainer)
|
|
361
709
|
{
|
|
362
710
|
let tmpProvider = this.pict.providers['Pict-InlineDocumentation'];
|
|
711
|
+
let tmpState = this.pict.AppData.InlineDocumentation;
|
|
712
|
+
|
|
713
|
+
let tmpSelf = this;
|
|
714
|
+
|
|
715
|
+
// Collapse toggle (chevron)
|
|
716
|
+
let tmpCollapseToggle = pContainer.querySelector('#InlineDoc-Nav-CollapseToggle');
|
|
717
|
+
if (tmpCollapseToggle)
|
|
718
|
+
{
|
|
719
|
+
tmpCollapseToggle.addEventListener('click', () =>
|
|
720
|
+
{
|
|
721
|
+
if (tmpState)
|
|
722
|
+
{
|
|
723
|
+
tmpState.NavCollapsed = !tmpState.NavCollapsed;
|
|
724
|
+
}
|
|
725
|
+
tmpSelf._renderNavigation();
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// Title click also toggles
|
|
730
|
+
let tmpTitleToggle = pContainer.querySelector('#InlineDoc-Nav-TitleToggle');
|
|
731
|
+
if (tmpTitleToggle)
|
|
732
|
+
{
|
|
733
|
+
tmpTitleToggle.addEventListener('click', () =>
|
|
734
|
+
{
|
|
735
|
+
if (tmpState)
|
|
736
|
+
{
|
|
737
|
+
tmpState.NavCollapsed = !tmpState.NavCollapsed;
|
|
738
|
+
}
|
|
739
|
+
tmpSelf._renderNavigation();
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// Search icon — expands outline and focuses search input
|
|
744
|
+
let tmpSearchBtn = pContainer.querySelector('#InlineDoc-Nav-SearchBtn');
|
|
745
|
+
if (tmpSearchBtn)
|
|
746
|
+
{
|
|
747
|
+
tmpSearchBtn.addEventListener('click', (pEvent) =>
|
|
748
|
+
{
|
|
749
|
+
pEvent.stopPropagation();
|
|
750
|
+
if (tmpState)
|
|
751
|
+
{
|
|
752
|
+
tmpState.NavCollapsed = false;
|
|
753
|
+
}
|
|
754
|
+
tmpSelf._renderNavigation();
|
|
755
|
+
|
|
756
|
+
let tmpInput = document.getElementById('InlineDoc-Nav-FilterInput');
|
|
757
|
+
if (tmpInput)
|
|
758
|
+
{
|
|
759
|
+
tmpInput.focus();
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// Search / filter input
|
|
765
|
+
let tmpFilterInput = pContainer.querySelector('#InlineDoc-Nav-FilterInput');
|
|
766
|
+
if (tmpFilterInput)
|
|
767
|
+
{
|
|
768
|
+
let tmpDebounceTimer = null;
|
|
769
|
+
|
|
770
|
+
tmpFilterInput.addEventListener('input', (pEvent) =>
|
|
771
|
+
{
|
|
772
|
+
let tmpValue = pEvent.target.value || '';
|
|
773
|
+
|
|
774
|
+
if (tmpState)
|
|
775
|
+
{
|
|
776
|
+
tmpState.NavFilterText = tmpValue;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// If search index is loaded, debounce full-text search
|
|
780
|
+
if (tmpState && tmpState.SearchIndexLoaded && tmpProvider && typeof tmpProvider.search === 'function')
|
|
781
|
+
{
|
|
782
|
+
if (tmpDebounceTimer) clearTimeout(tmpDebounceTimer);
|
|
783
|
+
tmpDebounceTimer = setTimeout(() =>
|
|
784
|
+
{
|
|
785
|
+
tmpState.SearchQuery = tmpValue;
|
|
786
|
+
tmpState.SearchResults = tmpValue.trim() ? tmpProvider.search(tmpValue) : [];
|
|
787
|
+
tmpSelf._renderNavigation();
|
|
788
|
+
|
|
789
|
+
let tmpNewInput = document.getElementById('InlineDoc-Nav-FilterInput');
|
|
790
|
+
if (tmpNewInput)
|
|
791
|
+
{
|
|
792
|
+
tmpNewInput.focus();
|
|
793
|
+
let tmpLen = tmpNewInput.value.length;
|
|
794
|
+
tmpNewInput.setSelectionRange(tmpLen, tmpLen);
|
|
795
|
+
}
|
|
796
|
+
}, 250);
|
|
797
|
+
}
|
|
798
|
+
else
|
|
799
|
+
{
|
|
800
|
+
// No search index — immediate client-side filter only
|
|
801
|
+
tmpSelf._renderNavigation();
|
|
802
|
+
|
|
803
|
+
let tmpNewInput = document.getElementById('InlineDoc-Nav-FilterInput');
|
|
804
|
+
if (tmpNewInput)
|
|
805
|
+
{
|
|
806
|
+
tmpNewInput.focus();
|
|
807
|
+
let tmpLen = tmpNewInput.value.length;
|
|
808
|
+
tmpNewInput.setSelectionRange(tmpLen, tmpLen);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// Search result clicks
|
|
815
|
+
let tmpSearchResults = pContainer.querySelectorAll('.pict-inline-doc-nav-search-result[data-search-path]');
|
|
816
|
+
for (let i = 0; i < tmpSearchResults.length; i++)
|
|
817
|
+
{
|
|
818
|
+
let tmpResult = tmpSearchResults[i];
|
|
819
|
+
tmpResult.addEventListener('click', (pEvent) =>
|
|
820
|
+
{
|
|
821
|
+
pEvent.preventDefault();
|
|
822
|
+
let tmpPath = tmpResult.getAttribute('data-search-path');
|
|
823
|
+
if (tmpProvider && tmpPath)
|
|
824
|
+
{
|
|
825
|
+
if (tmpState)
|
|
826
|
+
{
|
|
827
|
+
tmpState.SearchQuery = '';
|
|
828
|
+
tmpState.SearchResults = [];
|
|
829
|
+
tmpState.NavFilterText = '';
|
|
830
|
+
}
|
|
831
|
+
tmpProvider.loadDocument(tmpPath);
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// External links — open in new tab
|
|
837
|
+
let tmpExternalLinks = pContainer.querySelectorAll('[data-external-url]');
|
|
838
|
+
for (let i = 0; i < tmpExternalLinks.length; i++)
|
|
839
|
+
{
|
|
840
|
+
let tmpExtLink = tmpExternalLinks[i];
|
|
841
|
+
tmpExtLink.addEventListener('click', (pEvent) =>
|
|
842
|
+
{
|
|
843
|
+
pEvent.preventDefault();
|
|
844
|
+
let tmpURL = tmpExtLink.getAttribute('data-external-url');
|
|
845
|
+
if (tmpURL)
|
|
846
|
+
{
|
|
847
|
+
window.open(tmpURL, '_blank');
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
}
|
|
363
851
|
|
|
364
852
|
// Document links
|
|
365
853
|
let tmpLinks = pContainer.querySelectorAll('.pict-inline-doc-nav-item[data-doc-path]');
|
|
@@ -372,11 +860,32 @@ class InlineDocumentationNavView extends libPictView
|
|
|
372
860
|
let tmpPath = tmpLink.getAttribute('data-doc-path');
|
|
373
861
|
if (tmpProvider && tmpPath)
|
|
374
862
|
{
|
|
863
|
+
// Clear filter when navigating
|
|
864
|
+
if (tmpState)
|
|
865
|
+
{
|
|
866
|
+
tmpState.NavFilterText = '';
|
|
867
|
+
}
|
|
375
868
|
tmpProvider.loadDocument(tmpPath);
|
|
376
869
|
}
|
|
377
870
|
});
|
|
378
871
|
}
|
|
379
872
|
|
|
873
|
+
// Heading links
|
|
874
|
+
let tmpHeadingLinks = pContainer.querySelectorAll('.pict-inline-doc-nav-heading[data-heading-slug]');
|
|
875
|
+
for (let i = 0; i < tmpHeadingLinks.length; i++)
|
|
876
|
+
{
|
|
877
|
+
let tmpHeadingLink = tmpHeadingLinks[i];
|
|
878
|
+
tmpHeadingLink.addEventListener('click', (pEvent) =>
|
|
879
|
+
{
|
|
880
|
+
pEvent.preventDefault();
|
|
881
|
+
let tmpSlug = tmpHeadingLink.getAttribute('data-heading-slug');
|
|
882
|
+
if (tmpProvider && tmpSlug)
|
|
883
|
+
{
|
|
884
|
+
tmpProvider._scrollToAnchor(tmpSlug);
|
|
885
|
+
}
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
|
|
380
889
|
// Group collapse toggle
|
|
381
890
|
let tmpHeaders = pContainer.querySelectorAll('.pict-inline-doc-nav-group-header');
|
|
382
891
|
for (let i = 0; i < tmpHeaders.length; i++)
|
|
@@ -388,6 +897,33 @@ class InlineDocumentationNavView extends libPictView
|
|
|
388
897
|
if (tmpGroup)
|
|
389
898
|
{
|
|
390
899
|
tmpGroup.classList.toggle('collapsed');
|
|
900
|
+
|
|
901
|
+
// Persist collapse state
|
|
902
|
+
let tmpGroupKey = tmpGroup.getAttribute('data-group');
|
|
903
|
+
if (tmpState && tmpGroupKey)
|
|
904
|
+
{
|
|
905
|
+
if (!tmpState.CollapsedGroups)
|
|
906
|
+
{
|
|
907
|
+
tmpState.CollapsedGroups = {};
|
|
908
|
+
}
|
|
909
|
+
let tmpToggle = tmpGroup.querySelector('.pict-inline-doc-nav-group-toggle');
|
|
910
|
+
if (tmpGroup.classList.contains('collapsed'))
|
|
911
|
+
{
|
|
912
|
+
tmpState.CollapsedGroups[tmpGroupKey] = true;
|
|
913
|
+
if (tmpToggle)
|
|
914
|
+
{
|
|
915
|
+
tmpToggle.classList.add('collapsed');
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
else
|
|
919
|
+
{
|
|
920
|
+
delete tmpState.CollapsedGroups[tmpGroupKey];
|
|
921
|
+
if (tmpToggle)
|
|
922
|
+
{
|
|
923
|
+
tmpToggle.classList.remove('collapsed');
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
}
|
|
391
927
|
}
|
|
392
928
|
});
|
|
393
929
|
}
|