@yuneta/gobj-ui 7.26.34 → 7.26.35
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/README.md +223 -53
- package/dist/gobj-ui.cjs.js +1035 -141
- package/dist/gobj-ui.es.js +1035 -141
- package/package.json +2 -2
- package/scripts/validate-locales.mjs +672 -96
- package/src/c_yui_form.js +186 -9
- package/src/c_yui_gclass.js +2 -0
- package/src/c_yui_gobj_tree_js.js +2 -0
- package/src/c_yui_json.js +2 -0
- package/src/c_yui_json_graph.js +2 -0
- package/src/c_yui_nav.js +23 -5
- package/src/c_yui_shell.css +16 -0
- package/src/c_yui_shell.js +282 -26
- package/src/c_yui_treedb_graph.js +26 -8
- package/src/c_yui_treedb_topic_with_form.js +40 -18
- package/src/c_yui_treedb_topics.js +34 -11
- package/src/c_yui_window.js +132 -32
- package/src/c_yui_window_manager.js +156 -44
- package/src/form_json_editor_names.js +448 -0
- package/src/form_json_editor_names.wiring.test.js +595 -0
- package/src/form_label_i18n.wiring.test.js +169 -0
- package/src/i18n_key_functions.js +14 -6
- package/src/i18n_key_functions.test.js +124 -2
- package/src/lib_maplibre.js +26 -2
- package/src/lib_maplibre_relocalize.test.js +78 -0
- package/src/named_controls.wiring.test.js +468 -0
- package/src/nav_cards_helpers.js +9 -1
- package/src/nav_item_badge.wiring.test.js +182 -1
- package/src/shell_route_map.js +25 -8
- package/src/table_editor_name.wiring.test.js +201 -0
- package/src/treedb_column_title.wiring.test.js +151 -0
- package/src/treedb_json_drill.wiring.test.js +41 -1
- package/src/window_layer.wiring.test.js +308 -43
- package/src/window_show.wiring.test.js +6 -2
- package/src/window_stacking.wiring.test.js +334 -0
- package/src/yui_badge.js +58 -13
- package/src/yui_badge.test.js +40 -3
- package/src/yui_dev.js +2 -1
- package/src/yui_file_field.js +2 -0
- package/src/yui_frontend_view.js +2 -1
- package/src/yui_gclass_view.js +9 -6
- package/src/yui_tabulator_i18n.js +42 -0
- package/src/yui_tabulator_i18n.test.js +48 -1
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -545,14 +545,26 @@ function text_list_item_formatter(label) {
|
|
|
545
545
|
* ALWAYS RENDERED, hidden when empty, so the runtime setters have a
|
|
546
546
|
* node to write into and never rebuild the control that holds it.
|
|
547
547
|
*
|
|
548
|
-
*
|
|
549
|
-
* carries an explicit aria-label, and an explicit label
|
|
550
|
-
* the element's content for a screen reader -- so a badge
|
|
551
|
-
* it
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
548
|
+
* PART OF THE CONTROL'S NAME (name_control_with_badge()). The
|
|
549
|
+
* control carries an explicit aria-label, and an explicit label
|
|
550
|
+
* REPLACES the element's content for a screen reader -- so a badge
|
|
551
|
+
* inside it is silent, and inside a <button> (the toolbar, an
|
|
552
|
+
* accordion head) its children are not even in the tree. The
|
|
553
|
+
* control is labelled by ITSELF (its aria-label, which
|
|
554
|
+
* refresh_language() re-translates) and by the badge: the name is
|
|
555
|
+
* "Alarms 3" while there is a count, "Alarms" while there is none,
|
|
556
|
+
* with nothing composed in javascript that a language switch would
|
|
557
|
+
* leave behind.
|
|
558
|
+
*
|
|
559
|
+
* NOT a live region any more. Up to 7.26.34 the badge was its own
|
|
560
|
+
* role="status", and that said "3" with no word of what has three;
|
|
561
|
+
* hidden while empty, it was not in the tree when the first count
|
|
562
|
+
* arrived, so 0 -> 1 was most likely never said; and inside a
|
|
563
|
+
* <button> it was not there at all. The change is said by the
|
|
564
|
+
* shell, in one live region of its own that is always there, with
|
|
565
|
+
* the name of the item: "Alarms, 3" (yui_shell_set_nav_item_badge,
|
|
566
|
+
* yui_shell_set_toolbar_item_badge). A write that changes nothing
|
|
567
|
+
* still touches no DOM.
|
|
556
568
|
*
|
|
557
569
|
* A TONE, optional: one of BADGE_TONES, drawn as Bulma's
|
|
558
570
|
* `is-<tone>` on the badge. It says HOW BAD the count is -- the
|
|
@@ -578,6 +590,7 @@ var BADGE_TONES = Object.freeze([
|
|
|
578
590
|
"primary",
|
|
579
591
|
"link"
|
|
580
592
|
]);
|
|
593
|
+
var __badge_seq__ = 0;
|
|
581
594
|
/************************************************************
|
|
582
595
|
* The text a badge shows for `value`, "" when it shows none.
|
|
583
596
|
************************************************************/
|
|
@@ -611,10 +624,7 @@ function badge_tone(tone, who) {
|
|
|
611
624
|
function badge_node(value, tone, classes, who) {
|
|
612
625
|
let text = badge_text(value);
|
|
613
626
|
let known = badge_tone(tone, who);
|
|
614
|
-
let attrs = {
|
|
615
|
-
class: known ? `${classes} is-${known}` : classes,
|
|
616
|
-
role: "status"
|
|
617
|
-
};
|
|
627
|
+
let attrs = { class: known ? `${classes} is-${known}` : classes };
|
|
618
628
|
if (!text) attrs.hidden = "hidden";
|
|
619
629
|
return [
|
|
620
630
|
"span",
|
|
@@ -623,6 +633,31 @@ function badge_node(value, tone, classes, who) {
|
|
|
623
633
|
];
|
|
624
634
|
}
|
|
625
635
|
/************************************************************
|
|
636
|
+
* Make the count part of the NAME of the control that carries
|
|
637
|
+
* the badge: its `aria-labelledby` points at the control itself
|
|
638
|
+
* and at the badge.
|
|
639
|
+
*
|
|
640
|
+
* The control keeps its `aria-label` and its
|
|
641
|
+
* data-i18n-aria-label: a self-reference reads the aria-label,
|
|
642
|
+
* so the name is the translated label followed by the badge's
|
|
643
|
+
* text -- "Alarms 3" -- or the label alone while the badge is
|
|
644
|
+
* empty. A painted count is in the name at once, and a language
|
|
645
|
+
* switch re-translates the label as it always did.
|
|
646
|
+
*
|
|
647
|
+
* Both are createElement2() descriptions, before anything is
|
|
648
|
+
* built: `control_attrs` (the attrs of the <a> or <button>, which
|
|
649
|
+
* must carry its aria-label) gets an `id` when it has none, and
|
|
650
|
+
* the `aria-labelledby`; `badge` (what badge_node() answered)
|
|
651
|
+
* gets its `id`.
|
|
652
|
+
************************************************************/
|
|
653
|
+
function name_control_with_badge(control_attrs, badge) {
|
|
654
|
+
let seq = ++__badge_seq__;
|
|
655
|
+
if (!control_attrs.id) control_attrs.id = `yui-badged-${seq}`;
|
|
656
|
+
let badge_attrs = badge[1];
|
|
657
|
+
badge_attrs.id = `yui-badge-${seq}`;
|
|
658
|
+
control_attrs["aria-labelledby"] = `${control_attrs.id} ${badge_attrs.id}`;
|
|
659
|
+
}
|
|
660
|
+
/************************************************************
|
|
626
661
|
* Write a badge that is already in the DOM, as badge_node()
|
|
627
662
|
* draws it. `tone` is one badge_tone() answered: the setter
|
|
628
663
|
* checks it once for all the badges it paints.
|
|
@@ -1019,6 +1054,8 @@ function secondary_nav_renders(item, layout) {
|
|
|
1019
1054
|
*
|
|
1020
1055
|
* Parses a JSON config to build:
|
|
1021
1056
|
* - Layers (z-stacked): base, overlay, popup, modal, notification, loading
|
|
1057
|
+
* (the overlay holds the WINDOW layer, where the windows live,
|
|
1058
|
+
* under the drawer: yui_shell_window_layer())
|
|
1022
1059
|
* - Zones (inside base layer): top, top-sub, left, center, right,
|
|
1023
1060
|
* bottom-sub, bottom
|
|
1024
1061
|
* - Menus (primary + submenus) rendered via C_YUI_NAV — one nav
|
|
@@ -1046,6 +1083,8 @@ function secondary_nav_renders(item, layout) {
|
|
|
1046
1083
|
***************************************************************/
|
|
1047
1084
|
var GCLASS_NAME$22 = "C_YUI_SHELL";
|
|
1048
1085
|
var __last_shell__ = null;
|
|
1086
|
+
var __shell_watchers__ = [];
|
|
1087
|
+
var __window_z__ = 10;
|
|
1049
1088
|
var ZONE_IDS = [
|
|
1050
1089
|
"top",
|
|
1051
1090
|
"top-sub",
|
|
@@ -1080,10 +1119,12 @@ var attrs_table$22 = [
|
|
|
1080
1119
|
var PRIVATE_DATA$22 = {
|
|
1081
1120
|
zones: {},
|
|
1082
1121
|
layers: {},
|
|
1122
|
+
window_layer: null,
|
|
1083
1123
|
stages: {},
|
|
1084
1124
|
navs: [],
|
|
1085
1125
|
item_index: {},
|
|
1086
1126
|
nav_badges: {},
|
|
1127
|
+
badge_status: null,
|
|
1087
1128
|
dynamic_items: {},
|
|
1088
1129
|
section_pos: {},
|
|
1089
1130
|
route_mru: [],
|
|
@@ -1124,6 +1165,7 @@ function mt_create$22(gobj) {
|
|
|
1124
1165
|
if (subscriber) (0, _yuneta_gobj_js.gobj_subscribe_event)(gobj, null, {}, subscriber);
|
|
1125
1166
|
__last_shell__ = gobj;
|
|
1126
1167
|
build_ui$19(gobj);
|
|
1168
|
+
tell_shell_watchers(gobj);
|
|
1127
1169
|
}
|
|
1128
1170
|
/***************************************************************
|
|
1129
1171
|
* Framework Method: Start
|
|
@@ -1307,10 +1349,11 @@ function mt_stop$20(gobj) {
|
|
|
1307
1349
|
***************************************************************/
|
|
1308
1350
|
function mt_destroy$22(gobj) {
|
|
1309
1351
|
close_toolbar_dropdown(gobj);
|
|
1352
|
+
if (__last_shell__ === gobj) __last_shell__ = null;
|
|
1310
1353
|
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
1311
1354
|
if ($container && $container.parentNode) $container.parentNode.removeChild($container);
|
|
1355
|
+
tell_shell_watchers(gobj);
|
|
1312
1356
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "$container", null);
|
|
1313
|
-
if (__last_shell__ === gobj) __last_shell__ = null;
|
|
1314
1357
|
}
|
|
1315
1358
|
/***************************
|
|
1316
1359
|
* Local Methods
|
|
@@ -1433,6 +1476,17 @@ function build_ui$19(gobj) {
|
|
|
1433
1476
|
$container.appendChild($layer);
|
|
1434
1477
|
priv.layers[id] = $layer;
|
|
1435
1478
|
}
|
|
1479
|
+
let $windows = (0, _yuneta_gobj_js.createElement2)(["div", { class: "SHELL_WINDOW_LAYER yui-window-layer" }]);
|
|
1480
|
+
priv.layers.overlay.appendChild($windows);
|
|
1481
|
+
priv.window_layer = $windows;
|
|
1482
|
+
let $status = (0, _yuneta_gobj_js.createElement2)(["div", {
|
|
1483
|
+
class: "SHELL_BADGE_STATUS is-sr-only",
|
|
1484
|
+
role: "status",
|
|
1485
|
+
"aria-live": "polite",
|
|
1486
|
+
"aria-atomic": "true"
|
|
1487
|
+
}]);
|
|
1488
|
+
$container.appendChild($status);
|
|
1489
|
+
priv.badge_status = $status;
|
|
1436
1490
|
let $base = priv.layers.base;
|
|
1437
1491
|
$base.classList.add("yui-base-grid");
|
|
1438
1492
|
let zones_cfg = shell_cfg.zones || {};
|
|
@@ -2026,14 +2080,18 @@ function toolbar_link_attrs(it) {
|
|
|
2026
2080
|
************************************************************/
|
|
2027
2081
|
function build_toolbar_action_item(gobj, it) {
|
|
2028
2082
|
let children = [];
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
[
|
|
2033
|
-
|
|
2034
|
-
"
|
|
2035
|
-
|
|
2036
|
-
|
|
2083
|
+
let badge = null;
|
|
2084
|
+
if (!(0, _yuneta_gobj_js.empty_string)(it.icon)) {
|
|
2085
|
+
badge = badge_node(it.badge, it.badge_tone, "TOOLBAR_ITEM_BADGE yui-badge yui-toolbar-badge", `C_YUI_SHELL: toolbar item '${it.id || "?"}'`);
|
|
2086
|
+
children.push([
|
|
2087
|
+
"span",
|
|
2088
|
+
{ class: "icon yui-toolbar-icon" },
|
|
2089
|
+
[["i", {
|
|
2090
|
+
class: it.icon,
|
|
2091
|
+
"aria-hidden": "true"
|
|
2092
|
+
}], badge]
|
|
2093
|
+
]);
|
|
2094
|
+
}
|
|
2037
2095
|
if (!(0, _yuneta_gobj_js.empty_string)(it.name)) children.push([
|
|
2038
2096
|
"span",
|
|
2039
2097
|
{
|
|
@@ -2060,6 +2118,7 @@ function build_toolbar_action_item(gobj, it) {
|
|
|
2060
2118
|
btn_attrs.title = tip;
|
|
2061
2119
|
btn_attrs["data-i18n-title"] = tip;
|
|
2062
2120
|
}
|
|
2121
|
+
if (badge && !(0, _yuneta_gobj_js.empty_string)(aria_key)) name_control_with_badge(btn_attrs, badge);
|
|
2063
2122
|
let link = toolbar_link_attrs(it);
|
|
2064
2123
|
if (link) {
|
|
2065
2124
|
delete btn_attrs.type;
|
|
@@ -2844,23 +2903,32 @@ function update_secondary_nav_visibility(gobj, entry) {
|
|
|
2844
2903
|
}
|
|
2845
2904
|
}
|
|
2846
2905
|
/************************************************************
|
|
2847
|
-
*
|
|
2848
|
-
* of a menu of app_config.json, of one of
|
|
2849
|
-
* one given to yui_shell_set_submenu() since
|
|
2906
|
+
* The item `item_id` a menu of this shell declares, null when
|
|
2907
|
+
* none does: an item of a menu of app_config.json, of one of
|
|
2908
|
+
* their submenus, or one given to yui_shell_set_submenu() since
|
|
2909
|
+
* -- which comes first, because it replaced what the submenu
|
|
2910
|
+
* declared and is what the navs draw.
|
|
2850
2911
|
************************************************************/
|
|
2851
|
-
function
|
|
2912
|
+
function nav_item_of(gobj, item_id) {
|
|
2852
2913
|
let priv = gobj.priv;
|
|
2853
2914
|
let config = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "config") || {};
|
|
2854
2915
|
let menus = (0, _yuneta_gobj_js.is_object)(config.menu) ? config.menu : {};
|
|
2855
|
-
let
|
|
2916
|
+
let find = (items) => (0, _yuneta_gobj_js.is_array)(items) && items.find((it) => it && it.id === item_id) || null;
|
|
2917
|
+
for (let parent_item_id in priv.dynamic_items) {
|
|
2918
|
+
let it = find(priv.dynamic_items[parent_item_id]);
|
|
2919
|
+
if (it) return it;
|
|
2920
|
+
}
|
|
2856
2921
|
for (let menu_id in menus) {
|
|
2857
2922
|
let items = menus[menu_id] && menus[menu_id].items;
|
|
2858
2923
|
if (!(0, _yuneta_gobj_js.is_array)(items)) continue;
|
|
2859
|
-
|
|
2860
|
-
|
|
2924
|
+
let it = find(items);
|
|
2925
|
+
if (it) return it;
|
|
2926
|
+
for (let parent of items) {
|
|
2927
|
+
let sub = parent && parent.submenu && find(parent.submenu.items);
|
|
2928
|
+
if (sub) return sub;
|
|
2929
|
+
}
|
|
2861
2930
|
}
|
|
2862
|
-
|
|
2863
|
-
return false;
|
|
2931
|
+
return null;
|
|
2864
2932
|
}
|
|
2865
2933
|
/************************************************************
|
|
2866
2934
|
* Every C_YUI_NAV of this shell: the navs of its menus, and the
|
|
@@ -2878,6 +2946,61 @@ function shell_navs(gobj) {
|
|
|
2878
2946
|
}
|
|
2879
2947
|
return navs;
|
|
2880
2948
|
}
|
|
2949
|
+
/************************************************************
|
|
2950
|
+
* Say a badge that changed, with the name of what it counts:
|
|
2951
|
+
* "Alarms, 3", in the shell's live region (build_ui()).
|
|
2952
|
+
*
|
|
2953
|
+
* The badge itself is no live region (yui_badge.js): its number
|
|
2954
|
+
* alone said nothing, hidden while empty it missed the first
|
|
2955
|
+
* count, and inside a <button> it was not there at all. The
|
|
2956
|
+
* setters call this only when the text a reader would see
|
|
2957
|
+
* changes and is not empty: a count going away is not news, and
|
|
2958
|
+
* the same count again is not either.
|
|
2959
|
+
*
|
|
2960
|
+
* `name_key` is the key of the control's name; the phrase is a
|
|
2961
|
+
* key of its own, so a language orders and punctuates it its
|
|
2962
|
+
* way. Said once: a live region needs no re-translation.
|
|
2963
|
+
************************************************************/
|
|
2964
|
+
function announce_badge(gobj, name_key, text) {
|
|
2965
|
+
let priv = gobj.priv;
|
|
2966
|
+
let $status = priv.badge_status;
|
|
2967
|
+
if (!$status) {
|
|
2968
|
+
(0, _yuneta_gobj_js.log_error)(`C_YUI_SHELL: no live region to say badge '${name_key}': ${text}`);
|
|
2969
|
+
return;
|
|
2970
|
+
}
|
|
2971
|
+
let message;
|
|
2972
|
+
if (typeof priv.translator === "function") {
|
|
2973
|
+
const tr = priv.translator;
|
|
2974
|
+
message = tr("{{name}}, {{n}}", {
|
|
2975
|
+
name: tr(name_key),
|
|
2976
|
+
n: text
|
|
2977
|
+
});
|
|
2978
|
+
} else message = `${name_key}, ${text}`;
|
|
2979
|
+
$status.textContent = message;
|
|
2980
|
+
}
|
|
2981
|
+
/************************************************************
|
|
2982
|
+
* A shell was built (mt_create) or is being destroyed
|
|
2983
|
+
* (mt_destroy): tell every gobj that keeps DOM in a shell's
|
|
2984
|
+
* layers without being its child (yui_shell_watch_changes()).
|
|
2985
|
+
* Each one decides in its own action what it means for it --
|
|
2986
|
+
* the trace shows EV_SHELL_CHANGED arriving, from a `!!` shell
|
|
2987
|
+
* when it is the one going.
|
|
2988
|
+
*
|
|
2989
|
+
* An event, not a call into the window's module: the shell does
|
|
2990
|
+
* not import its watchers, and the move is work, so it crosses
|
|
2991
|
+
* their FSM. A watcher that is being destroyed is one whose
|
|
2992
|
+
* mt_destroy did not unwatch: it is dropped, and said.
|
|
2993
|
+
************************************************************/
|
|
2994
|
+
function tell_shell_watchers(gobj) {
|
|
2995
|
+
for (let watcher of __shell_watchers__.slice()) {
|
|
2996
|
+
if ((0, _yuneta_gobj_js.gobj_is_destroying)(watcher)) {
|
|
2997
|
+
(0, _yuneta_gobj_js.log_error)(`C_YUI_SHELL: a destroyed gobj still watches the shell (${(0, _yuneta_gobj_js.gobj_short_name)(watcher)}): it must call yui_shell_unwatch_changes() in its mt_destroy`);
|
|
2998
|
+
yui_shell_unwatch_changes(watcher);
|
|
2999
|
+
continue;
|
|
3000
|
+
}
|
|
3001
|
+
(0, _yuneta_gobj_js.gobj_send_event)(watcher, "EV_SHELL_CHANGED", {}, gobj);
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
2881
3004
|
/***************************
|
|
2882
3005
|
* Actions
|
|
2883
3006
|
***************************/
|
|
@@ -3147,6 +3270,81 @@ function yui_shell_of(gobj) {
|
|
|
3147
3270
|
return __last_shell__;
|
|
3148
3271
|
}
|
|
3149
3272
|
/************************************************************
|
|
3273
|
+
* The DOM where a C_YUI_WINDOW lives when its host names no
|
|
3274
|
+
* `$parent`: the WINDOW layer, a stacking context of its own
|
|
3275
|
+
* inside the overlay layer -- above the content, below the
|
|
3276
|
+
* drawer, the toolbar's dropdowns, the dialogs and the toasts,
|
|
3277
|
+
* whatever z-index a window takes there. Null with no shell (the
|
|
3278
|
+
* window then lives in document.body).
|
|
3279
|
+
************************************************************/
|
|
3280
|
+
function yui_shell_window_layer(shell_gobj) {
|
|
3281
|
+
if (!shell_gobj || !shell_gobj.priv) return null;
|
|
3282
|
+
let priv = shell_gobj.priv;
|
|
3283
|
+
return priv.window_layer || priv.layers && priv.layers.overlay || null;
|
|
3284
|
+
}
|
|
3285
|
+
/************************************************************
|
|
3286
|
+
* Put a window on top of the others: the next number of ONE
|
|
3287
|
+
* counter, the same for a window of the dock and for a floating
|
|
3288
|
+
* one.
|
|
3289
|
+
*
|
|
3290
|
+
* Up to 7.26.34 there were two orders: the dock raised its windows
|
|
3291
|
+
* to a counter of its own (11, 12, ...), and a window without a
|
|
3292
|
+
* dock sat at 3 and was raised by being moved to the end of its
|
|
3293
|
+
* parent -- so a window opened LATER without a dock (a treedb's
|
|
3294
|
+
* raw json) opened UNDER any docked one, and no click could bring
|
|
3295
|
+
* it up. They share the window layer, and this one number orders
|
|
3296
|
+
* them all. It grows for ever, and it can: nothing else lives in
|
|
3297
|
+
* the window layer's stacking context.
|
|
3298
|
+
*
|
|
3299
|
+
* A number, not a move in the DOM: moving an element takes its
|
|
3300
|
+
* focus, its scroll positions and the pointer press that started
|
|
3301
|
+
* on it.
|
|
3302
|
+
************************************************************/
|
|
3303
|
+
function yui_shell_raise_window($el) {
|
|
3304
|
+
if (!$el || !$el.style) {
|
|
3305
|
+
(0, _yuneta_gobj_js.log_error)("C_YUI_SHELL: yui_shell_raise_window() needs an element");
|
|
3306
|
+
return;
|
|
3307
|
+
}
|
|
3308
|
+
__window_z__ += 1;
|
|
3309
|
+
$el.style.zIndex = String(__window_z__);
|
|
3310
|
+
}
|
|
3311
|
+
/************************************************************
|
|
3312
|
+
* Ask to be told (EV_SHELL_CHANGED, an INPUT event the gclass of
|
|
3313
|
+
* `gobj` must take in its FSM) when a shell is built or
|
|
3314
|
+
* destroyed.
|
|
3315
|
+
*
|
|
3316
|
+
* For a gobj that keeps DOM in a shell's layers without being
|
|
3317
|
+
* its child -- a window parented to the app, the dock. A shell's
|
|
3318
|
+
* children are destroyed with it; such a gobj is not, and its
|
|
3319
|
+
* place goes with the shell: a logout destroys the shell, the
|
|
3320
|
+
* login builds another. Told, it takes its place again in the
|
|
3321
|
+
* action.
|
|
3322
|
+
*
|
|
3323
|
+
* Idempotent. Pair it with yui_shell_unwatch_changes() in
|
|
3324
|
+
* mt_destroy, or the next shell sends the event to a destroyed
|
|
3325
|
+
* gobj.
|
|
3326
|
+
*
|
|
3327
|
+
* function mt_create(gobj) {
|
|
3328
|
+
* ...
|
|
3329
|
+
* yui_shell_watch_changes(gobj);
|
|
3330
|
+
* }
|
|
3331
|
+
* function mt_destroy(gobj) {
|
|
3332
|
+
* yui_shell_unwatch_changes(gobj);
|
|
3333
|
+
* ...
|
|
3334
|
+
* }
|
|
3335
|
+
************************************************************/
|
|
3336
|
+
function yui_shell_watch_changes(gobj) {
|
|
3337
|
+
if (!(0, _yuneta_gobj_js.is_gobj)(gobj)) {
|
|
3338
|
+
(0, _yuneta_gobj_js.log_error)("C_YUI_SHELL: yui_shell_watch_changes() needs a gobj");
|
|
3339
|
+
return;
|
|
3340
|
+
}
|
|
3341
|
+
if (__shell_watchers__.indexOf(gobj) < 0) __shell_watchers__.push(gobj);
|
|
3342
|
+
}
|
|
3343
|
+
function yui_shell_unwatch_changes(gobj) {
|
|
3344
|
+
let idx = __shell_watchers__.indexOf(gobj);
|
|
3345
|
+
if (idx >= 0) __shell_watchers__.splice(idx, 1);
|
|
3346
|
+
}
|
|
3347
|
+
/************************************************************
|
|
3150
3348
|
* Programmatic navigation.
|
|
3151
3349
|
*
|
|
3152
3350
|
* Default — PUSH: the user MOVED somewhere new, so change the URL via
|
|
@@ -3402,7 +3600,13 @@ function yui_shell_set_toolbar_item_badge(shell_gobj, item_id, value, tone) {
|
|
|
3402
3600
|
if (!$container) return;
|
|
3403
3601
|
let $badge = $container.querySelector(`[data-toolbar-item-id="${item_id}"] .yui-toolbar-badge`);
|
|
3404
3602
|
if (!$badge) return;
|
|
3603
|
+
let before = $badge.hasAttribute("hidden") ? "" : $badge.textContent;
|
|
3405
3604
|
paint_badge($badge, value, tone);
|
|
3605
|
+
let now = badge_text(value);
|
|
3606
|
+
if (now && now !== before) {
|
|
3607
|
+
let $item = $badge.closest("[data-toolbar-item-id]");
|
|
3608
|
+
announce_badge(shell_gobj, $item && $item.getAttribute("data-i18n-aria-label") || item_id, now);
|
|
3609
|
+
}
|
|
3406
3610
|
}
|
|
3407
3611
|
/************************************************************
|
|
3408
3612
|
* Set (or clear) the badge of a MENU item — the twin of
|
|
@@ -3436,8 +3640,11 @@ function yui_shell_set_nav_item_badge(shell_gobj, item_id, value, tone) {
|
|
|
3436
3640
|
tone = badge_tone(tone, `C_YUI_SHELL: yui_shell_set_nav_item_badge('${item_id}')`);
|
|
3437
3641
|
if (!shell_gobj || !(0, _yuneta_gobj_js.is_gobj)(shell_gobj) || (0, _yuneta_gobj_js.gobj_is_destroying)(shell_gobj) || (0, _yuneta_gobj_js.empty_string)(item_id)) return;
|
|
3438
3642
|
let priv = shell_gobj.priv;
|
|
3439
|
-
|
|
3643
|
+
let item = priv ? nav_item_of(shell_gobj, item_id) : null;
|
|
3644
|
+
if (!item) return;
|
|
3440
3645
|
let badge = value === void 0 ? null : value;
|
|
3646
|
+
let was = priv.nav_badges[item_id];
|
|
3647
|
+
let before = badge_text(was ? was.badge : item.badge);
|
|
3441
3648
|
priv.nav_badges[item_id] = {
|
|
3442
3649
|
badge,
|
|
3443
3650
|
badge_tone: tone
|
|
@@ -3447,6 +3654,8 @@ function yui_shell_set_nav_item_badge(shell_gobj, item_id, value, tone) {
|
|
|
3447
3654
|
badge,
|
|
3448
3655
|
badge_tone: tone
|
|
3449
3656
|
}, shell_gobj);
|
|
3657
|
+
let now = badge_text(badge);
|
|
3658
|
+
if (now && now !== before) announce_badge(shell_gobj, item.name || item_id, now);
|
|
3450
3659
|
}
|
|
3451
3660
|
/************************************************************
|
|
3452
3661
|
* Programmatic close of any open toolbar dropdown. Useful for
|
|
@@ -4050,7 +4259,7 @@ var MOBILE_MAX = 768;
|
|
|
4050
4259
|
***************************************************************/
|
|
4051
4260
|
var attrs_table$21 = [
|
|
4052
4261
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "subscriber", 0, null, "Subscriber of output events"),
|
|
4053
|
-
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$parent", 0, null, "$container will be appended to $parent if not null, else to the
|
|
4262
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$parent", 0, null, "$container will be appended to $parent if not null, else to the window layer of the shell (document.body while there is none), following the shell when it is destroyed or another is built"),
|
|
4054
4263
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "x", 0, "300", "X position"),
|
|
4055
4264
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "y", 0, "100", "Y position"),
|
|
4056
4265
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "width", 0, "700", "Width of the window"),
|
|
@@ -4086,7 +4295,11 @@ var attrs_table$21 = [
|
|
|
4086
4295
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "win_resize_handler", 0, null, "Internal: native window 'resize' listener"),
|
|
4087
4296
|
(0, _yuneta_gobj_js.SDATA_END)()
|
|
4088
4297
|
];
|
|
4089
|
-
var PRIVATE_DATA$21 = {
|
|
4298
|
+
var PRIVATE_DATA$21 = {
|
|
4299
|
+
prevSize: 0,
|
|
4300
|
+
placed_by_shell: false,
|
|
4301
|
+
back_shell: null
|
|
4302
|
+
};
|
|
4090
4303
|
var __gclass__$21 = null;
|
|
4091
4304
|
/******************************
|
|
4092
4305
|
* Framework Methods
|
|
@@ -4101,6 +4314,7 @@ function mt_create$21(gobj) {
|
|
|
4101
4314
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "window_id", window_id);
|
|
4102
4315
|
let manager = resolve_manager(gobj);
|
|
4103
4316
|
build_ui$18(gobj);
|
|
4317
|
+
yui_shell_watch_changes(gobj);
|
|
4104
4318
|
if (manager) {
|
|
4105
4319
|
let $c = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
4106
4320
|
if ($c) $c.addEventListener("pointerdown", function() {
|
|
@@ -4116,7 +4330,16 @@ function mt_create$21(gobj) {
|
|
|
4116
4330
|
title_prefix: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "title_prefix") || "",
|
|
4117
4331
|
icon: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "icon") || ""
|
|
4118
4332
|
}, gobj);
|
|
4119
|
-
} else
|
|
4333
|
+
} else {
|
|
4334
|
+
let $c = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
4335
|
+
if ($c) {
|
|
4336
|
+
yui_shell_raise_window($c);
|
|
4337
|
+
$c.addEventListener("pointerdown", function() {
|
|
4338
|
+
if (!(0, _yuneta_gobj_js.gobj_is_destroying)(gobj)) (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SHOW", {}, gobj);
|
|
4339
|
+
}, true);
|
|
4340
|
+
}
|
|
4341
|
+
if ((0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "back_dismissable")) register_back_overlay(gobj);
|
|
4342
|
+
}
|
|
4120
4343
|
let on_win_resize = function() {
|
|
4121
4344
|
handleResize(gobj);
|
|
4122
4345
|
};
|
|
@@ -4127,13 +4350,15 @@ function mt_create$21(gobj) {
|
|
|
4127
4350
|
* Framework Method: Destroy
|
|
4128
4351
|
***************************************************************/
|
|
4129
4352
|
function mt_destroy$21(gobj) {
|
|
4353
|
+
let priv = gobj.priv;
|
|
4354
|
+
yui_shell_unwatch_changes(gobj);
|
|
4130
4355
|
let manager = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(gobj, "manager");
|
|
4131
4356
|
if (manager) (0, _yuneta_gobj_js.gobj_send_event)(manager, "EV_UNREGISTER_WINDOW", { window: (0, _yuneta_gobj_js.gobj_full_name)(gobj) }, gobj);
|
|
4132
4357
|
let back_overlay = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "back_overlay");
|
|
4133
4358
|
if (back_overlay) {
|
|
4134
|
-
|
|
4135
|
-
if (shell) yui_shell_overlay_dismissed(shell, back_overlay);
|
|
4359
|
+
if (priv.back_shell) yui_shell_overlay_dismissed(priv.back_shell, back_overlay);
|
|
4136
4360
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "back_overlay", null);
|
|
4361
|
+
priv.back_shell = null;
|
|
4137
4362
|
}
|
|
4138
4363
|
let on_win_resize = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "win_resize_handler");
|
|
4139
4364
|
if (on_win_resize) {
|
|
@@ -4545,7 +4770,8 @@ function build_ui$18(gobj) {
|
|
|
4545
4770
|
}
|
|
4546
4771
|
(0, _yuneta_gobj_js.refresh_language)($container, i18next.t);
|
|
4547
4772
|
let $parent = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$parent");
|
|
4548
|
-
|
|
4773
|
+
gobj.priv.placed_by_shell = !$parent;
|
|
4774
|
+
if (!$parent) $parent = window_place(gobj);
|
|
4549
4775
|
$parent.appendChild($container);
|
|
4550
4776
|
if ((0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "openMaximized")) max$2(gobj);
|
|
4551
4777
|
else if (!mobile) {
|
|
@@ -4587,11 +4813,13 @@ function register_back_overlay(gobj) {
|
|
|
4587
4813
|
};
|
|
4588
4814
|
let overlay = yui_shell_register_overlay(shell, function() {
|
|
4589
4815
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "back_overlay", null);
|
|
4816
|
+
gobj.priv.back_shell = null;
|
|
4590
4817
|
const closing = close_window(gobj);
|
|
4591
4818
|
if (closing.state === "vetoed") rearm();
|
|
4592
4819
|
else if (closing.state === "asking") closing.answer.then(rearm);
|
|
4593
4820
|
}, { keep_on_navigate: (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "keep_on_navigate") });
|
|
4594
4821
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "back_overlay", overlay);
|
|
4822
|
+
gobj.priv.back_shell = overlay ? shell : null;
|
|
4595
4823
|
}
|
|
4596
4824
|
/************************************************************
|
|
4597
4825
|
* Ask to close the window. Answers what happened:
|
|
@@ -4633,7 +4861,8 @@ function close_window(gobj) {
|
|
|
4633
4861
|
}
|
|
4634
4862
|
/************************************************************
|
|
4635
4863
|
* Where a window lives when its host names no `$parent`: the
|
|
4636
|
-
*
|
|
4864
|
+
* WINDOW layer of its shell (yui_shell_window_layer()), inside
|
|
4865
|
+
* the overlay layer -- above the content, below the drawer, the
|
|
4637
4866
|
* toolbar's dropdowns, the dialogs and the toasts.
|
|
4638
4867
|
*
|
|
4639
4868
|
* It used to be document.body, and that put every window above
|
|
@@ -4646,14 +4875,17 @@ function close_window(gobj) {
|
|
|
4646
4875
|
* toolbar, any dialog opened with a window on screen, the same.
|
|
4647
4876
|
*
|
|
4648
4877
|
* Inside the layer the dock's z-index still orders the windows
|
|
4649
|
-
* among themselves
|
|
4650
|
-
* the
|
|
4878
|
+
* among themselves, and no number it gives them reaches the
|
|
4879
|
+
* drawer (7.26.31 put them in the overlay layer itself, beside
|
|
4880
|
+
* it). No shell (a page with windows and no shell, or the time
|
|
4881
|
+
* between a logout and the next login): the body.
|
|
4882
|
+
*
|
|
4883
|
+
* The place is the shell's, and a window parented to the app
|
|
4884
|
+
* outlives it: ac_shell_changed() moves it when a shell goes or
|
|
4885
|
+
* comes.
|
|
4651
4886
|
************************************************************/
|
|
4652
|
-
function
|
|
4653
|
-
|
|
4654
|
-
let layers = shell && shell.priv && shell.priv.layers;
|
|
4655
|
-
if (layers && layers.overlay) return layers.overlay;
|
|
4656
|
-
return document.body;
|
|
4887
|
+
function window_place(gobj) {
|
|
4888
|
+
return yui_shell_window_layer(yui_shell_of(gobj)) || document.body;
|
|
4657
4889
|
}
|
|
4658
4890
|
/************************************************************
|
|
4659
4891
|
*
|
|
@@ -4925,8 +5157,7 @@ function ac_show$15(gobj, event, kw, src) {
|
|
|
4925
5157
|
return -1;
|
|
4926
5158
|
}
|
|
4927
5159
|
$container.style.removeProperty("display");
|
|
4928
|
-
|
|
4929
|
-
if ($parent && $parent.lastChild !== $container) $parent.appendChild($container);
|
|
5160
|
+
yui_shell_raise_window($container);
|
|
4930
5161
|
return 0;
|
|
4931
5162
|
}
|
|
4932
5163
|
/************************************************************
|
|
@@ -4943,6 +5174,49 @@ function ac_close(gobj, event, kw, src) {
|
|
|
4943
5174
|
close_window(gobj);
|
|
4944
5175
|
return 0;
|
|
4945
5176
|
}
|
|
5177
|
+
/************************************************************
|
|
5178
|
+
* EV_SHELL_CHANGED -- a shell was built, or is being destroyed
|
|
5179
|
+
* (`src`, then destroying): the place this window lives in may
|
|
5180
|
+
* have gone with it, or be in the new one
|
|
5181
|
+
* (yui_shell_watch_changes()).
|
|
5182
|
+
*
|
|
5183
|
+
* - A window whose host named no `$parent` takes the window place
|
|
5184
|
+
* again: the window layer of the shell that governs it NOW,
|
|
5185
|
+
* document.body while there is none. So the developer window
|
|
5186
|
+
* outlives a logout in the body, and the login's shell takes it
|
|
5187
|
+
* in -- above its content, under its dialogs. From 7.26.31 to
|
|
5188
|
+
* 7.26.34 it stayed in the destroyed shell's layer: alive,
|
|
5189
|
+
* detached, invisible.
|
|
5190
|
+
* - A window its host placed stays where it was put, unless that
|
|
5191
|
+
* element was inside the shell being destroyed: then no place
|
|
5192
|
+
* is left, and it takes the window place from now on.
|
|
5193
|
+
* - Its Back entry, when the shell being destroyed held it, went
|
|
5194
|
+
* with that shell's history and is forgotten. The next shell
|
|
5195
|
+
* does not get one: a history entry pushed while a shell is
|
|
5196
|
+
* still being built would sit under its first route. Back no
|
|
5197
|
+
* longer closes such a window; its ✕ does, as before 7.26.31.
|
|
5198
|
+
************************************************************/
|
|
5199
|
+
function ac_shell_changed$1(gobj, event, kw, src) {
|
|
5200
|
+
let priv = gobj.priv;
|
|
5201
|
+
let going = (0, _yuneta_gobj_js.gobj_is_destroying)(src);
|
|
5202
|
+
if (going && priv.back_shell === src) {
|
|
5203
|
+
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "back_overlay", null);
|
|
5204
|
+
priv.back_shell = null;
|
|
5205
|
+
}
|
|
5206
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
5207
|
+
if (!$container) {
|
|
5208
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: EV_SHELL_CHANGED without a container`);
|
|
5209
|
+
return -1;
|
|
5210
|
+
}
|
|
5211
|
+
if (!priv.placed_by_shell) {
|
|
5212
|
+
let $shell = going ? (0, _yuneta_gobj_js.gobj_read_attr)(src, "$container") : null;
|
|
5213
|
+
if (!$shell || !$shell.contains($container)) return 0;
|
|
5214
|
+
priv.placed_by_shell = true;
|
|
5215
|
+
}
|
|
5216
|
+
let $place = window_place(gobj);
|
|
5217
|
+
if ($container.parentNode !== $place) $place.appendChild($container);
|
|
5218
|
+
return 0;
|
|
5219
|
+
}
|
|
4946
5220
|
/***************************
|
|
4947
5221
|
* FSM
|
|
4948
5222
|
***************************/
|
|
@@ -4978,6 +5252,11 @@ function create_gclass$21(gclass_name) {
|
|
|
4978
5252
|
"EV_CLOSE_WINDOW",
|
|
4979
5253
|
ac_close,
|
|
4980
5254
|
null
|
|
5255
|
+
],
|
|
5256
|
+
[
|
|
5257
|
+
"EV_SHELL_CHANGED",
|
|
5258
|
+
ac_shell_changed$1,
|
|
5259
|
+
null
|
|
4981
5260
|
]
|
|
4982
5261
|
]]];
|
|
4983
5262
|
const event_types = [
|
|
@@ -4987,7 +5266,8 @@ function create_gclass$21(gclass_name) {
|
|
|
4987
5266
|
["EV_REFRESH", 0],
|
|
4988
5267
|
["EV_SHOW", 0],
|
|
4989
5268
|
["EV_HIDE", 0],
|
|
4990
|
-
["EV_CLOSE_WINDOW", 0]
|
|
5269
|
+
["EV_CLOSE_WINDOW", 0],
|
|
5270
|
+
["EV_SHELL_CHANGED", 0]
|
|
4991
5271
|
];
|
|
4992
5272
|
__gclass__$21 = (0, _yuneta_gobj_js.gclass_create)(gclass_name, event_types, states, gmt$21, 0, attrs_table$21, PRIVATE_DATA$21, 0, 0, 0, 0);
|
|
4993
5273
|
if (!__gclass__$21) return -1;
|
|
@@ -5038,6 +5318,7 @@ function register_c_yui_window() {
|
|
|
5038
5318
|
var GCLASS_NAME$20 = "C_YUI_WINDOW_MANAGER";
|
|
5039
5319
|
var DOCK_Z = 1e6;
|
|
5040
5320
|
var WC_X = "<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M4.5 4.5 L11.5 11.5 M11.5 4.5 L4.5 11.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg>";
|
|
5321
|
+
var __chip_seq__ = 0;
|
|
5041
5322
|
/***************************************************************
|
|
5042
5323
|
* Data
|
|
5043
5324
|
***************************************************************/
|
|
@@ -5047,13 +5328,12 @@ var attrs_table$20 = [
|
|
|
5047
5328
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "dock_corner", 0, "bottom-left", "Floating placement: top-left | top-right | bottom-left | bottom-right"),
|
|
5048
5329
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "inline_selector", 0, "", "CSS selector of the container the dock mounts into when inline (e.g. a shell zone)"),
|
|
5049
5330
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "responsive_query", 0, "(max-width: 768px)", "Media query that selects inline placement when dock_mode is 'responsive'"),
|
|
5050
|
-
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$parent", 0, null, "Where the floating dock mounts (default document.body)"),
|
|
5331
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$parent", 0, null, "Where the floating dock mounts (default: the popup layer of the shell, document.body while there is none)"),
|
|
5051
5332
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$container", 0, null, "Internal: the dock element"),
|
|
5052
5333
|
(0, _yuneta_gobj_js.SDATA_END)()
|
|
5053
5334
|
];
|
|
5054
5335
|
var PRIVATE_DATA$20 = {
|
|
5055
5336
|
windows: null,
|
|
5056
|
-
z: 0,
|
|
5057
5337
|
mql: null,
|
|
5058
5338
|
mql_handler: null
|
|
5059
5339
|
};
|
|
@@ -5067,7 +5347,6 @@ var __gclass__$20 = null;
|
|
|
5067
5347
|
function mt_create$20(gobj) {
|
|
5068
5348
|
let priv = gobj.priv;
|
|
5069
5349
|
priv.windows = [];
|
|
5070
|
-
priv.z = 10;
|
|
5071
5350
|
if (((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "dock_mode") || "floating") === "responsive") {
|
|
5072
5351
|
let q = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "responsive_query") || "(max-width: 768px)";
|
|
5073
5352
|
priv.mql = window.matchMedia(q);
|
|
@@ -5077,6 +5356,7 @@ function mt_create$20(gobj) {
|
|
|
5077
5356
|
priv.mql.addEventListener("change", priv.mql_handler);
|
|
5078
5357
|
}
|
|
5079
5358
|
build_dock(gobj);
|
|
5359
|
+
yui_shell_watch_changes(gobj);
|
|
5080
5360
|
const subscriber = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(gobj, "subscriber");
|
|
5081
5361
|
if (subscriber) (0, _yuneta_gobj_js.gobj_subscribe_event)(gobj, null, {}, subscriber);
|
|
5082
5362
|
}
|
|
@@ -5085,6 +5365,7 @@ function mt_create$20(gobj) {
|
|
|
5085
5365
|
***************************************************************/
|
|
5086
5366
|
function mt_destroy$20(gobj) {
|
|
5087
5367
|
let priv = gobj.priv;
|
|
5368
|
+
yui_shell_unwatch_changes(gobj);
|
|
5088
5369
|
if (priv.mql && priv.mql_handler) {
|
|
5089
5370
|
priv.mql.removeEventListener("change", priv.mql_handler);
|
|
5090
5371
|
priv.mql = null;
|
|
@@ -5134,10 +5415,18 @@ function ensure_dock_style() {
|
|
|
5134
5415
|
}
|
|
5135
5416
|
.yui-dock-chip {
|
|
5136
5417
|
display: inline-flex; align-items: center; gap: 7px; font: inherit; font-size: 12px;
|
|
5137
|
-
padding:
|
|
5138
|
-
background: var(--bulma-scheme-main); color: var(--bulma-text);
|
|
5418
|
+
padding: 0 5px 0 0; border: 1px solid var(--bulma-border); border-radius: 7px;
|
|
5419
|
+
background: var(--bulma-scheme-main); color: var(--bulma-text); white-space: nowrap;
|
|
5139
5420
|
}
|
|
5140
5421
|
.yui-dock-chip:hover { border-color: var(--bulma-text-weak); }
|
|
5422
|
+
/* The chip is the look; its toggle a button that adds none, and
|
|
5423
|
+
* takes the pill's padding, so the whole label is what a press lands
|
|
5424
|
+
* on and the chip reads as one pill with its ✕ at the end. */
|
|
5425
|
+
.yui-dock-chip-toggle {
|
|
5426
|
+
display: inline-flex; align-items: center; gap: 7px;
|
|
5427
|
+
padding: 4px 0 4px 11px; margin: 0; border: 0; border-radius: 7px 0 0 7px;
|
|
5428
|
+
background: transparent; font: inherit; color: inherit; cursor: pointer; white-space: nowrap;
|
|
5429
|
+
}
|
|
5141
5430
|
/* The BORDER says active, not the text: blue ink on a blue tint is
|
|
5142
5431
|
* the same hue on itself -- 4.49:1 on the light chip, under the 4.5
|
|
5143
5432
|
* its 12px label needs. The label takes the text colour (11:1). */
|
|
@@ -5227,10 +5516,33 @@ function apply_placement(gobj) {
|
|
|
5227
5516
|
"bottom-left",
|
|
5228
5517
|
"bottom-right"
|
|
5229
5518
|
]) $dock.classList.toggle(`yui-dock--${c}`, !inline && c === corner);
|
|
5230
|
-
let target = inline ? $inline : (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$parent") ||
|
|
5519
|
+
let target = inline ? $inline : (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$parent") || dock_place(gobj);
|
|
5231
5520
|
if ($dock.parentNode !== target) target.appendChild($dock);
|
|
5232
5521
|
}
|
|
5233
5522
|
/************************************************************
|
|
5523
|
+
* Where the FLOATING dock lives when the app names no
|
|
5524
|
+
* `$parent`: the popup layer of the shell, at the top of it.
|
|
5525
|
+
*
|
|
5526
|
+
* It was document.body at z-index 1000000, and that put it
|
|
5527
|
+
* above the WHOLE shell -- `.yui-shell` is a stacking context
|
|
5528
|
+
* of its own, so its dialogs (modal layer, 99) and toasts (120)
|
|
5529
|
+
* counted only inside it: the dock stayed clickable over a
|
|
5530
|
+
* dialog's backdrop (a window could be closed from its chip
|
|
5531
|
+
* while its own "all changes will be lost" question was open),
|
|
5532
|
+
* and it covered a toast where they met.
|
|
5533
|
+
*
|
|
5534
|
+
* The popup layer, not the window layer: the dock has to stay
|
|
5535
|
+
* above EVERY window, and windows live in two layers -- the
|
|
5536
|
+
* window layer (no `$parent`) and the popup layer, where the
|
|
5537
|
+
* site map and the JSON windows of the treedb views put theirs.
|
|
5538
|
+
* Above both; below the dialogs, the toasts and the loading
|
|
5539
|
+
* cover. No shell (before the first, between a logout and the
|
|
5540
|
+
* next login): the body.
|
|
5541
|
+
************************************************************/
|
|
5542
|
+
function dock_place(gobj) {
|
|
5543
|
+
return yui_shell_popup_layer(yui_shell_of(gobj)) || document.body;
|
|
5544
|
+
}
|
|
5545
|
+
/************************************************************
|
|
5234
5546
|
* Destroy the dock element.
|
|
5235
5547
|
************************************************************/
|
|
5236
5548
|
function destroy_dock(gobj) {
|
|
@@ -5307,7 +5619,6 @@ function set_active(gobj, entry) {
|
|
|
5307
5619
|
* Bring a window to front and mark it active/visible.
|
|
5308
5620
|
************************************************************/
|
|
5309
5621
|
function focus_entry(gobj, entry) {
|
|
5310
|
-
let priv = gobj.priv;
|
|
5311
5622
|
let $win = (0, _yuneta_gobj_js.gobj_read_attr)(entry.gobj, "$container");
|
|
5312
5623
|
if ($win) {
|
|
5313
5624
|
if (entry.minimized) {
|
|
@@ -5315,8 +5626,7 @@ function focus_entry(gobj, entry) {
|
|
|
5315
5626
|
entry.minimized = false;
|
|
5316
5627
|
if (entry.$chip) entry.$chip.classList.remove("is-min");
|
|
5317
5628
|
}
|
|
5318
|
-
|
|
5319
|
-
$win.style.zIndex = priv.z;
|
|
5629
|
+
yui_shell_raise_window($win);
|
|
5320
5630
|
}
|
|
5321
5631
|
set_active(gobj, entry);
|
|
5322
5632
|
}
|
|
@@ -5383,57 +5693,57 @@ function ac_register_window(gobj, event, kw, src) {
|
|
|
5383
5693
|
{ class: "yui-dock-label-kind" },
|
|
5384
5694
|
text_node(title)
|
|
5385
5695
|
]);
|
|
5696
|
+
let chip_seq = ++__chip_seq__;
|
|
5697
|
+
let label_ids = label_items.map(function(item, i) {
|
|
5698
|
+
item[1].id = `yui-dock-chip-${chip_seq}-${i}`;
|
|
5699
|
+
return item[1].id;
|
|
5700
|
+
});
|
|
5386
5701
|
let entry = {
|
|
5387
5702
|
gobj: win,
|
|
5388
5703
|
$chip: null,
|
|
5389
5704
|
minimized: false
|
|
5390
5705
|
};
|
|
5706
|
+
let window_name = (0, _yuneta_gobj_js.gobj_full_name)(win);
|
|
5391
5707
|
let $chip = (0, _yuneta_gobj_js.createElement2)([
|
|
5392
5708
|
"div",
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5709
|
+
{ class: "DOCK_CHIP yui-dock-chip" },
|
|
5710
|
+
[[
|
|
5711
|
+
"button",
|
|
5712
|
+
Object.assign({
|
|
5713
|
+
class: "DOCK_CHIP_TOGGLE yui-dock-chip-toggle",
|
|
5714
|
+
type: "button",
|
|
5715
|
+
title,
|
|
5716
|
+
"aria-label": title,
|
|
5717
|
+
"aria-labelledby": label_ids.join(" ")
|
|
5718
|
+
}, !prefix && title_key ? {
|
|
5719
|
+
"data-i18n-title": title_key,
|
|
5720
|
+
"data-i18n-aria-label": title_key
|
|
5721
|
+
} : {}),
|
|
5722
|
+
[chip_lead(kw.icon), [
|
|
5402
5723
|
"span",
|
|
5403
5724
|
{ class: "yui-dock-label" },
|
|
5404
5725
|
label_items
|
|
5405
|
-
],
|
|
5406
|
-
|
|
5407
|
-
"button",
|
|
5408
|
-
{
|
|
5409
|
-
class: "yui-dock-close",
|
|
5410
|
-
type: "button",
|
|
5411
|
-
title: (0, i18next.t)("close"),
|
|
5412
|
-
"data-i18n-title": "close",
|
|
5413
|
-
"aria-label": (0, i18next.t)("close"),
|
|
5414
|
-
"data-i18n-aria-label": "close"
|
|
5415
|
-
},
|
|
5416
|
-
(0, _yuneta_gobj_js.html_markup)(WC_X),
|
|
5417
|
-
{ click: (evt) => {
|
|
5418
|
-
evt.stopPropagation();
|
|
5419
|
-
(0, _yuneta_gobj_js.gobj_send_event)(entry.gobj, "EV_CLOSE_WINDOW", {}, gobj);
|
|
5420
|
-
} }
|
|
5421
|
-
]
|
|
5422
|
-
],
|
|
5423
|
-
{
|
|
5424
|
-
click: (evt) => {
|
|
5726
|
+
]],
|
|
5727
|
+
{ click: (evt) => {
|
|
5425
5728
|
evt.stopPropagation();
|
|
5426
|
-
|
|
5729
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_WINDOW", { window: window_name }, gobj);
|
|
5730
|
+
} }
|
|
5731
|
+
], [
|
|
5732
|
+
"button",
|
|
5733
|
+
{
|
|
5734
|
+
class: "DOCK_CHIP_CLOSE yui-dock-close",
|
|
5735
|
+
type: "button",
|
|
5736
|
+
title: (0, i18next.t)("close"),
|
|
5737
|
+
"data-i18n-title": "close",
|
|
5738
|
+
"aria-label": (0, i18next.t)("close"),
|
|
5739
|
+
"data-i18n-aria-label": "close"
|
|
5427
5740
|
},
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
}
|
|
5435
|
-
}
|
|
5436
|
-
}
|
|
5741
|
+
(0, _yuneta_gobj_js.html_markup)(WC_X),
|
|
5742
|
+
{ click: (evt) => {
|
|
5743
|
+
evt.stopPropagation();
|
|
5744
|
+
(0, _yuneta_gobj_js.gobj_send_event)(entry.gobj, "EV_CLOSE_WINDOW", {}, gobj);
|
|
5745
|
+
} }
|
|
5746
|
+
]]
|
|
5437
5747
|
]);
|
|
5438
5748
|
entry.$chip = $chip;
|
|
5439
5749
|
priv.windows.push(entry);
|
|
@@ -5477,6 +5787,41 @@ function ac_focus_window(gobj, event, kw, src) {
|
|
|
5477
5787
|
if (entry) focus_entry(gobj, entry);
|
|
5478
5788
|
return 0;
|
|
5479
5789
|
}
|
|
5790
|
+
/************************************************************
|
|
5791
|
+
* EV_TOGGLE_WINDOW { window } -- the toggle of a chip of THIS
|
|
5792
|
+
* dock was pressed: bring a minimized or covered window to the
|
|
5793
|
+
* front, send the one in front to the dock. Only the dock's own
|
|
5794
|
+
* chip sends it (src is the dock): the events a window sends
|
|
5795
|
+
* about itself come from the window, and this one from the chip
|
|
5796
|
+
* that names it.
|
|
5797
|
+
************************************************************/
|
|
5798
|
+
function ac_toggle_window(gobj, event, kw, src) {
|
|
5799
|
+
let priv = gobj.priv;
|
|
5800
|
+
if (src !== gobj) {
|
|
5801
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} comes from the dock's own chip, not from ${(0, _yuneta_gobj_js.is_gobj)(src) ? (0, _yuneta_gobj_js.gobj_full_name)(src) : String(src)}`);
|
|
5802
|
+
return -1;
|
|
5803
|
+
}
|
|
5804
|
+
let name = kw && kw.window;
|
|
5805
|
+
let entry = priv.windows.find((e) => (0, _yuneta_gobj_js.gobj_full_name)(e.gobj) === name);
|
|
5806
|
+
if (!entry) {
|
|
5807
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event}: no window '${name}' in the dock`);
|
|
5808
|
+
return -1;
|
|
5809
|
+
}
|
|
5810
|
+
on_chip_click(gobj, entry);
|
|
5811
|
+
return 0;
|
|
5812
|
+
}
|
|
5813
|
+
/************************************************************
|
|
5814
|
+
* EV_SHELL_CHANGED -- a shell was built, or is being destroyed
|
|
5815
|
+
* (yui_shell_watch_changes()). The dock's place -- the shell's
|
|
5816
|
+
* popup layer, or its zone when inline -- may have gone with
|
|
5817
|
+
* it, or be in the new one: place it again. Up to 7.26.34 an
|
|
5818
|
+
* inline dock stayed in the destroyed shell's zone after a
|
|
5819
|
+
* logout, detached, until a window registered.
|
|
5820
|
+
************************************************************/
|
|
5821
|
+
function ac_shell_changed(gobj, event, kw, src) {
|
|
5822
|
+
apply_placement(gobj);
|
|
5823
|
+
return 0;
|
|
5824
|
+
}
|
|
5480
5825
|
/***************************
|
|
5481
5826
|
* FSM
|
|
5482
5827
|
***************************/
|
|
@@ -5496,7 +5841,9 @@ function create_gclass$20(gclass_name) {
|
|
|
5496
5841
|
["EV_REGISTER_WINDOW", 0],
|
|
5497
5842
|
["EV_UNREGISTER_WINDOW", 0],
|
|
5498
5843
|
["EV_MINIMIZE_WINDOW", 0],
|
|
5499
|
-
["EV_FOCUS_WINDOW", 0]
|
|
5844
|
+
["EV_FOCUS_WINDOW", 0],
|
|
5845
|
+
["EV_TOGGLE_WINDOW", 0],
|
|
5846
|
+
["EV_SHELL_CHANGED", 0]
|
|
5500
5847
|
], [["ST_IDLE", [
|
|
5501
5848
|
[
|
|
5502
5849
|
"EV_REGISTER_WINDOW",
|
|
@@ -5517,6 +5864,16 @@ function create_gclass$20(gclass_name) {
|
|
|
5517
5864
|
"EV_FOCUS_WINDOW",
|
|
5518
5865
|
ac_focus_window,
|
|
5519
5866
|
null
|
|
5867
|
+
],
|
|
5868
|
+
[
|
|
5869
|
+
"EV_TOGGLE_WINDOW",
|
|
5870
|
+
ac_toggle_window,
|
|
5871
|
+
null
|
|
5872
|
+
],
|
|
5873
|
+
[
|
|
5874
|
+
"EV_SHELL_CHANGED",
|
|
5875
|
+
ac_shell_changed,
|
|
5876
|
+
null
|
|
5520
5877
|
]
|
|
5521
5878
|
]]], gmt$20, 0, attrs_table$20, PRIVATE_DATA$20, 0, 0, 0, 0);
|
|
5522
5879
|
if (!__gclass__$20) return -1;
|
|
@@ -6796,6 +7153,41 @@ function yui_tabulator_name_row_selects(table, t) {
|
|
|
6796
7153
|
}
|
|
6797
7154
|
} catch (e) {}
|
|
6798
7155
|
}
|
|
7156
|
+
/***************************************************************
|
|
7157
|
+
* Name the EDITOR of an editable column: the box Tabulator draws
|
|
7158
|
+
* in a cell while it is edited (input, number, textarea, list,
|
|
7159
|
+
* tickCross, date...).
|
|
7160
|
+
*
|
|
7161
|
+
* Tabulator gives it nothing -- no label, no aria-label, no title
|
|
7162
|
+
* -- so a reader lands in an anonymous edit box. Its name is the
|
|
7163
|
+
* column's: a cell is edited under its column's title. Asked at
|
|
7164
|
+
* the MOMENT of editing: Tabulator takes `editorParams` as a
|
|
7165
|
+
* function of the cell, and every built-in editor writes the
|
|
7166
|
+
* `elementAttributes` it answers onto the element it draws. So
|
|
7167
|
+
* the name is in the language of that moment, with nothing to
|
|
7168
|
+
* re-apply after a language change or a rebuild of the columns
|
|
7169
|
+
* -- the twin of the header filters above, which have to be
|
|
7170
|
+
* renamed after every render.
|
|
7171
|
+
*
|
|
7172
|
+
* `name_of(cell)` answers the column's title, TRANSLATED (the
|
|
7173
|
+
* view's own label: a cascade, a schema header); "" names
|
|
7174
|
+
* nothing. What `editorParams` the column had is kept, its own
|
|
7175
|
+
* `elementAttributes` too; a name it set itself wins.
|
|
7176
|
+
***************************************************************/
|
|
7177
|
+
function yui_tabulator_name_editor(column_def, name_of) {
|
|
7178
|
+
if (!column_def || !column_def.editor || typeof name_of !== "function") return;
|
|
7179
|
+
let base = column_def.editorParams;
|
|
7180
|
+
column_def.editorParams = function(cell) {
|
|
7181
|
+
let params = typeof base === "function" ? base(cell) : base || {};
|
|
7182
|
+
let name = name_of(cell);
|
|
7183
|
+
if (!name) return params;
|
|
7184
|
+
let attrs = Object.assign({
|
|
7185
|
+
"aria-label": name,
|
|
7186
|
+
title: name
|
|
7187
|
+
}, params.elementAttributes || {});
|
|
7188
|
+
return Object.assign({}, params, { elementAttributes: attrs });
|
|
7189
|
+
};
|
|
7190
|
+
}
|
|
6799
7191
|
function yui_tabulator_relocalize(table, t) {
|
|
6800
7192
|
if (!table) return;
|
|
6801
7193
|
try {
|
|
@@ -7316,6 +7708,7 @@ function yui_file_control(gobj, { name, value, readonly, accept, on_pick }) {
|
|
|
7316
7708
|
{
|
|
7317
7709
|
type: "button",
|
|
7318
7710
|
class: "FILE_PICK button is-small",
|
|
7711
|
+
title: (0, i18next.t)("choose a file"),
|
|
7319
7712
|
"data-i18n-title": "choose a file",
|
|
7320
7713
|
"aria-label": (0, i18next.t)("choose a file"),
|
|
7321
7714
|
"data-i18n-aria-label": "choose a file"
|
|
@@ -7334,6 +7727,7 @@ function yui_file_control(gobj, { name, value, readonly, accept, on_pick }) {
|
|
|
7334
7727
|
{
|
|
7335
7728
|
type: "button",
|
|
7336
7729
|
class: "FILE_CLEAR button is-small",
|
|
7730
|
+
title: (0, i18next.t)("remove the file"),
|
|
7337
7731
|
"data-i18n-title": "remove the file",
|
|
7338
7732
|
"aria-label": (0, i18next.t)("remove the file"),
|
|
7339
7733
|
"data-i18n-aria-label": "remove the file"
|
|
@@ -8682,6 +9076,293 @@ function json_editor_value(content) {
|
|
|
8682
9076
|
return JSON.stringify(content.json);
|
|
8683
9077
|
}
|
|
8684
9078
|
//#endregion
|
|
9079
|
+
//#region src/form_json_editor_names.js
|
|
9080
|
+
/***********************************************************************
|
|
9081
|
+
* form_json_editor_names.js
|
|
9082
|
+
*
|
|
9083
|
+
* The NAMES of the buttons vanilla-jsoneditor draws in its menu
|
|
9084
|
+
* (a json field of C_YUI_FORM): in the app's language, and with an
|
|
9085
|
+
* aria-label.
|
|
9086
|
+
*
|
|
9087
|
+
* The editor draws them itself, in English, with a `title` and
|
|
9088
|
+
* nothing else: "Format JSON: add proper indentation and new lines
|
|
9089
|
+
* (Ctrl+I)", "Undo (Ctrl+Z)", and three mode buttons whose text is
|
|
9090
|
+
* "text", "tree" and "table" (REV-CLOUD V23.5.6). Two hooks reach
|
|
9091
|
+
* them, and both are needed:
|
|
9092
|
+
*
|
|
9093
|
+
* - json_editor_menu_items(), the editor's `onRenderMenu`: the
|
|
9094
|
+
* items it is about to draw, with each title translated (its
|
|
9095
|
+
* shortcut kept) and the mode buttons' text too. Svelte draws
|
|
9096
|
+
* from these, so a button born in a re-render is born named.
|
|
9097
|
+
* - name_json_editor_menu(), after the render, from the form's
|
|
9098
|
+
* FSM: the aria-label of each button, with its key, so
|
|
9099
|
+
* refresh_language() re-translates it, and the state of the
|
|
9100
|
+
* mode buttons (aria-pressed). A menu item has no field for
|
|
9101
|
+
* either.
|
|
9102
|
+
*
|
|
9103
|
+
* A button is known by the CLASS the editor gives it (`jse-format`,
|
|
9104
|
+
* `jse-undo`...), never by its English title: a class is what the
|
|
9105
|
+
* editor's own stylesheet relies on. A button not listed here keeps
|
|
9106
|
+
* the editor's words.
|
|
9107
|
+
*
|
|
9108
|
+
* Its CONTEXT MENU (`onRenderContextMenu`,
|
|
9109
|
+
* json_editor_context_menu_items()) has no class on its items, so
|
|
9110
|
+
* an item is known by what it IS and where it IS: the icon the
|
|
9111
|
+
* editor draws it with (a FontAwesome name: `paste`, `scissors`),
|
|
9112
|
+
* the column of the menu it stands in, its place in a dropdown
|
|
9113
|
+
* (the main button, the first or the second of its list), the
|
|
9114
|
+
* mode of the editor (tree or table) -- never by its words. Its
|
|
9115
|
+
* text and title go back translated; after the render the same
|
|
9116
|
+
* pass names its buttons, and the arrow of each dropdown, which
|
|
9117
|
+
* the editor draws with no name at all.
|
|
9118
|
+
*
|
|
9119
|
+
* Not reached, because the editor gives them no hook: its search
|
|
9120
|
+
* box, its repair messages, the tip at the foot of the context
|
|
9121
|
+
* menu, and its modals (sort, transform). They stay in its
|
|
9122
|
+
* English.
|
|
9123
|
+
*
|
|
9124
|
+
* Copyright (c) 2026, ArtGins.
|
|
9125
|
+
* All Rights Reserved.
|
|
9126
|
+
***********************************************************************/
|
|
9127
|
+
/***************************************************************
|
|
9128
|
+
* Constants
|
|
9129
|
+
***************************************************************/
|
|
9130
|
+
var JSON_EDITOR_BUTTON_KEYS = {
|
|
9131
|
+
"jse-expand-all": "expand all",
|
|
9132
|
+
"jse-collapse-all": "collapse all",
|
|
9133
|
+
"jse-search": "search",
|
|
9134
|
+
"jse-copy": "copy",
|
|
9135
|
+
"jse-undo": "undo",
|
|
9136
|
+
"jse-redo": "redo",
|
|
9137
|
+
"jse-cancel": "cancel",
|
|
9138
|
+
"jse-format": "format json",
|
|
9139
|
+
"jse-compact": "compact json",
|
|
9140
|
+
"jse-sort": "sort",
|
|
9141
|
+
"jse-transform": "transform",
|
|
9142
|
+
"jse-contextmenu": "open context menu"
|
|
9143
|
+
};
|
|
9144
|
+
var JSON_EDITOR_MODE_NAME_KEYS = {
|
|
9145
|
+
text: "text view",
|
|
9146
|
+
tree: "tree view",
|
|
9147
|
+
table: "table view"
|
|
9148
|
+
};
|
|
9149
|
+
var JSON_EDITOR_MODE_TEXT_KEYS = {
|
|
9150
|
+
text: "text mode",
|
|
9151
|
+
tree: "tree mode",
|
|
9152
|
+
table: "table mode"
|
|
9153
|
+
};
|
|
9154
|
+
var MODE_CLASS = "yui-jse-mode-";
|
|
9155
|
+
var SHORTCUT = /\((?:Ctrl|Cmd|⌘)[^()]*\)\s*$/;
|
|
9156
|
+
var CONTEXT_BUTTON_KEYS = {
|
|
9157
|
+
"pen": "edit key",
|
|
9158
|
+
"paste": "paste",
|
|
9159
|
+
"clone": "duplicate",
|
|
9160
|
+
"crop-simple": "extract",
|
|
9161
|
+
"arrow-down-short-wide": "sort",
|
|
9162
|
+
"filter": "transform",
|
|
9163
|
+
"trash-can": "remove",
|
|
9164
|
+
"square-caret-up": "insert before",
|
|
9165
|
+
"square-caret-down": "insert after"
|
|
9166
|
+
};
|
|
9167
|
+
var CONTEXT_ROW_BUTTON_KEYS = {
|
|
9168
|
+
"pen": "edit row",
|
|
9169
|
+
"clone": "duplicate row",
|
|
9170
|
+
"trash-can": "remove row"
|
|
9171
|
+
};
|
|
9172
|
+
var CONTEXT_DROPDOWN_MAIN_KEYS = {
|
|
9173
|
+
"pen": "edit value",
|
|
9174
|
+
"scissors": "cut",
|
|
9175
|
+
"copy": "copy"
|
|
9176
|
+
};
|
|
9177
|
+
var CONTEXT_DROPDOWN_FIRST_KEYS = {
|
|
9178
|
+
"pen": "edit value",
|
|
9179
|
+
"scissors": "cut formatted",
|
|
9180
|
+
"copy": "copy formatted"
|
|
9181
|
+
};
|
|
9182
|
+
var CONTEXT_DROPDOWN_SECOND_KEYS = {
|
|
9183
|
+
"pen": "enforce string",
|
|
9184
|
+
"scissors": "cut compacted",
|
|
9185
|
+
"copy": "copy compacted"
|
|
9186
|
+
};
|
|
9187
|
+
var CONTEXT_TARGET_KEYS = {
|
|
9188
|
+
"0": "structure",
|
|
9189
|
+
"1": "object",
|
|
9190
|
+
"2": "array",
|
|
9191
|
+
"3": "value"
|
|
9192
|
+
};
|
|
9193
|
+
var TARGET_ICONS = ["arrow-right-arrow-left", "plus"];
|
|
9194
|
+
var CONTEXT_LABEL_KEYS = {
|
|
9195
|
+
convert: "convert to",
|
|
9196
|
+
insert: "insert",
|
|
9197
|
+
cell: "table cell",
|
|
9198
|
+
row: "table row"
|
|
9199
|
+
};
|
|
9200
|
+
/***************************
|
|
9201
|
+
* Local Methods
|
|
9202
|
+
***************************/
|
|
9203
|
+
function has_key(table, name) {
|
|
9204
|
+
return Object.prototype.hasOwnProperty.call(table, name);
|
|
9205
|
+
}
|
|
9206
|
+
function button_class(classes) {
|
|
9207
|
+
return (Array.isArray(classes) ? classes : String(classes || "").split(/\s+/)).find((c) => has_key(JSON_EDITOR_BUTTON_KEYS, c)) || "";
|
|
9208
|
+
}
|
|
9209
|
+
function mode_of_item(item) {
|
|
9210
|
+
if (String(item.className || "").split(/\s+/).indexOf("jse-group-button") < 0) return "";
|
|
9211
|
+
return has_key(JSON_EDITOR_MODE_NAME_KEYS, item.text) ? item.text : "";
|
|
9212
|
+
}
|
|
9213
|
+
function icon_of(item) {
|
|
9214
|
+
return item && item.icon && typeof item.icon.iconName === "string" ? item.icon.iconName : "";
|
|
9215
|
+
}
|
|
9216
|
+
function named_item(item, name) {
|
|
9217
|
+
let m = SHORTCUT.exec(String(item.title || ""));
|
|
9218
|
+
return Object.assign({}, item, {
|
|
9219
|
+
text: name,
|
|
9220
|
+
title: m ? `${name} ${m[0].trim()}` : name
|
|
9221
|
+
});
|
|
9222
|
+
}
|
|
9223
|
+
function context_dropdown(item) {
|
|
9224
|
+
let icon = icon_of(item.main);
|
|
9225
|
+
if (!has_key(CONTEXT_DROPDOWN_MAIN_KEYS, icon)) return item;
|
|
9226
|
+
let list = Array.isArray(item.items) ? item.items : [];
|
|
9227
|
+
return Object.assign({}, item, {
|
|
9228
|
+
main: named_item(item.main, (0, i18next.t)(CONTEXT_DROPDOWN_MAIN_KEYS[icon])),
|
|
9229
|
+
items: list.map(function(it, i) {
|
|
9230
|
+
if (!it || it.type !== "button") return it;
|
|
9231
|
+
if (i === 0) return named_item(it, (0, i18next.t)(CONTEXT_DROPDOWN_FIRST_KEYS[icon]));
|
|
9232
|
+
if (i === 1) return named_item(it, (0, i18next.t)(CONTEXT_DROPDOWN_SECOND_KEYS[icon]));
|
|
9233
|
+
return it;
|
|
9234
|
+
})
|
|
9235
|
+
});
|
|
9236
|
+
}
|
|
9237
|
+
function context_button(item, row_column) {
|
|
9238
|
+
let icon = icon_of(item);
|
|
9239
|
+
if (row_column && has_key(CONTEXT_ROW_BUTTON_KEYS, icon)) return named_item(item, (0, i18next.t)(CONTEXT_ROW_BUTTON_KEYS[icon]));
|
|
9240
|
+
if (has_key(CONTEXT_BUTTON_KEYS, icon)) return named_item(item, (0, i18next.t)(CONTEXT_BUTTON_KEYS[icon]));
|
|
9241
|
+
return item;
|
|
9242
|
+
}
|
|
9243
|
+
function context_column(item, table, index) {
|
|
9244
|
+
let list = Array.isArray(item.items) ? item.items : [];
|
|
9245
|
+
let buttons = list.filter((it) => it && it.type === "button");
|
|
9246
|
+
let targets = !table && buttons.length > 0 && buttons.every((it) => TARGET_ICONS.indexOf(icon_of(it)) >= 0);
|
|
9247
|
+
let row_column = table && index === 1;
|
|
9248
|
+
let label_kind = "";
|
|
9249
|
+
if (table) label_kind = index === 0 ? "cell" : index === 1 ? "row" : "";
|
|
9250
|
+
else if (targets) label_kind = icon_of(buttons[0]) === "plus" ? "insert" : "convert";
|
|
9251
|
+
let target = 0;
|
|
9252
|
+
let insert_row = 0;
|
|
9253
|
+
return Object.assign({}, item, { items: list.map(function(it) {
|
|
9254
|
+
if (!it || typeof it !== "object") return it;
|
|
9255
|
+
if (it.type === "label") return label_kind ? Object.assign({}, it, { text: (0, i18next.t)(CONTEXT_LABEL_KEYS[label_kind]) }) : it;
|
|
9256
|
+
if (it.type === "dropdown-button") return context_dropdown(it);
|
|
9257
|
+
if (it.type !== "button") return it;
|
|
9258
|
+
if (targets) return named_item(it, (0, i18next.t)(CONTEXT_TARGET_KEYS[String(target++)]));
|
|
9259
|
+
if (row_column && icon_of(it) === "plus") return named_item(it, (0, i18next.t)(insert_row++ === 0 ? CONTEXT_BUTTON_KEYS["square-caret-up"] : CONTEXT_BUTTON_KEYS["square-caret-down"]));
|
|
9260
|
+
return context_button(it, row_column);
|
|
9261
|
+
}) });
|
|
9262
|
+
}
|
|
9263
|
+
function context_item(item, table) {
|
|
9264
|
+
if (!item || typeof item !== "object") return item;
|
|
9265
|
+
if (item.type === "row") {
|
|
9266
|
+
let column = 0;
|
|
9267
|
+
let list = Array.isArray(item.items) ? item.items : [];
|
|
9268
|
+
return Object.assign({}, item, { items: list.map(function(it) {
|
|
9269
|
+
if (it && it.type === "column") return context_column(it, table, column++);
|
|
9270
|
+
return context_item(it, table);
|
|
9271
|
+
}) });
|
|
9272
|
+
}
|
|
9273
|
+
if (item.type === "dropdown-button") return context_dropdown(item);
|
|
9274
|
+
if (item.type === "button") return context_button(item, false);
|
|
9275
|
+
return item;
|
|
9276
|
+
}
|
|
9277
|
+
function mode_of_button($b) {
|
|
9278
|
+
for (let c of $b.classList) if (c.indexOf(MODE_CLASS) === 0) {
|
|
9279
|
+
let mode = c.slice(13);
|
|
9280
|
+
if (has_key(JSON_EDITOR_MODE_NAME_KEYS, mode)) return mode;
|
|
9281
|
+
}
|
|
9282
|
+
return "";
|
|
9283
|
+
}
|
|
9284
|
+
/***************************
|
|
9285
|
+
* Public
|
|
9286
|
+
***************************/
|
|
9287
|
+
/************************************************************
|
|
9288
|
+
* The editor's `onRenderMenu`: the items it is about to draw,
|
|
9289
|
+
* translated. A title keeps the editor's shortcut after the
|
|
9290
|
+
* translated name ("Deshacer (Ctrl+Z)"); a mode button gets its
|
|
9291
|
+
* mode's name as title and its short text translated, and a class
|
|
9292
|
+
* that says its mode. Anything else is returned as it came.
|
|
9293
|
+
*
|
|
9294
|
+
* Pure: what it answers is data for the editor to draw.
|
|
9295
|
+
************************************************************/
|
|
9296
|
+
function json_editor_menu_items(items) {
|
|
9297
|
+
if (!Array.isArray(items)) return items;
|
|
9298
|
+
return items.map(function(item) {
|
|
9299
|
+
if (!item || item.type !== "button") return item;
|
|
9300
|
+
let mode = mode_of_item(item);
|
|
9301
|
+
if (mode) return Object.assign({}, item, {
|
|
9302
|
+
className: `${item.className} ${MODE_CLASS}${mode}`,
|
|
9303
|
+
title: (0, i18next.t)(JSON_EDITOR_MODE_NAME_KEYS[mode]),
|
|
9304
|
+
text: (0, i18next.t)(JSON_EDITOR_MODE_TEXT_KEYS[mode])
|
|
9305
|
+
});
|
|
9306
|
+
let cls = button_class(item.className);
|
|
9307
|
+
if (!cls) return item;
|
|
9308
|
+
let m = SHORTCUT.exec(String(item.title || ""));
|
|
9309
|
+
let name = (0, i18next.t)(JSON_EDITOR_BUTTON_KEYS[cls]);
|
|
9310
|
+
return Object.assign({}, item, { title: m ? `${name} ${m[0].trim()}` : name });
|
|
9311
|
+
});
|
|
9312
|
+
}
|
|
9313
|
+
/************************************************************
|
|
9314
|
+
* The editor's `onRenderContextMenu`: the items it is about to
|
|
9315
|
+
* draw, translated -- each known by its icon and its place, never
|
|
9316
|
+
* by its words (context_item()). Anything the module does not
|
|
9317
|
+
* know comes back as it came: a newer editor that moves an item
|
|
9318
|
+
* leaves it in English, it does not mislabel it.
|
|
9319
|
+
*
|
|
9320
|
+
* Pure: what it answers is data for the editor to draw.
|
|
9321
|
+
************************************************************/
|
|
9322
|
+
function json_editor_context_menu_items(items, context) {
|
|
9323
|
+
if (!Array.isArray(items)) return items;
|
|
9324
|
+
let table = !!(context && context.mode === "table");
|
|
9325
|
+
return items.map((item) => context_item(item, table));
|
|
9326
|
+
}
|
|
9327
|
+
/************************************************************
|
|
9328
|
+
* Name the buttons of a rendered editor's menu: an aria-label
|
|
9329
|
+
* with its key (data-i18n-aria-label, so a language change
|
|
9330
|
+
* reaches it), and aria-pressed on the mode buttons -- the
|
|
9331
|
+
* selected one is the mode on screen (`jse-selected`). Run
|
|
9332
|
+
* after every render of the menu: a re-render may draw new
|
|
9333
|
+
* buttons, which carry none of it.
|
|
9334
|
+
************************************************************/
|
|
9335
|
+
function name_json_editor_menu($editor) {
|
|
9336
|
+
if (!$editor || typeof $editor.querySelectorAll !== "function") return 0;
|
|
9337
|
+
let named = 0;
|
|
9338
|
+
for (let $b of $editor.querySelectorAll(".jse-menu button")) {
|
|
9339
|
+
let mode = mode_of_button($b);
|
|
9340
|
+
const key = mode ? JSON_EDITOR_MODE_NAME_KEYS[mode] : JSON_EDITOR_BUTTON_KEYS[button_class([...$b.classList])];
|
|
9341
|
+
if (!key) continue;
|
|
9342
|
+
$b.setAttribute("aria-label", (0, i18next.t)(key));
|
|
9343
|
+
$b.setAttribute("data-i18n-aria-label", key);
|
|
9344
|
+
if (mode) $b.setAttribute("aria-pressed", $b.classList.contains("jse-selected") ? "true" : "false");
|
|
9345
|
+
named++;
|
|
9346
|
+
}
|
|
9347
|
+
const MORE = "more options";
|
|
9348
|
+
for (let $b of $editor.querySelectorAll("div.jse-contextmenu button")) {
|
|
9349
|
+
if ($b.getAttribute("data-type") === "jse-open-dropdown") {
|
|
9350
|
+
$b.setAttribute("title", (0, i18next.t)(MORE));
|
|
9351
|
+
$b.setAttribute("data-i18n-title", MORE);
|
|
9352
|
+
$b.setAttribute("aria-label", (0, i18next.t)(MORE));
|
|
9353
|
+
$b.setAttribute("data-i18n-aria-label", MORE);
|
|
9354
|
+
named++;
|
|
9355
|
+
continue;
|
|
9356
|
+
}
|
|
9357
|
+
let text = ($b.textContent || "").trim();
|
|
9358
|
+
if (text) {
|
|
9359
|
+
$b.setAttribute("aria-label", text);
|
|
9360
|
+
named++;
|
|
9361
|
+
}
|
|
9362
|
+
}
|
|
9363
|
+
return named;
|
|
9364
|
+
}
|
|
9365
|
+
//#endregion
|
|
8685
9366
|
//#region src/c_yui_form.js
|
|
8686
9367
|
/***********************************************************************
|
|
8687
9368
|
* c_yui_form.js
|
|
@@ -8731,7 +9412,9 @@ var attrs_table$17 = [
|
|
|
8731
9412
|
var PRIVATE_DATA$17 = {
|
|
8732
9413
|
rearm_timer: null,
|
|
8733
9414
|
tables: null,
|
|
8734
|
-
table_seq: 0
|
|
9415
|
+
table_seq: 0,
|
|
9416
|
+
json_names_posted: false,
|
|
9417
|
+
lang_shell: null
|
|
8735
9418
|
};
|
|
8736
9419
|
var __gclass__$17 = null;
|
|
8737
9420
|
/***************************
|
|
@@ -8762,13 +9445,23 @@ function mt_destroy$17(gobj) {
|
|
|
8762
9445
|
* Framework Method start
|
|
8763
9446
|
************************************************************/
|
|
8764
9447
|
function mt_start$17(gobj) {
|
|
9448
|
+
let priv = gobj.priv;
|
|
9449
|
+
let shell = yui_shell_of(gobj);
|
|
9450
|
+
if (shell) {
|
|
9451
|
+
(0, _yuneta_gobj_js.gobj_subscribe_event)(shell, "EV_LANGUAGE_CHANGED", {}, gobj);
|
|
9452
|
+
priv.lang_shell = shell;
|
|
9453
|
+
}
|
|
8765
9454
|
let record = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "record");
|
|
8766
9455
|
if (record) (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_LOAD_RECORD", record, gobj);
|
|
8767
9456
|
}
|
|
8768
9457
|
/************************************************************
|
|
8769
9458
|
* Framework Method stop
|
|
8770
9459
|
************************************************************/
|
|
8771
|
-
function mt_stop$17(gobj) {
|
|
9460
|
+
function mt_stop$17(gobj) {
|
|
9461
|
+
let priv = gobj.priv;
|
|
9462
|
+
if (priv.lang_shell && !(0, _yuneta_gobj_js.gobj_is_destroying)(priv.lang_shell)) (0, _yuneta_gobj_js.gobj_unsubscribe_event)(priv.lang_shell, "EV_LANGUAGE_CHANGED", {}, gobj);
|
|
9463
|
+
priv.lang_shell = null;
|
|
9464
|
+
}
|
|
8772
9465
|
/***************************
|
|
8773
9466
|
* Local Methods
|
|
8774
9467
|
***************************/
|
|
@@ -9224,6 +9917,80 @@ function name_form_control$1($field, conf) {
|
|
|
9224
9917
|
$clear.setAttribute("data-i18n-aria-label", CLEAR_KEY);
|
|
9225
9918
|
}
|
|
9226
9919
|
}
|
|
9920
|
+
/************************************************************
|
|
9921
|
+
* The ✕ of ONE selected option of a Tom Select: its
|
|
9922
|
+
* remove_button plugin calls this for every option it draws.
|
|
9923
|
+
*
|
|
9924
|
+
* The plugin's own was a div titled "Remove" in English -- never
|
|
9925
|
+
* translated, no aria-label -- with tabindex -1, and the form
|
|
9926
|
+
* turns Backspace deletion off (no_backspace_delete): a keyboard
|
|
9927
|
+
* could not take one option out at all. Named here through t()
|
|
9928
|
+
* with its key (so a language change reaches it), and pressed by
|
|
9929
|
+
* Enter or Space as the clear button is: the key clicks it, which
|
|
9930
|
+
* runs the plugin's own handler.
|
|
9931
|
+
************************************************************/
|
|
9932
|
+
function remove_option_button() {
|
|
9933
|
+
const KEY = "remove this option";
|
|
9934
|
+
let $b = (0, _yuneta_gobj_js.createElement2)([
|
|
9935
|
+
"div",
|
|
9936
|
+
{
|
|
9937
|
+
class: "remove",
|
|
9938
|
+
role: "button",
|
|
9939
|
+
tabindex: "0",
|
|
9940
|
+
title: (0, i18next.t)(KEY),
|
|
9941
|
+
"data-i18n-title": KEY,
|
|
9942
|
+
"aria-label": (0, i18next.t)(KEY),
|
|
9943
|
+
"data-i18n-aria-label": KEY
|
|
9944
|
+
},
|
|
9945
|
+
"×"
|
|
9946
|
+
]);
|
|
9947
|
+
$b.addEventListener("keydown", function(evt) {
|
|
9948
|
+
if (evt.key === "Enter" || evt.key === " ") {
|
|
9949
|
+
evt.preventDefault();
|
|
9950
|
+
evt.stopPropagation();
|
|
9951
|
+
$b.click();
|
|
9952
|
+
}
|
|
9953
|
+
});
|
|
9954
|
+
return $b;
|
|
9955
|
+
}
|
|
9956
|
+
/************************************************************
|
|
9957
|
+
* The `onRenderMenu` of a json editor of this form.
|
|
9958
|
+
*
|
|
9959
|
+
* The editor calls it with the items it is about to draw: they go
|
|
9960
|
+
* back translated (json_editor_menu_items(), data for the editor
|
|
9961
|
+
* to draw). What no item can carry -- an aria-label, the state of
|
|
9962
|
+
* the mode buttons -- is written on the drawn buttons, after the
|
|
9963
|
+
* render, by the form's FSM (EV_NAME_JSON_EDITORS): the callback
|
|
9964
|
+
* only posts the event, once until it is handled. Posted, not
|
|
9965
|
+
* sent: when it runs the editor has not drawn the menu yet.
|
|
9966
|
+
*
|
|
9967
|
+
* A new function each call: handing an editor a new one is what
|
|
9968
|
+
* makes it draw its menu again (ac_language_changed).
|
|
9969
|
+
************************************************************/
|
|
9970
|
+
function json_editor_render_menu(gobj) {
|
|
9971
|
+
return function(items) {
|
|
9972
|
+
ask_json_editor_names(gobj);
|
|
9973
|
+
return json_editor_menu_items(items);
|
|
9974
|
+
};
|
|
9975
|
+
}
|
|
9976
|
+
/************************************************************
|
|
9977
|
+
* The `onRenderContextMenu` of a json editor of this form: the
|
|
9978
|
+
* same, for the menu it opens on a right click or Ctrl+Q. It is
|
|
9979
|
+
* built each time it opens, in the language of that moment.
|
|
9980
|
+
************************************************************/
|
|
9981
|
+
function json_editor_render_context_menu(gobj) {
|
|
9982
|
+
return function(items, context) {
|
|
9983
|
+
ask_json_editor_names(gobj);
|
|
9984
|
+
return json_editor_context_menu_items(items, context);
|
|
9985
|
+
};
|
|
9986
|
+
}
|
|
9987
|
+
function ask_json_editor_names(gobj) {
|
|
9988
|
+
let priv = gobj.priv;
|
|
9989
|
+
if (!priv.json_names_posted && !(0, _yuneta_gobj_js.gobj_is_destroying)(gobj)) {
|
|
9990
|
+
priv.json_names_posted = true;
|
|
9991
|
+
(0, _yuneta_gobj_js.gobj_post_event)(gobj, "EV_NAME_JSON_EDITORS", {}, gobj);
|
|
9992
|
+
}
|
|
9993
|
+
}
|
|
9227
9994
|
function build_form(gobj) {
|
|
9228
9995
|
let form_id = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "form_id");
|
|
9229
9996
|
let $form = (0, _yuneta_gobj_js.createElement2)(["form", {
|
|
@@ -9255,7 +10022,7 @@ function build_html_form(gobj, $form, prefix, template) {
|
|
|
9255
10022
|
let label_keys = topic_name ? [topic_name + "." + field_desc.name, field_desc.name] : [field_desc.name];
|
|
9256
10023
|
const NO_I18N = "\0";
|
|
9257
10024
|
html_field_conf.label = (0, i18next.t)(label_keys, { defaultValue: field_desc.header });
|
|
9258
|
-
html_field_conf.label_i18n = (0, i18next.t)(
|
|
10025
|
+
html_field_conf.label_i18n = label_keys.find((k) => (0, i18next.t)(k, { defaultValue: NO_I18N }) !== NO_I18N) || null;
|
|
9259
10026
|
html_field_conf.placeholder = field_desc.placeholder ? (0, i18next.t)(field_desc.placeholder) : "";
|
|
9260
10027
|
let placeholders = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "placeholders");
|
|
9261
10028
|
if (placeholders[key]) html_field_conf.placeholder = placeholders[key];
|
|
@@ -9961,7 +10728,7 @@ function create_form_field(gobj, $form, prefix, field_desc, { tag, inputType, na
|
|
|
9961
10728
|
"clear_button": { "title": (0, i18next.t)("remove all selected options") },
|
|
9962
10729
|
"no_active_items": {},
|
|
9963
10730
|
"no_backspace_delete": {},
|
|
9964
|
-
"remove_button": {}
|
|
10731
|
+
"remove_button": { html: remove_option_button }
|
|
9965
10732
|
}
|
|
9966
10733
|
});
|
|
9967
10734
|
$extend.tom_select.on("change", function() {
|
|
@@ -10030,7 +10797,9 @@ function create_form_field(gobj, $form, prefix, field_desc, { tag, inputType, na
|
|
|
10030
10797
|
},
|
|
10031
10798
|
timestampTag: function({ field, value, path }) {
|
|
10032
10799
|
return is_time_field(field);
|
|
10033
|
-
}
|
|
10800
|
+
},
|
|
10801
|
+
onRenderMenu: json_editor_render_menu(gobj),
|
|
10802
|
+
onRenderContextMenu: json_editor_render_context_menu(gobj)
|
|
10034
10803
|
}
|
|
10035
10804
|
});
|
|
10036
10805
|
break;
|
|
@@ -10562,6 +11331,9 @@ function template2columns(gobj, columns, template, sub_elements) {
|
|
|
10562
11331
|
}
|
|
10563
11332
|
if (column) {
|
|
10564
11333
|
if (readonly) delete column.editor;
|
|
11334
|
+
yui_tabulator_name_editor(column, function() {
|
|
11335
|
+
return (0, i18next.t)(field_desc.header || field_desc.name);
|
|
11336
|
+
});
|
|
10565
11337
|
columns.push(column);
|
|
10566
11338
|
}
|
|
10567
11339
|
});
|
|
@@ -11322,6 +12094,39 @@ function ac_hide$11(gobj, event, kw, src) {
|
|
|
11322
12094
|
function ac_timeout(gobj, event, kw, src) {
|
|
11323
12095
|
return 0;
|
|
11324
12096
|
}
|
|
12097
|
+
/************************************************************
|
|
12098
|
+
* EV_NAME_JSON_EDITORS {} -- a menu of a json editor of this
|
|
12099
|
+
* form was drawn, its menu or its context menu (posted by
|
|
12100
|
+
* ask_json_editor_names): name its buttons. Every editor of the
|
|
12101
|
+
* form: naming is idempotent, and a kw is plain json, which an
|
|
12102
|
+
* editor is not.
|
|
12103
|
+
************************************************************/
|
|
12104
|
+
function ac_name_json_editors(gobj, event, kw, src) {
|
|
12105
|
+
let priv = gobj.priv;
|
|
12106
|
+
priv.json_names_posted = false;
|
|
12107
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
12108
|
+
if (!$container) {
|
|
12109
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} without a container`);
|
|
12110
|
+
return -1;
|
|
12111
|
+
}
|
|
12112
|
+
for (let $editor of $container.querySelectorAll(".jsoneditor")) name_json_editor_menu($editor);
|
|
12113
|
+
return 0;
|
|
12114
|
+
}
|
|
12115
|
+
/************************************************************
|
|
12116
|
+
* EV_LANGUAGE_CHANGED {} -- from the shell. A json editor draws
|
|
12117
|
+
* its menu once: its titles and the text of its mode buttons stay
|
|
12118
|
+
* in the old language until it draws it again, so each is told to
|
|
12119
|
+
* (a new onRenderMenu), and the render names it again.
|
|
12120
|
+
************************************************************/
|
|
12121
|
+
function ac_language_changed$10(gobj, event, kw, src) {
|
|
12122
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
12123
|
+
if (!$container) return 0;
|
|
12124
|
+
for (let $editor of $container.querySelectorAll(".jsoneditor")) {
|
|
12125
|
+
let editor = $editor.jsoneditor;
|
|
12126
|
+
if (editor && typeof editor.updateProps === "function") editor.updateProps({ onRenderMenu: json_editor_render_menu(gobj) });
|
|
12127
|
+
}
|
|
12128
|
+
return 0;
|
|
12129
|
+
}
|
|
11325
12130
|
/***************************
|
|
11326
12131
|
* FSM
|
|
11327
12132
|
***************************/
|
|
@@ -11471,6 +12276,16 @@ function create_gclass$17(gclass_name) {
|
|
|
11471
12276
|
"EV_TIMEOUT",
|
|
11472
12277
|
ac_timeout,
|
|
11473
12278
|
null
|
|
12279
|
+
],
|
|
12280
|
+
[
|
|
12281
|
+
"EV_NAME_JSON_EDITORS",
|
|
12282
|
+
ac_name_json_editors,
|
|
12283
|
+
null
|
|
12284
|
+
],
|
|
12285
|
+
[
|
|
12286
|
+
"EV_LANGUAGE_CHANGED",
|
|
12287
|
+
ac_language_changed$10,
|
|
12288
|
+
null
|
|
11474
12289
|
]
|
|
11475
12290
|
]]];
|
|
11476
12291
|
const event_types = [
|
|
@@ -11489,7 +12304,9 @@ function create_gclass$17(gclass_name) {
|
|
|
11489
12304
|
["EV_REFRESH", 0],
|
|
11490
12305
|
["EV_SHOW", 0],
|
|
11491
12306
|
["EV_HIDE", 0],
|
|
11492
|
-
["EV_TIMEOUT", 0]
|
|
12307
|
+
["EV_TIMEOUT", 0],
|
|
12308
|
+
["EV_NAME_JSON_EDITORS", 0],
|
|
12309
|
+
["EV_LANGUAGE_CHANGED", 0]
|
|
11493
12310
|
];
|
|
11494
12311
|
__gclass__$17 = (0, _yuneta_gobj_js.gclass_create)(gclass_name, event_types, states, gmt$17, 0, attrs_table$17, PRIVATE_DATA$17, 0, 0, 0, 0);
|
|
11495
12312
|
if (!__gclass__$17) return -1;
|
|
@@ -11509,7 +12326,7 @@ function register_c_yui_form() {
|
|
|
11509
12326
|
*
|
|
11510
12327
|
* Utilities for maplibre
|
|
11511
12328
|
*
|
|
11512
|
-
* Copyright (c) 2025, ArtGins.
|
|
12329
|
+
* Copyright (c) 2025-2026, ArtGins.
|
|
11513
12330
|
* All Rights Reserved.
|
|
11514
12331
|
***********************************************************************/
|
|
11515
12332
|
var EditControl = class {
|
|
@@ -11705,9 +12522,14 @@ function label_ctrl($root, selector, text) {
|
|
|
11705
12522
|
$el.setAttribute("aria-label", text);
|
|
11706
12523
|
}
|
|
11707
12524
|
}
|
|
12525
|
+
function relabel_written($root, selector, was, now) {
|
|
12526
|
+
if (!$root || !now) return;
|
|
12527
|
+
for (const $el of $root.querySelectorAll(selector)) if ($el.getAttribute("aria-label") === was) $el.setAttribute("aria-label", now);
|
|
12528
|
+
}
|
|
11708
12529
|
function yui_maplibre_relocalize(map, t) {
|
|
11709
12530
|
if (!map || typeof map.getContainer !== "function") return;
|
|
11710
12531
|
const strings = yui_maplibre_locale(t);
|
|
12532
|
+
const was = Object.assign({}, map._locale);
|
|
11711
12533
|
try {
|
|
11712
12534
|
map._locale = Object.assign({}, map._locale, strings);
|
|
11713
12535
|
} catch (e) {}
|
|
@@ -11719,6 +12541,8 @@ function yui_maplibre_relocalize(map, t) {
|
|
|
11719
12541
|
label_ctrl($c, ".maplibregl-ctrl-attrib-button", strings["AttributionControl.ToggleAttribution"]);
|
|
11720
12542
|
label_ctrl($c, ".maplibregl-ctrl-fullscreen", strings["FullscreenControl.Enter"]);
|
|
11721
12543
|
label_ctrl($c, ".maplibregl-popup-close-button", strings["Popup.Close"]);
|
|
12544
|
+
relabel_written($c, ".maplibregl-canvas", was["Map.Title"], strings["Map.Title"]);
|
|
12545
|
+
relabel_written($c, ".maplibregl-marker", was["Marker.Title"], strings["Marker.Title"]);
|
|
11722
12546
|
const mac = typeof navigator !== "undefined" && (navigator.userAgent || "").includes("Mac");
|
|
11723
12547
|
const $desktop = $c.querySelector(".maplibregl-desktop-message");
|
|
11724
12548
|
if ($desktop) $desktop.textContent = mac ? strings["CooperativeGesturesHandler.MacHelpText"] : strings["CooperativeGesturesHandler.WindowsHelpText"];
|
|
@@ -14467,6 +15291,8 @@ function make_toolbar$5(gobj) {
|
|
|
14467
15291
|
type: "text",
|
|
14468
15292
|
placeholder: (0, i18next.t)("search"),
|
|
14469
15293
|
"data-i18n-placeholder": "search",
|
|
15294
|
+
title: (0, i18next.t)("search"),
|
|
15295
|
+
"data-i18n-title": "search",
|
|
14470
15296
|
"aria-label": (0, i18next.t)("search"),
|
|
14471
15297
|
"data-i18n-aria-label": "search"
|
|
14472
15298
|
},
|
|
@@ -16007,6 +16833,8 @@ function make_toolbar$4(gobj) {
|
|
|
16007
16833
|
type: "text",
|
|
16008
16834
|
placeholder: (0, i18next.t)("search"),
|
|
16009
16835
|
"data-i18n-placeholder": "search",
|
|
16836
|
+
title: (0, i18next.t)("search"),
|
|
16837
|
+
"data-i18n-title": "search",
|
|
16010
16838
|
"aria-label": (0, i18next.t)("search"),
|
|
16011
16839
|
"data-i18n-aria-label": "search"
|
|
16012
16840
|
},
|
|
@@ -19280,6 +20108,8 @@ function make_toolbar$2(gobj) {
|
|
|
19280
20108
|
type: "text",
|
|
19281
20109
|
placeholder: (0, i18next.t)("search"),
|
|
19282
20110
|
"data-i18n-placeholder": "search",
|
|
20111
|
+
title: (0, i18next.t)("search"),
|
|
20112
|
+
"data-i18n-title": "search",
|
|
19283
20113
|
"aria-label": (0, i18next.t)("search"),
|
|
19284
20114
|
"data-i18n-aria-label": "search"
|
|
19285
20115
|
},
|
|
@@ -21100,7 +21930,7 @@ function open_gclass_view(host, gclass_name, opts) {
|
|
|
21100
21930
|
(0, _yuneta_gobj_js.gobj_start)(jv);
|
|
21101
21931
|
return handle;
|
|
21102
21932
|
}
|
|
21103
|
-
let $win_parent = window_layer_of(host
|
|
21933
|
+
let $win_parent = window_layer_of(host);
|
|
21104
21934
|
handle.win = (0, _yuneta_gobj_js.gobj_create_service)(`gclass-win-${(0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(host))}`, "C_YUI_WINDOW", {
|
|
21105
21935
|
$parent: $win_parent,
|
|
21106
21936
|
subscriber: null,
|
|
@@ -21168,14 +21998,19 @@ function close_gclass_view(handle) {
|
|
|
21168
21998
|
* window on `body` and mounted in the shell's popup layer
|
|
21169
21999
|
* lands BEHIND its opener whatever number it is given, and
|
|
21170
22000
|
* the button reads as one that did nothing.
|
|
22001
|
+
*
|
|
22002
|
+
* Opened from no window: null -- the window layer of the
|
|
22003
|
+
* shell, where every window lives (the legacy '#top-layer'
|
|
22004
|
+
* when a page has one). It was the shell's popup layer: above
|
|
22005
|
+
* the drawer, in the way of the toolbar's dropdowns.
|
|
21171
22006
|
************************************************************/
|
|
21172
|
-
function window_layer_of(host
|
|
22007
|
+
function window_layer_of(host) {
|
|
21173
22008
|
let $c = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(host, "$container");
|
|
21174
22009
|
if ($c && typeof $c.closest === "function") {
|
|
21175
22010
|
let $win = $c.closest(".C_YUI_WINDOW");
|
|
21176
22011
|
if ($win && $win.parentNode) return $win.parentNode;
|
|
21177
22012
|
}
|
|
21178
|
-
return typeof document !== "undefined" && document.getElementById("top-layer") ||
|
|
22013
|
+
return typeof document !== "undefined" && document.getElementById("top-layer") || null;
|
|
21179
22014
|
}
|
|
21180
22015
|
/************************************************************
|
|
21181
22016
|
* A window is not a sheet: below this width there is no room
|
|
@@ -21844,6 +22679,8 @@ function make_find_items(gobj) {
|
|
|
21844
22679
|
type: "text",
|
|
21845
22680
|
placeholder: (0, i18next.t)("search"),
|
|
21846
22681
|
"data-i18n-placeholder": "search",
|
|
22682
|
+
title: (0, i18next.t)("search"),
|
|
22683
|
+
"data-i18n-title": "search",
|
|
21847
22684
|
"aria-label": (0, i18next.t)("search"),
|
|
21848
22685
|
"data-i18n-aria-label": "search"
|
|
21849
22686
|
},
|
|
@@ -23629,7 +24466,7 @@ function card_descriptor(it, show_label, badge_of) {
|
|
|
23629
24466
|
"aria-label": label || it.id
|
|
23630
24467
|
};
|
|
23631
24468
|
if (label) a_attrs["data-i18n-aria-label"] = label;
|
|
23632
|
-
let tip = it.tooltip || it.aria_label;
|
|
24469
|
+
let tip = it.tooltip || it.aria_label || label;
|
|
23633
24470
|
if (tip) {
|
|
23634
24471
|
a_attrs.title = tip;
|
|
23635
24472
|
a_attrs["data-i18n-title"] = tip;
|
|
@@ -23638,6 +24475,7 @@ function card_descriptor(it, show_label, badge_of) {
|
|
|
23638
24475
|
a_attrs["aria-disabled"] = "true";
|
|
23639
24476
|
a_attrs["tabindex"] = "-1";
|
|
23640
24477
|
}
|
|
24478
|
+
if (badge) name_control_with_badge(a_attrs, badge);
|
|
23641
24479
|
return [
|
|
23642
24480
|
"a",
|
|
23643
24481
|
a_attrs,
|
|
@@ -24040,6 +24878,7 @@ function render_tabs(gobj, items) {
|
|
|
24040
24878
|
a_attrs.title = tip;
|
|
24041
24879
|
a_attrs["data-i18n-title"] = tip;
|
|
24042
24880
|
}
|
|
24881
|
+
name_control_with_badge(a_attrs, badge_el);
|
|
24043
24882
|
let li_class = (0, _yuneta_gobj_js.empty_string)(it.class) ? "" : String(it.class);
|
|
24044
24883
|
lis.push([
|
|
24045
24884
|
"li",
|
|
@@ -24119,11 +24958,14 @@ function render_breadcrumb(gobj, items) {
|
|
|
24119
24958
|
href: it.route ? "#" + it.route : "#",
|
|
24120
24959
|
"data-item-id": it.id,
|
|
24121
24960
|
"data-route": it.route || "",
|
|
24122
|
-
"data-disabled": it.disabled ? "1" : "0"
|
|
24961
|
+
"data-disabled": it.disabled ? "1" : "0",
|
|
24962
|
+
"aria-label": it.name || it.id
|
|
24123
24963
|
};
|
|
24124
|
-
if (it.name)
|
|
24125
|
-
|
|
24126
|
-
|
|
24964
|
+
if (it.name) a_attrs["data-i18n-aria-label"] = it.name;
|
|
24965
|
+
let tip = it.tooltip || it.aria_label || it.name;
|
|
24966
|
+
if (tip) {
|
|
24967
|
+
a_attrs.title = tip;
|
|
24968
|
+
a_attrs["data-i18n-title"] = tip;
|
|
24127
24969
|
}
|
|
24128
24970
|
lis.push([
|
|
24129
24971
|
"li",
|
|
@@ -24256,17 +25098,19 @@ function render_accordion(gobj, items) {
|
|
|
24256
25098
|
"aria-expanded": "false",
|
|
24257
25099
|
"aria-controls": body_id
|
|
24258
25100
|
};
|
|
25101
|
+
let head_badge = item_badge_node(gobj, it, false);
|
|
24259
25102
|
if (!(0, _yuneta_gobj_js.empty_string)(head_text)) {
|
|
24260
25103
|
head_attrs.i18n = head_text;
|
|
24261
25104
|
head_attrs.title = head_text;
|
|
24262
25105
|
head_attrs["data-i18n-title"] = head_text;
|
|
24263
25106
|
head_attrs["aria-label"] = head_text;
|
|
24264
25107
|
head_attrs["data-i18n-aria-label"] = head_text;
|
|
25108
|
+
name_control_with_badge(head_attrs, head_badge);
|
|
24265
25109
|
}
|
|
24266
25110
|
let $hdr = (0, _yuneta_gobj_js.createElement2)([
|
|
24267
25111
|
"button",
|
|
24268
25112
|
head_attrs,
|
|
24269
|
-
[text_node(head_text),
|
|
25113
|
+
[text_node(head_text), head_badge]
|
|
24270
25114
|
]);
|
|
24271
25115
|
$container.appendChild($hdr);
|
|
24272
25116
|
let $ul = (0, _yuneta_gobj_js.createElement2)(["ul", {
|
|
@@ -24355,6 +25199,7 @@ function item_li(gobj, it, opts) {
|
|
|
24355
25199
|
a_attrs["aria-disabled"] = "true";
|
|
24356
25200
|
a_attrs["tabindex"] = "-1";
|
|
24357
25201
|
}
|
|
25202
|
+
name_control_with_badge(a_attrs, badge_el);
|
|
24358
25203
|
return [
|
|
24359
25204
|
"li",
|
|
24360
25205
|
{},
|
|
@@ -24401,6 +25246,7 @@ function item_iconbar(gobj, it, opts) {
|
|
|
24401
25246
|
a_attrs.title = tip;
|
|
24402
25247
|
a_attrs["data-i18n-title"] = tip;
|
|
24403
25248
|
}
|
|
25249
|
+
name_control_with_badge(a_attrs, badge_el);
|
|
24404
25250
|
return [
|
|
24405
25251
|
"div",
|
|
24406
25252
|
{ class: "level-item" },
|
|
@@ -24658,7 +25504,10 @@ function render_node(node) {
|
|
|
24658
25504
|
if (node.icon && /^yi-[a-z0-9-]+$/.test(node.icon)) row.push([
|
|
24659
25505
|
"span",
|
|
24660
25506
|
{ class: "icon ROUTEMAP_ICON" },
|
|
24661
|
-
[["i", {
|
|
25507
|
+
[["i", {
|
|
25508
|
+
class: node.icon,
|
|
25509
|
+
"aria-hidden": "true"
|
|
25510
|
+
}]]
|
|
24662
25511
|
]);
|
|
24663
25512
|
row.push([
|
|
24664
25513
|
"span",
|
|
@@ -24707,16 +25556,23 @@ function render_node(node) {
|
|
|
24707
25556
|
]);
|
|
24708
25557
|
let row_class = (node.current ? " ROUTEMAP_CURRENT" : "") + (node.ref ? " ROUTEMAP_IS_REF" : "");
|
|
24709
25558
|
let $row;
|
|
24710
|
-
if (node.route)
|
|
24711
|
-
|
|
24712
|
-
{
|
|
25559
|
+
if (node.route) {
|
|
25560
|
+
let a_attrs = {
|
|
24713
25561
|
class: "ROUTEMAP_LINK ROUTEMAP_ROW" + row_class,
|
|
24714
25562
|
href: "#" + node.route,
|
|
24715
25563
|
title: node.route
|
|
24716
|
-
}
|
|
24717
|
-
|
|
24718
|
-
|
|
24719
|
-
|
|
25564
|
+
};
|
|
25565
|
+
if (node.label) {
|
|
25566
|
+
a_attrs["aria-label"] = node.label;
|
|
25567
|
+
a_attrs["data-i18n-aria-label"] = node.label;
|
|
25568
|
+
}
|
|
25569
|
+
if (node.current) a_attrs["aria-current"] = "page";
|
|
25570
|
+
$row = (0, _yuneta_gobj_js.createElement2)([
|
|
25571
|
+
"a",
|
|
25572
|
+
a_attrs,
|
|
25573
|
+
row
|
|
25574
|
+
]);
|
|
25575
|
+
} else $row = (0, _yuneta_gobj_js.createElement2)([
|
|
24720
25576
|
"span",
|
|
24721
25577
|
{ class: "ROUTEMAP_ROW ROUTEMAP_STRUCT" + row_class },
|
|
24722
25578
|
row
|
|
@@ -25000,7 +25856,7 @@ function yui_shell_show_route_map(shell, opts) {
|
|
|
25000
25856
|
if ((0, _yuneta_gobj_js.gclass_find_by_name)("C_YUI_WINDOW")) {
|
|
25001
25857
|
let win_ref = { gobj: null };
|
|
25002
25858
|
let $body = build_body(shell, t);
|
|
25003
|
-
let $parent =
|
|
25859
|
+
let $parent = typeof document !== "undefined" && document.getElementById("top-layer") || null;
|
|
25004
25860
|
let win = (0, _yuneta_gobj_js.gobj_create_service)(WIN_NAME$2, "C_YUI_WINDOW", {
|
|
25005
25861
|
$parent,
|
|
25006
25862
|
subscriber: null,
|
|
@@ -26074,7 +26930,13 @@ function add_tab(gobj, gobj2, id, text, icon) {
|
|
|
26074
26930
|
let $item = (0, _yuneta_gobj_js.createElement2)([
|
|
26075
26931
|
"li",
|
|
26076
26932
|
{ class: "" },
|
|
26077
|
-
[["a", {
|
|
26933
|
+
[["a", {
|
|
26934
|
+
href: id,
|
|
26935
|
+
title: (0, i18next.t)(text),
|
|
26936
|
+
"data-i18n-title": text,
|
|
26937
|
+
"aria-label": (0, i18next.t)(text),
|
|
26938
|
+
"data-i18n-aria-label": text
|
|
26939
|
+
}]]
|
|
26078
26940
|
]);
|
|
26079
26941
|
$tabs.appendChild($item);
|
|
26080
26942
|
$item.gobj = gobj2;
|
|
@@ -26082,7 +26944,10 @@ function add_tab(gobj, gobj2, id, text, icon) {
|
|
|
26082
26944
|
if (icon) $a.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
26083
26945
|
"span",
|
|
26084
26946
|
{ class: "icon is-small is-hidden-mobile" },
|
|
26085
|
-
["i", {
|
|
26947
|
+
["i", {
|
|
26948
|
+
class: `${icon}`,
|
|
26949
|
+
"aria-hidden": "true"
|
|
26950
|
+
}]
|
|
26086
26951
|
]));
|
|
26087
26952
|
$a.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
26088
26953
|
"span",
|
|
@@ -26271,7 +27136,9 @@ function add_topic_card(gobj, id, text, icon, desc) {
|
|
|
26271
27136
|
class: "yui-nav-item yui-nav-card TREEDB_TOPIC_CARD",
|
|
26272
27137
|
href: "#",
|
|
26273
27138
|
"data-topic-href": id,
|
|
26274
|
-
|
|
27139
|
+
title: (0, i18next.t)(text),
|
|
27140
|
+
"data-i18n-title": text,
|
|
27141
|
+
"aria-label": (0, i18next.t)(text),
|
|
26275
27142
|
"data-i18n-aria-label": text
|
|
26276
27143
|
},
|
|
26277
27144
|
[[
|
|
@@ -27115,7 +27982,7 @@ function open_json_viewer$1(gobj, opts) {
|
|
|
27115
27982
|
}
|
|
27116
27983
|
});
|
|
27117
27984
|
} else {
|
|
27118
|
-
let $win_parent =
|
|
27985
|
+
let $win_parent = typeof document !== "undefined" && document.getElementById("top-layer") || null;
|
|
27119
27986
|
priv.json_win = (0, _yuneta_gobj_js.gobj_create_service)(`treedb-topics-jsonwin-${(0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj))}`, "C_YUI_WINDOW", {
|
|
27120
27987
|
$parent: $win_parent,
|
|
27121
27988
|
subscriber: null,
|
|
@@ -27242,7 +28109,9 @@ function request_print_tranger$1(gobj, path) {
|
|
|
27242
28109
|
}, gobj);
|
|
27243
28110
|
if (ret) {
|
|
27244
28111
|
(0, _yuneta_gobj_js.log_error)(ret);
|
|
27245
|
-
|
|
28112
|
+
const refusal = refusal_text$1(ret);
|
|
28113
|
+
if (refusal) answer_print_tranger_refused$1(gobj, path, { error: refusal });
|
|
28114
|
+
else answer_print_tranger_refused$1(gobj, path, { i18n: "print-tranger failed" });
|
|
27246
28115
|
return;
|
|
27247
28116
|
}
|
|
27248
28117
|
if (path) priv.drills_in_flight.add(path);
|
|
@@ -27310,9 +28179,13 @@ function ac_mt_command_answer$2(gobj, event, kw, src) {
|
|
|
27310
28179
|
}
|
|
27311
28180
|
} else gobj.priv.drills_in_flight.clear();
|
|
27312
28181
|
if (result < 0) {
|
|
27313
|
-
if (path) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", {
|
|
28182
|
+
if (path && comment) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", {
|
|
27314
28183
|
path,
|
|
27315
|
-
error: comment
|
|
28184
|
+
error: comment
|
|
28185
|
+
}, gobj);
|
|
28186
|
+
else if (path) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", {
|
|
28187
|
+
path,
|
|
28188
|
+
i18n: "print-tranger failed"
|
|
27316
28189
|
}, gobj);
|
|
27317
28190
|
else yui_shell_show_error(yui_shell_of(gobj), comment || "print-tranger failed", { t: i18next.t });
|
|
27318
28191
|
return 0;
|
|
@@ -29097,7 +29970,7 @@ function present_json_popup(gobj, $box, opts) {
|
|
|
29097
29970
|
win: null
|
|
29098
29971
|
};
|
|
29099
29972
|
let win = (0, _yuneta_gobj_js.gobj_create_service)(opts.name, "C_YUI_WINDOW", {
|
|
29100
|
-
$parent: popup_mount_layer(
|
|
29973
|
+
$parent: popup_mount_layer(),
|
|
29101
29974
|
subscriber: null,
|
|
29102
29975
|
modal: false,
|
|
29103
29976
|
showMax: true,
|
|
@@ -29151,10 +30024,17 @@ function retire_popup_window(win) {
|
|
|
29151
30024
|
(0, _yuneta_gobj_js.log_warning)(`${GCLASS_NAME$5}: json window already gone: ${e}`);
|
|
29152
30025
|
}
|
|
29153
30026
|
}
|
|
29154
|
-
|
|
29155
|
-
|
|
29156
|
-
|
|
29157
|
-
|
|
30027
|
+
/************************************************************
|
|
30028
|
+
* Where a json window of this view lives: null, the WINDOW
|
|
30029
|
+
* layer of the shell, where every window lives -- below the
|
|
30030
|
+
* shell's dialogs, so a confirm asked over it paints above it
|
|
30031
|
+
* (the legacy C_YUI_MAIN '#popup-layer' when a page has one).
|
|
30032
|
+
* It was the shell's popup layer: above the drawer, in the way
|
|
30033
|
+
* of the toolbar's dropdowns, and in an order of its own no
|
|
30034
|
+
* other window could rise above.
|
|
30035
|
+
************************************************************/
|
|
30036
|
+
function popup_mount_layer() {
|
|
30037
|
+
return document.getElementById("popup-layer") || null;
|
|
29158
30038
|
}
|
|
29159
30039
|
/******************************
|
|
29160
30040
|
* Framework Methods
|
|
@@ -29769,7 +30649,10 @@ function col_title_formatter(gobj, col) {
|
|
|
29769
30649
|
let text = col_label(col, topic_name);
|
|
29770
30650
|
let attrs = {};
|
|
29771
30651
|
const NO_I18N = "\0";
|
|
29772
|
-
|
|
30652
|
+
let key = null;
|
|
30653
|
+
if (topic_name && (0, i18next.t)(topic_name + "." + col.id, { defaultValue: NO_I18N }) !== NO_I18N) key = topic_name + "." + col.id;
|
|
30654
|
+
else if ((0, i18next.t)(col.id, { defaultValue: NO_I18N }) !== NO_I18N) key = col.id;
|
|
30655
|
+
if (key) attrs.i18n = key;
|
|
29773
30656
|
return (0, _yuneta_gobj_js.createElement2)([
|
|
29774
30657
|
"span",
|
|
29775
30658
|
attrs,
|
|
@@ -29863,6 +30746,9 @@ function create_tabulator(gobj) {
|
|
|
29863
30746
|
colDef.editable = function() {
|
|
29864
30747
|
return (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "editable") && !(0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "readonly");
|
|
29865
30748
|
};
|
|
30749
|
+
yui_tabulator_name_editor(colDef, function() {
|
|
30750
|
+
return col_label(col, (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "topic_name"));
|
|
30751
|
+
});
|
|
29866
30752
|
}
|
|
29867
30753
|
const FILTERABLE = [
|
|
29868
30754
|
"string",
|
|
@@ -71221,7 +72107,7 @@ function open_json_viewer(gobj) {
|
|
|
71221
72107
|
});
|
|
71222
72108
|
(0, _yuneta_gobj_js.gobj_start)(jv);
|
|
71223
72109
|
} else {
|
|
71224
|
-
let $win_parent =
|
|
72110
|
+
let $win_parent = typeof document !== "undefined" && document.getElementById("top-layer") || null;
|
|
71225
72111
|
priv.json_win = (0, _yuneta_gobj_js.gobj_create_service)(`treedb-jsonwin-${(0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj))}`, "C_YUI_WINDOW", {
|
|
71226
72112
|
$parent: $win_parent,
|
|
71227
72113
|
subscriber: null,
|
|
@@ -71335,7 +72221,9 @@ function request_print_tranger(gobj, path) {
|
|
|
71335
72221
|
}, gobj);
|
|
71336
72222
|
if (ret) {
|
|
71337
72223
|
(0, _yuneta_gobj_js.log_error)(ret);
|
|
71338
|
-
|
|
72224
|
+
const refusal = refusal_text(ret);
|
|
72225
|
+
if (refusal) answer_print_tranger_refused(gobj, path, { error: refusal });
|
|
72226
|
+
else answer_print_tranger_refused(gobj, path, { i18n: "print-tranger failed" });
|
|
71339
72227
|
return;
|
|
71340
72228
|
}
|
|
71341
72229
|
if (path) priv.drills_in_flight.add(path);
|
|
@@ -71740,9 +72628,13 @@ function ac_mt_command_answer$1(gobj, event, kw, src) {
|
|
|
71740
72628
|
}
|
|
71741
72629
|
} else priv.drills_in_flight.clear();
|
|
71742
72630
|
if (result < 0) {
|
|
71743
|
-
if (path) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", {
|
|
72631
|
+
if (path && comment) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", {
|
|
72632
|
+
path,
|
|
72633
|
+
error: comment
|
|
72634
|
+
}, gobj);
|
|
72635
|
+
else if (path) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", {
|
|
71744
72636
|
path,
|
|
71745
|
-
|
|
72637
|
+
i18n: "print-tranger failed"
|
|
71746
72638
|
}, gobj);
|
|
71747
72639
|
else yui_shell_show_error(yui_shell_of(gobj), comment || "print-tranger failed", { t: i18next.t });
|
|
71748
72640
|
return 0;
|
|
@@ -83334,7 +84226,8 @@ function apply_dev_traces() {
|
|
|
83334
84226
|
* Shell-agnostic: the legacy C_YUI_MAIN shell has a
|
|
83335
84227
|
* '#top-layer' stacking element; the new C_YUI_SHELL does not.
|
|
83336
84228
|
* We pass that element when present, otherwise null — C_YUI_WINDOW
|
|
83337
|
-
*
|
|
84229
|
+
* then takes the window layer of the shell (document.body while
|
|
84230
|
+
* there is none), and follows the shell across a logout.
|
|
83338
84231
|
************************************************************/
|
|
83339
84232
|
function setup_dev(self, show) {
|
|
83340
84233
|
if (show) {
|
|
@@ -83424,7 +84317,8 @@ var WIN_NAME$1 = "Frontend-View-Window";
|
|
|
83424
84317
|
* Shell-agnostic: the legacy C_YUI_MAIN shell has a
|
|
83425
84318
|
* '#top-layer' stacking element; the new C_YUI_SHELL does not.
|
|
83426
84319
|
* We pass that element when present, otherwise null — C_YUI_WINDOW
|
|
83427
|
-
*
|
|
84320
|
+
* then takes the window layer of the shell (document.body while
|
|
84321
|
+
* there is none), and follows the shell across a logout.
|
|
83428
84322
|
*
|
|
83429
84323
|
* Returns the window gobj, or null.
|
|
83430
84324
|
************************************************************/
|