chuijs 4.0.2 → 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.
- package/CHANGELOG.md +61 -0
- package/README.md +43 -644
- package/framework/appLayout/default/chui_app_layout.js +308 -260
- package/framework/appLayout/default/global_style.css +85 -48
- package/framework/components/chui_accordion/accordion.js +29 -26
- package/framework/components/chui_accordion/styles.css +6 -5
- package/framework/components/chui_action_sheet/action_sheet.js +59 -33
- package/framework/components/chui_action_sheet/styles.css +2 -1
- package/framework/components/chui_affix/affix.js +11 -6
- package/framework/components/chui_alert/alert.js +23 -14
- package/framework/components/chui_avatar/avatar.js +23 -22
- package/framework/components/chui_avatar_group/avatar_group.js +21 -19
- package/framework/components/chui_backtop/backtop.js +35 -19
- package/framework/components/chui_badge/badge.js +15 -13
- package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
- package/framework/components/chui_button/button.js +42 -22
- package/framework/components/chui_button/styles.css +2 -2
- package/framework/components/chui_calendar/calendar.js +12 -10
- package/framework/components/chui_card/card.js +43 -23
- package/framework/components/chui_chat/chat.js +72 -33
- package/framework/components/chui_clipboard_history/clipboard_history.js +30 -21
- package/framework/components/chui_clipboard_history/styles.css +4 -2
- package/framework/components/chui_code/code.js +2 -2
- package/framework/components/chui_code/styles.css +2 -2
- package/framework/components/chui_code_editor/code_editor.js +47 -31
- package/framework/components/chui_code_editor/styles.css +3 -2
- package/framework/components/chui_command_palette/command_palette.js +60 -37
- package/framework/components/chui_console/console.js +5 -5
- package/framework/components/chui_console/styles.css +1 -1
- package/framework/components/chui_content_block/content_block.js +33 -19
- package/framework/components/chui_content_block/styles.css +2 -2
- package/framework/components/chui_context_menu/context_menu.js +9 -4
- package/framework/components/chui_custom_element/custom_element.js +22 -15
- package/framework/components/chui_data_grid/data_grid.js +396 -234
- package/framework/components/chui_data_grid/styles.css +10 -8
- package/framework/components/chui_descriptions/descriptions.js +34 -17
- package/framework/components/chui_details/details.js +32 -26
- package/framework/components/chui_details/styles.css +5 -4
- package/framework/components/chui_diff_viewer/diff_viewer.js +91 -66
- package/framework/components/chui_diff_viewer/styles.css +1 -1
- package/framework/components/chui_divider/divider.js +13 -11
- package/framework/components/chui_drawer/drawer.js +27 -25
- package/framework/components/chui_drop_zone/drop_zone.js +31 -21
- package/framework/components/chui_empty_state/empty_state.js +20 -15
- package/framework/components/chui_fieldset/fieldset.js +37 -20
- package/framework/components/chui_fieldset/styles.css +1 -1
- package/framework/components/chui_file_explorer/file_explorer.js +157 -86
- package/framework/components/chui_file_explorer/styles.css +2 -1
- package/framework/components/chui_form/form.js +31 -19
- package/framework/components/chui_form/styles.css +1 -1
- package/framework/components/chui_gantt/gantt.js +64 -40
- package/framework/components/chui_graphs/graphs.js +301 -200
- package/framework/components/chui_graphs/styles.css +1 -1
- package/framework/components/chui_hero/hero.js +40 -22
- package/framework/components/chui_html_block/html_block.js +6 -6
- package/framework/components/chui_html_block/styles.css +2 -2
- package/framework/components/chui_hx/hx.js +3 -3
- package/framework/components/chui_hx/styles.css +11 -4
- package/framework/components/chui_icons/icons.js +2109 -2109
- package/framework/components/chui_icons/styles.css +2 -2
- package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
- package/framework/components/chui_inputs/chui_check_box/styles.css +18 -18
- package/framework/components/chui_inputs/chui_chips/chips.js +50 -40
- package/framework/components/chui_inputs/chui_chips/styles.css +4 -2
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +36 -24
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +100 -82
- package/framework/components/chui_inputs/chui_combo_box/styles.css +14 -12
- package/framework/components/chui_inputs/chui_date/date.js +102 -66
- package/framework/components/chui_inputs/chui_date/styles.css +12 -11
- package/framework/components/chui_inputs/chui_date_range/date_range.js +40 -29
- package/framework/components/chui_inputs/chui_datetime/datetime.js +35 -27
- package/framework/components/chui_inputs/chui_email/email.js +43 -31
- package/framework/components/chui_inputs/chui_email/styles.css +5 -5
- package/framework/components/chui_inputs/chui_file/file.js +68 -41
- package/framework/components/chui_inputs/chui_file/styles.css +13 -12
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +61 -36
- package/framework/components/chui_inputs/chui_masked/masked.js +39 -28
- package/framework/components/chui_inputs/chui_mention/mention.js +77 -30
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +173 -153
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +9 -7
- package/framework/components/chui_inputs/chui_number/number.js +58 -41
- package/framework/components/chui_inputs/chui_number/styles.css +7 -7
- package/framework/components/chui_inputs/chui_otp/otp.js +38 -29
- package/framework/components/chui_inputs/chui_password/password.js +58 -36
- package/framework/components/chui_inputs/chui_password/styles.css +8 -8
- package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
- package/framework/components/chui_inputs/chui_radio_button/styles.css +20 -20
- package/framework/components/chui_inputs/chui_rating/rating.js +26 -22
- package/framework/components/chui_inputs/chui_select_box/select_box.js +102 -78
- package/framework/components/chui_inputs/chui_select_box/styles.css +11 -11
- package/framework/components/chui_inputs/chui_slider/slider.js +29 -26
- package/framework/components/chui_inputs/chui_slider/styles.css +2 -1
- package/framework/components/chui_inputs/chui_text/styles.css +8 -8
- package/framework/components/chui_inputs/chui_text/text.js +65 -44
- package/framework/components/chui_inputs/chui_text_area/styles.css +6 -6
- package/framework/components/chui_inputs/chui_text_area/text_area.js +51 -28
- package/framework/components/chui_inputs/chui_time/styles.css +5 -3
- package/framework/components/chui_inputs/chui_time/time.js +38 -27
- package/framework/components/chui_inputs/chui_toggle/styles.css +3 -3
- package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
- package/framework/components/chui_json_editor/json_editor.js +53 -43
- package/framework/components/chui_json_viewer/json_viewer.js +52 -33
- package/framework/components/chui_json_viewer/styles.css +3 -2
- package/framework/components/chui_kanban/kanban.js +52 -34
- package/framework/components/chui_kbd/kbd.js +12 -10
- package/framework/components/chui_label/label.js +14 -12
- package/framework/components/chui_label/styles.css +2 -2
- package/framework/components/chui_link/link.js +27 -20
- package/framework/components/chui_list/list.js +31 -27
- package/framework/components/chui_list/styles.css +2 -1
- package/framework/components/chui_markdown_editor/markdown_editor.js +60 -44
- package/framework/components/chui_media/audio.js +326 -227
- package/framework/components/chui_media/audio_styles.css +40 -21
- package/framework/components/chui_media/image.js +70 -38
- package/framework/components/chui_media/image_compare.js +52 -21
- package/framework/components/chui_media/image_styles.css +3 -3
- package/framework/components/chui_media/video.js +155 -62
- package/framework/components/chui_media/video_styles.css +33 -16
- package/framework/components/chui_menu_bar/menu_bar.js +26 -24
- package/framework/components/chui_menu_bar/styles.css +4 -2
- package/framework/components/chui_modal/modal.js +44 -43
- package/framework/components/chui_modal/styles.css +3 -2
- package/framework/components/chui_notification/notification.js +50 -34
- package/framework/components/chui_notification/notification_download.js +31 -25
- package/framework/components/chui_notification/notification_download_progress.css +3 -2
- package/framework/components/chui_notification/notification_download_progress.js +47 -41
- package/framework/components/chui_notification/notification_update.js +23 -16
- package/framework/components/chui_notification/status_plate.js +2 -2
- package/framework/components/chui_notification/styles_download.css +1 -1
- package/framework/components/chui_notification/styles_update.css +1 -1
- package/framework/components/chui_org_chart/org_chart.js +74 -35
- package/framework/components/chui_pagination/pagination.js +62 -27
- package/framework/components/chui_paragraph/paragraph.js +2 -2
- package/framework/components/chui_paragraph/styles.css +1 -1
- package/framework/components/chui_popover/popover.js +49 -28
- package/framework/components/chui_popups/popups.js +137 -108
- package/framework/components/chui_popups/styles.css +2 -2
- package/framework/components/chui_print_button/print_button.js +33 -23
- package/framework/components/chui_progress_bar/progress_bar.js +23 -15
- package/framework/components/chui_progress_bar/styles.css +2 -2
- package/framework/components/chui_progress_ring/progress_ring.js +17 -15
- package/framework/components/chui_qrcode/qrcode.js +75 -31
- package/framework/components/chui_query_builder/query_builder.js +216 -123
- package/framework/components/chui_radio_group/radio_group.js +36 -26
- package/framework/components/chui_radio_group/styles.css +1 -1
- package/framework/components/chui_result/result.js +26 -16
- package/framework/components/chui_scheduler/scheduler.js +57 -35
- package/framework/components/chui_scheduler/styles.css +6 -2
- package/framework/components/chui_segmented_control/segmented_control.js +27 -21
- package/framework/components/chui_settings/settings.js +122 -48
- package/framework/components/chui_shortcut_help/shortcut_help.js +55 -32
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +33 -23
- package/framework/components/chui_skeleton/skeleton.js +29 -24
- package/framework/components/chui_slideshow/slideshow.js +60 -41
- package/framework/components/chui_slideshow/styles.css +18 -12
- package/framework/components/chui_spinner/spinner.js +8 -8
- package/framework/components/chui_spinner/styles.css +0 -1
- package/framework/components/chui_split_button/split_button.js +23 -18
- package/framework/components/chui_split_button/styles.css +1 -1
- package/framework/components/chui_splitter/splitter.js +35 -28
- package/framework/components/chui_statistic/statistic.js +65 -38
- package/framework/components/chui_status_bar/status_bar.js +11 -9
- package/framework/components/chui_stepper/stepper.js +27 -22
- package/framework/components/chui_sticky_bar/sticky_bar.js +9 -4
- package/framework/components/chui_sticky_bar/styles.css +3 -1
- package/framework/components/chui_tabs/chui_tabs.js +28 -22
- package/framework/components/chui_tabs/styles.css +3 -3
- package/framework/components/chui_text_editor/styles.css +20 -19
- package/framework/components/chui_text_editor/text_editor.js +85 -61
- package/framework/components/chui_text_editor/text_editor_panel.js +346 -284
- package/framework/components/chui_theme_toggle/theme_toggle.js +27 -22
- package/framework/components/chui_timeline/timeline.js +14 -12
- package/framework/components/chui_toast_queue/toast_queue.js +52 -46
- package/framework/components/chui_toolbar/toolbar.js +20 -13
- package/framework/components/chui_tooltip/tooltip.js +37 -24
- package/framework/components/chui_tour/styles.css +8 -3
- package/framework/components/chui_tour/tour.js +61 -27
- package/framework/components/chui_transfer/styles.css +2 -1
- package/framework/components/chui_transfer/transfer.js +75 -42
- package/framework/components/chui_tree_table/tree_table.js +43 -29
- package/framework/components/chui_tree_view/styles.css +4 -2
- package/framework/components/chui_tree_view/tree_view.js +142 -99
- package/framework/components/chui_watermark/watermark.js +24 -16
- package/framework/components/chui_webview/styles.css +2 -2
- package/framework/components/chui_webview/webview.js +62 -50
- package/framework/components/telegram_bot/chui_telegram_bot.js +71 -64
- package/framework/modules/chui_a11y/chui_a11y.js +77 -46
- package/framework/modules/chui_animations/animations.js +42 -42
- package/framework/modules/chui_animations/styles.css +1 -1
- package/framework/modules/chui_bridge/preload.js +36 -25
- package/framework/modules/chui_functions.js +52 -50
- package/framework/modules/chui_highlight/chui_highlight.js +25 -22
- package/framework/modules/chui_i18n/chui_i18n.js +9 -7
- package/framework/modules/chui_i18n/locales/a11y.js +5 -5
- package/framework/modules/chui_i18n/locales/app_layout.js +5 -5
- package/framework/modules/chui_i18n/locales/calendar.js +3 -3
- package/framework/modules/chui_i18n/locales/common.js +3 -3
- package/framework/modules/chui_i18n/locales/data.js +36 -26
- package/framework/modules/chui_i18n/locales/editors.js +40 -13
- package/framework/modules/chui_i18n/locales/feedback.js +3 -3
- package/framework/modules/chui_i18n/locales/forms.js +8 -8
- package/framework/modules/chui_i18n/locales/graphics.js +8 -8
- package/framework/modules/chui_i18n/locales/media.js +4 -4
- package/framework/modules/chui_i18n/locales/navigation.js +8 -8
- package/framework/modules/chui_i18n/locales/validate.js +3 -3
- package/framework/modules/chui_json/chui_json.js +9 -9
- package/framework/modules/chui_layout/chui_layout.js +12 -10
- package/framework/modules/chui_logger/chui_logger.js +29 -25
- package/framework/modules/chui_page/page.js +33 -27
- package/framework/modules/chui_qr/chui_qr.js +158 -67
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +35 -24
- package/framework/modules/chui_scrollbar/styles.css +3 -1
- package/framework/modules/chui_services/chui_channels.js +27 -13
- package/framework/modules/chui_services/chui_services.js +39 -31
- package/framework/modules/chui_services/desktop.js +32 -31
- package/framework/modules/chui_sortable/chui_sortable.js +17 -12
- package/framework/modules/chui_validate/chui_validate.js +7 -4
- package/framework/tray_bar/chui_menu_items.js +136 -46
- package/index.d.ts +4814 -0
- package/index.js +385 -292
- 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:
|
|
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;
|
|
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:
|
|
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;
|
|
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(
|
|
2
|
-
const {I18n} = require(
|
|
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(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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(
|
|
13
|
-
#bt = document.createElement(
|
|
14
|
-
#barrow = document.createElement(
|
|
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(
|
|
17
|
-
#html = document.createElement(
|
|
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(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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(
|
|
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(
|
|
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 ===
|
|
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(
|
|
77
|
-
elem.classList.toggle(
|
|
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(
|
|
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);
|
|
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(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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) =>
|
|
200
|
-
? {type: GAP, from: entry.from, to: entry.to}
|
|
201
|
-
|
|
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()
|
|
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] =
|
|
398
|
-
|
|
399
|
-
|
|
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 (
|
|
439
|
-
|
|
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(
|
|
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(
|
|
501
|
-
|
|
502
|
-
|
|
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)
|
|
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,
|
|
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 =
|
|
736
|
-
|
|
737
|
-
|
|
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)
|
|
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
|
-
|
|
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;
|