pict-docuserve 0.0.1

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.
Files changed (36) hide show
  1. package/LICENSE +21 -0
  2. package/build-site.js +172 -0
  3. package/css/docuserve.css +73 -0
  4. package/dist/css/docuserve.css +73 -0
  5. package/dist/index.html +32 -0
  6. package/dist/js/pict.compatible.js +7793 -0
  7. package/dist/js/pict.compatible.js.map +1 -0
  8. package/dist/js/pict.compatible.min.js +12 -0
  9. package/dist/js/pict.compatible.min.js.map +1 -0
  10. package/dist/js/pict.js +7792 -0
  11. package/dist/js/pict.js.map +1 -0
  12. package/dist/js/pict.min.js +12 -0
  13. package/dist/js/pict.min.js.map +1 -0
  14. package/dist/pict-docuserve.compatible.js +5148 -0
  15. package/dist/pict-docuserve.compatible.js.map +1 -0
  16. package/dist/pict-docuserve.compatible.min.js +2 -0
  17. package/dist/pict-docuserve.compatible.min.js.map +1 -0
  18. package/dist/pict-docuserve.js +4670 -0
  19. package/dist/pict-docuserve.js.map +1 -0
  20. package/dist/pict-docuserve.min.js +2 -0
  21. package/dist/pict-docuserve.min.js.map +1 -0
  22. package/html/index.html +32 -0
  23. package/package.json +52 -0
  24. package/source/Pict-Application-Docuserve-Configuration.json +15 -0
  25. package/source/Pict-Application-Docuserve.js +246 -0
  26. package/source/cli/Docuserve-CLI-Program.js +16 -0
  27. package/source/cli/Docuserve-CLI-Run.js +3 -0
  28. package/source/cli/commands/Docuserve-Command-Inject.js +127 -0
  29. package/source/cli/commands/Docuserve-Command-Serve.js +135 -0
  30. package/source/providers/Pict-Provider-Docuserve-Documentation.js +1156 -0
  31. package/source/providers/PictRouter-Docuserve-Configuration.json +26 -0
  32. package/source/views/PictView-Docuserve-Content.js +208 -0
  33. package/source/views/PictView-Docuserve-Layout.js +105 -0
  34. package/source/views/PictView-Docuserve-Sidebar.js +362 -0
  35. package/source/views/PictView-Docuserve-Splash.js +264 -0
  36. package/source/views/PictView-Docuserve-TopBar.js +213 -0
@@ -0,0 +1,26 @@
1
+ {
2
+ "ProviderIdentifier": "Pict-Router",
3
+
4
+ "AutoInitialize": true,
5
+ "AutoInitializeOrdinal": 0,
6
+
7
+ "Routes":
8
+ [
9
+ {
10
+ "path": "/Home",
11
+ "template": "{~LV:Pict.PictApplication.showView(`Docuserve-Splash`)~}"
12
+ },
13
+ {
14
+ "path": "/doc/:group/:module",
15
+ "template": "{~LV:Pict.PictApplication.navigateToModule(Record.data.group,Record.data.module)~}"
16
+ },
17
+ {
18
+ "path": "/doc/:group/:module/:path",
19
+ "template": "{~LV:Pict.PictApplication.navigateToModulePath(Record.data.group,Record.data.module,Record.data.path)~}"
20
+ },
21
+ {
22
+ "path": "/page/:docpath",
23
+ "template": "{~LV:Pict.PictApplication.navigateToPage(Record.data.docpath)~}"
24
+ }
25
+ ]
26
+ }
@@ -0,0 +1,208 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "Docuserve-Content",
6
+
7
+ DefaultRenderable: "Docuserve-Content-Display",
8
+ DefaultDestinationAddress: "#Docuserve-Content-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ .docuserve-content {
14
+ padding: 2em 3em;
15
+ max-width: 900px;
16
+ margin: 0 auto;
17
+ }
18
+ .docuserve-content-loading {
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ min-height: 200px;
23
+ color: #999;
24
+ font-size: 1em;
25
+ }
26
+ .docuserve-content h1 {
27
+ font-size: 2em;
28
+ color: #2c3e50;
29
+ border-bottom: 1px solid #eee;
30
+ padding-bottom: 0.3em;
31
+ margin-top: 0;
32
+ }
33
+ .docuserve-content h2 {
34
+ font-size: 1.5em;
35
+ color: #2c3e50;
36
+ border-bottom: 1px solid #f0f0f0;
37
+ padding-bottom: 0.25em;
38
+ margin-top: 1.5em;
39
+ }
40
+ .docuserve-content h3 {
41
+ font-size: 1.25em;
42
+ color: #333;
43
+ margin-top: 1.25em;
44
+ }
45
+ .docuserve-content h4, .docuserve-content h5, .docuserve-content h6 {
46
+ color: #555;
47
+ margin-top: 1em;
48
+ }
49
+ .docuserve-content p {
50
+ line-height: 1.7;
51
+ color: #444;
52
+ margin: 0.75em 0;
53
+ }
54
+ .docuserve-content a {
55
+ color: #42b983;
56
+ text-decoration: none;
57
+ }
58
+ .docuserve-content a:hover {
59
+ text-decoration: underline;
60
+ }
61
+ .docuserve-content pre {
62
+ background: #2c3e50;
63
+ color: #ecf0f1;
64
+ padding: 1.25em;
65
+ border-radius: 6px;
66
+ overflow-x: auto;
67
+ line-height: 1.5;
68
+ font-size: 0.9em;
69
+ }
70
+ .docuserve-content code {
71
+ background: #f4f4f5;
72
+ padding: 0.15em 0.4em;
73
+ border-radius: 3px;
74
+ font-size: 0.9em;
75
+ color: #e74c3c;
76
+ }
77
+ .docuserve-content pre code {
78
+ background: none;
79
+ padding: 0;
80
+ color: inherit;
81
+ font-size: inherit;
82
+ }
83
+ .docuserve-content blockquote {
84
+ border-left: 4px solid #42b983;
85
+ margin: 1em 0;
86
+ padding: 0.5em 1em;
87
+ background: #f9f9f9;
88
+ color: #666;
89
+ }
90
+ .docuserve-content blockquote p {
91
+ margin: 0.25em 0;
92
+ }
93
+ .docuserve-content ul, .docuserve-content ol {
94
+ padding-left: 2em;
95
+ line-height: 1.8;
96
+ }
97
+ .docuserve-content li {
98
+ margin: 0.25em 0;
99
+ color: #444;
100
+ }
101
+ .docuserve-content hr {
102
+ border: none;
103
+ border-top: 1px solid #eee;
104
+ margin: 2em 0;
105
+ }
106
+ .docuserve-content table {
107
+ width: 100%;
108
+ border-collapse: collapse;
109
+ margin: 1em 0;
110
+ }
111
+ .docuserve-content table th {
112
+ background: #f5f7fa;
113
+ border: 1px solid #e0e0e0;
114
+ padding: 0.6em 0.8em;
115
+ text-align: left;
116
+ font-weight: 600;
117
+ color: #2c3e50;
118
+ }
119
+ .docuserve-content table td {
120
+ border: 1px solid #e0e0e0;
121
+ padding: 0.5em 0.8em;
122
+ color: #444;
123
+ }
124
+ .docuserve-content table tr:nth-child(even) {
125
+ background: #fafafa;
126
+ }
127
+ .docuserve-content img {
128
+ max-width: 100%;
129
+ height: auto;
130
+ }
131
+ .docuserve-not-found {
132
+ text-align: center;
133
+ padding: 3em 1em;
134
+ color: #666;
135
+ }
136
+ .docuserve-not-found h2 {
137
+ color: #999;
138
+ font-size: 1.5em;
139
+ border-bottom: none;
140
+ }
141
+ .docuserve-not-found code {
142
+ background: #f4f4f5;
143
+ padding: 0.15em 0.4em;
144
+ border-radius: 3px;
145
+ font-size: 0.9em;
146
+ color: #e74c3c;
147
+ }
148
+ `,
149
+
150
+ Templates:
151
+ [
152
+ {
153
+ Hash: "Docuserve-Content-Template",
154
+ Template: /*html*/`
155
+ <div class="docuserve-content" id="Docuserve-Content-Body">
156
+ <div class="docuserve-content-loading">Loading documentation...</div>
157
+ </div>
158
+ `
159
+ }
160
+ ],
161
+
162
+ Renderables:
163
+ [
164
+ {
165
+ RenderableHash: "Docuserve-Content-Display",
166
+ TemplateHash: "Docuserve-Content-Template",
167
+ DestinationAddress: "#Docuserve-Content-Container",
168
+ RenderMethod: "replace"
169
+ }
170
+ ]
171
+ };
172
+
173
+ class DocuserveContentView extends libPictView
174
+ {
175
+ constructor(pFable, pOptions, pServiceHash)
176
+ {
177
+ super(pFable, pOptions, pServiceHash);
178
+ }
179
+
180
+ /**
181
+ * Display parsed HTML content in the content area.
182
+ *
183
+ * @param {string} pHTMLContent - The HTML to display
184
+ */
185
+ displayContent(pHTMLContent)
186
+ {
187
+ this.pict.ContentAssignment.assignContent('#Docuserve-Content-Body', pHTMLContent);
188
+
189
+ // Scroll to top of content area
190
+ let tmpContentContainer = document.getElementById('Docuserve-Content-Container');
191
+ if (tmpContentContainer)
192
+ {
193
+ tmpContentContainer.scrollTop = 0;
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Show a loading indicator.
199
+ */
200
+ showLoading()
201
+ {
202
+ this.pict.ContentAssignment.assignContent('#Docuserve-Content-Body', '<div class="docuserve-content-loading">Loading documentation...</div>');
203
+ }
204
+ }
205
+
206
+ module.exports = DocuserveContentView;
207
+
208
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,105 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "Docuserve-Layout",
6
+
7
+ DefaultRenderable: "Docuserve-Layout-Shell",
8
+ DefaultDestinationAddress: "#Docuserve-Application-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ #Docuserve-Application-Container {
14
+ display: flex;
15
+ flex-direction: column;
16
+ height: 100vh;
17
+ overflow: hidden;
18
+ }
19
+ #Docuserve-TopBar-Container {
20
+ flex-shrink: 0;
21
+ }
22
+ .docuserve-body {
23
+ display: flex;
24
+ flex: 1;
25
+ min-height: 0;
26
+ }
27
+ #Docuserve-Sidebar-Container {
28
+ flex-shrink: 0;
29
+ width: 280px;
30
+ overflow-y: auto;
31
+ }
32
+ #Docuserve-Content-Container {
33
+ flex: 1;
34
+ min-width: 0;
35
+ overflow-y: auto;
36
+ }
37
+ `,
38
+
39
+ Templates:
40
+ [
41
+ {
42
+ Hash: "Docuserve-Layout-Shell-Template",
43
+ Template: /*html*/`
44
+ <div id="Docuserve-TopBar-Container"></div>
45
+ <div class="docuserve-body">
46
+ <div id="Docuserve-Sidebar-Container"></div>
47
+ <div id="Docuserve-Content-Container"></div>
48
+ </div>
49
+ `
50
+ }
51
+ ],
52
+
53
+ Renderables:
54
+ [
55
+ {
56
+ RenderableHash: "Docuserve-Layout-Shell",
57
+ TemplateHash: "Docuserve-Layout-Shell-Template",
58
+ DestinationAddress: "#Docuserve-Application-Container",
59
+ RenderMethod: "replace"
60
+ }
61
+ ]
62
+ };
63
+
64
+ class DocuserveLayoutView extends libPictView
65
+ {
66
+ constructor(pFable, pOptions, pServiceHash)
67
+ {
68
+ super(pFable, pOptions, pServiceHash);
69
+ }
70
+
71
+ onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
72
+ {
73
+ // After the layout shell is rendered, render the child views into their containers
74
+ this.pict.views['Docuserve-TopBar'].render();
75
+ this.pict.views['Docuserve-Sidebar'].render();
76
+
77
+ // Show the splash screen initially
78
+ this.pict.views['Docuserve-Splash'].render();
79
+
80
+ // Inject all view CSS into the PICT-CSS style element
81
+ this.pict.CSSMap.injectCSS();
82
+
83
+ // Resolve the current hash on initial load
84
+ this.pict.PictApplication.resolveHash();
85
+
86
+ // Listen for hash changes so that plain <a href="#/..."> links trigger
87
+ // navigation. This covers sidebar links, splash action buttons,
88
+ // in-content links, and browser back/forward navigation.
89
+ if (!this._HashChangeListenerBound)
90
+ {
91
+ this._HashChangeListenerBound = true;
92
+ let tmpSelf = this;
93
+ window.addEventListener('hashchange', () =>
94
+ {
95
+ tmpSelf.pict.PictApplication.resolveHash();
96
+ });
97
+ }
98
+
99
+ return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
100
+ }
101
+ }
102
+
103
+ module.exports = DocuserveLayoutView;
104
+
105
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,362 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "Docuserve-Sidebar",
6
+
7
+ DefaultRenderable: "Docuserve-Sidebar-Content",
8
+ DefaultDestinationAddress: "#Docuserve-Sidebar-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ .docuserve-sidebar {
14
+ background-color: #f8f9fa;
15
+ border-right: 1px solid #e0e0e0;
16
+ padding: 1em 0;
17
+ height: 100%;
18
+ position: relative;
19
+ }
20
+ .docuserve-sidebar-close {
21
+ position: absolute;
22
+ top: 0.5em;
23
+ right: 0.5em;
24
+ background: none;
25
+ border: none;
26
+ color: #999;
27
+ font-size: 1.2em;
28
+ cursor: pointer;
29
+ padding: 0.2em 0.4em;
30
+ line-height: 1;
31
+ }
32
+ .docuserve-sidebar-close:hover {
33
+ color: #42b983;
34
+ }
35
+ .docuserve-sidebar-search {
36
+ padding: 0 1em 1em 1em;
37
+ border-bottom: 1px solid #e9ecef;
38
+ margin-bottom: 0.5em;
39
+ }
40
+ .docuserve-sidebar-search input {
41
+ width: 100%;
42
+ padding: 0.5em 0.75em;
43
+ border: 1px solid #ddd;
44
+ border-radius: 4px;
45
+ font-size: 0.85em;
46
+ outline: none;
47
+ box-sizing: border-box;
48
+ }
49
+ .docuserve-sidebar-search input:focus {
50
+ border-color: #42b983;
51
+ }
52
+ .docuserve-sidebar-home {
53
+ padding: 0.5em 1.25em;
54
+ font-weight: 600;
55
+ font-size: 0.85em;
56
+ text-transform: uppercase;
57
+ letter-spacing: 0.03em;
58
+ }
59
+ .docuserve-sidebar-home a {
60
+ color: #666;
61
+ text-decoration: none;
62
+ cursor: pointer;
63
+ user-select: none;
64
+ }
65
+ .docuserve-sidebar-home a:hover {
66
+ color: #42b983;
67
+ }
68
+ .docuserve-sidebar-group {
69
+ margin-top: 0.25em;
70
+ }
71
+ .docuserve-sidebar-group-title {
72
+ display: block;
73
+ padding: 0.5em 1.25em;
74
+ font-weight: 600;
75
+ font-size: 0.85em;
76
+ color: #666;
77
+ text-decoration: none;
78
+ text-transform: uppercase;
79
+ letter-spacing: 0.03em;
80
+ cursor: pointer;
81
+ user-select: none;
82
+ }
83
+ .docuserve-sidebar-group-title:hover {
84
+ color: #42b983;
85
+ }
86
+ .docuserve-sidebar-modules {
87
+ list-style: none;
88
+ margin: 0;
89
+ padding: 0;
90
+ }
91
+ .docuserve-sidebar-modules li {
92
+ padding: 0;
93
+ }
94
+ .docuserve-sidebar-modules a {
95
+ display: block;
96
+ padding: 0.3em 1.25em 0.3em 2em;
97
+ color: #555;
98
+ text-decoration: none;
99
+ font-size: 0.85em;
100
+ transition: background-color 0.1s, color 0.1s;
101
+ cursor: pointer;
102
+ }
103
+ .docuserve-sidebar-modules a:hover {
104
+ background-color: #e9ecef;
105
+ color: #42b983;
106
+ }
107
+ .docuserve-sidebar-modules a.active {
108
+ color: #42b983;
109
+ font-weight: 600;
110
+ background-color: #e8f5e9;
111
+ }
112
+ .docuserve-sidebar-modules .no-docs {
113
+ display: block;
114
+ padding: 0.3em 1.25em 0.3em 2em;
115
+ color: #bbb;
116
+ font-size: 0.85em;
117
+ }
118
+ .docuserve-sidebar-module-nav {
119
+ border-top: 1px solid #e9ecef;
120
+ margin-top: 0.5em;
121
+ padding-top: 0.5em;
122
+ }
123
+ .docuserve-sidebar-module-nav-section {
124
+ padding: 0.4em 1.25em;
125
+ font-weight: 600;
126
+ font-size: 0.8em;
127
+ color: #888;
128
+ text-transform: uppercase;
129
+ letter-spacing: 0.02em;
130
+ }
131
+ .docuserve-sidebar-module-nav a {
132
+ display: block;
133
+ padding: 0.25em 1.25em 0.25em 2.25em;
134
+ color: #555;
135
+ text-decoration: none;
136
+ font-size: 0.82em;
137
+ transition: background-color 0.1s, color 0.1s;
138
+ cursor: pointer;
139
+ }
140
+ .docuserve-sidebar-module-nav a:hover {
141
+ background-color: #e9ecef;
142
+ color: #42b983;
143
+ }
144
+ `,
145
+
146
+ Templates:
147
+ [
148
+ {
149
+ Hash: "Docuserve-Sidebar-Template",
150
+ Template: /*html*/`
151
+ <div class="docuserve-sidebar">
152
+ <button class="docuserve-sidebar-close" onclick="{~P~}.views['Docuserve-Sidebar'].toggleSidebar()">&times;</button>
153
+ <div class="docuserve-sidebar-home">
154
+ <a onclick="{~P~}.PictApplication.navigateTo('/Home')">Home</a>
155
+ </div>
156
+ <div id="Docuserve-Sidebar-Groups"></div>
157
+ <div id="Docuserve-Sidebar-ModuleNav"></div>
158
+ </div>
159
+ `
160
+ }
161
+ ],
162
+
163
+ Renderables:
164
+ [
165
+ {
166
+ RenderableHash: "Docuserve-Sidebar-Content",
167
+ TemplateHash: "Docuserve-Sidebar-Template",
168
+ DestinationAddress: "#Docuserve-Sidebar-Container",
169
+ RenderMethod: "replace"
170
+ }
171
+ ]
172
+ };
173
+
174
+ class DocusserveSidebarView extends libPictView
175
+ {
176
+ constructor(pFable, pOptions, pServiceHash)
177
+ {
178
+ super(pFable, pOptions, pServiceHash);
179
+ }
180
+
181
+ onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
182
+ {
183
+ this.renderSidebarGroups();
184
+
185
+ return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
186
+ }
187
+
188
+ /**
189
+ * Render the sidebar group navigation from catalog data.
190
+ */
191
+ renderSidebarGroups()
192
+ {
193
+ let tmpGroups = this.pict.AppData.Docuserve.SidebarGroups;
194
+
195
+ if (!tmpGroups || tmpGroups.length < 1)
196
+ {
197
+ this.pict.ContentAssignment.assignContent('#Docuserve-Sidebar-Groups', '<p style="padding: 1em; color: #999; font-size: 0.85em;">Loading catalog...</p>');
198
+ return;
199
+ }
200
+
201
+ let tmpHTML = '';
202
+
203
+ for (let i = 0; i < tmpGroups.length; i++)
204
+ {
205
+ let tmpGroup = tmpGroups[i];
206
+ tmpHTML += '<div class="docuserve-sidebar-group">';
207
+
208
+ // Determine the route for the group title: use the group's own route,
209
+ // or fall back to the first module with docs.
210
+ let tmpGroupRoute = tmpGroup.Route || '';
211
+ if (!tmpGroupRoute)
212
+ {
213
+ for (let k = 0; k < tmpGroup.Modules.length; k++)
214
+ {
215
+ if (tmpGroup.Modules[k].HasDocs && tmpGroup.Modules[k].Route)
216
+ {
217
+ tmpGroupRoute = tmpGroup.Modules[k].Route;
218
+ break;
219
+ }
220
+ }
221
+ }
222
+
223
+ if (tmpGroupRoute)
224
+ {
225
+ tmpHTML += '<a class="docuserve-sidebar-group-title" href="' + tmpGroupRoute + '">' + this.escapeHTML(tmpGroup.Name) + '</a>';
226
+ }
227
+ else
228
+ {
229
+ tmpHTML += '<div class="docuserve-sidebar-group-title">' + this.escapeHTML(tmpGroup.Name) + '</div>';
230
+ }
231
+ tmpHTML += '<ul class="docuserve-sidebar-modules">';
232
+
233
+ for (let j = 0; j < tmpGroup.Modules.length; j++)
234
+ {
235
+ let tmpModule = tmpGroup.Modules[j];
236
+ if (tmpModule.HasDocs)
237
+ {
238
+ let tmpActiveClass = '';
239
+ if (this.pict.AppData.Docuserve.CurrentGroup === tmpModule.Group && this.pict.AppData.Docuserve.CurrentModule === tmpModule.Name)
240
+ {
241
+ tmpActiveClass = ' class="active"';
242
+ }
243
+ tmpHTML += '<li><a' + tmpActiveClass + ' href="' + tmpModule.Route + '">' + this.escapeHTML(tmpModule.Name) + '</a></li>';
244
+ }
245
+ else
246
+ {
247
+ tmpHTML += '<li><span class="no-docs">' + this.escapeHTML(tmpModule.Name) + '</span></li>';
248
+ }
249
+ }
250
+
251
+ tmpHTML += '</ul>';
252
+ tmpHTML += '</div>';
253
+ }
254
+
255
+ this.pict.ContentAssignment.assignContent('#Docuserve-Sidebar-Groups', tmpHTML);
256
+ }
257
+
258
+ /**
259
+ * Render module-specific sub-navigation when viewing a module.
260
+ *
261
+ * @param {string} pGroup - The group key
262
+ * @param {string} pModule - The module name
263
+ */
264
+ renderModuleNav(pGroup, pModule)
265
+ {
266
+ let tmpDocProvider = this.pict.providers['Docuserve-Documentation'];
267
+ if (!tmpDocProvider)
268
+ {
269
+ return;
270
+ }
271
+
272
+ let tmpSidebar = tmpDocProvider.getModuleSidebar(pGroup, pModule);
273
+ if (!tmpSidebar)
274
+ {
275
+ this.pict.ContentAssignment.assignContent('#Docuserve-Sidebar-ModuleNav', '');
276
+ return;
277
+ }
278
+
279
+ let tmpRoutePrefix = '#/doc/' + pGroup + '/' + pModule + '/';
280
+ let tmpHTML = '<div class="docuserve-sidebar-module-nav">';
281
+
282
+ for (let i = 0; i < tmpSidebar.length; i++)
283
+ {
284
+ let tmpEntry = tmpSidebar[i];
285
+
286
+ if (tmpEntry.Children)
287
+ {
288
+ tmpHTML += '<div class="docuserve-sidebar-module-nav-section">' + this.escapeHTML(tmpEntry.Title) + '</div>';
289
+
290
+ for (let j = 0; j < tmpEntry.Children.length; j++)
291
+ {
292
+ let tmpChild = tmpEntry.Children[j];
293
+ if (tmpChild.Path)
294
+ {
295
+ tmpHTML += '<a href="' + tmpRoutePrefix + tmpChild.Path + '">' + this.escapeHTML(tmpChild.Title) + '</a>';
296
+ }
297
+ }
298
+ }
299
+ else if (tmpEntry.Path)
300
+ {
301
+ tmpHTML += '<a href="' + tmpRoutePrefix + tmpEntry.Path + '">' + this.escapeHTML(tmpEntry.Title) + '</a>';
302
+ }
303
+ }
304
+
305
+ tmpHTML += '</div>';
306
+
307
+ this.pict.ContentAssignment.assignContent('#Docuserve-Sidebar-ModuleNav', tmpHTML);
308
+ }
309
+
310
+ /**
311
+ * Toggle the sidebar visibility and update the top bar hamburger button.
312
+ */
313
+ toggleSidebar()
314
+ {
315
+ this.pict.AppData.Docuserve.SidebarVisible = !this.pict.AppData.Docuserve.SidebarVisible;
316
+
317
+ let tmpContainer = document.getElementById('Docuserve-Sidebar-Container');
318
+ let tmpToggle = document.getElementById('Docuserve-TopBar-Toggle');
319
+
320
+ if (this.pict.AppData.Docuserve.SidebarVisible)
321
+ {
322
+ if (tmpContainer) tmpContainer.style.display = '';
323
+ if (tmpToggle) tmpToggle.style.display = 'none';
324
+ }
325
+ else
326
+ {
327
+ if (tmpContainer) tmpContainer.style.display = 'none';
328
+ if (tmpToggle) tmpToggle.style.display = 'inline-block';
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Clear the module-specific sub-navigation.
334
+ */
335
+ clearModuleNav()
336
+ {
337
+ this.pict.ContentAssignment.assignContent('#Docuserve-Sidebar-ModuleNav', '');
338
+ }
339
+
340
+ /**
341
+ * Escape HTML special characters.
342
+ *
343
+ * @param {string} pText - The text to escape
344
+ * @returns {string} The escaped text
345
+ */
346
+ escapeHTML(pText)
347
+ {
348
+ if (!pText)
349
+ {
350
+ return '';
351
+ }
352
+ return pText
353
+ .replace(/&/g, '&amp;')
354
+ .replace(/</g, '&lt;')
355
+ .replace(/>/g, '&gt;')
356
+ .replace(/"/g, '&quot;');
357
+ }
358
+ }
359
+
360
+ module.exports = DocusserveSidebarView;
361
+
362
+ module.exports.default_configuration = _ViewConfiguration;