chuijs 4.0.3 → 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 +536 -0
- package/framework/appLayout/default/chui_app_layout.js +361 -303
- package/framework/appLayout/default/global_style.css +243 -89
- package/framework/appLayout/default/main_theme_style.css +188 -101
- package/framework/components/chui_accordion/accordion.js +17 -17
- package/framework/components/chui_accordion/styles.css +7 -7
- package/framework/components/chui_action_sheet/action_sheet.js +35 -32
- package/framework/components/chui_action_sheet/styles.css +10 -4
- 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 +4 -4
- package/framework/components/chui_affix/styles.css +5 -0
- package/framework/components/chui_alert/alert.js +11 -5
- package/framework/components/chui_alert/styles.css +7 -0
- package/framework/components/chui_avatar/avatar.js +13 -13
- package/framework/components/chui_avatar/styles.css +1 -1
- package/framework/components/chui_avatar_group/avatar_group.js +4 -4
- package/framework/components/chui_avatar_group/styles.css +1 -1
- package/framework/components/chui_backtop/backtop.js +25 -2
- package/framework/components/chui_backtop/styles.css +21 -0
- package/framework/components/chui_badge/badge.js +15 -15
- 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/styles.css +1 -1
- package/framework/components/chui_button/button.js +24 -28
- package/framework/components/chui_button/styles.css +5 -5
- package/framework/components/chui_calendar/calendar.js +6 -6
- package/framework/components/chui_card/card.js +14 -14
- 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 +73 -51
- package/framework/components/chui_chat/styles.css +18 -7
- package/framework/components/chui_clipboard_history/clipboard_history.js +25 -20
- package/framework/components/chui_clipboard_history/styles.css +10 -8
- package/framework/components/chui_code/code.js +8 -8
- package/framework/components/chui_code/styles.css +2 -2
- package/framework/components/chui_code_editor/code_editor.js +26 -26
- package/framework/components/chui_code_editor/styles.css +3 -3
- package/framework/components/chui_command_palette/command_palette.js +29 -29
- package/framework/components/chui_command_palette/styles.css +5 -5
- package/framework/components/chui_console/console.js +9 -9
- package/framework/components/chui_console/styles.css +5 -2
- package/framework/components/chui_content_block/content_block.js +2 -2
- package/framework/components/chui_context_menu/context_menu.js +162 -54
- package/framework/components/chui_context_menu/styles.css +82 -8
- package/framework/components/chui_custom_element/custom_element.js +11 -11
- package/framework/components/chui_data_grid/data_grid.js +268 -268
- package/framework/components/chui_data_grid/styles.css +14 -14
- package/framework/components/chui_descriptions/styles.css +1 -1
- package/framework/components/chui_details/details.js +12 -12
- package/framework/components/chui_details/styles.css +7 -7
- package/framework/components/chui_diff_viewer/diff_viewer.js +88 -88
- package/framework/components/chui_diff_viewer/styles.css +9 -9
- package/framework/components/chui_divider/divider.js +6 -6
- package/framework/components/chui_divider/styles.css +2 -2
- package/framework/components/chui_drawer/drawer.js +37 -14
- package/framework/components/chui_drawer/styles.css +18 -4
- package/framework/components/chui_drop_zone/drop_zone.js +6 -6
- package/framework/components/chui_drop_zone/styles.css +10 -6
- package/framework/components/chui_fieldset/fieldset.js +6 -6
- package/framework/components/chui_fieldset/styles.css +5 -5
- package/framework/components/chui_file_explorer/file_explorer.js +115 -115
- package/framework/components/chui_file_explorer/styles.css +6 -6
- package/framework/components/chui_form/form.js +11 -11
- package/framework/components/chui_gantt/gantt.js +41 -41
- package/framework/components/chui_gantt/styles.css +5 -5
- package/framework/components/chui_graphs/graphs.js +82 -46
- package/framework/components/chui_graphs/styles.css +26 -5
- package/framework/components/chui_hero/hero.js +63 -20
- package/framework/components/chui_hero/styles.css +176 -7
- package/framework/components/chui_html_block/html_block.js +5 -5
- package/framework/components/chui_html_block/styles.css +1 -1
- package/framework/components/chui_hx/styles.css +2 -2
- package/framework/components/chui_icons/icons.js +7 -7
- package/framework/components/chui_icons/styles.css +2 -1
- package/framework/components/chui_inputs/chui_check_box/styles.css +12 -3
- package/framework/components/chui_inputs/chui_chips/chips.js +92 -31
- package/framework/components/chui_inputs/chui_chips/styles.css +28 -5
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +20 -15
- package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +58 -58
- package/framework/components/chui_inputs/chui_combo_box/styles.css +9 -9
- package/framework/components/chui_inputs/chui_date/date.js +93 -95
- package/framework/components/chui_inputs/chui_date/styles.css +8 -8
- package/framework/components/chui_inputs/chui_date_range/date_range.js +22 -22
- package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
- package/framework/components/chui_inputs/chui_datetime/datetime.js +12 -12
- package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
- package/framework/components/chui_inputs/chui_email/email.js +10 -10
- package/framework/components/chui_inputs/chui_email/styles.css +6 -6
- package/framework/components/chui_inputs/chui_file/file.js +8 -8
- package/framework/components/chui_inputs/chui_file/styles.css +12 -9
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +39 -39
- package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
- package/framework/components/chui_inputs/chui_masked/masked.js +44 -44
- package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
- package/framework/components/chui_inputs/chui_mention/mention.js +13 -13
- package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +147 -137
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +14 -8
- package/framework/components/chui_inputs/chui_number/number.js +42 -45
- package/framework/components/chui_inputs/chui_number/styles.css +6 -6
- package/framework/components/chui_inputs/chui_otp/otp.js +32 -32
- package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
- package/framework/components/chui_inputs/chui_password/password.js +30 -36
- package/framework/components/chui_inputs/chui_password/styles.css +7 -7
- package/framework/components/chui_inputs/chui_radio_button/styles.css +2 -2
- package/framework/components/chui_inputs/chui_rating/rating.js +28 -28
- package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
- package/framework/components/chui_inputs/chui_select_box/select_box.js +54 -54
- package/framework/components/chui_inputs/chui_select_box/styles.css +10 -10
- package/framework/components/chui_inputs/chui_slider/slider.js +14 -14
- package/framework/components/chui_inputs/chui_slider/styles.css +5 -4
- package/framework/components/chui_inputs/chui_text/styles.css +7 -7
- package/framework/components/chui_inputs/chui_text/text.js +13 -17
- package/framework/components/chui_inputs/chui_text_area/styles.css +8 -8
- package/framework/components/chui_inputs/chui_text_area/text_area.js +23 -23
- package/framework/components/chui_inputs/chui_time/styles.css +13 -17
- package/framework/components/chui_inputs/chui_time/time.js +35 -24
- package/framework/components/chui_inputs/chui_toggle/styles.css +10 -3
- package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
- package/framework/components/chui_json_editor/json_editor.js +87 -87
- package/framework/components/chui_json_editor/styles.css +5 -5
- package/framework/components/chui_json_viewer/json_viewer.js +80 -80
- package/framework/components/chui_json_viewer/styles.css +6 -6
- package/framework/components/chui_kanban/kanban.js +27 -27
- package/framework/components/chui_kanban/styles.css +8 -4
- package/framework/components/chui_kbd/styles.css +1 -1
- package/framework/components/chui_label/label.js +17 -17
- package/framework/components/chui_label/styles.css +1 -1
- package/framework/components/chui_link/link.js +9 -9
- package/framework/components/chui_link/styles.css +11 -4
- package/framework/components/chui_list/list.js +11 -11
- package/framework/components/chui_list/styles.css +2 -2
- package/framework/components/chui_markdown_editor/markdown_editor.js +66 -66
- package/framework/components/chui_markdown_editor/styles.css +5 -5
- package/framework/components/chui_media/audio.js +240 -246
- package/framework/components/chui_media/audio_styles.css +41 -23
- package/framework/components/chui_media/image.js +49 -46
- package/framework/components/chui_media/image_compare.js +35 -35
- package/framework/components/chui_media/image_compare_styles.css +5 -5
- package/framework/components/chui_media/image_styles.css +1 -1
- package/framework/components/chui_media/video.js +148 -148
- package/framework/components/chui_media/video_styles.css +27 -11
- package/framework/components/chui_menu_bar/menu_bar.js +54 -54
- package/framework/components/chui_menu_bar/styles.css +10 -10
- 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 +37 -13
- package/framework/components/chui_notification/notification.js +76 -54
- package/framework/components/chui_notification/notification_download.js +26 -81
- package/framework/components/chui_notification/notification_download_card.js +115 -0
- package/framework/components/chui_notification/notification_download_progress.css +2 -2
- package/framework/components/chui_notification/notification_download_progress.js +70 -108
- package/framework/components/chui_notification/notification_update.js +31 -31
- package/framework/components/chui_notification/status_plate.css +3 -3
- package/framework/components/chui_notification/styles.css +6 -1
- package/framework/components/chui_notification/styles_download.css +1 -1
- package/framework/components/chui_notification/styles_update.css +2 -2
- package/framework/components/chui_org_chart/org_chart.js +29 -29
- package/framework/components/chui_org_chart/styles.css +2 -2
- package/framework/components/chui_pagination/pagination.js +3 -3
- package/framework/components/chui_pagination/styles.css +1 -1
- package/framework/components/chui_paragraph/styles.css +2 -2
- package/framework/components/chui_popover/popover.js +29 -23
- package/framework/components/chui_popover/styles.css +1 -1
- package/framework/components/chui_popups/popups.js +124 -124
- package/framework/components/chui_popups/styles.css +5 -5
- package/framework/components/chui_print_button/print_button.js +15 -10
- package/framework/components/chui_progress_bar/progress_bar.js +34 -12
- package/framework/components/chui_progress_bar/styles.css +4 -4
- package/framework/components/chui_progress_ring/progress_ring.js +15 -15
- package/framework/components/chui_progress_ring/styles.css +1 -1
- package/framework/components/chui_qrcode/qrcode.js +12 -12
- package/framework/components/chui_query_builder/query_builder.js +46 -46
- package/framework/components/chui_query_builder/styles.css +4 -4
- package/framework/components/chui_radio_group/styles.css +1 -1
- package/framework/components/chui_result/result.js +15 -15
- package/framework/components/chui_result/styles.css +3 -3
- package/framework/components/chui_scheduler/scheduler.js +74 -74
- package/framework/components/chui_scheduler/styles.css +5 -5
- 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 +63 -6
- package/framework/components/chui_segmented_control/styles.css +32 -6
- package/framework/components/chui_settings/settings.js +45 -46
- package/framework/components/chui_settings/styles.css +4 -4
- package/framework/components/chui_shortcut_help/shortcut_help.js +32 -34
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +98 -29
- package/framework/components/chui_sidebar_nav/styles.css +9 -3
- package/framework/components/chui_slideshow/slideshow.js +85 -85
- package/framework/components/chui_slideshow/styles.css +6 -6
- package/framework/components/chui_spinner/spinner.js +10 -10
- package/framework/components/chui_split_button/split_button.js +30 -12
- package/framework/components/chui_split_button/styles.css +21 -5
- package/framework/components/chui_splitter/splitter.js +11 -11
- package/framework/components/chui_splitter/styles.css +2 -2
- package/framework/components/chui_statistic/statistic.js +47 -47
- package/framework/components/chui_status_bar/styles.css +2 -2
- package/framework/components/chui_stepper/stepper.js +202 -31
- package/framework/components/chui_stepper/styles.css +79 -14
- package/framework/components/chui_sticky_bar/sticky_bar.js +44 -13
- package/framework/components/chui_sticky_bar/styles.css +10 -8
- package/framework/components/chui_tabs/chui_tabs.js +74 -26
- package/framework/components/chui_tabs/styles.css +40 -12
- package/framework/components/chui_text_editor/styles.css +7 -7
- package/framework/components/chui_text_editor/text_editor.js +56 -56
- package/framework/components/chui_text_editor/text_editor_panel.js +173 -174
- package/framework/components/chui_theme_toggle/theme_toggle.js +21 -5
- package/framework/components/chui_timeline/styles.css +3 -1
- package/framework/components/chui_toast_queue/styles.css +11 -11
- package/framework/components/chui_toast_queue/toast_queue.js +30 -27
- package/framework/components/chui_toolbar/styles.css +2 -2
- package/framework/components/chui_tooltip/styles.css +2 -2
- package/framework/components/chui_tooltip/tooltip.js +3 -3
- package/framework/components/chui_tour/styles.css +8 -8
- package/framework/components/chui_tour/tour.js +72 -72
- package/framework/components/chui_transfer/styles.css +6 -6
- package/framework/components/chui_transfer/transfer.js +93 -106
- package/framework/components/chui_tree_table/styles.css +4 -4
- package/framework/components/chui_tree_table/tree_table.js +45 -45
- package/framework/components/chui_tree_view/styles.css +10 -8
- package/framework/components/chui_tree_view/tree_view.js +185 -183
- 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 +17 -17
- package/framework/components/chui_webview/webview.js +9 -9
- 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 +78 -79
- package/framework/modules/chui_animations/animations.js +77 -15
- package/framework/modules/chui_animations/motion.js +120 -0
- package/framework/modules/chui_animations/styles.css +36 -3
- package/framework/modules/chui_functions.js +31 -27
- package/framework/modules/chui_highlight/styles.css +13 -10
- package/framework/modules/chui_i18n/chui_i18n.js +3 -3
- package/framework/modules/chui_i18n/locales/feedback.js +62 -0
- package/framework/modules/chui_i18n/locales/navigation.js +4 -0
- package/framework/modules/chui_json/chui_json.js +2 -2
- package/framework/modules/chui_logger/chui_logger.js +23 -8
- package/framework/modules/chui_page/page.js +10 -10
- package/framework/modules/chui_palette/palette.js +61 -0
- package/framework/modules/chui_qr/chui_qr.js +23 -23
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +45 -45
- package/framework/modules/chui_scrollbar/styles.css +3 -3
- package/framework/modules/chui_services/chui_services.js +8 -8
- package/framework/modules/chui_services/desktop.js +77 -71
- package/framework/modules/chui_sortable/chui_sortable.js +17 -17
- package/framework/modules/chui_validate/chui_validate.js +3 -3
- package/framework/tray_bar/chui_menu_items.js +2 -2
- package/index.d.ts +266 -34
- package/index.js +20 -1168
- package/package.json +6 -4
- package/framework/components/telegram_bot/chui_telegram_bot.js +0 -191
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { SERVICES_CHANNELS, SERVICES_CALLS, SERVICES_SYNC_CALLS, APP_PATH_NAMES } = require("./chui_channels");
|
|
2
|
+
const { crossFade } = require("../chui_animations/motion");
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Десктоп-сервисы со стороны страницы: буфер обмена, последние документы, прогресс на иконке
|
|
@@ -86,12 +87,16 @@ class Desktop {
|
|
|
86
87
|
off: (accelerator = String(), handler = () => {}) => Desktop.#unsubscribe(accelerator, handler),
|
|
87
88
|
offAll: () => Desktop.#unsubscribeAll(),
|
|
88
89
|
/** Комбинации, на которые подписано это окно */
|
|
89
|
-
get: () => [...Desktop.#
|
|
90
|
+
get: () => [...Desktop.#shortcutHandlers.keys()],
|
|
90
91
|
};
|
|
91
92
|
|
|
92
93
|
/**
|
|
93
94
|
* Тема приложения. Палитры в стилях разложены по `prefers-color-scheme`, поэтому смена
|
|
94
|
-
* источника меняет цвета без правок в DOM
|
|
95
|
+
* источника меняет цвета без правок в DOM: Chromium сам сообщает странице новое значение
|
|
96
|
+
* запроса. Смена идёт кроссфейдом (`crossFade` в `chui_animations/motion`) — обычный
|
|
97
|
+
* CSS-переход на изменение из запроса браузер не запускает, и без него тема переключалась бы
|
|
98
|
+
* кадром. Смену системной схемы при источнике «system» так показать нельзя: её присылает
|
|
99
|
+
* сама система, и снимка «до» в этот момент уже нет.
|
|
95
100
|
*
|
|
96
101
|
* ```javascript
|
|
97
102
|
* await Desktop.theme.set(Desktop.theme.SOURCE.DARK); // 'dark' | 'light' | 'system'
|
|
@@ -102,9 +107,10 @@ class Desktop {
|
|
|
102
107
|
SOURCE: { SYSTEM: "system", LIGHT: "light", DARK: "dark" },
|
|
103
108
|
/** @returns {Promise<{theme: string, source: string}>} фактическая тема и выбранный источник */
|
|
104
109
|
get: () => Desktop.#call("themeGet"),
|
|
105
|
-
set: (source = String()) =>
|
|
110
|
+
set: (source = String()) =>
|
|
111
|
+
crossFade(() => Desktop.#call("themeSet", String(source)), { waitFor: "(prefers-color-scheme: dark)" }),
|
|
106
112
|
/** Переключить светлую и тёмную */
|
|
107
|
-
toggle: () => Desktop.#call("themeToggle"),
|
|
113
|
+
toggle: () => crossFade(() => Desktop.#call("themeToggle"), { waitFor: "(prefers-color-scheme: dark)" }),
|
|
108
114
|
/** Подписка на смену темы; возвращает функцию отписки */
|
|
109
115
|
onChange: (listener = () => {}) => Desktop.#subscribeTheme(listener),
|
|
110
116
|
};
|
|
@@ -227,21 +233,21 @@ class Desktop {
|
|
|
227
233
|
};
|
|
228
234
|
|
|
229
235
|
// accelerator → набор обработчиков этого окна
|
|
230
|
-
static #
|
|
231
|
-
static #
|
|
232
|
-
static #
|
|
233
|
-
static #
|
|
234
|
-
static #
|
|
235
|
-
static #
|
|
236
|
-
static #
|
|
237
|
-
static #
|
|
238
|
-
static #
|
|
239
|
-
static #
|
|
240
|
-
static #
|
|
241
|
-
static #
|
|
236
|
+
static #shortcutHandlers = new Map();
|
|
237
|
+
static #shortcutEventBound = false;
|
|
238
|
+
static #shortcutBridgeUnsubscribe = undefined;
|
|
239
|
+
static #themeHandlers = new Set();
|
|
240
|
+
static #themeEventBound = false;
|
|
241
|
+
static #themeBridgeUnsubscribe = undefined;
|
|
242
|
+
static #localeHandlers = new Set();
|
|
243
|
+
static #localeEventBound = false;
|
|
244
|
+
static #localeBridgeUnsubscribe = undefined;
|
|
245
|
+
static #historyHandlers = new Set();
|
|
246
|
+
static #historyEventBound = false;
|
|
247
|
+
static #historyBridgeUnsubscribe = undefined;
|
|
242
248
|
// Пути приложения, уже полученные значением: `sendSync` останавливает страницу на время
|
|
243
249
|
// ответа, поэтому за одним и тем же именем в main ходят один раз
|
|
244
|
-
static #
|
|
250
|
+
static #appPaths = new Map();
|
|
245
251
|
|
|
246
252
|
static #bridge() {
|
|
247
253
|
if (typeof window === "undefined" || window.chui === undefined) return undefined;
|
|
@@ -281,9 +287,9 @@ class Desktop {
|
|
|
281
287
|
* страницы одним и тем же вызовом.
|
|
282
288
|
*/
|
|
283
289
|
static #appPath(name = String()) {
|
|
284
|
-
if (Desktop.#
|
|
290
|
+
if (Desktop.#appPaths.has(name)) return Desktop.#appPaths.get(name);
|
|
285
291
|
const value = Desktop.#inMainProcess() ? Desktop.#appPathInMain(name) : Desktop.#callSync("appPathSync", name);
|
|
286
|
-
Desktop.#
|
|
292
|
+
Desktop.#appPaths.set(name, value);
|
|
287
293
|
return value;
|
|
288
294
|
}
|
|
289
295
|
|
|
@@ -317,31 +323,31 @@ class Desktop {
|
|
|
317
323
|
}
|
|
318
324
|
|
|
319
325
|
static #subscribe(accelerator = String(), handler = () => {}) {
|
|
320
|
-
const handlers = Desktop.#
|
|
326
|
+
const handlers = Desktop.#shortcutHandlers.get(accelerator) ?? new Set();
|
|
321
327
|
const first = handlers.size === 0;
|
|
322
328
|
handlers.add(handler);
|
|
323
|
-
Desktop.#
|
|
324
|
-
if (!Desktop.#
|
|
329
|
+
Desktop.#shortcutHandlers.set(accelerator, handlers);
|
|
330
|
+
if (!Desktop.#shortcutEventBound) Desktop.#bindShortcutEvent();
|
|
325
331
|
// В main клавиша регистрируется один раз на все окна, поэтому подписка — на первую
|
|
326
332
|
if (first) Desktop.#call("shortcutSubscribe", accelerator);
|
|
327
333
|
return () => Desktop.#unsubscribe(accelerator, handler);
|
|
328
334
|
}
|
|
329
335
|
|
|
330
336
|
static #unsubscribe(accelerator = String(), handler = () => {}) {
|
|
331
|
-
const handlers = Desktop.#
|
|
337
|
+
const handlers = Desktop.#shortcutHandlers.get(accelerator);
|
|
332
338
|
if (handlers === undefined) return Desktop;
|
|
333
339
|
handlers.delete(handler);
|
|
334
340
|
if (handlers.size === 0) {
|
|
335
|
-
Desktop.#
|
|
341
|
+
Desktop.#shortcutHandlers.delete(accelerator);
|
|
336
342
|
Desktop.#call("shortcutUnsubscribe", accelerator);
|
|
337
343
|
}
|
|
338
|
-
if (Desktop.#
|
|
344
|
+
if (Desktop.#shortcutHandlers.size === 0) Desktop.#unbindShortcutEvent();
|
|
339
345
|
return Desktop;
|
|
340
346
|
}
|
|
341
347
|
|
|
342
348
|
static #unsubscribeAll() {
|
|
343
|
-
for (const accelerator of [...Desktop.#
|
|
344
|
-
Desktop.#
|
|
349
|
+
for (const accelerator of [...Desktop.#shortcutHandlers.keys()]) {
|
|
350
|
+
Desktop.#shortcutHandlers.delete(accelerator);
|
|
345
351
|
Desktop.#call("shortcutUnsubscribe", accelerator);
|
|
346
352
|
}
|
|
347
353
|
Desktop.#unbindShortcutEvent();
|
|
@@ -350,16 +356,16 @@ class Desktop {
|
|
|
350
356
|
|
|
351
357
|
/** Событие приходит из main: сработала глобальная клавиша */
|
|
352
358
|
static #onShortcutEvent = (accelerator = String()) => {
|
|
353
|
-
const handlers = Desktop.#
|
|
359
|
+
const handlers = Desktop.#shortcutHandlers.get(accelerator);
|
|
354
360
|
if (handlers === undefined) return;
|
|
355
361
|
for (const handler of [...handlers]) handler(accelerator);
|
|
356
362
|
};
|
|
357
363
|
|
|
358
364
|
static #bindShortcutEvent() {
|
|
359
|
-
Desktop.#
|
|
365
|
+
Desktop.#shortcutEventBound = true;
|
|
360
366
|
const services = Desktop.#bridge();
|
|
361
367
|
if (services !== undefined && typeof services.onShortcut === "function") {
|
|
362
|
-
Desktop.#
|
|
368
|
+
Desktop.#shortcutBridgeUnsubscribe = services.onShortcut(Desktop.#onShortcutEvent);
|
|
363
369
|
return;
|
|
364
370
|
}
|
|
365
371
|
const { ipcRenderer } = require("electron");
|
|
@@ -367,11 +373,11 @@ class Desktop {
|
|
|
367
373
|
}
|
|
368
374
|
|
|
369
375
|
static #unbindShortcutEvent() {
|
|
370
|
-
if (!Desktop.#
|
|
371
|
-
Desktop.#
|
|
372
|
-
if (Desktop.#
|
|
373
|
-
Desktop.#
|
|
374
|
-
Desktop.#
|
|
376
|
+
if (!Desktop.#shortcutEventBound) return;
|
|
377
|
+
Desktop.#shortcutEventBound = false;
|
|
378
|
+
if (Desktop.#shortcutBridgeUnsubscribe !== undefined) {
|
|
379
|
+
Desktop.#shortcutBridgeUnsubscribe();
|
|
380
|
+
Desktop.#shortcutBridgeUnsubscribe = undefined;
|
|
375
381
|
return;
|
|
376
382
|
}
|
|
377
383
|
const { ipcRenderer } = require("electron");
|
|
@@ -383,28 +389,28 @@ class Desktop {
|
|
|
383
389
|
};
|
|
384
390
|
|
|
385
391
|
static #subscribeTheme(listener = () => {}) {
|
|
386
|
-
Desktop.#
|
|
387
|
-
if (!Desktop.#
|
|
392
|
+
Desktop.#themeHandlers.add(listener);
|
|
393
|
+
if (!Desktop.#themeEventBound) Desktop.#bindThemeEvent();
|
|
388
394
|
return () => Desktop.#unsubscribeTheme(listener);
|
|
389
395
|
}
|
|
390
396
|
|
|
391
397
|
static #unsubscribeTheme(listener = () => {}) {
|
|
392
|
-
Desktop.#
|
|
393
|
-
if (Desktop.#
|
|
398
|
+
Desktop.#themeHandlers.delete(listener);
|
|
399
|
+
if (Desktop.#themeHandlers.size === 0) Desktop.#unbindThemeEvent();
|
|
394
400
|
return Desktop;
|
|
395
401
|
}
|
|
396
402
|
|
|
397
403
|
/** Событие приходит из main: тема изменилась (системой или по выбору пользователя) */
|
|
398
404
|
static #onThemeEvent = (theme = String()) => {
|
|
399
|
-
for (const listener of [...Desktop.#
|
|
405
|
+
for (const listener of [...Desktop.#themeHandlers]) listener(theme);
|
|
400
406
|
};
|
|
401
407
|
|
|
402
408
|
static #bindThemeEvent() {
|
|
403
|
-
Desktop.#
|
|
409
|
+
Desktop.#themeEventBound = true;
|
|
404
410
|
const bridge = typeof window === "undefined" ? undefined : window.chui;
|
|
405
411
|
const theme = bridge === undefined ? undefined : bridge.theme;
|
|
406
412
|
if (theme !== undefined && typeof theme.onChange === "function") {
|
|
407
|
-
Desktop.#
|
|
413
|
+
Desktop.#themeBridgeUnsubscribe = theme.onChange(Desktop.#onThemeEvent);
|
|
408
414
|
return;
|
|
409
415
|
}
|
|
410
416
|
const { ipcRenderer } = require("electron");
|
|
@@ -412,11 +418,11 @@ class Desktop {
|
|
|
412
418
|
}
|
|
413
419
|
|
|
414
420
|
static #unbindThemeEvent() {
|
|
415
|
-
if (!Desktop.#
|
|
416
|
-
Desktop.#
|
|
417
|
-
if (Desktop.#
|
|
418
|
-
Desktop.#
|
|
419
|
-
Desktop.#
|
|
421
|
+
if (!Desktop.#themeEventBound) return;
|
|
422
|
+
Desktop.#themeEventBound = false;
|
|
423
|
+
if (Desktop.#themeBridgeUnsubscribe !== undefined) {
|
|
424
|
+
Desktop.#themeBridgeUnsubscribe();
|
|
425
|
+
Desktop.#themeBridgeUnsubscribe = undefined;
|
|
420
426
|
return;
|
|
421
427
|
}
|
|
422
428
|
const { ipcRenderer } = require("electron");
|
|
@@ -428,28 +434,28 @@ class Desktop {
|
|
|
428
434
|
};
|
|
429
435
|
|
|
430
436
|
static #subscribeLocale(listener = () => {}) {
|
|
431
|
-
Desktop.#
|
|
432
|
-
if (!Desktop.#
|
|
437
|
+
Desktop.#localeHandlers.add(listener);
|
|
438
|
+
if (!Desktop.#localeEventBound) Desktop.#bindLocaleEvent();
|
|
433
439
|
return () => Desktop.#unsubscribeLocale(listener);
|
|
434
440
|
}
|
|
435
441
|
|
|
436
442
|
static #unsubscribeLocale(listener = () => {}) {
|
|
437
|
-
Desktop.#
|
|
438
|
-
if (Desktop.#
|
|
443
|
+
Desktop.#localeHandlers.delete(listener);
|
|
444
|
+
if (Desktop.#localeHandlers.size === 0) Desktop.#unbindLocaleEvent();
|
|
439
445
|
return Desktop;
|
|
440
446
|
}
|
|
441
447
|
|
|
442
448
|
/** Событие приходит из main: приложение сменило язык */
|
|
443
449
|
static #onLocaleEvent = (locale = String()) => {
|
|
444
|
-
for (const listener of [...Desktop.#
|
|
450
|
+
for (const listener of [...Desktop.#localeHandlers]) listener(locale);
|
|
445
451
|
};
|
|
446
452
|
|
|
447
453
|
static #bindLocaleEvent() {
|
|
448
|
-
Desktop.#
|
|
454
|
+
Desktop.#localeEventBound = true;
|
|
449
455
|
const bridge = typeof window === "undefined" ? undefined : window.chui;
|
|
450
456
|
const locale = bridge === undefined ? undefined : bridge.locale;
|
|
451
457
|
if (locale !== undefined && typeof locale.onChange === "function") {
|
|
452
|
-
Desktop.#
|
|
458
|
+
Desktop.#localeBridgeUnsubscribe = locale.onChange(Desktop.#onLocaleEvent);
|
|
453
459
|
return;
|
|
454
460
|
}
|
|
455
461
|
const { ipcRenderer } = require("electron");
|
|
@@ -457,11 +463,11 @@ class Desktop {
|
|
|
457
463
|
}
|
|
458
464
|
|
|
459
465
|
static #unbindLocaleEvent() {
|
|
460
|
-
if (!Desktop.#
|
|
461
|
-
Desktop.#
|
|
462
|
-
if (Desktop.#
|
|
463
|
-
Desktop.#
|
|
464
|
-
Desktop.#
|
|
466
|
+
if (!Desktop.#localeEventBound) return;
|
|
467
|
+
Desktop.#localeEventBound = false;
|
|
468
|
+
if (Desktop.#localeBridgeUnsubscribe !== undefined) {
|
|
469
|
+
Desktop.#localeBridgeUnsubscribe();
|
|
470
|
+
Desktop.#localeBridgeUnsubscribe = undefined;
|
|
465
471
|
return;
|
|
466
472
|
}
|
|
467
473
|
const { ipcRenderer } = require("electron");
|
|
@@ -473,26 +479,26 @@ class Desktop {
|
|
|
473
479
|
};
|
|
474
480
|
|
|
475
481
|
static #subscribeHistory(listener = () => {}) {
|
|
476
|
-
Desktop.#
|
|
477
|
-
if (!Desktop.#
|
|
482
|
+
Desktop.#historyHandlers.add(listener);
|
|
483
|
+
if (!Desktop.#historyEventBound) Desktop.#bindHistoryEvent();
|
|
478
484
|
return () => Desktop.#unsubscribeHistory(listener);
|
|
479
485
|
}
|
|
480
486
|
|
|
481
487
|
static #unsubscribeHistory(listener = () => {}) {
|
|
482
|
-
Desktop.#
|
|
483
|
-
if (Desktop.#
|
|
488
|
+
Desktop.#historyHandlers.delete(listener);
|
|
489
|
+
if (Desktop.#historyHandlers.size === 0) Desktop.#unbindHistoryEvent();
|
|
484
490
|
return Desktop;
|
|
485
491
|
}
|
|
486
492
|
|
|
487
493
|
static #onHistoryEvent = (items = []) => {
|
|
488
|
-
for (const listener of [...Desktop.#
|
|
494
|
+
for (const listener of [...Desktop.#historyHandlers]) listener(items);
|
|
489
495
|
};
|
|
490
496
|
|
|
491
497
|
static #bindHistoryEvent() {
|
|
492
|
-
Desktop.#
|
|
498
|
+
Desktop.#historyEventBound = true;
|
|
493
499
|
const services = Desktop.#bridge();
|
|
494
500
|
if (services !== undefined && typeof services.onClipboardHistory === "function") {
|
|
495
|
-
Desktop.#
|
|
501
|
+
Desktop.#historyBridgeUnsubscribe = services.onClipboardHistory(Desktop.#onHistoryEvent);
|
|
496
502
|
return;
|
|
497
503
|
}
|
|
498
504
|
const { ipcRenderer } = require("electron");
|
|
@@ -500,11 +506,11 @@ class Desktop {
|
|
|
500
506
|
}
|
|
501
507
|
|
|
502
508
|
static #unbindHistoryEvent() {
|
|
503
|
-
if (!Desktop.#
|
|
504
|
-
Desktop.#
|
|
505
|
-
if (Desktop.#
|
|
506
|
-
Desktop.#
|
|
507
|
-
Desktop.#
|
|
509
|
+
if (!Desktop.#historyEventBound) return;
|
|
510
|
+
Desktop.#historyEventBound = false;
|
|
511
|
+
if (Desktop.#historyBridgeUnsubscribe !== undefined) {
|
|
512
|
+
Desktop.#historyBridgeUnsubscribe();
|
|
513
|
+
Desktop.#historyBridgeUnsubscribe = undefined;
|
|
508
514
|
return;
|
|
509
515
|
}
|
|
510
516
|
const { ipcRenderer } = require("electron");
|
|
@@ -31,14 +31,14 @@ class Sortable {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
#container = undefined;
|
|
34
|
-
#
|
|
35
|
-
#
|
|
34
|
+
#itemSelector = undefined;
|
|
35
|
+
#handleSelector = undefined;
|
|
36
36
|
#axis = Sortable.AXIS.Y;
|
|
37
|
-
#
|
|
37
|
+
#onReorder = undefined;
|
|
38
38
|
#enabled = true;
|
|
39
39
|
#source = undefined;
|
|
40
40
|
#before = undefined;
|
|
41
|
-
#
|
|
41
|
+
#orderBefore = [];
|
|
42
42
|
// Точка отсчёта отмены: сюда возвращает cancel(), и только здесь, а не в каждой перестановке
|
|
43
43
|
#baseline = [];
|
|
44
44
|
#bound = false;
|
|
@@ -55,10 +55,10 @@ class Sortable {
|
|
|
55
55
|
) {
|
|
56
56
|
setStyles(__dirname + "/styles.css", "chUiJS_Sortable");
|
|
57
57
|
this.#container = container;
|
|
58
|
-
this.#
|
|
59
|
-
this.#
|
|
58
|
+
this.#itemSelector = options.itemSelector === undefined ? "*" : options.itemSelector;
|
|
59
|
+
this.#handleSelector = options.handleSelector;
|
|
60
60
|
this.#axis = options.axis === undefined ? Sortable.AXIS.Y : options.axis;
|
|
61
|
-
this.#
|
|
61
|
+
this.#onReorder = options.onReorder;
|
|
62
62
|
this.#enabled = options.enabled !== false;
|
|
63
63
|
this.#container.addEventListener("dragstart", this.#onDragStart);
|
|
64
64
|
this.#container.addEventListener("dragover", this.#onDragOver);
|
|
@@ -89,7 +89,7 @@ class Sortable {
|
|
|
89
89
|
|
|
90
90
|
/** Порядок изменился после последней перестановки (или с момента refresh) */
|
|
91
91
|
isChanged() {
|
|
92
|
-
return !Sortable.#sameOrder(this.#
|
|
92
|
+
return !Sortable.#sameOrder(this.#orderBefore, this.#items());
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
// SET
|
|
@@ -108,8 +108,8 @@ class Sortable {
|
|
|
108
108
|
if (item.getAttribute("tabindex") === null) item.setAttribute("tabindex", "0");
|
|
109
109
|
item.classList.add("sortable_item");
|
|
110
110
|
}
|
|
111
|
-
this.#
|
|
112
|
-
this.#baseline = [...this.#
|
|
111
|
+
this.#orderBefore = this.#items();
|
|
112
|
+
this.#baseline = [...this.#orderBefore];
|
|
113
113
|
return this;
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -118,7 +118,7 @@ class Sortable {
|
|
|
118
118
|
// Возврат идёт к точке отсчёта refresh(), а не к порядку последней перестановки: иначе
|
|
119
119
|
// отмена после перетаскивания ничего бы не делала (порядок сверялся бы сам с собой)
|
|
120
120
|
for (const item of this.#baseline) this.#container.appendChild(item);
|
|
121
|
-
this.#
|
|
121
|
+
this.#orderBefore = this.#items();
|
|
122
122
|
return this;
|
|
123
123
|
}
|
|
124
124
|
|
|
@@ -140,15 +140,15 @@ class Sortable {
|
|
|
140
140
|
// === ВНУТРЕННЕЕ ===
|
|
141
141
|
// Только прямые дети контейнера: вложенные списки сортируются своим Sortable
|
|
142
142
|
#items() {
|
|
143
|
-
return [...this.#container.children].filter((child) => child.matches(this.#
|
|
143
|
+
return [...this.#container.children].filter((child) => child.matches(this.#itemSelector));
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
#itemFromEvent(event) {
|
|
147
147
|
const target = event.target instanceof Element ? event.target : null;
|
|
148
148
|
if (target === null) return null;
|
|
149
|
-
const item = target.closest(this.#
|
|
149
|
+
const item = target.closest(this.#itemSelector);
|
|
150
150
|
if (item === null || item.parentElement !== this.#container) return null;
|
|
151
|
-
if (this.#
|
|
151
|
+
if (this.#handleSelector !== undefined && target.closest(this.#handleSelector) === null) return null;
|
|
152
152
|
return item;
|
|
153
153
|
}
|
|
154
154
|
|
|
@@ -173,9 +173,9 @@ class Sortable {
|
|
|
173
173
|
const before = this.#before;
|
|
174
174
|
this.#source = undefined;
|
|
175
175
|
this.#before = undefined;
|
|
176
|
-
if (Sortable.#sameOrder(this.#
|
|
177
|
-
this.#
|
|
178
|
-
if (this.#
|
|
176
|
+
if (Sortable.#sameOrder(this.#orderBefore, this.#items())) return;
|
|
177
|
+
this.#orderBefore = this.#items();
|
|
178
|
+
if (this.#onReorder !== undefined) this.#onReorder(this.getOrder(), { source: source, before: before });
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
static #sameOrder(left = [], right = []) {
|
|
@@ -76,9 +76,9 @@ function check(value, rules = {}) {
|
|
|
76
76
|
if (rules.max !== undefined && (Number.isNaN(number) || number > rules.max)) return fail("max", rules);
|
|
77
77
|
if (rules.minLength !== undefined && text.length < rules.minLength) return fail("minLength", rules);
|
|
78
78
|
if (rules.maxLength !== undefined && text.length > rules.maxLength) return fail("maxLength", rules);
|
|
79
|
-
const
|
|
80
|
-
const pattern =
|
|
81
|
-
if (pattern !== undefined && !new RegExp(pattern).test(text)) return fail(
|
|
79
|
+
const isEmail = rules.type === "email";
|
|
80
|
+
const pattern = isEmail ? EMAIL_PATTERN : rules.pattern;
|
|
81
|
+
if (pattern !== undefined && !new RegExp(pattern).test(text)) return fail(isEmail ? "email" : "pattern", rules);
|
|
82
82
|
if (typeof rules.validate === "function") {
|
|
83
83
|
const custom = rules.validate(value);
|
|
84
84
|
if (custom !== undefined && custom !== null && custom !== true) {
|
|
@@ -5,8 +5,8 @@ class MenuItem {
|
|
|
5
5
|
separator() {
|
|
6
6
|
return { type: "separator" };
|
|
7
7
|
}
|
|
8
|
-
submenu(title = String(),
|
|
9
|
-
return { label: title, submenu:
|
|
8
|
+
submenu(title = String(), submenuList = Array()) {
|
|
9
|
+
return { label: title, submenu: submenuList };
|
|
10
10
|
}
|
|
11
11
|
radio(title = String(), checked = Boolean(), action = () => {}) {
|
|
12
12
|
return { label: title, type: "radio", checked: checked, click: action };
|