chuijs 4.0.1 → 4.0.3

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/CHANGELOG.md +113 -0
  2. package/README.md +43 -632
  3. package/framework/appLayout/default/chui_app_layout.js +314 -273
  4. package/framework/appLayout/default/global_style.css +93 -53
  5. package/framework/components/chui_accordion/accordion.js +29 -26
  6. package/framework/components/chui_accordion/styles.css +6 -5
  7. package/framework/components/chui_action_sheet/action_sheet.js +59 -33
  8. package/framework/components/chui_action_sheet/styles.css +2 -1
  9. package/framework/components/chui_affix/affix.js +11 -6
  10. package/framework/components/chui_alert/alert.js +23 -14
  11. package/framework/components/chui_avatar/avatar.js +23 -22
  12. package/framework/components/chui_avatar_group/avatar_group.js +21 -19
  13. package/framework/components/chui_backtop/backtop.js +35 -19
  14. package/framework/components/chui_badge/badge.js +15 -13
  15. package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
  16. package/framework/components/chui_button/button.js +42 -22
  17. package/framework/components/chui_button/styles.css +2 -2
  18. package/framework/components/chui_calendar/calendar.js +12 -10
  19. package/framework/components/chui_card/card.js +43 -23
  20. package/framework/components/chui_chat/chat.js +72 -33
  21. package/framework/components/chui_clipboard_history/clipboard_history.js +30 -21
  22. package/framework/components/chui_clipboard_history/styles.css +4 -2
  23. package/framework/components/chui_code/code.js +2 -2
  24. package/framework/components/chui_code/styles.css +2 -2
  25. package/framework/components/chui_code_editor/code_editor.js +47 -31
  26. package/framework/components/chui_code_editor/styles.css +3 -2
  27. package/framework/components/chui_command_palette/command_palette.js +60 -37
  28. package/framework/components/chui_console/console.js +5 -5
  29. package/framework/components/chui_console/styles.css +1 -1
  30. package/framework/components/chui_content_block/content_block.js +33 -19
  31. package/framework/components/chui_content_block/styles.css +2 -2
  32. package/framework/components/chui_context_menu/context_menu.js +9 -4
  33. package/framework/components/chui_custom_element/custom_element.js +22 -15
  34. package/framework/components/chui_data_grid/data_grid.js +396 -234
  35. package/framework/components/chui_data_grid/styles.css +10 -8
  36. package/framework/components/chui_descriptions/descriptions.js +34 -17
  37. package/framework/components/chui_details/details.js +32 -26
  38. package/framework/components/chui_details/styles.css +5 -4
  39. package/framework/components/chui_diff_viewer/diff_viewer.js +91 -66
  40. package/framework/components/chui_diff_viewer/styles.css +1 -1
  41. package/framework/components/chui_divider/divider.js +13 -11
  42. package/framework/components/chui_drawer/drawer.js +27 -25
  43. package/framework/components/chui_drop_zone/drop_zone.js +31 -21
  44. package/framework/components/chui_empty_state/empty_state.js +20 -15
  45. package/framework/components/chui_fieldset/fieldset.js +37 -20
  46. package/framework/components/chui_fieldset/styles.css +1 -1
  47. package/framework/components/chui_file_explorer/file_explorer.js +157 -86
  48. package/framework/components/chui_file_explorer/styles.css +2 -1
  49. package/framework/components/chui_form/form.js +31 -19
  50. package/framework/components/chui_form/styles.css +1 -1
  51. package/framework/components/chui_gantt/gantt.js +64 -40
  52. package/framework/components/chui_graphs/graphs.js +301 -200
  53. package/framework/components/chui_graphs/styles.css +1 -1
  54. package/framework/components/chui_hero/hero.js +40 -22
  55. package/framework/components/chui_html_block/html_block.js +6 -6
  56. package/framework/components/chui_html_block/styles.css +2 -2
  57. package/framework/components/chui_hx/hx.js +3 -3
  58. package/framework/components/chui_hx/styles.css +11 -4
  59. package/framework/components/chui_icons/icons.js +2109 -2109
  60. package/framework/components/chui_icons/styles.css +2 -2
  61. package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
  62. package/framework/components/chui_inputs/chui_check_box/styles.css +18 -18
  63. package/framework/components/chui_inputs/chui_chips/chips.js +50 -40
  64. package/framework/components/chui_inputs/chui_chips/styles.css +4 -2
  65. package/framework/components/chui_inputs/chui_color_picker/color_picker.js +36 -24
  66. package/framework/components/chui_inputs/chui_combo_box/combo_box.js +100 -82
  67. package/framework/components/chui_inputs/chui_combo_box/styles.css +14 -12
  68. package/framework/components/chui_inputs/chui_date/date.js +102 -66
  69. package/framework/components/chui_inputs/chui_date/styles.css +12 -11
  70. package/framework/components/chui_inputs/chui_date_range/date_range.js +40 -29
  71. package/framework/components/chui_inputs/chui_datetime/datetime.js +35 -27
  72. package/framework/components/chui_inputs/chui_email/email.js +43 -31
  73. package/framework/components/chui_inputs/chui_email/styles.css +5 -5
  74. package/framework/components/chui_inputs/chui_file/file.js +68 -41
  75. package/framework/components/chui_inputs/chui_file/styles.css +13 -12
  76. package/framework/components/chui_inputs/chui_hotkey/hotkey.js +61 -36
  77. package/framework/components/chui_inputs/chui_masked/masked.js +39 -28
  78. package/framework/components/chui_inputs/chui_mention/mention.js +77 -30
  79. package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +173 -153
  80. package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +9 -7
  81. package/framework/components/chui_inputs/chui_number/number.js +58 -41
  82. package/framework/components/chui_inputs/chui_number/styles.css +7 -7
  83. package/framework/components/chui_inputs/chui_otp/otp.js +38 -29
  84. package/framework/components/chui_inputs/chui_password/password.js +58 -36
  85. package/framework/components/chui_inputs/chui_password/styles.css +8 -8
  86. package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
  87. package/framework/components/chui_inputs/chui_radio_button/styles.css +20 -20
  88. package/framework/components/chui_inputs/chui_rating/rating.js +26 -22
  89. package/framework/components/chui_inputs/chui_select_box/select_box.js +102 -78
  90. package/framework/components/chui_inputs/chui_select_box/styles.css +11 -11
  91. package/framework/components/chui_inputs/chui_slider/slider.js +29 -26
  92. package/framework/components/chui_inputs/chui_slider/styles.css +2 -1
  93. package/framework/components/chui_inputs/chui_text/styles.css +8 -8
  94. package/framework/components/chui_inputs/chui_text/text.js +65 -44
  95. package/framework/components/chui_inputs/chui_text_area/styles.css +6 -6
  96. package/framework/components/chui_inputs/chui_text_area/text_area.js +51 -28
  97. package/framework/components/chui_inputs/chui_time/styles.css +5 -3
  98. package/framework/components/chui_inputs/chui_time/time.js +38 -27
  99. package/framework/components/chui_inputs/chui_toggle/styles.css +3 -3
  100. package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
  101. package/framework/components/chui_json_editor/json_editor.js +53 -43
  102. package/framework/components/chui_json_viewer/json_viewer.js +52 -33
  103. package/framework/components/chui_json_viewer/styles.css +3 -2
  104. package/framework/components/chui_kanban/kanban.js +52 -34
  105. package/framework/components/chui_kbd/kbd.js +12 -10
  106. package/framework/components/chui_label/label.js +14 -12
  107. package/framework/components/chui_label/styles.css +2 -2
  108. package/framework/components/chui_link/link.js +27 -20
  109. package/framework/components/chui_list/list.js +31 -27
  110. package/framework/components/chui_list/styles.css +2 -1
  111. package/framework/components/chui_markdown_editor/markdown_editor.js +60 -44
  112. package/framework/components/chui_media/audio.js +326 -227
  113. package/framework/components/chui_media/audio_styles.css +40 -21
  114. package/framework/components/chui_media/image.js +70 -38
  115. package/framework/components/chui_media/image_compare.js +52 -21
  116. package/framework/components/chui_media/image_styles.css +3 -3
  117. package/framework/components/chui_media/video.js +155 -62
  118. package/framework/components/chui_media/video_styles.css +33 -16
  119. package/framework/components/chui_menu_bar/menu_bar.js +26 -24
  120. package/framework/components/chui_menu_bar/styles.css +4 -2
  121. package/framework/components/chui_modal/modal.js +44 -43
  122. package/framework/components/chui_modal/styles.css +3 -2
  123. package/framework/components/chui_notification/notification.js +50 -34
  124. package/framework/components/chui_notification/notification_download.js +31 -25
  125. package/framework/components/chui_notification/notification_download_progress.css +3 -2
  126. package/framework/components/chui_notification/notification_download_progress.js +47 -41
  127. package/framework/components/chui_notification/notification_update.js +23 -16
  128. package/framework/components/chui_notification/status_plate.js +2 -2
  129. package/framework/components/chui_notification/styles_download.css +1 -1
  130. package/framework/components/chui_notification/styles_update.css +1 -1
  131. package/framework/components/chui_org_chart/org_chart.js +74 -35
  132. package/framework/components/chui_pagination/pagination.js +62 -27
  133. package/framework/components/chui_paragraph/paragraph.js +2 -2
  134. package/framework/components/chui_paragraph/styles.css +1 -1
  135. package/framework/components/chui_popover/popover.js +49 -28
  136. package/framework/components/chui_popups/popups.js +137 -108
  137. package/framework/components/chui_popups/styles.css +2 -2
  138. package/framework/components/chui_print_button/print_button.js +33 -23
  139. package/framework/components/chui_progress_bar/progress_bar.js +23 -15
  140. package/framework/components/chui_progress_bar/styles.css +2 -2
  141. package/framework/components/chui_progress_ring/progress_ring.js +17 -15
  142. package/framework/components/chui_qrcode/qrcode.js +75 -31
  143. package/framework/components/chui_query_builder/query_builder.js +216 -123
  144. package/framework/components/chui_radio_group/radio_group.js +36 -26
  145. package/framework/components/chui_radio_group/styles.css +1 -1
  146. package/framework/components/chui_result/result.js +26 -16
  147. package/framework/components/chui_scheduler/scheduler.js +57 -35
  148. package/framework/components/chui_scheduler/styles.css +6 -2
  149. package/framework/components/chui_segmented_control/segmented_control.js +27 -21
  150. package/framework/components/chui_settings/settings.js +122 -48
  151. package/framework/components/chui_shortcut_help/shortcut_help.js +55 -32
  152. package/framework/components/chui_sidebar_nav/sidebar_nav.js +33 -23
  153. package/framework/components/chui_skeleton/skeleton.js +29 -24
  154. package/framework/components/chui_slideshow/slideshow.js +60 -41
  155. package/framework/components/chui_slideshow/styles.css +18 -12
  156. package/framework/components/chui_spinner/spinner.js +8 -8
  157. package/framework/components/chui_spinner/styles.css +0 -1
  158. package/framework/components/chui_split_button/split_button.js +23 -18
  159. package/framework/components/chui_split_button/styles.css +1 -1
  160. package/framework/components/chui_splitter/splitter.js +35 -28
  161. package/framework/components/chui_statistic/statistic.js +65 -38
  162. package/framework/components/chui_status_bar/status_bar.js +11 -9
  163. package/framework/components/chui_stepper/stepper.js +27 -22
  164. package/framework/components/chui_sticky_bar/sticky_bar.js +9 -4
  165. package/framework/components/chui_sticky_bar/styles.css +3 -1
  166. package/framework/components/chui_tabs/chui_tabs.js +28 -22
  167. package/framework/components/chui_tabs/styles.css +3 -3
  168. package/framework/components/chui_text_editor/styles.css +20 -19
  169. package/framework/components/chui_text_editor/text_editor.js +85 -61
  170. package/framework/components/chui_text_editor/text_editor_panel.js +346 -284
  171. package/framework/components/chui_theme_toggle/theme_toggle.js +27 -22
  172. package/framework/components/chui_timeline/timeline.js +14 -12
  173. package/framework/components/chui_toast_queue/toast_queue.js +52 -46
  174. package/framework/components/chui_toolbar/toolbar.js +20 -13
  175. package/framework/components/chui_tooltip/tooltip.js +37 -24
  176. package/framework/components/chui_tour/styles.css +8 -3
  177. package/framework/components/chui_tour/tour.js +61 -27
  178. package/framework/components/chui_transfer/styles.css +2 -1
  179. package/framework/components/chui_transfer/transfer.js +75 -42
  180. package/framework/components/chui_tree_table/tree_table.js +43 -29
  181. package/framework/components/chui_tree_view/styles.css +4 -2
  182. package/framework/components/chui_tree_view/tree_view.js +142 -99
  183. package/framework/components/chui_watermark/watermark.js +24 -16
  184. package/framework/components/chui_webview/styles.css +2 -2
  185. package/framework/components/chui_webview/webview.js +62 -50
  186. package/framework/components/telegram_bot/chui_telegram_bot.js +71 -64
  187. package/framework/modules/chui_a11y/chui_a11y.js +77 -46
  188. package/framework/modules/chui_animations/animations.js +42 -42
  189. package/framework/modules/chui_animations/styles.css +1 -1
  190. package/framework/modules/chui_bridge/preload.js +56 -26
  191. package/framework/modules/chui_functions.js +52 -50
  192. package/framework/modules/chui_highlight/chui_highlight.js +25 -22
  193. package/framework/modules/chui_i18n/chui_i18n.js +9 -7
  194. package/framework/modules/chui_i18n/locales/a11y.js +5 -5
  195. package/framework/modules/chui_i18n/locales/app_layout.js +5 -5
  196. package/framework/modules/chui_i18n/locales/calendar.js +3 -3
  197. package/framework/modules/chui_i18n/locales/common.js +3 -3
  198. package/framework/modules/chui_i18n/locales/data.js +36 -26
  199. package/framework/modules/chui_i18n/locales/editors.js +40 -13
  200. package/framework/modules/chui_i18n/locales/feedback.js +3 -3
  201. package/framework/modules/chui_i18n/locales/forms.js +8 -8
  202. package/framework/modules/chui_i18n/locales/graphics.js +8 -8
  203. package/framework/modules/chui_i18n/locales/media.js +4 -4
  204. package/framework/modules/chui_i18n/locales/navigation.js +8 -8
  205. package/framework/modules/chui_i18n/locales/validate.js +3 -3
  206. package/framework/modules/chui_json/chui_json.js +9 -9
  207. package/framework/modules/chui_layout/chui_layout.js +12 -10
  208. package/framework/modules/chui_logger/chui_logger.js +29 -25
  209. package/framework/modules/chui_page/page.js +33 -27
  210. package/framework/modules/chui_page/styles.css +3 -26
  211. package/framework/modules/chui_qr/chui_qr.js +158 -67
  212. package/framework/modules/chui_scrollbar/chui_scrollbar.js +35 -24
  213. package/framework/modules/chui_scrollbar/styles.css +3 -1
  214. package/framework/modules/chui_services/chui_channels.js +76 -11
  215. package/framework/modules/chui_services/chui_services.js +39 -31
  216. package/framework/modules/chui_services/desktop.js +149 -30
  217. package/framework/modules/chui_sortable/chui_sortable.js +17 -12
  218. package/framework/modules/chui_validate/chui_validate.js +7 -4
  219. package/framework/tray_bar/chui_menu_items.js +136 -46
  220. package/index.d.ts +4814 -0
  221. package/index.js +449 -334
  222. package/package.json +79 -68
@@ -14,7 +14,8 @@ chui_data_grid {
14
14
  серого: так полоса шапки читается, но не превращается в яркую ленту */
15
15
  --data_grid_surface: color-mix(in srgb, var(--element_background) 60%, transparent);
16
16
  --data_grid_body: linear-gradient(var(--data_grid_surface), var(--data_grid_surface)), var(--element_background_2);
17
- --data_grid_head: linear-gradient(var(--element_background), var(--element_background)),
17
+ --data_grid_head:
18
+ linear-gradient(var(--element_background), var(--element_background)),
18
19
  linear-gradient(var(--data_grid_surface), var(--data_grid_surface)), var(--element_background_2);
19
20
  /* Выделение — мягкая тонировка акцента: плотный токен (0.26 в тёмной схеме) читался
20
21
  тяжёлым синим блоком во всю строку */
@@ -56,7 +57,8 @@ data_grid_error {
56
57
  box-sizing: border-box;
57
58
  width: 100%;
58
59
  margin-bottom: 6px;
59
- padding-block: 6px 6px; padding-inline: 12px 12px;
60
+ padding-block: 6px 6px;
61
+ padding-inline: 12px 12px;
60
62
  border: 1px solid var(--badge_error_back);
61
63
  border-radius: var(--border_radius);
62
64
  background: var(--element_background_2);
@@ -106,15 +108,14 @@ data_grid_cell.data_grid_cell_pinned_last {
106
108
  /* Наведение на строку: у закреплённой ячейки свой непрозрачный фон, поэтому заливку
107
109
  строки она перекрывает — плотность поднимаем её же слоями */
108
110
  chui_data_grid data_grid_body data_grid_row:hover data_grid_cell.data_grid_cell_pinned {
109
- background: linear-gradient(var(--element_background_hover), var(--element_background_hover)),
110
- var(--data_grid_body);
111
+ background:
112
+ linear-gradient(var(--element_background_hover), var(--element_background_hover)), var(--data_grid_body);
111
113
  }
112
114
 
113
115
  chui_data_grid data_grid_row[aria-selected="true"] data_grid_cell.data_grid_cell_pinned {
114
116
  /* Тонировка выделения поверх непрозрачной поверхности — закреплённая ячейка и в выделенной
115
117
  строке не просвечивает прокрученным содержимым */
116
- background: linear-gradient(var(--data_grid_selection), var(--data_grid_selection)),
117
- var(--data_grid_body);
118
+ background: linear-gradient(var(--data_grid_selection), var(--data_grid_selection)), var(--data_grid_body);
118
119
  }
119
120
 
120
121
  /* Полоса выделения — на первой ячейке: закреплённая ячейка перекрывает фон строки,
@@ -422,7 +423,8 @@ data_grid_cell.data_grid_cell_editing {
422
423
  /* Отступ снимаем: у своих редакторов-компонентов он свой (`margin: var(--margin)`),
423
424
  и поле съезжало в ячейке */
424
425
  margin: 0;
425
- padding-block: 0 0; padding-inline: 8px 8px;
426
+ padding-block: 0 0;
427
+ padding-inline: 8px 8px;
426
428
  border: 1px solid var(--blue_prime_background);
427
429
  border-radius: var(--border_radius);
428
430
  /* Приподнятая непрозрачная поверхность — та же, что у полей фреймворка: непрозрачная,
@@ -467,7 +469,7 @@ data_grid_row:has(data_grid_cell.data_grid_cell_editing) {
467
469
  }
468
470
 
469
471
  /* Крутилка числа — системная: значение правят клавишами, поэтому вид у поля свой */
470
- input[type=number].data_grid_editor::-webkit-inner-spin-button {
472
+ input[type="number"].data_grid_editor::-webkit-inner-spin-button {
471
473
  -webkit-appearance: none;
472
474
  }
473
475
 
@@ -1,5 +1,5 @@
1
- const {setStyles, optionOr} = require('../../modules/chui_functions');
2
- const {I18n} = require('../../modules/chui_i18n/chui_i18n');
1
+ const { setStyles, optionOr } = require("../../modules/chui_functions");
2
+ const { I18n } = require("../../modules/chui_i18n/chui_i18n");
3
3
 
4
4
  /**
5
5
  * Список свойств: пары «подпись — значение» одной таблицей — для панели свойств, карточки
@@ -34,11 +34,11 @@ const {I18n} = require('../../modules/chui_i18n/chui_i18n');
34
34
  class Descriptions {
35
35
  static LAYOUT = {
36
36
  HORIZONTAL: "horizontal",
37
- VERTICAL: "vertical"
37
+ VERTICAL: "vertical",
38
38
  };
39
39
  static SIZE = {
40
40
  DEFAULT: "default",
41
- SMALL: "small"
41
+ SMALL: "small",
42
42
  };
43
43
  static #counter = 0;
44
44
  static #MAX_COLUMNS = 4;
@@ -52,11 +52,18 @@ class Descriptions {
52
52
  #columns = 1;
53
53
  #bordered = false;
54
54
 
55
- constructor(options = {
56
- id: String(), title: String(), items: [],
57
- columns: Number(), bordered: Boolean(),
58
- layout: String(), size: String(), label: String()
59
- }) {
55
+ constructor(
56
+ options = {
57
+ id: String(),
58
+ title: String(),
59
+ items: [],
60
+ columns: Number(),
61
+ bordered: Boolean(),
62
+ layout: String(),
63
+ size: String(),
64
+ label: String(),
65
+ }
66
+ ) {
60
67
  setStyles(__dirname + "/styles.css", "chUiJS_Descriptions");
61
68
  Descriptions.#counter += 1;
62
69
  this.#id = optionOr(options.id, `chui_descriptions_${Descriptions.#counter}`);
@@ -93,7 +100,7 @@ class Descriptions {
93
100
  return this.#entries.map((entry) => ({
94
101
  label: entry.label,
95
102
  value: entry.value,
96
- span: Math.min(entry.span, this.#columns)
103
+ span: Math.min(entry.span, this.#columns),
97
104
  }));
98
105
  }
99
106
 
@@ -149,14 +156,16 @@ class Descriptions {
149
156
 
150
157
  /** Раскладка пары: подпись слева от значения или над ним */
151
158
  setLayout(layout = String()) {
152
- const known = layout === Descriptions.LAYOUT.VERTICAL ? Descriptions.LAYOUT.VERTICAL : Descriptions.LAYOUT.HORIZONTAL;
159
+ const known =
160
+ layout === Descriptions.LAYOUT.VERTICAL ? Descriptions.LAYOUT.VERTICAL : Descriptions.LAYOUT.HORIZONTAL;
153
161
  this.#root.dataset.layout = known;
154
162
  return this;
155
163
  }
156
164
 
157
165
  /** Размер строк: `Descriptions.SIZE.{DEFAULT, SMALL}` */
158
166
  setSize(size = String()) {
159
- this.#root.dataset.size = size === Descriptions.SIZE.SMALL ? Descriptions.SIZE.SMALL : Descriptions.SIZE.DEFAULT;
167
+ this.#root.dataset.size =
168
+ size === Descriptions.SIZE.SMALL ? Descriptions.SIZE.SMALL : Descriptions.SIZE.DEFAULT;
160
169
  return this;
161
170
  }
162
171
 
@@ -197,10 +206,18 @@ class Descriptions {
197
206
  #push(item = undefined) {
198
207
  if (item === undefined || item === null) return;
199
208
  const label = item.label === undefined ? "" : String(item.label);
200
- const span = Number.isFinite(Number(item.span)) && Math.floor(Number(item.span)) >= 1
201
- ? Math.floor(Number(item.span))
202
- : 1;
203
- this.#entries.push({label: label, value: item.value, span: span, node: undefined, term: undefined, value_node: undefined});
209
+ const span =
210
+ Number.isFinite(Number(item.span)) && Math.floor(Number(item.span)) >= 1
211
+ ? Math.floor(Number(item.span))
212
+ : 1;
213
+ this.#entries.push({
214
+ label: label,
215
+ value: item.value,
216
+ span: span,
217
+ node: undefined,
218
+ term: undefined,
219
+ value_node: undefined,
220
+ });
204
221
  }
205
222
 
206
223
  #render() {
@@ -250,4 +267,4 @@ class Descriptions {
250
267
  }
251
268
  }
252
269
 
253
- exports.Descriptions = Descriptions
270
+ exports.Descriptions = Descriptions;
@@ -1,6 +1,6 @@
1
- const {Icon, Icons} = require("../chui_icons/icons");
1
+ const { Icon, Icons } = require("../chui_icons/icons");
2
2
 
3
- const {makeKeyboardButton} = require("../../modules/chui_a11y/chui_a11y");
3
+ const { makeKeyboardButton } = require("../../modules/chui_a11y/chui_a11y");
4
4
 
5
5
  /** Идентификаторы для aria-controls у раскрывающихся панелей */
6
6
  let disclosure_panel_counter = 0;
@@ -9,23 +9,29 @@ class Details {
9
9
  #name = require("randomstring").generate();
10
10
  #chui_details = document.createElement(`chui_details`);
11
11
  //
12
- #ab = document.createElement('details_button')
13
- #bt = document.createElement('details_button_text')
14
- #barrow = document.createElement('details_button_arrow')
12
+ #ab = document.createElement("details_button");
13
+ #bt = document.createElement("details_button_text");
14
+ #barrow = document.createElement("details_button_arrow");
15
15
  //
16
- #ap = document.createElement('details_panel')
17
- #html = document.createElement('details_panel_html')
16
+ #ap = document.createElement("details_panel");
17
+ #html = document.createElement("details_panel_html");
18
18
  #direction;
19
19
  #wrap;
20
20
  #align;
21
21
  #justify;
22
22
  #width;
23
- constructor(options = {
24
- title: String(), contenteditable: Boolean(),
25
- direction: String(), wrap: String(), align: String(),
26
- justify: String(), width: String()
27
- }) {
28
- require('../../modules/chui_functions').setStyles(__dirname + "/styles.css", 'chUiJS_Details');
23
+ constructor(
24
+ options = {
25
+ title: String(),
26
+ contenteditable: Boolean(),
27
+ direction: String(),
28
+ wrap: String(),
29
+ align: String(),
30
+ justify: String(),
31
+ width: String(),
32
+ }
33
+ ) {
34
+ require("../../modules/chui_functions").setStyles(__dirname + "/styles.css", "chUiJS_Details");
29
35
  this.#direction = options.direction;
30
36
  this.#wrap = options.wrap;
31
37
  this.#align = options.align;
@@ -33,7 +39,7 @@ class Details {
33
39
  this.#width = options.width;
34
40
  // Заготовка опции (`Boolean()`) равносильна незаданной: без проверки в разметке оставался
35
41
  // `contenteditable="undefined"` — посторонний атрибут на каждой панели
36
- if (options.contenteditable !== undefined) this.#html.setAttribute('contenteditable', options.contenteditable);
42
+ if (options.contenteditable !== undefined) this.#html.setAttribute("contenteditable", options.contenteditable);
37
43
 
38
44
  if (this.#direction !== undefined) this.#html.style.flexDirection = this.#direction;
39
45
  if (this.#wrap !== undefined) this.#html.style.flexWrap = this.#wrap;
@@ -46,23 +52,23 @@ class Details {
46
52
  this.#html.style.width = this.#width;
47
53
  }
48
54
 
49
- this.#ab.setAttribute('name', this.#name)
55
+ this.#ab.setAttribute("name", this.#name);
50
56
  // Пустая заготовка (`title: String()` в описании опций) — это «заголовка нет»,
51
57
  // а не текст «undefined» в кнопке раскрытия
52
58
  this.#bt.innerText = options.title === undefined || options.title === null ? "" : String(options.title);
53
59
  this.#barrow.innerHTML = new Icon(Icons.HARDWARE.KEYBOARD_ARROW_DOWN).getHTML();
54
- this.#ab.appendChild(this.#bt)
55
- this.#ab.appendChild(this.#barrow)
56
- this.#ap.appendChild(this.#html)
57
- this.#chui_details.appendChild(this.#ab)
58
- this.#chui_details.appendChild(this.#ap)
60
+ this.#ab.appendChild(this.#bt);
61
+ this.#ab.appendChild(this.#barrow);
62
+ this.#ap.appendChild(this.#html);
63
+ this.#chui_details.appendChild(this.#ab);
64
+ this.#chui_details.appendChild(this.#ap);
59
65
 
60
66
  //ФУНКЦИИ
61
67
  let test = this.#chui_details.children;
62
68
  let i;
63
69
  for (i = 0; i < test.length; i++) {
64
70
  let elem = test[i];
65
- if (elem.tagName === 'DETAILS_BUTTON') {
71
+ if (elem.tagName === "DETAILS_BUTTON") {
66
72
  let panel = elem.nextElementSibling;
67
73
  // Доступность: кнопка раскрытия — role=button с состоянием, панель — отдельный регион
68
74
  panel.id = "chui_details_panel_" + (disclosure_panel_counter += 1);
@@ -73,8 +79,8 @@ class Details {
73
79
  // Tab и в дереве доступности — поэтому свёрнутая панель помечается инерт
74
80
  panel.inert = true;
75
81
  makeKeyboardButton(elem);
76
- elem.addEventListener('click', () => {
77
- elem.classList.toggle('details_active')
82
+ elem.addEventListener("click", () => {
83
+ elem.classList.toggle("details_active");
78
84
  let panel = elem.nextElementSibling;
79
85
  // Стрелка и углы кнопки зависят от `aria-expanded` — их ведёт CSS,
80
86
  // а инлайном остаётся только измеренная высота панели
@@ -85,8 +91,8 @@ class Details {
85
91
  panel.inert = false;
86
92
  panel.style.maxHeight = panel.scrollHeight + "px";
87
93
  }
88
- elem.setAttribute("aria-expanded", elem.classList.contains('details_active') ? "true" : "false");
89
- })
94
+ elem.setAttribute("aria-expanded", elem.classList.contains("details_active") ? "true" : "false");
95
+ });
90
96
  }
91
97
  }
92
98
  }
@@ -100,4 +106,4 @@ class Details {
100
106
  }
101
107
  }
102
108
 
103
- exports.Details = Details
109
+ exports.Details = Details;
@@ -7,7 +7,7 @@ chui_details {
7
7
  width: -webkit-fill-available;
8
8
  margin: var(--margin);
9
9
  font-size: var(--font_default_size);
10
- font-weight:400;
10
+ font-weight: 400;
11
11
  border-radius: var(--border_radius);
12
12
  border: none;
13
13
  }
@@ -52,7 +52,7 @@ details_panel {
52
52
  details_panel_html {
53
53
  padding: 8px 0;
54
54
  width: -webkit-fill-available;
55
- display: flex
55
+ display: flex;
56
56
  }
57
57
 
58
58
  details_button:hover {
@@ -60,7 +60,8 @@ details_button:hover {
60
60
  }
61
61
 
62
62
  details_button:active {
63
- background: var(--element_background_prime); color: var(--text_color_hover);
63
+ background: var(--element_background_prime);
64
+ color: var(--text_color_hover);
64
65
  }
65
66
 
66
67
  details_button:hover details_button_text {
@@ -98,4 +99,4 @@ details_button[aria-expanded="true"] details_button_arrow chui_icon {
98
99
 
99
100
  details_button[aria-expanded="false"] details_button_arrow chui_icon {
100
101
  transform: rotate(0deg);
101
- }
102
+ }
@@ -1,5 +1,5 @@
1
- const {setStyles} = require("../../modules/chui_functions");
2
- const {I18n} = require("../../modules/chui_i18n/chui_i18n");
1
+ const { setStyles } = require("../../modules/chui_functions");
2
+ const { I18n } = require("../../modules/chui_i18n/chui_i18n");
3
3
 
4
4
  /** Типы строк модели сравнения */
5
5
  const EQUAL = "equal";
@@ -46,8 +46,8 @@ const GAP = "gap";
46
46
  * Слушателей вне своих узлов нет, поэтому `destroy()` не нужен.
47
47
  */
48
48
  class DiffViewer {
49
- static MODE = {SIDE_BY_SIDE: "side", UNIFIED: "unified"};
50
- static ROW = {EQUAL: EQUAL, INSERT: INSERT, DELETE: DELETE, REPLACE: REPLACE, GAP: GAP};
49
+ static MODE = { SIDE_BY_SIDE: "side", UNIFIED: "unified" };
50
+ static ROW = { EQUAL: EQUAL, INSERT: INSERT, DELETE: DELETE, REPLACE: REPLACE, GAP: GAP };
51
51
  /** Предел таблицы LCS (ячеек): больше — середина расхождения показывается одним блоком */
52
52
  static LCS_LIMIT = 250000;
53
53
  static #counter = 0;
@@ -79,26 +79,28 @@ class DiffViewer {
79
79
  #label_text = undefined;
80
80
  #empty_text = undefined;
81
81
  #rows = [];
82
- #stats_data = {equal: 0, added: 0, removed: 0, changed: 0, groups: 0};
82
+ #stats_data = { equal: 0, added: 0, removed: 0, changed: 0, groups: 0 };
83
83
  #approximate = false;
84
84
  #expanded = [];
85
85
  #active_index = undefined;
86
86
  #focus_index = undefined;
87
87
 
88
- constructor(options = {
89
- id: String(),
90
- title: String(),
91
- label: String(),
92
- left: String(),
93
- right: String(),
94
- leftTitle: String(),
95
- rightTitle: String(),
96
- mode: String(),
97
- context: Number(),
98
- lineNumbers: Boolean(),
99
- height: String(),
100
- emptyText: String()
101
- }) {
88
+ constructor(
89
+ options = {
90
+ id: String(),
91
+ title: String(),
92
+ label: String(),
93
+ left: String(),
94
+ right: String(),
95
+ leftTitle: String(),
96
+ rightTitle: String(),
97
+ mode: String(),
98
+ context: Number(),
99
+ lineNumbers: Boolean(),
100
+ height: String(),
101
+ emptyText: String(),
102
+ }
103
+ ) {
102
104
  require("../../modules/chui_fonts").installMono();
103
105
  setStyles(__dirname + "/styles.css", "chUiJS_DiffViewer");
104
106
  DiffViewer.#counter += 1;
@@ -196,14 +198,16 @@ class DiffViewer {
196
198
 
197
199
  /** Строки с учётом свёрнутых участков: у пропуска `{type: "gap", from, to}` (индексы модели) */
198
200
  getVisibleRows() {
199
- return this.#visibleRows().map((entry) => (entry.type === GAP
200
- ? {type: GAP, from: entry.from, to: entry.to}
201
- : DiffViewer.#describe(entry.row)));
201
+ return this.#visibleRows().map((entry) =>
202
+ entry.type === GAP ? { type: GAP, from: entry.from, to: entry.to } : DiffViewer.#describe(entry.row)
203
+ );
202
204
  }
203
205
 
204
206
  /** Показан ли хоть один пропуск */
205
207
  getGaps() {
206
- return this.#visibleRows().filter((entry) => entry.type === GAP).map((entry) => ({from: entry.from, to: entry.to}));
208
+ return this.#visibleRows()
209
+ .filter((entry) => entry.type === GAP)
210
+ .map((entry) => ({ from: entry.from, to: entry.to }));
207
211
  }
208
212
 
209
213
  getContext() {
@@ -317,7 +321,7 @@ class DiffViewer {
317
321
 
318
322
  /** Раскрыть пропуск по индексам модели (как кнопка «Показать N строк») */
319
323
  expandRange(from = Number(), to = Number()) {
320
- this.#expanded.push({from: Number(from), to: Number(to)});
324
+ this.#expanded.push({ from: Number(from), to: Number(to) });
321
325
  this.#focus_index = Number(from);
322
326
  this.#render();
323
327
  return this;
@@ -380,9 +384,9 @@ class DiffViewer {
380
384
  }
381
385
 
382
386
  static #describe(row = Object()) {
383
- const descriptor = {type: row.type};
384
- if (row.left !== undefined) descriptor.left = {number: row.left.number, text: row.left.text};
385
- if (row.right !== undefined) descriptor.right = {number: row.right.number, text: row.right.text};
387
+ const descriptor = { type: row.type };
388
+ if (row.left !== undefined) descriptor.left = { number: row.left.number, text: row.left.text };
389
+ if (row.right !== undefined) descriptor.right = { number: row.right.number, text: row.right.text };
386
390
  return descriptor;
387
391
  }
388
392
 
@@ -394,9 +398,10 @@ class DiffViewer {
394
398
  const table = new Int32Array((rows + 1) * width);
395
399
  for (let i = rows - 1; i >= 0; i -= 1) {
396
400
  for (let j = columns - 1; j >= 0; j -= 1) {
397
- table[i * width + j] = left[i] === right[j]
398
- ? table[(i + 1) * width + (j + 1)] + 1
399
- : Math.max(table[(i + 1) * width + j], table[i * width + (j + 1)]);
401
+ table[i * width + j] =
402
+ left[i] === right[j]
403
+ ? table[(i + 1) * width + (j + 1)] + 1
404
+ : Math.max(table[(i + 1) * width + j], table[i * width + (j + 1)]);
400
405
  }
401
406
  }
402
407
  const pairs = [];
@@ -419,14 +424,14 @@ class DiffViewer {
419
424
  let li = 0;
420
425
  let ri = 0;
421
426
  for (const [i, j] of DiffViewer.#pairs(left, right)) {
422
- if (i > li) operations.push({type: DELETE, from: li, to: i});
423
- if (j > ri) operations.push({type: INSERT, from: ri, to: j});
424
- operations.push({type: EQUAL, i: i, j: j});
427
+ if (i > li) operations.push({ type: DELETE, from: li, to: i });
428
+ if (j > ri) operations.push({ type: INSERT, from: ri, to: j });
429
+ operations.push({ type: EQUAL, i: i, j: j });
425
430
  li = i + 1;
426
431
  ri = j + 1;
427
432
  }
428
- if (li < left.length) operations.push({type: DELETE, from: li, to: left.length});
429
- if (ri < right.length) operations.push({type: INSERT, from: ri, to: right.length});
433
+ if (li < left.length) operations.push({ type: DELETE, from: li, to: left.length });
434
+ if (ri < right.length) operations.push({ type: INSERT, from: ri, to: right.length });
430
435
  return operations;
431
436
  }
432
437
 
@@ -435,8 +440,12 @@ class DiffViewer {
435
440
  let prefix = 0;
436
441
  while (prefix < left.length && prefix < right.length && left[prefix] === right[prefix]) prefix += 1;
437
442
  let suffix = 0;
438
- while (suffix < left.length - prefix && suffix < right.length - prefix &&
439
- left[left.length - 1 - suffix] === right[right.length - 1 - suffix]) suffix += 1;
443
+ while (
444
+ suffix < left.length - prefix &&
445
+ suffix < right.length - prefix &&
446
+ left[left.length - 1 - suffix] === right[right.length - 1 - suffix]
447
+ )
448
+ suffix += 1;
440
449
  const rows = [];
441
450
  for (let i = 0; i < prefix; i += 1) rows.push(DiffViewer.#equalRow(left[i], i + 1, right[i], i + 1));
442
451
  const mid_left = left.slice(prefix, left.length - suffix);
@@ -447,8 +456,8 @@ class DiffViewer {
447
456
  // Предел алгоритма: вместо честного (но не помещающегося) LCS показываем один блок
448
457
  this.#approximate = true;
449
458
  operations = [];
450
- if (mid_left.length > 0) operations.push({type: DELETE, from: 0, to: mid_left.length});
451
- if (mid_right.length > 0) operations.push({type: INSERT, from: 0, to: mid_right.length});
459
+ if (mid_left.length > 0) operations.push({ type: DELETE, from: 0, to: mid_left.length });
460
+ if (mid_right.length > 0) operations.push({ type: INSERT, from: 0, to: mid_right.length });
452
461
  } else {
453
462
  operations = DiffViewer.#operations(mid_left, mid_right);
454
463
  }
@@ -465,8 +474,8 @@ class DiffViewer {
465
474
  static #equalRow(left_text = String(), left_number = Number(), right_text = String(), right_number = Number()) {
466
475
  return {
467
476
  type: EQUAL,
468
- left: {number: left_number, text: left_text},
469
- right: {number: right_number, text: right_text}
477
+ left: { number: left_number, text: left_text },
478
+ right: { number: right_number, text: right_text },
470
479
  };
471
480
  }
472
481
 
@@ -485,28 +494,37 @@ class DiffViewer {
485
494
  const has_right = ri < next.to;
486
495
  rows.push({
487
496
  type: has_left && has_right ? REPLACE : has_left ? DELETE : INSERT,
488
- left: has_left ? {number: offset + li + 1, text: left[li]} : undefined,
489
- right: has_right ? {number: offset + ri + 1, text: right[ri]} : undefined
497
+ left: has_left ? { number: offset + li + 1, text: left[li] } : undefined,
498
+ right: has_right ? { number: offset + ri + 1, text: right[ri] } : undefined,
490
499
  });
491
500
  }
492
501
  index += 1;
493
502
  continue;
494
503
  }
495
504
  if (operation.type === EQUAL) {
496
- rows.push(DiffViewer.#equalRow(left[operation.i], offset + operation.i + 1, right[operation.j], offset + operation.j + 1));
505
+ rows.push(
506
+ DiffViewer.#equalRow(
507
+ left[operation.i],
508
+ offset + operation.i + 1,
509
+ right[operation.j],
510
+ offset + operation.j + 1
511
+ )
512
+ );
497
513
  continue;
498
514
  }
499
515
  for (let i = operation.from; i < operation.to; i += 1) {
500
- rows.push(operation.type === DELETE
501
- ? {type: DELETE, left: {number: offset + i + 1, text: left[i]}, right: undefined}
502
- : {type: INSERT, left: undefined, right: {number: offset + i + 1, text: right[i]}});
516
+ rows.push(
517
+ operation.type === DELETE
518
+ ? { type: DELETE, left: { number: offset + i + 1, text: left[i] }, right: undefined }
519
+ : { type: INSERT, left: undefined, right: { number: offset + i + 1, text: right[i] } }
520
+ );
503
521
  }
504
522
  }
505
523
  return rows;
506
524
  }
507
525
 
508
526
  #collectStats() {
509
- const stats = {equal: 0, added: 0, removed: 0, changed: 0, groups: 0};
527
+ const stats = { equal: 0, added: 0, removed: 0, changed: 0, groups: 0 };
510
528
  for (const row of this.#rows) {
511
529
  if (row.type === EQUAL) stats.equal += 1;
512
530
  if (row.type === INSERT) stats.added += 1;
@@ -538,7 +556,8 @@ class DiffViewer {
538
556
  const total = this.#rows.length;
539
557
  const list = [];
540
558
  if (this.#context === Infinity || this.#stats_data.groups === 0) {
541
- for (let index = 0; index < total; index += 1) list.push({type: this.#rows[index].type, row: this.#rows[index], index: index});
559
+ for (let index = 0; index < total; index += 1)
560
+ list.push({ type: this.#rows[index].type, row: this.#rows[index], index: index });
542
561
  return list;
543
562
  }
544
563
  const context = Number.isFinite(this.#context) ? Math.max(0, Math.floor(this.#context)) : 0;
@@ -553,16 +572,16 @@ class DiffViewer {
553
572
  for (let index = 0; index < total; index += 1) {
554
573
  if (keep[index] || this.#isExpanded(index)) {
555
574
  if (gap !== undefined) {
556
- list.push({type: GAP, from: gap.from, to: gap.to});
575
+ list.push({ type: GAP, from: gap.from, to: gap.to });
557
576
  gap = undefined;
558
577
  }
559
- list.push({type: this.#rows[index].type, row: this.#rows[index], index: index});
578
+ list.push({ type: this.#rows[index].type, row: this.#rows[index], index: index });
560
579
  continue;
561
580
  }
562
- if (gap === undefined) gap = {from: index, to: index};
581
+ if (gap === undefined) gap = { from: index, to: index };
563
582
  else gap.to = index;
564
583
  }
565
- if (gap !== undefined) list.push({type: GAP, from: gap.from, to: gap.to});
584
+ if (gap !== undefined) list.push({ type: GAP, from: gap.from, to: gap.to });
566
585
  return list;
567
586
  }
568
587
 
@@ -612,9 +631,9 @@ class DiffViewer {
612
631
 
613
632
  // Вид изменения словами: номер строки берётся из «своей» версии текста
614
633
  #rowLabel(row = Object()) {
615
- if (row.type === INSERT) return I18n.t("diffViewer.lineAdded", {number: row.right.number});
616
- if (row.type === DELETE) return I18n.t("diffViewer.lineRemoved", {number: row.left.number});
617
- if (row.type === REPLACE) return I18n.t("diffViewer.lineChanged", {number: row.left.number});
634
+ if (row.type === INSERT) return I18n.t("diffViewer.lineAdded", { number: row.right.number });
635
+ if (row.type === DELETE) return I18n.t("diffViewer.lineRemoved", { number: row.left.number });
636
+ if (row.type === REPLACE) return I18n.t("diffViewer.lineChanged", { number: row.left.number });
618
637
  return undefined;
619
638
  }
620
639
 
@@ -696,7 +715,7 @@ class DiffViewer {
696
715
  button.className = "diff_viewer_expand";
697
716
  button.dataset.from = String(entry.from);
698
717
  button.dataset.to = String(entry.to);
699
- button.innerText = I18n.t("diffViewer.showLines", {count: count});
718
+ button.innerText = I18n.t("diffViewer.showLines", { count: count });
700
719
  cell.appendChild(button);
701
720
  node.appendChild(cell);
702
721
  return node;
@@ -720,7 +739,10 @@ class DiffViewer {
720
739
  return this;
721
740
  }
722
741
  this.#status.innerText = I18n.t("diffViewer.summary", {
723
- groups: stats.groups, added: stats.added, removed: stats.removed, changed: stats.changed
742
+ groups: stats.groups,
743
+ added: stats.added,
744
+ removed: stats.removed,
745
+ changed: stats.changed,
724
746
  });
725
747
  return this;
726
748
  }
@@ -732,9 +754,10 @@ class DiffViewer {
732
754
  if (focused !== null && focused.dataset.index !== undefined) this.#focus_index = Number(focused.dataset.index);
733
755
  this.#head_row.innerHTML = "";
734
756
  this.#body.innerHTML = "";
735
- const titles = this.#mode === DiffViewer.MODE.UNIFIED
736
- ? [I18n.t("diffViewer.changes")]
737
- : [this.#left_title, this.#right_title];
757
+ const titles =
758
+ this.#mode === DiffViewer.MODE.UNIFIED
759
+ ? [I18n.t("diffViewer.changes")]
760
+ : [this.#left_title, this.#right_title];
738
761
  for (const title of titles) {
739
762
  const cell = document.createElement("div");
740
763
  cell.className = "diff_viewer_head_cell";
@@ -745,7 +768,8 @@ class DiffViewer {
745
768
  this.#grid.setAttribute("aria-colcount", String(titles.length));
746
769
  this.#grid.classList.toggle("diff_viewer_grid_unified", this.#mode === DiffViewer.MODE.UNIFIED);
747
770
  const list = this.#visibleRows();
748
- for (const entry of list) this.#body.appendChild(entry.type === GAP ? this.#gapNode(entry) : this.#rowNode(entry));
771
+ for (const entry of list)
772
+ this.#body.appendChild(entry.type === GAP ? this.#gapNode(entry) : this.#rowNode(entry));
749
773
  this.#grid.setAttribute("aria-rowcount", String(list.length + 1));
750
774
  this.#grid.hidden = this.#rows.length === 0;
751
775
  this.#empty.hidden = this.#stats_data.groups !== 0;
@@ -784,11 +808,12 @@ class DiffViewer {
784
808
  }
785
809
 
786
810
  #focusIndexAt(index = Number()) {
787
- const row = [...this.#body.querySelectorAll(".diff_viewer_row")]
788
- .find((node) => Number(node.dataset.index) === Number(index));
811
+ const row = [...this.#body.querySelectorAll(".diff_viewer_row")].find(
812
+ (node) => Number(node.dataset.index) === Number(index)
813
+ );
789
814
  if (row === undefined) return this;
790
815
  this.#focusRow(row);
791
- row.scrollIntoView({block: "nearest"});
816
+ row.scrollIntoView({ block: "nearest" });
792
817
  return this;
793
818
  }
794
819
 
@@ -864,4 +889,4 @@ class DiffViewer {
864
889
  };
865
890
  }
866
891
 
867
- exports.DiffViewer = DiffViewer
892
+ exports.DiffViewer = DiffViewer;
@@ -13,7 +13,7 @@ chui_diff_viewer {
13
13
  border-radius: var(--border_radius);
14
14
  background: var(--element_background);
15
15
  color: var(--text_color);
16
- font-family: 'chui_mono', monospace;
16
+ font-family: "chui_mono", monospace;
17
17
  font-size: var(--font_default_size);
18
18
  }
19
19