pict-section-inlinedocumentation 0.0.4 → 0.0.7
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/example_applications/basic/index.html +5 -5
- package/example_applications/bookshop/html/index.html +5 -5
- package/example_applications/bookshop/views/PictView-Bookshop-BookList.js +6 -6
- package/example_applications/bookshop/views/PictView-Bookshop-Store.js +3 -3
- package/package.json +9 -8
- package/source/providers/Pict-Provider-InlineDocumentation.js +293 -9
- package/source/views/Pict-View-InlineDocumentation-Content.js +114 -45
- package/source/views/Pict-View-InlineDocumentation-Layout.js +7 -54
- package/source/views/Pict-View-InlineDocumentation-Nav.js +678 -130
- package/source/views/Pict-View-InlineDocumentation-TopicManager.js +64 -64
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
body {
|
|
10
10
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
11
11
|
background: #F5F3EE;
|
|
12
|
-
color: #3D3229;
|
|
12
|
+
color: var(--theme-color-text-primary, #3D3229);
|
|
13
13
|
padding: 2em;
|
|
14
14
|
}
|
|
15
15
|
h1 {
|
|
@@ -26,17 +26,17 @@
|
|
|
26
26
|
padding: 0.4em 0.8em;
|
|
27
27
|
border: 1px solid #C4BAA8;
|
|
28
28
|
border-radius: 4px;
|
|
29
|
-
background: #fff;
|
|
30
|
-
color: #3D3229;
|
|
29
|
+
background: var(--theme-color-background-panel, #fff);
|
|
30
|
+
color: var(--theme-color-text-primary, #3D3229);
|
|
31
31
|
cursor: pointer;
|
|
32
32
|
font-size: 0.9em;
|
|
33
33
|
}
|
|
34
34
|
.controls button:hover {
|
|
35
|
-
background: #F0ECE4;
|
|
35
|
+
background: var(--theme-color-background-secondary, #F0ECE4);
|
|
36
36
|
}
|
|
37
37
|
.controls button.active {
|
|
38
38
|
background: #2E7D74;
|
|
39
|
-
color: #fff;
|
|
39
|
+
color: var(--theme-color-background-panel, #fff);
|
|
40
40
|
border-color: #2E7D74;
|
|
41
41
|
}
|
|
42
42
|
#InlineDoc-Container {
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
/* --- Header Bar --- */
|
|
15
15
|
.pict-example-header { display: flex; align-items: stretch; background: #264653; border-bottom: 3px solid #E76F51; position: fixed; top: 0; left: 0; right: 0; z-index: 100; }
|
|
16
|
-
.pict-example-badge { background: #E76F51; color: #fff; padding: 0.6rem 1rem; font-size: 0.7rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.1em; display: flex; align-items: center; gap: 0.5rem; }
|
|
17
|
-
.pict-example-badge svg { width: 14px; height: 14px; fill: #fff; flex-shrink: 0; }
|
|
16
|
+
.pict-example-badge { background: #E76F51; color: var(--theme-color-background-panel, #fff); padding: 0.6rem 1rem; font-size: 0.7rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.1em; display: flex; align-items: center; gap: 0.5rem; }
|
|
17
|
+
.pict-example-badge svg { width: 14px; height: 14px; fill: var(--theme-color-background-panel, #fff); flex-shrink: 0; }
|
|
18
18
|
.pict-example-app-name { padding: 0.6rem 1rem; color: #FAEDCD; font-size: 1.1rem; font-weight: 600; display: flex; align-items: center; }
|
|
19
19
|
.pict-example-module { margin-left: auto; padding: 0.6rem 1rem; color: #D4A373; font-size: 0.75rem; display: flex; align-items: center; letter-spacing: 0.03em; }
|
|
20
20
|
.pict-example-header-help-btn {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
margin-right: 380px;
|
|
42
42
|
}
|
|
43
43
|
#Bookshop-Content-Container {
|
|
44
|
-
background: #fff;
|
|
44
|
+
background: var(--theme-color-background-panel, #fff);
|
|
45
45
|
border: 1px solid #D4A373;
|
|
46
46
|
border-top: 4px solid #E76F51;
|
|
47
47
|
border-radius: 6px;
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
bottom: 0;
|
|
58
58
|
width: 380px;
|
|
59
59
|
min-width: 320px;
|
|
60
|
-
background: #FDFCFA;
|
|
60
|
+
background: var(--theme-color-background-panel, #FDFCFA);
|
|
61
61
|
border-left: 1px solid #D4A373;
|
|
62
62
|
box-shadow: -2px 0 12px rgba(38,70,83,0.08);
|
|
63
63
|
transform: translateX(100%);
|
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
#Bookshop-Help-Panel .pict-inline-doc-nav-item.active {
|
|
154
154
|
border-left: none;
|
|
155
155
|
background: #2E7D74;
|
|
156
|
-
color: #fff;
|
|
156
|
+
color: var(--theme-color-background-panel, #fff);
|
|
157
157
|
}
|
|
158
158
|
#Bookshop-Help-Panel .pict-inline-doc-nav-topic-badge {
|
|
159
159
|
margin: 0 0.3em;
|
|
@@ -42,7 +42,7 @@ const _ViewConfiguration =
|
|
|
42
42
|
}
|
|
43
43
|
.bookshop-help-btn:hover {
|
|
44
44
|
background: #D4A373;
|
|
45
|
-
color: #fff;
|
|
45
|
+
color: var(--theme-color-background-panel, #fff);
|
|
46
46
|
}
|
|
47
47
|
.bookshop-filter-bar {
|
|
48
48
|
margin-bottom: 1.25em;
|
|
@@ -53,14 +53,14 @@ const _ViewConfiguration =
|
|
|
53
53
|
.bookshop-filter-bar label {
|
|
54
54
|
font-size: 0.85em;
|
|
55
55
|
font-weight: 600;
|
|
56
|
-
color: #5E5549;
|
|
56
|
+
color: var(--theme-color-text-secondary, #5E5549);
|
|
57
57
|
}
|
|
58
58
|
.bookshop-filter-bar select {
|
|
59
59
|
padding: 0.35em 0.7em;
|
|
60
60
|
border: 1px solid #D4A373;
|
|
61
61
|
border-radius: 4px;
|
|
62
62
|
font-size: 0.85em;
|
|
63
|
-
background: #fff;
|
|
63
|
+
background: var(--theme-color-background-panel, #fff);
|
|
64
64
|
color: #264653;
|
|
65
65
|
}
|
|
66
66
|
.bookshop-book-grid {
|
|
@@ -72,7 +72,7 @@ const _ViewConfiguration =
|
|
|
72
72
|
display: flex;
|
|
73
73
|
gap: 1em;
|
|
74
74
|
padding: 1em;
|
|
75
|
-
background: #fff;
|
|
75
|
+
background: var(--theme-color-background-panel, #fff);
|
|
76
76
|
border: 1px solid #E5DED4;
|
|
77
77
|
border-radius: 6px;
|
|
78
78
|
cursor: pointer;
|
|
@@ -88,7 +88,7 @@ const _ViewConfiguration =
|
|
|
88
88
|
border-radius: 4px;
|
|
89
89
|
object-fit: cover;
|
|
90
90
|
flex-shrink: 0;
|
|
91
|
-
background: #F0ECE4;
|
|
91
|
+
background: var(--theme-color-background-secondary, #F0ECE4);
|
|
92
92
|
}
|
|
93
93
|
.bookshop-book-info {
|
|
94
94
|
flex: 1;
|
|
@@ -110,7 +110,7 @@ const _ViewConfiguration =
|
|
|
110
110
|
font-size: 0.7em;
|
|
111
111
|
padding: 0.15em 0.5em;
|
|
112
112
|
background: #E8E3D8;
|
|
113
|
-
color: #5E5549;
|
|
113
|
+
color: var(--theme-color-text-secondary, #5E5549);
|
|
114
114
|
border-radius: 3px;
|
|
115
115
|
margin-bottom: 0.4em;
|
|
116
116
|
}
|
|
@@ -20,7 +20,7 @@ const _ViewConfiguration =
|
|
|
20
20
|
padding: 0.4em 0.8em;
|
|
21
21
|
border: 1px solid #D4A373;
|
|
22
22
|
border-radius: 4px;
|
|
23
|
-
background: #fff;
|
|
23
|
+
background: var(--theme-color-background-panel, #fff);
|
|
24
24
|
color: #264653;
|
|
25
25
|
cursor: pointer;
|
|
26
26
|
font-size: 0.85em;
|
|
@@ -40,7 +40,7 @@ const _ViewConfiguration =
|
|
|
40
40
|
border-radius: 6px;
|
|
41
41
|
object-fit: cover;
|
|
42
42
|
flex-shrink: 0;
|
|
43
|
-
background: #F0ECE4;
|
|
43
|
+
background: var(--theme-color-background-secondary, #F0ECE4);
|
|
44
44
|
box-shadow: 0 2px 12px rgba(38,70,83,0.12);
|
|
45
45
|
}
|
|
46
46
|
.bookshop-store-info {
|
|
@@ -94,7 +94,7 @@ const _ViewConfiguration =
|
|
|
94
94
|
display: inline-block;
|
|
95
95
|
padding: 0.6em 1.5em;
|
|
96
96
|
background: #E76F51;
|
|
97
|
-
color: #fff;
|
|
97
|
+
color: var(--theme-color-background-panel, #fff);
|
|
98
98
|
border: none;
|
|
99
99
|
border-radius: 5px;
|
|
100
100
|
font-size: 1em;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pict-section-inlinedocumentation",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Pict embeddable inline documentation browser with topic support",
|
|
5
5
|
"main": "source/Pict-Section-InlineDocumentation.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,17 +22,18 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/stevenvelozo/pict-section-inlinedocumentation#readme",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"
|
|
26
|
-
"pict-
|
|
27
|
-
"pict-section-
|
|
28
|
-
"pict-section-
|
|
25
|
+
"lunr": "^2.3.9",
|
|
26
|
+
"pict-provider": "^1.0.13",
|
|
27
|
+
"pict-section-content": "^1.0.0",
|
|
28
|
+
"pict-section-markdowneditor": "^1.0.15",
|
|
29
|
+
"pict-section-modal": "^1.0.1",
|
|
29
30
|
"pict-view": "^1.0.68"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
|
-
"pict": "^1.0.
|
|
33
|
-
"pict-docuserve": "^0.
|
|
33
|
+
"pict": "^1.0.368",
|
|
34
|
+
"pict-docuserve": "^1.0.0",
|
|
34
35
|
"puppeteer": "^24.40.0",
|
|
35
|
-
"quackage": "^1.
|
|
36
|
+
"quackage": "^1.2.3"
|
|
36
37
|
},
|
|
37
38
|
"mocha": {
|
|
38
39
|
"diff": true,
|
|
@@ -3,6 +3,7 @@ const libPictSectionContent = require('pict-section-content');
|
|
|
3
3
|
const libPictContentProvider = libPictSectionContent.PictContentProvider;
|
|
4
4
|
const libPictSectionModal = require('pict-section-modal');
|
|
5
5
|
const libPictSectionMarkdownEditor = require('pict-section-markdowneditor');
|
|
6
|
+
const libLunr = require('lunr');
|
|
6
7
|
|
|
7
8
|
const libViewLayout = require('../views/Pict-View-InlineDocumentation-Layout.js');
|
|
8
9
|
const libViewContent = require('../views/Pict-View-InlineDocumentation-Content.js');
|
|
@@ -90,8 +91,31 @@ class InlineDocumentationProvider extends libPictProvider
|
|
|
90
91
|
tmpState.Topics = tmpState.Topics || {};
|
|
91
92
|
tmpState.NavigationHistory = [];
|
|
92
93
|
|
|
93
|
-
//
|
|
94
|
-
tmpState.
|
|
94
|
+
// Navigation outline state
|
|
95
|
+
tmpState.NavCollapsed = true;
|
|
96
|
+
tmpState.CollapsedGroups = {};
|
|
97
|
+
tmpState.ActiveDocumentHeadings = [];
|
|
98
|
+
tmpState.NavFilterText = '';
|
|
99
|
+
|
|
100
|
+
// Full-text search state
|
|
101
|
+
tmpState.SearchIndexLoaded = false;
|
|
102
|
+
tmpState.SearchQuery = '';
|
|
103
|
+
tmpState.SearchResults = [];
|
|
104
|
+
|
|
105
|
+
// External link resolution — paths starting with / in the
|
|
106
|
+
// sidebar are cross-module references. ExternalDocBaseURL
|
|
107
|
+
// is prepended to make them full URLs opened in a new tab.
|
|
108
|
+
tmpState.ExternalDocBaseURL = tmpOptions.ExternalDocBaseURL || '';
|
|
109
|
+
|
|
110
|
+
// Edit mode state — read from pOptions if provided
|
|
111
|
+
if (tmpOptions.EditEnabled !== undefined)
|
|
112
|
+
{
|
|
113
|
+
tmpState.EditEnabled = !!tmpOptions.EditEnabled;
|
|
114
|
+
}
|
|
115
|
+
else
|
|
116
|
+
{
|
|
117
|
+
tmpState.EditEnabled = tmpState.EditEnabled || false;
|
|
118
|
+
}
|
|
95
119
|
tmpState.Editing = false;
|
|
96
120
|
tmpState.EditingPath = '';
|
|
97
121
|
tmpState.EditingContent = '';
|
|
@@ -142,17 +166,23 @@ class InlineDocumentationProvider extends libPictProvider
|
|
|
142
166
|
}
|
|
143
167
|
}
|
|
144
168
|
|
|
145
|
-
// Load sidebar and
|
|
169
|
+
// Load sidebar, topics, and search index in parallel
|
|
146
170
|
let tmpPending = 2;
|
|
171
|
+
if (tmpOptions.SearchIndexURL) tmpPending++;
|
|
172
|
+
|
|
173
|
+
let tmpSelf = this;
|
|
147
174
|
let tmpFinish = () =>
|
|
148
175
|
{
|
|
149
176
|
tmpPending--;
|
|
150
177
|
if (tmpPending <= 0)
|
|
151
178
|
{
|
|
179
|
+
// Mark sidebar items as external based on ExternalDocBaseURL
|
|
180
|
+
tmpSelf._markExternalSidebarItems();
|
|
181
|
+
|
|
152
182
|
// Render the layout (which contains nav and content containers)
|
|
153
|
-
|
|
183
|
+
tmpSelf.pict.views['InlineDoc-Layout'].render();
|
|
154
184
|
// Render the navigation
|
|
155
|
-
|
|
185
|
+
tmpSelf.pict.views['InlineDoc-Nav'].render();
|
|
156
186
|
|
|
157
187
|
return tmpCallback();
|
|
158
188
|
}
|
|
@@ -160,6 +190,11 @@ class InlineDocumentationProvider extends libPictProvider
|
|
|
160
190
|
|
|
161
191
|
this._loadSidebar(tmpFinish);
|
|
162
192
|
this._loadTopics(tmpOptions.TopicsURL, tmpFinish);
|
|
193
|
+
|
|
194
|
+
if (tmpOptions.SearchIndexURL)
|
|
195
|
+
{
|
|
196
|
+
this._loadSearchIndex(tmpOptions.SearchIndexURL, tmpFinish);
|
|
197
|
+
}
|
|
163
198
|
}
|
|
164
199
|
|
|
165
200
|
/**
|
|
@@ -226,7 +261,11 @@ class InlineDocumentationProvider extends libPictProvider
|
|
|
226
261
|
this._scrollToAnchor(tmpAnchor);
|
|
227
262
|
}
|
|
228
263
|
|
|
229
|
-
//
|
|
264
|
+
// Collapse the nav outline and clear search/filter
|
|
265
|
+
tmpState.NavCollapsed = true;
|
|
266
|
+
tmpState.NavFilterText = '';
|
|
267
|
+
tmpState.SearchQuery = '';
|
|
268
|
+
tmpState.SearchResults = [];
|
|
230
269
|
this.pict.views['InlineDoc-Nav'].render();
|
|
231
270
|
|
|
232
271
|
return tmpCallback(null, pHTML);
|
|
@@ -1429,7 +1468,7 @@ class InlineDocumentationProvider extends libPictProvider
|
|
|
1429
1468
|
|
|
1430
1469
|
let tmpEditorHTML = '<div class="pict-inline-doc-tm-form-group">';
|
|
1431
1470
|
tmpEditorHTML += '<label class="pict-inline-doc-tm-form-label">Tooltip Key</label>';
|
|
1432
|
-
tmpEditorHTML += '<div style="font-family:monospace;font-size:0.85em;color
|
|
1471
|
+
tmpEditorHTML += '<div style="font-family:monospace;font-size:0.85em;color:var(--theme-color-text-muted, #8A7F72);padding:0.3em 0;">' + this._escapeTooltipHTML(pTooltipKey) + '</div>';
|
|
1433
1472
|
tmpEditorHTML += '</div>';
|
|
1434
1473
|
tmpEditorHTML += '<div class="pict-inline-doc-tm-form-group">';
|
|
1435
1474
|
tmpEditorHTML += '<label class="pict-inline-doc-tm-form-label">Content (Markdown)</label>';
|
|
@@ -1458,7 +1497,7 @@ class InlineDocumentationProvider extends libPictProvider
|
|
|
1458
1497
|
{
|
|
1459
1498
|
// Initial preview
|
|
1460
1499
|
let tmpLinkResolver = tmpSelf._createTooltipLinkResolver();
|
|
1461
|
-
let tmpInitialHTML = tmpCurrentContent ? tmpSelf._ContentProvider.parseMarkdown(tmpCurrentContent, tmpLinkResolver) : '<span style="color
|
|
1500
|
+
let tmpInitialHTML = tmpCurrentContent ? tmpSelf._ContentProvider.parseMarkdown(tmpCurrentContent, tmpLinkResolver) : '<span style="color:var(--theme-color-text-muted, #8A7F72);">No content yet.</span>';
|
|
1462
1501
|
tmpPreview.innerHTML = tmpInitialHTML;
|
|
1463
1502
|
|
|
1464
1503
|
// Live preview on input
|
|
@@ -1471,7 +1510,7 @@ class InlineDocumentationProvider extends libPictProvider
|
|
|
1471
1510
|
}
|
|
1472
1511
|
else
|
|
1473
1512
|
{
|
|
1474
|
-
tmpPreview.innerHTML = '<span style="color
|
|
1513
|
+
tmpPreview.innerHTML = '<span style="color:var(--theme-color-text-muted, #8A7F72);">No content yet.</span>';
|
|
1475
1514
|
}
|
|
1476
1515
|
});
|
|
1477
1516
|
|
|
@@ -1615,6 +1654,251 @@ class InlineDocumentationProvider extends libPictProvider
|
|
|
1615
1654
|
}, 50);
|
|
1616
1655
|
}
|
|
1617
1656
|
|
|
1657
|
+
// ================================================================
|
|
1658
|
+
// Full-text search
|
|
1659
|
+
// ================================================================
|
|
1660
|
+
|
|
1661
|
+
/**
|
|
1662
|
+
* Load a lunr.js keyword index from a URL.
|
|
1663
|
+
*
|
|
1664
|
+
* The index file is the same format generated by Indoctrinate's
|
|
1665
|
+
* generate_keyword_index command: { LunrIndex, Documents, DocumentCount }.
|
|
1666
|
+
*
|
|
1667
|
+
* @param {string} pURL - URL to the retold-keyword-index.json file
|
|
1668
|
+
* @param {Function} [fCallback] - Callback when done
|
|
1669
|
+
*/
|
|
1670
|
+
_loadSearchIndex(pURL, fCallback)
|
|
1671
|
+
{
|
|
1672
|
+
let tmpCallback = (typeof fCallback === 'function') ? fCallback : () => {};
|
|
1673
|
+
let tmpSelf = this;
|
|
1674
|
+
|
|
1675
|
+
if (typeof fetch === 'undefined')
|
|
1676
|
+
{
|
|
1677
|
+
return tmpCallback();
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
fetch(pURL)
|
|
1681
|
+
.then((pResponse) =>
|
|
1682
|
+
{
|
|
1683
|
+
if (!pResponse.ok)
|
|
1684
|
+
{
|
|
1685
|
+
return null;
|
|
1686
|
+
}
|
|
1687
|
+
return pResponse.json();
|
|
1688
|
+
})
|
|
1689
|
+
.then((pIndexData) =>
|
|
1690
|
+
{
|
|
1691
|
+
if (!pIndexData || !pIndexData.LunrIndex || !pIndexData.Documents)
|
|
1692
|
+
{
|
|
1693
|
+
if (tmpSelf.log) tmpSelf.log.info('InlineDocumentation: No keyword index found; search unavailable.');
|
|
1694
|
+
return tmpCallback();
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
try
|
|
1698
|
+
{
|
|
1699
|
+
tmpSelf._LunrIndex = libLunr.Index.load(pIndexData.LunrIndex);
|
|
1700
|
+
tmpSelf._SearchDocuments = pIndexData.Documents;
|
|
1701
|
+
|
|
1702
|
+
let tmpState = tmpSelf.pict.AppData.InlineDocumentation;
|
|
1703
|
+
if (tmpState)
|
|
1704
|
+
{
|
|
1705
|
+
tmpState.SearchIndexLoaded = true;
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
if (tmpSelf.log) tmpSelf.log.info('InlineDocumentation: Search index loaded (' + (pIndexData.DocumentCount || 0) + ' documents).');
|
|
1709
|
+
}
|
|
1710
|
+
catch (pError)
|
|
1711
|
+
{
|
|
1712
|
+
if (tmpSelf.log) tmpSelf.log.warn('InlineDocumentation: Error hydrating lunr index: ' + pError);
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
return tmpCallback();
|
|
1716
|
+
})
|
|
1717
|
+
.catch((pError) =>
|
|
1718
|
+
{
|
|
1719
|
+
if (tmpSelf.log) tmpSelf.log.warn('InlineDocumentation: Error loading search index: ' + pError);
|
|
1720
|
+
return tmpCallback();
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/**
|
|
1725
|
+
* Search the loaded lunr index.
|
|
1726
|
+
*
|
|
1727
|
+
* @param {string} pQuery - The search query
|
|
1728
|
+
* @returns {Array} Array of { Key, Title, Group, DocPath, Score }
|
|
1729
|
+
*/
|
|
1730
|
+
search(pQuery)
|
|
1731
|
+
{
|
|
1732
|
+
if (!this._LunrIndex || !this._SearchDocuments || !pQuery || !pQuery.trim())
|
|
1733
|
+
{
|
|
1734
|
+
return [];
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
let tmpResults = [];
|
|
1738
|
+
|
|
1739
|
+
try
|
|
1740
|
+
{
|
|
1741
|
+
let tmpLunrResults = this._LunrIndex.search(pQuery);
|
|
1742
|
+
|
|
1743
|
+
for (let i = 0; i < tmpLunrResults.length; i++)
|
|
1744
|
+
{
|
|
1745
|
+
let tmpRef = tmpLunrResults[i].ref;
|
|
1746
|
+
let tmpScore = tmpLunrResults[i].score;
|
|
1747
|
+
let tmpDoc = this._SearchDocuments[tmpRef];
|
|
1748
|
+
|
|
1749
|
+
if (!tmpDoc)
|
|
1750
|
+
{
|
|
1751
|
+
continue;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
tmpResults.push(
|
|
1755
|
+
{
|
|
1756
|
+
Key: tmpRef,
|
|
1757
|
+
Title: tmpDoc.Title || tmpRef,
|
|
1758
|
+
Group: tmpDoc.Group || '',
|
|
1759
|
+
Module: tmpDoc.Module || '',
|
|
1760
|
+
DocPath: tmpDoc.DocPath || tmpRef,
|
|
1761
|
+
Score: tmpScore
|
|
1762
|
+
});
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
catch (pError)
|
|
1766
|
+
{
|
|
1767
|
+
if (this.log) this.log.warn('InlineDocumentation: Search error: ' + pError);
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
return tmpResults;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
// ================================================================
|
|
1774
|
+
// External link resolution (catalog-based)
|
|
1775
|
+
// ================================================================
|
|
1776
|
+
|
|
1777
|
+
/**
|
|
1778
|
+
* Check if a path is an external reference.
|
|
1779
|
+
*
|
|
1780
|
+
* Paths that started with / in the sidebar are cross-module
|
|
1781
|
+
* references. They get normalized during parsing (leading /
|
|
1782
|
+
* stripped), but they contain 2+ path segments (group/module/).
|
|
1783
|
+
* Simple filenames like README.md are local.
|
|
1784
|
+
*
|
|
1785
|
+
* An ExternalDocBaseURL must be configured for this to return true.
|
|
1786
|
+
*
|
|
1787
|
+
* @param {string} pPath - The normalized document path
|
|
1788
|
+
* @returns {boolean}
|
|
1789
|
+
*/
|
|
1790
|
+
isExternalPath(pPath)
|
|
1791
|
+
{
|
|
1792
|
+
if (!pPath) return false;
|
|
1793
|
+
|
|
1794
|
+
let tmpState = this.pict.AppData.InlineDocumentation;
|
|
1795
|
+
if (!tmpState || !tmpState.ExternalDocBaseURL) return false;
|
|
1796
|
+
|
|
1797
|
+
// Paths with 2+ segments (e.g., pict/pict/, fable/fable/)
|
|
1798
|
+
// are cross-module references. Simple filenames are local.
|
|
1799
|
+
let tmpPath = pPath.replace(/^\.\//, '').replace(/^\//, '');
|
|
1800
|
+
let tmpParts = tmpPath.split('/').filter((p) => p.length > 0);
|
|
1801
|
+
return tmpParts.length >= 2;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/**
|
|
1805
|
+
* Resolve an external path to a full URL.
|
|
1806
|
+
*
|
|
1807
|
+
* @param {string} pPath - The document path
|
|
1808
|
+
* @returns {string|null} The external URL, or null if not external
|
|
1809
|
+
*/
|
|
1810
|
+
resolveExternalURL(pPath)
|
|
1811
|
+
{
|
|
1812
|
+
if (!this.isExternalPath(pPath)) return null;
|
|
1813
|
+
|
|
1814
|
+
let tmpState = this.pict.AppData.InlineDocumentation;
|
|
1815
|
+
let tmpBaseURL = (tmpState && tmpState.ExternalDocBaseURL) || '';
|
|
1816
|
+
if (!tmpBaseURL) return null;
|
|
1817
|
+
|
|
1818
|
+
let tmpPath = pPath.replace(/^\.\//, '').replace(/^\//, '');
|
|
1819
|
+
return tmpBaseURL + tmpPath;
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
/**
|
|
1823
|
+
* After sidebar is loaded, mark items that are external
|
|
1824
|
+
* references with External: true and ExternalURL.
|
|
1825
|
+
*/
|
|
1826
|
+
_markExternalSidebarItems()
|
|
1827
|
+
{
|
|
1828
|
+
let tmpState = this.pict.AppData.InlineDocumentation;
|
|
1829
|
+
if (!tmpState || !tmpState.ExternalDocBaseURL) return;
|
|
1830
|
+
|
|
1831
|
+
let tmpGroups = tmpState.SidebarGroups || [];
|
|
1832
|
+
for (let i = 0; i < tmpGroups.length; i++)
|
|
1833
|
+
{
|
|
1834
|
+
let tmpItems = tmpGroups[i].Items || [];
|
|
1835
|
+
for (let j = 0; j < tmpItems.length; j++)
|
|
1836
|
+
{
|
|
1837
|
+
let tmpItem = tmpItems[j];
|
|
1838
|
+
if (this.isExternalPath(tmpItem.Path))
|
|
1839
|
+
{
|
|
1840
|
+
tmpItem.External = true;
|
|
1841
|
+
tmpItem.ExternalURL = this.resolveExternalURL(tmpItem.Path);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
/**
|
|
1848
|
+
* Extract h2 and h3 headings from the rendered content body.
|
|
1849
|
+
*
|
|
1850
|
+
* Queries #InlineDoc-Content-Body for heading elements, extracts
|
|
1851
|
+
* their text, generates slugified IDs for anchor scrolling, and
|
|
1852
|
+
* stores the results in AppData for the nav outline.
|
|
1853
|
+
*
|
|
1854
|
+
* @returns {Array} Array of { Text, Slug, Level }
|
|
1855
|
+
*/
|
|
1856
|
+
_extractHeadings()
|
|
1857
|
+
{
|
|
1858
|
+
let tmpHeadings = [];
|
|
1859
|
+
|
|
1860
|
+
if (typeof document === 'undefined')
|
|
1861
|
+
{
|
|
1862
|
+
return tmpHeadings;
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
let tmpContentBody = document.getElementById('InlineDoc-Content-Body');
|
|
1866
|
+
if (!tmpContentBody)
|
|
1867
|
+
{
|
|
1868
|
+
return tmpHeadings;
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
let tmpElements = tmpContentBody.querySelectorAll('h2, h3');
|
|
1872
|
+
|
|
1873
|
+
for (let i = 0; i < tmpElements.length; i++)
|
|
1874
|
+
{
|
|
1875
|
+
let tmpElement = tmpElements[i];
|
|
1876
|
+
let tmpText = (tmpElement.textContent || '').trim();
|
|
1877
|
+
let tmpLevel = parseInt(tmpElement.tagName.substring(1), 10);
|
|
1878
|
+
let tmpSlug = tmpText.toLowerCase()
|
|
1879
|
+
.replace(/[^a-z0-9\s-]/g, '')
|
|
1880
|
+
.replace(/\s+/g, '-')
|
|
1881
|
+
.replace(/-+/g, '-');
|
|
1882
|
+
|
|
1883
|
+
// Assign the ID to the heading element if not already set
|
|
1884
|
+
// so scrollIntoView can find it
|
|
1885
|
+
if (!tmpElement.id)
|
|
1886
|
+
{
|
|
1887
|
+
tmpElement.id = tmpSlug;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
tmpHeadings.push({ Text: tmpText, Slug: tmpSlug, Level: tmpLevel });
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
let tmpState = this.pict.AppData.InlineDocumentation;
|
|
1894
|
+
if (tmpState)
|
|
1895
|
+
{
|
|
1896
|
+
tmpState.ActiveDocumentHeadings = tmpHeadings;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
return tmpHeadings;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1618
1902
|
// -- Internal methods --
|
|
1619
1903
|
|
|
1620
1904
|
/**
|