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,14 +14,14 @@
|
|
|
14
14
|
* (popup_button_ok и подобным) tabindex выставляет вызывающий компонент.
|
|
15
15
|
*/
|
|
16
16
|
const FOCUSABLE_SELECTOR = [
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
"a[href]",
|
|
18
|
+
"button:not([disabled])",
|
|
19
|
+
"input:not([disabled])",
|
|
20
|
+
"select:not([disabled])",
|
|
21
|
+
"textarea:not([disabled])",
|
|
22
22
|
'[contenteditable="true"]',
|
|
23
23
|
'[tabindex]:not([tabindex="-1"])',
|
|
24
|
-
].join(
|
|
24
|
+
].join(", ");
|
|
25
25
|
|
|
26
26
|
class OverlayA11y {
|
|
27
27
|
// Стек открытых слоёв: нужен, чтобы вложенный слой не снимал фон-инерт у родителя
|
|
@@ -37,10 +37,16 @@ class OverlayA11y {
|
|
|
37
37
|
#previous_focus = undefined;
|
|
38
38
|
#is_open = false;
|
|
39
39
|
|
|
40
|
-
constructor(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
constructor(
|
|
41
|
+
element,
|
|
42
|
+
options = {
|
|
43
|
+
role: String(),
|
|
44
|
+
label: String(),
|
|
45
|
+
labelNode: undefined,
|
|
46
|
+
describedBy: undefined,
|
|
47
|
+
onEscape: undefined,
|
|
48
|
+
}
|
|
49
|
+
) {
|
|
44
50
|
this.#element = element;
|
|
45
51
|
if (options.role !== undefined) this.#role = options.role;
|
|
46
52
|
this.#label = options.label;
|
|
@@ -125,8 +131,9 @@ class OverlayA11y {
|
|
|
125
131
|
}
|
|
126
132
|
|
|
127
133
|
#focusables() {
|
|
128
|
-
return [...this.#element.querySelectorAll(FOCUSABLE_SELECTOR)]
|
|
129
|
-
|
|
134
|
+
return [...this.#element.querySelectorAll(FOCUSABLE_SELECTOR)].filter(
|
|
135
|
+
(element) => element.offsetWidth > 0 || element.offsetHeight > 0 || element === document.activeElement
|
|
136
|
+
);
|
|
130
137
|
}
|
|
131
138
|
|
|
132
139
|
#focusFirst() {
|
|
@@ -175,7 +182,7 @@ class OverlayA11y {
|
|
|
175
182
|
return;
|
|
176
183
|
}
|
|
177
184
|
if (event.key === "Tab") this.#trapFocus(event);
|
|
178
|
-
}
|
|
185
|
+
};
|
|
179
186
|
}
|
|
180
187
|
|
|
181
188
|
/**
|
|
@@ -194,16 +201,22 @@ function makeKeyboardButton(element, role = "button") {
|
|
|
194
201
|
return element;
|
|
195
202
|
}
|
|
196
203
|
|
|
197
|
-
exports.OverlayA11y = OverlayA11y
|
|
198
|
-
exports.makeKeyboardButton = makeKeyboardButton
|
|
199
|
-
exports.A11Y_FOCUSABLE_SELECTOR = FOCUSABLE_SELECTOR
|
|
204
|
+
exports.OverlayA11y = OverlayA11y;
|
|
205
|
+
exports.makeKeyboardButton = makeKeyboardButton;
|
|
206
|
+
exports.A11Y_FOCUSABLE_SELECTOR = FOCUSABLE_SELECTOR;
|
|
200
207
|
|
|
201
208
|
// Подсветка активного пункта меню/опции, когда фокус остаётся на поле ввода
|
|
202
209
|
const ACTIVE_CLASS = "chui_a11y_active";
|
|
203
210
|
|
|
204
|
-
const isVisible = (element) =>
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
const isVisible = (element) =>
|
|
212
|
+
element.offsetWidth > 0 || element.offsetHeight > 0 || element === document.activeElement;
|
|
213
|
+
const isDisabled = (element) =>
|
|
214
|
+
element.disabled === true ||
|
|
215
|
+
element.getAttribute("aria-disabled") === "true" ||
|
|
216
|
+
(element.className !== undefined &&
|
|
217
|
+
String(element.className)
|
|
218
|
+
.split(" ")
|
|
219
|
+
.some((name) => name.endsWith("_disabled")));
|
|
207
220
|
|
|
208
221
|
/**
|
|
209
222
|
* Клавиатура для всплывающих меню (ContextMenu, MenuBar, меню шапки).
|
|
@@ -225,10 +238,17 @@ class MenuKeyboard {
|
|
|
225
238
|
#trigger = undefined;
|
|
226
239
|
#trigger_bound = false;
|
|
227
240
|
|
|
228
|
-
constructor(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
241
|
+
constructor(
|
|
242
|
+
container,
|
|
243
|
+
options = {
|
|
244
|
+
role: String(),
|
|
245
|
+
itemRole: String(),
|
|
246
|
+
itemSelector: String(),
|
|
247
|
+
submenuSelector: String(),
|
|
248
|
+
onEscape: undefined,
|
|
249
|
+
trigger: undefined,
|
|
250
|
+
}
|
|
251
|
+
) {
|
|
232
252
|
this.#container = container;
|
|
233
253
|
if (options.role !== undefined) this.#role = options.role;
|
|
234
254
|
if (options.itemRole !== undefined) this.#item_role = options.itemRole;
|
|
@@ -276,8 +296,9 @@ class MenuKeyboard {
|
|
|
276
296
|
|
|
277
297
|
// Все пункты своего уровня (и скрытые — им тоже нужны роли и tabindex)
|
|
278
298
|
#allItems() {
|
|
279
|
-
return [...this.#container.querySelectorAll(this.#item_selector)]
|
|
280
|
-
|
|
299
|
+
return [...this.#container.querySelectorAll(this.#item_selector)].filter(
|
|
300
|
+
(item) => item.closest('[role="menu"]') === this.#container
|
|
301
|
+
);
|
|
281
302
|
}
|
|
282
303
|
|
|
283
304
|
#focusItem(index) {
|
|
@@ -290,7 +311,7 @@ class MenuKeyboard {
|
|
|
290
311
|
}
|
|
291
312
|
|
|
292
313
|
#activeIndex(items) {
|
|
293
|
-
return items.findIndex(item => item === document.activeElement || item.classList.contains(ACTIVE_CLASS));
|
|
314
|
+
return items.findIndex((item) => item === document.activeElement || item.classList.contains(ACTIVE_CLASS));
|
|
294
315
|
}
|
|
295
316
|
|
|
296
317
|
// Для навигации — только видимые пункты своего уровня
|
|
@@ -382,7 +403,7 @@ class MenuKeyboard {
|
|
|
382
403
|
}
|
|
383
404
|
break;
|
|
384
405
|
}
|
|
385
|
-
}
|
|
406
|
+
};
|
|
386
407
|
|
|
387
408
|
#typeahead(char) {
|
|
388
409
|
const now = Date.now();
|
|
@@ -394,7 +415,7 @@ class MenuKeyboard {
|
|
|
394
415
|
const current = this.#activeIndex(items);
|
|
395
416
|
// Ищем по кругу, начиная со следующего пункта
|
|
396
417
|
const ordered = current === -1 ? items : [...items.slice(current + 1), ...items.slice(0, current + 1)];
|
|
397
|
-
const match = ordered.find(item => this.#label(item).startsWith(this.#type_buffer));
|
|
418
|
+
const match = ordered.find((item) => this.#label(item).startsWith(this.#type_buffer));
|
|
398
419
|
if (match !== undefined) this.#focusItem(items.indexOf(match));
|
|
399
420
|
}
|
|
400
421
|
|
|
@@ -412,7 +433,8 @@ class MenuKeyboard {
|
|
|
412
433
|
|
|
413
434
|
destroy() {
|
|
414
435
|
this.#container.removeEventListener("keydown", this.#keydownEvent);
|
|
415
|
-
if (this.#trigger !== undefined && this.#trigger_bound)
|
|
436
|
+
if (this.#trigger !== undefined && this.#trigger_bound)
|
|
437
|
+
this.#trigger.removeEventListener("keydown", this.#keydownEvent);
|
|
416
438
|
}
|
|
417
439
|
}
|
|
418
440
|
|
|
@@ -430,9 +452,16 @@ class ComboboxKeyboard {
|
|
|
430
452
|
#active = undefined;
|
|
431
453
|
#selection_state = undefined;
|
|
432
454
|
|
|
433
|
-
constructor(
|
|
434
|
-
|
|
435
|
-
|
|
455
|
+
constructor(
|
|
456
|
+
input,
|
|
457
|
+
options = {
|
|
458
|
+
dropdown: undefined,
|
|
459
|
+
optionSelector: String(),
|
|
460
|
+
onEscape: undefined,
|
|
461
|
+
onOpen: undefined,
|
|
462
|
+
selectionState: undefined,
|
|
463
|
+
}
|
|
464
|
+
) {
|
|
436
465
|
this.#input = input;
|
|
437
466
|
this.#dropdown = options.dropdown;
|
|
438
467
|
this.#option_selector = options.optionSelector;
|
|
@@ -455,7 +484,8 @@ class ComboboxKeyboard {
|
|
|
455
484
|
// Роли и id нужны всем опциям, даже когда дропдаун ещё закрыт
|
|
456
485
|
for (const option of this.#allOptions()) {
|
|
457
486
|
if (option.getAttribute("role") === null) option.setAttribute("role", "option");
|
|
458
|
-
if (option.id === undefined || option.id === "")
|
|
487
|
+
if (option.id === undefined || option.id === "")
|
|
488
|
+
option.id = "chui_a11y_option_" + Math.random().toString(36).slice(2, 9);
|
|
459
489
|
}
|
|
460
490
|
this.#applyActive();
|
|
461
491
|
}
|
|
@@ -477,7 +507,7 @@ class ComboboxKeyboard {
|
|
|
477
507
|
}
|
|
478
508
|
|
|
479
509
|
#options() {
|
|
480
|
-
return this.#allOptions().filter(option => isVisible(option) && !isDisabled(option));
|
|
510
|
+
return this.#allOptions().filter((option) => isVisible(option) && !isDisabled(option));
|
|
481
511
|
}
|
|
482
512
|
|
|
483
513
|
#applyActive() {
|
|
@@ -511,7 +541,8 @@ class ComboboxKeyboard {
|
|
|
511
541
|
case "ArrowDown":
|
|
512
542
|
case "ArrowUp": {
|
|
513
543
|
event.preventDefault();
|
|
514
|
-
if (this.#input.getAttribute("aria-expanded") !== "true" && this.#on_open !== undefined)
|
|
544
|
+
if (this.#input.getAttribute("aria-expanded") !== "true" && this.#on_open !== undefined)
|
|
545
|
+
this.#on_open();
|
|
515
546
|
this.#move(event.key === "ArrowDown" ? 1 : -1);
|
|
516
547
|
break;
|
|
517
548
|
}
|
|
@@ -547,7 +578,7 @@ class ComboboxKeyboard {
|
|
|
547
578
|
default:
|
|
548
579
|
break;
|
|
549
580
|
}
|
|
550
|
-
}
|
|
581
|
+
};
|
|
551
582
|
|
|
552
583
|
destroy() {
|
|
553
584
|
this.#input.removeEventListener("keydown", this.#keydownEvent);
|
|
@@ -582,7 +613,7 @@ class RovingKeyboard {
|
|
|
582
613
|
/** Перечитать пункты: остановка остаётся на прежнем, если он ещё доступен */
|
|
583
614
|
refresh() {
|
|
584
615
|
const visible = this.#items();
|
|
585
|
-
const current = visible.find(item => item.getAttribute("tabindex") === "0");
|
|
616
|
+
const current = visible.find((item) => item.getAttribute("tabindex") === "0");
|
|
586
617
|
// Панель может быть ещё не в документе (размеры нулевые) — тогда остановку получает
|
|
587
618
|
// первый пункт: без неё группа целиком выпала бы из обхода Tab
|
|
588
619
|
const fallback = visible[0] === undefined ? this.#allItems()[0] : visible[0];
|
|
@@ -598,13 +629,13 @@ class RovingKeyboard {
|
|
|
598
629
|
|
|
599
630
|
// Пункты, по которым ходит клавиатура: видимые и не запрещённые
|
|
600
631
|
#items() {
|
|
601
|
-
return this.#allItems().filter(item => !isDisabled(item) && isVisible(item));
|
|
632
|
+
return this.#allItems().filter((item) => !isDisabled(item) && isVisible(item));
|
|
602
633
|
}
|
|
603
634
|
|
|
604
635
|
#activeIndex(items) {
|
|
605
|
-
const focused = items.findIndex(item => item === document.activeElement);
|
|
636
|
+
const focused = items.findIndex((item) => item === document.activeElement);
|
|
606
637
|
if (focused !== -1) return focused;
|
|
607
|
-
return items.findIndex(item => item.getAttribute("tabindex") === "0");
|
|
638
|
+
return items.findIndex((item) => item.getAttribute("tabindex") === "0");
|
|
608
639
|
}
|
|
609
640
|
|
|
610
641
|
#applyStop(item) {
|
|
@@ -659,10 +690,10 @@ class RovingKeyboard {
|
|
|
659
690
|
}
|
|
660
691
|
}
|
|
661
692
|
|
|
662
|
-
exports.MenuKeyboard = MenuKeyboard
|
|
663
|
-
exports.ComboboxKeyboard = ComboboxKeyboard
|
|
664
|
-
exports.RovingKeyboard = RovingKeyboard
|
|
665
|
-
exports.A11Y_ACTIVE_CLASS = ACTIVE_CLASS
|
|
693
|
+
exports.MenuKeyboard = MenuKeyboard;
|
|
694
|
+
exports.ComboboxKeyboard = ComboboxKeyboard;
|
|
695
|
+
exports.RovingKeyboard = RovingKeyboard;
|
|
696
|
+
exports.A11Y_ACTIVE_CLASS = ACTIVE_CLASS;
|
|
666
697
|
|
|
667
698
|
/**
|
|
668
699
|
* Перенести фокус на следующий (или предыдущий) видимый фокусируемый элемент страницы.
|
|
@@ -670,7 +701,7 @@ exports.A11Y_ACTIVE_CLASS = ACTIVE_CLASS
|
|
|
670
701
|
* браузер уведёт фокус в `body`, а не к следующему полю. `skip` — узел или поддерево,
|
|
671
702
|
* которое в обходе не участвует (например, сам список).
|
|
672
703
|
*/
|
|
673
|
-
function moveFocusAway(from, options = {backwards: false, skip: undefined}) {
|
|
704
|
+
function moveFocusAway(from, options = { backwards: false, skip: undefined }) {
|
|
674
705
|
const nodes = [...document.querySelectorAll(FOCUSABLE_SELECTOR)]
|
|
675
706
|
.filter((node) => node.disabled !== true)
|
|
676
707
|
.filter((node) => isVisible(node))
|
|
@@ -684,4 +715,4 @@ function moveFocusAway(from, options = {backwards: false, skip: undefined}) {
|
|
|
684
715
|
return true;
|
|
685
716
|
}
|
|
686
717
|
|
|
687
|
-
exports.moveFocusAway = moveFocusAway
|
|
718
|
+
exports.moveFocusAway = moveFocusAway;
|
|
@@ -4,7 +4,7 @@ class Animation {
|
|
|
4
4
|
#element = undefined;
|
|
5
5
|
|
|
6
6
|
constructor(element) {
|
|
7
|
-
require(
|
|
7
|
+
require("../chui_functions").setStyles(__dirname + "/styles.css", "chUiJS_Animations");
|
|
8
8
|
if (element !== undefined) this.#element = element;
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -14,101 +14,101 @@ class Animation {
|
|
|
14
14
|
* доиграла, этот обработчик прятал уже открытый слой — вид расходился с состоянием.
|
|
15
15
|
*/
|
|
16
16
|
#cancelHide() {
|
|
17
|
-
this.#element.removeEventListener(
|
|
18
|
-
this.#element.style.removeProperty(
|
|
17
|
+
this.#element.removeEventListener("animationend", removeEvents);
|
|
18
|
+
this.#element.style.removeProperty("animation-name");
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
fadeIn() {
|
|
22
22
|
this.#cancelHide();
|
|
23
|
-
if (window.getComputedStyle(this.#element, null).display ===
|
|
24
|
-
if (this.#element.tagName !== "TABLE") this.#element.style.display =
|
|
23
|
+
if (window.getComputedStyle(this.#element, null).display === "none") {
|
|
24
|
+
if (this.#element.tagName !== "TABLE") this.#element.style.display = "flex";
|
|
25
25
|
}
|
|
26
|
-
this.#element.style.transition = "transform .0s"
|
|
27
|
-
this.#element.style.animationName =
|
|
26
|
+
this.#element.style.transition = "transform .0s";
|
|
27
|
+
this.#element.style.animationName = "fade-in";
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
fadeOut() {
|
|
31
|
-
this.#element.style.transition = "transform .0s"
|
|
31
|
+
this.#element.style.transition = "transform .0s";
|
|
32
32
|
if (this.#element.style.animationName) {
|
|
33
|
-
this.#element.style.animationName =
|
|
34
|
-
this.#element.addEventListener(
|
|
33
|
+
this.#element.style.animationName = "fade-out";
|
|
34
|
+
this.#element.addEventListener("animationend", removeEvents);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// SCALE
|
|
39
39
|
scaleIn() {
|
|
40
40
|
this.#cancelHide();
|
|
41
|
-
if (window.getComputedStyle(this.#element, null).display ===
|
|
42
|
-
if (this.#element.tagName !== "TABLE") this.#element.style.display =
|
|
41
|
+
if (window.getComputedStyle(this.#element, null).display === "none") {
|
|
42
|
+
if (this.#element.tagName !== "TABLE") this.#element.style.display = "flex";
|
|
43
43
|
}
|
|
44
|
-
this.#element.style.animationName =
|
|
44
|
+
this.#element.style.animationName = "scale-in";
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
scaleOut() {
|
|
48
48
|
if (this.#element.style.animationName) {
|
|
49
|
-
this.#element.style.animationName =
|
|
50
|
-
this.#element.addEventListener(
|
|
49
|
+
this.#element.style.animationName = "scale-out";
|
|
50
|
+
this.#element.addEventListener("animationend", removeEvents);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// SLIDE RIGHT
|
|
55
55
|
slideRightIn() {
|
|
56
56
|
this.#cancelHide();
|
|
57
|
-
if (window.getComputedStyle(this.#element, null).display ===
|
|
58
|
-
if (this.#element.tagName !== "TABLE") this.#element.style.display =
|
|
57
|
+
if (window.getComputedStyle(this.#element, null).display === "none") {
|
|
58
|
+
if (this.#element.tagName !== "TABLE") this.#element.style.display = "flex";
|
|
59
59
|
}
|
|
60
|
-
this.#element.style.animationName =
|
|
60
|
+
this.#element.style.animationName = "slide-right-in";
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
slideRightOut() {
|
|
64
64
|
if (this.#element.style.animationName) {
|
|
65
|
-
this.#element.style.animationName =
|
|
66
|
-
this.#element.addEventListener(
|
|
65
|
+
this.#element.style.animationName = "slide-right-out";
|
|
66
|
+
this.#element.addEventListener("animationend", removeEvents);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
// SLIDE BOTTOM
|
|
71
71
|
slideBottomIn() {
|
|
72
72
|
this.#cancelHide();
|
|
73
|
-
if (window.getComputedStyle(this.#element, null).display ===
|
|
74
|
-
if (this.#element.tagName !== "TABLE") this.#element.style.display =
|
|
73
|
+
if (window.getComputedStyle(this.#element, null).display === "none") {
|
|
74
|
+
if (this.#element.tagName !== "TABLE") this.#element.style.display = "flex";
|
|
75
75
|
}
|
|
76
|
-
this.#element.style.animationName =
|
|
76
|
+
this.#element.style.animationName = "slide-bottom-in";
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
slideBottomOut() {
|
|
80
80
|
if (this.#element.style.animationName) {
|
|
81
|
-
this.#element.style.animationName =
|
|
82
|
-
this.#element.addEventListener(
|
|
81
|
+
this.#element.style.animationName = "slide-bottom-out";
|
|
82
|
+
this.#element.addEventListener("animationend", removeEvents);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
// REMOVE
|
|
87
87
|
slideBottomOutAndRemove() {
|
|
88
88
|
if (this.#element.style.animationName) {
|
|
89
|
-
this.#element.style.animationName =
|
|
90
|
-
this.#element.addEventListener(
|
|
89
|
+
this.#element.style.animationName = "slide-bottom-out";
|
|
90
|
+
this.#element.addEventListener("animationend", removeEvents);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
slideRightOutAndRemove() {
|
|
95
95
|
if (this.#element.style.animationName) {
|
|
96
|
-
this.#element.style.animationName =
|
|
97
|
-
this.#element.addEventListener(
|
|
96
|
+
this.#element.style.animationName = "slide-right-out";
|
|
97
|
+
this.#element.addEventListener("animationend", removeEvents);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
scaleOutAndRemove() {
|
|
102
102
|
if (this.#element.style.animationName) {
|
|
103
|
-
this.#element.style.animationName =
|
|
104
|
-
this.#element.addEventListener(
|
|
103
|
+
this.#element.style.animationName = "scale-out";
|
|
104
|
+
this.#element.addEventListener("animationend", removeEvents2);
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
fadeOutAndRemove() {
|
|
109
109
|
if (this.#element.style.animationName) {
|
|
110
|
-
this.#element.style.animationName =
|
|
111
|
-
this.#element.addEventListener(
|
|
110
|
+
this.#element.style.animationName = "fade-out";
|
|
111
|
+
this.#element.addEventListener("animationend", removeEvents2);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -118,19 +118,19 @@ class Animation {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
removeStyles() {
|
|
121
|
-
this.#element.removeAttribute("style")
|
|
121
|
+
this.#element.removeAttribute("style");
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
const removeEvents2 = (event) => {
|
|
126
|
-
event.target.remove()
|
|
127
|
-
event.target.removeEventListener(
|
|
128
|
-
}
|
|
126
|
+
event.target.remove();
|
|
127
|
+
event.target.removeEventListener("animationend", removeEvents2);
|
|
128
|
+
};
|
|
129
129
|
|
|
130
130
|
const removeEvents = (event) => {
|
|
131
|
-
event.target.style.removeProperty(
|
|
132
|
-
event.target.style.removeProperty(
|
|
133
|
-
event.target.removeEventListener(
|
|
134
|
-
}
|
|
131
|
+
event.target.style.removeProperty("animation-name");
|
|
132
|
+
event.target.style.removeProperty("display");
|
|
133
|
+
event.target.removeEventListener("animationend", removeEvents);
|
|
134
|
+
};
|
|
135
135
|
|
|
136
|
-
exports.Animation = Animation
|
|
136
|
+
exports.Animation = Animation;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
const {contextBridge, ipcRenderer} = require("electron");
|
|
2
|
-
const {
|
|
1
|
+
const { contextBridge, ipcRenderer } = require("electron");
|
|
2
|
+
const {
|
|
3
|
+
SERVICES_CHANNELS,
|
|
4
|
+
SERVICES_CALLS,
|
|
5
|
+
SERVICES_SYNC_CALLS,
|
|
6
|
+
BRIDGE_CHANNELS,
|
|
7
|
+
BRIDGE_ARGS,
|
|
8
|
+
} = require("../chui_services/chui_channels");
|
|
3
9
|
// Мост переиспользует ту же обёртку сервисов, что и страница: разница только в транспорте
|
|
4
10
|
// (`Desktop` в preload'е сам вызовет ipcRenderer, потому что `window.chui` ему не виден)
|
|
5
|
-
const {Desktop} = require("../chui_services/desktop");
|
|
11
|
+
const { Desktop } = require("../chui_services/desktop");
|
|
6
12
|
|
|
7
13
|
/**
|
|
8
14
|
* Preload безопасного режима (`Main({security: {contextIsolation: true}})`).
|
|
@@ -32,7 +38,10 @@ function argValue(prefix = String()) {
|
|
|
32
38
|
|
|
33
39
|
const renderPath = argValue(BRIDGE_ARGS.RENDER);
|
|
34
40
|
const csp = argValue(BRIDGE_ARGS.CSP);
|
|
35
|
-
const channels = (argValue(BRIDGE_ARGS.CHANNELS) ?? "")
|
|
41
|
+
const channels = (argValue(BRIDGE_ARGS.CHANNELS) ?? "")
|
|
42
|
+
.split(",")
|
|
43
|
+
.map((channel) => channel.trim())
|
|
44
|
+
.filter(Boolean);
|
|
36
45
|
|
|
37
46
|
/**
|
|
38
47
|
* Content-Security-Policy вставляется в документ до его скриптов: preload выполняется раньше
|
|
@@ -50,7 +59,7 @@ function applyCsp() {
|
|
|
50
59
|
return true;
|
|
51
60
|
}
|
|
52
61
|
|
|
53
|
-
if (!applyCsp()) document.addEventListener("readystatechange", () => applyCsp(), {once: true});
|
|
62
|
+
if (!applyCsp()) document.addEventListener("readystatechange", () => applyCsp(), { once: true });
|
|
54
63
|
|
|
55
64
|
const call = (method = String(), ...args) => {
|
|
56
65
|
const channel = SERVICES_CALLS[method];
|
|
@@ -100,7 +109,7 @@ contextBridge.exposeInMainWorld("chui", {
|
|
|
100
109
|
versions: {
|
|
101
110
|
node: process.versions.node,
|
|
102
111
|
chrome: process.versions.chrome,
|
|
103
|
-
electron: process.versions.electron
|
|
112
|
+
electron: process.versions.electron,
|
|
104
113
|
},
|
|
105
114
|
platform: process.platform,
|
|
106
115
|
/** Путь к странице окна (как он задан в опции `render`) */
|
|
@@ -120,20 +129,20 @@ contextBridge.exposeInMainWorld("chui", {
|
|
|
120
129
|
copy: (text = String()) => Desktop.clipboard.history.copy(text),
|
|
121
130
|
remove: (target = undefined) => Desktop.clipboard.history.remove(target),
|
|
122
131
|
clear: () => Desktop.clipboard.history.clear(),
|
|
123
|
-
onChange: (listener = () => {}) => services.onClipboardHistory(listener)
|
|
124
|
-
}
|
|
132
|
+
onChange: (listener = () => {}) => services.onClipboardHistory(listener),
|
|
133
|
+
},
|
|
125
134
|
},
|
|
126
135
|
recent: {
|
|
127
136
|
add: (path = String(), name = undefined) => Desktop.recent.add(path, name),
|
|
128
137
|
clear: () => Desktop.recent.clear(),
|
|
129
|
-
list: () => Desktop.recent.list()
|
|
138
|
+
list: () => Desktop.recent.list(),
|
|
130
139
|
},
|
|
131
140
|
progress: {
|
|
132
141
|
set: (value = Number(), mode = "normal") => Desktop.progress.set(value, mode),
|
|
133
|
-
clear: () => Desktop.progress.clear()
|
|
142
|
+
clear: () => Desktop.progress.clear(),
|
|
134
143
|
},
|
|
135
144
|
shell: {
|
|
136
|
-
openExternal: (url = String()) => Desktop.shell.openExternal(url)
|
|
145
|
+
openExternal: (url = String()) => Desktop.shell.openExternal(url),
|
|
137
146
|
},
|
|
138
147
|
app: {
|
|
139
148
|
// Путь приходит значением, без промиса (синхронный канал), а `Desktop` в preload'е
|
|
@@ -148,36 +157,36 @@ contextBridge.exposeInMainWorld("chui", {
|
|
|
148
157
|
// Закрытие и перезапуск — как у `Desktop` из пакета: те же шаги, что у пункта меню.
|
|
149
158
|
// Отвечают значением, а не промисом (синхронный канал), поэтому `await` не нужен
|
|
150
159
|
quit: () => Desktop.app.quit(),
|
|
151
|
-
restart: () => Desktop.app.restart()
|
|
160
|
+
restart: () => Desktop.app.restart(),
|
|
152
161
|
},
|
|
153
162
|
dialog: {
|
|
154
163
|
open: (options = {}) => Desktop.dialog.open(options),
|
|
155
164
|
save: (options = {}) => Desktop.dialog.save(options),
|
|
156
|
-
message: (options = {}) => Desktop.dialog.message(options)
|
|
165
|
+
message: (options = {}) => Desktop.dialog.message(options),
|
|
157
166
|
},
|
|
158
167
|
session: {
|
|
159
168
|
getCacheSize: () => Desktop.session.getCacheSize(),
|
|
160
169
|
clearCache: () => Desktop.session.clearCache(),
|
|
161
|
-
clearStorageData: (options = {}) => Desktop.session.clearStorageData(options)
|
|
170
|
+
clearStorageData: (options = {}) => Desktop.session.clearStorageData(options),
|
|
162
171
|
},
|
|
163
172
|
print: {
|
|
164
173
|
page: (options = {}) => Desktop.print.page(options),
|
|
165
174
|
html: (html = String(), options = {}) => Desktop.print.html(html, options),
|
|
166
|
-
pdf: (html = String(), options = {}) => Desktop.print.pdf(html, options)
|
|
175
|
+
pdf: (html = String(), options = {}) => Desktop.print.pdf(html, options),
|
|
167
176
|
},
|
|
168
177
|
shortcuts: {
|
|
169
178
|
on: (accelerator = String(), handler = () => {}) => Desktop.shortcuts.on(accelerator, handler),
|
|
170
179
|
off: (accelerator = String(), handler = () => {}) => Desktop.shortcuts.off(accelerator, handler),
|
|
171
180
|
offAll: () => Desktop.shortcuts.offAll(),
|
|
172
|
-
get: () => Desktop.shortcuts.get()
|
|
173
|
-
}
|
|
181
|
+
get: () => Desktop.shortcuts.get(),
|
|
182
|
+
},
|
|
174
183
|
},
|
|
175
184
|
window: {
|
|
176
185
|
minimize: () => windowAction("minimize"),
|
|
177
186
|
toggleMaximize: () => windowAction("toggle-maximize"),
|
|
178
187
|
restore: () => windowAction("restore"),
|
|
179
188
|
close: () => windowAction("close"),
|
|
180
|
-
getState: () => ipcRenderer.invoke(BRIDGE_CHANNELS.WINDOW_STATE)
|
|
189
|
+
getState: () => ipcRenderer.invoke(BRIDGE_CHANNELS.WINDOW_STATE),
|
|
181
190
|
},
|
|
182
191
|
theme: {
|
|
183
192
|
get: () => ipcRenderer.invoke(BRIDGE_CHANNELS.THEME_GET),
|
|
@@ -187,7 +196,7 @@ contextBridge.exposeInMainWorld("chui", {
|
|
|
187
196
|
onChange: (listener = () => {}) => {
|
|
188
197
|
themeListeners.add(listener);
|
|
189
198
|
return () => themeListeners.delete(listener);
|
|
190
|
-
}
|
|
199
|
+
},
|
|
191
200
|
},
|
|
192
201
|
locale: {
|
|
193
202
|
get: () => ipcRenderer.invoke(BRIDGE_CHANNELS.LOCALE_GET),
|
|
@@ -196,17 +205,19 @@ contextBridge.exposeInMainWorld("chui", {
|
|
|
196
205
|
onChange: (listener = () => {}) => {
|
|
197
206
|
localeListeners.add(listener);
|
|
198
207
|
return () => localeListeners.delete(listener);
|
|
199
|
-
}
|
|
208
|
+
},
|
|
200
209
|
},
|
|
201
210
|
messaging: {
|
|
202
211
|
/** Каналы задаёт приложение: `security: {channels: ['preview:update']}` */
|
|
203
212
|
channels: [...channels],
|
|
204
213
|
send: (channel = String(), ...args) => {
|
|
205
|
-
if (!channels.includes(channel))
|
|
214
|
+
if (!channels.includes(channel))
|
|
215
|
+
throw new Error(`chui: канал «${channel}» не разрешён в security.channels`);
|
|
206
216
|
return ipcRenderer.invoke(BRIDGE_CHANNELS.MESSAGE, channel, ...args);
|
|
207
217
|
},
|
|
208
218
|
on: (channel = String(), listener = () => {}) => {
|
|
209
|
-
if (!channels.includes(channel))
|
|
219
|
+
if (!channels.includes(channel))
|
|
220
|
+
throw new Error(`chui: канал «${channel}» не разрешён в security.channels`);
|
|
210
221
|
const listeners = messageListeners.get(channel) ?? new Set();
|
|
211
222
|
listeners.add(listener);
|
|
212
223
|
messageListeners.set(channel, listeners);
|
|
@@ -214,8 +225,8 @@ contextBridge.exposeInMainWorld("chui", {
|
|
|
214
225
|
listeners.delete(listener);
|
|
215
226
|
if (listeners.size === 0) messageListeners.delete(channel);
|
|
216
227
|
};
|
|
217
|
-
}
|
|
218
|
-
}
|
|
228
|
+
},
|
|
229
|
+
},
|
|
219
230
|
});
|
|
220
231
|
|
|
221
232
|
// Скрипт страницы подключается здесь: в безопасном режиме `render` — это скрипт документа,
|
|
@@ -227,6 +238,6 @@ if (renderPath !== undefined) {
|
|
|
227
238
|
script.defer = true;
|
|
228
239
|
document.head.appendChild(script);
|
|
229
240
|
};
|
|
230
|
-
if (document.readyState === "loading") window.addEventListener("DOMContentLoaded", addPageScript, {once: true});
|
|
241
|
+
if (document.readyState === "loading") window.addEventListener("DOMContentLoaded", addPageScript, { once: true });
|
|
231
242
|
else addPageScript();
|
|
232
243
|
}
|