chuijs 4.0.2 → 4.0.4

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 (292) hide show
  1. package/CHANGELOG.md +597 -0
  2. package/README.md +43 -644
  3. package/framework/appLayout/default/chui_app_layout.js +602 -496
  4. package/framework/appLayout/default/global_style.css +288 -97
  5. package/framework/appLayout/default/main_theme_style.css +188 -101
  6. package/framework/components/chui_accordion/accordion.js +38 -35
  7. package/framework/components/chui_accordion/styles.css +13 -12
  8. package/framework/components/chui_action_sheet/action_sheet.js +93 -64
  9. package/framework/components/chui_action_sheet/styles.css +12 -5
  10. package/framework/components/chui_actions_bar/actions_bar.js +338 -0
  11. package/framework/components/chui_actions_bar/styles.css +139 -0
  12. package/framework/components/chui_affix/affix.js +16 -11
  13. package/framework/components/chui_affix/styles.css +5 -0
  14. package/framework/components/chui_alert/alert.js +34 -19
  15. package/framework/components/chui_alert/styles.css +7 -0
  16. package/framework/components/chui_avatar/avatar.js +36 -35
  17. package/framework/components/chui_avatar/styles.css +1 -1
  18. package/framework/components/chui_avatar_group/avatar_group.js +25 -23
  19. package/framework/components/chui_avatar_group/styles.css +1 -1
  20. package/framework/components/chui_backtop/backtop.js +60 -21
  21. package/framework/components/chui_backtop/styles.css +21 -0
  22. package/framework/components/chui_badge/badge.js +30 -28
  23. package/framework/components/chui_badge/styles.css +6 -6
  24. package/framework/components/chui_banner/banner.js +222 -0
  25. package/framework/components/chui_banner/styles.css +170 -0
  26. package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
  27. package/framework/components/chui_breadcrumb/styles.css +1 -1
  28. package/framework/components/chui_button/button.js +52 -36
  29. package/framework/components/chui_button/styles.css +7 -7
  30. package/framework/components/chui_calendar/calendar.js +18 -16
  31. package/framework/components/chui_card/card.js +52 -32
  32. package/framework/components/chui_card_scroll/card_scroll.js +169 -0
  33. package/framework/components/chui_card_scroll/styles.css +86 -0
  34. package/framework/components/chui_chat/chat.js +140 -79
  35. package/framework/components/chui_chat/styles.css +18 -7
  36. package/framework/components/chui_clipboard_history/clipboard_history.js +53 -39
  37. package/framework/components/chui_clipboard_history/styles.css +13 -9
  38. package/framework/components/chui_code/code.js +10 -10
  39. package/framework/components/chui_code/styles.css +4 -4
  40. package/framework/components/chui_code_editor/code_editor.js +73 -57
  41. package/framework/components/chui_code_editor/styles.css +6 -5
  42. package/framework/components/chui_command_palette/command_palette.js +87 -64
  43. package/framework/components/chui_command_palette/styles.css +5 -5
  44. package/framework/components/chui_console/console.js +13 -13
  45. package/framework/components/chui_console/styles.css +6 -3
  46. package/framework/components/chui_content_block/content_block.js +35 -21
  47. package/framework/components/chui_content_block/styles.css +2 -2
  48. package/framework/components/chui_context_menu/context_menu.js +171 -58
  49. package/framework/components/chui_context_menu/styles.css +82 -8
  50. package/framework/components/chui_custom_element/custom_element.js +25 -18
  51. package/framework/components/chui_data_grid/data_grid.js +633 -471
  52. package/framework/components/chui_data_grid/styles.css +24 -22
  53. package/framework/components/chui_descriptions/descriptions.js +34 -17
  54. package/framework/components/chui_descriptions/styles.css +1 -1
  55. package/framework/components/chui_details/details.js +42 -36
  56. package/framework/components/chui_details/styles.css +12 -11
  57. package/framework/components/chui_diff_viewer/diff_viewer.js +172 -147
  58. package/framework/components/chui_diff_viewer/styles.css +10 -10
  59. package/framework/components/chui_divider/divider.js +19 -17
  60. package/framework/components/chui_divider/styles.css +2 -2
  61. package/framework/components/chui_drawer/drawer.js +63 -38
  62. package/framework/components/chui_drawer/styles.css +18 -4
  63. package/framework/components/chui_drop_zone/drop_zone.js +37 -27
  64. package/framework/components/chui_drop_zone/styles.css +10 -6
  65. package/framework/components/chui_empty_state/empty_state.js +20 -15
  66. package/framework/components/chui_fieldset/fieldset.js +40 -23
  67. package/framework/components/chui_fieldset/styles.css +6 -6
  68. package/framework/components/chui_file_explorer/file_explorer.js +260 -189
  69. package/framework/components/chui_file_explorer/styles.css +8 -7
  70. package/framework/components/chui_form/form.js +40 -28
  71. package/framework/components/chui_form/styles.css +1 -1
  72. package/framework/components/chui_gantt/gantt.js +102 -78
  73. package/framework/components/chui_gantt/styles.css +5 -5
  74. package/framework/components/chui_graphs/graphs.js +376 -239
  75. package/framework/components/chui_graphs/styles.css +27 -6
  76. package/framework/components/chui_hero/hero.js +98 -37
  77. package/framework/components/chui_hero/styles.css +176 -7
  78. package/framework/components/chui_html_block/html_block.js +8 -8
  79. package/framework/components/chui_html_block/styles.css +3 -3
  80. package/framework/components/chui_hx/hx.js +3 -3
  81. package/framework/components/chui_hx/styles.css +13 -6
  82. package/framework/components/chui_icons/icons.js +2115 -2115
  83. package/framework/components/chui_icons/styles.css +4 -3
  84. package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
  85. package/framework/components/chui_inputs/chui_check_box/styles.css +30 -21
  86. package/framework/components/chui_inputs/chui_chips/chips.js +141 -70
  87. package/framework/components/chui_inputs/chui_chips/styles.css +32 -7
  88. package/framework/components/chui_inputs/chui_color_picker/color_picker.js +55 -38
  89. package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
  90. package/framework/components/chui_inputs/chui_combo_box/combo_box.js +127 -109
  91. package/framework/components/chui_inputs/chui_combo_box/styles.css +23 -21
  92. package/framework/components/chui_inputs/chui_date/date.js +161 -127
  93. package/framework/components/chui_inputs/chui_date/styles.css +20 -19
  94. package/framework/components/chui_inputs/chui_date_range/date_range.js +61 -50
  95. package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
  96. package/framework/components/chui_inputs/chui_datetime/datetime.js +47 -39
  97. package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
  98. package/framework/components/chui_inputs/chui_email/email.js +48 -36
  99. package/framework/components/chui_inputs/chui_email/styles.css +11 -11
  100. package/framework/components/chui_inputs/chui_file/file.js +71 -44
  101. package/framework/components/chui_inputs/chui_file/styles.css +23 -19
  102. package/framework/components/chui_inputs/chui_hotkey/hotkey.js +101 -76
  103. package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
  104. package/framework/components/chui_inputs/chui_masked/masked.js +83 -72
  105. package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
  106. package/framework/components/chui_inputs/chui_mention/mention.js +87 -40
  107. package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
  108. package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +242 -212
  109. package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +23 -15
  110. package/framework/components/chui_inputs/chui_number/number.js +84 -70
  111. package/framework/components/chui_inputs/chui_number/styles.css +13 -13
  112. package/framework/components/chui_inputs/chui_otp/otp.js +71 -62
  113. package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
  114. package/framework/components/chui_inputs/chui_password/password.js +72 -56
  115. package/framework/components/chui_inputs/chui_password/styles.css +15 -15
  116. package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
  117. package/framework/components/chui_inputs/chui_radio_button/styles.css +22 -22
  118. package/framework/components/chui_inputs/chui_rating/rating.js +54 -50
  119. package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
  120. package/framework/components/chui_inputs/chui_select_box/select_box.js +132 -108
  121. package/framework/components/chui_inputs/chui_select_box/styles.css +21 -21
  122. package/framework/components/chui_inputs/chui_slider/slider.js +41 -38
  123. package/framework/components/chui_inputs/chui_slider/styles.css +7 -5
  124. package/framework/components/chui_inputs/chui_text/styles.css +14 -14
  125. package/framework/components/chui_inputs/chui_text/text.js +69 -52
  126. package/framework/components/chui_inputs/chui_text_area/styles.css +14 -14
  127. package/framework/components/chui_inputs/chui_text_area/text_area.js +59 -36
  128. package/framework/components/chui_inputs/chui_time/styles.css +18 -20
  129. package/framework/components/chui_inputs/chui_time/time.js +71 -49
  130. package/framework/components/chui_inputs/chui_toggle/styles.css +13 -6
  131. package/framework/components/chui_inputs/chui_toggle/toggle.js +27 -27
  132. package/framework/components/chui_json_editor/json_editor.js +137 -127
  133. package/framework/components/chui_json_editor/styles.css +5 -5
  134. package/framework/components/chui_json_viewer/json_viewer.js +133 -114
  135. package/framework/components/chui_json_viewer/styles.css +9 -8
  136. package/framework/components/chui_kanban/kanban.js +78 -60
  137. package/framework/components/chui_kanban/styles.css +8 -4
  138. package/framework/components/chui_kbd/kbd.js +12 -10
  139. package/framework/components/chui_kbd/styles.css +1 -1
  140. package/framework/components/chui_label/label.js +31 -29
  141. package/framework/components/chui_label/styles.css +3 -3
  142. package/framework/components/chui_link/link.js +36 -29
  143. package/framework/components/chui_link/styles.css +11 -4
  144. package/framework/components/chui_list/list.js +42 -38
  145. package/framework/components/chui_list/styles.css +4 -3
  146. package/framework/components/chui_markdown_editor/markdown_editor.js +125 -109
  147. package/framework/components/chui_markdown_editor/styles.css +5 -5
  148. package/framework/components/chui_media/audio.js +457 -364
  149. package/framework/components/chui_media/audio_styles.css +74 -37
  150. package/framework/components/chui_media/image.js +99 -64
  151. package/framework/components/chui_media/image_compare.js +86 -55
  152. package/framework/components/chui_media/image_compare_styles.css +5 -5
  153. package/framework/components/chui_media/image_styles.css +4 -4
  154. package/framework/components/chui_media/video.js +264 -171
  155. package/framework/components/chui_media/video_styles.css +57 -24
  156. package/framework/components/chui_menu_bar/menu_bar.js +67 -65
  157. package/framework/components/chui_menu_bar/styles.css +14 -12
  158. package/framework/components/chui_message_bar/message_bar.js +551 -0
  159. package/framework/components/chui_message_bar/styles.css +248 -0
  160. package/framework/components/chui_modal/modal.js +81 -56
  161. package/framework/components/chui_modal/styles.css +3 -2
  162. package/framework/components/chui_notification/notification.js +107 -69
  163. package/framework/components/chui_notification/notification_download.js +28 -77
  164. package/framework/components/chui_notification/notification_download_card.js +115 -0
  165. package/framework/components/chui_notification/notification_download_progress.css +5 -4
  166. package/framework/components/chui_notification/notification_download_progress.js +73 -105
  167. package/framework/components/chui_notification/notification_update.js +44 -37
  168. package/framework/components/chui_notification/status_plate.css +3 -3
  169. package/framework/components/chui_notification/status_plate.js +2 -2
  170. package/framework/components/chui_notification/styles.css +6 -1
  171. package/framework/components/chui_notification/styles_download.css +2 -2
  172. package/framework/components/chui_notification/styles_update.css +3 -3
  173. package/framework/components/chui_org_chart/org_chart.js +101 -62
  174. package/framework/components/chui_org_chart/styles.css +2 -2
  175. package/framework/components/chui_pagination/pagination.js +65 -30
  176. package/framework/components/chui_pagination/styles.css +1 -1
  177. package/framework/components/chui_paragraph/paragraph.js +2 -2
  178. package/framework/components/chui_paragraph/styles.css +3 -3
  179. package/framework/components/chui_popover/popover.js +77 -50
  180. package/framework/components/chui_popover/styles.css +1 -1
  181. package/framework/components/chui_popups/popups.js +210 -181
  182. package/framework/components/chui_popups/styles.css +7 -7
  183. package/framework/components/chui_print_button/print_button.js +48 -33
  184. package/framework/components/chui_progress_bar/progress_bar.js +49 -19
  185. package/framework/components/chui_progress_bar/styles.css +6 -6
  186. package/framework/components/chui_progress_ring/progress_ring.js +32 -30
  187. package/framework/components/chui_progress_ring/styles.css +1 -1
  188. package/framework/components/chui_qrcode/qrcode.js +85 -41
  189. package/framework/components/chui_query_builder/query_builder.js +263 -170
  190. package/framework/components/chui_query_builder/styles.css +4 -4
  191. package/framework/components/chui_radio_group/radio_group.js +36 -26
  192. package/framework/components/chui_radio_group/styles.css +2 -2
  193. package/framework/components/chui_result/result.js +41 -31
  194. package/framework/components/chui_result/styles.css +3 -3
  195. package/framework/components/chui_scheduler/scheduler.js +126 -104
  196. package/framework/components/chui_scheduler/styles.css +11 -7
  197. package/framework/components/chui_screen_spinner/screen_spinner.js +167 -0
  198. package/framework/components/chui_screen_spinner/styles.css +49 -0
  199. package/framework/components/chui_segmented_control/segmented_control.js +90 -27
  200. package/framework/components/chui_segmented_control/styles.css +32 -6
  201. package/framework/components/chui_settings/settings.js +160 -87
  202. package/framework/components/chui_settings/styles.css +4 -4
  203. package/framework/components/chui_shortcut_help/shortcut_help.js +82 -61
  204. package/framework/components/chui_sidebar_nav/sidebar_nav.js +132 -53
  205. package/framework/components/chui_sidebar_nav/styles.css +9 -3
  206. package/framework/components/chui_skeleton/skeleton.js +29 -24
  207. package/framework/components/chui_slideshow/slideshow.js +122 -103
  208. package/framework/components/chui_slideshow/styles.css +22 -16
  209. package/framework/components/chui_spinner/spinner.js +17 -17
  210. package/framework/components/chui_spinner/styles.css +0 -1
  211. package/framework/components/chui_split_button/split_button.js +53 -30
  212. package/framework/components/chui_split_button/styles.css +22 -6
  213. package/framework/components/chui_splitter/splitter.js +46 -39
  214. package/framework/components/chui_splitter/styles.css +2 -2
  215. package/framework/components/chui_statistic/statistic.js +111 -84
  216. package/framework/components/chui_status_bar/status_bar.js +11 -9
  217. package/framework/components/chui_status_bar/styles.css +2 -2
  218. package/framework/components/chui_stepper/stepper.js +230 -54
  219. package/framework/components/chui_stepper/styles.css +79 -14
  220. package/framework/components/chui_sticky_bar/sticky_bar.js +53 -17
  221. package/framework/components/chui_sticky_bar/styles.css +11 -7
  222. package/framework/components/chui_tabs/chui_tabs.js +100 -46
  223. package/framework/components/chui_tabs/styles.css +43 -15
  224. package/framework/components/chui_text_editor/styles.css +24 -23
  225. package/framework/components/chui_text_editor/text_editor.js +103 -79
  226. package/framework/components/chui_text_editor/text_editor_panel.js +428 -367
  227. package/framework/components/chui_theme_toggle/theme_toggle.js +46 -25
  228. package/framework/components/chui_timeline/styles.css +3 -1
  229. package/framework/components/chui_timeline/timeline.js +14 -12
  230. package/framework/components/chui_toast_queue/styles.css +11 -11
  231. package/framework/components/chui_toast_queue/toast_queue.js +82 -73
  232. package/framework/components/chui_toolbar/styles.css +2 -2
  233. package/framework/components/chui_toolbar/toolbar.js +20 -13
  234. package/framework/components/chui_tooltip/styles.css +2 -2
  235. package/framework/components/chui_tooltip/tooltip.js +40 -27
  236. package/framework/components/chui_tour/styles.css +12 -7
  237. package/framework/components/chui_tour/tour.js +132 -98
  238. package/framework/components/chui_transfer/styles.css +8 -7
  239. package/framework/components/chui_transfer/transfer.js +143 -123
  240. package/framework/components/chui_tree_table/styles.css +4 -4
  241. package/framework/components/chui_tree_table/tree_table.js +88 -74
  242. package/framework/components/chui_tree_view/styles.css +14 -10
  243. package/framework/components/chui_tree_view/tree_view.js +298 -253
  244. package/framework/components/chui_user_bar/styles.css +145 -0
  245. package/framework/components/chui_user_bar/user_bar.js +402 -0
  246. package/framework/components/chui_user_list_bar/styles.css +173 -0
  247. package/framework/components/chui_user_list_bar/user_list_bar.js +485 -0
  248. package/framework/components/chui_watermark/watermark.js +41 -33
  249. package/framework/components/chui_webview/styles.css +2 -2
  250. package/framework/components/chui_webview/webview.js +64 -52
  251. package/framework/components/chui_write_bar/styles.css +172 -0
  252. package/framework/components/chui_write_bar/write_bar.js +320 -0
  253. package/framework/main_window.js +1234 -0
  254. package/framework/modules/chui_a11y/chui_a11y.js +153 -123
  255. package/framework/modules/chui_animations/animations.js +105 -43
  256. package/framework/modules/chui_animations/motion.js +120 -0
  257. package/framework/modules/chui_animations/styles.css +37 -4
  258. package/framework/modules/chui_bridge/preload.js +36 -25
  259. package/framework/modules/chui_functions.js +69 -63
  260. package/framework/modules/chui_highlight/chui_highlight.js +25 -22
  261. package/framework/modules/chui_highlight/styles.css +13 -10
  262. package/framework/modules/chui_i18n/chui_i18n.js +12 -10
  263. package/framework/modules/chui_i18n/locales/a11y.js +5 -5
  264. package/framework/modules/chui_i18n/locales/app_layout.js +5 -5
  265. package/framework/modules/chui_i18n/locales/calendar.js +3 -3
  266. package/framework/modules/chui_i18n/locales/common.js +3 -3
  267. package/framework/modules/chui_i18n/locales/data.js +36 -26
  268. package/framework/modules/chui_i18n/locales/editors.js +40 -13
  269. package/framework/modules/chui_i18n/locales/feedback.js +65 -3
  270. package/framework/modules/chui_i18n/locales/forms.js +8 -8
  271. package/framework/modules/chui_i18n/locales/graphics.js +8 -8
  272. package/framework/modules/chui_i18n/locales/media.js +4 -4
  273. package/framework/modules/chui_i18n/locales/navigation.js +12 -8
  274. package/framework/modules/chui_i18n/locales/validate.js +3 -3
  275. package/framework/modules/chui_json/chui_json.js +11 -11
  276. package/framework/modules/chui_layout/chui_layout.js +12 -10
  277. package/framework/modules/chui_logger/chui_logger.js +47 -28
  278. package/framework/modules/chui_page/page.js +39 -33
  279. package/framework/modules/chui_palette/palette.js +61 -0
  280. package/framework/modules/chui_qr/chui_qr.js +179 -88
  281. package/framework/modules/chui_scrollbar/chui_scrollbar.js +79 -68
  282. package/framework/modules/chui_scrollbar/styles.css +4 -2
  283. package/framework/modules/chui_services/chui_channels.js +27 -13
  284. package/framework/modules/chui_services/chui_services.js +47 -39
  285. package/framework/modules/chui_services/desktop.js +108 -101
  286. package/framework/modules/chui_sortable/chui_sortable.js +33 -28
  287. package/framework/modules/chui_validate/chui_validate.js +10 -7
  288. package/framework/tray_bar/chui_menu_items.js +136 -46
  289. package/index.d.ts +5046 -0
  290. package/index.js +199 -1254
  291. package/package.json +81 -68
  292. package/framework/components/telegram_bot/chui_telegram_bot.js +0 -184
@@ -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;
@@ -56,65 +56,67 @@ class DiffViewer {
56
56
  #title = document.createElement("diff_viewer_title");
57
57
  #head = document.createElement("diff_viewer_head");
58
58
  #stats = document.createElement("diff_viewer_stats");
59
- #stat_removed = document.createElement("diff_viewer_stat");
60
- #stat_added = document.createElement("diff_viewer_stat");
61
- #stat_changed = document.createElement("diff_viewer_stat");
59
+ #statRemoved = document.createElement("diff_viewer_stat");
60
+ #statAdded = document.createElement("diff_viewer_stat");
61
+ #statChanged = document.createElement("diff_viewer_stat");
62
62
  #prev = document.createElement("button");
63
63
  #next = document.createElement("button");
64
64
  #grid = document.createElement("diff_viewer_grid");
65
- #head_row = document.createElement("diff_viewer_head_row");
65
+ #headRow = document.createElement("diff_viewer_head_row");
66
66
  #body = document.createElement("diff_viewer_body");
67
67
  #empty = document.createElement("diff_viewer_empty");
68
68
  #status = document.createElement("diff_viewer_status");
69
69
  #id = undefined;
70
70
  #left = "";
71
71
  #right = "";
72
- #left_title = undefined;
73
- #right_title = undefined;
72
+ #leftTitle = undefined;
73
+ #rightTitle = undefined;
74
74
  #mode = DiffViewer.MODE.SIDE_BY_SIDE;
75
75
  #context = 3;
76
- #line_numbers = true;
76
+ #lineNumbers = true;
77
77
  #height = "360px";
78
- #title_text = undefined;
79
- #label_text = undefined;
80
- #empty_text = undefined;
78
+ #titleText = undefined;
79
+ #labelText = undefined;
80
+ #emptyText = undefined;
81
81
  #rows = [];
82
- #stats_data = {equal: 0, added: 0, removed: 0, changed: 0, groups: 0};
82
+ #statsData = { equal: 0, added: 0, removed: 0, changed: 0, groups: 0 };
83
83
  #approximate = false;
84
84
  #expanded = [];
85
- #active_index = undefined;
86
- #focus_index = undefined;
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
- }) {
85
+ #activeIndex = undefined;
86
+ #focusIndex = undefined;
87
+
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;
105
107
  this.#id = options.id === undefined ? `chui_diff_viewer_${DiffViewer.#counter}` : options.id;
106
108
  this.#root.id = this.#id;
107
109
  this.#root.setAttribute("role", "group");
108
- this.#label_text = options.label;
109
- if (options.leftTitle !== undefined) this.#left_title = String(options.leftTitle);
110
- else this.#left_title = I18n.t("diffViewer.before");
111
- if (options.rightTitle !== undefined) this.#right_title = String(options.rightTitle);
112
- else this.#right_title = I18n.t("diffViewer.after");
113
- if (options.emptyText !== undefined) this.#empty_text = String(options.emptyText);
114
- else this.#empty_text = I18n.t("diffViewer.noChanges");
110
+ this.#labelText = options.label;
111
+ if (options.leftTitle !== undefined) this.#leftTitle = String(options.leftTitle);
112
+ else this.#leftTitle = I18n.t("diffViewer.before");
113
+ if (options.rightTitle !== undefined) this.#rightTitle = String(options.rightTitle);
114
+ else this.#rightTitle = I18n.t("diffViewer.after");
115
+ if (options.emptyText !== undefined) this.#emptyText = String(options.emptyText);
116
+ else this.#emptyText = I18n.t("diffViewer.noChanges");
115
117
  this.#mode = options.mode === DiffViewer.MODE.UNIFIED ? DiffViewer.MODE.UNIFIED : DiffViewer.MODE.SIDE_BY_SIDE;
116
118
  this.#context = options.context === undefined ? this.#context : options.context;
117
- this.#line_numbers = options.lineNumbers !== false;
119
+ this.#lineNumbers = options.lineNumbers !== false;
118
120
  this.#title.className = "diff_viewer_title";
119
121
  this.#title.id = `${this.#id}_title`;
120
122
  this.#head.className = "diff_viewer_head";
@@ -123,8 +125,8 @@ class DiffViewer {
123
125
  this.#stats.setAttribute("aria-hidden", "true");
124
126
  this.#grid.className = "diff_viewer_grid";
125
127
  this.#grid.setAttribute("role", "table");
126
- this.#head_row.className = "diff_viewer_head_row";
127
- this.#head_row.setAttribute("role", "row");
128
+ this.#headRow.className = "diff_viewer_head_row";
129
+ this.#headRow.setAttribute("role", "row");
128
130
  this.#body.className = "diff_viewer_body";
129
131
  this.#body.setAttribute("role", "rowgroup");
130
132
  this.#empty.className = "diff_viewer_empty";
@@ -134,14 +136,14 @@ class DiffViewer {
134
136
  this.#buildHead();
135
137
  this.#root.appendChild(this.#title);
136
138
  this.#root.appendChild(this.#head);
137
- this.#grid.appendChild(this.#head_row);
139
+ this.#grid.appendChild(this.#headRow);
138
140
  this.#grid.appendChild(this.#body);
139
141
  this.#root.appendChild(this.#grid);
140
142
  this.#root.appendChild(this.#empty);
141
143
  this.#root.appendChild(this.#status);
142
144
  if (options.title !== undefined) this.setTitle(options.title);
143
145
  else this.#title.hidden = true;
144
- this.setLabel(this.#label_text === undefined ? I18n.t("diffViewer.title") : this.#label_text);
146
+ this.setLabel(this.#labelText === undefined ? I18n.t("diffViewer.title") : this.#labelText);
145
147
  // Высота из опций: без неё остаётся своя по умолчанию (360px, тело прокручивается)
146
148
  this.setHeight(options.height === undefined ? this.#height : options.height);
147
149
  this.setTexts(options.left === undefined ? "" : options.left, options.right === undefined ? "" : options.right);
@@ -156,12 +158,12 @@ class DiffViewer {
156
158
  }
157
159
 
158
160
  getTitle() {
159
- return this.#title_text;
161
+ return this.#titleText;
160
162
  }
161
163
 
162
164
  /** Доступное имя компонента, заданное в `label` */
163
165
  getLabel() {
164
- return this.#label_text;
166
+ return this.#labelText;
165
167
  }
166
168
 
167
169
  getMode() {
@@ -177,11 +179,11 @@ class DiffViewer {
177
179
  }
178
180
 
179
181
  getLeftTitle() {
180
- return this.#left_title;
182
+ return this.#leftTitle;
181
183
  }
182
184
 
183
185
  getRightTitle() {
184
- return this.#right_title;
186
+ return this.#rightTitle;
185
187
  }
186
188
 
187
189
  /** Строки модели: `{type, left, right}` (у вставки нет левой строки, у удаления — правой) */
@@ -191,19 +193,21 @@ class DiffViewer {
191
193
 
192
194
  /** Счёт изменений: `{equal, added, removed, changed, groups}` */
193
195
  getStats() {
194
- return Object.assign({}, this.#stats_data);
196
+ return Object.assign({}, this.#statsData);
195
197
  }
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() {
@@ -211,7 +215,7 @@ class DiffViewer {
211
215
  }
212
216
 
213
217
  isLineNumbers() {
214
- return this.#line_numbers;
218
+ return this.#lineNumbers;
215
219
  }
216
220
 
217
221
  getHeight() {
@@ -219,7 +223,7 @@ class DiffViewer {
219
223
  }
220
224
 
221
225
  getEmptyText() {
222
- return this.#empty_text;
226
+ return this.#emptyText;
223
227
  }
224
228
 
225
229
  /** Сработал ли предел алгоритма: середина расхождения показана одним блоком */
@@ -238,7 +242,7 @@ class DiffViewer {
238
242
 
239
243
  /** Подпись над сравнением; `undefined` её убирает (имя тогда даёт `label`) */
240
244
  setTitle(text = undefined) {
241
- this.#title_text = text;
245
+ this.#titleText = text;
242
246
  if (text === undefined || text === "") {
243
247
  this.#title.hidden = true;
244
248
  this.#title.innerText = "";
@@ -253,19 +257,19 @@ class DiffViewer {
253
257
 
254
258
  /** Имя сравнения, когда подписи в разметке нет */
255
259
  setLabel(text = undefined) {
256
- this.#label_text = text;
260
+ this.#labelText = text;
257
261
  this.#syncLabel();
258
262
  return this;
259
263
  }
260
264
 
261
265
  setLeftTitle(text = String()) {
262
- this.#left_title = String(text);
266
+ this.#leftTitle = String(text);
263
267
  this.#render();
264
268
  return this;
265
269
  }
266
270
 
267
271
  setRightTitle(text = String()) {
268
- this.#right_title = String(text);
272
+ this.#rightTitle = String(text);
269
273
  this.#render();
270
274
  return this;
271
275
  }
@@ -294,8 +298,8 @@ class DiffViewer {
294
298
  this.#expanded = [];
295
299
  this.#approximate = false;
296
300
  this.#rows = this.#buildRows(DiffViewer.#split(this.#left), DiffViewer.#split(this.#right));
297
- this.#stats_data = this.#collectStats();
298
- this.#active_index = undefined;
301
+ this.#statsData = this.#collectStats();
302
+ this.#activeIndex = undefined;
299
303
  this.#render();
300
304
  this.#announce();
301
305
  return this;
@@ -317,14 +321,14 @@ class DiffViewer {
317
321
 
318
322
  /** Раскрыть пропуск по индексам модели (как кнопка «Показать N строк») */
319
323
  expandRange(from = Number(), to = Number()) {
320
- this.#expanded.push({from: Number(from), to: Number(to)});
321
- this.#focus_index = Number(from);
324
+ this.#expanded.push({ from: Number(from), to: Number(to) });
325
+ this.#focusIndex = Number(from);
322
326
  this.#render();
323
327
  return this;
324
328
  }
325
329
 
326
330
  setLineNumbers(shown = Boolean()) {
327
- this.#line_numbers = shown !== false;
331
+ this.#lineNumbers = shown !== false;
328
332
  this.#render();
329
333
  return this;
330
334
  }
@@ -343,7 +347,7 @@ class DiffViewer {
343
347
  }
344
348
 
345
349
  setEmptyText(text = String()) {
346
- this.#empty_text = text === undefined ? "" : String(text);
350
+ this.#emptyText = text === undefined ? "" : String(text);
347
351
  this.#render();
348
352
  return this;
349
353
  }
@@ -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,24 +440,28 @@ 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
- const mid_left = left.slice(prefix, left.length - suffix);
443
- const mid_right = right.slice(prefix, right.length - suffix);
444
- if (mid_left.length > 0 || mid_right.length > 0) {
451
+ const middleLeft = left.slice(prefix, left.length - suffix);
452
+ const middleRight = right.slice(prefix, right.length - suffix);
453
+ if (middleLeft.length > 0 || middleRight.length > 0) {
445
454
  let operations;
446
- if (mid_left.length * mid_right.length > DiffViewer.LCS_LIMIT) {
455
+ if (middleLeft.length * middleRight.length > DiffViewer.LCS_LIMIT) {
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 (middleLeft.length > 0) operations.push({ type: DELETE, from: 0, to: middleLeft.length });
460
+ if (middleRight.length > 0) operations.push({ type: INSERT, from: 0, to: middleRight.length });
452
461
  } else {
453
- operations = DiffViewer.#operations(mid_left, mid_right);
462
+ operations = DiffViewer.#operations(middleLeft, middleRight);
454
463
  }
455
- for (const row of DiffViewer.#middleRows(operations, mid_left, mid_right, prefix)) rows.push(row);
464
+ for (const row of DiffViewer.#middleRows(operations, middleLeft, middleRight, prefix)) rows.push(row);
456
465
  }
457
466
  for (let k = 0; k < suffix; k += 1) {
458
467
  const li = left.length - suffix + k;
@@ -462,11 +471,11 @@ class DiffViewer {
462
471
  return rows;
463
472
  }
464
473
 
465
- static #equalRow(left_text = String(), left_number = Number(), right_text = String(), right_number = Number()) {
474
+ static #equalRow(leftText = String(), leftNumber = Number(), rightText = String(), rightNumber = 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: leftNumber, text: leftText },
478
+ right: { number: rightNumber, text: rightText },
470
479
  };
471
480
  }
472
481
 
@@ -481,32 +490,41 @@ class DiffViewer {
481
490
  for (let k = 0; k < pairs; k += 1) {
482
491
  const li = operation.from + k;
483
492
  const ri = next.from + k;
484
- const has_left = li < operation.to;
485
- const has_right = ri < next.to;
493
+ const hasLeft = li < operation.to;
494
+ const hasRight = ri < next.to;
486
495
  rows.push({
487
- 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
496
+ type: hasLeft && hasRight ? REPLACE : hasLeft ? DELETE : INSERT,
497
+ left: hasLeft ? { number: offset + li + 1, text: left[li] } : undefined,
498
+ right: hasRight ? { 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;
@@ -537,8 +555,9 @@ class DiffViewer {
537
555
  #visibleRows() {
538
556
  const total = this.#rows.length;
539
557
  const list = [];
540
- 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});
558
+ if (this.#context === Infinity || this.#statsData.groups === 0) {
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,29 +572,29 @@ 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
 
569
588
  #accessibleName() {
570
- if (this.#title_text !== undefined && this.#title_text !== "") return this.#title_text;
571
- if (this.#label_text !== undefined && this.#label_text !== "") return this.#label_text;
589
+ if (this.#titleText !== undefined && this.#titleText !== "") return this.#titleText;
590
+ if (this.#labelText !== undefined && this.#labelText !== "") return this.#labelText;
572
591
  return I18n.t("diffViewer.title");
573
592
  }
574
593
 
575
594
  // Имя компонента: видимая подпись — через aria-labelledby, скрытая — через aria-label.
576
595
  // Таблица внутри получает то же имя: у неё своя роль, и без имени она читалась бы безымянной
577
596
  #syncLabel() {
578
- if (this.#title_text !== undefined && this.#title_text !== "") {
597
+ if (this.#titleText !== undefined && this.#titleText !== "") {
579
598
  this.#root.setAttribute("aria-labelledby", this.#title.id);
580
599
  this.#root.removeAttribute("aria-label");
581
600
  } else {
@@ -588,12 +607,12 @@ class DiffViewer {
588
607
 
589
608
  #buildHead() {
590
609
  this.#stats.innerHTML = "";
591
- this.#stat_removed.className = "diff_viewer_stat diff_viewer_stat_removed";
592
- this.#stat_added.className = "diff_viewer_stat diff_viewer_stat_added";
593
- this.#stat_changed.className = "diff_viewer_stat diff_viewer_stat_changed";
594
- this.#stats.appendChild(this.#stat_removed);
595
- this.#stats.appendChild(this.#stat_added);
596
- this.#stats.appendChild(this.#stat_changed);
610
+ this.#statRemoved.className = "diff_viewer_stat diff_viewer_stat_removed";
611
+ this.#statAdded.className = "diff_viewer_stat diff_viewer_stat_added";
612
+ this.#statChanged.className = "diff_viewer_stat diff_viewer_stat_changed";
613
+ this.#stats.appendChild(this.#statRemoved);
614
+ this.#stats.appendChild(this.#statAdded);
615
+ this.#stats.appendChild(this.#statChanged);
597
616
  this.#prev.type = "button";
598
617
  this.#prev.className = "diff_viewer_move diff_viewer_move_prev";
599
618
  this.#prev.setAttribute("aria-label", I18n.t("diffViewer.previousChange"));
@@ -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
 
@@ -639,7 +658,7 @@ class DiffViewer {
639
658
  const number = document.createElement("span");
640
659
  number.className = "diff_viewer_number";
641
660
  number.setAttribute("aria-hidden", "true");
642
- number.innerText = this.#line_numbers && line !== undefined ? String(line.number) : "";
661
+ number.innerText = this.#lineNumbers && line !== undefined ? String(line.number) : "";
643
662
  const text = document.createElement("span");
644
663
  text.className = "diff_viewer_text";
645
664
  text.innerText = line === undefined ? "" : line.text;
@@ -658,7 +677,7 @@ class DiffViewer {
658
677
  const label = this.#rowLabel(row);
659
678
  if (label !== undefined) node.setAttribute("aria-label", label);
660
679
  if (row.type !== EQUAL) node.classList.add(`diff_viewer_row_${row.type}`);
661
- node.classList.toggle("diff_viewer_row_no_numbers", this.#line_numbers === false);
680
+ node.classList.toggle("diff_viewer_row_no_numbers", this.#lineNumbers === false);
662
681
  for (const cell of this.#cells(row)) node.appendChild(cell);
663
682
  return node;
664
683
  }
@@ -696,17 +715,17 @@ 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;
703
722
  }
704
723
 
705
724
  #applyStats() {
706
- const stats = this.#stats_data;
707
- this.#stat_removed.innerText = `−${stats.removed}`;
708
- this.#stat_added.innerText = `+${stats.added}`;
709
- this.#stat_changed.innerText = `~${stats.changed}`;
725
+ const stats = this.#statsData;
726
+ this.#statRemoved.innerText = `−${stats.removed}`;
727
+ this.#statAdded.innerText = `+${stats.added}`;
728
+ this.#statChanged.innerText = `~${stats.changed}`;
710
729
  const empty = stats.groups === 0;
711
730
  this.#prev.disabled = empty;
712
731
  this.#next.disabled = empty;
@@ -714,13 +733,16 @@ class DiffViewer {
714
733
  }
715
734
 
716
735
  #announce() {
717
- const stats = this.#stats_data;
736
+ const stats = this.#statsData;
718
737
  if (stats.groups === 0) {
719
738
  this.#status.innerText = I18n.t("diffViewer.noChanges");
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
  }
@@ -729,27 +751,29 @@ class DiffViewer {
729
751
  // Строки пересобираются, а фокус живёт на строке: запоминаем её до перерисовки
730
752
  const active = document.activeElement;
731
753
  const focused = active === null || !this.#grid.contains(active) ? null : active.closest(".diff_viewer_row");
732
- if (focused !== null && focused.dataset.index !== undefined) this.#focus_index = Number(focused.dataset.index);
733
- this.#head_row.innerHTML = "";
754
+ if (focused !== null && focused.dataset.index !== undefined) this.#focusIndex = Number(focused.dataset.index);
755
+ this.#headRow.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.#leftTitle, this.#rightTitle];
738
761
  for (const title of titles) {
739
762
  const cell = document.createElement("div");
740
763
  cell.className = "diff_viewer_head_cell";
741
764
  cell.setAttribute("role", "columnheader");
742
765
  cell.innerText = title;
743
- this.#head_row.appendChild(cell);
766
+ this.#headRow.appendChild(cell);
744
767
  }
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
- this.#empty.hidden = this.#stats_data.groups !== 0;
752
- this.#empty.innerText = this.#empty_text;
775
+ this.#empty.hidden = this.#statsData.groups !== 0;
776
+ this.#empty.innerText = this.#emptyText;
753
777
  this.#applyStats();
754
778
  this.#applyStop();
755
779
  return this;
@@ -760,14 +784,14 @@ class DiffViewer {
760
784
  const list = [...this.#body.querySelectorAll(".diff_viewer_row")];
761
785
  if (list.length === 0) return;
762
786
  const stop =
763
- list.find((row) => Number(row.dataset.index) === this.#active_index) ??
764
- list.find((row) => Number(row.dataset.index) === this.#focus_index) ??
787
+ list.find((row) => Number(row.dataset.index) === this.#activeIndex) ??
788
+ list.find((row) => Number(row.dataset.index) === this.#focusIndex) ??
765
789
  list[0];
766
- this.#active_index = Number(stop.dataset.index);
790
+ this.#activeIndex = Number(stop.dataset.index);
767
791
  for (const row of list) row.setAttribute("tabindex", row === stop ? "0" : "-1");
768
792
  // Фокус возвращаем, только если он был в теле: иначе перерисовка его бы украла
769
- if (this.#focus_index !== undefined && Number(stop.dataset.index) === this.#focus_index) {
770
- this.#focus_index = undefined;
793
+ if (this.#focusIndex !== undefined && Number(stop.dataset.index) === this.#focusIndex) {
794
+ this.#focusIndex = undefined;
771
795
  stop.focus();
772
796
  }
773
797
  return this;
@@ -775,7 +799,7 @@ class DiffViewer {
775
799
 
776
800
  #focusRow(row = undefined) {
777
801
  if (row === undefined || row === null) return this;
778
- this.#active_index = Number(row.dataset.index);
802
+ this.#activeIndex = Number(row.dataset.index);
779
803
  for (const other of this.#body.querySelectorAll(".diff_viewer_row")) {
780
804
  other.setAttribute("tabindex", other === row ? "0" : "-1");
781
805
  }
@@ -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
 
@@ -814,7 +839,7 @@ class DiffViewer {
814
839
  #goToChange(direction = Number()) {
815
840
  const groups = this.#changeGroups();
816
841
  if (groups.length === 0) return this;
817
- const current = this.#active_index;
842
+ const current = this.#activeIndex;
818
843
  const forward = direction > 0;
819
844
  let target;
820
845
  if (current === undefined) target = forward ? groups[0] : groups[groups.length - 1];
@@ -834,7 +859,7 @@ class DiffViewer {
834
859
  #onFocusIn = (event) => {
835
860
  const row = event.target instanceof Element ? event.target.closest(".diff_viewer_row") : null;
836
861
  if (row === null || row.dataset.index === undefined) return;
837
- this.#active_index = Number(row.dataset.index);
862
+ this.#activeIndex = Number(row.dataset.index);
838
863
  };
839
864
 
840
865
  #onKeyDown = (event) => {
@@ -864,4 +889,4 @@ class DiffViewer {
864
889
  };
865
890
  }
866
891
 
867
- exports.DiffViewer = DiffViewer
892
+ exports.DiffViewer = DiffViewer;