@yuneta/gobj-ui 7.20.0 → 7.21.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 +51 -27
- package/dist/gobj-ui.cjs.js +230 -62
- package/dist/gobj-ui.es.js +230 -62
- package/package.json +1 -1
- package/src/c_yui_json.css +78 -1
- package/src/c_yui_json.js +264 -65
- package/src/c_yui_json_graph.js +8 -0
package/README.md
CHANGED
|
@@ -426,42 +426,66 @@ with limits, or any equivalent), and hands the subtree back via
|
|
|
426
426
|
the DOM, so the tree stays bounded regardless of document size. With no
|
|
427
427
|
sentinels present it degrades to a plain client-side collapsible tree.
|
|
428
428
|
|
|
429
|
-
**
|
|
430
|
-
`"tree"` | `"text"`
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
429
|
+
**Three views, one document.** The toolbar switch (and the `view_mode` attr,
|
|
430
|
+
`"tree"` | `"text"` | `"graph"`) picks which. They answer three different
|
|
431
|
+
questions:
|
|
432
|
+
|
|
433
|
+
| view | question | notes |
|
|
434
|
+
|---|---|---|
|
|
435
|
+
| `tree` | *where is this value, and what is around it* | the lazy view; the only one that can drill |
|
|
436
|
+
| `text` | *what does this document say, verbatim* | `JSON.stringify(…, 4)`, four characters per level |
|
|
437
|
+
| `graph` | *what shape is this* | a hosted `C_YUI_JSON_GRAPH` child (AntV/G6) |
|
|
438
|
+
|
|
439
|
+
- **Neither text nor graph is lazy.** Both show what the client currently
|
|
440
|
+
holds, `__collapsed__` sentinels included, because that is honestly what it
|
|
441
|
+
has. Drill in the tree and they grow with it.
|
|
442
|
+
- **The tree-only controls** (search, expand-loaded, collapse-all) hide with
|
|
443
|
+
the tree; copy stays. A control that can answer nothing is worse than an
|
|
444
|
+
absent one. The graph brings its own zoom/centre toolbar.
|
|
445
|
+
- **The graph child is built on first entry** into graph mode, never in
|
|
446
|
+
`build_ui`: G6 sizes itself from its container, so a graph created behind
|
|
447
|
+
`is-hidden` comes up 0×0. `register_c_yui_json()` auto-registers
|
|
448
|
+
`C_YUI_JSON_GRAPH` (and that register is idempotent, so an app may also
|
|
449
|
+
register it itself, in either order).
|
|
450
|
+
|
|
451
|
+
Two layout facts the browser taught this component, both worth keeping:
|
|
452
|
+
|
|
453
|
+
- In the text view long lines scroll sideways **inside** the viewer
|
|
454
|
+
(`white-space: pre` on a `max-content`-wide `<pre>`), never on the page body:
|
|
455
|
+
in a raw dump the indentation *is* the structure, and a wrapped line restarts
|
|
456
|
+
at column 0 and lies about the depth of everything under it. The `<pre>` must
|
|
457
|
+
be `max-content` wide or the container reports no overflow and the tail of
|
|
458
|
+
every long line is unreachable.
|
|
459
|
+
- The graph body carries a **definite `height`** (`24rem`, with
|
|
460
|
+
`flex: 1 1 auto` so a constrained host still wins). Not `min-height`: a
|
|
461
|
+
percentage height does not resolve against a box sized by a minimum, and the
|
|
462
|
+
tree and the text push their own height while a canvas pushes none — so in an
|
|
463
|
+
unconstrained host the graph came up as a 2px hairline.
|
|
447
464
|
|
|
448
465
|
**Contract:**
|
|
449
466
|
|
|
450
|
-
- Attributes: `subscriber`, `title` (i18n key, optional
|
|
451
|
-
|
|
452
|
-
(
|
|
467
|
+
- Attributes: `subscriber`, `title` (i18n key, optional — hidden on mobile,
|
|
468
|
+
where the toolbar cannot hold it as well as the buttons), `json_data`
|
|
469
|
+
(initial JSON, optional), `view_mode` (`"tree"` default | `"text"` |
|
|
470
|
+
`"graph"`), `$container` (mounted by the parent).
|
|
453
471
|
- Input events: `EV_SET_JSON {json}` (replace the whole document; `ST_EMPTY` →
|
|
454
472
|
`ST_READY`), `EV_SUBTREE_LOADED {path, json}` (splice a fetched subtree),
|
|
455
473
|
`EV_SUBTREE_ERROR {path, error}`, `EV_SET_VIEW_MODE {mode}` (`"tree"` /
|
|
456
|
-
`"text"`; **no mode
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
474
|
+
`"text"` / `"graph"`; **no mode advances** to the next view, which is what
|
|
475
|
+
the two-view toggle did when the list was two long), plus `EV_REFRESH` /
|
|
476
|
+
`EV_SHOW` / `EV_HIDE` / `EV_LANGUAGE_CHANGED`.
|
|
477
|
+
- Output events: `EV_EXPAND_PATH {path, size}` (`EVF_OUTPUT_EVENT`) — the parent
|
|
478
|
+
must declare it in its own FSM (CHILD subscription model) — and
|
|
479
|
+
`EV_JSON_ITEM_CLICKED`, republished from the graph child so the host has one
|
|
480
|
+
contract and never has to know that child exists (`EVF_NO_WARN_SUBS`: most
|
|
481
|
+
hosts do not care).
|
|
460
482
|
- Internal (DOM → FSM): `EV_TOGGLE_NODE`, `EV_EXPAND_COLLAPSED`, `EV_SEARCH`,
|
|
461
483
|
`EV_EXPAND_ALL`, `EV_COLLAPSE_ALL`, `EV_COPY_ALL`. Every kw carries only a
|
|
462
484
|
`path` string — never a DOM node or gobj.
|
|
463
|
-
- i18n keys
|
|
464
|
-
`text truncated; collapse some branches`.
|
|
485
|
+
- i18n keys the switch needs: `tree view`, `text view`, `graph view`,
|
|
486
|
+
`text truncated; collapse some branches`. All spelled out inside `t()` in
|
|
487
|
+
`view_label()` — never `t(VIEWS[i].key)`, which no `validate-locales` can
|
|
488
|
+
see (that shipped once, in `7.20.0`).
|
|
465
489
|
- Paths use the kernel delimiter (backtick) and index arrays numerically, so a
|
|
466
490
|
path emitted by the viewer round-trips through `kw_find_path` on the backend.
|
|
467
491
|
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -10277,6 +10277,7 @@ function create_gclass$11(gclass_name) {
|
|
|
10277
10277
|
* Register GClass
|
|
10278
10278
|
***************************************************************/
|
|
10279
10279
|
function register_c_yui_json_graph() {
|
|
10280
|
+
if ((0, _yuneta_gobj_js.gclass_find_by_name)(GCLASS_NAME$11, false)) return 0;
|
|
10280
10281
|
return create_gclass$11(GCLASS_NAME$11);
|
|
10281
10282
|
}
|
|
10282
10283
|
/************************************************************
|
|
@@ -10477,19 +10478,32 @@ function json_text_dump(root, max_chars) {
|
|
|
10477
10478
|
* Only expanded containers are materialised in the DOM, so the tree
|
|
10478
10479
|
* stays bounded no matter how large the source document is.
|
|
10479
10480
|
*
|
|
10480
|
-
*
|
|
10481
|
-
* attr ("tree" | "text") and switched from the
|
|
10482
|
-
*
|
|
10483
|
-
*
|
|
10484
|
-
*
|
|
10485
|
-
*
|
|
10486
|
-
*
|
|
10481
|
+
* THREE VIEWS over the same working document, chosen by the
|
|
10482
|
+
* `view_mode` attr ("tree" | "text" | "graph") and switched from the
|
|
10483
|
+
* toolbar. They answer three different questions:
|
|
10484
|
+
*
|
|
10485
|
+
* tree where is this value, and what is around it — the lazy
|
|
10486
|
+
* view above, the only one that can drill.
|
|
10487
|
+
* text what does this document SAY, verbatim — for reading it
|
|
10488
|
+
* as written, selecting a slab of it, or searching it with
|
|
10489
|
+
* the browser's own Ctrl+F.
|
|
10490
|
+
* graph what SHAPE is this — nesting as a hierarchy, drawn by a
|
|
10491
|
+
* hosted C_YUI_JSON_GRAPH child (AntV/G6).
|
|
10492
|
+
*
|
|
10493
|
+
* Neither text nor graph is lazy: both show what the client currently
|
|
10494
|
+
* holds, `__collapsed__` sentinels included, because that is honestly
|
|
10495
|
+
* what it has. Drill in the tree and they grow with it. The
|
|
10487
10496
|
* tree-only controls (search, expand/collapse) hide with the tree.
|
|
10488
10497
|
*
|
|
10498
|
+
* The graph child is built on FIRST entry into graph mode and not
|
|
10499
|
+
* before: G6 measures its container, so a graph created behind
|
|
10500
|
+
* `is-hidden` comes up 0x0, and a viewer nobody switches to graph
|
|
10501
|
+
* should not pay for a canvas.
|
|
10502
|
+
*
|
|
10489
10503
|
* DOM is self-describing (UPPER_SNAKE logical classes): JSON_VIEWER /
|
|
10490
|
-
* JSON_TOOLBAR / JSON_SEARCH /
|
|
10491
|
-
*
|
|
10492
|
-
* JSON_COLLAPSED / JSON_TIME.
|
|
10504
|
+
* JSON_TOOLBAR / JSON_SEARCH / JSON_VIEW_SWITCH / JSON_VIEW_MODE /
|
|
10505
|
+
* JSON_TREE / JSON_TEXT / JSON_TEXT_BODY / JSON_GRAPH / JSON_ROW /
|
|
10506
|
+
* JSON_KEY / JSON_VALUE / JSON_SUMMARY / JSON_COLLAPSED / JSON_TIME.
|
|
10493
10507
|
*
|
|
10494
10508
|
* Copyright (c) 2026, ArtGins.
|
|
10495
10509
|
* All Rights Reserved.
|
|
@@ -10500,6 +10514,23 @@ function json_text_dump(root, max_chars) {
|
|
|
10500
10514
|
var GCLASS_NAME$10 = "C_YUI_JSON";
|
|
10501
10515
|
var MAX_RENDER_ROWS = 5e3;
|
|
10502
10516
|
var MAX_TEXT_CHARS = 2e6;
|
|
10517
|
+
var VIEWS = [
|
|
10518
|
+
{
|
|
10519
|
+
mode: "tree",
|
|
10520
|
+
icon: "yi-sitemap",
|
|
10521
|
+
key: "tree view"
|
|
10522
|
+
},
|
|
10523
|
+
{
|
|
10524
|
+
mode: "text",
|
|
10525
|
+
icon: "yi-code",
|
|
10526
|
+
key: "text view"
|
|
10527
|
+
},
|
|
10528
|
+
{
|
|
10529
|
+
mode: "graph",
|
|
10530
|
+
icon: "yi-hexagon-nodes",
|
|
10531
|
+
key: "graph view"
|
|
10532
|
+
}
|
|
10533
|
+
];
|
|
10503
10534
|
/***************************************************************
|
|
10504
10535
|
* Data
|
|
10505
10536
|
***************************************************************/
|
|
@@ -10507,7 +10538,7 @@ var attrs_table$10 = [
|
|
|
10507
10538
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "subscriber", 0, null, "Subscriber of output events"),
|
|
10508
10539
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "title", 0, "", "Optional header title (i18n key)"),
|
|
10509
10540
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_JSON, "json_data", 0, null, "Initial JSON to render (usually already collapsed)"),
|
|
10510
|
-
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "view_mode", 0, "tree", "View: 'tree' (lazy tree)
|
|
10541
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "view_mode", 0, "tree", "View: 'tree' (lazy tree), 'text' (raw dump) or 'graph'"),
|
|
10511
10542
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$container", 0, null, "HTMLElement root, mounted by the parent"),
|
|
10512
10543
|
(0, _yuneta_gobj_js.SDATA_END)()
|
|
10513
10544
|
];
|
|
@@ -10520,11 +10551,13 @@ var PRIVATE_DATA$10 = {
|
|
|
10520
10551
|
$tree: null,
|
|
10521
10552
|
$text: null,
|
|
10522
10553
|
$text_body: null,
|
|
10554
|
+
$graph: null,
|
|
10555
|
+
graph_gobj: null,
|
|
10523
10556
|
$search: null,
|
|
10524
10557
|
$search_ctl: null,
|
|
10525
10558
|
$expand_btn: null,
|
|
10526
10559
|
$collapse_btn: null,
|
|
10527
|
-
$
|
|
10560
|
+
$mode_btns: null
|
|
10528
10561
|
};
|
|
10529
10562
|
var __gclass__$10 = null;
|
|
10530
10563
|
/******************************
|
|
@@ -10561,6 +10594,7 @@ function mt_stop$10(gobj) {}
|
|
|
10561
10594
|
* Framework Method: Destroy
|
|
10562
10595
|
***************************************************************/
|
|
10563
10596
|
function mt_destroy$10(gobj) {
|
|
10597
|
+
teardown_graph_child(gobj);
|
|
10564
10598
|
destroy_ui$5(gobj);
|
|
10565
10599
|
}
|
|
10566
10600
|
/***************************
|
|
@@ -10599,6 +10633,14 @@ function build_ui$9(gobj) {
|
|
|
10599
10633
|
style: "flex:1 1 auto; min-height:0; overflow:auto;"
|
|
10600
10634
|
},
|
|
10601
10635
|
[]
|
|
10636
|
+
],
|
|
10637
|
+
[
|
|
10638
|
+
"div",
|
|
10639
|
+
{
|
|
10640
|
+
class: "JSON_GRAPH is-flex-grow-1 is-hidden",
|
|
10641
|
+
style: "flex:1 1 auto; overflow:hidden;"
|
|
10642
|
+
},
|
|
10643
|
+
[]
|
|
10602
10644
|
]
|
|
10603
10645
|
]
|
|
10604
10646
|
]);
|
|
@@ -10609,7 +10651,12 @@ function build_ui$9(gobj) {
|
|
|
10609
10651
|
priv.$search_ctl = $container.querySelector(".JSON_SEARCH_CONTROL");
|
|
10610
10652
|
priv.$expand_btn = $container.querySelector(".EV_EXPAND_ALL");
|
|
10611
10653
|
priv.$collapse_btn = $container.querySelector(".EV_COLLAPSE_ALL");
|
|
10612
|
-
priv.$
|
|
10654
|
+
priv.$graph = $container.querySelector(".JSON_GRAPH");
|
|
10655
|
+
priv.$mode_btns = /* @__PURE__ */ new Map();
|
|
10656
|
+
VIEWS.forEach(function(v) {
|
|
10657
|
+
let $btn = $container.querySelector(".JSON_VIEW_MODE_" + v.mode.toUpperCase());
|
|
10658
|
+
if ($btn) priv.$mode_btns.set(v.mode, $btn);
|
|
10659
|
+
});
|
|
10613
10660
|
(0, _yuneta_gobj_js.refresh_language)($container, i18next.t);
|
|
10614
10661
|
}
|
|
10615
10662
|
/************************************************************
|
|
@@ -10625,11 +10672,12 @@ function destroy_ui$5(gobj) {
|
|
|
10625
10672
|
priv.$tree = null;
|
|
10626
10673
|
priv.$text = null;
|
|
10627
10674
|
priv.$text_body = null;
|
|
10675
|
+
priv.$graph = null;
|
|
10628
10676
|
priv.$search = null;
|
|
10629
10677
|
priv.$search_ctl = null;
|
|
10630
10678
|
priv.$expand_btn = null;
|
|
10631
10679
|
priv.$collapse_btn = null;
|
|
10632
|
-
priv.$
|
|
10680
|
+
priv.$mode_btns = null;
|
|
10633
10681
|
}
|
|
10634
10682
|
/************************************************************
|
|
10635
10683
|
* Toolbar: search + tree/text switch + expand-all /
|
|
@@ -10641,7 +10689,7 @@ function make_toolbar$2(gobj) {
|
|
|
10641
10689
|
if (title) left_items.push([
|
|
10642
10690
|
"span",
|
|
10643
10691
|
{
|
|
10644
|
-
class: "JSON_TITLE is-flex is-align-items-center px-2",
|
|
10692
|
+
class: "JSON_TITLE is-flex is-align-items-center px-2 is-hidden-mobile",
|
|
10645
10693
|
style: "font-weight:600;",
|
|
10646
10694
|
"data-i18n": title
|
|
10647
10695
|
},
|
|
@@ -10674,7 +10722,7 @@ function make_toolbar$2(gobj) {
|
|
|
10674
10722
|
attach_clear($search_control, $search_input);
|
|
10675
10723
|
left_items.push($search_control);
|
|
10676
10724
|
let right_items = [
|
|
10677
|
-
|
|
10725
|
+
view_mode_switch(gobj),
|
|
10678
10726
|
icon_button(gobj, "yi-chevron-right", "EV_EXPAND_ALL", "expand loaded"),
|
|
10679
10727
|
icon_button(gobj, "yi-chevron-right", "EV_COLLAPSE_ALL", "collapse all"),
|
|
10680
10728
|
icon_button(gobj, "yi-copy", "EV_COPY_ALL", "copy json")
|
|
@@ -10731,74 +10779,174 @@ function icon_button(gobj, icon, event_name, label_key) {
|
|
|
10731
10779
|
];
|
|
10732
10780
|
}
|
|
10733
10781
|
/************************************************************
|
|
10734
|
-
* The
|
|
10782
|
+
* The view switch: one button per view, the current one marked.
|
|
10735
10783
|
*
|
|
10736
|
-
*
|
|
10737
|
-
*
|
|
10738
|
-
*
|
|
10739
|
-
*
|
|
10740
|
-
*
|
|
10784
|
+
* Three views do not fit a toggle. A button that CYCLES cannot be
|
|
10785
|
+
* aimed — reaching the graph from the tree would mean passing
|
|
10786
|
+
* through the text and rebuilding it on the way — so each view gets
|
|
10787
|
+
* its own button and says where it goes. apply_view_mode() moves
|
|
10788
|
+
* the `is-active` mark.
|
|
10741
10789
|
************************************************************/
|
|
10742
|
-
function
|
|
10790
|
+
function view_mode_switch(gobj) {
|
|
10743
10791
|
return [
|
|
10744
|
-
"
|
|
10745
|
-
{
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10792
|
+
"div",
|
|
10793
|
+
{ class: "buttons has-addons is-flex-wrap-nowrap mb-0 JSON_VIEW_SWITCH" },
|
|
10794
|
+
VIEWS.map(function(v) {
|
|
10795
|
+
let label = view_label(v.mode);
|
|
10796
|
+
return [
|
|
10797
|
+
"button",
|
|
10798
|
+
{
|
|
10799
|
+
class: `button JSON_VIEW_MODE JSON_VIEW_MODE_${v.mode.toUpperCase()}`,
|
|
10800
|
+
type: "button",
|
|
10801
|
+
style: "width:2.5em;",
|
|
10802
|
+
title: label,
|
|
10803
|
+
"data-i18n-title": v.key,
|
|
10804
|
+
"aria-label": label,
|
|
10805
|
+
"data-i18n-aria-label": v.key
|
|
10806
|
+
},
|
|
10807
|
+
[[
|
|
10808
|
+
"span",
|
|
10809
|
+
{ class: "icon" },
|
|
10810
|
+
[["i", { class: v.icon }]]
|
|
10811
|
+
]],
|
|
10812
|
+
{ click: function(evt) {
|
|
10813
|
+
evt.stopPropagation();
|
|
10814
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SET_VIEW_MODE", { mode: v.mode }, gobj);
|
|
10815
|
+
} }
|
|
10816
|
+
];
|
|
10817
|
+
})
|
|
10762
10818
|
];
|
|
10763
10819
|
}
|
|
10764
10820
|
/************************************************************
|
|
10765
|
-
* The
|
|
10821
|
+
* The label of a view, with every key SPELLED OUT inside t().
|
|
10822
|
+
*
|
|
10823
|
+
* Never t(VIEWS[i].key): the apps' validate-locales scans for
|
|
10824
|
+
* t("literal"), so a key reached through a variable is a key it
|
|
10825
|
+
* cannot demand — and i18next answers an undefined key with the key
|
|
10826
|
+
* ITSELF, which renders in lower-case English and never changes
|
|
10827
|
+
* language. That shipped once already (7.20.0, `tree view`); this
|
|
10828
|
+
* table would have hidden all three.
|
|
10829
|
+
************************************************************/
|
|
10830
|
+
function view_label(mode) {
|
|
10831
|
+
switch (mode) {
|
|
10832
|
+
case "text": return (0, i18next.t)("text view");
|
|
10833
|
+
case "graph": return (0, i18next.t)("graph view");
|
|
10834
|
+
default: return (0, i18next.t)("tree view");
|
|
10835
|
+
}
|
|
10836
|
+
}
|
|
10837
|
+
/************************************************************
|
|
10838
|
+
* The current view, normalised. Anything unknown is the tree.
|
|
10766
10839
|
************************************************************/
|
|
10767
10840
|
function current_view_mode(gobj) {
|
|
10768
|
-
|
|
10841
|
+
let mode = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "view_mode");
|
|
10842
|
+
return VIEWS.some((v) => v.mode === mode) ? mode : "tree";
|
|
10769
10843
|
}
|
|
10770
10844
|
/************************************************************
|
|
10771
10845
|
* Show the chrome of the current view and hide the other's.
|
|
10772
10846
|
************************************************************/
|
|
10773
10847
|
function apply_view_mode(gobj) {
|
|
10774
10848
|
let priv = gobj.priv;
|
|
10775
|
-
let
|
|
10776
|
-
|
|
10777
|
-
|
|
10849
|
+
let mode = current_view_mode(gobj);
|
|
10850
|
+
let bodies = {
|
|
10851
|
+
tree: priv.$tree,
|
|
10852
|
+
text: priv.$text,
|
|
10853
|
+
graph: priv.$graph
|
|
10854
|
+
};
|
|
10855
|
+
for (let [m, $el] of Object.entries(bodies)) if ($el) $el.classList.toggle("is-hidden", m !== mode);
|
|
10778
10856
|
[
|
|
10779
10857
|
priv.$search_ctl,
|
|
10780
10858
|
priv.$expand_btn,
|
|
10781
10859
|
priv.$collapse_btn
|
|
10782
10860
|
].forEach(function($el) {
|
|
10783
|
-
if ($el) $el.classList.toggle("is-hidden",
|
|
10861
|
+
if ($el) $el.classList.toggle("is-hidden", mode !== "tree");
|
|
10784
10862
|
});
|
|
10785
|
-
if (priv.$
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
let $i = priv.$mode_btn.querySelector("i");
|
|
10789
|
-
if ($i) $i.className = icon;
|
|
10790
|
-
priv.$mode_btn.setAttribute("data-i18n-title", key);
|
|
10791
|
-
priv.$mode_btn.setAttribute("data-i18n-aria-label", key);
|
|
10792
|
-
priv.$mode_btn.setAttribute("title", (0, i18next.t)(key));
|
|
10793
|
-
priv.$mode_btn.setAttribute("aria-label", (0, i18next.t)(key));
|
|
10863
|
+
if (priv.$mode_btns) for (let [m, $btn] of priv.$mode_btns) {
|
|
10864
|
+
$btn.classList.toggle("is-active", m === mode);
|
|
10865
|
+
$btn.setAttribute("aria-pressed", m === mode ? "true" : "false");
|
|
10794
10866
|
}
|
|
10795
10867
|
}
|
|
10796
10868
|
/************************************************************
|
|
10797
10869
|
* Render whichever view is current.
|
|
10798
10870
|
************************************************************/
|
|
10799
10871
|
function render_view(gobj) {
|
|
10800
|
-
|
|
10801
|
-
|
|
10872
|
+
switch (current_view_mode(gobj)) {
|
|
10873
|
+
case "text":
|
|
10874
|
+
render_text(gobj);
|
|
10875
|
+
break;
|
|
10876
|
+
case "graph":
|
|
10877
|
+
render_graph(gobj);
|
|
10878
|
+
break;
|
|
10879
|
+
default: render_tree(gobj);
|
|
10880
|
+
}
|
|
10881
|
+
}
|
|
10882
|
+
/************************************************************
|
|
10883
|
+
* Render the graph view.
|
|
10884
|
+
*
|
|
10885
|
+
* The C_YUI_JSON_GRAPH child is built HERE, on first entry, and
|
|
10886
|
+
* never in build_ui: G6 sizes itself from its container, and a
|
|
10887
|
+
* container behind `is-hidden` measures 0x0. By the time this
|
|
10888
|
+
* runs apply_view_mode() has already revealed the body.
|
|
10889
|
+
************************************************************/
|
|
10890
|
+
function render_graph(gobj) {
|
|
10891
|
+
let priv = gobj.priv;
|
|
10892
|
+
let $graph = priv.$graph;
|
|
10893
|
+
if (!$graph) return;
|
|
10894
|
+
if (priv.root === null || priv.root === void 0) {
|
|
10895
|
+
teardown_graph_child(gobj);
|
|
10896
|
+
$graph.textContent = "";
|
|
10897
|
+
$graph.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
10898
|
+
"div",
|
|
10899
|
+
{
|
|
10900
|
+
class: "JSON_EMPTY has-text-grey p-3",
|
|
10901
|
+
"data-i18n": "no data"
|
|
10902
|
+
},
|
|
10903
|
+
"no data"
|
|
10904
|
+
]));
|
|
10905
|
+
(0, _yuneta_gobj_js.refresh_language)($graph, i18next.t);
|
|
10906
|
+
return;
|
|
10907
|
+
}
|
|
10908
|
+
if (!priv.graph_gobj) {
|
|
10909
|
+
$graph.textContent = "";
|
|
10910
|
+
if (!build_graph_child(gobj)) return;
|
|
10911
|
+
}
|
|
10912
|
+
(0, _yuneta_gobj_js.gobj_send_event)(priv.graph_gobj, "EV_LOAD_DATA", {
|
|
10913
|
+
data: priv.root,
|
|
10914
|
+
path: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "title") || ""
|
|
10915
|
+
}, gobj);
|
|
10916
|
+
(0, _yuneta_gobj_js.gobj_send_event)(priv.graph_gobj, "EV_RESIZE", {}, gobj);
|
|
10917
|
+
}
|
|
10918
|
+
/************************************************************
|
|
10919
|
+
* Build and mount the hosted graph child. Returns true on
|
|
10920
|
+
* success; every failure path logs.
|
|
10921
|
+
************************************************************/
|
|
10922
|
+
function build_graph_child(gobj) {
|
|
10923
|
+
let priv = gobj.priv;
|
|
10924
|
+
let graph = (0, _yuneta_gobj_js.gobj_create_pure_child)("graph_" + (0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj)), "C_YUI_JSON_GRAPH", {}, gobj);
|
|
10925
|
+
if (!graph) {
|
|
10926
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot create the graph viewer`);
|
|
10927
|
+
return false;
|
|
10928
|
+
}
|
|
10929
|
+
let $box = (0, _yuneta_gobj_js.gobj_read_attr)(graph, "$container");
|
|
10930
|
+
if (!$box) {
|
|
10931
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: the graph viewer built no $container`);
|
|
10932
|
+
(0, _yuneta_gobj_js.gobj_destroy)(graph);
|
|
10933
|
+
return false;
|
|
10934
|
+
}
|
|
10935
|
+
priv.$graph.appendChild($box);
|
|
10936
|
+
priv.graph_gobj = graph;
|
|
10937
|
+
(0, _yuneta_gobj_js.gobj_start)(graph);
|
|
10938
|
+
return true;
|
|
10939
|
+
}
|
|
10940
|
+
/************************************************************
|
|
10941
|
+
* Destroy the hosted graph child, if any.
|
|
10942
|
+
************************************************************/
|
|
10943
|
+
function teardown_graph_child(gobj) {
|
|
10944
|
+
let priv = gobj.priv;
|
|
10945
|
+
if (priv.graph_gobj) {
|
|
10946
|
+
if ((0, _yuneta_gobj_js.gobj_is_running)(priv.graph_gobj)) (0, _yuneta_gobj_js.gobj_stop)(priv.graph_gobj);
|
|
10947
|
+
(0, _yuneta_gobj_js.gobj_destroy)(priv.graph_gobj);
|
|
10948
|
+
priv.graph_gobj = null;
|
|
10949
|
+
}
|
|
10802
10950
|
}
|
|
10803
10951
|
/************************************************************
|
|
10804
10952
|
* Render the text view: the whole loaded document, verbatim.
|
|
@@ -11289,23 +11437,36 @@ function ac_copy_all(gobj, event, kw, src) {
|
|
|
11289
11437
|
return 0;
|
|
11290
11438
|
}
|
|
11291
11439
|
/************************************************************
|
|
11292
|
-
* EV_SET_VIEW_MODE { mode } — "tree" | "text".
|
|
11440
|
+
* EV_SET_VIEW_MODE { mode } — "tree" | "text" | "graph".
|
|
11293
11441
|
*
|
|
11294
|
-
* With no mode it
|
|
11442
|
+
* With no mode it ADVANCES to the next view in VIEWS order, which
|
|
11443
|
+
* is what the two-view toggle did when the list was two long. The
|
|
11444
|
+
* toolbar buttons always name their mode.
|
|
11295
11445
|
************************************************************/
|
|
11296
11446
|
function ac_set_view_mode(gobj, event, kw, src) {
|
|
11297
11447
|
let mode = kw.mode;
|
|
11298
|
-
if (mode === void 0 || mode === null || mode === "") mode =
|
|
11299
|
-
else if (
|
|
11448
|
+
if (mode === void 0 || mode === null || mode === "") mode = VIEWS[(VIEWS.findIndex((v) => v.mode === current_view_mode(gobj)) + 1) % VIEWS.length].mode;
|
|
11449
|
+
else if (!VIEWS.some((v) => v.mode === mode)) {
|
|
11300
11450
|
(0, _yuneta_gobj_js.log_error)(`${GCLASS_NAME$10}: unknown view_mode '${mode}'`);
|
|
11301
11451
|
return -1;
|
|
11302
11452
|
}
|
|
11453
|
+
if (mode === current_view_mode(gobj)) return 0;
|
|
11303
11454
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "view_mode", mode);
|
|
11304
11455
|
apply_view_mode(gobj);
|
|
11305
11456
|
render_view(gobj);
|
|
11306
11457
|
return 0;
|
|
11307
11458
|
}
|
|
11308
11459
|
/************************************************************
|
|
11460
|
+
* EV_JSON_ITEM_CLICKED — from the hosted graph child.
|
|
11461
|
+
*
|
|
11462
|
+
* Republished under this gclass's own name so the host has ONE
|
|
11463
|
+
* contract and never has to know the child exists.
|
|
11464
|
+
************************************************************/
|
|
11465
|
+
function ac_json_item_clicked(gobj, event, kw, src) {
|
|
11466
|
+
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_JSON_ITEM_CLICKED", kw);
|
|
11467
|
+
return 0;
|
|
11468
|
+
}
|
|
11469
|
+
/************************************************************
|
|
11309
11470
|
* EV_LANGUAGE_CHANGED — re-translate chrome + re-render
|
|
11310
11471
|
************************************************************/
|
|
11311
11472
|
function ac_language_changed$3(gobj, event, kw, src) {
|
|
@@ -11393,6 +11554,11 @@ function create_gclass$10(gclass_name) {
|
|
|
11393
11554
|
ac_set_json,
|
|
11394
11555
|
null
|
|
11395
11556
|
],
|
|
11557
|
+
[
|
|
11558
|
+
"EV_JSON_ITEM_CLICKED",
|
|
11559
|
+
ac_json_item_clicked,
|
|
11560
|
+
null
|
|
11561
|
+
],
|
|
11396
11562
|
[
|
|
11397
11563
|
"EV_SUBTREE_LOADED",
|
|
11398
11564
|
ac_subtree_loaded,
|
|
@@ -11470,6 +11636,7 @@ function create_gclass$10(gclass_name) {
|
|
|
11470
11636
|
["EV_COLLAPSE_ALL", 0],
|
|
11471
11637
|
["EV_COPY_ALL", 0],
|
|
11472
11638
|
["EV_SET_VIEW_MODE", 0],
|
|
11639
|
+
["EV_JSON_ITEM_CLICKED", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT | _yuneta_gobj_js.event_flag_t.EVF_NO_WARN_SUBS],
|
|
11473
11640
|
["EV_LANGUAGE_CHANGED", 0],
|
|
11474
11641
|
["EV_REFRESH", 0],
|
|
11475
11642
|
["EV_SHOW", 0],
|
|
@@ -11485,6 +11652,7 @@ function create_gclass$10(gclass_name) {
|
|
|
11485
11652
|
***************************************************************/
|
|
11486
11653
|
function register_c_yui_json() {
|
|
11487
11654
|
if ((0, _yuneta_gobj_js.gclass_find_by_name)(GCLASS_NAME$10, false)) return 0;
|
|
11655
|
+
if (!(0, _yuneta_gobj_js.gclass_find_by_name)("C_YUI_JSON_GRAPH", false)) register_c_yui_json_graph();
|
|
11488
11656
|
return create_gclass$10(GCLASS_NAME$10);
|
|
11489
11657
|
}
|
|
11490
11658
|
//#endregion
|