@yuneta/gobj-ui 2.2.0 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gobj-ui.cjs.js +46 -17
- package/dist/gobj-ui.es.js +47 -18
- package/package.json +3 -3
- package/src/c_yui_shell.js +12 -3
- package/src/c_yui_window.js +27 -10
- package/src/c_yui_window_manager.js +15 -1
- package/src/yui_dev.js +24 -4
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -816,6 +816,17 @@ function update_stats() {
|
|
|
816
816
|
});
|
|
817
817
|
}
|
|
818
818
|
/************************************************************
|
|
819
|
+
* Append a row and follow the tail — but only when the user is
|
|
820
|
+
* already at (or near) the bottom; a reader scrolled up into the
|
|
821
|
+
* backlog must not be yanked down. Container-local on purpose:
|
|
822
|
+
* scrollIntoView also scrolls the host page's ancestors.
|
|
823
|
+
************************************************************/
|
|
824
|
+
function append_and_follow(logger, node) {
|
|
825
|
+
let at_bottom = logger.scrollHeight - logger.scrollTop - logger.clientHeight < 40;
|
|
826
|
+
logger.appendChild(node);
|
|
827
|
+
if (at_bottom) logger.scrollTop = logger.scrollHeight;
|
|
828
|
+
}
|
|
829
|
+
/************************************************************
|
|
819
830
|
* Append one inter-event message. Kept in a bounded buffer so
|
|
820
831
|
* view/filter switches repaint from memory. Shared by the legacy
|
|
821
832
|
* C_YUI_WINDOW (setup_dev) and the modal (build_dev_panel).
|
|
@@ -876,8 +887,7 @@ function info_traffic(title, msg, direction, size) {
|
|
|
876
887
|
entry.$node = node;
|
|
877
888
|
let ph = logger.querySelector(".YDEV_EMPTY");
|
|
878
889
|
if (ph) ph.remove();
|
|
879
|
-
logger
|
|
880
|
-
node.scrollIntoView({ block: "end" });
|
|
890
|
+
append_and_follow(logger, node);
|
|
881
891
|
}
|
|
882
892
|
update_stats();
|
|
883
893
|
}
|
|
@@ -931,8 +941,7 @@ function info_log(level, msg, hora) {
|
|
|
931
941
|
entry.$node = node;
|
|
932
942
|
let ph = logger.querySelector(".YDEV_EMPTY");
|
|
933
943
|
if (ph) ph.remove();
|
|
934
|
-
logger
|
|
935
|
-
node.scrollIntoView({ block: "end" });
|
|
944
|
+
append_and_follow(logger, node);
|
|
936
945
|
}
|
|
937
946
|
update_stats();
|
|
938
947
|
} finally {
|
|
@@ -1061,6 +1070,11 @@ function traffic_to_text() {
|
|
|
1061
1070
|
let out = [];
|
|
1062
1071
|
for (let e of TRAFFIC_LOG) {
|
|
1063
1072
|
if (entry_hidden(e, ctx)) continue;
|
|
1073
|
+
if (e.kind === "log") {
|
|
1074
|
+
out.push(`${e.ts} ${e.level}: ${e.text}`);
|
|
1075
|
+
out.push("");
|
|
1076
|
+
continue;
|
|
1077
|
+
}
|
|
1064
1078
|
let head = `${e.ts} ${dir_arrow(e.dir)} ${e.title ? "[" + e.title + "] " : ""}${e.event}${e.command ? " " + e.command : ""}`;
|
|
1065
1079
|
out.push(head);
|
|
1066
1080
|
let payload = e.kw ? e.kw : e.jn;
|
|
@@ -2857,7 +2871,7 @@ function resolve_manager(gobj) {
|
|
|
2857
2871
|
let m = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(gobj, "manager");
|
|
2858
2872
|
if (!m) return null;
|
|
2859
2873
|
if (typeof m === "string") {
|
|
2860
|
-
m = (0, _yuneta_gobj_js.gobj_find_service)(m, false);
|
|
2874
|
+
m = (0, _yuneta_gobj_js.gobj_find_service)(m, false) || null;
|
|
2861
2875
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "manager", m);
|
|
2862
2876
|
}
|
|
2863
2877
|
return m;
|
|
@@ -3154,13 +3168,14 @@ function close_window(gobj) {
|
|
|
3154
3168
|
let kw_close = { abort_close: false };
|
|
3155
3169
|
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_WINDOW_TO_CLOSE", kw_close);
|
|
3156
3170
|
let on_close = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "on_close");
|
|
3157
|
-
if (on_close) on_close();
|
|
3158
3171
|
if (!kw_close.abort_close) {
|
|
3172
|
+
if (on_close) on_close();
|
|
3159
3173
|
if ((0, _yuneta_gobj_js.gobj_is_running)(gobj)) (0, _yuneta_gobj_js.gobj_stop)(gobj);
|
|
3160
3174
|
(0, _yuneta_gobj_js.gobj_stop_children)(gobj);
|
|
3161
3175
|
(0, _yuneta_gobj_js.gobj_destroy)(gobj);
|
|
3162
3176
|
} else if (kw_close.warning) get_yesnocancel(kw_close.warning, function(resp) {
|
|
3163
3177
|
if (resp === "yes") {
|
|
3178
|
+
if (on_close) on_close();
|
|
3164
3179
|
(0, _yuneta_gobj_js.gobj_stop)(gobj);
|
|
3165
3180
|
(0, _yuneta_gobj_js.gobj_stop_children)(gobj);
|
|
3166
3181
|
(0, _yuneta_gobj_js.gobj_destroy)(gobj);
|
|
@@ -3242,6 +3257,9 @@ function mvStart(gobj, evt) {
|
|
|
3242
3257
|
$container.style.transform = "translate3d(" + div_x + "px, " + div_y + "px, 0px)";
|
|
3243
3258
|
}
|
|
3244
3259
|
function mvStop(evt) {
|
|
3260
|
+
document.removeEventListener("pointermove", mvMove);
|
|
3261
|
+
document.removeEventListener("pointerup", mvStop);
|
|
3262
|
+
if ((0, _yuneta_gobj_js.gobj_is_destroying)(gobj)) return;
|
|
3245
3263
|
div_x = evt.screenX - x;
|
|
3246
3264
|
div_y = evt.screenY - y;
|
|
3247
3265
|
let xx = pos_x + div_x;
|
|
@@ -3250,8 +3268,6 @@ function mvStart(gobj, evt) {
|
|
|
3250
3268
|
$container.style.top = yy + "px";
|
|
3251
3269
|
$container.style.transition = "none";
|
|
3252
3270
|
$container.style.transform = "translate3d(0px, 0px, 0px)";
|
|
3253
|
-
document.removeEventListener("pointermove", mvMove);
|
|
3254
|
-
document.removeEventListener("pointerup", mvStop);
|
|
3255
3271
|
let rect = $container.getBoundingClientRect();
|
|
3256
3272
|
(0, _yuneta_gobj_js.gobj_write_integer_attr)(gobj, "x", rect.x);
|
|
3257
3273
|
(0, _yuneta_gobj_js.gobj_write_integer_attr)(gobj, "y", rect.y);
|
|
@@ -3291,12 +3307,13 @@ function rsStart(gobj, evt) {
|
|
|
3291
3307
|
$container.style.height = height + rel_h + "px";
|
|
3292
3308
|
}
|
|
3293
3309
|
function rsStop(evt) {
|
|
3310
|
+
document.removeEventListener("pointermove", rsMove);
|
|
3311
|
+
document.removeEventListener("pointerup", rsStop);
|
|
3312
|
+
if ((0, _yuneta_gobj_js.gobj_is_destroying)(gobj)) return;
|
|
3294
3313
|
rel_w = evt.pageX - pageX;
|
|
3295
3314
|
rel_h = evt.pageY - pageY;
|
|
3296
3315
|
$container.style.width = width + rel_w + "px";
|
|
3297
3316
|
$container.style.height = height + rel_h + "px";
|
|
3298
|
-
document.removeEventListener("pointermove", rsMove);
|
|
3299
|
-
document.removeEventListener("pointerup", rsStop);
|
|
3300
3317
|
let rect = $container.getBoundingClientRect();
|
|
3301
3318
|
if ((0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "force_center")) {
|
|
3302
3319
|
rect = do_center(gobj, rect.x, rect.y, rect.width, rect.height);
|
|
@@ -3675,7 +3692,7 @@ function build_dock(gobj) {
|
|
|
3675
3692
|
ensure_dock_style();
|
|
3676
3693
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "$container", (0, _yuneta_gobj_js.createElement2)([
|
|
3677
3694
|
"div",
|
|
3678
|
-
{ class: "yui-dock is-empty" },
|
|
3695
|
+
{ class: "C_YUI_WINDOW_MANAGER yui-dock is-empty" },
|
|
3679
3696
|
[]
|
|
3680
3697
|
]));
|
|
3681
3698
|
apply_placement(gobj);
|
|
@@ -3861,10 +3878,20 @@ function ac_register_window(gobj, event, kw, src) {
|
|
|
3861
3878
|
} }
|
|
3862
3879
|
]
|
|
3863
3880
|
],
|
|
3864
|
-
{
|
|
3865
|
-
evt
|
|
3866
|
-
|
|
3867
|
-
|
|
3881
|
+
{
|
|
3882
|
+
click: (evt) => {
|
|
3883
|
+
evt.stopPropagation();
|
|
3884
|
+
on_chip_click(gobj, entry);
|
|
3885
|
+
},
|
|
3886
|
+
keydown: (evt) => {
|
|
3887
|
+
if (evt.target !== evt.currentTarget) return;
|
|
3888
|
+
if (evt.key === "Enter" || evt.key === " ") {
|
|
3889
|
+
if (evt.key === " ") evt.preventDefault();
|
|
3890
|
+
evt.stopPropagation();
|
|
3891
|
+
on_chip_click(gobj, entry);
|
|
3892
|
+
}
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3868
3895
|
]);
|
|
3869
3896
|
entry.$chip = $chip;
|
|
3870
3897
|
priv.windows.push(entry);
|
|
@@ -12340,9 +12367,10 @@ function navigate_to(gobj, route) {
|
|
|
12340
12367
|
let prev_route = stage.active_route;
|
|
12341
12368
|
if (prev_route && prev_route !== matched_route) {
|
|
12342
12369
|
let prev_gobj = stage.items[prev_route];
|
|
12370
|
+
let $prev = null;
|
|
12343
12371
|
if (prev_gobj) {
|
|
12344
|
-
|
|
12345
|
-
if ($
|
|
12372
|
+
$prev = (0, _yuneta_gobj_js.gobj_read_attr)(prev_gobj, "$container");
|
|
12373
|
+
if ($prev) $prev.classList.add("is-hidden");
|
|
12346
12374
|
}
|
|
12347
12375
|
let prev_entry = priv.item_index[prev_route];
|
|
12348
12376
|
if (prev_entry && prev_entry.target && prev_entry.target.lifecycle === "lazy_destroy") {
|
|
@@ -12352,6 +12380,7 @@ function navigate_to(gobj, route) {
|
|
|
12352
12380
|
} catch (e) {
|
|
12353
12381
|
(0, _yuneta_gobj_js.log_warning)(`C_YUI_SHELL: lazy_destroy of '${prev_route}' failed: ${e}`);
|
|
12354
12382
|
}
|
|
12383
|
+
if ($prev && $prev.parentNode) $prev.parentNode.removeChild($prev);
|
|
12355
12384
|
delete stage.items[prev_route];
|
|
12356
12385
|
}
|
|
12357
12386
|
}
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SDATA, SDATA_END, clean_name, createElement2, createOneHtml, create_template_record, data_type_t, debounce, duplicate_objects, empty_string, escapeHtml, event_flag_t, gclass_create, gclass_flag_t, getPositionRelativeToBody, gobj_command, gobj_create, gobj_create_service, gobj_current_state, gobj_default_service, gobj_destroy, gobj_find_child, gobj_find_service, gobj_full_name, gobj_gclass_name, gobj_has_attr, gobj_is_playing, gobj_is_pure_child, gobj_is_running, gobj_is_service, gobj_is_volatil, gobj_match_children, gobj_name, gobj_parent, gobj_publish_event, gobj_read_attr, gobj_read_bool_attr, gobj_read_integer_attr, gobj_read_pointer_attr, gobj_read_str_attr, gobj_save_persistent_attrs, gobj_send_event, gobj_set_trace_machine_format, gobj_short_name, gobj_start, gobj_stop, gobj_stop_children, gobj_subscribe_event, gobj_unsubscribe_event, gobj_write_attr, gobj_write_bool_attr, gobj_write_integer_attr, gobj_write_str_attr, gobj_yuno, is_array, is_boolean, is_date, is_gobj, is_null, is_number, is_object, is_pure_number, is_string, json_deep_copy, json_object_size, json_object_update, json_object_update_missing, json_size, kw_clone_by_keys, kw_flag_t, kw_get_dict, kw_get_dict_value, kw_get_int, kw_get_local_storage_value, kw_get_str, kw_has_key, kw_set_dict_value, kw_set_local_storage_value, kwid_find_one_record, kwid_get_ids, kwid_new_dict, list2options, log_error, log_warning, msg_iev_get_stack, parseBoolean, parseSVG, refresh_language, safeSrc, sdata_flag_t, set_log_callback, sprintf, str_in_list, template_get_field_desc, trace_json, trace_msg, treedb_decoder_fkey, treedb_encoder_fkey, treedb_get_field_desc, treedb_hook_data_size } from "@yuneta/gobj-js";
|
|
1
|
+
import { SDATA, SDATA_END, clean_name, createElement2, createOneHtml, create_template_record, data_type_t, debounce, duplicate_objects, empty_string, escapeHtml, event_flag_t, gclass_create, gclass_flag_t, getPositionRelativeToBody, gobj_command, gobj_create, gobj_create_service, gobj_current_state, gobj_default_service, gobj_destroy, gobj_find_child, gobj_find_service, gobj_full_name, gobj_gclass_name, gobj_has_attr, gobj_is_destroying, gobj_is_playing, gobj_is_pure_child, gobj_is_running, gobj_is_service, gobj_is_volatil, gobj_match_children, gobj_name, gobj_parent, gobj_publish_event, gobj_read_attr, gobj_read_bool_attr, gobj_read_integer_attr, gobj_read_pointer_attr, gobj_read_str_attr, gobj_save_persistent_attrs, gobj_send_event, gobj_set_trace_machine_format, gobj_short_name, gobj_start, gobj_stop, gobj_stop_children, gobj_subscribe_event, gobj_unsubscribe_event, gobj_write_attr, gobj_write_bool_attr, gobj_write_integer_attr, gobj_write_str_attr, gobj_yuno, is_array, is_boolean, is_date, is_gobj, is_null, is_number, is_object, is_pure_number, is_string, json_deep_copy, json_object_size, json_object_update, json_object_update_missing, json_size, kw_clone_by_keys, kw_flag_t, kw_get_dict, kw_get_dict_value, kw_get_int, kw_get_local_storage_value, kw_get_str, kw_has_key, kw_set_dict_value, kw_set_local_storage_value, kwid_find_one_record, kwid_get_ids, kwid_new_dict, list2options, log_error, log_warning, msg_iev_get_stack, parseBoolean, parseSVG, refresh_language, safeSrc, sdata_flag_t, set_log_callback, sprintf, str_in_list, template_get_field_desc, trace_json, trace_msg, treedb_decoder_fkey, treedb_encoder_fkey, treedb_get_field_desc, treedb_hook_data_size } from "@yuneta/gobj-js";
|
|
2
2
|
import i18next, { t } from "i18next";
|
|
3
3
|
import TomSelect from "tom-select";
|
|
4
4
|
import { TabulatorFull } from "tabulator-tables";
|
|
@@ -811,6 +811,17 @@ function update_stats() {
|
|
|
811
811
|
});
|
|
812
812
|
}
|
|
813
813
|
/************************************************************
|
|
814
|
+
* Append a row and follow the tail — but only when the user is
|
|
815
|
+
* already at (or near) the bottom; a reader scrolled up into the
|
|
816
|
+
* backlog must not be yanked down. Container-local on purpose:
|
|
817
|
+
* scrollIntoView also scrolls the host page's ancestors.
|
|
818
|
+
************************************************************/
|
|
819
|
+
function append_and_follow(logger, node) {
|
|
820
|
+
let at_bottom = logger.scrollHeight - logger.scrollTop - logger.clientHeight < 40;
|
|
821
|
+
logger.appendChild(node);
|
|
822
|
+
if (at_bottom) logger.scrollTop = logger.scrollHeight;
|
|
823
|
+
}
|
|
824
|
+
/************************************************************
|
|
814
825
|
* Append one inter-event message. Kept in a bounded buffer so
|
|
815
826
|
* view/filter switches repaint from memory. Shared by the legacy
|
|
816
827
|
* C_YUI_WINDOW (setup_dev) and the modal (build_dev_panel).
|
|
@@ -871,8 +882,7 @@ function info_traffic(title, msg, direction, size) {
|
|
|
871
882
|
entry.$node = node;
|
|
872
883
|
let ph = logger.querySelector(".YDEV_EMPTY");
|
|
873
884
|
if (ph) ph.remove();
|
|
874
|
-
logger
|
|
875
|
-
node.scrollIntoView({ block: "end" });
|
|
885
|
+
append_and_follow(logger, node);
|
|
876
886
|
}
|
|
877
887
|
update_stats();
|
|
878
888
|
}
|
|
@@ -926,8 +936,7 @@ function info_log(level, msg, hora) {
|
|
|
926
936
|
entry.$node = node;
|
|
927
937
|
let ph = logger.querySelector(".YDEV_EMPTY");
|
|
928
938
|
if (ph) ph.remove();
|
|
929
|
-
logger
|
|
930
|
-
node.scrollIntoView({ block: "end" });
|
|
939
|
+
append_and_follow(logger, node);
|
|
931
940
|
}
|
|
932
941
|
update_stats();
|
|
933
942
|
} finally {
|
|
@@ -1056,6 +1065,11 @@ function traffic_to_text() {
|
|
|
1056
1065
|
let out = [];
|
|
1057
1066
|
for (let e of TRAFFIC_LOG) {
|
|
1058
1067
|
if (entry_hidden(e, ctx)) continue;
|
|
1068
|
+
if (e.kind === "log") {
|
|
1069
|
+
out.push(`${e.ts} ${e.level}: ${e.text}`);
|
|
1070
|
+
out.push("");
|
|
1071
|
+
continue;
|
|
1072
|
+
}
|
|
1059
1073
|
let head = `${e.ts} ${dir_arrow(e.dir)} ${e.title ? "[" + e.title + "] " : ""}${e.event}${e.command ? " " + e.command : ""}`;
|
|
1060
1074
|
out.push(head);
|
|
1061
1075
|
let payload = e.kw ? e.kw : e.jn;
|
|
@@ -2852,7 +2866,7 @@ function resolve_manager(gobj) {
|
|
|
2852
2866
|
let m = gobj_read_pointer_attr(gobj, "manager");
|
|
2853
2867
|
if (!m) return null;
|
|
2854
2868
|
if (typeof m === "string") {
|
|
2855
|
-
m = gobj_find_service(m, false);
|
|
2869
|
+
m = gobj_find_service(m, false) || null;
|
|
2856
2870
|
gobj_write_attr(gobj, "manager", m);
|
|
2857
2871
|
}
|
|
2858
2872
|
return m;
|
|
@@ -3149,13 +3163,14 @@ function close_window(gobj) {
|
|
|
3149
3163
|
let kw_close = { abort_close: false };
|
|
3150
3164
|
gobj_publish_event(gobj, "EV_WINDOW_TO_CLOSE", kw_close);
|
|
3151
3165
|
let on_close = gobj_read_attr(gobj, "on_close");
|
|
3152
|
-
if (on_close) on_close();
|
|
3153
3166
|
if (!kw_close.abort_close) {
|
|
3167
|
+
if (on_close) on_close();
|
|
3154
3168
|
if (gobj_is_running(gobj)) gobj_stop(gobj);
|
|
3155
3169
|
gobj_stop_children(gobj);
|
|
3156
3170
|
gobj_destroy(gobj);
|
|
3157
3171
|
} else if (kw_close.warning) get_yesnocancel(kw_close.warning, function(resp) {
|
|
3158
3172
|
if (resp === "yes") {
|
|
3173
|
+
if (on_close) on_close();
|
|
3159
3174
|
gobj_stop(gobj);
|
|
3160
3175
|
gobj_stop_children(gobj);
|
|
3161
3176
|
gobj_destroy(gobj);
|
|
@@ -3237,6 +3252,9 @@ function mvStart(gobj, evt) {
|
|
|
3237
3252
|
$container.style.transform = "translate3d(" + div_x + "px, " + div_y + "px, 0px)";
|
|
3238
3253
|
}
|
|
3239
3254
|
function mvStop(evt) {
|
|
3255
|
+
document.removeEventListener("pointermove", mvMove);
|
|
3256
|
+
document.removeEventListener("pointerup", mvStop);
|
|
3257
|
+
if (gobj_is_destroying(gobj)) return;
|
|
3240
3258
|
div_x = evt.screenX - x;
|
|
3241
3259
|
div_y = evt.screenY - y;
|
|
3242
3260
|
let xx = pos_x + div_x;
|
|
@@ -3245,8 +3263,6 @@ function mvStart(gobj, evt) {
|
|
|
3245
3263
|
$container.style.top = yy + "px";
|
|
3246
3264
|
$container.style.transition = "none";
|
|
3247
3265
|
$container.style.transform = "translate3d(0px, 0px, 0px)";
|
|
3248
|
-
document.removeEventListener("pointermove", mvMove);
|
|
3249
|
-
document.removeEventListener("pointerup", mvStop);
|
|
3250
3266
|
let rect = $container.getBoundingClientRect();
|
|
3251
3267
|
gobj_write_integer_attr(gobj, "x", rect.x);
|
|
3252
3268
|
gobj_write_integer_attr(gobj, "y", rect.y);
|
|
@@ -3286,12 +3302,13 @@ function rsStart(gobj, evt) {
|
|
|
3286
3302
|
$container.style.height = height + rel_h + "px";
|
|
3287
3303
|
}
|
|
3288
3304
|
function rsStop(evt) {
|
|
3305
|
+
document.removeEventListener("pointermove", rsMove);
|
|
3306
|
+
document.removeEventListener("pointerup", rsStop);
|
|
3307
|
+
if (gobj_is_destroying(gobj)) return;
|
|
3289
3308
|
rel_w = evt.pageX - pageX;
|
|
3290
3309
|
rel_h = evt.pageY - pageY;
|
|
3291
3310
|
$container.style.width = width + rel_w + "px";
|
|
3292
3311
|
$container.style.height = height + rel_h + "px";
|
|
3293
|
-
document.removeEventListener("pointermove", rsMove);
|
|
3294
|
-
document.removeEventListener("pointerup", rsStop);
|
|
3295
3312
|
let rect = $container.getBoundingClientRect();
|
|
3296
3313
|
if (gobj_read_bool_attr(gobj, "force_center")) {
|
|
3297
3314
|
rect = do_center(gobj, rect.x, rect.y, rect.width, rect.height);
|
|
@@ -3670,7 +3687,7 @@ function build_dock(gobj) {
|
|
|
3670
3687
|
ensure_dock_style();
|
|
3671
3688
|
gobj_write_attr(gobj, "$container", createElement2([
|
|
3672
3689
|
"div",
|
|
3673
|
-
{ class: "yui-dock is-empty" },
|
|
3690
|
+
{ class: "C_YUI_WINDOW_MANAGER yui-dock is-empty" },
|
|
3674
3691
|
[]
|
|
3675
3692
|
]));
|
|
3676
3693
|
apply_placement(gobj);
|
|
@@ -3856,10 +3873,20 @@ function ac_register_window(gobj, event, kw, src) {
|
|
|
3856
3873
|
} }
|
|
3857
3874
|
]
|
|
3858
3875
|
],
|
|
3859
|
-
{
|
|
3860
|
-
evt
|
|
3861
|
-
|
|
3862
|
-
|
|
3876
|
+
{
|
|
3877
|
+
click: (evt) => {
|
|
3878
|
+
evt.stopPropagation();
|
|
3879
|
+
on_chip_click(gobj, entry);
|
|
3880
|
+
},
|
|
3881
|
+
keydown: (evt) => {
|
|
3882
|
+
if (evt.target !== evt.currentTarget) return;
|
|
3883
|
+
if (evt.key === "Enter" || evt.key === " ") {
|
|
3884
|
+
if (evt.key === " ") evt.preventDefault();
|
|
3885
|
+
evt.stopPropagation();
|
|
3886
|
+
on_chip_click(gobj, entry);
|
|
3887
|
+
}
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3863
3890
|
]);
|
|
3864
3891
|
entry.$chip = $chip;
|
|
3865
3892
|
priv.windows.push(entry);
|
|
@@ -12335,9 +12362,10 @@ function navigate_to(gobj, route) {
|
|
|
12335
12362
|
let prev_route = stage.active_route;
|
|
12336
12363
|
if (prev_route && prev_route !== matched_route) {
|
|
12337
12364
|
let prev_gobj = stage.items[prev_route];
|
|
12365
|
+
let $prev = null;
|
|
12338
12366
|
if (prev_gobj) {
|
|
12339
|
-
|
|
12340
|
-
if ($
|
|
12367
|
+
$prev = gobj_read_attr(prev_gobj, "$container");
|
|
12368
|
+
if ($prev) $prev.classList.add("is-hidden");
|
|
12341
12369
|
}
|
|
12342
12370
|
let prev_entry = priv.item_index[prev_route];
|
|
12343
12371
|
if (prev_entry && prev_entry.target && prev_entry.target.lifecycle === "lazy_destroy") {
|
|
@@ -12347,6 +12375,7 @@ function navigate_to(gobj, route) {
|
|
|
12347
12375
|
} catch (e) {
|
|
12348
12376
|
log_warning(`C_YUI_SHELL: lazy_destroy of '${prev_route}' failed: ${e}`);
|
|
12349
12377
|
}
|
|
12378
|
+
if ($prev && $prev.parentNode) $prev.parentNode.removeChild($prev);
|
|
12350
12379
|
delete stage.items[prev_route];
|
|
12351
12380
|
}
|
|
12352
12381
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuneta/gobj-ui",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/gobj-ui.cjs.js",
|
|
6
6
|
"module": "dist/gobj-ui.es.js",
|
|
@@ -29,13 +29,13 @@
|
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@rollup/plugin-terser": "^1.0.0",
|
|
31
31
|
"@vitest/coverage-v8": "^4.1.6",
|
|
32
|
-
"@yuneta/gobj-js": "^7.
|
|
32
|
+
"@yuneta/gobj-js": "^7.7.0",
|
|
33
33
|
"vite": "^8.0.10",
|
|
34
34
|
"vitest": "^4.1.6"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@antv/g6": "^5.1.0",
|
|
38
|
-
"@yuneta/gobj-js": "^7.
|
|
38
|
+
"@yuneta/gobj-js": "^7.7.0",
|
|
39
39
|
"bulma": "^1.0.4",
|
|
40
40
|
"i18next": "^26.0.7",
|
|
41
41
|
"maplibre-gl": "^5.24.0",
|
package/src/c_yui_shell.js
CHANGED
|
@@ -1050,10 +1050,11 @@ function navigate_to(gobj, route)
|
|
|
1050
1050
|
let prev_route = stage.active_route;
|
|
1051
1051
|
if(prev_route && prev_route !== matched_route) {
|
|
1052
1052
|
let prev_gobj = stage.items[prev_route];
|
|
1053
|
+
let $prev = null;
|
|
1053
1054
|
if(prev_gobj) {
|
|
1054
|
-
|
|
1055
|
-
if($
|
|
1056
|
-
$
|
|
1055
|
+
$prev = gobj_read_attr(prev_gobj, "$container");
|
|
1056
|
+
if($prev) {
|
|
1057
|
+
$prev.classList.add("is-hidden");
|
|
1057
1058
|
}
|
|
1058
1059
|
}
|
|
1059
1060
|
/* lazy_destroy: drop previous on exit */
|
|
@@ -1065,6 +1066,14 @@ function navigate_to(gobj, route)
|
|
|
1065
1066
|
} catch(e) {
|
|
1066
1067
|
log_warning(`C_YUI_SHELL: lazy_destroy of '${prev_route}' failed: ${e}`);
|
|
1067
1068
|
}
|
|
1069
|
+
/* The shell appended $container on mount (build_view_gobj), so
|
|
1070
|
+
* remove it symmetrically here: a view that doesn't remove its
|
|
1071
|
+
* own container in mt_destroy would otherwise leak a hidden
|
|
1072
|
+
* copy in the stage on every revisit — and any fixed DOM id
|
|
1073
|
+
* inside it then shadows the fresh instance's. */
|
|
1074
|
+
if($prev && $prev.parentNode) {
|
|
1075
|
+
$prev.parentNode.removeChild($prev);
|
|
1076
|
+
}
|
|
1068
1077
|
delete stage.items[prev_route];
|
|
1069
1078
|
}
|
|
1070
1079
|
}
|
package/src/c_yui_window.js
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
gobj_stop,
|
|
39
39
|
gobj_stop_children,
|
|
40
40
|
gobj_is_running,
|
|
41
|
+
gobj_is_destroying,
|
|
41
42
|
refresh_language,
|
|
42
43
|
} from "@yuneta/gobj-js";
|
|
43
44
|
|
|
@@ -287,7 +288,7 @@ function resolve_manager(gobj)
|
|
|
287
288
|
return null;
|
|
288
289
|
}
|
|
289
290
|
if(typeof m === "string") {
|
|
290
|
-
m = gobj_find_service(m, false);
|
|
291
|
+
m = gobj_find_service(m, false) || null;
|
|
291
292
|
gobj_write_attr(gobj, "manager", m);
|
|
292
293
|
}
|
|
293
294
|
return m;
|
|
@@ -656,12 +657,15 @@ function close_window(gobj)
|
|
|
656
657
|
abort_close: false
|
|
657
658
|
};
|
|
658
659
|
gobj_publish_event(gobj, "EV_WINDOW_TO_CLOSE", kw_close);
|
|
660
|
+
|
|
661
|
+
/* on_close only fires when the close actually proceeds:
|
|
662
|
+
* a subscriber may abort it and keep the window open. */
|
|
659
663
|
let on_close = gobj_read_attr(gobj, "on_close");
|
|
660
|
-
if(on_close) {
|
|
661
|
-
on_close();
|
|
662
|
-
}
|
|
663
664
|
|
|
664
665
|
if(!kw_close.abort_close) {
|
|
666
|
+
if(on_close) {
|
|
667
|
+
on_close();
|
|
668
|
+
}
|
|
665
669
|
if(gobj_is_running(gobj)) {
|
|
666
670
|
gobj_stop(gobj);
|
|
667
671
|
}
|
|
@@ -670,6 +674,9 @@ function close_window(gobj)
|
|
|
670
674
|
} else if(kw_close.warning) {
|
|
671
675
|
get_yesnocancel(kw_close.warning, function(resp) {
|
|
672
676
|
if(resp === "yes") {
|
|
677
|
+
if(on_close) {
|
|
678
|
+
on_close();
|
|
679
|
+
}
|
|
673
680
|
gobj_stop(gobj);
|
|
674
681
|
gobj_stop_children(gobj);
|
|
675
682
|
gobj_destroy(gobj);
|
|
@@ -794,6 +801,14 @@ function mvStart(gobj, evt)
|
|
|
794
801
|
|
|
795
802
|
function mvStop(evt)
|
|
796
803
|
{
|
|
804
|
+
document.removeEventListener('pointermove', mvMove);
|
|
805
|
+
document.removeEventListener('pointerup', mvStop);
|
|
806
|
+
|
|
807
|
+
/* The window can be destroyed mid-drag (e.g. dock ✕). */
|
|
808
|
+
if(gobj_is_destroying(gobj)) {
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
|
|
797
812
|
div_x = (evt.screenX - x);
|
|
798
813
|
div_y = (evt.screenY - y);
|
|
799
814
|
let xx = pos_x + div_x;
|
|
@@ -804,9 +819,6 @@ function mvStart(gobj, evt)
|
|
|
804
819
|
$container.style.transition = 'none';
|
|
805
820
|
$container.style.transform = 'translate3d(0px, 0px, 0px)';
|
|
806
821
|
|
|
807
|
-
document.removeEventListener('pointermove', mvMove);
|
|
808
|
-
document.removeEventListener('pointerup', mvStop);
|
|
809
|
-
|
|
810
822
|
// trigger event
|
|
811
823
|
let rect = $container.getBoundingClientRect();
|
|
812
824
|
|
|
@@ -859,15 +871,20 @@ function rsStart(gobj, evt)
|
|
|
859
871
|
|
|
860
872
|
function rsStop(evt)
|
|
861
873
|
{
|
|
874
|
+
document.removeEventListener('pointermove', rsMove);
|
|
875
|
+
document.removeEventListener('pointerup', rsStop);
|
|
876
|
+
|
|
877
|
+
/* The window can be destroyed mid-resize (e.g. dock ✕). */
|
|
878
|
+
if(gobj_is_destroying(gobj)) {
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
|
|
862
882
|
rel_w = evt.pageX - pageX;
|
|
863
883
|
rel_h = evt.pageY - pageY;
|
|
864
884
|
|
|
865
885
|
$container.style.width = (width + rel_w) +'px';
|
|
866
886
|
$container.style.height = (height + rel_h) +'px';
|
|
867
887
|
|
|
868
|
-
document.removeEventListener('pointermove', rsMove);
|
|
869
|
-
document.removeEventListener('pointerup', rsStop);
|
|
870
|
-
|
|
871
888
|
// trigger event
|
|
872
889
|
let rect = $container.getBoundingClientRect();
|
|
873
890
|
if(gobj_read_bool_attr(gobj, "force_center")) {
|
|
@@ -228,7 +228,7 @@ function build_dock(gobj)
|
|
|
228
228
|
{
|
|
229
229
|
ensure_dock_style();
|
|
230
230
|
|
|
231
|
-
let $dock = createElement2(['div', {class: 'yui-dock is-empty'}, []]);
|
|
231
|
+
let $dock = createElement2(['div', {class: 'C_YUI_WINDOW_MANAGER yui-dock is-empty'}, []]);
|
|
232
232
|
gobj_write_attr(gobj, "$container", $dock);
|
|
233
233
|
|
|
234
234
|
apply_placement(gobj);
|
|
@@ -462,6 +462,20 @@ function ac_register_window(gobj, event, kw, src)
|
|
|
462
462
|
click: (evt) => {
|
|
463
463
|
evt.stopPropagation();
|
|
464
464
|
on_chip_click(gobj, entry);
|
|
465
|
+
},
|
|
466
|
+
keydown: (evt) => {
|
|
467
|
+
/* Only the chip itself — Enter on the inner ✕ button
|
|
468
|
+
* already fires its own click. */
|
|
469
|
+
if(evt.target !== evt.currentTarget) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
if(evt.key === "Enter" || evt.key === " ") {
|
|
473
|
+
if(evt.key === " ") {
|
|
474
|
+
evt.preventDefault();
|
|
475
|
+
}
|
|
476
|
+
evt.stopPropagation();
|
|
477
|
+
on_chip_click(gobj, entry);
|
|
478
|
+
}
|
|
465
479
|
}
|
|
466
480
|
}]
|
|
467
481
|
);
|
package/src/yui_dev.js
CHANGED
|
@@ -808,6 +808,22 @@ function update_stats()
|
|
|
808
808
|
});
|
|
809
809
|
}
|
|
810
810
|
|
|
811
|
+
/************************************************************
|
|
812
|
+
* Append a row and follow the tail — but only when the user is
|
|
813
|
+
* already at (or near) the bottom; a reader scrolled up into the
|
|
814
|
+
* backlog must not be yanked down. Container-local on purpose:
|
|
815
|
+
* scrollIntoView also scrolls the host page's ancestors.
|
|
816
|
+
************************************************************/
|
|
817
|
+
function append_and_follow(logger, node)
|
|
818
|
+
{
|
|
819
|
+
let at_bottom =
|
|
820
|
+
logger.scrollHeight - logger.scrollTop - logger.clientHeight < 40;
|
|
821
|
+
logger.appendChild(node);
|
|
822
|
+
if(at_bottom) {
|
|
823
|
+
logger.scrollTop = logger.scrollHeight;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
811
827
|
/************************************************************
|
|
812
828
|
* Append one inter-event message. Kept in a bounded buffer so
|
|
813
829
|
* view/filter switches repaint from memory. Shared by the legacy
|
|
@@ -886,8 +902,7 @@ function info_traffic(title, msg, direction, size)
|
|
|
886
902
|
if(ph) {
|
|
887
903
|
ph.remove();
|
|
888
904
|
}
|
|
889
|
-
logger
|
|
890
|
-
node.scrollIntoView({block: "end"});
|
|
905
|
+
append_and_follow(logger, node);
|
|
891
906
|
}
|
|
892
907
|
update_stats();
|
|
893
908
|
}
|
|
@@ -956,8 +971,7 @@ function info_log(level, msg, hora)
|
|
|
956
971
|
if(ph) {
|
|
957
972
|
ph.remove();
|
|
958
973
|
}
|
|
959
|
-
logger
|
|
960
|
-
node.scrollIntoView({block: "end"});
|
|
974
|
+
append_and_follow(logger, node);
|
|
961
975
|
}
|
|
962
976
|
update_stats();
|
|
963
977
|
} finally {
|
|
@@ -1130,6 +1144,12 @@ function traffic_to_text()
|
|
|
1130
1144
|
if(entry_hidden(e, ctx)) {
|
|
1131
1145
|
continue;
|
|
1132
1146
|
}
|
|
1147
|
+
if(e.kind === "log") {
|
|
1148
|
+
/* Mirrored log/automata line: no event/kw — serialize as shown. */
|
|
1149
|
+
out.push(`${e.ts} ${e.level}: ${e.text}`);
|
|
1150
|
+
out.push("");
|
|
1151
|
+
continue;
|
|
1152
|
+
}
|
|
1133
1153
|
let head = `${e.ts} ${dir_arrow(e.dir)} ` +
|
|
1134
1154
|
`${e.title ? "[" + e.title + "] " : ""}${e.event}` +
|
|
1135
1155
|
`${e.command ? " " + e.command : ""}`;
|