hdoc-tools 0.62.4 → 0.63.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.
Files changed (73) hide show
  1. package/editor/dist/assets/{index-BtxvGZHW.js → index-Dknn5g5A.js} +5 -4
  2. package/editor/dist/index.html +13 -13
  3. package/hdoc-build.js +5 -3
  4. package/hdoc-content-routes.js +136 -4
  5. package/hdoc-serve.js +26 -3
  6. package/hdoc-validate-interbook.js +8 -0
  7. package/hdoc-validate.js +92 -35
  8. package/package.json +1 -1
  9. package/ui/css/theme-default/styles/base.css +86 -21
  10. package/ui/css/theme-default/styles/components/api-doc.css +6 -3
  11. package/ui/css/theme-default/styles/components/content.css +140 -39
  12. package/ui/css/theme-default/styles/components/custom-block.css +1 -1
  13. package/ui/css/theme-default/styles/components/htl-doc.css +243 -64
  14. package/ui/css/theme-default/styles/components/htl-library.css +152 -0
  15. package/ui/css/theme-default/styles/components/htl-search.css +267 -0
  16. package/ui/css/theme-default/styles/components/sidebar.css +59 -16
  17. package/ui/css/theme-default/styles/fonts.css +17 -3
  18. package/ui/css/theme-default/styles/htldoc.layouts.css +756 -87
  19. package/ui/css/theme-default/styles/vars.css +40 -35
  20. package/ui/favicon.svg +64 -0
  21. package/ui/images/hornbill-logo-full-reversed.svg +92 -0
  22. package/ui/images/hornbill-logo-full.svg +92 -0
  23. package/ui/images/hug_library.jpg +0 -0
  24. package/ui/images/mcp-catalog.svg +9 -0
  25. package/ui/images/products/hornbill-square.svg +1 -0
  26. package/ui/index.html +1106 -342
  27. package/ui/js/bootstrap.js +89 -0
  28. package/ui/js/doc.hornbill.js +3156 -751
  29. package/ui/js/hb.vue.js +121 -0
  30. package/ui/js/highlightjs/highlight.pack.js +1513 -2
  31. package/ui/js/highlightjs/styles/vs2015-accessible.css +141 -0
  32. package/ui/js/highlightjs-badge.js +41 -58
  33. package/ui/js/mermaid.min.js +1447 -1295
  34. package/ui/js/webcomponents/hdocApprove.js +115 -0
  35. package/ui/js/highlightjs/styles/brown-paper.css +0 -64
  36. package/ui/js/highlightjs/styles/brown-papersq.png +0 -0
  37. package/ui/js/highlightjs/styles/codepen-embed.css +0 -60
  38. package/ui/js/highlightjs/styles/color-brewer.css +0 -71
  39. package/ui/js/highlightjs/styles/darcula.css +0 -77
  40. package/ui/js/highlightjs/styles/dark.css +0 -63
  41. package/ui/js/highlightjs/styles/darkula.css +0 -6
  42. package/ui/js/highlightjs/styles/default.css +0 -99
  43. package/ui/js/highlightjs/styles/dracula.css +0 -76
  44. package/ui/js/highlightjs/styles/far.css +0 -71
  45. package/ui/js/highlightjs/styles/foundation.css +0 -88
  46. package/ui/js/highlightjs/styles/github-gist.css +0 -71
  47. package/ui/js/highlightjs/styles/github-mm.css +0 -71
  48. package/ui/js/highlightjs/styles/github.css +0 -99
  49. package/ui/js/highlightjs/styles/googlecode.css +0 -89
  50. package/ui/js/highlightjs/styles/grayscale.css +0 -101
  51. package/ui/js/highlightjs/styles/idea.css +0 -97
  52. package/ui/js/highlightjs/styles/ir-black.css +0 -73
  53. package/ui/js/highlightjs/styles/kavadocs.css +0 -71
  54. package/ui/js/highlightjs/styles/kavadocsdark.css +0 -120
  55. package/ui/js/highlightjs/styles/kimbie.dark.css +0 -74
  56. package/ui/js/highlightjs/styles/kimbie.light.css +0 -74
  57. package/ui/js/highlightjs/styles/magula.css +0 -70
  58. package/ui/js/highlightjs/styles/mono-blue.css +0 -59
  59. package/ui/js/highlightjs/styles/monokai-sublime.css +0 -83
  60. package/ui/js/highlightjs/styles/monokai.css +0 -70
  61. package/ui/js/highlightjs/styles/obsidian.css +0 -88
  62. package/ui/js/highlightjs/styles/paraiso-dark.css +0 -72
  63. package/ui/js/highlightjs/styles/paraiso-light.css +0 -72
  64. package/ui/js/highlightjs/styles/railscasts.css +0 -106
  65. package/ui/js/highlightjs/styles/rainbow.css +0 -85
  66. package/ui/js/highlightjs/styles/solarized-dark.css +0 -84
  67. package/ui/js/highlightjs/styles/solarized-light.css +0 -84
  68. package/ui/js/highlightjs/styles/sunburst.css +0 -102
  69. package/ui/js/highlightjs/styles/twilight.css +0 -97
  70. package/ui/js/highlightjs/styles/vs.css +0 -68
  71. package/ui/js/highlightjs/styles/vs2015.css +0 -117
  72. package/ui/js/highlightjs/styles/xcode.css +0 -104
  73. package/ui/js/highlightjs/styles/zenburn.css +0 -80
@@ -0,0 +1,267 @@
1
+ .LibrarySearch .searchResultsContainer
2
+ {
3
+ max-width: 1080px;
4
+ }
5
+
6
+ .LibrarySearch .searchResults > li .title
7
+ {
8
+ align-items: center;
9
+ color:var(--htl-c-blue);
10
+ cursor:pointer;
11
+ }
12
+
13
+ /* The results list stays mounted while a new query is in flight (it used to be swapped for the
14
+ skeleton, which destroyed and rebuilt all 300 rows per search). Dim it so the state is obvious,
15
+ and stop clicks landing on results that are about to be replaced. aria-busy is set alongside. */
16
+ .LibrarySearch .searchResults.is-searching,
17
+ .LibrarySearch h3.is-searching
18
+ {
19
+ opacity: 0.55;
20
+ pointer-events: none;
21
+ }
22
+
23
+ /* The filter sidebar dims too - its counts belong to the previous response - but keeps
24
+ pointer events: choosing another filter mid-flight is valid (the in-flight request is
25
+ superseded), and the close button must stay usable on narrow viewports. */
26
+ .LibrarySearch .DocSidebar.is-searching
27
+ {
28
+ opacity: 0.55;
29
+ }
30
+
31
+ /* Always reserve the scrollbar's width. The panel is overflow-auto, so the bar appears
32
+ only when the facet lists outgrow the viewport - and every filter change alters those
33
+ lists, so the bar popped in and out, shifting the right-aligned count pills sideways
34
+ by its width between one response and the next. Browsers with overlay scrollbars
35
+ (which take no layout space) treat this as a no-op. */
36
+ .LibrarySearch .DocSidebar
37
+ {
38
+ scrollbar-gutter: stable;
39
+ }
40
+
41
+ /* Skip layout and paint for off-screen rows. 300 results are rendered at once and the server
42
+ caps there (maximum_results_returned in doc_search.cpp), so this is the cheapest way to stop
43
+ paying for the ~290 nobody is looking at: measured 102-120ms -> 20-44ms per full render.
44
+ - "auto", never "hidden": find-in-page and assistive tech activate auto subtrees, so off-screen
45
+ result text stays findable and readable.
46
+ - contain-intrinsic-size is a CONTENT-box estimate. Rows average 195px including their p-3
47
+ padding; feeding 195 in overshoots the scroll height by ~14%. The "auto" keyword makes each
48
+ row remember its real size once rendered, so the estimate only governs unvisited rows.
49
+ Scoped to .searchResultsList so the 8 skeleton rows are unaffected. */
50
+ .LibrarySearch .searchResultsList > li
51
+ {
52
+ content-visibility: auto;
53
+ contain-intrinsic-size: auto 160px;
54
+ }
55
+
56
+ /* Dark mode: Lighter blue for search result titles (WCAG AAA 7:1 on dark bg) */
57
+ .dark .LibrarySearch .searchResults > li .title
58
+ {
59
+ color: var(--htl-c-blue-light);
60
+ }
61
+
62
+ /* Dark mode: Lighter green for search result URLs (WCAG AAA 7:1 on dark bg) */
63
+ .dark .LibrarySearch .searchResults .text-success
64
+ {
65
+ color: var(--htl-c-green-light) !important;
66
+ }
67
+
68
+ /* Search result keyword highlights */
69
+ .LibrarySearch .searchResults mark,
70
+ .LibrarySearch .searchResults b
71
+ {
72
+ background-color: #fff3cd;
73
+ color: #000000;
74
+ padding: 0.1em 0.2em;
75
+ border-radius: 4px;
76
+ }
77
+
78
+ /* Dark mode: Softer highlight for keywords */
79
+ .dark .LibrarySearch .searchResults mark,
80
+ .dark .LibrarySearch .searchResults b
81
+ {
82
+ background-color: #5a4a00;
83
+ color: #ffffff;
84
+ }
85
+
86
+ /* Search channel badges - flags whether a result was found by keyword (FTS5),
87
+ semantic (vector) search, or both. Rendered inline after the result title. */
88
+ .LibrarySearch .searchResults .search-match-badge
89
+ {
90
+ display: inline-block;
91
+ margin-left: 0.5em;
92
+ padding: 0.1em 0.55em;
93
+ border-radius: 999px;
94
+ font-size: 0.62em;
95
+ font-weight: 600;
96
+ letter-spacing: 0.03em;
97
+ text-transform: uppercase;
98
+ vertical-align: middle;
99
+ white-space: nowrap;
100
+ cursor: default;
101
+ }
102
+
103
+ .LibrarySearch .searchResults .search-match-keyword
104
+ {
105
+ background-color: #eef1f4;
106
+ color: #55606b;
107
+ }
108
+
109
+ .LibrarySearch .searchResults .search-match-semantic
110
+ {
111
+ background-color: #ede7f8;
112
+ color: #5e35b1;
113
+ }
114
+
115
+ .LibrarySearch .searchResults .search-match-both
116
+ {
117
+ background-color: #e3f0fb;
118
+ color: #1565c0;
119
+ }
120
+
121
+ .dark .LibrarySearch .searchResults .search-match-keyword
122
+ {
123
+ background-color: #3a4148;
124
+ color: #b8c1ca;
125
+ }
126
+
127
+ .dark .LibrarySearch .searchResults .search-match-semantic
128
+ {
129
+ background-color: #45355e;
130
+ color: #cbb5f4;
131
+ }
132
+
133
+ .dark .LibrarySearch .searchResults .search-match-both
134
+ {
135
+ background-color: #2c4361;
136
+ color: #a9cdf3;
137
+ }
138
+
139
+ .LibrarySearch .searchFilterProducts .form-check .form-check-input
140
+ {
141
+ margin-top: 0.18rem;
142
+ }
143
+
144
+ /* Vary skeleton widths for more natural appearance */
145
+ .LibrarySearch .searchResults > li:nth-child(1) .HTL-skeleton-text-100:first-child { width: 65%; }
146
+ .LibrarySearch .searchResults > li:nth-child(1) .HTL-skeleton-text-100:last-child { width: 85%; }
147
+
148
+ .LibrarySearch .searchResults > li:nth-child(2) .HTL-skeleton-text-100:first-child { width: 45%; }
149
+ .LibrarySearch .searchResults > li:nth-child(2) .HTL-skeleton-text-100:last-child { width: 70%; }
150
+
151
+ .LibrarySearch .searchResults > li:nth-child(3) .HTL-skeleton-text-100:first-child { width: 80%; }
152
+ .LibrarySearch .searchResults > li:nth-child(3) .HTL-skeleton-text-100:last-child { width: 55%; }
153
+
154
+ .LibrarySearch .searchResults > li:nth-child(4) .HTL-skeleton-text-100:first-child { width: 55%; }
155
+ .LibrarySearch .searchResults > li:nth-child(4) .HTL-skeleton-text-100:last-child { width: 90%; }
156
+
157
+ .LibrarySearch .searchResults > li:nth-child(5) .HTL-skeleton-text-100:first-child { width: 70%; }
158
+ .LibrarySearch .searchResults > li:nth-child(5) .HTL-skeleton-text-100:last-child { width: 60%; }
159
+
160
+ .LibrarySearch .searchResults > li:nth-child(6) .HTL-skeleton-text-100:first-child { width: 40%; }
161
+ .LibrarySearch .searchResults > li:nth-child(6) .HTL-skeleton-text-100:last-child { width: 75%; }
162
+
163
+ .LibrarySearch .searchResults > li:nth-child(7) .HTL-skeleton-text-100:first-child { width: 60%; }
164
+ .LibrarySearch .searchResults > li:nth-child(7) .HTL-skeleton-text-100:last-child { width: 50%; }
165
+
166
+ .LibrarySearch .searchResults > li:nth-child(8) .HTL-skeleton-text-100:first-child { width: 75%; }
167
+ .LibrarySearch .searchResults > li:nth-child(8) .HTL-skeleton-text-100:last-child { width: 65%; }
168
+
169
+
170
+ /*--
171
+ Search filter rows (Information type, Books, Products).
172
+
173
+ The count badge was floated right, which drops onto its own line as soon as the
174
+ number is wide enough - three digits was enough ("API reference 140"), leaving the
175
+ count stranded above the next option. Books and Products carry the same latent bug
176
+ and are fixed by the same rule; they only looked fine because their counts happened
177
+ to be single digits.
178
+
179
+ Flex row instead: the label takes the slack and truncates, the badge keeps its
180
+ natural width and cannot wrap. The width:85% inline style on the label wrapper needs
181
+ !important to be overridden. --*/
182
+ .searchFilterProducts .form-check {
183
+ display: flex;
184
+ align-items: center;
185
+ gap: 0.5rem;
186
+ /*-- bootstrap reserves 1.5em here for the absolutely-positioned input. In a flex
187
+ row the input sits in normal flow, so that padding is dead space that indents
188
+ every option past its own section heading --*/
189
+ padding-left: 0;
190
+ }
191
+
192
+ .searchFilterProducts .form-check .form-check-input {
193
+ flex: 0 0 auto;
194
+ margin-top: 0;
195
+ margin-left: 0;
196
+ }
197
+
198
+ .searchFilterProducts .form-check > div {
199
+ flex: 1 1 auto;
200
+ min-width: 0;
201
+ width: auto !important;
202
+ }
203
+
204
+ .searchFilterProducts .form-check label {
205
+ min-width: 0;
206
+ }
207
+
208
+ .searchFilterProducts .form-check .badge {
209
+ flex: 0 0 auto;
210
+ margin-left: auto;
211
+ float: none !important;
212
+ }
213
+
214
+ /*--
215
+ Search filter sidebar: width and mobile access.
216
+
217
+ Scoped to .LibrarySearch so the book-page navigation sidebar, which shares the
218
+ .DocSidebar class, keeps its own behaviour.
219
+
220
+ WIDTH: sidebar.css widens .DocSidebar to 420px only at 1720px, so between 1020 and
221
+ 1719 the filter list is squeezed into 320px and long book titles truncate. Filters
222
+ are the point of this view, so they get the wider treatment for the whole range in
223
+ which the sidebar is docked - 1020px, the same breakpoint at which sidebar.css stops
224
+ showing it inline and it becomes the slide-in panel. There is deliberately no middle
225
+ width: an intermediate step only moves the moment the titles start truncating rather
226
+ than removing it, which is what a 1400px threshold did. At the 1020px floor this
227
+ still leaves 600px for results.
228
+
229
+ MOBILE: sidebar.css hides .LibrarySearch .DocSidebar below 1020px, and unlike a book
230
+ page this view has no burger, so the filters were simply unreachable - the panel is
231
+ styled to slide in (.DocSidebar.open) but nothing here could open it. The Filters
232
+ button below does, and this re-enables display for the open state. --*/
233
+ @media (min-width: 1020px) {
234
+ .LibrarySearch .DocSidebar {
235
+ min-width: 420px;
236
+ max-width: 420px;
237
+ }
238
+ }
239
+
240
+ @media (max-width: 1019px) {
241
+ .LibrarySearch .DocSidebar.open {
242
+ display: block;
243
+ }
244
+ }
245
+
246
+ /*-- only offered where the sidebar is hidden --*/
247
+ .search-filter-btn {
248
+ display: none;
249
+ }
250
+
251
+ @media (max-width: 1019px) {
252
+ .search-filter-btn {
253
+ display: inline-flex;
254
+ align-items: center;
255
+ gap: 0.4rem;
256
+ }
257
+ }
258
+
259
+ .search-filter-close {
260
+ display: none;
261
+ }
262
+
263
+ @media (max-width: 1019px) {
264
+ .search-filter-close {
265
+ display: inline-flex;
266
+ }
267
+ }
@@ -1,13 +1,19 @@
1
1
  .DocSidebar {
2
- position:relative;
2
+ position:relative;
3
3
  width: 0px;
4
4
  opacity: 0;
5
5
  box-shadow: var(--htl-c-shadow-3);
6
6
  transform: translateX(-100%);
7
- --transition: opacity 0.5s, transform 0.25s ease;
7
+ /* no transition in the base state - a "--transition:" custom property sat here that no
8
+ var() ever consumed; the media queries below declare their own real transitions */
8
9
  border-right: 1px solid var(--htl-c-divider-light);
9
10
  }
10
-
11
+
12
+ .LibrarySearch .DocSidebar
13
+ {
14
+ display:none;
15
+ }
16
+
11
17
  .dark .DocSidebar {
12
18
  box-shadow: var(--htl-shadow-1);
13
19
  }
@@ -24,7 +30,11 @@
24
30
  opacity: 1;
25
31
  position:absolute;
26
32
  z-index:999;
27
- visibility: visible;
33
+ /* NO visibility:visible here. The base .DocSidebar rule never hides via visibility
34
+ (it uses opacity/transform), so this only ever did one thing: override the
35
+ inherited visibility:hidden of the .hb-hidden pre-Vue boot guard on #vDocDevApp,
36
+ which made the sidebar paint its own uncompiled template - literal {{mustaches}} -
37
+ for the whole boot window. //-- SG */
28
38
  transform: translateX(0);
29
39
  transition: opacity 0.25s,
30
40
  transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
@@ -35,16 +45,24 @@
35
45
  @media (min-width: 1020px) {
36
46
  .DocSidebar {
37
47
  min-width:320px;
38
- max-width:320px;
48
+ max-width:320px;
39
49
  z-index: 1;
40
50
  opacity: 1;
41
- visibility: visible;
51
+ /* no visibility:visible - see the note in the max-width:1019px block above */
42
52
  box-shadow: none;
43
53
  transform: translateX(0);
44
54
  }
45
55
 
46
-
47
- .toolbar-layout .mobile-menu-btn
56
+ .LibrarySearch .DocSidebar
57
+ {
58
+ display:unset;
59
+ }
60
+
61
+ /* covers the main app (title band) and settings (toolbar) locations. The .title-band
62
+ selector is needed at equal specificity to the display:flex in htldoc.layouts.css -
63
+ this file loads later, so source order makes the hide win on desktop */
64
+ .mobile-menu-btn,
65
+ .title-band .mobile-menu-btn
48
66
  {
49
67
  display:none;
50
68
  }
@@ -59,6 +77,7 @@
59
77
 
60
78
  }
61
79
 
80
+
62
81
  .DocSidebar .hdoc-nav {
63
82
  background-color: var(--htl-c-bg);
64
83
  outline: 0;
@@ -80,7 +99,7 @@
80
99
  .DocSidebar .group + .group {
81
100
  margin-top: 5px;
82
101
  margin-bottom: 5px;
83
- /*border-top: 1px solid var(--htl-c-divider-light);*/
102
+ /* border-top: 1px solid var(--htl-c-divider-light);*/
84
103
  }
85
104
 
86
105
 
@@ -105,6 +124,18 @@
105
124
  transition: color 0.5s;
106
125
  line-height: 20px;
107
126
  }
127
+
128
+ /* WCAG 2.5.5: 44px touch targets - only on touch devices */
129
+ @media (pointer: coarse) {
130
+ .DocSidebarGroup .title-text {
131
+ padding-top: 10px;
132
+ padding-bottom: 10px;
133
+ margin: 2px 0;
134
+ line-height: 24px;
135
+ min-height: 44px;
136
+ box-sizing: border-box;
137
+ }
138
+ }
108
139
 
109
140
  .DocSidebarGroup .action {
110
141
  /*display: none;*/
@@ -129,7 +160,7 @@
129
160
 
130
161
  .DocSidebarGroup .icon {
131
162
  position: absolute;
132
- top: 10px;
163
+ top: 4px;
133
164
  left: 0px;
134
165
  width: 16px;
135
166
  height: 16px;
@@ -143,7 +174,6 @@
143
174
  }
144
175
 
145
176
 
146
- /*.DocLink */
147
177
  .DocLink.link {
148
178
  display: block;
149
179
  padding-top: 2px;
@@ -151,6 +181,17 @@
151
181
  margin: 4px 0;
152
182
  transition: color 0.5s;
153
183
  }
184
+
185
+ /* WCAG 2.5.5: 44px touch targets - only on touch devices */
186
+ @media (pointer: coarse) {
187
+ .DocLink.link {
188
+ padding-top: 10px;
189
+ padding-bottom: 10px;
190
+ margin: 2px 0;
191
+ min-height: 44px;
192
+ box-sizing: border-box;
193
+ }
194
+ }
154
195
 
155
196
  .DocLink.link:hover {
156
197
  color: var(--htl-c-text-1);
@@ -160,13 +201,15 @@
160
201
  .DocLink.link.active {
161
202
  color: var(--htl-c-brand);
162
203
  }
163
-
164
- .DocLink.link :deep(.icon) {
165
- width: 12px;
166
- height: 12px;
167
- fill: currentColor;
204
+
205
+ .dark .DocLink.link.active {
206
+ color: var(--htl-c-brand-light);
168
207
  }
169
208
 
209
+ /* A ".DocLink.link :deep(.icon)" rule sat here. :deep() is a Vue SFC scoped-style construct -
210
+ this no-build site has no SFCs, so the browser discarded the whole rule as invalid; it has
211
+ never applied and is removed rather than "fixed" into a new visual change. */
212
+
170
213
  .DocLink.noitems {
171
214
  margin-left: 23px;
172
215
  }
@@ -1,6 +1,20 @@
1
- /* webfont-marker-begin */
2
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');
3
- /* webfont-marker-end */
1
+ /* An @import of Google's Inter used to sit here. Removed: it was dead weight AND the single
2
+ worst-placed request on the site.
3
+
4
+ Dead, because it supplies the family 'Inter', which is only the THIRD entry in
5
+ --htl-font-family-base ('Inter var experimental', 'Inter var', 'Inter', ...) - and the 21
6
+ @font-face blocks below define 'Inter var' from 21 self-hosted woff2 files in ../fonts/, with
7
+ the same subset coverage Google serves (latin, latin-ext, greek, greek-ext, cyrillic,
8
+ cyrillic-ext, vietnamese; roman and italic). So 'Inter var' always wins and Google's copy was
9
+ never selected for any glyph.
10
+
11
+ Worst-placed, because a stylesheet @import is a CHAINED render-blocking request: the browser
12
+ cannot discover it until this file itself has arrived, so it could not start in parallel with
13
+ the other stylesheets and delayed first paint on its own. It showed up in the network panel
14
+ after vue.global.prod.js, which is what gave it away.
15
+
16
+ If a glyph ever does fall through, add it to the self-hosted set - do not put the @import
17
+ back. //-- SG */
4
18
 
5
19
  @font-face {
6
20
  font-family: 'Inter var';