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.
- package/CHANGELOG.md +597 -0
- package/README.md +43 -644
- package/framework/appLayout/default/chui_app_layout.js +602 -496
- package/framework/appLayout/default/global_style.css +288 -97
- package/framework/appLayout/default/main_theme_style.css +188 -101
- package/framework/components/chui_accordion/accordion.js +38 -35
- package/framework/components/chui_accordion/styles.css +13 -12
- package/framework/components/chui_action_sheet/action_sheet.js +93 -64
- package/framework/components/chui_action_sheet/styles.css +12 -5
- package/framework/components/chui_actions_bar/actions_bar.js +338 -0
- package/framework/components/chui_actions_bar/styles.css +139 -0
- package/framework/components/chui_affix/affix.js +16 -11
- package/framework/components/chui_affix/styles.css +5 -0
- package/framework/components/chui_alert/alert.js +34 -19
- package/framework/components/chui_alert/styles.css +7 -0
- package/framework/components/chui_avatar/avatar.js +36 -35
- package/framework/components/chui_avatar/styles.css +1 -1
- package/framework/components/chui_avatar_group/avatar_group.js +25 -23
- package/framework/components/chui_avatar_group/styles.css +1 -1
- package/framework/components/chui_backtop/backtop.js +60 -21
- package/framework/components/chui_backtop/styles.css +21 -0
- package/framework/components/chui_badge/badge.js +30 -28
- package/framework/components/chui_badge/styles.css +6 -6
- package/framework/components/chui_banner/banner.js +222 -0
- package/framework/components/chui_banner/styles.css +170 -0
- package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
- package/framework/components/chui_breadcrumb/styles.css +1 -1
- package/framework/components/chui_button/button.js +52 -36
- package/framework/components/chui_button/styles.css +7 -7
- package/framework/components/chui_calendar/calendar.js +18 -16
- package/framework/components/chui_card/card.js +52 -32
- package/framework/components/chui_card_scroll/card_scroll.js +169 -0
- package/framework/components/chui_card_scroll/styles.css +86 -0
- package/framework/components/chui_chat/chat.js +140 -79
- package/framework/components/chui_chat/styles.css +18 -7
- package/framework/components/chui_clipboard_history/clipboard_history.js +53 -39
- package/framework/components/chui_clipboard_history/styles.css +13 -9
- package/framework/components/chui_code/code.js +10 -10
- package/framework/components/chui_code/styles.css +4 -4
- package/framework/components/chui_code_editor/code_editor.js +73 -57
- package/framework/components/chui_code_editor/styles.css +6 -5
- package/framework/components/chui_command_palette/command_palette.js +87 -64
- package/framework/components/chui_command_palette/styles.css +5 -5
- package/framework/components/chui_console/console.js +13 -13
- package/framework/components/chui_console/styles.css +6 -3
- package/framework/components/chui_content_block/content_block.js +35 -21
- package/framework/components/chui_content_block/styles.css +2 -2
- package/framework/components/chui_context_menu/context_menu.js +171 -58
- package/framework/components/chui_context_menu/styles.css +82 -8
- package/framework/components/chui_custom_element/custom_element.js +25 -18
- package/framework/components/chui_data_grid/data_grid.js +633 -471
- package/framework/components/chui_data_grid/styles.css +24 -22
- package/framework/components/chui_descriptions/descriptions.js +34 -17
- package/framework/components/chui_descriptions/styles.css +1 -1
- package/framework/components/chui_details/details.js +42 -36
- package/framework/components/chui_details/styles.css +12 -11
- package/framework/components/chui_diff_viewer/diff_viewer.js +172 -147
- package/framework/components/chui_diff_viewer/styles.css +10 -10
- package/framework/components/chui_divider/divider.js +19 -17
- package/framework/components/chui_divider/styles.css +2 -2
- package/framework/components/chui_drawer/drawer.js +63 -38
- package/framework/components/chui_drawer/styles.css +18 -4
- package/framework/components/chui_drop_zone/drop_zone.js +37 -27
- package/framework/components/chui_drop_zone/styles.css +10 -6
- package/framework/components/chui_empty_state/empty_state.js +20 -15
- package/framework/components/chui_fieldset/fieldset.js +40 -23
- package/framework/components/chui_fieldset/styles.css +6 -6
- package/framework/components/chui_file_explorer/file_explorer.js +260 -189
- package/framework/components/chui_file_explorer/styles.css +8 -7
- package/framework/components/chui_form/form.js +40 -28
- package/framework/components/chui_form/styles.css +1 -1
- package/framework/components/chui_gantt/gantt.js +102 -78
- package/framework/components/chui_gantt/styles.css +5 -5
- package/framework/components/chui_graphs/graphs.js +376 -239
- package/framework/components/chui_graphs/styles.css +27 -6
- package/framework/components/chui_hero/hero.js +98 -37
- package/framework/components/chui_hero/styles.css +176 -7
- package/framework/components/chui_html_block/html_block.js +8 -8
- package/framework/components/chui_html_block/styles.css +3 -3
- package/framework/components/chui_hx/hx.js +3 -3
- package/framework/components/chui_hx/styles.css +13 -6
- package/framework/components/chui_icons/icons.js +2115 -2115
- package/framework/components/chui_icons/styles.css +4 -3
- package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
- package/framework/components/chui_inputs/chui_check_box/styles.css +30 -21
- package/framework/components/chui_inputs/chui_chips/chips.js +141 -70
- package/framework/components/chui_inputs/chui_chips/styles.css +32 -7
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +55 -38
- package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +127 -109
- package/framework/components/chui_inputs/chui_combo_box/styles.css +23 -21
- package/framework/components/chui_inputs/chui_date/date.js +161 -127
- package/framework/components/chui_inputs/chui_date/styles.css +20 -19
- package/framework/components/chui_inputs/chui_date_range/date_range.js +61 -50
- package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
- package/framework/components/chui_inputs/chui_datetime/datetime.js +47 -39
- package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
- package/framework/components/chui_inputs/chui_email/email.js +48 -36
- package/framework/components/chui_inputs/chui_email/styles.css +11 -11
- package/framework/components/chui_inputs/chui_file/file.js +71 -44
- package/framework/components/chui_inputs/chui_file/styles.css +23 -19
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +101 -76
- package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
- package/framework/components/chui_inputs/chui_masked/masked.js +83 -72
- package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
- package/framework/components/chui_inputs/chui_mention/mention.js +87 -40
- package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +242 -212
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +23 -15
- package/framework/components/chui_inputs/chui_number/number.js +84 -70
- package/framework/components/chui_inputs/chui_number/styles.css +13 -13
- package/framework/components/chui_inputs/chui_otp/otp.js +71 -62
- package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
- package/framework/components/chui_inputs/chui_password/password.js +72 -56
- package/framework/components/chui_inputs/chui_password/styles.css +15 -15
- package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
- package/framework/components/chui_inputs/chui_radio_button/styles.css +22 -22
- package/framework/components/chui_inputs/chui_rating/rating.js +54 -50
- package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
- package/framework/components/chui_inputs/chui_select_box/select_box.js +132 -108
- package/framework/components/chui_inputs/chui_select_box/styles.css +21 -21
- package/framework/components/chui_inputs/chui_slider/slider.js +41 -38
- package/framework/components/chui_inputs/chui_slider/styles.css +7 -5
- package/framework/components/chui_inputs/chui_text/styles.css +14 -14
- package/framework/components/chui_inputs/chui_text/text.js +69 -52
- package/framework/components/chui_inputs/chui_text_area/styles.css +14 -14
- package/framework/components/chui_inputs/chui_text_area/text_area.js +59 -36
- package/framework/components/chui_inputs/chui_time/styles.css +18 -20
- package/framework/components/chui_inputs/chui_time/time.js +71 -49
- package/framework/components/chui_inputs/chui_toggle/styles.css +13 -6
- package/framework/components/chui_inputs/chui_toggle/toggle.js +27 -27
- package/framework/components/chui_json_editor/json_editor.js +137 -127
- package/framework/components/chui_json_editor/styles.css +5 -5
- package/framework/components/chui_json_viewer/json_viewer.js +133 -114
- package/framework/components/chui_json_viewer/styles.css +9 -8
- package/framework/components/chui_kanban/kanban.js +78 -60
- package/framework/components/chui_kanban/styles.css +8 -4
- package/framework/components/chui_kbd/kbd.js +12 -10
- package/framework/components/chui_kbd/styles.css +1 -1
- package/framework/components/chui_label/label.js +31 -29
- package/framework/components/chui_label/styles.css +3 -3
- package/framework/components/chui_link/link.js +36 -29
- package/framework/components/chui_link/styles.css +11 -4
- package/framework/components/chui_list/list.js +42 -38
- package/framework/components/chui_list/styles.css +4 -3
- package/framework/components/chui_markdown_editor/markdown_editor.js +125 -109
- package/framework/components/chui_markdown_editor/styles.css +5 -5
- package/framework/components/chui_media/audio.js +457 -364
- package/framework/components/chui_media/audio_styles.css +74 -37
- package/framework/components/chui_media/image.js +99 -64
- package/framework/components/chui_media/image_compare.js +86 -55
- package/framework/components/chui_media/image_compare_styles.css +5 -5
- package/framework/components/chui_media/image_styles.css +4 -4
- package/framework/components/chui_media/video.js +264 -171
- package/framework/components/chui_media/video_styles.css +57 -24
- package/framework/components/chui_menu_bar/menu_bar.js +67 -65
- package/framework/components/chui_menu_bar/styles.css +14 -12
- package/framework/components/chui_message_bar/message_bar.js +551 -0
- package/framework/components/chui_message_bar/styles.css +248 -0
- package/framework/components/chui_modal/modal.js +81 -56
- package/framework/components/chui_modal/styles.css +3 -2
- package/framework/components/chui_notification/notification.js +107 -69
- package/framework/components/chui_notification/notification_download.js +28 -77
- package/framework/components/chui_notification/notification_download_card.js +115 -0
- package/framework/components/chui_notification/notification_download_progress.css +5 -4
- package/framework/components/chui_notification/notification_download_progress.js +73 -105
- package/framework/components/chui_notification/notification_update.js +44 -37
- package/framework/components/chui_notification/status_plate.css +3 -3
- package/framework/components/chui_notification/status_plate.js +2 -2
- package/framework/components/chui_notification/styles.css +6 -1
- package/framework/components/chui_notification/styles_download.css +2 -2
- package/framework/components/chui_notification/styles_update.css +3 -3
- package/framework/components/chui_org_chart/org_chart.js +101 -62
- package/framework/components/chui_org_chart/styles.css +2 -2
- package/framework/components/chui_pagination/pagination.js +65 -30
- package/framework/components/chui_pagination/styles.css +1 -1
- package/framework/components/chui_paragraph/paragraph.js +2 -2
- package/framework/components/chui_paragraph/styles.css +3 -3
- package/framework/components/chui_popover/popover.js +77 -50
- package/framework/components/chui_popover/styles.css +1 -1
- package/framework/components/chui_popups/popups.js +210 -181
- package/framework/components/chui_popups/styles.css +7 -7
- package/framework/components/chui_print_button/print_button.js +48 -33
- package/framework/components/chui_progress_bar/progress_bar.js +49 -19
- package/framework/components/chui_progress_bar/styles.css +6 -6
- package/framework/components/chui_progress_ring/progress_ring.js +32 -30
- package/framework/components/chui_progress_ring/styles.css +1 -1
- package/framework/components/chui_qrcode/qrcode.js +85 -41
- package/framework/components/chui_query_builder/query_builder.js +263 -170
- package/framework/components/chui_query_builder/styles.css +4 -4
- package/framework/components/chui_radio_group/radio_group.js +36 -26
- package/framework/components/chui_radio_group/styles.css +2 -2
- package/framework/components/chui_result/result.js +41 -31
- package/framework/components/chui_result/styles.css +3 -3
- package/framework/components/chui_scheduler/scheduler.js +126 -104
- package/framework/components/chui_scheduler/styles.css +11 -7
- package/framework/components/chui_screen_spinner/screen_spinner.js +167 -0
- package/framework/components/chui_screen_spinner/styles.css +49 -0
- package/framework/components/chui_segmented_control/segmented_control.js +90 -27
- package/framework/components/chui_segmented_control/styles.css +32 -6
- package/framework/components/chui_settings/settings.js +160 -87
- package/framework/components/chui_settings/styles.css +4 -4
- package/framework/components/chui_shortcut_help/shortcut_help.js +82 -61
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +132 -53
- package/framework/components/chui_sidebar_nav/styles.css +9 -3
- package/framework/components/chui_skeleton/skeleton.js +29 -24
- package/framework/components/chui_slideshow/slideshow.js +122 -103
- package/framework/components/chui_slideshow/styles.css +22 -16
- package/framework/components/chui_spinner/spinner.js +17 -17
- package/framework/components/chui_spinner/styles.css +0 -1
- package/framework/components/chui_split_button/split_button.js +53 -30
- package/framework/components/chui_split_button/styles.css +22 -6
- package/framework/components/chui_splitter/splitter.js +46 -39
- package/framework/components/chui_splitter/styles.css +2 -2
- package/framework/components/chui_statistic/statistic.js +111 -84
- package/framework/components/chui_status_bar/status_bar.js +11 -9
- package/framework/components/chui_status_bar/styles.css +2 -2
- package/framework/components/chui_stepper/stepper.js +230 -54
- package/framework/components/chui_stepper/styles.css +79 -14
- package/framework/components/chui_sticky_bar/sticky_bar.js +53 -17
- package/framework/components/chui_sticky_bar/styles.css +11 -7
- package/framework/components/chui_tabs/chui_tabs.js +100 -46
- package/framework/components/chui_tabs/styles.css +43 -15
- package/framework/components/chui_text_editor/styles.css +24 -23
- package/framework/components/chui_text_editor/text_editor.js +103 -79
- package/framework/components/chui_text_editor/text_editor_panel.js +428 -367
- package/framework/components/chui_theme_toggle/theme_toggle.js +46 -25
- package/framework/components/chui_timeline/styles.css +3 -1
- package/framework/components/chui_timeline/timeline.js +14 -12
- package/framework/components/chui_toast_queue/styles.css +11 -11
- package/framework/components/chui_toast_queue/toast_queue.js +82 -73
- package/framework/components/chui_toolbar/styles.css +2 -2
- package/framework/components/chui_toolbar/toolbar.js +20 -13
- package/framework/components/chui_tooltip/styles.css +2 -2
- package/framework/components/chui_tooltip/tooltip.js +40 -27
- package/framework/components/chui_tour/styles.css +12 -7
- package/framework/components/chui_tour/tour.js +132 -98
- package/framework/components/chui_transfer/styles.css +8 -7
- package/framework/components/chui_transfer/transfer.js +143 -123
- package/framework/components/chui_tree_table/styles.css +4 -4
- package/framework/components/chui_tree_table/tree_table.js +88 -74
- package/framework/components/chui_tree_view/styles.css +14 -10
- package/framework/components/chui_tree_view/tree_view.js +298 -253
- package/framework/components/chui_user_bar/styles.css +145 -0
- package/framework/components/chui_user_bar/user_bar.js +402 -0
- package/framework/components/chui_user_list_bar/styles.css +173 -0
- package/framework/components/chui_user_list_bar/user_list_bar.js +485 -0
- package/framework/components/chui_watermark/watermark.js +41 -33
- package/framework/components/chui_webview/styles.css +2 -2
- package/framework/components/chui_webview/webview.js +64 -52
- package/framework/components/chui_write_bar/styles.css +172 -0
- package/framework/components/chui_write_bar/write_bar.js +320 -0
- package/framework/main_window.js +1234 -0
- package/framework/modules/chui_a11y/chui_a11y.js +153 -123
- package/framework/modules/chui_animations/animations.js +105 -43
- package/framework/modules/chui_animations/motion.js +120 -0
- package/framework/modules/chui_animations/styles.css +37 -4
- package/framework/modules/chui_bridge/preload.js +36 -25
- package/framework/modules/chui_functions.js +69 -63
- package/framework/modules/chui_highlight/chui_highlight.js +25 -22
- package/framework/modules/chui_highlight/styles.css +13 -10
- package/framework/modules/chui_i18n/chui_i18n.js +12 -10
- 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 +65 -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 +12 -8
- package/framework/modules/chui_i18n/locales/validate.js +3 -3
- package/framework/modules/chui_json/chui_json.js +11 -11
- package/framework/modules/chui_layout/chui_layout.js +12 -10
- package/framework/modules/chui_logger/chui_logger.js +47 -28
- package/framework/modules/chui_page/page.js +39 -33
- package/framework/modules/chui_palette/palette.js +61 -0
- package/framework/modules/chui_qr/chui_qr.js +179 -88
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +79 -68
- package/framework/modules/chui_scrollbar/styles.css +4 -2
- package/framework/modules/chui_services/chui_channels.js +27 -13
- package/framework/modules/chui_services/chui_services.js +47 -39
- package/framework/modules/chui_services/desktop.js +108 -101
- package/framework/modules/chui_sortable/chui_sortable.js +33 -28
- package/framework/modules/chui_validate/chui_validate.js +10 -7
- package/framework/tray_bar/chui_menu_items.js +136 -46
- package/index.d.ts +5046 -0
- package/index.js +199 -1254
- package/package.json +81 -68
- package/framework/components/telegram_bot/chui_telegram_bot.js +0 -184
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {setStyles} = require("../chui_functions");
|
|
1
|
+
const { setStyles } = require("../chui_functions");
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Полосы прокрутки поверх содержимого (overlay), автоматически на все прокручиваемые узлы.
|
|
@@ -36,7 +36,7 @@ const {setStyles} = require("../chui_functions");
|
|
|
36
36
|
*/
|
|
37
37
|
const AXIS = {
|
|
38
38
|
VERTICAL: "vertical",
|
|
39
|
-
HORIZONTAL: "horizontal"
|
|
39
|
+
HORIZONTAL: "horizontal",
|
|
40
40
|
};
|
|
41
41
|
const AXES = [AXIS.VERTICAL, AXIS.HORIZONTAL];
|
|
42
42
|
/** Толщина глифа и зазор от края узла: глиф ложится в отступ узла, а не на содержимое */
|
|
@@ -122,22 +122,22 @@ class Scrollbar {
|
|
|
122
122
|
#listeners = [];
|
|
123
123
|
#thickness = THICKNESS;
|
|
124
124
|
#inset = INSET;
|
|
125
|
-
#
|
|
126
|
-
#
|
|
125
|
+
#insetCache = undefined;
|
|
126
|
+
#zIndex = 0;
|
|
127
127
|
#hovered = false;
|
|
128
128
|
#dragging = undefined;
|
|
129
|
-
#
|
|
129
|
+
#shouldShow = false;
|
|
130
130
|
#timer = 0;
|
|
131
131
|
#frame = 0;
|
|
132
|
-
#
|
|
133
|
-
#
|
|
132
|
+
#dragStart = 0;
|
|
133
|
+
#dragScroll = 0;
|
|
134
134
|
|
|
135
135
|
constructor(element = undefined, options = { thickness: Number(), inset: Number(), zIndex: Number() }) {
|
|
136
136
|
setStyles(__dirname + "/styles.css", "chUiJS_Scrollbar");
|
|
137
137
|
this.#element = element;
|
|
138
138
|
this.#thickness = Scrollbar.#numberOr(options.thickness, THICKNESS);
|
|
139
139
|
this.#inset = Scrollbar.#numberOr(options.inset, INSET);
|
|
140
|
-
this.#
|
|
140
|
+
this.#zIndex = Scrollbar.#zIndexFor(element, options.zIndex);
|
|
141
141
|
// Нативная полоса скрыта: место под неё не резервируется, иначе содержимое уезжало бы
|
|
142
142
|
// из центра, а поверх системной полосы лёг бы второй глиф
|
|
143
143
|
element.classList.add(HOST_CLASS);
|
|
@@ -203,7 +203,7 @@ class Scrollbar {
|
|
|
203
203
|
thumb = document.createElement("chui_scrollbar_thumb");
|
|
204
204
|
thumb.dataset.axis = axis;
|
|
205
205
|
thumb.setAttribute("aria-hidden", "true");
|
|
206
|
-
thumb.style.zIndex = String(this.#
|
|
206
|
+
thumb.style.zIndex = String(this.#zIndex);
|
|
207
207
|
document.body.appendChild(thumb);
|
|
208
208
|
this.#thumbs.set(axis, thumb);
|
|
209
209
|
this.#listen(thumb, "pointerenter", () => this.#onEnter());
|
|
@@ -229,24 +229,24 @@ class Scrollbar {
|
|
|
229
229
|
* `refreshInsets()` (наблюдатель за размерами и resize окна).
|
|
230
230
|
*/
|
|
231
231
|
#insets() {
|
|
232
|
-
if (this.#
|
|
232
|
+
if (this.#insetCache !== undefined) return this.#insetCache;
|
|
233
233
|
const style = getComputedStyle(this.#element);
|
|
234
234
|
const read = (name) => {
|
|
235
235
|
const value = Number.parseFloat(style.getPropertyValue(name));
|
|
236
236
|
return Number.isFinite(value) === true && value > 0 ? value : 0;
|
|
237
237
|
};
|
|
238
|
-
this.#
|
|
238
|
+
this.#insetCache = {
|
|
239
239
|
top: read("--scrollbar_inset_top"),
|
|
240
240
|
right: read("--scrollbar_inset_right"),
|
|
241
241
|
bottom: read("--scrollbar_inset_bottom"),
|
|
242
|
-
left: read("--scrollbar_inset_left")
|
|
242
|
+
left: read("--scrollbar_inset_left"),
|
|
243
243
|
};
|
|
244
|
-
return this.#
|
|
244
|
+
return this.#insetCache;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
/** Сбросить кэш отступов и пересчитать: вместе с раскладкой мог смениться и токен */
|
|
248
248
|
refreshInsets() {
|
|
249
|
-
this.#
|
|
249
|
+
this.#insetCache = undefined;
|
|
250
250
|
this.#render();
|
|
251
251
|
return this;
|
|
252
252
|
}
|
|
@@ -269,16 +269,16 @@ class Scrollbar {
|
|
|
269
269
|
// ползунок не доезжает до конца (замер: недоезд 14px на странице 2917px).
|
|
270
270
|
const overflow = content - view;
|
|
271
271
|
if (track <= 0 || overflow <= 1) return undefined;
|
|
272
|
-
const
|
|
272
|
+
const thumbSize = Math.max(MIN_THUMB, Math.round((track * track) / content));
|
|
273
273
|
return {
|
|
274
274
|
track: track,
|
|
275
275
|
content: content,
|
|
276
276
|
overflow: overflow,
|
|
277
|
-
thumb_size:
|
|
278
|
-
travel: track -
|
|
277
|
+
thumb_size: thumbSize,
|
|
278
|
+
travel: track - thumbSize,
|
|
279
279
|
offset: vertical ? element.scrollTop : element.scrollLeft,
|
|
280
280
|
start: vertical ? insets.top : insets.left,
|
|
281
|
-
end: vertical ? insets.bottom : insets.right
|
|
281
|
+
end: vertical ? insets.bottom : insets.right,
|
|
282
282
|
};
|
|
283
283
|
}
|
|
284
284
|
|
|
@@ -289,17 +289,17 @@ class Scrollbar {
|
|
|
289
289
|
const vertical = axis === AXIS.VERTICAL;
|
|
290
290
|
const box = vertical
|
|
291
291
|
? {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
292
|
+
left: Math.round(rect.right - metrics.end - this.#inset - this.#thickness),
|
|
293
|
+
top: Math.round(rect.top + metrics.start + position),
|
|
294
|
+
width: this.#thickness,
|
|
295
|
+
height: metrics.thumb_size,
|
|
296
|
+
}
|
|
297
297
|
: {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
298
|
+
left: Math.round(rect.left + metrics.start + position),
|
|
299
|
+
top: Math.round(rect.bottom - metrics.end - this.#inset - this.#thickness),
|
|
300
|
+
width: metrics.thumb_size,
|
|
301
|
+
height: this.#thickness,
|
|
302
|
+
};
|
|
303
303
|
// Запись в стиль всегда обнуляет разметку, а пересчёт идёт каждый кадр прокрутки:
|
|
304
304
|
// одинаковую геометрию не переписываем, иначе получаем reflow на каждый узел
|
|
305
305
|
const signature = `${box.left}|${box.top}|${box.width}|${box.height}`;
|
|
@@ -321,11 +321,16 @@ class Scrollbar {
|
|
|
321
321
|
return;
|
|
322
322
|
}
|
|
323
323
|
const rect = element.getBoundingClientRect();
|
|
324
|
-
const
|
|
325
|
-
|
|
324
|
+
const onScreen =
|
|
325
|
+
rect.width > 0 &&
|
|
326
|
+
rect.height > 0 &&
|
|
327
|
+
rect.bottom > 0 &&
|
|
328
|
+
rect.top < window.innerHeight &&
|
|
329
|
+
rect.right > 0 &&
|
|
330
|
+
rect.left < window.innerWidth;
|
|
326
331
|
// Узел за пределами окна (его вытянет прокрутка родителя): писать в глифы нечего,
|
|
327
332
|
// кроме снятия видимости при уходе — иначе на каждый узел приходился бы reflow
|
|
328
|
-
if (
|
|
333
|
+
if (onScreen === false) {
|
|
329
334
|
if (this.#ready.size === 0) return;
|
|
330
335
|
this.#ready.clear();
|
|
331
336
|
this.#paint();
|
|
@@ -345,16 +350,16 @@ class Scrollbar {
|
|
|
345
350
|
for (const axis of AXES) {
|
|
346
351
|
const thumb = this.#thumbs.get(axis);
|
|
347
352
|
if (thumb === undefined) continue;
|
|
348
|
-
const shown = this.#
|
|
353
|
+
const shown = this.#shouldShow === true && this.#ready.has(axis) === true;
|
|
349
354
|
// Лишняя запись класса — тоже изменение разметки, поэтому только по факту смены
|
|
350
355
|
if (thumb.classList.contains(VISIBLE_CLASS) !== shown) thumb.classList.toggle(VISIBLE_CLASS, shown);
|
|
351
356
|
}
|
|
352
|
-
if (this.#
|
|
357
|
+
if (this.#shouldShow === true && this.#ready.size > 0) this.#startFollowFrame();
|
|
353
358
|
else this.#stopFollowFrame();
|
|
354
359
|
}
|
|
355
360
|
|
|
356
361
|
#onScroll() {
|
|
357
|
-
this.#
|
|
362
|
+
this.#shouldShow = true;
|
|
358
363
|
this.#render();
|
|
359
364
|
// Курсор над узлом — глиф и так держится наведением; иначе показываем и убираем
|
|
360
365
|
if (this.#hovered === false) this.#scheduleHide(HIDE_DELAY);
|
|
@@ -362,7 +367,7 @@ class Scrollbar {
|
|
|
362
367
|
|
|
363
368
|
#onEnter() {
|
|
364
369
|
this.#hovered = true;
|
|
365
|
-
this.#
|
|
370
|
+
this.#shouldShow = true;
|
|
366
371
|
this.#cancelHide();
|
|
367
372
|
this.#render();
|
|
368
373
|
}
|
|
@@ -378,7 +383,7 @@ class Scrollbar {
|
|
|
378
383
|
this.#timer = setTimeout(() => {
|
|
379
384
|
this.#timer = 0;
|
|
380
385
|
if (this.#hovered === true || this.#dragging !== undefined) return;
|
|
381
|
-
this.#
|
|
386
|
+
this.#shouldShow = false;
|
|
382
387
|
this.#paint();
|
|
383
388
|
}, delay);
|
|
384
389
|
}
|
|
@@ -410,14 +415,14 @@ class Scrollbar {
|
|
|
410
415
|
// Без preventDefault указатель увёл бы фокус и начал выделение текста под глифом
|
|
411
416
|
event.preventDefault();
|
|
412
417
|
this.#dragging = axis;
|
|
413
|
-
this.#
|
|
418
|
+
this.#shouldShow = true;
|
|
414
419
|
this.#cancelHide();
|
|
415
420
|
const thumb = this.#thumbFor(axis);
|
|
416
421
|
thumb.classList.add(DRAGGING_CLASS);
|
|
417
422
|
if (typeof thumb.setPointerCapture === "function") thumb.setPointerCapture(event.pointerId);
|
|
418
423
|
const vertical = axis === AXIS.VERTICAL;
|
|
419
|
-
this.#
|
|
420
|
-
this.#
|
|
424
|
+
this.#dragStart = vertical ? event.clientY : event.clientX;
|
|
425
|
+
this.#dragScroll = vertical ? this.#element.scrollTop : this.#element.scrollLeft;
|
|
421
426
|
this.#render();
|
|
422
427
|
}
|
|
423
428
|
|
|
@@ -429,9 +434,9 @@ class Scrollbar {
|
|
|
429
434
|
const vertical = axis === AXIS.VERTICAL;
|
|
430
435
|
const pointer = vertical ? event.clientY : event.clientX;
|
|
431
436
|
// Глиф проходит `travel` пикселей, содержимое за это время — `overflow`: отсюда масштаб
|
|
432
|
-
const delta = (pointer - this.#
|
|
433
|
-
if (vertical) this.#element.scrollTop = this.#
|
|
434
|
-
else this.#element.scrollLeft = this.#
|
|
437
|
+
const delta = (pointer - this.#dragStart) * (metrics.overflow / metrics.travel);
|
|
438
|
+
if (vertical) this.#element.scrollTop = this.#dragScroll + delta;
|
|
439
|
+
else this.#element.scrollLeft = this.#dragScroll + delta;
|
|
435
440
|
}
|
|
436
441
|
|
|
437
442
|
#onDragEnd(event = Object()) {
|
|
@@ -462,8 +467,8 @@ class OverlayScrollbars {
|
|
|
462
467
|
/** Что перепроверить в ближайшем кадре: узел → надо ли обойти его поддерево */
|
|
463
468
|
static #pending = new Map();
|
|
464
469
|
static #frame = 0;
|
|
465
|
-
static #
|
|
466
|
-
static #
|
|
470
|
+
static #scrollFrame = 0;
|
|
471
|
+
static #scanFrame = 0;
|
|
467
472
|
/** Прокрутка и изменение окна: глифы надо догнать (прокрутка родителя двигает и детей) */
|
|
468
473
|
static #onViewportChange = () => OverlayScrollbars.#scheduleRefresh();
|
|
469
474
|
/*
|
|
@@ -484,9 +489,9 @@ class OverlayScrollbars {
|
|
|
484
489
|
};
|
|
485
490
|
|
|
486
491
|
static #scheduleScan() {
|
|
487
|
-
if (OverlayScrollbars.#
|
|
488
|
-
OverlayScrollbars.#
|
|
489
|
-
OverlayScrollbars.#
|
|
492
|
+
if (OverlayScrollbars.#scanFrame !== 0) return;
|
|
493
|
+
OverlayScrollbars.#scanFrame = requestAnimationFrame(() => {
|
|
494
|
+
OverlayScrollbars.#scanFrame = 0;
|
|
490
495
|
OverlayScrollbars.refreshAll();
|
|
491
496
|
OverlayScrollbars.scan(document.body);
|
|
492
497
|
});
|
|
@@ -522,19 +527,25 @@ class OverlayScrollbars {
|
|
|
522
527
|
subtree: true,
|
|
523
528
|
characterData: true,
|
|
524
529
|
attributes: true,
|
|
525
|
-
attributeFilter: ["class", "style", "hidden"]
|
|
530
|
+
attributeFilter: ["class", "style", "hidden"],
|
|
526
531
|
});
|
|
527
532
|
}
|
|
528
533
|
OverlayScrollbars.scan(document.body);
|
|
529
534
|
// Прокрутка любого узла двигает и вложенные в него: свой слушатель есть у каждого
|
|
530
535
|
// накрытого узла, но «прокрутился родитель» его не будит. Событие `scroll` не
|
|
531
536
|
// всплывает, поэтому ловим на фазе захвата — так оно доходит и от потомков.
|
|
532
|
-
document.addEventListener("scroll", OverlayScrollbars.#onViewportChange, {capture: true, passive: true});
|
|
533
|
-
window.addEventListener("resize", OverlayScrollbars.#onResize, {passive: true});
|
|
537
|
+
document.addEventListener("scroll", OverlayScrollbars.#onViewportChange, { capture: true, passive: true });
|
|
538
|
+
window.addEventListener("resize", OverlayScrollbars.#onResize, { passive: true });
|
|
534
539
|
// Панели и слои появляются анимацией (сдвиг, масштаб). Пока узел ехал, он был за
|
|
535
540
|
// пределами окна и геометрия не считалась, поэтому по завершении анимации пересчитываем.
|
|
536
|
-
document.addEventListener("transitionend", OverlayScrollbars.#onViewportChange, {
|
|
537
|
-
|
|
541
|
+
document.addEventListener("transitionend", OverlayScrollbars.#onViewportChange, {
|
|
542
|
+
capture: true,
|
|
543
|
+
passive: true,
|
|
544
|
+
});
|
|
545
|
+
document.addEventListener("animationend", OverlayScrollbars.#onViewportChange, {
|
|
546
|
+
capture: true,
|
|
547
|
+
passive: true,
|
|
548
|
+
});
|
|
538
549
|
return OverlayScrollbars;
|
|
539
550
|
}
|
|
540
551
|
|
|
@@ -542,20 +553,20 @@ class OverlayScrollbars {
|
|
|
542
553
|
static stop() {
|
|
543
554
|
if (OverlayScrollbars.#started === false) return OverlayScrollbars;
|
|
544
555
|
OverlayScrollbars.#started = false;
|
|
545
|
-
document.removeEventListener("scroll", OverlayScrollbars.#onViewportChange, {capture: true});
|
|
546
|
-
document.removeEventListener("transitionend", OverlayScrollbars.#onViewportChange, {capture: true});
|
|
547
|
-
document.removeEventListener("animationend", OverlayScrollbars.#onViewportChange, {capture: true});
|
|
556
|
+
document.removeEventListener("scroll", OverlayScrollbars.#onViewportChange, { capture: true });
|
|
557
|
+
document.removeEventListener("transitionend", OverlayScrollbars.#onViewportChange, { capture: true });
|
|
558
|
+
document.removeEventListener("animationend", OverlayScrollbars.#onViewportChange, { capture: true });
|
|
548
559
|
window.removeEventListener("resize", OverlayScrollbars.#onResize);
|
|
549
560
|
if (OverlayScrollbars.#observer !== undefined) OverlayScrollbars.#observer.disconnect();
|
|
550
561
|
if (OverlayScrollbars.#resize !== undefined) OverlayScrollbars.#resize.disconnect();
|
|
551
562
|
OverlayScrollbars.#observer = undefined;
|
|
552
563
|
OverlayScrollbars.#resize = undefined;
|
|
553
564
|
if (OverlayScrollbars.#frame !== 0) cancelAnimationFrame(OverlayScrollbars.#frame);
|
|
554
|
-
if (OverlayScrollbars.#
|
|
555
|
-
if (OverlayScrollbars.#
|
|
565
|
+
if (OverlayScrollbars.#scrollFrame !== 0) cancelAnimationFrame(OverlayScrollbars.#scrollFrame);
|
|
566
|
+
if (OverlayScrollbars.#scanFrame !== 0) cancelAnimationFrame(OverlayScrollbars.#scanFrame);
|
|
556
567
|
OverlayScrollbars.#frame = 0;
|
|
557
|
-
OverlayScrollbars.#
|
|
558
|
-
OverlayScrollbars.#
|
|
568
|
+
OverlayScrollbars.#scrollFrame = 0;
|
|
569
|
+
OverlayScrollbars.#scanFrame = 0;
|
|
559
570
|
OverlayScrollbars.#pending.clear();
|
|
560
571
|
for (const element of [...OverlayScrollbars.#instances]) OverlayScrollbars.#detach(element);
|
|
561
572
|
return OverlayScrollbars;
|
|
@@ -571,9 +582,9 @@ class OverlayScrollbars {
|
|
|
571
582
|
}
|
|
572
583
|
|
|
573
584
|
static #scheduleRefresh() {
|
|
574
|
-
if (OverlayScrollbars.#
|
|
575
|
-
OverlayScrollbars.#
|
|
576
|
-
OverlayScrollbars.#
|
|
585
|
+
if (OverlayScrollbars.#scrollFrame !== 0) return;
|
|
586
|
+
OverlayScrollbars.#scrollFrame = requestAnimationFrame(() => {
|
|
587
|
+
OverlayScrollbars.#scrollFrame = 0;
|
|
577
588
|
OverlayScrollbars.refreshAll();
|
|
578
589
|
});
|
|
579
590
|
}
|
|
@@ -623,13 +634,13 @@ class OverlayScrollbars {
|
|
|
623
634
|
if (node === document.body || node === document.documentElement) return false;
|
|
624
635
|
if (node.tagName === "CHUI_SCROLLBAR_THUMB") return false;
|
|
625
636
|
// Быстрая отсечка до чтения стилей: переполнения нет — прокручивать нечего
|
|
626
|
-
const
|
|
627
|
-
const
|
|
628
|
-
if (
|
|
637
|
+
const overflowY = node.scrollHeight - node.clientHeight > 1;
|
|
638
|
+
const overflowX = node.scrollWidth - node.clientWidth > 1;
|
|
639
|
+
if (overflowY === false && overflowX === false) return false;
|
|
629
640
|
const style = getComputedStyle(node);
|
|
630
|
-
const
|
|
631
|
-
const
|
|
632
|
-
return
|
|
641
|
+
const scrollsY = overflowY === true && (style.overflowY === "auto" || style.overflowY === "scroll");
|
|
642
|
+
const scrollsX = overflowX === true && (style.overflowX === "auto" || style.overflowX === "scroll");
|
|
643
|
+
return scrollsY === true || scrollsX === true;
|
|
633
644
|
}
|
|
634
645
|
|
|
635
646
|
static #onMutations(records = []) {
|
|
@@ -15,14 +15,16 @@ chui_scrollbar_thumb {
|
|
|
15
15
|
z-index: 900;
|
|
16
16
|
display: block;
|
|
17
17
|
box-sizing: border-box;
|
|
18
|
-
border-radius: var(--
|
|
18
|
+
border-radius: var(--radius_sm);
|
|
19
19
|
background: var(--scrollbar_thumb);
|
|
20
20
|
/* Пока глиф не виден, он не должен перехватывать курсор: наведение ловит сам узел */
|
|
21
21
|
pointer-events: none;
|
|
22
22
|
opacity: 0;
|
|
23
23
|
/* Плавно только появление и цвет: `top`/`left`/`width`/`height` анимировать нельзя —
|
|
24
24
|
глиф отставал бы от прокрутки и «плыл» за содержимым */
|
|
25
|
-
transition:
|
|
25
|
+
transition:
|
|
26
|
+
opacity var(--motion_fast) var(--motion_ease),
|
|
27
|
+
background-color var(--motion_fast) var(--motion_ease);
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
chui_scrollbar_thumb.chui_scrollbar_visible {
|
|
@@ -76,7 +76,7 @@ const SERVICES_CHANNELS = {
|
|
|
76
76
|
/** Сессия окна-отправителя: кеш и хранилище */
|
|
77
77
|
SESSION_CACHE_SIZE: "chui_services_session_cache_size",
|
|
78
78
|
SESSION_CLEAR_CACHE: "chui_services_session_clear_cache",
|
|
79
|
-
SESSION_CLEAR_STORAGE: "chui_services_session_clear_storage"
|
|
79
|
+
SESSION_CLEAR_STORAGE: "chui_services_session_clear_storage",
|
|
80
80
|
};
|
|
81
81
|
|
|
82
82
|
/**
|
|
@@ -85,8 +85,22 @@ const SERVICES_CHANNELS = {
|
|
|
85
85
|
* Имена совпадают с именами Electron, кроме `logs` (в Electron это `logs`).
|
|
86
86
|
*/
|
|
87
87
|
const APP_PATH_NAMES = [
|
|
88
|
-
"home",
|
|
89
|
-
"
|
|
88
|
+
"home",
|
|
89
|
+
"appData",
|
|
90
|
+
"userData",
|
|
91
|
+
"sessionData",
|
|
92
|
+
"temp",
|
|
93
|
+
"exe",
|
|
94
|
+
"module",
|
|
95
|
+
"desktop",
|
|
96
|
+
"documents",
|
|
97
|
+
"downloads",
|
|
98
|
+
"music",
|
|
99
|
+
"pictures",
|
|
100
|
+
"videos",
|
|
101
|
+
"logs",
|
|
102
|
+
"recent",
|
|
103
|
+
"crashDumps",
|
|
90
104
|
];
|
|
91
105
|
|
|
92
106
|
/**
|
|
@@ -130,7 +144,7 @@ const SERVICES_CALLS = {
|
|
|
130
144
|
dialogMessage: SERVICES_CHANNELS.DIALOG_MESSAGE,
|
|
131
145
|
sessionCacheSize: SERVICES_CHANNELS.SESSION_CACHE_SIZE,
|
|
132
146
|
sessionClearCache: SERVICES_CHANNELS.SESSION_CLEAR_CACHE,
|
|
133
|
-
sessionClearStorage: SERVICES_CHANNELS.SESSION_CLEAR_STORAGE
|
|
147
|
+
sessionClearStorage: SERVICES_CHANNELS.SESSION_CLEAR_STORAGE,
|
|
134
148
|
};
|
|
135
149
|
|
|
136
150
|
/**
|
|
@@ -154,7 +168,7 @@ const SERVICES_SYNC_CALLS = {
|
|
|
154
168
|
// Закрытие и перезапуск отвечают мгновенно (`setImmediate` в main откладывает выход),
|
|
155
169
|
// поэтому синхронный канал здесь так же уместен, как у пути: странице не нужен `await`
|
|
156
170
|
appQuitSync: SERVICES_CHANNELS.APP_QUIT_SYNC,
|
|
157
|
-
appRestartSync: SERVICES_CHANNELS.APP_RESTART_SYNC
|
|
171
|
+
appRestartSync: SERVICES_CHANNELS.APP_RESTART_SYNC,
|
|
158
172
|
};
|
|
159
173
|
|
|
160
174
|
/** Каналы моста: окно, тема и прикладные сообщения безопасного окна */
|
|
@@ -166,19 +180,19 @@ const BRIDGE_CHANNELS = {
|
|
|
166
180
|
LOCALE_GET: "chui_bridge_locale_get",
|
|
167
181
|
LOCALE_EVENT: "chui_bridge_locale_event",
|
|
168
182
|
/** Прикладные сообщения страницы в main по своему каналу из белого списка */
|
|
169
|
-
MESSAGE: "chui_bridge_message"
|
|
183
|
+
MESSAGE: "chui_bridge_message",
|
|
170
184
|
};
|
|
171
185
|
|
|
172
186
|
/** Дополнительные аргументы процесса preload'а: страница, белый список каналов и CSP */
|
|
173
187
|
const BRIDGE_ARGS = {
|
|
174
188
|
RENDER: "--chui-render=",
|
|
175
189
|
CHANNELS: "--chui-channels=",
|
|
176
|
-
CSP: "--chui-csp="
|
|
190
|
+
CSP: "--chui-csp=",
|
|
177
191
|
};
|
|
178
192
|
|
|
179
|
-
exports.SERVICES_CHANNELS = SERVICES_CHANNELS
|
|
180
|
-
exports.SERVICES_CALLS = SERVICES_CALLS
|
|
181
|
-
exports.SERVICES_SYNC_CALLS = SERVICES_SYNC_CALLS
|
|
182
|
-
exports.BRIDGE_CHANNELS = BRIDGE_CHANNELS
|
|
183
|
-
exports.APP_PATH_NAMES = APP_PATH_NAMES
|
|
184
|
-
exports.BRIDGE_ARGS = BRIDGE_ARGS
|
|
193
|
+
exports.SERVICES_CHANNELS = SERVICES_CHANNELS;
|
|
194
|
+
exports.SERVICES_CALLS = SERVICES_CALLS;
|
|
195
|
+
exports.SERVICES_SYNC_CALLS = SERVICES_SYNC_CALLS;
|
|
196
|
+
exports.BRIDGE_CHANNELS = BRIDGE_CHANNELS;
|
|
197
|
+
exports.APP_PATH_NAMES = APP_PATH_NAMES;
|
|
198
|
+
exports.BRIDGE_ARGS = BRIDGE_ARGS;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const {globalShortcut, clipboard, app, dialog, nativeImage, nativeTheme, shell, BrowserWindow} = require("electron");
|
|
1
|
+
const { globalShortcut, clipboard, app, dialog, nativeImage, nativeTheme, shell, BrowserWindow } = require("electron");
|
|
2
2
|
const fs = require("fs");
|
|
3
|
-
const {Log} = require("../chui_logger/chui_logger");
|
|
4
|
-
const {SERVICES_CHANNELS} = require("./chui_channels");
|
|
5
|
-
const {I18n} = require("../chui_i18n/chui_i18n");
|
|
3
|
+
const { Log } = require("../chui_logger/chui_logger");
|
|
4
|
+
const { SERVICES_CHANNELS } = require("./chui_channels");
|
|
5
|
+
const { I18n } = require("../chui_i18n/chui_i18n");
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Десктоп-сервисы main-процесса. Имена IPC-каналов живут в `chui_channels.js` — тот модуль
|
|
@@ -52,9 +52,9 @@ class Shell {
|
|
|
52
52
|
*/
|
|
53
53
|
class Shortcuts {
|
|
54
54
|
#registered = new Map();
|
|
55
|
-
#
|
|
55
|
+
#boundQuit = false;
|
|
56
56
|
#destroyed = false;
|
|
57
|
-
#
|
|
57
|
+
#onQuit = () => this.unregisterAll();
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* `register("Mod+Shift+P", () => {})` — вернёт `false`, если комбинацию уже занял
|
|
@@ -113,15 +113,15 @@ class Shortcuts {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
#bindQuit() {
|
|
116
|
-
if (this.#
|
|
117
|
-
this.#
|
|
118
|
-
app.on("will-quit", this.#
|
|
116
|
+
if (this.#boundQuit) return;
|
|
117
|
+
this.#boundQuit = true;
|
|
118
|
+
app.on("will-quit", this.#onQuit);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
#unbindQuit() {
|
|
122
|
-
if (!this.#
|
|
123
|
-
this.#
|
|
124
|
-
app.removeListener("will-quit", this.#
|
|
122
|
+
if (!this.#boundQuit) return;
|
|
123
|
+
this.#boundQuit = false;
|
|
124
|
+
app.removeListener("will-quit", this.#onQuit);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -173,7 +173,7 @@ class RecentDocuments {
|
|
|
173
173
|
#items = [];
|
|
174
174
|
#limit = RecentDocuments.MAX;
|
|
175
175
|
|
|
176
|
-
constructor(options = {limit: RecentDocuments.MAX}) {
|
|
176
|
+
constructor(options = { limit: RecentDocuments.MAX }) {
|
|
177
177
|
if (options.limit !== undefined) this.#limit = options.limit;
|
|
178
178
|
}
|
|
179
179
|
|
|
@@ -183,8 +183,10 @@ class RecentDocuments {
|
|
|
183
183
|
}
|
|
184
184
|
app.addRecentDocument(path);
|
|
185
185
|
// Один и тот же файл не должен появляться дважды
|
|
186
|
-
this.#items = [
|
|
187
|
-
|
|
186
|
+
this.#items = [
|
|
187
|
+
{ path: path, name: name === undefined ? path : name },
|
|
188
|
+
...this.#items.filter((item) => item.path !== path),
|
|
189
|
+
].slice(0, this.#limit);
|
|
188
190
|
return this;
|
|
189
191
|
}
|
|
190
192
|
|
|
@@ -207,7 +209,7 @@ class RecentDocuments {
|
|
|
207
209
|
return {
|
|
208
210
|
role: "recentDocuments",
|
|
209
211
|
label: pageTitle,
|
|
210
|
-
submenu: [{label: clearLabel, role: "clearRecentDocuments"}]
|
|
212
|
+
submenu: [{ label: clearLabel, role: "clearRecentDocuments" }],
|
|
211
213
|
};
|
|
212
214
|
}
|
|
213
215
|
}
|
|
@@ -223,7 +225,7 @@ class TaskbarProgress {
|
|
|
223
225
|
NORMAL: "normal",
|
|
224
226
|
ERROR: "error",
|
|
225
227
|
PAUSED: "paused",
|
|
226
|
-
INDETERMINATE: "indeterminate"
|
|
228
|
+
INDETERMINATE: "indeterminate",
|
|
227
229
|
};
|
|
228
230
|
#window = undefined;
|
|
229
231
|
#value = 0;
|
|
@@ -285,7 +287,7 @@ class TaskbarProgress {
|
|
|
285
287
|
const window = this.#window;
|
|
286
288
|
if (window === undefined || window === null || typeof window.setProgressBar !== "function") return;
|
|
287
289
|
if (window.isDestroyed()) return;
|
|
288
|
-
window.setProgressBar(value, {mode: mode});
|
|
290
|
+
window.setProgressBar(value, { mode: mode });
|
|
289
291
|
}
|
|
290
292
|
|
|
291
293
|
/**
|
|
@@ -320,7 +322,7 @@ class Theme {
|
|
|
320
322
|
static SOURCE = {
|
|
321
323
|
SYSTEM: "system",
|
|
322
324
|
LIGHT: "light",
|
|
323
|
-
DARK: "dark"
|
|
325
|
+
DARK: "dark",
|
|
324
326
|
};
|
|
325
327
|
static #KEY = "theme_source";
|
|
326
328
|
#store = undefined;
|
|
@@ -414,7 +416,7 @@ class ClipboardHistory {
|
|
|
414
416
|
#limit = ClipboardHistory.MAX;
|
|
415
417
|
#store = undefined;
|
|
416
418
|
|
|
417
|
-
constructor(options = {limit: ClipboardHistory.MAX, store: undefined}) {
|
|
419
|
+
constructor(options = { limit: ClipboardHistory.MAX, store: undefined }) {
|
|
418
420
|
if (options.limit !== undefined) this.#limit = options.limit;
|
|
419
421
|
this.#store = options.store;
|
|
420
422
|
this.restore();
|
|
@@ -477,7 +479,7 @@ class ClipboardHistory {
|
|
|
477
479
|
}
|
|
478
480
|
}
|
|
479
481
|
|
|
480
|
-
exports.Shortcuts = Shortcuts
|
|
482
|
+
exports.Shortcuts = Shortcuts;
|
|
481
483
|
/**
|
|
482
484
|
* Печать: текущее окно, произвольный HTML и PDF.
|
|
483
485
|
*
|
|
@@ -492,15 +494,18 @@ exports.Shortcuts = Shortcuts
|
|
|
492
494
|
class Print {
|
|
493
495
|
static DEFAULT_OPTIONS = {
|
|
494
496
|
printBackground: true,
|
|
495
|
-
pageSize: "A4"
|
|
497
|
+
pageSize: "A4",
|
|
496
498
|
};
|
|
497
499
|
|
|
498
500
|
/** Печать окна; возвращает `{success, failureReason}` — печать асинхронна и не бросает */
|
|
499
501
|
page(window = undefined, options = {}) {
|
|
500
|
-
if (window === undefined || window === null || window.isDestroyed())
|
|
501
|
-
|
|
502
|
+
if (window === undefined || window === null || window.isDestroyed())
|
|
503
|
+
return Promise.resolve({ success: false, failureReason: I18n.t("feedback.printNoWindow") });
|
|
504
|
+
const settings = { ...Print.DEFAULT_OPTIONS, ...options };
|
|
502
505
|
return new Promise((resolve) => {
|
|
503
|
-
window.webContents.print(settings, (success, failureReason) =>
|
|
506
|
+
window.webContents.print(settings, (success, failureReason) =>
|
|
507
|
+
resolve({ success: success, failureReason: failureReason })
|
|
508
|
+
);
|
|
504
509
|
});
|
|
505
510
|
}
|
|
506
511
|
|
|
@@ -526,19 +531,22 @@ class Print {
|
|
|
526
531
|
let file = options.path;
|
|
527
532
|
if (file === undefined) {
|
|
528
533
|
const suggested = options.fileName === undefined ? "document.pdf" : options.fileName;
|
|
529
|
-
const result = await dialog.showSaveDialog(options.parent, {
|
|
530
|
-
|
|
534
|
+
const result = await dialog.showSaveDialog(options.parent, {
|
|
535
|
+
defaultPath: suggested,
|
|
536
|
+
filters: [{ name: "PDF", extensions: ["pdf"] }],
|
|
537
|
+
});
|
|
538
|
+
if (result.canceled || result.filePath === undefined) return { saved: false, canceled: true };
|
|
531
539
|
file = result.filePath;
|
|
532
540
|
}
|
|
533
541
|
fs.writeFileSync(file, data);
|
|
534
|
-
return {saved: true, path: file, canceled: false};
|
|
542
|
+
return { saved: true, path: file, canceled: false };
|
|
535
543
|
} finally {
|
|
536
544
|
if (!window.isDestroyed()) window.close();
|
|
537
545
|
}
|
|
538
546
|
}
|
|
539
547
|
|
|
540
548
|
static #pdfOptions(options = {}) {
|
|
541
|
-
const pdf = {...Print.DEFAULT_OPTIONS};
|
|
549
|
+
const pdf = { ...Print.DEFAULT_OPTIONS };
|
|
542
550
|
for (const key of ["landscape", "pageSize", "scale", "printBackground", "margins", "preferCSSPageSize"]) {
|
|
543
551
|
if (options[key] !== undefined) pdf[key] = options[key];
|
|
544
552
|
}
|
|
@@ -550,7 +558,7 @@ class Print {
|
|
|
550
558
|
const window = new BrowserWindow({
|
|
551
559
|
show: false,
|
|
552
560
|
parent: options.parent,
|
|
553
|
-
webPreferences: {sandbox: true, contextIsolation: true, nodeIntegration: false}
|
|
561
|
+
webPreferences: { sandbox: true, contextIsolation: true, nodeIntegration: false },
|
|
554
562
|
});
|
|
555
563
|
const source = `data:text/html;charset=utf-8,${encodeURIComponent(String(html))}`;
|
|
556
564
|
await window.loadURL(source);
|
|
@@ -558,12 +566,12 @@ class Print {
|
|
|
558
566
|
}
|
|
559
567
|
}
|
|
560
568
|
|
|
561
|
-
exports.Shell = Shell
|
|
562
|
-
exports.Clipboard = Clipboard
|
|
563
|
-
exports.ClipboardHistory = ClipboardHistory
|
|
564
|
-
exports.Theme = Theme
|
|
565
|
-
exports.Locale = Locale
|
|
566
|
-
exports.RecentDocuments = RecentDocuments
|
|
567
|
-
exports.Print = Print
|
|
568
|
-
exports.TaskbarProgress = TaskbarProgress
|
|
569
|
-
exports.SERVICES_CHANNELS = SERVICES_CHANNELS
|
|
569
|
+
exports.Shell = Shell;
|
|
570
|
+
exports.Clipboard = Clipboard;
|
|
571
|
+
exports.ClipboardHistory = ClipboardHistory;
|
|
572
|
+
exports.Theme = Theme;
|
|
573
|
+
exports.Locale = Locale;
|
|
574
|
+
exports.RecentDocuments = RecentDocuments;
|
|
575
|
+
exports.Print = Print;
|
|
576
|
+
exports.TaskbarProgress = TaskbarProgress;
|
|
577
|
+
exports.SERVICES_CHANNELS = SERVICES_CHANNELS;
|