@yuneta/gobj-ui 7.23.24 → 7.23.26
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 +155 -21
- package/dist/gobj-ui.es.js +156 -22
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +21 -1
- package/src/c_yui_gobj_tree_js.js +56 -12
- package/src/c_yui_json.css +32 -0
- package/src/c_yui_json_graph.js +128 -20
- package/src/lib_graph.css +35 -1
- package/src/yui_graph_camera.js +91 -5
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -9679,7 +9679,7 @@ function yui_graph_update_anchor($container, state) {
|
|
|
9679
9679
|
if (!$container) return;
|
|
9680
9680
|
let $btn = $container.querySelector(".EV_TOGGLE_ANCHOR");
|
|
9681
9681
|
if (!$btn) return;
|
|
9682
|
-
set_pressed_state($container, ".EV_TOGGLE_ANCHOR", state
|
|
9682
|
+
set_pressed_state($container, ".EV_TOGGLE_ANCHOR", state === "on");
|
|
9683
9683
|
$btn.classList.toggle("color_pending_state", state === "arming");
|
|
9684
9684
|
$btn.setAttribute("aria-pressed", state === "on" ? "true" : "false");
|
|
9685
9685
|
let key = state === "arming" ? "click the element to centre on" : state === "on" ? "centred: click to release" : "anchor view";
|
|
@@ -9695,21 +9695,55 @@ function yui_graph_update_anchor($container, state) {
|
|
|
9695
9695
|
* the zoom is what the reader asked for, the centring is what
|
|
9696
9696
|
* keeps the thing they are reading under their eyes.
|
|
9697
9697
|
*
|
|
9698
|
+
* The translate is computed and applied HERE rather than
|
|
9699
|
+
* delegated to `graph.focusElement()`, which is the obvious
|
|
9700
|
+
* call and does NOT work on these graphs. Measured: it
|
|
9701
|
+
* resolves, having computed the very offset wanted -- `[0,
|
|
9702
|
+
* 306]` for a card 306px above centre -- and the camera does
|
|
9703
|
+
* not move. `getPosition()` reads the same before and after,
|
|
9704
|
+
* and so does the card's box on screen. Three public calls do
|
|
9705
|
+
* move it, so that is what is used.
|
|
9706
|
+
*
|
|
9698
9707
|
* Guarded on every side because it runs on every wheel notch:
|
|
9699
9708
|
* a graph mid-rebuild, an anchor whose node went away with a
|
|
9700
|
-
* fold, a G6
|
|
9709
|
+
* fold, a G6 missing one of these calls -- none of those is
|
|
9701
9710
|
* an error worth a log line per notch, they are all "there is
|
|
9702
9711
|
* nothing to centre right now".
|
|
9703
9712
|
************************************************************/
|
|
9704
|
-
|
|
9713
|
+
var __centring__ = /* @__PURE__ */ new WeakMap();
|
|
9714
|
+
async function yui_graph_center_on(graph, node_id) {
|
|
9705
9715
|
if (!graph || !node_id) return false;
|
|
9716
|
+
let st = __centring__.get(graph);
|
|
9717
|
+
if (st && st.running) {
|
|
9718
|
+
st.again = node_id;
|
|
9719
|
+
return true;
|
|
9720
|
+
}
|
|
9721
|
+
__centring__.set(graph, {
|
|
9722
|
+
running: true,
|
|
9723
|
+
again: null
|
|
9724
|
+
});
|
|
9706
9725
|
try {
|
|
9707
9726
|
if (typeof graph.getElementData === "function" && !graph.getElementData(node_id)) return false;
|
|
9708
|
-
if (typeof graph.
|
|
9709
|
-
|
|
9727
|
+
if (typeof graph.getElementPosition !== "function" || typeof graph.getViewportByCanvas !== "function" || typeof graph.getCanvasCenter !== "function" || typeof graph.translateTo !== "function") return false;
|
|
9728
|
+
for (let i = 0; i < 3; i++) {
|
|
9729
|
+
let at = graph.getViewportByCanvas(graph.getElementPosition(node_id));
|
|
9730
|
+
let want = graph.getCanvasCenter();
|
|
9731
|
+
let dx = want[0] - at[0];
|
|
9732
|
+
let dy = want[1] - at[1];
|
|
9733
|
+
if (Math.abs(dx) < 1 && Math.abs(dy) < 1) break;
|
|
9734
|
+
let pos = graph.getPosition();
|
|
9735
|
+
await graph.translateTo([pos[0] + dx, pos[1] + dy]);
|
|
9736
|
+
}
|
|
9710
9737
|
return true;
|
|
9711
9738
|
} catch (e) {
|
|
9712
9739
|
return false;
|
|
9740
|
+
} finally {
|
|
9741
|
+
let pending = __centring__.get(graph);
|
|
9742
|
+
__centring__.set(graph, {
|
|
9743
|
+
running: false,
|
|
9744
|
+
again: null
|
|
9745
|
+
});
|
|
9746
|
+
if (pending && pending.again) yui_graph_center_on(graph, pending.again);
|
|
9713
9747
|
}
|
|
9714
9748
|
}
|
|
9715
9749
|
/************************************************************
|
|
@@ -10924,11 +10958,7 @@ function build_graph$3(gobj) {
|
|
|
10924
10958
|
}
|
|
10925
10959
|
},
|
|
10926
10960
|
layout: layout_cfg.g6_layout,
|
|
10927
|
-
behaviors:
|
|
10928
|
-
"drag-canvas",
|
|
10929
|
-
"zoom-canvas",
|
|
10930
|
-
"drag-element"
|
|
10931
|
-
]
|
|
10961
|
+
behaviors: BEHAVIORS_READING$1.slice()
|
|
10932
10962
|
});
|
|
10933
10963
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
10934
10964
|
graph.on(_antv_g6.NodeEvent.CLICK, (evt) => {
|
|
@@ -11035,6 +11065,12 @@ function build_cell_html(key, value, type, dark, matched, fold) {
|
|
|
11035
11065
|
* forever. `+3` and `−` need no language.
|
|
11036
11066
|
************************************************************/
|
|
11037
11067
|
var FOLD_SPACER = `<span style="width:24px; flex:0 0 auto;"></span>`;
|
|
11068
|
+
var BEHAVIORS_READING$1 = [
|
|
11069
|
+
"drag-canvas",
|
|
11070
|
+
"zoom-canvas",
|
|
11071
|
+
"drag-element"
|
|
11072
|
+
];
|
|
11073
|
+
var BEHAVIORS_PICKING$1 = ["drag-canvas", "zoom-canvas"];
|
|
11038
11074
|
var CARD_HEADER_H$1 = 24;
|
|
11039
11075
|
var CARD_ROW_H$1 = 22;
|
|
11040
11076
|
function fold_toggle_html(path, foldable, folded, branches, colors) {
|
|
@@ -11171,7 +11207,7 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port)
|
|
|
11171
11207
|
let min_width = Math.max(180, label.length * 9);
|
|
11172
11208
|
let card_height = CARD_HEADER_H$1 + lines.length * CARD_ROW_H$1;
|
|
11173
11209
|
let node_html = `
|
|
11174
|
-
<div style="
|
|
11210
|
+
<div class="JSON_CARD" data-json-path="${(0, _yuneta_gobj_js.escapeHtml)(path)}" style="
|
|
11175
11211
|
min-width: ${min_width}px;
|
|
11176
11212
|
background: ${colors.bg};
|
|
11177
11213
|
border: ${border_width}px ${is_dict ? "dashed" : "solid"} ${border_color};
|
|
@@ -11275,6 +11311,7 @@ function load_json(gobj) {
|
|
|
11275
11311
|
});
|
|
11276
11312
|
graph.render().then(() => {
|
|
11277
11313
|
reanchor$1(gobj);
|
|
11314
|
+
paint_anchor_mark(gobj);
|
|
11278
11315
|
if (preserve_view) {
|
|
11279
11316
|
yui_graph_update_zoom((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.graph);
|
|
11280
11317
|
return;
|
|
@@ -11596,6 +11633,52 @@ function reanchor$1(gobj) {
|
|
|
11596
11633
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
11597
11634
|
}
|
|
11598
11635
|
/************************************************************
|
|
11636
|
+
* Reading, or picking the node to anchor.
|
|
11637
|
+
*
|
|
11638
|
+
* Two visible consequences and one invisible: the cursor says
|
|
11639
|
+
* a click is expected, the mount says which mode it is in for
|
|
11640
|
+
* anyone reading the DOM, and node dragging stands aside so a
|
|
11641
|
+
* click that drifts is still a click.
|
|
11642
|
+
************************************************************/
|
|
11643
|
+
function set_picking_mode$1(gobj, picking) {
|
|
11644
|
+
let graph = gobj.priv.graph;
|
|
11645
|
+
if (graph && typeof graph.setBehaviors === "function") graph.setBehaviors((picking ? BEHAVIORS_PICKING$1 : BEHAVIORS_READING$1).slice());
|
|
11646
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
11647
|
+
if ($container) {
|
|
11648
|
+
let $mount = $container.querySelector(".json-graph-container");
|
|
11649
|
+
if ($mount) $mount.classList.toggle("JSON_GRAPH_PICKING", !!picking);
|
|
11650
|
+
}
|
|
11651
|
+
}
|
|
11652
|
+
/************************************************************
|
|
11653
|
+
* Mark the card the camera is holding.
|
|
11654
|
+
*
|
|
11655
|
+
* A class on the card's own element and not a G6 node state:
|
|
11656
|
+
* G6 paints no state style on an html node, so `setElementState`
|
|
11657
|
+
* would select it correctly and show nothing.
|
|
11658
|
+
*
|
|
11659
|
+
* Re-applied after every rebuild, because the cards are new DOM
|
|
11660
|
+
* each time and the mark would otherwise survive only until the
|
|
11661
|
+
* next fold.
|
|
11662
|
+
************************************************************/
|
|
11663
|
+
function paint_anchor_mark(gobj) {
|
|
11664
|
+
let priv = gobj.priv;
|
|
11665
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
11666
|
+
if (!$container) return;
|
|
11667
|
+
for (let $card of $container.querySelectorAll(".JSON_CARD_ANCHORED")) $card.classList.remove("JSON_CARD_ANCHORED");
|
|
11668
|
+
if (priv.anchor_state !== "on" || !priv.anchor_path) return;
|
|
11669
|
+
let $it = $container.querySelector(".JSON_CARD[data-json-path=\"" + CSS.escape(priv.anchor_path) + "\"]");
|
|
11670
|
+
if ($it) $it.classList.add("JSON_CARD_ANCHORED");
|
|
11671
|
+
}
|
|
11672
|
+
/************************************************************
|
|
11673
|
+
* Centre on the anchor, one cycle after it was chosen.
|
|
11674
|
+
************************************************************/
|
|
11675
|
+
function ac_center_anchor$2(gobj, event, kw, src) {
|
|
11676
|
+
let priv = gobj.priv;
|
|
11677
|
+
paint_anchor_mark(gobj);
|
|
11678
|
+
if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
11679
|
+
return 0;
|
|
11680
|
+
}
|
|
11681
|
+
/************************************************************
|
|
11599
11682
|
* Arm the anchor, or let it go.
|
|
11600
11683
|
*
|
|
11601
11684
|
* Three states and one button, so a press ADVANCES: with no
|
|
@@ -11612,6 +11695,8 @@ function ac_toggle_anchor$2(gobj, event, kw, src) {
|
|
|
11612
11695
|
priv.anchor_path = "";
|
|
11613
11696
|
}
|
|
11614
11697
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
11698
|
+
paint_anchor_mark(gobj);
|
|
11699
|
+
set_picking_mode$1(gobj, priv.anchor_state === "arming");
|
|
11615
11700
|
return 0;
|
|
11616
11701
|
}
|
|
11617
11702
|
/************************************************************
|
|
@@ -11678,7 +11763,8 @@ function ac_node_click$4(gobj, event, kw, src) {
|
|
|
11678
11763
|
priv.anchor_path = nodedata && nodedata.data ? nodedata.data.path : "";
|
|
11679
11764
|
priv.anchor_state = "on";
|
|
11680
11765
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
11681
|
-
|
|
11766
|
+
set_picking_mode$1(gobj, false);
|
|
11767
|
+
(0, _yuneta_gobj_js.gobj_post_event)(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
11682
11768
|
return 0;
|
|
11683
11769
|
}
|
|
11684
11770
|
if (nodedata && nodedata.data) (0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_JSON_ITEM_CLICKED", {
|
|
@@ -11819,6 +11905,11 @@ function create_gclass$11(gclass_name) {
|
|
|
11819
11905
|
ac_toggle_anchor$2,
|
|
11820
11906
|
null
|
|
11821
11907
|
],
|
|
11908
|
+
[
|
|
11909
|
+
"EV_CENTER_ANCHOR",
|
|
11910
|
+
ac_center_anchor$2,
|
|
11911
|
+
null
|
|
11912
|
+
],
|
|
11822
11913
|
[
|
|
11823
11914
|
"EV_RESIZE",
|
|
11824
11915
|
ac_resize$2,
|
|
@@ -11850,6 +11941,7 @@ function create_gclass$11(gclass_name) {
|
|
|
11850
11941
|
["EV_CENTER", 0],
|
|
11851
11942
|
["EV_NODE_CLICK", 0],
|
|
11852
11943
|
["EV_TOGGLE_ANCHOR", 0],
|
|
11944
|
+
["EV_CENTER_ANCHOR", 0],
|
|
11853
11945
|
["EV_RESIZE", 0],
|
|
11854
11946
|
["EV_SHOW", 0],
|
|
11855
11947
|
["EV_HIDE", 0],
|
|
@@ -13138,6 +13230,12 @@ var attrs_table$9 = [
|
|
|
13138
13230
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "collapse_threshold", 0, 10, "Auto-collapse a node whose direct children exceed this number. 0 disables auto-collapse."),
|
|
13139
13231
|
(0, _yuneta_gobj_js.SDATA_END)()
|
|
13140
13232
|
];
|
|
13233
|
+
var BEHAVIORS_READING = [
|
|
13234
|
+
"drag-canvas",
|
|
13235
|
+
"zoom-canvas",
|
|
13236
|
+
"drag-element"
|
|
13237
|
+
];
|
|
13238
|
+
var BEHAVIORS_PICKING = ["drag-canvas", "zoom-canvas"];
|
|
13141
13239
|
var PRIVATE_DATA$9 = {
|
|
13142
13240
|
canvas_id: "",
|
|
13143
13241
|
graph: null,
|
|
@@ -13619,11 +13717,7 @@ function build_graph$2(gobj) {
|
|
|
13619
13717
|
}
|
|
13620
13718
|
},
|
|
13621
13719
|
layout: layout_cfg.g6_layout,
|
|
13622
|
-
behaviors:
|
|
13623
|
-
"drag-canvas",
|
|
13624
|
-
"zoom-canvas",
|
|
13625
|
-
"drag-element"
|
|
13626
|
-
]
|
|
13720
|
+
behaviors: BEHAVIORS_READING.slice()
|
|
13627
13721
|
});
|
|
13628
13722
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
13629
13723
|
graph.on("aftertransform", () => {
|
|
@@ -14487,6 +14581,24 @@ function reanchor(gobj) {
|
|
|
14487
14581
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
14488
14582
|
}
|
|
14489
14583
|
/************************************************************
|
|
14584
|
+
* Centre on the anchor, one cycle after it was chosen.
|
|
14585
|
+
************************************************************/
|
|
14586
|
+
function ac_center_anchor$1(gobj, event, kw, src) {
|
|
14587
|
+
let priv = gobj.priv;
|
|
14588
|
+
if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
14589
|
+
return 0;
|
|
14590
|
+
}
|
|
14591
|
+
/************************************************************
|
|
14592
|
+
* Reading, or picking the node to anchor.
|
|
14593
|
+
************************************************************/
|
|
14594
|
+
function set_picking_mode(gobj, picking) {
|
|
14595
|
+
let graph = gobj.priv.graph;
|
|
14596
|
+
if (graph && typeof graph.setBehaviors === "function") graph.setBehaviors((picking ? BEHAVIORS_PICKING : BEHAVIORS_READING).slice());
|
|
14597
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
14598
|
+
let $mount = $container ? $container.querySelector(".gobj-tree-container") : null;
|
|
14599
|
+
if ($mount) $mount.classList.toggle("GOBJ_TREE_PICKING", !!picking);
|
|
14600
|
+
}
|
|
14601
|
+
/************************************************************
|
|
14490
14602
|
* Arm the anchor, or let it go.
|
|
14491
14603
|
*
|
|
14492
14604
|
* Three states and one button, so a press ADVANCES: with no
|
|
@@ -14503,6 +14615,7 @@ function ac_toggle_anchor$1(gobj, event, kw, src) {
|
|
|
14503
14615
|
priv.anchor_name = "";
|
|
14504
14616
|
}
|
|
14505
14617
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
14618
|
+
set_picking_mode(gobj, priv.anchor_state === "arming");
|
|
14506
14619
|
return 0;
|
|
14507
14620
|
}
|
|
14508
14621
|
/************************************************************
|
|
@@ -14571,7 +14684,8 @@ function ac_node_click$3(gobj, event, kw, src) {
|
|
|
14571
14684
|
priv.anchor_name = node_data.full_name || "";
|
|
14572
14685
|
priv.anchor_state = "on";
|
|
14573
14686
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
14574
|
-
|
|
14687
|
+
set_picking_mode(gobj, false);
|
|
14688
|
+
(0, _yuneta_gobj_js.gobj_post_event)(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
14575
14689
|
return 0;
|
|
14576
14690
|
}
|
|
14577
14691
|
let client_x = kw.evt && kw.evt.client ? kw.evt.client.x : 0;
|
|
@@ -14655,6 +14769,7 @@ function create_gclass$9(gclass_name) {
|
|
|
14655
14769
|
["EV_CENTER", 0],
|
|
14656
14770
|
["EV_NODE_CLICK", 0],
|
|
14657
14771
|
["EV_TOGGLE_ANCHOR", 0],
|
|
14772
|
+
["EV_CENTER_ANCHOR", 0],
|
|
14658
14773
|
["EV_RESIZE", 0],
|
|
14659
14774
|
["EV_SHOW", 0],
|
|
14660
14775
|
["EV_HIDE", 0]
|
|
@@ -14719,6 +14834,11 @@ function create_gclass$9(gclass_name) {
|
|
|
14719
14834
|
ac_toggle_anchor$1,
|
|
14720
14835
|
null
|
|
14721
14836
|
],
|
|
14837
|
+
[
|
|
14838
|
+
"EV_CENTER_ANCHOR",
|
|
14839
|
+
ac_center_anchor$1,
|
|
14840
|
+
null
|
|
14841
|
+
],
|
|
14722
14842
|
[
|
|
14723
14843
|
"EV_RESIZE",
|
|
14724
14844
|
ac_resize$1,
|
|
@@ -37560,7 +37680,7 @@ Text.PARSED_STYLE_LIST = new Set([].concat(_toConsumableArray(DisplayObject.PARS
|
|
|
37560
37680
|
* * register property @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/RegisterProperty
|
|
37561
37681
|
* * CSS Layout API
|
|
37562
37682
|
*/
|
|
37563
|
-
var CSS = {
|
|
37683
|
+
var CSS$1 = {
|
|
37564
37684
|
/**
|
|
37565
37685
|
* <number>
|
|
37566
37686
|
* @see https://drafts.csswg.org/css-values-4/#number-value
|
|
@@ -47609,7 +47729,7 @@ var e = 1e-4;
|
|
|
47609
47729
|
syntax: PropertySyntax.ANGLE
|
|
47610
47730
|
}
|
|
47611
47731
|
].forEach(function(property) {
|
|
47612
|
-
CSS.registerProperty(property);
|
|
47732
|
+
CSS$1.registerProperty(property);
|
|
47613
47733
|
});
|
|
47614
47734
|
var polarToCartesian = function polarToCartesian(centerX, centerY, radius, angleInRadian) {
|
|
47615
47735
|
return {
|
|
@@ -52931,6 +53051,14 @@ function ac_zoom_reset(gobj, event, kw, src) {
|
|
|
52931
53051
|
/************************************************************
|
|
52932
53052
|
* What the anchor button says it will do next.
|
|
52933
53053
|
************************************************************/
|
|
53054
|
+
function ac_center_anchor(gobj, event, kw, src) {
|
|
53055
|
+
let priv = gobj.priv;
|
|
53056
|
+
if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
53057
|
+
return 0;
|
|
53058
|
+
}
|
|
53059
|
+
/************************************************************
|
|
53060
|
+
* What the anchor button says it will do next.
|
|
53061
|
+
************************************************************/
|
|
52934
53062
|
function anchor_title(state) {
|
|
52935
53063
|
if (state === "arming") return (0, i18next.t)("click the element to centre on");
|
|
52936
53064
|
if (state === "on") return (0, i18next.t)("centred: click to release");
|
|
@@ -53149,7 +53277,7 @@ function ac_node_click$2(gobj, event, kw, src) {
|
|
|
53149
53277
|
priv.anchor_id = node_id;
|
|
53150
53278
|
priv.anchor_state = "on";
|
|
53151
53279
|
update_toolbar(gobj);
|
|
53152
|
-
|
|
53280
|
+
(0, _yuneta_gobj_js.gobj_post_event)(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
53153
53281
|
return 0;
|
|
53154
53282
|
}
|
|
53155
53283
|
try {
|
|
@@ -53418,6 +53546,11 @@ function create_gclass$4(gclass_name) {
|
|
|
53418
53546
|
ac_toggle_anchor,
|
|
53419
53547
|
null
|
|
53420
53548
|
],
|
|
53549
|
+
[
|
|
53550
|
+
"EV_CENTER_ANCHOR",
|
|
53551
|
+
ac_center_anchor,
|
|
53552
|
+
null
|
|
53553
|
+
],
|
|
53421
53554
|
[
|
|
53422
53555
|
"EV_TOGGLE_TOOLBARS",
|
|
53423
53556
|
ac_toggle_toolbars,
|
|
@@ -53532,6 +53665,7 @@ function create_gclass$4(gclass_name) {
|
|
|
53532
53665
|
["EV_ZOOM_OUT", 0],
|
|
53533
53666
|
["EV_ZOOM_RESET", 0],
|
|
53534
53667
|
["EV_TOGGLE_ANCHOR", 0],
|
|
53668
|
+
["EV_CENTER_ANCHOR", 0],
|
|
53535
53669
|
["EV_TOGGLE_TOOLBARS", 0],
|
|
53536
53670
|
["EV_AUTO_FIT", 0],
|
|
53537
53671
|
["EV_ZOOM_SELECTION", 0],
|
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_find_by_name, gclass_flag_t, getPositionRelativeToBody, gobj_change_state, gobj_command, gobj_create, gobj_create_pure_child, gobj_create_service, gobj_current_state, gobj_destroy, gobj_find_child, gobj_find_service, gobj_full_name, gobj_gclass_name, 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_start_tree, 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_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, log_error, log_warning, msg_iev_get_stack, parseBoolean, parseSVG, refresh_language, safeSrc, sdata_flag_t, set_console_log_enabled, set_log_callback, sprintf, str_in_list, template_get_field_desc, 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_find_by_name, gclass_flag_t, getPositionRelativeToBody, gobj_change_state, gobj_command, gobj_create, gobj_create_pure_child, gobj_create_service, gobj_current_state, gobj_destroy, gobj_find_child, gobj_find_service, gobj_full_name, gobj_gclass_name, 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_post_event, 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_start_tree, 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_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, log_error, log_warning, msg_iev_get_stack, parseBoolean, parseSVG, refresh_language, safeSrc, sdata_flag_t, set_console_log_enabled, set_log_callback, sprintf, str_in_list, template_get_field_desc, 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 { createJSONEditor } from "vanilla-jsoneditor";
|
|
@@ -9674,7 +9674,7 @@ function yui_graph_update_anchor($container, state) {
|
|
|
9674
9674
|
if (!$container) return;
|
|
9675
9675
|
let $btn = $container.querySelector(".EV_TOGGLE_ANCHOR");
|
|
9676
9676
|
if (!$btn) return;
|
|
9677
|
-
set_pressed_state($container, ".EV_TOGGLE_ANCHOR", state
|
|
9677
|
+
set_pressed_state($container, ".EV_TOGGLE_ANCHOR", state === "on");
|
|
9678
9678
|
$btn.classList.toggle("color_pending_state", state === "arming");
|
|
9679
9679
|
$btn.setAttribute("aria-pressed", state === "on" ? "true" : "false");
|
|
9680
9680
|
let key = state === "arming" ? "click the element to centre on" : state === "on" ? "centred: click to release" : "anchor view";
|
|
@@ -9690,21 +9690,55 @@ function yui_graph_update_anchor($container, state) {
|
|
|
9690
9690
|
* the zoom is what the reader asked for, the centring is what
|
|
9691
9691
|
* keeps the thing they are reading under their eyes.
|
|
9692
9692
|
*
|
|
9693
|
+
* The translate is computed and applied HERE rather than
|
|
9694
|
+
* delegated to `graph.focusElement()`, which is the obvious
|
|
9695
|
+
* call and does NOT work on these graphs. Measured: it
|
|
9696
|
+
* resolves, having computed the very offset wanted -- `[0,
|
|
9697
|
+
* 306]` for a card 306px above centre -- and the camera does
|
|
9698
|
+
* not move. `getPosition()` reads the same before and after,
|
|
9699
|
+
* and so does the card's box on screen. Three public calls do
|
|
9700
|
+
* move it, so that is what is used.
|
|
9701
|
+
*
|
|
9693
9702
|
* Guarded on every side because it runs on every wheel notch:
|
|
9694
9703
|
* a graph mid-rebuild, an anchor whose node went away with a
|
|
9695
|
-
* fold, a G6
|
|
9704
|
+
* fold, a G6 missing one of these calls -- none of those is
|
|
9696
9705
|
* an error worth a log line per notch, they are all "there is
|
|
9697
9706
|
* nothing to centre right now".
|
|
9698
9707
|
************************************************************/
|
|
9699
|
-
|
|
9708
|
+
var __centring__ = /* @__PURE__ */ new WeakMap();
|
|
9709
|
+
async function yui_graph_center_on(graph, node_id) {
|
|
9700
9710
|
if (!graph || !node_id) return false;
|
|
9711
|
+
let st = __centring__.get(graph);
|
|
9712
|
+
if (st && st.running) {
|
|
9713
|
+
st.again = node_id;
|
|
9714
|
+
return true;
|
|
9715
|
+
}
|
|
9716
|
+
__centring__.set(graph, {
|
|
9717
|
+
running: true,
|
|
9718
|
+
again: null
|
|
9719
|
+
});
|
|
9701
9720
|
try {
|
|
9702
9721
|
if (typeof graph.getElementData === "function" && !graph.getElementData(node_id)) return false;
|
|
9703
|
-
if (typeof graph.
|
|
9704
|
-
|
|
9722
|
+
if (typeof graph.getElementPosition !== "function" || typeof graph.getViewportByCanvas !== "function" || typeof graph.getCanvasCenter !== "function" || typeof graph.translateTo !== "function") return false;
|
|
9723
|
+
for (let i = 0; i < 3; i++) {
|
|
9724
|
+
let at = graph.getViewportByCanvas(graph.getElementPosition(node_id));
|
|
9725
|
+
let want = graph.getCanvasCenter();
|
|
9726
|
+
let dx = want[0] - at[0];
|
|
9727
|
+
let dy = want[1] - at[1];
|
|
9728
|
+
if (Math.abs(dx) < 1 && Math.abs(dy) < 1) break;
|
|
9729
|
+
let pos = graph.getPosition();
|
|
9730
|
+
await graph.translateTo([pos[0] + dx, pos[1] + dy]);
|
|
9731
|
+
}
|
|
9705
9732
|
return true;
|
|
9706
9733
|
} catch (e) {
|
|
9707
9734
|
return false;
|
|
9735
|
+
} finally {
|
|
9736
|
+
let pending = __centring__.get(graph);
|
|
9737
|
+
__centring__.set(graph, {
|
|
9738
|
+
running: false,
|
|
9739
|
+
again: null
|
|
9740
|
+
});
|
|
9741
|
+
if (pending && pending.again) yui_graph_center_on(graph, pending.again);
|
|
9708
9742
|
}
|
|
9709
9743
|
}
|
|
9710
9744
|
/************************************************************
|
|
@@ -10919,11 +10953,7 @@ function build_graph$3(gobj) {
|
|
|
10919
10953
|
}
|
|
10920
10954
|
},
|
|
10921
10955
|
layout: layout_cfg.g6_layout,
|
|
10922
|
-
behaviors:
|
|
10923
|
-
"drag-canvas",
|
|
10924
|
-
"zoom-canvas",
|
|
10925
|
-
"drag-element"
|
|
10926
|
-
]
|
|
10956
|
+
behaviors: BEHAVIORS_READING$1.slice()
|
|
10927
10957
|
});
|
|
10928
10958
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
10929
10959
|
graph.on(NodeEvent.CLICK, (evt) => {
|
|
@@ -11030,6 +11060,12 @@ function build_cell_html(key, value, type, dark, matched, fold) {
|
|
|
11030
11060
|
* forever. `+3` and `−` need no language.
|
|
11031
11061
|
************************************************************/
|
|
11032
11062
|
var FOLD_SPACER = `<span style="width:24px; flex:0 0 auto;"></span>`;
|
|
11063
|
+
var BEHAVIORS_READING$1 = [
|
|
11064
|
+
"drag-canvas",
|
|
11065
|
+
"zoom-canvas",
|
|
11066
|
+
"drag-element"
|
|
11067
|
+
];
|
|
11068
|
+
var BEHAVIORS_PICKING$1 = ["drag-canvas", "zoom-canvas"];
|
|
11033
11069
|
var CARD_HEADER_H$1 = 24;
|
|
11034
11070
|
var CARD_ROW_H$1 = 22;
|
|
11035
11071
|
function fold_toggle_html(path, foldable, folded, branches, colors) {
|
|
@@ -11166,7 +11202,7 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port)
|
|
|
11166
11202
|
let min_width = Math.max(180, label.length * 9);
|
|
11167
11203
|
let card_height = CARD_HEADER_H$1 + lines.length * CARD_ROW_H$1;
|
|
11168
11204
|
let node_html = `
|
|
11169
|
-
<div style="
|
|
11205
|
+
<div class="JSON_CARD" data-json-path="${escapeHtml(path)}" style="
|
|
11170
11206
|
min-width: ${min_width}px;
|
|
11171
11207
|
background: ${colors.bg};
|
|
11172
11208
|
border: ${border_width}px ${is_dict ? "dashed" : "solid"} ${border_color};
|
|
@@ -11270,6 +11306,7 @@ function load_json(gobj) {
|
|
|
11270
11306
|
});
|
|
11271
11307
|
graph.render().then(() => {
|
|
11272
11308
|
reanchor$1(gobj);
|
|
11309
|
+
paint_anchor_mark(gobj);
|
|
11273
11310
|
if (preserve_view) {
|
|
11274
11311
|
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
11275
11312
|
return;
|
|
@@ -11591,6 +11628,52 @@ function reanchor$1(gobj) {
|
|
|
11591
11628
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
11592
11629
|
}
|
|
11593
11630
|
/************************************************************
|
|
11631
|
+
* Reading, or picking the node to anchor.
|
|
11632
|
+
*
|
|
11633
|
+
* Two visible consequences and one invisible: the cursor says
|
|
11634
|
+
* a click is expected, the mount says which mode it is in for
|
|
11635
|
+
* anyone reading the DOM, and node dragging stands aside so a
|
|
11636
|
+
* click that drifts is still a click.
|
|
11637
|
+
************************************************************/
|
|
11638
|
+
function set_picking_mode$1(gobj, picking) {
|
|
11639
|
+
let graph = gobj.priv.graph;
|
|
11640
|
+
if (graph && typeof graph.setBehaviors === "function") graph.setBehaviors((picking ? BEHAVIORS_PICKING$1 : BEHAVIORS_READING$1).slice());
|
|
11641
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
11642
|
+
if ($container) {
|
|
11643
|
+
let $mount = $container.querySelector(".json-graph-container");
|
|
11644
|
+
if ($mount) $mount.classList.toggle("JSON_GRAPH_PICKING", !!picking);
|
|
11645
|
+
}
|
|
11646
|
+
}
|
|
11647
|
+
/************************************************************
|
|
11648
|
+
* Mark the card the camera is holding.
|
|
11649
|
+
*
|
|
11650
|
+
* A class on the card's own element and not a G6 node state:
|
|
11651
|
+
* G6 paints no state style on an html node, so `setElementState`
|
|
11652
|
+
* would select it correctly and show nothing.
|
|
11653
|
+
*
|
|
11654
|
+
* Re-applied after every rebuild, because the cards are new DOM
|
|
11655
|
+
* each time and the mark would otherwise survive only until the
|
|
11656
|
+
* next fold.
|
|
11657
|
+
************************************************************/
|
|
11658
|
+
function paint_anchor_mark(gobj) {
|
|
11659
|
+
let priv = gobj.priv;
|
|
11660
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
11661
|
+
if (!$container) return;
|
|
11662
|
+
for (let $card of $container.querySelectorAll(".JSON_CARD_ANCHORED")) $card.classList.remove("JSON_CARD_ANCHORED");
|
|
11663
|
+
if (priv.anchor_state !== "on" || !priv.anchor_path) return;
|
|
11664
|
+
let $it = $container.querySelector(".JSON_CARD[data-json-path=\"" + CSS.escape(priv.anchor_path) + "\"]");
|
|
11665
|
+
if ($it) $it.classList.add("JSON_CARD_ANCHORED");
|
|
11666
|
+
}
|
|
11667
|
+
/************************************************************
|
|
11668
|
+
* Centre on the anchor, one cycle after it was chosen.
|
|
11669
|
+
************************************************************/
|
|
11670
|
+
function ac_center_anchor$2(gobj, event, kw, src) {
|
|
11671
|
+
let priv = gobj.priv;
|
|
11672
|
+
paint_anchor_mark(gobj);
|
|
11673
|
+
if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
11674
|
+
return 0;
|
|
11675
|
+
}
|
|
11676
|
+
/************************************************************
|
|
11594
11677
|
* Arm the anchor, or let it go.
|
|
11595
11678
|
*
|
|
11596
11679
|
* Three states and one button, so a press ADVANCES: with no
|
|
@@ -11607,6 +11690,8 @@ function ac_toggle_anchor$2(gobj, event, kw, src) {
|
|
|
11607
11690
|
priv.anchor_path = "";
|
|
11608
11691
|
}
|
|
11609
11692
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
11693
|
+
paint_anchor_mark(gobj);
|
|
11694
|
+
set_picking_mode$1(gobj, priv.anchor_state === "arming");
|
|
11610
11695
|
return 0;
|
|
11611
11696
|
}
|
|
11612
11697
|
/************************************************************
|
|
@@ -11673,7 +11758,8 @@ function ac_node_click$4(gobj, event, kw, src) {
|
|
|
11673
11758
|
priv.anchor_path = nodedata && nodedata.data ? nodedata.data.path : "";
|
|
11674
11759
|
priv.anchor_state = "on";
|
|
11675
11760
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
11676
|
-
|
|
11761
|
+
set_picking_mode$1(gobj, false);
|
|
11762
|
+
gobj_post_event(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
11677
11763
|
return 0;
|
|
11678
11764
|
}
|
|
11679
11765
|
if (nodedata && nodedata.data) gobj_publish_event(gobj, "EV_JSON_ITEM_CLICKED", {
|
|
@@ -11814,6 +11900,11 @@ function create_gclass$11(gclass_name) {
|
|
|
11814
11900
|
ac_toggle_anchor$2,
|
|
11815
11901
|
null
|
|
11816
11902
|
],
|
|
11903
|
+
[
|
|
11904
|
+
"EV_CENTER_ANCHOR",
|
|
11905
|
+
ac_center_anchor$2,
|
|
11906
|
+
null
|
|
11907
|
+
],
|
|
11817
11908
|
[
|
|
11818
11909
|
"EV_RESIZE",
|
|
11819
11910
|
ac_resize$2,
|
|
@@ -11845,6 +11936,7 @@ function create_gclass$11(gclass_name) {
|
|
|
11845
11936
|
["EV_CENTER", 0],
|
|
11846
11937
|
["EV_NODE_CLICK", 0],
|
|
11847
11938
|
["EV_TOGGLE_ANCHOR", 0],
|
|
11939
|
+
["EV_CENTER_ANCHOR", 0],
|
|
11848
11940
|
["EV_RESIZE", 0],
|
|
11849
11941
|
["EV_SHOW", 0],
|
|
11850
11942
|
["EV_HIDE", 0],
|
|
@@ -13133,6 +13225,12 @@ var attrs_table$9 = [
|
|
|
13133
13225
|
SDATA(data_type_t.DTP_INTEGER, "collapse_threshold", 0, 10, "Auto-collapse a node whose direct children exceed this number. 0 disables auto-collapse."),
|
|
13134
13226
|
SDATA_END()
|
|
13135
13227
|
];
|
|
13228
|
+
var BEHAVIORS_READING = [
|
|
13229
|
+
"drag-canvas",
|
|
13230
|
+
"zoom-canvas",
|
|
13231
|
+
"drag-element"
|
|
13232
|
+
];
|
|
13233
|
+
var BEHAVIORS_PICKING = ["drag-canvas", "zoom-canvas"];
|
|
13136
13234
|
var PRIVATE_DATA$9 = {
|
|
13137
13235
|
canvas_id: "",
|
|
13138
13236
|
graph: null,
|
|
@@ -13614,11 +13712,7 @@ function build_graph$2(gobj) {
|
|
|
13614
13712
|
}
|
|
13615
13713
|
},
|
|
13616
13714
|
layout: layout_cfg.g6_layout,
|
|
13617
|
-
behaviors:
|
|
13618
|
-
"drag-canvas",
|
|
13619
|
-
"zoom-canvas",
|
|
13620
|
-
"drag-element"
|
|
13621
|
-
]
|
|
13715
|
+
behaviors: BEHAVIORS_READING.slice()
|
|
13622
13716
|
});
|
|
13623
13717
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
13624
13718
|
graph.on("aftertransform", () => {
|
|
@@ -14482,6 +14576,24 @@ function reanchor(gobj) {
|
|
|
14482
14576
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
14483
14577
|
}
|
|
14484
14578
|
/************************************************************
|
|
14579
|
+
* Centre on the anchor, one cycle after it was chosen.
|
|
14580
|
+
************************************************************/
|
|
14581
|
+
function ac_center_anchor$1(gobj, event, kw, src) {
|
|
14582
|
+
let priv = gobj.priv;
|
|
14583
|
+
if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
14584
|
+
return 0;
|
|
14585
|
+
}
|
|
14586
|
+
/************************************************************
|
|
14587
|
+
* Reading, or picking the node to anchor.
|
|
14588
|
+
************************************************************/
|
|
14589
|
+
function set_picking_mode(gobj, picking) {
|
|
14590
|
+
let graph = gobj.priv.graph;
|
|
14591
|
+
if (graph && typeof graph.setBehaviors === "function") graph.setBehaviors((picking ? BEHAVIORS_PICKING : BEHAVIORS_READING).slice());
|
|
14592
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
14593
|
+
let $mount = $container ? $container.querySelector(".gobj-tree-container") : null;
|
|
14594
|
+
if ($mount) $mount.classList.toggle("GOBJ_TREE_PICKING", !!picking);
|
|
14595
|
+
}
|
|
14596
|
+
/************************************************************
|
|
14485
14597
|
* Arm the anchor, or let it go.
|
|
14486
14598
|
*
|
|
14487
14599
|
* Three states and one button, so a press ADVANCES: with no
|
|
@@ -14498,6 +14610,7 @@ function ac_toggle_anchor$1(gobj, event, kw, src) {
|
|
|
14498
14610
|
priv.anchor_name = "";
|
|
14499
14611
|
}
|
|
14500
14612
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
14613
|
+
set_picking_mode(gobj, priv.anchor_state === "arming");
|
|
14501
14614
|
return 0;
|
|
14502
14615
|
}
|
|
14503
14616
|
/************************************************************
|
|
@@ -14566,7 +14679,8 @@ function ac_node_click$3(gobj, event, kw, src) {
|
|
|
14566
14679
|
priv.anchor_name = node_data.full_name || "";
|
|
14567
14680
|
priv.anchor_state = "on";
|
|
14568
14681
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
14569
|
-
|
|
14682
|
+
set_picking_mode(gobj, false);
|
|
14683
|
+
gobj_post_event(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
14570
14684
|
return 0;
|
|
14571
14685
|
}
|
|
14572
14686
|
let client_x = kw.evt && kw.evt.client ? kw.evt.client.x : 0;
|
|
@@ -14650,6 +14764,7 @@ function create_gclass$9(gclass_name) {
|
|
|
14650
14764
|
["EV_CENTER", 0],
|
|
14651
14765
|
["EV_NODE_CLICK", 0],
|
|
14652
14766
|
["EV_TOGGLE_ANCHOR", 0],
|
|
14767
|
+
["EV_CENTER_ANCHOR", 0],
|
|
14653
14768
|
["EV_RESIZE", 0],
|
|
14654
14769
|
["EV_SHOW", 0],
|
|
14655
14770
|
["EV_HIDE", 0]
|
|
@@ -14714,6 +14829,11 @@ function create_gclass$9(gclass_name) {
|
|
|
14714
14829
|
ac_toggle_anchor$1,
|
|
14715
14830
|
null
|
|
14716
14831
|
],
|
|
14832
|
+
[
|
|
14833
|
+
"EV_CENTER_ANCHOR",
|
|
14834
|
+
ac_center_anchor$1,
|
|
14835
|
+
null
|
|
14836
|
+
],
|
|
14717
14837
|
[
|
|
14718
14838
|
"EV_RESIZE",
|
|
14719
14839
|
ac_resize$1,
|
|
@@ -37555,7 +37675,7 @@ Text.PARSED_STYLE_LIST = new Set([].concat(_toConsumableArray(DisplayObject.PARS
|
|
|
37555
37675
|
* * register property @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/RegisterProperty
|
|
37556
37676
|
* * CSS Layout API
|
|
37557
37677
|
*/
|
|
37558
|
-
var CSS = {
|
|
37678
|
+
var CSS$1 = {
|
|
37559
37679
|
/**
|
|
37560
37680
|
* <number>
|
|
37561
37681
|
* @see https://drafts.csswg.org/css-values-4/#number-value
|
|
@@ -47604,7 +47724,7 @@ var e = 1e-4;
|
|
|
47604
47724
|
syntax: PropertySyntax.ANGLE
|
|
47605
47725
|
}
|
|
47606
47726
|
].forEach(function(property) {
|
|
47607
|
-
CSS.registerProperty(property);
|
|
47727
|
+
CSS$1.registerProperty(property);
|
|
47608
47728
|
});
|
|
47609
47729
|
var polarToCartesian = function polarToCartesian(centerX, centerY, radius, angleInRadian) {
|
|
47610
47730
|
return {
|
|
@@ -52926,6 +53046,14 @@ function ac_zoom_reset(gobj, event, kw, src) {
|
|
|
52926
53046
|
/************************************************************
|
|
52927
53047
|
* What the anchor button says it will do next.
|
|
52928
53048
|
************************************************************/
|
|
53049
|
+
function ac_center_anchor(gobj, event, kw, src) {
|
|
53050
|
+
let priv = gobj.priv;
|
|
53051
|
+
if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
53052
|
+
return 0;
|
|
53053
|
+
}
|
|
53054
|
+
/************************************************************
|
|
53055
|
+
* What the anchor button says it will do next.
|
|
53056
|
+
************************************************************/
|
|
52929
53057
|
function anchor_title(state) {
|
|
52930
53058
|
if (state === "arming") return t("click the element to centre on");
|
|
52931
53059
|
if (state === "on") return t("centred: click to release");
|
|
@@ -53144,7 +53272,7 @@ function ac_node_click$2(gobj, event, kw, src) {
|
|
|
53144
53272
|
priv.anchor_id = node_id;
|
|
53145
53273
|
priv.anchor_state = "on";
|
|
53146
53274
|
update_toolbar(gobj);
|
|
53147
|
-
|
|
53275
|
+
gobj_post_event(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
53148
53276
|
return 0;
|
|
53149
53277
|
}
|
|
53150
53278
|
try {
|
|
@@ -53413,6 +53541,11 @@ function create_gclass$4(gclass_name) {
|
|
|
53413
53541
|
ac_toggle_anchor,
|
|
53414
53542
|
null
|
|
53415
53543
|
],
|
|
53544
|
+
[
|
|
53545
|
+
"EV_CENTER_ANCHOR",
|
|
53546
|
+
ac_center_anchor,
|
|
53547
|
+
null
|
|
53548
|
+
],
|
|
53416
53549
|
[
|
|
53417
53550
|
"EV_TOGGLE_TOOLBARS",
|
|
53418
53551
|
ac_toggle_toolbars,
|
|
@@ -53527,6 +53660,7 @@ function create_gclass$4(gclass_name) {
|
|
|
53527
53660
|
["EV_ZOOM_OUT", 0],
|
|
53528
53661
|
["EV_ZOOM_RESET", 0],
|
|
53529
53662
|
["EV_TOGGLE_ANCHOR", 0],
|
|
53663
|
+
["EV_CENTER_ANCHOR", 0],
|
|
53530
53664
|
["EV_TOGGLE_TOOLBARS", 0],
|
|
53531
53665
|
["EV_AUTO_FIT", 0],
|
|
53532
53666
|
["EV_ZOOM_SELECTION", 0],
|
package/package.json
CHANGED
package/src/c_g6_nodes_tree.js
CHANGED
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
gobj_subscribe_event,
|
|
43
43
|
gobj_publish_event,
|
|
44
44
|
gobj_send_event,
|
|
45
|
+
gobj_post_event,
|
|
45
46
|
gobj_save_persistent_attrs,
|
|
46
47
|
clean_name,
|
|
47
48
|
sprintf,
|
|
@@ -7505,6 +7506,19 @@ function ac_zoom_reset(gobj, event, kw, src)
|
|
|
7505
7506
|
return 0;
|
|
7506
7507
|
}
|
|
7507
7508
|
|
|
7509
|
+
/************************************************************
|
|
7510
|
+
* What the anchor button says it will do next.
|
|
7511
|
+
************************************************************/
|
|
7512
|
+
function ac_center_anchor(gobj, event, kw, src)
|
|
7513
|
+
{
|
|
7514
|
+
let priv = gobj.priv;
|
|
7515
|
+
|
|
7516
|
+
if(priv.anchor_state === "on" && priv.anchor_id) {
|
|
7517
|
+
yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
7518
|
+
}
|
|
7519
|
+
return 0;
|
|
7520
|
+
}
|
|
7521
|
+
|
|
7508
7522
|
/************************************************************
|
|
7509
7523
|
* What the anchor button says it will do next.
|
|
7510
7524
|
************************************************************/
|
|
@@ -7824,7 +7838,11 @@ function ac_node_click(gobj, event, kw, src)
|
|
|
7824
7838
|
priv.anchor_id = node_id;
|
|
7825
7839
|
priv.anchor_state = "on";
|
|
7826
7840
|
update_toolbar(gobj);
|
|
7827
|
-
|
|
7841
|
+
|
|
7842
|
+
/* POSTED, not made here: a camera move issued inside G6's click
|
|
7843
|
+
* dispatch is swallowed -- see the note in yui_graph_center_on.
|
|
7844
|
+
* An event to itself and not a timer: a deferral is not a TIME. */
|
|
7845
|
+
gobj_post_event(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
7828
7846
|
return 0;
|
|
7829
7847
|
}
|
|
7830
7848
|
|
|
@@ -8140,6 +8158,7 @@ function create_gclass(gclass_name)
|
|
|
8140
8158
|
["EV_ZOOM_OUT", ac_zoom_out, null],
|
|
8141
8159
|
["EV_ZOOM_RESET", ac_zoom_reset, null],
|
|
8142
8160
|
["EV_TOGGLE_ANCHOR", ac_toggle_anchor, null],
|
|
8161
|
+
["EV_CENTER_ANCHOR", ac_center_anchor, null],
|
|
8143
8162
|
["EV_TOGGLE_TOOLBARS", ac_toggle_toolbars, null],
|
|
8144
8163
|
["EV_AUTO_FIT", ac_auto_fit, null],
|
|
8145
8164
|
["EV_ZOOM_SELECTION", ac_zoom_selection, null],
|
|
@@ -8190,6 +8209,7 @@ function create_gclass(gclass_name)
|
|
|
8190
8209
|
["EV_ZOOM_OUT", 0],
|
|
8191
8210
|
["EV_ZOOM_RESET", 0],
|
|
8192
8211
|
["EV_TOGGLE_ANCHOR", 0],
|
|
8212
|
+
["EV_CENTER_ANCHOR", 0],
|
|
8193
8213
|
["EV_TOGGLE_TOOLBARS", 0],
|
|
8194
8214
|
["EV_AUTO_FIT", 0],
|
|
8195
8215
|
["EV_ZOOM_SELECTION", 0],
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
gobj_read_attr,
|
|
22
22
|
gobj_write_attr,
|
|
23
23
|
gobj_send_event,
|
|
24
|
+
gobj_post_event,
|
|
24
25
|
gobj_write_str_attr,
|
|
25
26
|
gobj_read_str_attr,
|
|
26
27
|
gobj_publish_event,
|
|
@@ -89,6 +90,20 @@ SDATA(data_type_t.DTP_INTEGER, "collapse_threshold", 0, 10, "Auto-collapse a no
|
|
|
89
90
|
SDATA_END()
|
|
90
91
|
];
|
|
91
92
|
|
|
93
|
+
/*
|
|
94
|
+
* What the graph listens for while you are READING it, and while you
|
|
95
|
+
* are PICKING the node to anchor.
|
|
96
|
+
*
|
|
97
|
+
* The difference is `drag-element`: with it on, a click that drifts
|
|
98
|
+
* two pixels -- which is every click a hand makes -- becomes a drag,
|
|
99
|
+
* G6 fires no `node:click`, and the pick silently does not happen.
|
|
100
|
+
* Swapped with `setBehaviors()` and not with a behavior's `enable`,
|
|
101
|
+
* which REPLACES the behavior's own default test rather than adding
|
|
102
|
+
* to it.
|
|
103
|
+
*/
|
|
104
|
+
const BEHAVIORS_READING = ['drag-canvas', 'zoom-canvas', 'drag-element'];
|
|
105
|
+
const BEHAVIORS_PICKING = ['drag-canvas', 'zoom-canvas'];
|
|
106
|
+
|
|
92
107
|
let PRIVATE_DATA = {
|
|
93
108
|
canvas_id: "",
|
|
94
109
|
graph: null,
|
|
@@ -653,17 +668,7 @@ function build_graph(gobj)
|
|
|
653
668
|
|
|
654
669
|
layout: layout_cfg.g6_layout,
|
|
655
670
|
|
|
656
|
-
behaviors:
|
|
657
|
-
'drag-canvas',
|
|
658
|
-
'zoom-canvas',
|
|
659
|
-
/* Move a card by dragging it. The position is not kept --
|
|
660
|
-
* this tree is rebuilt from the live gobj tree on every
|
|
661
|
-
* refresh -- and it is still worth having: pulling two
|
|
662
|
-
* cards apart to read the lines between them is the whole
|
|
663
|
-
* use of it. `enable` REPLACES a behavior's default rather
|
|
664
|
-
* than adding to it, so it is not passed. */
|
|
665
|
-
'drag-element',
|
|
666
|
-
],
|
|
671
|
+
behaviors: BEHAVIORS_READING.slice(),
|
|
667
672
|
});
|
|
668
673
|
|
|
669
674
|
if(priv.theme) {
|
|
@@ -2000,6 +2005,37 @@ function reanchor(gobj)
|
|
|
2000
2005
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
2001
2006
|
}
|
|
2002
2007
|
|
|
2008
|
+
/************************************************************
|
|
2009
|
+
* Centre on the anchor, one cycle after it was chosen.
|
|
2010
|
+
************************************************************/
|
|
2011
|
+
function ac_center_anchor(gobj, event, kw, src)
|
|
2012
|
+
{
|
|
2013
|
+
let priv = gobj.priv;
|
|
2014
|
+
|
|
2015
|
+
if(priv.anchor_state === "on" && priv.anchor_id) {
|
|
2016
|
+
yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
2017
|
+
}
|
|
2018
|
+
return 0;
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
/************************************************************
|
|
2022
|
+
* Reading, or picking the node to anchor.
|
|
2023
|
+
************************************************************/
|
|
2024
|
+
function set_picking_mode(gobj, picking)
|
|
2025
|
+
{
|
|
2026
|
+
let graph = gobj.priv.graph;
|
|
2027
|
+
|
|
2028
|
+
if(graph && typeof graph.setBehaviors === "function") {
|
|
2029
|
+
graph.setBehaviors((picking? BEHAVIORS_PICKING: BEHAVIORS_READING).slice());
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
2033
|
+
let $mount = $container? $container.querySelector('.gobj-tree-container'): null;
|
|
2034
|
+
if($mount) {
|
|
2035
|
+
$mount.classList.toggle('GOBJ_TREE_PICKING', !!picking);
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2003
2039
|
/************************************************************
|
|
2004
2040
|
* Arm the anchor, or let it go.
|
|
2005
2041
|
*
|
|
@@ -2021,6 +2057,7 @@ function ac_toggle_anchor(gobj, event, kw, src)
|
|
|
2021
2057
|
}
|
|
2022
2058
|
|
|
2023
2059
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
2060
|
+
set_picking_mode(gobj, priv.anchor_state === "arming");
|
|
2024
2061
|
return 0;
|
|
2025
2062
|
}
|
|
2026
2063
|
|
|
@@ -2125,7 +2162,12 @@ function ac_node_click(gobj, event, kw, src)
|
|
|
2125
2162
|
priv.anchor_name = node_data.full_name || "";
|
|
2126
2163
|
priv.anchor_state = "on";
|
|
2127
2164
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
2128
|
-
|
|
2165
|
+
set_picking_mode(gobj, false);
|
|
2166
|
+
|
|
2167
|
+
/* POSTED, not made here: a camera move issued inside G6's click
|
|
2168
|
+
* dispatch is swallowed -- see the note in yui_graph_center_on.
|
|
2169
|
+
* An event to itself and not a timer: a deferral is not a TIME. */
|
|
2170
|
+
gobj_post_event(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
2129
2171
|
return 0;
|
|
2130
2172
|
}
|
|
2131
2173
|
|
|
@@ -2255,6 +2297,7 @@ function create_gclass(gclass_name)
|
|
|
2255
2297
|
["EV_CENTER", ac_center, null],
|
|
2256
2298
|
["EV_NODE_CLICK", ac_node_click, null],
|
|
2257
2299
|
["EV_TOGGLE_ANCHOR", ac_toggle_anchor, null],
|
|
2300
|
+
["EV_CENTER_ANCHOR", ac_center_anchor, null],
|
|
2258
2301
|
["EV_RESIZE", ac_resize, null],
|
|
2259
2302
|
["EV_SHOW", ac_show, null],
|
|
2260
2303
|
["EV_HIDE", ac_hide, null],
|
|
@@ -2277,6 +2320,7 @@ function create_gclass(gclass_name)
|
|
|
2277
2320
|
["EV_CENTER", 0],
|
|
2278
2321
|
["EV_NODE_CLICK", 0],
|
|
2279
2322
|
["EV_TOGGLE_ANCHOR", 0],
|
|
2323
|
+
["EV_CENTER_ANCHOR", 0],
|
|
2280
2324
|
["EV_RESIZE", 0],
|
|
2281
2325
|
["EV_SHOW", 0],
|
|
2282
2326
|
["EV_HIDE", 0],
|
package/src/c_yui_json.css
CHANGED
|
@@ -293,6 +293,38 @@
|
|
|
293
293
|
z-index: 1;
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
/*
|
|
297
|
+
* Picking the node to anchor. The pointer says a click is expected --
|
|
298
|
+
* without it the only sign the graph is waiting for one is a button
|
|
299
|
+
* at the far end of a toolbar.
|
|
300
|
+
*/
|
|
301
|
+
.C_YUI_JSON .json-graph-container.JSON_GRAPH_PICKING,
|
|
302
|
+
.C_YUI_JSON .json-graph-container.JSON_GRAPH_PICKING * {
|
|
303
|
+
cursor: crosshair;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/*
|
|
307
|
+
* The card the camera is holding.
|
|
308
|
+
*
|
|
309
|
+
* It has to say so ON THE CARD: the toolbar button knows an anchor is
|
|
310
|
+
* set, and knowing WHICH node it is was left to the reader remembering
|
|
311
|
+
* what they clicked -- which is not a mark, it is a memory test.
|
|
312
|
+
*
|
|
313
|
+
* An outline and not a fill: the card's own colours mean things (a
|
|
314
|
+
* dashed border is a dict, a solid one a list, the header carries the
|
|
315
|
+
* group's hue), and a mark that repaints any of them would be saying
|
|
316
|
+
* two things with one channel. `outline` also draws OUTSIDE the box,
|
|
317
|
+
* so it cannot move a single row.
|
|
318
|
+
*
|
|
319
|
+
* Amber, the same "this one, right now" the toolbar's arming state
|
|
320
|
+
* uses. It is not one of the palette's action colours because it is
|
|
321
|
+
* not an action.
|
|
322
|
+
*/
|
|
323
|
+
.C_YUI_JSON .JSON_CARD_ANCHORED {
|
|
324
|
+
outline: 3px solid #fa8c16;
|
|
325
|
+
outline-offset: 2px;
|
|
326
|
+
}
|
|
327
|
+
|
|
296
328
|
/*
|
|
297
329
|
* The graph mount, once its cards can be DRAGGED.
|
|
298
330
|
*
|
package/src/c_yui_json_graph.js
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
gobj_read_attr,
|
|
26
26
|
gobj_write_attr,
|
|
27
27
|
gobj_send_event,
|
|
28
|
+
gobj_post_event,
|
|
28
29
|
gobj_find_service,
|
|
29
30
|
gobj_short_name,
|
|
30
31
|
gobj_read_str_attr,
|
|
@@ -691,24 +692,7 @@ function build_graph(gobj)
|
|
|
691
692
|
|
|
692
693
|
layout: layout_cfg.g6_layout,
|
|
693
694
|
|
|
694
|
-
behaviors:
|
|
695
|
-
'drag-canvas',
|
|
696
|
-
'zoom-canvas',
|
|
697
|
-
/*
|
|
698
|
-
* Move a card by dragging it. The position is NOT kept:
|
|
699
|
-
* the graph is rebuilt from the document on every refresh,
|
|
700
|
-
* fold and layout change, and there is nothing here to
|
|
701
|
-
* save it to -- this is a viewer over a value somebody
|
|
702
|
-
* handed it, not a document of its own. Deliberate: being
|
|
703
|
-
* able to pull two cards apart to read the lines between
|
|
704
|
-
* them is worth having even when it lasts one session.
|
|
705
|
-
*
|
|
706
|
-
* No `enable`: a behavior's `enable` REPLACES the default,
|
|
707
|
-
* it does not add to it, and the default here is exactly
|
|
708
|
-
* what is wanted.
|
|
709
|
-
*/
|
|
710
|
-
'drag-element',
|
|
711
|
-
],
|
|
695
|
+
behaviors: BEHAVIORS_READING.slice(),
|
|
712
696
|
});
|
|
713
697
|
|
|
714
698
|
if(priv.theme) {
|
|
@@ -898,6 +882,23 @@ function build_cell_html(key, value, type, dark, matched, fold)
|
|
|
898
882
|
************************************************************/
|
|
899
883
|
const FOLD_SPACER = `<span style="width:24px; flex:0 0 auto;"></span>`;
|
|
900
884
|
|
|
885
|
+
/*
|
|
886
|
+
* What the graph listens for while you are READING it, and while you
|
|
887
|
+
* are PICKING the node to anchor.
|
|
888
|
+
*
|
|
889
|
+
* The difference is `drag-element`, and dropping it is not a detail:
|
|
890
|
+
* with it on, a click that drifts two pixels -- which is every click a
|
|
891
|
+
* hand makes -- becomes a drag, G6 fires no `node:click`, and the pick
|
|
892
|
+
* silently does not happen. Measured: an instant click anchors, the
|
|
893
|
+
* same click with 2px of movement does not.
|
|
894
|
+
*
|
|
895
|
+
* Swapped with `setBehaviors()` and not with a behavior's `enable`,
|
|
896
|
+
* which REPLACES the behavior's own default test rather than adding to
|
|
897
|
+
* it -- the trap that made a card drag pan the canvas in 7.23.10.
|
|
898
|
+
*/
|
|
899
|
+
const BEHAVIORS_READING = ['drag-canvas', 'zoom-canvas', 'drag-element'];
|
|
900
|
+
const BEHAVIORS_PICKING = ['drag-canvas', 'zoom-canvas'];
|
|
901
|
+
|
|
901
902
|
/*
|
|
902
903
|
* The card's geometry, in ONE place.
|
|
903
904
|
*
|
|
@@ -1151,8 +1152,21 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port)
|
|
|
1151
1152
|
let min_width = Math.max(180, label.length * 9);
|
|
1152
1153
|
let card_height = CARD_HEADER_H + lines.length * CARD_ROW_H;
|
|
1153
1154
|
|
|
1155
|
+
/*
|
|
1156
|
+
* The card carries its NAME and its PLACE in the document.
|
|
1157
|
+
*
|
|
1158
|
+
* `JSON_CARD` because a gclass that builds DOM has to leave a tree
|
|
1159
|
+
* somebody can read in the Inspector, and until now every card here
|
|
1160
|
+
* was an anonymous `<div>` among the anonymous `<div>`s G6 stacks.
|
|
1161
|
+
*
|
|
1162
|
+
* `data-json-path` because the anchor has to be able to find the
|
|
1163
|
+
* card it is holding: G6 paints no state style on an html node, so
|
|
1164
|
+
* the mark cannot be a node state and has to be a class on this
|
|
1165
|
+
* element -- and the path is what survives a rebuild, where the
|
|
1166
|
+
* node id does not.
|
|
1167
|
+
*/
|
|
1154
1168
|
let node_html = `
|
|
1155
|
-
<div style="
|
|
1169
|
+
<div class="JSON_CARD" data-json-path="${escapeHtml(path)}" style="
|
|
1156
1170
|
min-width: ${min_width}px;
|
|
1157
1171
|
background: ${colors.bg};
|
|
1158
1172
|
border: ${border_width}px ${is_dict ? 'dashed' : 'solid'} ${border_color};
|
|
@@ -1347,6 +1361,7 @@ function load_json(gobj)
|
|
|
1347
1361
|
/* Ids are generated per build: point the anchor at its path
|
|
1348
1362
|
* again before anybody asks the camera to go there. */
|
|
1349
1363
|
reanchor(gobj);
|
|
1364
|
+
paint_anchor_mark(gobj);
|
|
1350
1365
|
|
|
1351
1366
|
if(preserve_view) {
|
|
1352
1367
|
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
@@ -1819,6 +1834,79 @@ function reanchor(gobj)
|
|
|
1819
1834
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
1820
1835
|
}
|
|
1821
1836
|
|
|
1837
|
+
/************************************************************
|
|
1838
|
+
* Reading, or picking the node to anchor.
|
|
1839
|
+
*
|
|
1840
|
+
* Two visible consequences and one invisible: the cursor says
|
|
1841
|
+
* a click is expected, the mount says which mode it is in for
|
|
1842
|
+
* anyone reading the DOM, and node dragging stands aside so a
|
|
1843
|
+
* click that drifts is still a click.
|
|
1844
|
+
************************************************************/
|
|
1845
|
+
function set_picking_mode(gobj, picking)
|
|
1846
|
+
{
|
|
1847
|
+
let priv = gobj.priv;
|
|
1848
|
+
let graph = priv.graph;
|
|
1849
|
+
|
|
1850
|
+
if(graph && typeof graph.setBehaviors === "function") {
|
|
1851
|
+
graph.setBehaviors((picking? BEHAVIORS_PICKING: BEHAVIORS_READING).slice());
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
1855
|
+
if($container) {
|
|
1856
|
+
let $mount = $container.querySelector('.json-graph-container');
|
|
1857
|
+
if($mount) {
|
|
1858
|
+
$mount.classList.toggle('JSON_GRAPH_PICKING', !!picking);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
/************************************************************
|
|
1864
|
+
* Mark the card the camera is holding.
|
|
1865
|
+
*
|
|
1866
|
+
* A class on the card's own element and not a G6 node state:
|
|
1867
|
+
* G6 paints no state style on an html node, so `setElementState`
|
|
1868
|
+
* would select it correctly and show nothing.
|
|
1869
|
+
*
|
|
1870
|
+
* Re-applied after every rebuild, because the cards are new DOM
|
|
1871
|
+
* each time and the mark would otherwise survive only until the
|
|
1872
|
+
* next fold.
|
|
1873
|
+
************************************************************/
|
|
1874
|
+
function paint_anchor_mark(gobj)
|
|
1875
|
+
{
|
|
1876
|
+
let priv = gobj.priv;
|
|
1877
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
1878
|
+
|
|
1879
|
+
if(!$container) {
|
|
1880
|
+
return;
|
|
1881
|
+
}
|
|
1882
|
+
for(let $card of $container.querySelectorAll('.JSON_CARD_ANCHORED')) {
|
|
1883
|
+
$card.classList.remove('JSON_CARD_ANCHORED');
|
|
1884
|
+
}
|
|
1885
|
+
if(priv.anchor_state !== "on" || !priv.anchor_path) {
|
|
1886
|
+
return;
|
|
1887
|
+
}
|
|
1888
|
+
let $it = $container.querySelector(
|
|
1889
|
+
'.JSON_CARD[data-json-path="' + CSS.escape(priv.anchor_path) + '"]'
|
|
1890
|
+
);
|
|
1891
|
+
if($it) {
|
|
1892
|
+
$it.classList.add('JSON_CARD_ANCHORED');
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
/************************************************************
|
|
1897
|
+
* Centre on the anchor, one cycle after it was chosen.
|
|
1898
|
+
************************************************************/
|
|
1899
|
+
function ac_center_anchor(gobj, event, kw, src)
|
|
1900
|
+
{
|
|
1901
|
+
let priv = gobj.priv;
|
|
1902
|
+
|
|
1903
|
+
paint_anchor_mark(gobj);
|
|
1904
|
+
if(priv.anchor_state === "on" && priv.anchor_id) {
|
|
1905
|
+
yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
1906
|
+
}
|
|
1907
|
+
return 0;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1822
1910
|
/************************************************************
|
|
1823
1911
|
* Arm the anchor, or let it go.
|
|
1824
1912
|
*
|
|
@@ -1840,6 +1928,8 @@ function ac_toggle_anchor(gobj, event, kw, src)
|
|
|
1840
1928
|
}
|
|
1841
1929
|
|
|
1842
1930
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
1931
|
+
paint_anchor_mark(gobj);
|
|
1932
|
+
set_picking_mode(gobj, priv.anchor_state === "arming");
|
|
1843
1933
|
return 0;
|
|
1844
1934
|
}
|
|
1845
1935
|
|
|
@@ -1931,7 +2021,23 @@ function ac_node_click(gobj, event, kw, src)
|
|
|
1931
2021
|
priv.anchor_path = (nodedata && nodedata.data)? nodedata.data.path: "";
|
|
1932
2022
|
priv.anchor_state = "on";
|
|
1933
2023
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
1934
|
-
|
|
2024
|
+
set_picking_mode(gobj, false);
|
|
2025
|
+
|
|
2026
|
+
/*
|
|
2027
|
+
* The camera move is POSTED, not made here.
|
|
2028
|
+
*
|
|
2029
|
+
* A translate issued inside G6's click dispatch is swallowed:
|
|
2030
|
+
* measured, the call computes the right offset, resolves, and
|
|
2031
|
+
* the camera reads the same before and after -- while the very
|
|
2032
|
+
* same call from a zoom action centres the node exactly. So the
|
|
2033
|
+
* first thing an anchor did was nothing, which is what "I don't
|
|
2034
|
+
* see how it works" looks like.
|
|
2035
|
+
*
|
|
2036
|
+
* An event to itself and not a timer: a deferral is not a TIME,
|
|
2037
|
+
* and writing it as one costs the name of what happens next in
|
|
2038
|
+
* the trace.
|
|
2039
|
+
*/
|
|
2040
|
+
gobj_post_event(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
1935
2041
|
return 0;
|
|
1936
2042
|
}
|
|
1937
2043
|
|
|
@@ -2057,6 +2163,7 @@ function create_gclass(gclass_name)
|
|
|
2057
2163
|
["EV_CENTER", ac_center, null],
|
|
2058
2164
|
["EV_NODE_CLICK", ac_node_click, null],
|
|
2059
2165
|
["EV_TOGGLE_ANCHOR", ac_toggle_anchor, null],
|
|
2166
|
+
["EV_CENTER_ANCHOR", ac_center_anchor, null],
|
|
2060
2167
|
["EV_RESIZE", ac_resize, null],
|
|
2061
2168
|
["EV_SHOW", ac_show, null],
|
|
2062
2169
|
["EV_HIDE", ac_hide, null],
|
|
@@ -2081,6 +2188,7 @@ function create_gclass(gclass_name)
|
|
|
2081
2188
|
["EV_CENTER", 0],
|
|
2082
2189
|
["EV_NODE_CLICK", 0],
|
|
2083
2190
|
["EV_TOGGLE_ANCHOR", 0],
|
|
2191
|
+
["EV_CENTER_ANCHOR", 0],
|
|
2084
2192
|
["EV_RESIZE", 0],
|
|
2085
2193
|
["EV_SHOW", 0],
|
|
2086
2194
|
["EV_HIDE", 0],
|
package/src/lib_graph.css
CHANGED
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
.color_create_state {
|
|
15
15
|
color: #1890ff !important;
|
|
16
16
|
}
|
|
17
|
-
.
|
|
17
|
+
/* Orange is "needs attention, waiting on you". A toggle that is armed
|
|
18
|
+
* and waiting for its target is exactly that and not a submit, so it
|
|
19
|
+
* takes the same colour under a name that says so. */
|
|
20
|
+
.color_submit_state,
|
|
21
|
+
.color_pending_state {
|
|
18
22
|
color: #fa8c16 !important;
|
|
19
23
|
}
|
|
20
24
|
.color_active_state {
|
|
@@ -237,6 +241,36 @@
|
|
|
237
241
|
border-radius: 4px;
|
|
238
242
|
}
|
|
239
243
|
|
|
244
|
+
/*
|
|
245
|
+
* The same pressed look for a toggle in a DOM toolbar.
|
|
246
|
+
*
|
|
247
|
+
* `pressed_state` was written for the G6 plugin toolbar and styled ONLY
|
|
248
|
+
* there, so the two toolbars built by `yui_graph_camera.js` were given
|
|
249
|
+
* the class and no rule: pressing the button changed nothing on screen,
|
|
250
|
+
* which from the outside is indistinguishable from a button that does
|
|
251
|
+
* not work.
|
|
252
|
+
*
|
|
253
|
+
* `border-color` as well as the fill, or Bulma's own border stays and
|
|
254
|
+
* the button reads as outlined-and-filled, which is neither state.
|
|
255
|
+
* The `:hover` half is the same guard as above: without it, hovering a
|
|
256
|
+
* pressed button hands it back to Bulma's rule and the toggle appears
|
|
257
|
+
* to switch off under the pointer.
|
|
258
|
+
*/
|
|
259
|
+
/* Picking the node to anchor, in the gobj tree: the pointer says a
|
|
260
|
+
* click is expected, which is otherwise only announced by a button at
|
|
261
|
+
* the far end of a toolbar. */
|
|
262
|
+
.gobj-tree-container.GOBJ_TREE_PICKING,
|
|
263
|
+
.gobj-tree-container.GOBJ_TREE_PICKING * {
|
|
264
|
+
cursor: crosshair;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.button.pressed_state,
|
|
268
|
+
.button.pressed_state:hover {
|
|
269
|
+
background-color: var(--bulma-text, #2e333d);
|
|
270
|
+
color: var(--bulma-background, #ffffff);
|
|
271
|
+
border-color: var(--bulma-text, #2e333d);
|
|
272
|
+
}
|
|
273
|
+
|
|
240
274
|
/*
|
|
241
275
|
* Touch: the context menu is a LIST OF COMMANDS, and G6 sizes its
|
|
242
276
|
* rows with `padding: 8px 12px` -- 34px, which is a mouse row. The
|
package/src/yui_graph_camera.js
CHANGED
|
@@ -191,7 +191,14 @@ export function yui_graph_update_anchor($container, state)
|
|
|
191
191
|
if(!$btn) {
|
|
192
192
|
return; /* a toolbar without the control: nothing to paint */
|
|
193
193
|
}
|
|
194
|
-
|
|
194
|
+
/*
|
|
195
|
+
* PRESSED is "on", and only "on": pressed is the state the control
|
|
196
|
+
* is IN, and while it is arming it is not in that state yet, it is
|
|
197
|
+
* asking for something. That gets the attention colour instead --
|
|
198
|
+
* which also keeps the two off each other, since an orange glyph on
|
|
199
|
+
* the pressed fill is orange on near-white in dark and unreadable.
|
|
200
|
+
*/
|
|
201
|
+
set_pressed_state($container, '.EV_TOGGLE_ANCHOR', state === "on");
|
|
195
202
|
$btn.classList.toggle('color_pending_state', state === "arming");
|
|
196
203
|
$btn.setAttribute("aria-pressed", (state === "on")? "true": "false");
|
|
197
204
|
|
|
@@ -211,28 +218,107 @@ export function yui_graph_update_anchor($container, state)
|
|
|
211
218
|
* the zoom is what the reader asked for, the centring is what
|
|
212
219
|
* keeps the thing they are reading under their eyes.
|
|
213
220
|
*
|
|
221
|
+
* The translate is computed and applied HERE rather than
|
|
222
|
+
* delegated to `graph.focusElement()`, which is the obvious
|
|
223
|
+
* call and does NOT work on these graphs. Measured: it
|
|
224
|
+
* resolves, having computed the very offset wanted -- `[0,
|
|
225
|
+
* 306]` for a card 306px above centre -- and the camera does
|
|
226
|
+
* not move. `getPosition()` reads the same before and after,
|
|
227
|
+
* and so does the card's box on screen. Three public calls do
|
|
228
|
+
* move it, so that is what is used.
|
|
229
|
+
*
|
|
214
230
|
* Guarded on every side because it runs on every wheel notch:
|
|
215
231
|
* a graph mid-rebuild, an anchor whose node went away with a
|
|
216
|
-
* fold, a G6
|
|
232
|
+
* fold, a G6 missing one of these calls -- none of those is
|
|
217
233
|
* an error worth a log line per notch, they are all "there is
|
|
218
234
|
* nothing to centre right now".
|
|
219
235
|
************************************************************/
|
|
220
|
-
|
|
236
|
+
const __centring__ = new WeakMap();
|
|
237
|
+
|
|
238
|
+
export async function yui_graph_center_on(graph, node_id)
|
|
221
239
|
{
|
|
222
240
|
if(!graph || !node_id) {
|
|
223
241
|
return false;
|
|
224
242
|
}
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
* ONE centring at a time, per graph.
|
|
246
|
+
*
|
|
247
|
+
* This runs on every zoom notch, and one run is several awaited
|
|
248
|
+
* camera moves. A wheel gesture is a BURST of notches, so without
|
|
249
|
+
* this the runs overlap: each one measures a position another one
|
|
250
|
+
* is in the middle of changing, and they walk the camera around
|
|
251
|
+
* instead of converging -- which reads as a graph that pans and
|
|
252
|
+
* never centres.
|
|
253
|
+
*
|
|
254
|
+
* A request that arrives mid-run is not dropped, it is remembered:
|
|
255
|
+
* the last one wins and runs once at the end, which is the only
|
|
256
|
+
* one whose answer is still true.
|
|
257
|
+
*/
|
|
258
|
+
let st = __centring__.get(graph);
|
|
259
|
+
if(st && st.running) {
|
|
260
|
+
st.again = node_id;
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
__centring__.set(graph, {running: true, again: null});
|
|
264
|
+
|
|
225
265
|
try {
|
|
226
266
|
if(typeof graph.getElementData === "function" && !graph.getElementData(node_id)) {
|
|
227
267
|
return false;
|
|
228
268
|
}
|
|
229
|
-
if(typeof graph.
|
|
269
|
+
if(typeof graph.getElementPosition !== "function" ||
|
|
270
|
+
typeof graph.getViewportByCanvas !== "function" ||
|
|
271
|
+
typeof graph.getCanvasCenter !== "function" ||
|
|
272
|
+
typeof graph.translateTo !== "function") {
|
|
230
273
|
return false;
|
|
231
274
|
}
|
|
232
|
-
|
|
275
|
+
|
|
276
|
+
/*
|
|
277
|
+
* MEASURE, MOVE, MEASURE AGAIN -- up to three times.
|
|
278
|
+
*
|
|
279
|
+
* Not the arithmetic anybody would write first, and the reason
|
|
280
|
+
* is worth keeping. The obvious call is `graph.focusElement()`,
|
|
281
|
+
* which computes the very offset wanted and then does not move
|
|
282
|
+
* the camera at all: measured on the JSON graph it resolves
|
|
283
|
+
* with `getPosition()` reading identical before and after.
|
|
284
|
+
* `translateBy()` (a RELATIVE transform) behaves the same way.
|
|
285
|
+
* `translateTo()` (ABSOLUTE) does move it -- and the units of
|
|
286
|
+
* its argument are not viewport pixels at any zoom but 1, so
|
|
287
|
+
* one shot lands short or long by a factor nobody should have
|
|
288
|
+
* to name.
|
|
289
|
+
*
|
|
290
|
+
* Probing for that factor gives noise: the camera settles
|
|
291
|
+
* asynchronously, so a position read straight after a
|
|
292
|
+
* translate is a value halfway through. AWAITING each move and
|
|
293
|
+
* measuring again needs no factor at all -- the direction is
|
|
294
|
+
* right, so the residual falls to nothing in two or three
|
|
295
|
+
* passes, and a graph whose maths change under us keeps
|
|
296
|
+
* working.
|
|
297
|
+
*
|
|
298
|
+
* The 1px floor is what stops it converging forever on the
|
|
299
|
+
* rounding.
|
|
300
|
+
*/
|
|
301
|
+
for(let i = 0; i < 3; i++) {
|
|
302
|
+
let at = graph.getViewportByCanvas(graph.getElementPosition(node_id));
|
|
303
|
+
let want = graph.getCanvasCenter();
|
|
304
|
+
let dx = want[0] - at[0];
|
|
305
|
+
let dy = want[1] - at[1];
|
|
306
|
+
|
|
307
|
+
if(Math.abs(dx) < 1 && Math.abs(dy) < 1) {
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
let pos = graph.getPosition();
|
|
311
|
+
await graph.translateTo([pos[0] + dx, pos[1] + dy]);
|
|
312
|
+
}
|
|
233
313
|
return true;
|
|
234
314
|
} catch(e) {
|
|
235
315
|
return false; /* the element is gone, or the graph is between renders */
|
|
316
|
+
} finally {
|
|
317
|
+
let pending = __centring__.get(graph);
|
|
318
|
+
__centring__.set(graph, {running: false, again: null});
|
|
319
|
+
if(pending && pending.again) {
|
|
320
|
+
yui_graph_center_on(graph, pending.again);
|
|
321
|
+
}
|
|
236
322
|
}
|
|
237
323
|
}
|
|
238
324
|
|