@yuneta/gobj-ui 7.21.1 → 7.23.0
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 +30 -5
- package/dist/gobj-ui.cjs.js +319 -14
- package/dist/gobj-ui.es.js +319 -14
- package/package.json +1 -1
- package/src/c_yui_json.css +22 -16
- package/src/c_yui_json.js +13 -4
- package/src/c_yui_json_graph.js +427 -9
package/dist/gobj-ui.es.js
CHANGED
|
@@ -9468,6 +9468,12 @@ function ensure_drag_canvas_patch() {
|
|
|
9468
9468
|
* Constants
|
|
9469
9469
|
***************************************************************/
|
|
9470
9470
|
var GCLASS_NAME$11 = "C_YUI_JSON_GRAPH";
|
|
9471
|
+
var FOLD_SWALLOWED_EVENTS = [
|
|
9472
|
+
"pointerdown",
|
|
9473
|
+
"pointerup",
|
|
9474
|
+
"mousedown",
|
|
9475
|
+
"click"
|
|
9476
|
+
];
|
|
9471
9477
|
/***************************************************************
|
|
9472
9478
|
* Data
|
|
9473
9479
|
***************************************************************/
|
|
@@ -9487,7 +9493,15 @@ var PRIVATE_DATA$11 = {
|
|
|
9487
9493
|
theme: null,
|
|
9488
9494
|
theme_observer: null,
|
|
9489
9495
|
resize_observer: null,
|
|
9490
|
-
_resize_raf: 0
|
|
9496
|
+
_resize_raf: 0,
|
|
9497
|
+
search: "",
|
|
9498
|
+
collapsed: null,
|
|
9499
|
+
match_count: 0,
|
|
9500
|
+
find_timer: null,
|
|
9501
|
+
fold_listener: null,
|
|
9502
|
+
$find_input: null,
|
|
9503
|
+
$find_result: null,
|
|
9504
|
+
$find_count: null
|
|
9491
9505
|
};
|
|
9492
9506
|
var __gclass__$11 = null;
|
|
9493
9507
|
var __layout_registered__$1 = false;
|
|
@@ -9556,6 +9570,8 @@ function type_color(type, dark) {
|
|
|
9556
9570
|
***************************************************************/
|
|
9557
9571
|
function mt_create$11(gobj) {
|
|
9558
9572
|
let priv = gobj.priv;
|
|
9573
|
+
priv.collapsed = /* @__PURE__ */ new Set();
|
|
9574
|
+
priv.search = "";
|
|
9559
9575
|
priv.canvas_id = "json-canvas-" + clean_name(gobj_name(gobj));
|
|
9560
9576
|
gobj_write_str_attr(gobj, "canvas_id", priv.canvas_id);
|
|
9561
9577
|
let subscriber = gobj_read_pointer_attr(gobj, "subscriber");
|
|
@@ -9585,6 +9601,10 @@ function mt_stop$11(gobj) {}
|
|
|
9585
9601
|
* Framework Method: Destroy
|
|
9586
9602
|
***************************************************************/
|
|
9587
9603
|
function mt_destroy$11(gobj) {
|
|
9604
|
+
if (gobj.priv.find_timer) {
|
|
9605
|
+
clearTimeout(gobj.priv.find_timer);
|
|
9606
|
+
gobj.priv.find_timer = null;
|
|
9607
|
+
}
|
|
9588
9608
|
let priv = gobj.priv;
|
|
9589
9609
|
if (priv.theme_observer) {
|
|
9590
9610
|
priv.theme_observer.disconnect();
|
|
@@ -9641,25 +9661,118 @@ function build_ui$10(gobj) {
|
|
|
9641
9661
|
]]
|
|
9642
9662
|
]);
|
|
9643
9663
|
gobj_write_attr(gobj, "$container", $container);
|
|
9664
|
+
let $mount = $container.querySelector("#" + priv.canvas_id);
|
|
9665
|
+
if ($mount) {
|
|
9666
|
+
priv.fold_listener = function(evt) {
|
|
9667
|
+
let $handle = evt.target && evt.target.closest ? evt.target.closest("[data-fold-path]") : null;
|
|
9668
|
+
if (!$handle) return;
|
|
9669
|
+
evt.stopPropagation();
|
|
9670
|
+
evt.preventDefault();
|
|
9671
|
+
if (evt.type !== "click") return;
|
|
9672
|
+
gobj_send_event(gobj, "EV_TOGGLE_FOLD", { path: $handle.getAttribute("data-fold-path") }, gobj);
|
|
9673
|
+
};
|
|
9674
|
+
for (let type of FOLD_SWALLOWED_EVENTS) $mount.addEventListener(type, priv.fold_listener, true);
|
|
9675
|
+
} else log_error(`${gobj_short_name(gobj)}: no canvas mount, fold handles are dead`);
|
|
9676
|
+
priv.$find_input = $container.querySelector(".JSON_GRAPH_FIND_INPUT");
|
|
9677
|
+
priv.$find_result = $container.querySelector(".JSON_GRAPH_FIND_RESULT");
|
|
9678
|
+
priv.$find_count = $container.querySelector(".JSON_GRAPH_FIND_COUNT");
|
|
9644
9679
|
refresh_language($container, t);
|
|
9645
9680
|
}
|
|
9646
9681
|
/************************************************************
|
|
9647
9682
|
* Destroy UI
|
|
9648
9683
|
************************************************************/
|
|
9649
9684
|
function destroy_ui$6(gobj) {
|
|
9685
|
+
let priv = gobj.priv;
|
|
9650
9686
|
let $container = gobj_read_attr(gobj, "$container");
|
|
9687
|
+
if (priv.fold_listener) {
|
|
9688
|
+
let $mount = $container ? $container.querySelector("#" + priv.canvas_id) : null;
|
|
9689
|
+
if ($mount) for (let type of FOLD_SWALLOWED_EVENTS) $mount.removeEventListener(type, priv.fold_listener, true);
|
|
9690
|
+
priv.fold_listener = null;
|
|
9691
|
+
}
|
|
9651
9692
|
if ($container) {
|
|
9652
9693
|
if ($container.parentNode) $container.parentNode.removeChild($container);
|
|
9653
9694
|
gobj_write_attr(gobj, "$container", null);
|
|
9654
9695
|
}
|
|
9655
9696
|
}
|
|
9656
9697
|
/************************************************************
|
|
9698
|
+
* One fold button. `open` rotates the chevron to the open
|
|
9699
|
+
* state, mirroring the per-node toggle of the lazy tree.
|
|
9700
|
+
************************************************************/
|
|
9701
|
+
function graph_fold_button(gobj, event_name, label_key, open) {
|
|
9702
|
+
let icon_style = "font-size:1.5em; color:inherit;" + (open ? " transform: rotate(90deg);" : "");
|
|
9703
|
+
return [
|
|
9704
|
+
"button",
|
|
9705
|
+
{
|
|
9706
|
+
class: `button ${event_name}`,
|
|
9707
|
+
type: "button",
|
|
9708
|
+
style: {
|
|
9709
|
+
height: gobj_read_attr(gobj, "wide"),
|
|
9710
|
+
width: "2.5em"
|
|
9711
|
+
},
|
|
9712
|
+
title: t(label_key),
|
|
9713
|
+
"data-i18n-title": label_key,
|
|
9714
|
+
"aria-label": t(label_key),
|
|
9715
|
+
"data-i18n-aria-label": label_key
|
|
9716
|
+
},
|
|
9717
|
+
["i", {
|
|
9718
|
+
style: icon_style,
|
|
9719
|
+
class: "yi-chevron-right"
|
|
9720
|
+
}],
|
|
9721
|
+
{ click: (evt) => {
|
|
9722
|
+
evt.stopPropagation();
|
|
9723
|
+
gobj_send_event(gobj, event_name, {}, gobj);
|
|
9724
|
+
} }
|
|
9725
|
+
];
|
|
9726
|
+
}
|
|
9727
|
+
/************************************************************
|
|
9657
9728
|
* Toolbar
|
|
9658
9729
|
************************************************************/
|
|
9659
9730
|
function make_toolbar$3(gobj) {
|
|
9660
|
-
gobj.priv;
|
|
9731
|
+
let priv = gobj.priv;
|
|
9661
9732
|
let toolbar_wide = gobj_read_attr(gobj, "wide");
|
|
9662
|
-
let left_items = [
|
|
9733
|
+
let left_items = [[
|
|
9734
|
+
"div",
|
|
9735
|
+
{
|
|
9736
|
+
class: "JSON_GRAPH_FIND control has-icons-left",
|
|
9737
|
+
style: "margin-right:.5rem; max-width:12rem; min-width:7rem;"
|
|
9738
|
+
},
|
|
9739
|
+
[["input", {
|
|
9740
|
+
class: "JSON_GRAPH_FIND_INPUT input",
|
|
9741
|
+
type: "text",
|
|
9742
|
+
placeholder: t("search"),
|
|
9743
|
+
"data-i18n-placeholder": "search",
|
|
9744
|
+
"aria-label": t("search"),
|
|
9745
|
+
"data-i18n-aria-label": "search"
|
|
9746
|
+
}], [
|
|
9747
|
+
"span",
|
|
9748
|
+
{ class: "icon is-left" },
|
|
9749
|
+
[["i", { class: "yi-magnifying-glass" }]]
|
|
9750
|
+
]],
|
|
9751
|
+
{ input: (evt) => {
|
|
9752
|
+
evt.stopPropagation();
|
|
9753
|
+
let text = evt.target.value.trim();
|
|
9754
|
+
if (priv.find_timer) clearTimeout(priv.find_timer);
|
|
9755
|
+
priv.find_timer = setTimeout(function() {
|
|
9756
|
+
priv.find_timer = null;
|
|
9757
|
+
gobj_send_event(gobj, "EV_FIND_NODES", { text }, gobj);
|
|
9758
|
+
}, 250);
|
|
9759
|
+
} }
|
|
9760
|
+
], [
|
|
9761
|
+
"div",
|
|
9762
|
+
{
|
|
9763
|
+
class: "JSON_GRAPH_FIND_RESULT is-hidden",
|
|
9764
|
+
style: "display:flex; align-items:center; gap:.3rem; margin-right:.5rem; font-size:.85rem;"
|
|
9765
|
+
},
|
|
9766
|
+
[[
|
|
9767
|
+
"span",
|
|
9768
|
+
{ class: "JSON_GRAPH_FIND_COUNT" },
|
|
9769
|
+
""
|
|
9770
|
+
], [
|
|
9771
|
+
"span",
|
|
9772
|
+
{ i18n: "matches" },
|
|
9773
|
+
"matches"
|
|
9774
|
+
]]
|
|
9775
|
+
]];
|
|
9663
9776
|
let center_items = [];
|
|
9664
9777
|
for (let item of [
|
|
9665
9778
|
[
|
|
@@ -9717,6 +9830,7 @@ function make_toolbar$3(gobj) {
|
|
|
9717
9830
|
} }
|
|
9718
9831
|
]);
|
|
9719
9832
|
}
|
|
9833
|
+
let right_items = [graph_fold_button(gobj, "EV_EXPAND_ALL", "expand all", true), graph_fold_button(gobj, "EV_COLLAPSE_ALL", "collapse all", false)];
|
|
9720
9834
|
const $toolbar = yui_toolbar({}, [
|
|
9721
9835
|
[
|
|
9722
9836
|
"div",
|
|
@@ -9731,7 +9845,7 @@ function make_toolbar$3(gobj) {
|
|
|
9731
9845
|
[
|
|
9732
9846
|
"div",
|
|
9733
9847
|
{ class: "yui-horizontal-toolbar-section right" },
|
|
9734
|
-
|
|
9848
|
+
right_items
|
|
9735
9849
|
]
|
|
9736
9850
|
]);
|
|
9737
9851
|
refresh_language($toolbar, t);
|
|
@@ -9782,7 +9896,7 @@ function build_graph$3(gobj) {
|
|
|
9782
9896
|
/************************************************************
|
|
9783
9897
|
* Build cell value HTML (matching old mx_json_viewer colors)
|
|
9784
9898
|
************************************************************/
|
|
9785
|
-
function build_cell_html(key, value, type, dark) {
|
|
9899
|
+
function build_cell_html(key, value, type, dark, matched) {
|
|
9786
9900
|
let color = type_color(type, dark);
|
|
9787
9901
|
let key_color = json_card_style(GROUP_COLORS.dict, dark).key;
|
|
9788
9902
|
let display_value = "";
|
|
@@ -9807,7 +9921,48 @@ function build_cell_html(key, value, type, dark) {
|
|
|
9807
9921
|
break;
|
|
9808
9922
|
default: display_value = String(value);
|
|
9809
9923
|
}
|
|
9810
|
-
|
|
9924
|
+
let row = `<span style="color:${key_color}">• ${escapeHtml(String(key))}: </span><span style="color:${color}">${display_value}</span>`;
|
|
9925
|
+
if (matched) row = `<span style="background:${dark ? "#7a5d00" : "#ffe082"}; border-radius:2px; padding:0 2px;">${row}</span>`;
|
|
9926
|
+
return row;
|
|
9927
|
+
}
|
|
9928
|
+
/************************************************************
|
|
9929
|
+
* The per-node fold handle, drawn in the card's header.
|
|
9930
|
+
*
|
|
9931
|
+
* Only a card with a BRANCH gets one — a leaf has nothing to
|
|
9932
|
+
* fold, and a handle that does nothing is worse than none.
|
|
9933
|
+
* It carries the path in `data-fold-path`, which is what the
|
|
9934
|
+
* delegated listener in build_ui reads; the card is an
|
|
9935
|
+
* innerHTML string, so there is no other way to hang a
|
|
9936
|
+
* handler on it.
|
|
9937
|
+
*
|
|
9938
|
+
* Folded it shows the glyph AND the count of branches hidden
|
|
9939
|
+
* under it; open, just the glyph. No word, no title: a word
|
|
9940
|
+
* inside this string could carry no i18n key.
|
|
9941
|
+
************************************************************/
|
|
9942
|
+
function fold_toggle_html(path, foldable, folded, branches) {
|
|
9943
|
+
if (!foldable) return `<span style="width:1.1em; flex:0 0 auto;"></span>`;
|
|
9944
|
+
let glyph = folded ? "▸" : "▾";
|
|
9945
|
+
let text = folded ? `${glyph} ${branches}` : glyph;
|
|
9946
|
+
return `<span data-fold-path="${escapeHtml(path)}" style="flex:0 0 auto; cursor:pointer; user-select:none; padding:0 .2em; min-width:1.1em; text-align:left;">${text}</span>`;
|
|
9947
|
+
}
|
|
9948
|
+
/************************************************************
|
|
9949
|
+
* Does this key/value pair match the find term?
|
|
9950
|
+
*
|
|
9951
|
+
* Scalars are matched on what the card SHOWS. A complex value
|
|
9952
|
+
* is not: its contents are a card of their own and match there,
|
|
9953
|
+
* so matching the `{3}` summary too would light up every
|
|
9954
|
+
* ancestor of every hit.
|
|
9955
|
+
************************************************************/
|
|
9956
|
+
function cell_matches(key, value, type, needle) {
|
|
9957
|
+
if (empty_string(needle)) return false;
|
|
9958
|
+
if (String(key).toLowerCase().includes(needle)) return true;
|
|
9959
|
+
switch (type) {
|
|
9960
|
+
case "string":
|
|
9961
|
+
case "number":
|
|
9962
|
+
case "boolean": return String(value).toLowerCase().includes(needle);
|
|
9963
|
+
case "null": return "null".includes(needle);
|
|
9964
|
+
default: return false;
|
|
9965
|
+
}
|
|
9811
9966
|
}
|
|
9812
9967
|
/************************************************************
|
|
9813
9968
|
* Get JSON type string
|
|
@@ -9853,12 +10008,21 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
9853
10008
|
let is_dict = is_object(kw);
|
|
9854
10009
|
let is_list = is_array(kw);
|
|
9855
10010
|
if (!is_dict && !is_list) return null;
|
|
10011
|
+
let priv = gobj.priv;
|
|
10012
|
+
let needle = priv.search || "";
|
|
9856
10013
|
let dark = yui_is_dark();
|
|
9857
10014
|
let lines = [];
|
|
9858
10015
|
let pending_complex = [];
|
|
10016
|
+
let card_matched = false;
|
|
9859
10017
|
let entries = is_dict ? Object.entries(kw) : kw.map((v, i) => [i, v]);
|
|
9860
10018
|
for (let [key, value] of entries) {
|
|
9861
|
-
let
|
|
10019
|
+
let type = get_json_type(value);
|
|
10020
|
+
let matched = cell_matches(key, value, type, needle);
|
|
10021
|
+
if (matched) {
|
|
10022
|
+
card_matched = true;
|
|
10023
|
+
priv.match_count++;
|
|
10024
|
+
}
|
|
10025
|
+
let html = build_cell_html(key, value, type, dark, matched);
|
|
9862
10026
|
lines.push(html);
|
|
9863
10027
|
if (is_object(value) && json_object_size(value) > 0 || is_array(value) && value.length > 0) pending_complex.push({
|
|
9864
10028
|
key,
|
|
@@ -9866,14 +10030,18 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
9866
10030
|
});
|
|
9867
10031
|
}
|
|
9868
10032
|
let label = get_group_label(path) || (is_dict ? "{}" : "[]");
|
|
10033
|
+
let foldable = pending_complex.length > 0;
|
|
10034
|
+
let folded = foldable && priv.collapsed.has(path);
|
|
9869
10035
|
let colors = json_card_style(is_dict ? GROUP_COLORS.dict : GROUP_COLORS.list, dark);
|
|
10036
|
+
let border_color = card_matched ? dark ? "#ffb300" : "#ff8f00" : colors.border;
|
|
10037
|
+
let border_width = card_matched ? 2 : 1;
|
|
9870
10038
|
let content_html = lines.map((line) => `<div style="font-family:monospace; font-size:13px; padding:1px 6px; white-space:nowrap;">${line}</div>`).join("");
|
|
9871
10039
|
let min_width = Math.max(180, label.length * 9);
|
|
9872
10040
|
let node_html = `
|
|
9873
10041
|
<div style="
|
|
9874
10042
|
min-width: ${min_width}px;
|
|
9875
10043
|
background: ${colors.bg};
|
|
9876
|
-
border:
|
|
10044
|
+
border: ${border_width}px ${is_dict ? "dashed" : "solid"} ${border_color};
|
|
9877
10045
|
border-radius: ${is_dict ? "6px" : "0"};
|
|
9878
10046
|
opacity: 0.9;
|
|
9879
10047
|
overflow: hidden;
|
|
@@ -9884,8 +10052,10 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
9884
10052
|
font-weight: bold;
|
|
9885
10053
|
font-size: 12px;
|
|
9886
10054
|
padding: 3px 8px;
|
|
9887
|
-
|
|
9888
|
-
|
|
10055
|
+
display: flex;
|
|
10056
|
+
align-items: center;
|
|
10057
|
+
gap: 6px;
|
|
10058
|
+
">${fold_toggle_html(path, foldable, folded, pending_complex.length)}<span style="flex:1 1 auto; text-align:center;">${escapeHtml(label)}</span></div>
|
|
9889
10059
|
${content_html}
|
|
9890
10060
|
</div>`;
|
|
9891
10061
|
let node = {
|
|
@@ -9911,6 +10081,7 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
9911
10081
|
lineWidth: 1
|
|
9912
10082
|
}
|
|
9913
10083
|
});
|
|
10084
|
+
if (folded) return group_id;
|
|
9914
10085
|
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, group_id);
|
|
9915
10086
|
return group_id;
|
|
9916
10087
|
}
|
|
@@ -9927,6 +10098,7 @@ function load_json(gobj) {
|
|
|
9927
10098
|
let path = gobj_read_str_attr(gobj, "path") || "`";
|
|
9928
10099
|
if (empty_string(path)) path = "`";
|
|
9929
10100
|
priv.node_counter = 0;
|
|
10101
|
+
priv.match_count = 0;
|
|
9930
10102
|
let nodes = [];
|
|
9931
10103
|
let edges = [];
|
|
9932
10104
|
build_json_nodes(gobj, path, json, nodes, edges, null);
|
|
@@ -9943,6 +10115,42 @@ function load_json(gobj) {
|
|
|
9943
10115
|
}
|
|
9944
10116
|
}
|
|
9945
10117
|
/************************************************************
|
|
10118
|
+
* Every path that HAS a branch to fold, in the same recursion
|
|
10119
|
+
* build_json_nodes uses — so "collapse all" can never name a
|
|
10120
|
+
* card that does not exist. The root is excluded: folding it
|
|
10121
|
+
* would leave an empty canvas.
|
|
10122
|
+
************************************************************/
|
|
10123
|
+
function collect_foldable_paths(value, path, out, is_root) {
|
|
10124
|
+
let is_dict = is_object(value);
|
|
10125
|
+
let is_list = is_array(value);
|
|
10126
|
+
if (!is_dict && !is_list) return false;
|
|
10127
|
+
let has_branch = false;
|
|
10128
|
+
let entries = is_dict ? Object.entries(value) : value.map((v, i) => [i, v]);
|
|
10129
|
+
for (let [key, child] of entries) if (is_object(child) && json_object_size(child) > 0 || is_array(child) && child.length > 0) {
|
|
10130
|
+
has_branch = true;
|
|
10131
|
+
collect_foldable_paths(child, add_segment(path, key), out, false);
|
|
10132
|
+
}
|
|
10133
|
+
if (has_branch && !is_root) out.push(path);
|
|
10134
|
+
return has_branch;
|
|
10135
|
+
}
|
|
10136
|
+
/************************************************************
|
|
10137
|
+
* Show the find count, or hide the chip when there is no
|
|
10138
|
+
* term. Zero is a RESULT and must show: a graph that did not
|
|
10139
|
+
* move looks the same whether nothing matched or the match
|
|
10140
|
+
* was already on screen.
|
|
10141
|
+
************************************************************/
|
|
10142
|
+
function update_find_result(gobj) {
|
|
10143
|
+
let priv = gobj.priv;
|
|
10144
|
+
if (!priv.$find_result || !priv.$find_count) return;
|
|
10145
|
+
if (empty_string(priv.search)) {
|
|
10146
|
+
priv.$find_result.classList.add("is-hidden");
|
|
10147
|
+
priv.$find_count.textContent = "";
|
|
10148
|
+
return;
|
|
10149
|
+
}
|
|
10150
|
+
priv.$find_count.textContent = String(priv.match_count);
|
|
10151
|
+
priv.$find_result.classList.remove("is-hidden");
|
|
10152
|
+
}
|
|
10153
|
+
/************************************************************
|
|
9946
10154
|
* Clear and reload.
|
|
9947
10155
|
* {preserve_view: true}
|
|
9948
10156
|
* keep the current zoom and translate (no fitView) —
|
|
@@ -10064,6 +10272,70 @@ function ac_refresh$5(gobj, event, kw, src) {
|
|
|
10064
10272
|
}
|
|
10065
10273
|
/************************************************************
|
|
10066
10274
|
* {theme: "dark"|"light"} — the app switched theme.
|
|
10275
|
+
* EV_TOGGLE_FOLD { path } — fold or unfold ONE card.
|
|
10276
|
+
*
|
|
10277
|
+
* The camera does not move: folding one branch is a local
|
|
10278
|
+
* edit of the picture, and refitting the whole graph for it
|
|
10279
|
+
* would throw away where the reader was looking. The toolbar
|
|
10280
|
+
* pair, which changes everything at once, does refit.
|
|
10281
|
+
************************************************************/
|
|
10282
|
+
function ac_toggle_fold(gobj, event, kw, src) {
|
|
10283
|
+
let priv = gobj.priv;
|
|
10284
|
+
let path = kw && kw.path || "";
|
|
10285
|
+
if (empty_string(path)) {
|
|
10286
|
+
log_error(`${gobj_short_name(gobj)}: EV_TOGGLE_FOLD with no path`);
|
|
10287
|
+
return -1;
|
|
10288
|
+
}
|
|
10289
|
+
if (priv.collapsed.has(path)) priv.collapsed.delete(path);
|
|
10290
|
+
else priv.collapsed.add(path);
|
|
10291
|
+
refresh_json(gobj, { preserve_view: true });
|
|
10292
|
+
update_find_result(gobj);
|
|
10293
|
+
return 0;
|
|
10294
|
+
}
|
|
10295
|
+
/************************************************************
|
|
10296
|
+
* EV_FIND_NODES { text }
|
|
10297
|
+
*
|
|
10298
|
+
* The camera does NOT move: a find is a way of reading what is
|
|
10299
|
+
* already on screen, and a viewport that jumps on every
|
|
10300
|
+
* keystroke is unusable. The count says whether there is
|
|
10301
|
+
* anything to look for elsewhere.
|
|
10302
|
+
************************************************************/
|
|
10303
|
+
function ac_find_nodes$2(gobj, event, kw, src) {
|
|
10304
|
+
let priv = gobj.priv;
|
|
10305
|
+
priv.search = (kw && kw.text || "").trim().toLowerCase();
|
|
10306
|
+
refresh_json(gobj, { preserve_view: true });
|
|
10307
|
+
update_find_result(gobj);
|
|
10308
|
+
return 0;
|
|
10309
|
+
}
|
|
10310
|
+
/************************************************************
|
|
10311
|
+
* EV_EXPAND_ALL
|
|
10312
|
+
************************************************************/
|
|
10313
|
+
function ac_expand_all$2(gobj, event, kw, src) {
|
|
10314
|
+
let priv = gobj.priv;
|
|
10315
|
+
if (priv.collapsed.size === 0) return 0;
|
|
10316
|
+
priv.collapsed.clear();
|
|
10317
|
+
refresh_json(gobj);
|
|
10318
|
+
update_find_result(gobj);
|
|
10319
|
+
return 0;
|
|
10320
|
+
}
|
|
10321
|
+
/************************************************************
|
|
10322
|
+
* EV_COLLAPSE_ALL — fold every card but the root.
|
|
10323
|
+
************************************************************/
|
|
10324
|
+
function ac_collapse_all$2(gobj, event, kw, src) {
|
|
10325
|
+
let priv = gobj.priv;
|
|
10326
|
+
let json_data = gobj_read_attr(gobj, "json_data");
|
|
10327
|
+
if (!json_data) return 0;
|
|
10328
|
+
let paths = [];
|
|
10329
|
+
let path = gobj_read_str_attr(gobj, "path") || "`";
|
|
10330
|
+
if (empty_string(path)) path = "`";
|
|
10331
|
+
collect_foldable_paths(json_data, path, paths, true);
|
|
10332
|
+
priv.collapsed = new Set(paths);
|
|
10333
|
+
refresh_json(gobj);
|
|
10334
|
+
update_find_result(gobj);
|
|
10335
|
+
return 0;
|
|
10336
|
+
}
|
|
10337
|
+
/************************************************************
|
|
10338
|
+
*
|
|
10067
10339
|
************************************************************/
|
|
10068
10340
|
function ac_theme$3(gobj, event, kw, src) {
|
|
10069
10341
|
let priv = gobj.priv;
|
|
@@ -10204,6 +10476,26 @@ function create_gclass$11(gclass_name) {
|
|
|
10204
10476
|
ac_refresh$5,
|
|
10205
10477
|
null
|
|
10206
10478
|
],
|
|
10479
|
+
[
|
|
10480
|
+
"EV_FIND_NODES",
|
|
10481
|
+
ac_find_nodes$2,
|
|
10482
|
+
null
|
|
10483
|
+
],
|
|
10484
|
+
[
|
|
10485
|
+
"EV_TOGGLE_FOLD",
|
|
10486
|
+
ac_toggle_fold,
|
|
10487
|
+
null
|
|
10488
|
+
],
|
|
10489
|
+
[
|
|
10490
|
+
"EV_EXPAND_ALL",
|
|
10491
|
+
ac_expand_all$2,
|
|
10492
|
+
null
|
|
10493
|
+
],
|
|
10494
|
+
[
|
|
10495
|
+
"EV_COLLAPSE_ALL",
|
|
10496
|
+
ac_collapse_all$2,
|
|
10497
|
+
null
|
|
10498
|
+
],
|
|
10207
10499
|
[
|
|
10208
10500
|
"EV_THEME",
|
|
10209
10501
|
ac_theme$3,
|
|
@@ -10253,6 +10545,10 @@ function create_gclass$11(gclass_name) {
|
|
|
10253
10545
|
const event_types = [
|
|
10254
10546
|
["EV_LOAD_DATA", 0],
|
|
10255
10547
|
["EV_REFRESH", 0],
|
|
10548
|
+
["EV_FIND_NODES", 0],
|
|
10549
|
+
["EV_TOGGLE_FOLD", 0],
|
|
10550
|
+
["EV_EXPAND_ALL", 0],
|
|
10551
|
+
["EV_COLLAPSE_ALL", 0],
|
|
10256
10552
|
["EV_THEME", 0],
|
|
10257
10553
|
["EV_ZOOM_IN", 0],
|
|
10258
10554
|
["EV_ZOOM_OUT", 0],
|
|
@@ -11454,11 +11750,20 @@ function ac_set_view_mode(gobj, event, kw, src) {
|
|
|
11454
11750
|
/************************************************************
|
|
11455
11751
|
* EV_JSON_ITEM_CLICKED — from the hosted graph child.
|
|
11456
11752
|
*
|
|
11457
|
-
*
|
|
11458
|
-
*
|
|
11753
|
+
* It STOPS here, and that is deliberate. 7.21.0 republished
|
|
11754
|
+
* it "so the host has one contract", which got the framework
|
|
11755
|
+
* backwards: this viewer is a CHILD of its host and subscribes
|
|
11756
|
+
* it to everything it publishes, so a new output event is a
|
|
11757
|
+
* new MANDATORY declaration in every host's FSM. None of the
|
|
11758
|
+
* six that mount this viewer asked for node clicks, and every
|
|
11759
|
+
* one of them answered a click on a graph card with
|
|
11760
|
+
* "Event NOT DEFINED in state".
|
|
11761
|
+
*
|
|
11762
|
+
* A host that wants node clicks mounts C_YUI_JSON_GRAPH
|
|
11763
|
+
* itself — that gclass publishes them, and a host that mounts
|
|
11764
|
+
* it has declared them.
|
|
11459
11765
|
************************************************************/
|
|
11460
11766
|
function ac_json_item_clicked(gobj, event, kw, src) {
|
|
11461
|
-
gobj_publish_event(gobj, "EV_JSON_ITEM_CLICKED", kw);
|
|
11462
11767
|
return 0;
|
|
11463
11768
|
}
|
|
11464
11769
|
/************************************************************
|
|
@@ -11631,7 +11936,7 @@ function create_gclass$10(gclass_name) {
|
|
|
11631
11936
|
["EV_COLLAPSE_ALL", 0],
|
|
11632
11937
|
["EV_COPY_ALL", 0],
|
|
11633
11938
|
["EV_SET_VIEW_MODE", 0],
|
|
11634
|
-
["EV_JSON_ITEM_CLICKED",
|
|
11939
|
+
["EV_JSON_ITEM_CLICKED", 0],
|
|
11635
11940
|
["EV_LANGUAGE_CHANGED", 0],
|
|
11636
11941
|
["EV_REFRESH", 0],
|
|
11637
11942
|
["EV_SHOW", 0],
|
package/package.json
CHANGED
package/src/c_yui_json.css
CHANGED
|
@@ -47,28 +47,34 @@
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/*
|
|
50
|
-
* Who YIELDS when the toolbar runs out of room
|
|
51
|
-
* it grows to `max-width` when there is space and shrinks to nothing
|
|
52
|
-
* when there is not, while the buttons keep their size. A narrow
|
|
53
|
-
* search box still accepts what you type; a button pushed past the
|
|
54
|
-
* edge can only be reached by scrolling the toolbar, and the view
|
|
55
|
-
* switch is the last control that should be hiding.
|
|
50
|
+
* Who YIELDS when the toolbar runs out of room — and how far.
|
|
56
51
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
52
|
+
* The search box yields, and the buttons keep their size: a button
|
|
53
|
+
* pushed past the edge is harder to reach than a narrower input. But
|
|
54
|
+
* it yields down to a FLOOR, not to nothing. Letting it shrink freely
|
|
55
|
+
* did make everything fit on a phone, and the result was worse than
|
|
56
|
+
* the overflow it cured: the box collapsed to 58px — the magnifier and
|
|
57
|
+
* no room to read what you typed — and, because nothing overflowed any
|
|
58
|
+
* more, `yui_toolbar` stopped offering its scroll arrows, so the row
|
|
59
|
+
* had no way to show you anything else either.
|
|
60
|
+
*
|
|
61
|
+
* With the floor the toolbar overflows again on a narrow screen, which
|
|
62
|
+
* is the state yui_toolbar is built for: the container is
|
|
63
|
+
* `overflow-x: auto` and the arrows appear.
|
|
59
64
|
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
/* Neither section shrinks below its content. With `min-width: 0` here
|
|
66
|
+
* the left section shrank to 70px while the search box inside it kept
|
|
67
|
+
* its floor — so the input was painted UNDERNEATH the buttons, and the
|
|
68
|
+
* container, whose own children all fitted, reported no overflow to
|
|
69
|
+
* scroll. Sized to content, the container overflows honestly. */
|
|
70
|
+
.C_YUI_JSON .yui-horizontal-toolbar-section.left,
|
|
71
|
+
.C_YUI_JSON .yui-horizontal-toolbar-section.right {
|
|
72
|
+
flex: 0 0 auto;
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
.C_YUI_JSON .JSON_SEARCH_CONTROL {
|
|
66
76
|
flex: 1 1 auto;
|
|
67
|
-
min-width:
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.C_YUI_JSON .yui-horizontal-toolbar-section.right {
|
|
71
|
-
flex: 0 0 auto;
|
|
77
|
+
min-width: 11rem;
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
.C_YUI_JSON .JSON_TREE {
|
package/src/c_yui_json.js
CHANGED
|
@@ -1175,12 +1175,21 @@ function ac_set_view_mode(gobj, event, kw, src)
|
|
|
1175
1175
|
/************************************************************
|
|
1176
1176
|
* EV_JSON_ITEM_CLICKED — from the hosted graph child.
|
|
1177
1177
|
*
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1178
|
+
* It STOPS here, and that is deliberate. 7.21.0 republished
|
|
1179
|
+
* it "so the host has one contract", which got the framework
|
|
1180
|
+
* backwards: this viewer is a CHILD of its host and subscribes
|
|
1181
|
+
* it to everything it publishes, so a new output event is a
|
|
1182
|
+
* new MANDATORY declaration in every host's FSM. None of the
|
|
1183
|
+
* six that mount this viewer asked for node clicks, and every
|
|
1184
|
+
* one of them answered a click on a graph card with
|
|
1185
|
+
* "Event NOT DEFINED in state".
|
|
1186
|
+
*
|
|
1187
|
+
* A host that wants node clicks mounts C_YUI_JSON_GRAPH
|
|
1188
|
+
* itself — that gclass publishes them, and a host that mounts
|
|
1189
|
+
* it has declared them.
|
|
1180
1190
|
************************************************************/
|
|
1181
1191
|
function ac_json_item_clicked(gobj, event, kw, src)
|
|
1182
1192
|
{
|
|
1183
|
-
gobj_publish_event(gobj, "EV_JSON_ITEM_CLICKED", kw);
|
|
1184
1193
|
return 0;
|
|
1185
1194
|
}
|
|
1186
1195
|
|
|
@@ -1307,7 +1316,7 @@ function create_gclass(gclass_name)
|
|
|
1307
1316
|
["EV_COLLAPSE_ALL", 0],
|
|
1308
1317
|
["EV_COPY_ALL", 0],
|
|
1309
1318
|
["EV_SET_VIEW_MODE", 0],
|
|
1310
|
-
["EV_JSON_ITEM_CLICKED",
|
|
1319
|
+
["EV_JSON_ITEM_CLICKED", 0],
|
|
1311
1320
|
["EV_LANGUAGE_CHANGED", 0],
|
|
1312
1321
|
["EV_REFRESH", 0],
|
|
1313
1322
|
["EV_SHOW", 0],
|