@yuneta/gobj-ui 7.23.139 → 7.23.141
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 +99 -26
- package/dist/gobj-ui.cjs.js +384 -112
- package/dist/gobj-ui.es.js +384 -112
- package/package.json +2 -2
- package/src/c_g6_nodes_tree.js +75 -46
- package/src/c_yui_node.js +6 -0
- package/src/c_yui_shell.js +54 -0
- package/src/c_yui_treedb_graph.js +146 -21
- package/src/c_yui_treedb_topics.js +62 -16
- package/src/treedb_fold_model.js +133 -1
- package/src/treedb_fold_model.test.js +80 -0
package/dist/gobj-ui.es.js
CHANGED
|
@@ -906,6 +906,7 @@ var PRIVATE_DATA$21 = {
|
|
|
906
906
|
navs: [],
|
|
907
907
|
item_index: {},
|
|
908
908
|
section_pos: {},
|
|
909
|
+
route_mru: [],
|
|
909
910
|
sub_routes: {},
|
|
910
911
|
event_handlers: {},
|
|
911
912
|
hash_handler: null,
|
|
@@ -1614,6 +1615,7 @@ function navigate_to(gobj, route, depth, no_drain) {
|
|
|
1614
1615
|
stage.active_route = matched_route;
|
|
1615
1616
|
gobj_write_attr(gobj, "current_route", route);
|
|
1616
1617
|
remember_position(gobj, route);
|
|
1618
|
+
remember_route(gobj, route);
|
|
1617
1619
|
update_secondary_nav_visibility(gobj, entry);
|
|
1618
1620
|
close_all_drawers(gobj);
|
|
1619
1621
|
close_toolbar_dropdown(gobj);
|
|
@@ -2640,6 +2642,40 @@ function remembered_position(gobj, route) {
|
|
|
2640
2642
|
return last;
|
|
2641
2643
|
}
|
|
2642
2644
|
/************************************************************
|
|
2645
|
+
* Every route the shell lands on, newest last, a route once.
|
|
2646
|
+
* Bounded: it answers "where was the reader last under X", and
|
|
2647
|
+
* a page that has been open all day has no business growing it.
|
|
2648
|
+
************************************************************/
|
|
2649
|
+
var ROUTE_MRU_MAX = 64;
|
|
2650
|
+
function remember_route(gobj, route) {
|
|
2651
|
+
let mru = gobj.priv.route_mru;
|
|
2652
|
+
let i = mru.indexOf(route);
|
|
2653
|
+
if (i >= 0) mru.splice(i, 1);
|
|
2654
|
+
mru.push(route);
|
|
2655
|
+
if (mru.length > ROUTE_MRU_MAX) mru.splice(0, mru.length - ROUTE_MRU_MAX);
|
|
2656
|
+
}
|
|
2657
|
+
/************************************************************
|
|
2658
|
+
* Where the reader last was UNDER `route`: the most recent
|
|
2659
|
+
* visited route that is `route` itself or lies below it, or
|
|
2660
|
+
* `route` when none does. A mirror of the url for the page, like
|
|
2661
|
+
* the section memory -- never stored, never applied on its own:
|
|
2662
|
+
* a control that wants to go back to a view AS IT WAS LEFT asks,
|
|
2663
|
+
* and navigates there itself.
|
|
2664
|
+
*
|
|
2665
|
+
* What it is for: a treedb graph's focus lives in the url
|
|
2666
|
+
* (`<graph>/<topic>`), so a button that opened the bare route
|
|
2667
|
+
* took the focus away every time it was used.
|
|
2668
|
+
************************************************************/
|
|
2669
|
+
function yui_shell_last_route_under(shell_gobj, route) {
|
|
2670
|
+
let priv = shell_gobj && shell_gobj.priv;
|
|
2671
|
+
if (!priv || !is_array(priv.route_mru) || !route) return route;
|
|
2672
|
+
for (let i = priv.route_mru.length - 1; i >= 0; i--) {
|
|
2673
|
+
let r = priv.route_mru[i];
|
|
2674
|
+
if (r === route || r.indexOf(route + "/") === 0) return r;
|
|
2675
|
+
}
|
|
2676
|
+
return route;
|
|
2677
|
+
}
|
|
2678
|
+
/************************************************************
|
|
2643
2679
|
* Resolve the shell that governs `gobj`: the nearest
|
|
2644
2680
|
* C_YUI_SHELL ancestor, else the last shell created on the
|
|
2645
2681
|
* page (apps have exactly one). Null when no shell exists —
|
|
@@ -13070,7 +13106,7 @@ function ac_find_nodes$3(gobj, event, kw, src) {
|
|
|
13070
13106
|
/************************************************************
|
|
13071
13107
|
* EV_EXPAND_ALL
|
|
13072
13108
|
************************************************************/
|
|
13073
|
-
function ac_expand_all$
|
|
13109
|
+
function ac_expand_all$2(gobj, event, kw, src) {
|
|
13074
13110
|
let priv = gobj.priv;
|
|
13075
13111
|
if (priv.collapsed.size === 0) return 0;
|
|
13076
13112
|
priv.collapsed.clear();
|
|
@@ -13082,7 +13118,7 @@ function ac_expand_all$4(gobj, event, kw, src) {
|
|
|
13082
13118
|
/************************************************************
|
|
13083
13119
|
* EV_COLLAPSE_ALL — fold every card but the root.
|
|
13084
13120
|
************************************************************/
|
|
13085
|
-
function ac_collapse_all$
|
|
13121
|
+
function ac_collapse_all$2(gobj, event, kw, src) {
|
|
13086
13122
|
let priv = gobj.priv;
|
|
13087
13123
|
let json_data = gobj_read_attr(gobj, "json_data");
|
|
13088
13124
|
if (!json_data) return 0;
|
|
@@ -13382,12 +13418,12 @@ function create_gclass$13(gclass_name) {
|
|
|
13382
13418
|
],
|
|
13383
13419
|
[
|
|
13384
13420
|
"EV_EXPAND_ALL",
|
|
13385
|
-
ac_expand_all$
|
|
13421
|
+
ac_expand_all$2,
|
|
13386
13422
|
null
|
|
13387
13423
|
],
|
|
13388
13424
|
[
|
|
13389
13425
|
"EV_COLLAPSE_ALL",
|
|
13390
|
-
ac_collapse_all$
|
|
13426
|
+
ac_collapse_all$2,
|
|
13391
13427
|
null
|
|
13392
13428
|
],
|
|
13393
13429
|
[
|
|
@@ -14459,7 +14495,7 @@ function ac_search$2(gobj, event, kw, src) {
|
|
|
14459
14495
|
/************************************************************
|
|
14460
14496
|
* EV_EXPAND_ALL — expand every already-loaded container
|
|
14461
14497
|
************************************************************/
|
|
14462
|
-
function ac_expand_all$
|
|
14498
|
+
function ac_expand_all$1(gobj, event, kw, src) {
|
|
14463
14499
|
let priv = gobj.priv;
|
|
14464
14500
|
if (priv.root === null || priv.root === void 0) return 0;
|
|
14465
14501
|
let paths = [];
|
|
@@ -14477,7 +14513,7 @@ function ac_expand_all$3(gobj, event, kw, src) {
|
|
|
14477
14513
|
/************************************************************
|
|
14478
14514
|
* EV_COLLAPSE_ALL
|
|
14479
14515
|
************************************************************/
|
|
14480
|
-
function ac_collapse_all$
|
|
14516
|
+
function ac_collapse_all$1(gobj, event, kw, src) {
|
|
14481
14517
|
gobj.priv.expanded.clear();
|
|
14482
14518
|
render_view$1(gobj);
|
|
14483
14519
|
return 0;
|
|
@@ -14662,12 +14698,12 @@ function create_gclass$12(gclass_name) {
|
|
|
14662
14698
|
],
|
|
14663
14699
|
[
|
|
14664
14700
|
"EV_EXPAND_ALL",
|
|
14665
|
-
ac_expand_all$
|
|
14701
|
+
ac_expand_all$1,
|
|
14666
14702
|
null
|
|
14667
14703
|
],
|
|
14668
14704
|
[
|
|
14669
14705
|
"EV_COLLAPSE_ALL",
|
|
14670
|
-
ac_collapse_all$
|
|
14706
|
+
ac_collapse_all$1,
|
|
14671
14707
|
null
|
|
14672
14708
|
],
|
|
14673
14709
|
[
|
|
@@ -19689,7 +19725,7 @@ function ac_toggle_collapse(gobj, event, kw, src) {
|
|
|
19689
19725
|
/************************************************************
|
|
19690
19726
|
* Force every node visible (overrides threshold).
|
|
19691
19727
|
************************************************************/
|
|
19692
|
-
function ac_expand_all
|
|
19728
|
+
function ac_expand_all(gobj, event, kw, src) {
|
|
19693
19729
|
let priv = gobj.priv;
|
|
19694
19730
|
if (!priv.collapse_state) priv.collapse_state = {};
|
|
19695
19731
|
if (priv.node_by_id) for (let id of Object.keys(priv.node_by_id)) {
|
|
@@ -19702,7 +19738,7 @@ function ac_expand_all$2(gobj, event, kw, src) {
|
|
|
19702
19738
|
/************************************************************
|
|
19703
19739
|
* Collapse every node that has children.
|
|
19704
19740
|
************************************************************/
|
|
19705
|
-
function ac_collapse_all
|
|
19741
|
+
function ac_collapse_all(gobj, event, kw, src) {
|
|
19706
19742
|
let priv = gobj.priv;
|
|
19707
19743
|
if (!priv.collapse_state) priv.collapse_state = {};
|
|
19708
19744
|
if (priv.node_by_id) for (let id of Object.keys(priv.node_by_id)) {
|
|
@@ -20054,12 +20090,12 @@ function create_gclass$9(gclass_name) {
|
|
|
20054
20090
|
],
|
|
20055
20091
|
[
|
|
20056
20092
|
"EV_EXPAND_ALL",
|
|
20057
|
-
ac_expand_all
|
|
20093
|
+
ac_expand_all,
|
|
20058
20094
|
null
|
|
20059
20095
|
],
|
|
20060
20096
|
[
|
|
20061
20097
|
"EV_COLLAPSE_ALL",
|
|
20062
|
-
ac_collapse_all
|
|
20098
|
+
ac_collapse_all,
|
|
20063
20099
|
null
|
|
20064
20100
|
],
|
|
20065
20101
|
[
|
|
@@ -21903,15 +21939,12 @@ function cmd_get_topic_data$1(gobj, cmd, kw, src) {
|
|
|
21903
21939
|
************************************************************/
|
|
21904
21940
|
function build_ui$6(gobj) {
|
|
21905
21941
|
let source_url = gobj_read_str_attr(gobj, "source_url") || "";
|
|
21906
|
-
let
|
|
21907
|
-
let graph_tpl = is_object(routes) && typeof routes.graph === "string" ? routes.graph : "";
|
|
21908
|
-
let graph_href = /\/\{topic\}$/.test(graph_tpl) ? graph_tpl.replace(/\/\{topic\}$/, "") : "";
|
|
21942
|
+
let graph_href = graph_route_of(gobj);
|
|
21909
21943
|
let graph_items = [];
|
|
21910
21944
|
if (graph_href) graph_items.push([
|
|
21911
|
-
"
|
|
21945
|
+
"button",
|
|
21912
21946
|
{
|
|
21913
21947
|
class: "button TREEDB_GRAPH_BTN",
|
|
21914
|
-
href: graph_href,
|
|
21915
21948
|
style: "margin-left:auto;",
|
|
21916
21949
|
title: t("graph"),
|
|
21917
21950
|
"aria-label": t("graph"),
|
|
@@ -21926,7 +21959,11 @@ function build_ui$6(gobj) {
|
|
|
21926
21959
|
"span",
|
|
21927
21960
|
{ i18n: "graph" },
|
|
21928
21961
|
"graph"
|
|
21929
|
-
]]
|
|
21962
|
+
]],
|
|
21963
|
+
{ click: (evt) => {
|
|
21964
|
+
evt.stopPropagation();
|
|
21965
|
+
gobj_send_event(gobj, "EV_OPEN_GRAPH", {}, gobj);
|
|
21966
|
+
} }
|
|
21930
21967
|
]);
|
|
21931
21968
|
let $container = createElement2([
|
|
21932
21969
|
"div",
|
|
@@ -22087,6 +22124,17 @@ function build_ui$6(gobj) {
|
|
|
22087
22124
|
if (gobj_read_bool_attr(gobj, "with_cards_landing")) show_topics_landing(gobj);
|
|
22088
22125
|
}
|
|
22089
22126
|
/************************************************************
|
|
22127
|
+
* The graph's route with no topic: the host's card template
|
|
22128
|
+
* `card_action_routes.graph` without its trailing `/{topic}`,
|
|
22129
|
+
* as a ROUTE (no `#`). "" when the host gives no such template.
|
|
22130
|
+
************************************************************/
|
|
22131
|
+
function graph_route_of(gobj) {
|
|
22132
|
+
let routes = gobj_read_attr(gobj, "card_action_routes");
|
|
22133
|
+
let tpl = is_object(routes) && typeof routes.graph === "string" ? routes.graph : "";
|
|
22134
|
+
if (!/\/\{topic\}$/.test(tpl)) return "";
|
|
22135
|
+
return tpl.replace(/\/\{topic\}$/, "").replace(/^#/, "");
|
|
22136
|
+
}
|
|
22137
|
+
/************************************************************
|
|
22090
22138
|
* Is the backend session live? The Raw JSON viewer issues a remote
|
|
22091
22139
|
* print-tranger, so it only makes sense with a session — the remote
|
|
22092
22140
|
* (C_IEVENT_CLI) is in ST_SESSION exactly while connected.
|
|
@@ -23455,6 +23503,26 @@ function ac_open_json$1(gobj, event, kw, src) {
|
|
|
23455
23503
|
return 0;
|
|
23456
23504
|
}
|
|
23457
23505
|
/********************************************
|
|
23506
|
+
* Open the graph where the reader left it: its last visited
|
|
23507
|
+
* route under the graph's base -- `<graph>/<topic>` when a topic
|
|
23508
|
+
* was focused there -- or the bare base when the graph was never
|
|
23509
|
+
* opened in this page. A user move: pushed, so Back returns.
|
|
23510
|
+
********************************************/
|
|
23511
|
+
function ac_open_graph(gobj, event, kw, src) {
|
|
23512
|
+
let base = graph_route_of(gobj);
|
|
23513
|
+
if (!base) {
|
|
23514
|
+
log_error(`${gobj_short_name(gobj)}: open graph with no graph route`);
|
|
23515
|
+
return -1;
|
|
23516
|
+
}
|
|
23517
|
+
let shell = yui_shell_of(gobj);
|
|
23518
|
+
if (!shell) {
|
|
23519
|
+
log_error(`${gobj_short_name(gobj)}: open graph with no shell`);
|
|
23520
|
+
return -1;
|
|
23521
|
+
}
|
|
23522
|
+
yui_shell_navigate(shell, yui_shell_last_route_under(shell, base), { push: true });
|
|
23523
|
+
return 0;
|
|
23524
|
+
}
|
|
23525
|
+
/********************************************
|
|
23458
23526
|
* The viewer asked to load a collapsed subtree (tranger mode only):
|
|
23459
23527
|
* re-issue print-tranger for that path.
|
|
23460
23528
|
********************************************/
|
|
@@ -23553,6 +23621,11 @@ function create_gclass$6(gclass_name) {
|
|
|
23553
23621
|
ac_open_json$1,
|
|
23554
23622
|
null
|
|
23555
23623
|
],
|
|
23624
|
+
[
|
|
23625
|
+
"EV_OPEN_GRAPH",
|
|
23626
|
+
ac_open_graph,
|
|
23627
|
+
null
|
|
23628
|
+
],
|
|
23556
23629
|
[
|
|
23557
23630
|
"EV_EXPAND_PATH",
|
|
23558
23631
|
ac_json_expand_path$1,
|
|
@@ -23617,6 +23690,7 @@ function create_gclass$6(gclass_name) {
|
|
|
23617
23690
|
["EV_RECORD_WRITTEN", event_flag_t.EVF_OUTPUT_EVENT | event_flag_t.EVF_NO_WARN_SUBS],
|
|
23618
23691
|
["EV_REFRESH_TOPIC", 0],
|
|
23619
23692
|
["EV_OPEN_JSON", 0],
|
|
23693
|
+
["EV_OPEN_GRAPH", 0],
|
|
23620
23694
|
["EV_EXPAND_PATH", 0],
|
|
23621
23695
|
["EV_JSON_CLOSED", 0],
|
|
23622
23696
|
["EV_SHOW", 0],
|
|
@@ -27660,7 +27734,7 @@ function fold_build_model(descs, records, opts) {
|
|
|
27660
27734
|
for (let k of reach_from(nodes, [node.key])) reached.add(k);
|
|
27661
27735
|
}
|
|
27662
27736
|
for (let topic_name of topics) if (roots[topic_name].length > 0) groups.set(fold_root_group_key(topic_name), roots[topic_name]);
|
|
27663
|
-
|
|
27737
|
+
let model = {
|
|
27664
27738
|
nodes,
|
|
27665
27739
|
groups,
|
|
27666
27740
|
topics,
|
|
@@ -27669,8 +27743,52 @@ function fold_build_model(descs, records, opts) {
|
|
|
27669
27743
|
main_topic,
|
|
27670
27744
|
linked,
|
|
27671
27745
|
loose,
|
|
27672
|
-
loose_shown
|
|
27746
|
+
loose_shown,
|
|
27747
|
+
level_of: null,
|
|
27748
|
+
levels: 0
|
|
27673
27749
|
};
|
|
27750
|
+
count_levels(model);
|
|
27751
|
+
return model;
|
|
27752
|
+
}
|
|
27753
|
+
/************************************************************
|
|
27754
|
+
* The LEVELS of the main tree: the roots of the main topic --
|
|
27755
|
+
* and of the topics hung from it, whose roots are the loose
|
|
27756
|
+
* records the reader asked for -- are level 1, their children
|
|
27757
|
+
* level 2, and so on down every hook of every topic that is not
|
|
27758
|
+
* hidden. A node reached by two paths takes the shallowest.
|
|
27759
|
+
*
|
|
27760
|
+
* With no main topic every topic is a tree of its own and all
|
|
27761
|
+
* of them count. A topic the schema does not tie to the main
|
|
27762
|
+
* one is a separate tree, and has no level: the stepper of the
|
|
27763
|
+
* toolbar speaks for the main tree and nothing else, those
|
|
27764
|
+
* trees are opened by their own pills.
|
|
27765
|
+
************************************************************/
|
|
27766
|
+
function count_levels(model) {
|
|
27767
|
+
let level_of = /* @__PURE__ */ new Map();
|
|
27768
|
+
let queue = [];
|
|
27769
|
+
let deepest = 0;
|
|
27770
|
+
for (let topic_name of model.topics) {
|
|
27771
|
+
if (model.main_topic && !model.linked.has(topic_name)) continue;
|
|
27772
|
+
let roots = model.groups.get(fold_root_group_key(topic_name)) || [];
|
|
27773
|
+
for (let key of roots) if (!level_of.has(key)) {
|
|
27774
|
+
level_of.set(key, 1);
|
|
27775
|
+
queue.push(key);
|
|
27776
|
+
}
|
|
27777
|
+
}
|
|
27778
|
+
let head = 0;
|
|
27779
|
+
while (head < queue.length) {
|
|
27780
|
+
let key = queue[head++];
|
|
27781
|
+
let lv = level_of.get(key);
|
|
27782
|
+
if (lv > deepest) deepest = lv;
|
|
27783
|
+
let node = model.nodes.get(key);
|
|
27784
|
+
if (!node) continue;
|
|
27785
|
+
for (let hook of Object.keys(node.hooks)) for (let child of node.hooks[hook]) if (!level_of.has(child)) {
|
|
27786
|
+
level_of.set(child, lv + 1);
|
|
27787
|
+
queue.push(child);
|
|
27788
|
+
}
|
|
27789
|
+
}
|
|
27790
|
+
model.level_of = level_of;
|
|
27791
|
+
model.levels = deepest;
|
|
27674
27792
|
}
|
|
27675
27793
|
/************************************************************
|
|
27676
27794
|
* The topic the schema hangs the others from: the one whose hooks
|
|
@@ -27796,14 +27914,6 @@ function fold_show_more(model, state, group_key) {
|
|
|
27796
27914
|
return n;
|
|
27797
27915
|
}
|
|
27798
27916
|
/************************************************************
|
|
27799
|
-
* Every group open on ALL its children. This is the reader
|
|
27800
|
-
* asking for the whole thing; the pages are for the other way in.
|
|
27801
|
-
************************************************************/
|
|
27802
|
-
function fold_expand_all(model, state) {
|
|
27803
|
-
state.shown.clear();
|
|
27804
|
-
for (let [group_key, list] of model.groups) if (list.length > 0) state.shown.set(group_key, list.length);
|
|
27805
|
-
}
|
|
27806
|
-
/************************************************************
|
|
27807
27917
|
* The roots and nothing else -- the first page of each topic's
|
|
27808
27918
|
* roots, the way the graph looks before anything is opened.
|
|
27809
27919
|
************************************************************/
|
|
@@ -27815,40 +27925,51 @@ function fold_collapse_all(model, state) {
|
|
|
27815
27925
|
}
|
|
27816
27926
|
}
|
|
27817
27927
|
/************************************************************
|
|
27818
|
-
*
|
|
27819
|
-
*
|
|
27820
|
-
*
|
|
27821
|
-
*
|
|
27928
|
+
* The toolbar's STEPPER over the levels of the main tree (see
|
|
27929
|
+
* count_levels): level N shows the roots and N-1 levels under
|
|
27930
|
+
* them. A level is a floor of what is open, not a picture that
|
|
27931
|
+
* replaces it:
|
|
27932
|
+
*
|
|
27933
|
+
* opening to N opens, on its first page, every hook of
|
|
27934
|
+
* every node above level N that is folded;
|
|
27935
|
+
* what the reader opened, and every page
|
|
27936
|
+
* already shown, stays
|
|
27937
|
+
* closing to N folds every hook of every node at level N
|
|
27938
|
+
* or below, and touches nothing above it
|
|
27939
|
+
*
|
|
27940
|
+
* A separate tree (a topic not tied to the main one) has no
|
|
27941
|
+
* level, so neither ever touches it.
|
|
27822
27942
|
************************************************************/
|
|
27823
|
-
function
|
|
27824
|
-
|
|
27825
|
-
|
|
27826
|
-
|
|
27827
|
-
|
|
27828
|
-
|
|
27829
|
-
|
|
27830
|
-
|
|
27831
|
-
|
|
27832
|
-
|
|
27833
|
-
}
|
|
27834
|
-
}
|
|
27835
|
-
while (queue.length) {
|
|
27836
|
-
let key = queue.shift();
|
|
27837
|
-
let lv = level.get(key);
|
|
27838
|
-
if (lv >= depth) continue;
|
|
27943
|
+
function fold_level_clamp(model, level) {
|
|
27944
|
+
let top = model.levels > 0 ? model.levels : 1;
|
|
27945
|
+
level = Math.floor(Number(level)) || 1;
|
|
27946
|
+
if (level < 1) return 1;
|
|
27947
|
+
if (level > top) return top;
|
|
27948
|
+
return level;
|
|
27949
|
+
}
|
|
27950
|
+
function fold_open_levels(model, state, level) {
|
|
27951
|
+
for (let [key, lv] of model.level_of) {
|
|
27952
|
+
if (lv >= level) continue;
|
|
27839
27953
|
let node = model.nodes.get(key);
|
|
27840
27954
|
if (!node) continue;
|
|
27841
27955
|
for (let hook of Object.keys(node.hooks)) {
|
|
27842
|
-
let
|
|
27843
|
-
if (
|
|
27844
|
-
state.shown.set(fold_group_key(key, hook), state.page_size);
|
|
27845
|
-
for (let child of children) if (!level.has(child)) {
|
|
27846
|
-
level.set(child, lv + 1);
|
|
27847
|
-
queue.push(child);
|
|
27848
|
-
}
|
|
27956
|
+
let group_key = fold_group_key(key, hook);
|
|
27957
|
+
if (node.hooks[hook].length > 0 && !fold_is_open(state, group_key)) state.shown.set(group_key, state.page_size);
|
|
27849
27958
|
}
|
|
27850
27959
|
}
|
|
27851
27960
|
}
|
|
27961
|
+
function fold_close_levels(model, state, level) {
|
|
27962
|
+
for (let [key, lv] of model.level_of) {
|
|
27963
|
+
if (lv < level) continue;
|
|
27964
|
+
let node = model.nodes.get(key);
|
|
27965
|
+
if (!node) continue;
|
|
27966
|
+
for (let hook of Object.keys(node.hooks)) state.shown.delete(fold_group_key(key, hook));
|
|
27967
|
+
}
|
|
27968
|
+
}
|
|
27969
|
+
function fold_expand_to_level(model, state, level) {
|
|
27970
|
+
fold_collapse_all(model, state);
|
|
27971
|
+
fold_open_levels(model, state, fold_level_clamp(model, level));
|
|
27972
|
+
}
|
|
27852
27973
|
/************************************************************
|
|
27853
27974
|
* The set of node keys on screen, from the roots down through
|
|
27854
27975
|
* every open group -- and only through open groups whose parent
|
|
@@ -55091,8 +55212,9 @@ function ensure_brush_select_owned() {
|
|
|
55091
55212
|
* The graph opens FOLDED, like a JSON viewer.
|
|
55092
55213
|
*
|
|
55093
55214
|
* Every record of every topic is fetched, but only the ones on
|
|
55094
|
-
* screen become G6 nodes: the roots,
|
|
55095
|
-
*
|
|
55215
|
+
* screen become G6 nodes: the roots, and the MAIN tree open to
|
|
55216
|
+
* the reader's level (`fold_level`, `expand_depth` until they
|
|
55217
|
+
* step it), one page (`fold_page_size`) of children per hook. Each
|
|
55096
55218
|
* card carries a pill per hook that has children -- `▸ devices
|
|
55097
55219
|
* 142` -- which opens or folds that hook; an open hook with more
|
|
55098
55220
|
* children than its page ends in a `+N` chip that opens the next
|
|
@@ -55270,7 +55392,8 @@ var attrs_table$4 = [
|
|
|
55270
55392
|
SDATA(data_type_t.DTP_LIST, "layout_names", sdata_flag_t.SDF_RD, JSON.stringify(Object.keys(_layouts)), "Available layout names (read-only, for parent to query)"),
|
|
55271
55393
|
SDATA(data_type_t.DTP_STRING, "hook_port_position", 0, "bottom", "Hook port position"),
|
|
55272
55394
|
SDATA(data_type_t.DTP_STRING, "fkey_port_position", 0, "top", "Fkey port position"),
|
|
55273
|
-
SDATA(data_type_t.DTP_INTEGER, "expand_depth", 0, 2, "Levels open when a treedb loads: 1 = the roots alone, 2 = the roots and their children. Every open hook shows its first page"),
|
|
55395
|
+
SDATA(data_type_t.DTP_INTEGER, "expand_depth", 0, 2, "Levels open when a treedb loads, until the reader steps (`fold_level`): 1 = the roots alone, 2 = the roots and their children. Every open hook shows its first page"),
|
|
55396
|
+
SDATA(data_type_t.DTP_INTEGER, "fold_level", 0, 0, "The level of the MAIN tree the toolbar's stepper stands on: 1 = its roots, N = N-1 levels under them; 0 = `expand_depth`. The host persists it and sends EV_SET_FOLD_LEVEL; it is published back in EV_LEGEND_STATE (`fold`) with the levels the tree has"),
|
|
55274
55397
|
SDATA(data_type_t.DTP_INTEGER, "fold_page_size", 0, 24, "Children of one hook shown per page; the `+N` chip after the page opens the next one"),
|
|
55275
55398
|
SDATA(data_type_t.DTP_LIST, "hidden_topics", 0, "[]", "Topics left out of the tree: no card, no pill counts them, no edge reaches them"),
|
|
55276
55399
|
SDATA(data_type_t.DTP_STRING, "main_topic", 0, "", "The topic the tree hangs from; empty = deduced (the one whose hooks reach the most others). Its parentless records are the roots; a parentless record of a topic linked to it is LOOSE and shown only on request"),
|
|
@@ -55362,6 +55485,7 @@ var PRIVATE_DATA$4 = {
|
|
|
55362
55485
|
_nodes_total: 0,
|
|
55363
55486
|
_nodes_placed: 0,
|
|
55364
55487
|
expand_depth: 2,
|
|
55488
|
+
fold_level: 0,
|
|
55365
55489
|
fold_page_size: 24,
|
|
55366
55490
|
hidden_topics: null,
|
|
55367
55491
|
main_topic: "",
|
|
@@ -61246,7 +61370,12 @@ function publish_legend_state(gobj, visible) {
|
|
|
61246
61370
|
gobj_publish_event(gobj, "EV_LEGEND_STATE", {
|
|
61247
61371
|
main_topic: model.main_topic,
|
|
61248
61372
|
main_chosen: !!gobj_read_str_attr(gobj, "main_topic"),
|
|
61249
|
-
topics
|
|
61373
|
+
topics,
|
|
61374
|
+
fold: {
|
|
61375
|
+
topic: model.main_topic,
|
|
61376
|
+
level: current_fold_level(gobj),
|
|
61377
|
+
levels: model.levels
|
|
61378
|
+
}
|
|
61250
61379
|
});
|
|
61251
61380
|
}
|
|
61252
61381
|
async function reconcile_fold_apply(gobj, opts, visible) {
|
|
@@ -61551,7 +61680,7 @@ function ac_load_data(gobj, event, kw, src) {
|
|
|
61551
61680
|
}
|
|
61552
61681
|
if (all_loaded && priv.graph) {
|
|
61553
61682
|
rebuild_fold_model(gobj);
|
|
61554
|
-
|
|
61683
|
+
fold_expand_to_level(priv._fold_model, priv._fold_state, current_fold_level(gobj));
|
|
61555
61684
|
count_placed_records(gobj);
|
|
61556
61685
|
let auto_laid = false;
|
|
61557
61686
|
try {
|
|
@@ -61955,19 +62084,46 @@ function ac_show_more(gobj, event, kw, src) {
|
|
|
61955
62084
|
return 0;
|
|
61956
62085
|
}
|
|
61957
62086
|
/************************************************************
|
|
61958
|
-
* The
|
|
61959
|
-
*
|
|
61960
|
-
* the
|
|
62087
|
+
* The level of the main tree the toolbar's stepper stands on:
|
|
62088
|
+
* `fold_level` once the reader has stepped, `expand_depth`
|
|
62089
|
+
* until then, clamped to the levels the tree has.
|
|
61961
62090
|
************************************************************/
|
|
61962
|
-
function
|
|
62091
|
+
function current_fold_level(gobj) {
|
|
61963
62092
|
let priv = gobj.priv;
|
|
61964
|
-
|
|
61965
|
-
|
|
62093
|
+
let level = gobj_read_integer_attr(gobj, "fold_level");
|
|
62094
|
+
if (!(level > 0)) level = gobj_read_integer_attr(gobj, "expand_depth");
|
|
62095
|
+
if (!priv._fold_model) return level;
|
|
62096
|
+
return fold_level_clamp(priv._fold_model, level);
|
|
62097
|
+
}
|
|
62098
|
+
/************************************************************
|
|
62099
|
+
* The toolbar's stepper: one level more or one less of the
|
|
62100
|
+
* MAIN tree (the host owns the number and persists it; this
|
|
62101
|
+
* applies it). Deeper opens the hooks above the new level,
|
|
62102
|
+
* shallower folds from it down -- a level is a floor, not a
|
|
62103
|
+
* picture, so what the reader opened by its pill stays (see
|
|
62104
|
+
* treedb_fold_model). Replaces expand all / collapse all
|
|
62105
|
+
* (7.23.141): the whole treedb at once was the pile, and
|
|
62106
|
+
* closing threw away everything the reader had opened.
|
|
62107
|
+
************************************************************/
|
|
62108
|
+
function ac_set_fold_level(gobj, event, kw, src) {
|
|
62109
|
+
let priv = gobj.priv;
|
|
62110
|
+
let level = Number(kw && kw.level);
|
|
62111
|
+
if (!(level > 0)) {
|
|
62112
|
+
log_error(`${gobj_short_name(gobj)}: fold level '${kw && kw.level}' is not a level`);
|
|
61966
62113
|
return -1;
|
|
61967
62114
|
}
|
|
62115
|
+
if (!priv._fold_model) {
|
|
62116
|
+
gobj_write_attr(gobj, "fold_level", level);
|
|
62117
|
+
return 0;
|
|
62118
|
+
}
|
|
62119
|
+
let from = current_fold_level(gobj);
|
|
62120
|
+
level = fold_level_clamp(priv._fold_model, level);
|
|
62121
|
+
gobj_write_attr(gobj, "fold_level", level);
|
|
62122
|
+
if (level === from) return 0;
|
|
61968
62123
|
let keep = fold_keep_node(gobj);
|
|
61969
62124
|
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
61970
|
-
|
|
62125
|
+
if (level > from) fold_open_levels(priv._fold_model, priv._fold_state, level);
|
|
62126
|
+
else fold_close_levels(priv._fold_model, priv._fold_state, level);
|
|
61971
62127
|
reconcile_fold(gobj, {
|
|
61972
62128
|
keep,
|
|
61973
62129
|
keep_vp: vp
|
|
@@ -61995,29 +62151,11 @@ function fold_keep_node(gobj) {
|
|
|
61995
62151
|
return "";
|
|
61996
62152
|
}
|
|
61997
62153
|
/************************************************************
|
|
61998
|
-
* The roots alone.
|
|
61999
|
-
************************************************************/
|
|
62000
|
-
function ac_collapse_all$1(gobj, event, kw, src) {
|
|
62001
|
-
let priv = gobj.priv;
|
|
62002
|
-
if (!priv._fold_model) {
|
|
62003
|
-
log_error(`${gobj_short_name(gobj)}: collapse all with no tree loaded`);
|
|
62004
|
-
return -1;
|
|
62005
|
-
}
|
|
62006
|
-
let keep = fold_keep_node(gobj);
|
|
62007
|
-
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
62008
|
-
fold_collapse_all(priv._fold_model, priv._fold_state);
|
|
62009
|
-
reconcile_fold(gobj, {
|
|
62010
|
-
keep,
|
|
62011
|
-
keep_vp: vp
|
|
62012
|
-
});
|
|
62013
|
-
return 0;
|
|
62014
|
-
}
|
|
62015
|
-
/************************************************************
|
|
62016
62154
|
* The legend's three settings, from the host, which persists
|
|
62017
62155
|
* them. Each rebuilds the tree; the fold state is kept -- it is
|
|
62018
62156
|
* keyed by group, and a group that is gone is never read -- except
|
|
62019
62157
|
* for a new MAIN topic, whose roots are other roots: the tree
|
|
62020
|
-
* opens again at
|
|
62158
|
+
* opens again at the reader's level, now counted from them.
|
|
62021
62159
|
************************************************************/
|
|
62022
62160
|
function ac_set_hidden_topics(gobj, event, kw, src) {
|
|
62023
62161
|
let priv = gobj.priv;
|
|
@@ -62035,7 +62173,7 @@ function ac_set_main_topic(gobj, event, kw, src) {
|
|
|
62035
62173
|
let keep = fold_keep_node(gobj);
|
|
62036
62174
|
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
62037
62175
|
rebuild_fold_model(gobj);
|
|
62038
|
-
|
|
62176
|
+
fold_expand_to_level(priv._fold_model, priv._fold_state, current_fold_level(gobj));
|
|
62039
62177
|
reconcile_fold(gobj, {
|
|
62040
62178
|
relayout: true,
|
|
62041
62179
|
keep,
|
|
@@ -62596,13 +62734,8 @@ function create_gclass$4(gclass_name) {
|
|
|
62596
62734
|
null
|
|
62597
62735
|
],
|
|
62598
62736
|
[
|
|
62599
|
-
"
|
|
62600
|
-
|
|
62601
|
-
null
|
|
62602
|
-
],
|
|
62603
|
-
[
|
|
62604
|
-
"EV_COLLAPSE_ALL",
|
|
62605
|
-
ac_collapse_all$1,
|
|
62737
|
+
"EV_SET_FOLD_LEVEL",
|
|
62738
|
+
ac_set_fold_level,
|
|
62606
62739
|
null
|
|
62607
62740
|
],
|
|
62608
62741
|
[
|
|
@@ -62745,8 +62878,7 @@ function create_gclass$4(gclass_name) {
|
|
|
62745
62878
|
["EV_CAMERA_CHANGED", event_flag_t.EVF_OUTPUT_EVENT | event_flag_t.EVF_NO_WARN_SUBS],
|
|
62746
62879
|
["EV_TOGGLE_FOLD", 0],
|
|
62747
62880
|
["EV_SHOW_MORE", 0],
|
|
62748
|
-
["
|
|
62749
|
-
["EV_COLLAPSE_ALL", 0],
|
|
62881
|
+
["EV_SET_FOLD_LEVEL", 0],
|
|
62750
62882
|
["EV_SET_HIDDEN_TOPICS", 0],
|
|
62751
62883
|
["EV_SET_MAIN_TOPIC", 0],
|
|
62752
62884
|
["EV_SET_LOOSE_TOPICS", 0],
|
|
@@ -62830,6 +62962,7 @@ var attrs_table$3 = [
|
|
|
62830
62962
|
SDATA(data_type_t.DTP_STRING, "node_mode", sdata_flag_t.SDF_PERSIST, "expanded", "How the records are drawn: `expanded` = the cards with their pills and ports, `compact` = one-line pills with the name, `shape` = coloured figures, the topology alone. User preference"),
|
|
62831
62963
|
SDATA(data_type_t.DTP_BOOLEAN, "node_labels", sdata_flag_t.SDF_PERSIST, true, "A `shape` node says its name under its figure. User preference"),
|
|
62832
62964
|
SDATA(data_type_t.DTP_DICT, "camera", sdata_flag_t.SDF_PERSIST, "{}", "Where the reader left the viewport: {zoom, x, y}. Handed to the engine on creation and written back when a move settles, so the graph opens where it was left. User preference, per treedb"),
|
|
62965
|
+
SDATA(data_type_t.DTP_INTEGER, "fold_level", sdata_flag_t.SDF_PERSIST, 0, "The level of the MAIN tree the toolbar's stepper stands on: 1 = the main topic's roots, N = N-1 levels under them; 0 = never stepped, `expand_depth`. Handed to the engine on creation, so the graph opens at the level it was left. User preference, per treedb"),
|
|
62833
62966
|
SDATA(data_type_t.DTP_POINTER, "gobj_remote_yuno", 0, null, "Remote Yuno to request data"),
|
|
62834
62967
|
SDATA(data_type_t.DTP_STRING, "treedb_name", 0, null, "Remote service treedb name"),
|
|
62835
62968
|
SDATA(data_type_t.DTP_DICT, "descs", 0, null, "Descriptions of topics obtained"),
|
|
@@ -62905,6 +63038,7 @@ function mt_create$3(gobj) {
|
|
|
62905
63038
|
hook_port_position: "bottom",
|
|
62906
63039
|
fkey_port_position: "top",
|
|
62907
63040
|
expand_depth: gobj_read_integer_attr(gobj, "expand_depth"),
|
|
63041
|
+
fold_level: gobj_read_integer_attr(gobj, "fold_level"),
|
|
62908
63042
|
fold_page_size: gobj_read_integer_attr(gobj, "fold_page_size"),
|
|
62909
63043
|
minimap_min_nodes: gobj_read_integer_attr(gobj, "minimap_min_nodes"),
|
|
62910
63044
|
with_gridline: gobj_read_bool_attr(gobj, "with_gridline"),
|
|
@@ -63212,6 +63346,127 @@ function refresh_node_shape_buttons(gobj, $root) {
|
|
|
63212
63346
|
$labels.disabled = mode !== "shape";
|
|
63213
63347
|
}
|
|
63214
63348
|
}
|
|
63349
|
+
/************************************************************
|
|
63350
|
+
* The fold STEPPER: one level less, where the tree stands, one
|
|
63351
|
+
* level more.
|
|
63352
|
+
*
|
|
63353
|
+
* It replaces the fold pair (7.23.141). `expand all` opened every
|
|
63354
|
+
* hook of the treedb -- the pile, on purpose, which on a treedb
|
|
63355
|
+
* of thousands is a pile nobody reads -- and `collapse all` threw
|
|
63356
|
+
* away everything the reader had opened. The stepper walks the
|
|
63357
|
+
* MAIN tree a level at a time, the way the frontend view opens
|
|
63358
|
+
* one level per press: `+` opens the next level under the main
|
|
63359
|
+
* topic's roots, through every topic that is not hidden; `-`
|
|
63360
|
+
* folds the deepest one. Pages and pills the reader opened stay.
|
|
63361
|
+
*
|
|
63362
|
+
* The readout says what the two buttons act on, which no chevron
|
|
63363
|
+
* can: the main topic -- its swatch and its name, which is DATA
|
|
63364
|
+
* and never translated -- and `level/levels`. On a phone the name
|
|
63365
|
+
* goes and the numbers stay. The level is the reader's, per
|
|
63366
|
+
* treedb: persisted (`fold_level`) and handed to the engine on
|
|
63367
|
+
* creation, so a reload opens where it was left.
|
|
63368
|
+
*
|
|
63369
|
+
* Both buttons are born disabled: nothing can be stepped until
|
|
63370
|
+
* the engine has said how deep the tree goes (EV_LEGEND_STATE).
|
|
63371
|
+
************************************************************/
|
|
63372
|
+
function fold_level_items(gobj, wide) {
|
|
63373
|
+
let step_button = (cls, icon, key, event_name) => {
|
|
63374
|
+
return [
|
|
63375
|
+
"button",
|
|
63376
|
+
{
|
|
63377
|
+
class: `${cls} button`,
|
|
63378
|
+
type: "button",
|
|
63379
|
+
style: {
|
|
63380
|
+
height: wide,
|
|
63381
|
+
width: "2.5em"
|
|
63382
|
+
},
|
|
63383
|
+
disabled: true,
|
|
63384
|
+
title: t(key),
|
|
63385
|
+
"data-i18n-title": key,
|
|
63386
|
+
"aria-label": t(key),
|
|
63387
|
+
"data-i18n-aria-label": key
|
|
63388
|
+
},
|
|
63389
|
+
yui_toolbar_icon(icon),
|
|
63390
|
+
{ click: (evt) => {
|
|
63391
|
+
evt.stopPropagation();
|
|
63392
|
+
gobj_send_event(gobj, event_name, {}, gobj);
|
|
63393
|
+
} }
|
|
63394
|
+
];
|
|
63395
|
+
};
|
|
63396
|
+
return [[
|
|
63397
|
+
"div",
|
|
63398
|
+
{
|
|
63399
|
+
class: "GRAPH_FOLD_STEPPER buttons has-addons",
|
|
63400
|
+
style: "margin:0; flex:0 0 auto; flex-wrap:nowrap; align-items:stretch;"
|
|
63401
|
+
},
|
|
63402
|
+
[
|
|
63403
|
+
step_button("GRAPH_FOLD_COLLAPSE", "yi-chevron-right", "collapse one level", "EV_COLLAPSE_LEVEL"),
|
|
63404
|
+
[
|
|
63405
|
+
"div",
|
|
63406
|
+
{
|
|
63407
|
+
class: "GRAPH_FOLD_LEVEL button",
|
|
63408
|
+
style: {
|
|
63409
|
+
height: wide,
|
|
63410
|
+
cursor: "default",
|
|
63411
|
+
gap: ".35rem"
|
|
63412
|
+
},
|
|
63413
|
+
role: "status",
|
|
63414
|
+
title: t("fold level"),
|
|
63415
|
+
"data-i18n-title": "fold level"
|
|
63416
|
+
},
|
|
63417
|
+
[
|
|
63418
|
+
["span", {
|
|
63419
|
+
class: "GRAPH_FOLD_SWATCH",
|
|
63420
|
+
style: "display:none; width:.8rem; height:.8rem; border-radius:3px; flex:0 0 auto; border:1px solid rgba(0,0,0,.25);"
|
|
63421
|
+
}],
|
|
63422
|
+
["span", {
|
|
63423
|
+
class: "GRAPH_FOLD_TOPIC is-hidden-mobile",
|
|
63424
|
+
style: "max-width:10em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:600;"
|
|
63425
|
+
}],
|
|
63426
|
+
[
|
|
63427
|
+
"span",
|
|
63428
|
+
{
|
|
63429
|
+
class: "GRAPH_FOLD_WORD",
|
|
63430
|
+
i18n: "level"
|
|
63431
|
+
},
|
|
63432
|
+
"level"
|
|
63433
|
+
],
|
|
63434
|
+
[
|
|
63435
|
+
"span",
|
|
63436
|
+
{
|
|
63437
|
+
class: "GRAPH_FOLD_COUNT",
|
|
63438
|
+
style: "font-variant-numeric:tabular-nums;"
|
|
63439
|
+
},
|
|
63440
|
+
"–"
|
|
63441
|
+
]
|
|
63442
|
+
]
|
|
63443
|
+
],
|
|
63444
|
+
step_button("GRAPH_FOLD_EXPAND", "yi-chevron-down", "expand one level", "EV_EXPAND_LEVEL")
|
|
63445
|
+
]
|
|
63446
|
+
]];
|
|
63447
|
+
}
|
|
63448
|
+
function refresh_fold_level(gobj) {
|
|
63449
|
+
let priv = gobj.priv;
|
|
63450
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
63451
|
+
if (!$container) return;
|
|
63452
|
+
let $readout = $container.querySelector(".GRAPH_FOLD_LEVEL");
|
|
63453
|
+
if (!$readout) return;
|
|
63454
|
+
let state = priv._legend_state || {};
|
|
63455
|
+
let fold = state.fold || {};
|
|
63456
|
+
let levels = fold.levels > 0 ? fold.levels : 0;
|
|
63457
|
+
let level = fold.level > 0 ? fold.level : 0;
|
|
63458
|
+
let topic = fold.topic || "";
|
|
63459
|
+
let entry = (is_array(state.topics) ? state.topics : []).find((e) => e.topic === topic);
|
|
63460
|
+
let $swatch = $readout.querySelector(".GRAPH_FOLD_SWATCH");
|
|
63461
|
+
$swatch.style.display = topic ? "inline-block" : "none";
|
|
63462
|
+
$swatch.style.background = entry && entry.color || "#94a3b8";
|
|
63463
|
+
$readout.querySelector(".GRAPH_FOLD_TOPIC").textContent = topic;
|
|
63464
|
+
$readout.querySelector(".GRAPH_FOLD_COUNT").textContent = levels ? `${level}/${levels}` : "–";
|
|
63465
|
+
let $collapse = $container.querySelector(".GRAPH_FOLD_COLLAPSE");
|
|
63466
|
+
let $expand = $container.querySelector(".GRAPH_FOLD_EXPAND");
|
|
63467
|
+
if ($collapse) $collapse.disabled = !(levels && level > 1);
|
|
63468
|
+
if ($expand) $expand.disabled = !(levels && level < levels);
|
|
63469
|
+
}
|
|
63215
63470
|
function make_toolbar(gobj) {
|
|
63216
63471
|
let priv = gobj.priv;
|
|
63217
63472
|
let modes = gobj_read_attr(gobj, "operation_modes");
|
|
@@ -63278,7 +63533,7 @@ function make_toolbar(gobj) {
|
|
|
63278
63533
|
} }
|
|
63279
63534
|
]
|
|
63280
63535
|
];
|
|
63281
|
-
let center_items = [...
|
|
63536
|
+
let center_items = [...fold_level_items(gobj, gobj_read_str_attr(gobj, "wide")), ...node_shape_items(gobj, gobj_read_str_attr(gobj, "wide"))];
|
|
63282
63537
|
let backend_items = [[
|
|
63283
63538
|
"button",
|
|
63284
63539
|
{
|
|
@@ -64534,6 +64789,7 @@ function ac_legend_state(gobj, event, kw, src) {
|
|
|
64534
64789
|
let priv = gobj.priv;
|
|
64535
64790
|
priv._legend_state = kw || null;
|
|
64536
64791
|
refresh_legend(gobj);
|
|
64792
|
+
refresh_fold_level(gobj);
|
|
64537
64793
|
return 0;
|
|
64538
64794
|
}
|
|
64539
64795
|
/************************************************************
|
|
@@ -64646,17 +64902,33 @@ function ac_find_nodes(gobj, event, kw, src) {
|
|
|
64646
64902
|
return 0;
|
|
64647
64903
|
}
|
|
64648
64904
|
/************************************************************
|
|
64649
|
-
*
|
|
64650
|
-
*
|
|
64905
|
+
* One press of the fold stepper (EV_EXPAND_LEVEL /
|
|
64906
|
+
* EV_COLLAPSE_LEVEL): the level moves by one, is SAVED (the
|
|
64907
|
+
* reader's, per treedb) and reaches the G6 child, which owns
|
|
64908
|
+
* the tree.
|
|
64909
|
+
*
|
|
64910
|
+
* The readout moves at once, not when the engine speaks again:
|
|
64911
|
+
* a reconcile is asynchronous, and a second press that came
|
|
64912
|
+
* before it would step from the level already left -- two
|
|
64913
|
+
* presses, one level.
|
|
64651
64914
|
************************************************************/
|
|
64652
|
-
function
|
|
64915
|
+
function ac_fold_level_step(gobj, event, kw, src) {
|
|
64653
64916
|
let priv = gobj.priv;
|
|
64654
|
-
|
|
64655
|
-
|
|
64656
|
-
}
|
|
64657
|
-
|
|
64658
|
-
|
|
64659
|
-
|
|
64917
|
+
let fold = priv._legend_state && priv._legend_state.fold;
|
|
64918
|
+
if (!fold || !(fold.levels > 0)) {
|
|
64919
|
+
log_error(`${gobj_short_name(gobj)}: ${event} with no tree to step through`);
|
|
64920
|
+
return -1;
|
|
64921
|
+
}
|
|
64922
|
+
let level = fold.level + (event === "EV_EXPAND_LEVEL" ? 1 : -1);
|
|
64923
|
+
if (level < 1 || level > fold.levels) {
|
|
64924
|
+
log_error(`${gobj_short_name(gobj)}: ${event}: level ${level} out of 1..${fold.levels}`);
|
|
64925
|
+
return -1;
|
|
64926
|
+
}
|
|
64927
|
+
gobj_write_attr(gobj, "fold_level", level);
|
|
64928
|
+
gobj_save_persistent_attrs(gobj, "fold_level");
|
|
64929
|
+
fold.level = level;
|
|
64930
|
+
refresh_fold_level(gobj);
|
|
64931
|
+
if (priv.gobj_nodes_tree) gobj_send_event(priv.gobj_nodes_tree, "EV_SET_FOLD_LEVEL", { level }, gobj);
|
|
64660
64932
|
return 0;
|
|
64661
64933
|
}
|
|
64662
64934
|
/************************************************************
|
|
@@ -64893,13 +65165,13 @@ function create_gclass$3(gclass_name) {
|
|
|
64893
65165
|
null
|
|
64894
65166
|
],
|
|
64895
65167
|
[
|
|
64896
|
-
"
|
|
64897
|
-
|
|
65168
|
+
"EV_EXPAND_LEVEL",
|
|
65169
|
+
ac_fold_level_step,
|
|
64898
65170
|
null
|
|
64899
65171
|
],
|
|
64900
65172
|
[
|
|
64901
|
-
"
|
|
64902
|
-
|
|
65173
|
+
"EV_COLLAPSE_LEVEL",
|
|
65174
|
+
ac_fold_level_step,
|
|
64903
65175
|
null
|
|
64904
65176
|
],
|
|
64905
65177
|
[
|
|
@@ -64984,8 +65256,8 @@ function create_gclass$3(gclass_name) {
|
|
|
64984
65256
|
["EV_SET_OPERATION_MODE", 0],
|
|
64985
65257
|
["EV_SET_FOCUS_TOPIC", 0],
|
|
64986
65258
|
["EV_FIND_NODES", 0],
|
|
64987
|
-
["
|
|
64988
|
-
["
|
|
65259
|
+
["EV_EXPAND_LEVEL", 0],
|
|
65260
|
+
["EV_COLLAPSE_LEVEL", 0],
|
|
64989
65261
|
["EV_SET_NODE_MODE", 0],
|
|
64990
65262
|
["EV_TOGGLE_NODE_LABELS", 0],
|
|
64991
65263
|
["EV_FIND_RESULT", 0],
|