@koobiq/components 21.0.0 → 21.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 (222) hide show
  1. package/fesm2022/koobiq-components-code-block.mjs +45 -17
  2. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  3. package/fesm2022/koobiq-components-core.mjs +1 -1
  4. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  5. package/fesm2022/koobiq-components-filter-bar.mjs +9 -5
  6. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  7. package/fesm2022/koobiq-components-icon.mjs +37 -16
  8. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  9. package/fesm2022/koobiq-components-tree-select.mjs +20 -5
  10. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  11. package/fesm2022/koobiq-components-tree.mjs +218 -83
  12. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  13. package/package.json +3 -3
  14. package/schematics/collection.json +94 -89
  15. package/schematics/migrations/accordion-state-saving-default/{index.js → index.cjs} +5 -4
  16. package/schematics/migrations/actions-panel-overlay-container/{index.js → index.cjs} +5 -4
  17. package/schematics/migrations/alert-signals/{index.js → index.cjs} +14 -13
  18. package/schematics/migrations/angular-animations-removal/index.cjs +21 -0
  19. package/schematics/migrations/app-switcher-signals/{index.js → index.cjs} +7 -6
  20. package/schematics/migrations/autocomplete-panel-width-auto/{index.js → index.cjs} +6 -5
  21. package/schematics/migrations/autocomplete-signals/{index.js → index.cjs} +7 -6
  22. package/schematics/migrations/badge-signals/{index.js → index.cjs} +7 -6
  23. package/schematics/migrations/button-state-and-styles/{index.js → index.cjs} +7 -6
  24. package/schematics/migrations/button-supported-colors/{index.js → index.cjs} +7 -6
  25. package/schematics/migrations/button-toggle-signals-and-aria/{index.js → index.cjs} +7 -6
  26. package/schematics/migrations/button-truncation/{index.js → index.cjs} +7 -6
  27. package/schematics/migrations/checkbox-signals/{index.js → index.cjs} +9 -8
  28. package/schematics/migrations/clamped-text-disclosure/{index.js → index.cjs} +5 -4
  29. package/schematics/migrations/code-block-highlight-js-core/README.md +53 -0
  30. package/schematics/migrations/code-block-highlight-js-core/data.cjs +64 -0
  31. package/schematics/migrations/code-block-highlight-js-core/index.cjs +319 -0
  32. package/schematics/migrations/code-block-highlight-js-core/schema.json +20 -0
  33. package/schematics/migrations/code-block-signals/{index.js → index.cjs} +7 -6
  34. package/schematics/migrations/color-signals/index.cjs +20 -0
  35. package/schematics/migrations/core-mixins-removal/index.cjs +18 -0
  36. package/schematics/migrations/css-selectors/{index.js → index.cjs} +4 -3
  37. package/schematics/migrations/datepicker-signals/index.cjs +18 -0
  38. package/schematics/migrations/deprecated-icons/{index.js → index.cjs} +8 -7
  39. package/schematics/migrations/design-tokens-v4/{index.js → index.cjs} +3 -2
  40. package/schematics/migrations/divider-signals-and-aria/{index.js → index.cjs} +5 -4
  41. package/schematics/migrations/dl-attribute-coercion/{index.js → index.cjs} +7 -6
  42. package/schematics/migrations/dl-standalone-names/{index.js → index.cjs} +11 -10
  43. package/schematics/migrations/dropdown-demote-overlay/{index.js → index.cjs} +7 -6
  44. package/schematics/migrations/dropdown-signals/index.cjs +20 -0
  45. package/schematics/migrations/empty-state-error-color/{index.js → index.cjs} +5 -4
  46. package/schematics/migrations/empty-state-size-attr/{index.js → index.cjs} +6 -5
  47. package/schematics/migrations/file-upload-cva-and-primitives/{index.js → index.cjs} +5 -4
  48. package/schematics/migrations/file-upload-deprecated-outputs/{index.js → index.cjs} +5 -4
  49. package/schematics/migrations/filter-bar-rename-action/{index.js → index.cjs} +5 -4
  50. package/schematics/migrations/filter-bar-signals/{index.js → index.cjs} +16 -15
  51. package/schematics/migrations/filter-bar-state-saving-default/{index.js → index.cjs} +5 -4
  52. package/schematics/migrations/flag-inner-html/{index.js → index.cjs} +5 -4
  53. package/schematics/migrations/form-field-signals/{index.js → index.cjs} +18 -17
  54. package/schematics/migrations/icon-semantics-and-api/{data.js → data.cjs} +4 -4
  55. package/schematics/migrations/icon-semantics-and-api/{index.js → index.cjs} +6 -5
  56. package/schematics/migrations/icons-replacement/{index.js → index.cjs} +4 -3
  57. package/schematics/migrations/inline-edit-a11y-and-types/{index.js → index.cjs} +5 -4
  58. package/schematics/migrations/input-number-surface/{index.js → index.cjs} +5 -4
  59. package/schematics/migrations/input-signals/index.cjs +18 -0
  60. package/schematics/migrations/link-deprecated-path/{index.js → index.cjs} +4 -3
  61. package/schematics/migrations/link-signals/{index.js → index.cjs} +5 -4
  62. package/schematics/migrations/list-signals/index.cjs +18 -0
  63. package/schematics/migrations/list-tree-multiple-input/{index.js → index.cjs} +7 -6
  64. package/schematics/migrations/loader-overlay-signals/{index.js → index.cjs} +7 -6
  65. package/schematics/migrations/loader-overlay-size-attr/{index.js → index.cjs} +6 -5
  66. package/schematics/migrations/locale-configuration-providers/{index.js → index.cjs} +5 -4
  67. package/schematics/migrations/mandatory-peer-dependencies/{index.js → index.cjs} +3 -2
  68. package/schematics/migrations/markdown-signals/{index.js → index.cjs} +7 -6
  69. package/schematics/migrations/modal-dialog-semantics/{index.js → index.cjs} +5 -4
  70. package/schematics/migrations/modal-signals/index.cjs +20 -0
  71. package/schematics/migrations/navbar-signals-and-aria/{index.js → index.cjs} +7 -6
  72. package/schematics/migrations/new-icons-pack/{index.js → index.cjs} +8 -7
  73. package/schematics/migrations/notification-center-signals/{index.js → index.cjs} +5 -4
  74. package/schematics/migrations/option-signals/index.cjs +20 -0
  75. package/schematics/migrations/popover-leave-delay/{index.js → index.cjs} +5 -4
  76. package/schematics/migrations/progress-bar-percentage-and-aria/{index.js → index.cjs} +5 -4
  77. package/schematics/migrations/progress-spinner-signals/{index.js → index.cjs} +7 -6
  78. package/schematics/migrations/query-list-signals/index.cjs +18 -0
  79. package/schematics/migrations/radio-signals-and-aria/{index.js → index.cjs} +9 -8
  80. package/schematics/migrations/read-state-dwell-handlers/{index.js → index.cjs} +5 -4
  81. package/schematics/migrations/scrollbar-deprecated-path/{index.js → index.cjs} +4 -3
  82. package/schematics/migrations/select-signal-inputs/{index.js → index.cjs} +5 -4
  83. package/schematics/migrations/sidepanel-non-modal-behavior/{index.js → index.cjs} +5 -4
  84. package/schematics/migrations/signal-inputs-subclasses/index.cjs +18 -0
  85. package/schematics/migrations/split-button-optional-disabled/{index.js → index.cjs} +5 -4
  86. package/schematics/migrations/splitter-deprecated-path/{index.js → index.cjs} +4 -3
  87. package/schematics/migrations/state-saving-default/{index.js → index.cjs} +5 -4
  88. package/schematics/migrations/table-cell-content/{index.js → index.cjs} +5 -4
  89. package/schematics/migrations/tabs-signals-and-aria/{index.js → index.cjs} +5 -4
  90. package/schematics/migrations/tag-list-cleaner/{index.js → index.cjs} +7 -6
  91. package/schematics/migrations/tag-slots/{index.js → index.cjs} +6 -5
  92. package/schematics/migrations/tags-signals/{index.js → index.cjs} +7 -6
  93. package/schematics/migrations/textarea-signals/{index.js → index.cjs} +7 -6
  94. package/schematics/migrations/time-range-title-for/{index.js → index.cjs} +5 -4
  95. package/schematics/migrations/timepicker-signals/{index.js → index.cjs} +7 -6
  96. package/schematics/migrations/timezone-grouping-utils/{index.js → index.cjs} +5 -4
  97. package/schematics/migrations/title-encapsulation/{index.js → index.cjs} +5 -4
  98. package/schematics/migrations/toast-stack-and-defaults/{index.js → index.cjs} +5 -4
  99. package/schematics/migrations/tooltip-pointer-events-and-types/{index.js → index.cjs} +5 -4
  100. package/schematics/migrations/top-bar-container-selectors/{index.js → index.cjs} +5 -4
  101. package/schematics/migrations/tree-select-signals/{index.js → index.cjs} +5 -4
  102. package/schematics/migrations/tree-signals/{index.js → index.cjs} +5 -4
  103. package/schematics/migrations/tree-state-saving-default/{index.js → index.cjs} +5 -4
  104. package/schematics/migrations/username-pipe-injection/{index.js → index.cjs} +5 -4
  105. package/schematics/migrations/v20-upgrade/{data.js → data.cjs} +7 -7
  106. package/schematics/migrations/v20-upgrade/index.cjs +19 -0
  107. package/schematics/migrations/v21-upgrade/{data.js → data.cjs} +22 -22
  108. package/schematics/migrations/v21-upgrade/{index.js → index.cjs} +11 -10
  109. package/schematics/migrations/zoneless-change-detection/index.cjs +21 -0
  110. package/schematics/migrations.json +87 -82
  111. package/schematics/ng-add/{index.js → index.cjs} +12 -286
  112. package/schematics/utils/{angular-parsing.js → angular-parsing.cjs} +2 -2
  113. package/schematics/utils/{deprecated-path-migration.js → deprecated-path-migration.cjs} +4 -3
  114. package/schematics/utils/html-config.cjs +148 -0
  115. package/schematics/utils/{icon-migration.js → icon-migration.cjs} +2 -2
  116. package/schematics/utils/list-item-pattern.cjs +16 -0
  117. package/schematics/utils/package-config.cjs +80 -0
  118. package/schematics/utils/project-files.cjs +25 -0
  119. package/schematics/utils/replacement-driver.cjs +337 -0
  120. package/schematics/utils/safe-rule.cjs +23 -0
  121. package/schematics/utils/signal-members-migration.cjs +779 -0
  122. package/schematics/utils/tag-patterns.cjs +21 -0
  123. package/schematics/utils/template-ref-access.cjs +155 -0
  124. package/schematics/utils/{typescript.js → typescript.cjs} +1 -1
  125. package/schematics/utils/warn-only-migration.cjs +52 -0
  126. package/schematics/utils/workspace-styles.cjs +123 -0
  127. package/types/koobiq-components-code-block.d.ts +38 -11
  128. package/types/koobiq-components-filter-bar.d.ts +2 -2
  129. package/types/koobiq-components-tree-select.d.ts +11 -8
  130. package/types/koobiq-components-tree.d.ts +108 -59
  131. package/schematics/migrations/angular-animations-removal/index.js +0 -20
  132. package/schematics/migrations/color-signals/index.js +0 -19
  133. package/schematics/migrations/core-mixins-removal/index.js +0 -17
  134. package/schematics/migrations/datepicker-signals/index.js +0 -17
  135. package/schematics/migrations/dropdown-signals/index.js +0 -19
  136. package/schematics/migrations/input-signals/index.js +0 -17
  137. package/schematics/migrations/list-signals/index.js +0 -17
  138. package/schematics/migrations/modal-signals/index.js +0 -19
  139. package/schematics/migrations/option-signals/index.js +0 -19
  140. package/schematics/migrations/query-list-signals/index.js +0 -17
  141. package/schematics/migrations/signal-inputs-subclasses/index.js +0 -17
  142. package/schematics/migrations/v20-upgrade/index.js +0 -18
  143. package/schematics/migrations/zoneless-change-detection/index.js +0 -20
  144. package/schematics/utils/package-config.js +0 -13
  145. /package/schematics/migrations/accordion-state-saving-default/{data.js → data.cjs} +0 -0
  146. /package/schematics/migrations/actions-panel-overlay-container/{data.js → data.cjs} +0 -0
  147. /package/schematics/migrations/alert-signals/{data.js → data.cjs} +0 -0
  148. /package/schematics/migrations/angular-animations-removal/{data.js → data.cjs} +0 -0
  149. /package/schematics/migrations/app-switcher-signals/{data.js → data.cjs} +0 -0
  150. /package/schematics/migrations/autocomplete-signals/{data.js → data.cjs} +0 -0
  151. /package/schematics/migrations/badge-signals/{data.js → data.cjs} +0 -0
  152. /package/schematics/migrations/button-state-and-styles/{data.js → data.cjs} +0 -0
  153. /package/schematics/migrations/button-supported-colors/{data.js → data.cjs} +0 -0
  154. /package/schematics/migrations/button-toggle-signals-and-aria/{data.js → data.cjs} +0 -0
  155. /package/schematics/migrations/button-truncation/{data.js → data.cjs} +0 -0
  156. /package/schematics/migrations/checkbox-signals/{data.js → data.cjs} +0 -0
  157. /package/schematics/migrations/clamped-text-disclosure/{data.js → data.cjs} +0 -0
  158. /package/schematics/migrations/code-block-signals/{data.js → data.cjs} +0 -0
  159. /package/schematics/migrations/color-signals/{data.js → data.cjs} +0 -0
  160. /package/schematics/migrations/core-mixins-removal/{data.js → data.cjs} +0 -0
  161. /package/schematics/migrations/css-selectors/{data.js → data.cjs} +0 -0
  162. /package/schematics/migrations/datepicker-signals/{data.js → data.cjs} +0 -0
  163. /package/schematics/migrations/deprecated-icons/{data.js → data.cjs} +0 -0
  164. /package/schematics/migrations/divider-signals-and-aria/{data.js → data.cjs} +0 -0
  165. /package/schematics/migrations/dl-attribute-coercion/{data.js → data.cjs} +0 -0
  166. /package/schematics/migrations/dl-standalone-names/{data.js → data.cjs} +0 -0
  167. /package/schematics/migrations/dropdown-demote-overlay/{data.js → data.cjs} +0 -0
  168. /package/schematics/migrations/dropdown-signals/{data.js → data.cjs} +0 -0
  169. /package/schematics/migrations/empty-state-error-color/{data.js → data.cjs} +0 -0
  170. /package/schematics/migrations/file-upload-cva-and-primitives/{data.js → data.cjs} +0 -0
  171. /package/schematics/migrations/file-upload-deprecated-outputs/{data.js → data.cjs} +0 -0
  172. /package/schematics/migrations/filter-bar-rename-action/{data.js → data.cjs} +0 -0
  173. /package/schematics/migrations/filter-bar-signals/{data.js → data.cjs} +0 -0
  174. /package/schematics/migrations/filter-bar-state-saving-default/{data.js → data.cjs} +0 -0
  175. /package/schematics/migrations/flag-inner-html/{data.js → data.cjs} +0 -0
  176. /package/schematics/migrations/form-field-signals/{data.js → data.cjs} +0 -0
  177. /package/schematics/migrations/icons-replacement/{data.js → data.cjs} +0 -0
  178. /package/schematics/migrations/inline-edit-a11y-and-types/{data.js → data.cjs} +0 -0
  179. /package/schematics/migrations/input-number-surface/{data.js → data.cjs} +0 -0
  180. /package/schematics/migrations/input-signals/{data.js → data.cjs} +0 -0
  181. /package/schematics/migrations/link-signals/{data.js → data.cjs} +0 -0
  182. /package/schematics/migrations/list-signals/{data.js → data.cjs} +0 -0
  183. /package/schematics/migrations/list-tree-multiple-input/{data.js → data.cjs} +0 -0
  184. /package/schematics/migrations/loader-overlay-signals/{data.js → data.cjs} +0 -0
  185. /package/schematics/migrations/locale-configuration-providers/{data.js → data.cjs} +0 -0
  186. /package/schematics/migrations/markdown-signals/{data.js → data.cjs} +0 -0
  187. /package/schematics/migrations/modal-dialog-semantics/{data.js → data.cjs} +0 -0
  188. /package/schematics/migrations/modal-signals/{data.js → data.cjs} +0 -0
  189. /package/schematics/migrations/navbar-signals-and-aria/{data.js → data.cjs} +0 -0
  190. /package/schematics/migrations/new-icons-pack/{data.js → data.cjs} +0 -0
  191. /package/schematics/migrations/notification-center-signals/{data.js → data.cjs} +0 -0
  192. /package/schematics/migrations/option-signals/{data.js → data.cjs} +0 -0
  193. /package/schematics/migrations/popover-leave-delay/{data.js → data.cjs} +0 -0
  194. /package/schematics/migrations/progress-bar-percentage-and-aria/{data.js → data.cjs} +0 -0
  195. /package/schematics/migrations/progress-spinner-signals/{data.js → data.cjs} +0 -0
  196. /package/schematics/migrations/query-list-signals/{data.js → data.cjs} +0 -0
  197. /package/schematics/migrations/radio-signals-and-aria/{data.js → data.cjs} +0 -0
  198. /package/schematics/migrations/read-state-dwell-handlers/{data.js → data.cjs} +0 -0
  199. /package/schematics/migrations/select-signal-inputs/{data.js → data.cjs} +0 -0
  200. /package/schematics/migrations/sidepanel-non-modal-behavior/{data.js → data.cjs} +0 -0
  201. /package/schematics/migrations/signal-inputs-subclasses/{data.js → data.cjs} +0 -0
  202. /package/schematics/migrations/split-button-optional-disabled/{data.js → data.cjs} +0 -0
  203. /package/schematics/migrations/state-saving-default/{data.js → data.cjs} +0 -0
  204. /package/schematics/migrations/table-cell-content/{data.js → data.cjs} +0 -0
  205. /package/schematics/migrations/tabs-signals-and-aria/{data.js → data.cjs} +0 -0
  206. /package/schematics/migrations/tag-list-cleaner/{data.js → data.cjs} +0 -0
  207. /package/schematics/migrations/tags-signals/{data.js → data.cjs} +0 -0
  208. /package/schematics/migrations/textarea-signals/{data.js → data.cjs} +0 -0
  209. /package/schematics/migrations/time-range-title-for/{data.js → data.cjs} +0 -0
  210. /package/schematics/migrations/timepicker-signals/{data.js → data.cjs} +0 -0
  211. /package/schematics/migrations/timezone-grouping-utils/{data.js → data.cjs} +0 -0
  212. /package/schematics/migrations/title-encapsulation/{data.js → data.cjs} +0 -0
  213. /package/schematics/migrations/toast-stack-and-defaults/{data.js → data.cjs} +0 -0
  214. /package/schematics/migrations/tooltip-pointer-events-and-types/{data.js → data.cjs} +0 -0
  215. /package/schematics/migrations/top-bar-container-selectors/{data.js → data.cjs} +0 -0
  216. /package/schematics/migrations/tree-select-signals/{data.js → data.cjs} +0 -0
  217. /package/schematics/migrations/tree-signals/{data.js → data.cjs} +0 -0
  218. /package/schematics/migrations/tree-state-saving-default/{data.js → data.cjs} +0 -0
  219. /package/schematics/migrations/username-pipe-injection/{data.js → data.cjs} +0 -0
  220. /package/schematics/migrations/zoneless-change-detection/{data.js → data.cjs} +0 -0
  221. /package/schematics/utils/{ast.js → ast.cjs} +0 -0
  222. /package/schematics/utils/{messages.js → messages.cjs} +0 -0
@@ -20,6 +20,7 @@ import { KbqTabsModule } from '@koobiq/components/tabs';
20
20
  import * as i5 from '@koobiq/components/tooltip';
21
21
  import { KbqToolTipModule } from '@koobiq/components/tooltip';
22
22
  import { take, merge, fromEvent, map, debounceTime, filter } from 'rxjs';
23
+ import plaintext from 'highlight.js/lib/languages/plaintext';
23
24
 
24
25
  /**
25
26
  * The highlight.js line numbers plugin, kept apart from the code that calls it until code blocks number their lines
@@ -350,9 +351,21 @@ function highlightJSLineNumbersPlugin(d, w) {
350
351
  }
351
352
  }
352
353
 
353
- const defaultHljsLoader = () => import('highlight.js');
354
+ // The core and not the full bundle: a bundler emits a chunk for every `import()` it finds, called or not, so the
355
+ // full bundle has to be imported by the application that asks for it. An instance of its own, as the module is one
356
+ // object for the whole process, the full bundle included: the languages one configuration registers on it would reach
357
+ // every other, and every later server render.
358
+ const defaultHljsLoader = async () => ({
359
+ default: (await import('highlight.js/lib/core')).default.newInstance()
360
+ });
354
361
  // The key of the default configuration: `config ?? {}` would make a new key on every call.
355
362
  const DEFAULT_CONFIG = {};
363
+ /**
364
+ * Language the loader registers on every instance, the fallback of a file the code block cannot highlight otherwise.
365
+ *
366
+ * @internal
367
+ */
368
+ const PLAIN_TEXT_LANGUAGE = 'plaintext';
356
369
  /**
357
370
  * Loads highlight.js once per configuration and installs its line numbers plugin once per application.
358
371
  *
@@ -403,14 +416,18 @@ class KbqCodeBlockHighlightJsLoader {
403
416
  // The plugin cannot take empty markup: it reads the last of no lines.
404
417
  return html ? this.lineNumbersPlugin().lineNumbersValue(html, options) : html;
405
418
  }
406
- async importInstance({ core, languages }) {
407
- const { default: instance } = await (core ?? defaultHljsLoader)();
408
- if (languages) {
409
- await Promise.all(Object.entries(languages).map(async ([name, loader]) => {
410
- const { default: language } = await loader();
411
- instance.registerLanguage(name, language);
412
- }));
413
- }
419
+ async importInstance({ core, languages = {} }) {
420
+ const entries = Object.entries(languages);
421
+ // The languages do not need the core to load, so they load alongside it.
422
+ const [{ default: instance }, loaded] = await Promise.all([
423
+ (core ?? defaultHljsLoader)(),
424
+ Promise.all(entries.map(([, loader]) => loader()))
425
+ ]);
426
+ entries.forEach(([name], index) => instance.registerLanguage(name, loaded[index].default));
427
+ // The directive falls back to plain text, and highlight.js throws on a language it has not registered, as the
428
+ // core has none.
429
+ if (!instance.getLanguage(PLAIN_TEXT_LANGUAGE))
430
+ instance.registerLanguage(PLAIN_TEXT_LANGUAGE, plaintext);
414
431
  return instance;
415
432
  }
416
433
  /**
@@ -454,7 +471,6 @@ const KBQ_CODE_BLOCK_HIGHLIGHT_JS_CONFIG = new InjectionToken('KBQ_CODE_BLOCK_HI
454
471
  * ```ts
455
472
  * providers: [
456
473
  * kbqCodeBlockHighlightJsConfigProvider({
457
- * core: () => import('highlight.js/lib/core'),
458
474
  * languages: {
459
475
  * typescript: () => import('highlight.js/lib/languages/typescript'),
460
476
  * css: () => import('highlight.js/lib/languages/css'),
@@ -469,11 +485,13 @@ const kbqCodeBlockHighlightJsConfigProvider = (options) => ({
469
485
  useValue: options
470
486
  });
471
487
  /**
472
- * Fallback language for code block if language is not supported/specified.
488
+ * Fallback language for code block if language is not supported/specified. It has to be registered in `languages` of
489
+ * `KbqCodeBlockHighlightJsConfig`, unless it is plain text or the full bundle of highlight.js is loaded, or the code
490
+ * block falls back to `plaintext`.
473
491
  *
474
- * See the [list of supported languages](https://highlightjs.readthedocs.io/en/stable/supported-languages.html).
492
+ * See the [list of supported languages](https://github.com/highlightjs/highlight.js/blob/11-stable/SUPPORTED_LANGUAGES.md).
475
493
  */
476
- const KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE = new InjectionToken('KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE', { factory: () => 'plaintext' });
494
+ const KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE = new InjectionToken('KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE', { factory: () => PLAIN_TEXT_LANGUAGE });
477
495
  /** Utility provider for `KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE`. */
478
496
  const kbqCodeBlockFallbackFileLanguageProvider = (language) => ({
479
497
  provide: KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE,
@@ -565,18 +583,21 @@ class KbqCodeBlockHighlight {
565
583
  let { language } = file;
566
584
  const isKnownLanguage = !!language && !!hljs.getLanguage(language);
567
585
  if (!language || !isKnownLanguage) {
586
+ const fallbackLanguage = this.fallbackLanguage(hljs);
568
587
  // A file without a language is plain text by design; only a language the core lacks is a mistake.
569
588
  if (language) {
570
- this.warn(`[KbqCodeBlock] Unknown file language: "${language}". Fall back to "${this.fallbackFileLanguage}".`, file);
589
+ this.warn(`[KbqCodeBlock] Unknown file language: "${language}". Fall back to "${fallbackLanguage}".`, file);
571
590
  }
572
- language = this.fallbackFileLanguage;
591
+ language = fallbackLanguage;
573
592
  }
574
593
  const { value: highlightedHTML, language: highlightedLanguage, illegal, relevance } = hljs.highlight(file.content, { language });
575
594
  if (illegal) {
576
595
  this.warn('[KbqCodeBlock] File content contains illegal characters.', file);
577
596
  }
578
- // Plain text has no syntax to score, so its relevance is always 0 — even for the fallback itself.
579
- if (relevance === 0 && isKnownLanguage && highlightedLanguage !== 'plaintext') {
597
+ // Plain text and an empty file have no syntax to score, so their relevance is always 0. Plain text is compared by
598
+ // definition: highlight.js returns the name the file gives, which may be an alias such as `text`.
599
+ const isPlainText = hljs.getLanguage(language) === hljs.getLanguage(PLAIN_TEXT_LANGUAGE);
600
+ if (relevance === 0 && isKnownLanguage && !isPlainText && file.content.trim()) {
580
601
  this.warn('[KbqCodeBlock] File content does not match the specified programming language.', file);
581
602
  }
582
603
  const safeHTML = this.domSanitizer.sanitize(SecurityContext.HTML, highlightedHTML) ?? '';
@@ -586,6 +607,13 @@ class KbqCodeBlockHighlight {
586
607
  this.renderer.setAttribute(this.nativeElement, HIGHLIGHTED_MARKUP_ATTRIBUTE, '');
587
608
  this._pending.set(false);
588
609
  }
610
+ /** The fallback language, or plain text, which the loader registers on every instance, if it is unknown too. */
611
+ fallbackLanguage(hljs) {
612
+ if (hljs.getLanguage(this.fallbackFileLanguage))
613
+ return this.fallbackFileLanguage;
614
+ this.warn(`[KbqCodeBlock] Unknown fallback language: "${this.fallbackFileLanguage}". Fall back to "${PLAIN_TEXT_LANGUAGE}".`);
615
+ return PLAIN_TEXT_LANGUAGE;
616
+ }
589
617
  warn(...messages) {
590
618
  if (!isDevMode())
591
619
  return;