@yuneta/gobj-ui 7.19.4 → 7.20.1
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 +26 -3
- package/dist/gobj-ui.cjs.js +256 -29
- package/dist/gobj-ui.es.js +256 -29
- package/package.json +1 -1
- package/src/c_yui_json.css +38 -1
- package/src/c_yui_json.js +233 -16
- package/src/json_view_helpers.js +32 -2
- package/src/json_view_helpers.test.js +42 -0
- package/src/yui_icons.css +13 -0
package/README.md
CHANGED
|
@@ -426,19 +426,42 @@ 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
|
+
**Two views, one document.** The toolbar switch (and the `view_mode` attr,
|
|
430
|
+
`"tree"` | `"text"`) turns the tree into the **raw text** of the same working
|
|
431
|
+
document — `JSON.stringify(…, 4)`, four characters per level like every other
|
|
432
|
+
indentation in the house. It is the view for reading a document as it is
|
|
433
|
+
written, selecting a slab of it, or searching it with the browser's own Ctrl+F.
|
|
434
|
+
Two consequences worth knowing:
|
|
435
|
+
|
|
436
|
+
- Nothing there is lazy. The text prints what the client currently holds,
|
|
437
|
+
`__collapsed__` sentinels included, because that is honestly what it has.
|
|
438
|
+
Expand a branch in the tree and the text grows with it.
|
|
439
|
+
- The tree-only controls (search, expand-loaded, collapse-all) hide with the
|
|
440
|
+
tree; copy stays. A control that can answer nothing is worse than an absent
|
|
441
|
+
one.
|
|
442
|
+
|
|
443
|
+
Long lines scroll sideways **inside** the viewer (`white-space: pre` on a
|
|
444
|
+
`max-content`-wide `<pre>`), never on the page body: in a raw dump the
|
|
445
|
+
indentation *is* the structure, and a wrapped line restarts at column 0 and
|
|
446
|
+
lies about the depth of everything under it.
|
|
447
|
+
|
|
429
448
|
**Contract:**
|
|
430
449
|
|
|
431
450
|
- Attributes: `subscriber`, `title` (i18n key, optional), `json_data` (initial
|
|
432
|
-
JSON, optional),
|
|
451
|
+
JSON, optional), `view_mode` (`"tree"` default | `"text"`), `$container`
|
|
452
|
+
(mounted by the parent).
|
|
433
453
|
- Input events: `EV_SET_JSON {json}` (replace the whole document; `ST_EMPTY` →
|
|
434
454
|
`ST_READY`), `EV_SUBTREE_LOADED {path, json}` (splice a fetched subtree),
|
|
435
|
-
`EV_SUBTREE_ERROR {path, error}`,
|
|
436
|
-
`
|
|
455
|
+
`EV_SUBTREE_ERROR {path, error}`, `EV_SET_VIEW_MODE {mode}` (`"tree"` /
|
|
456
|
+
`"text"`; **no mode = toggle**, which is what the toolbar button sends), plus
|
|
457
|
+
`EV_REFRESH` / `EV_SHOW` / `EV_HIDE` / `EV_LANGUAGE_CHANGED`.
|
|
437
458
|
- Output event: `EV_EXPAND_PATH {path, size}` (`EVF_OUTPUT_EVENT`) — the parent
|
|
438
459
|
must declare it in its own FSM (CHILD subscription model).
|
|
439
460
|
- Internal (DOM → FSM): `EV_TOGGLE_NODE`, `EV_EXPAND_COLLAPSED`, `EV_SEARCH`,
|
|
440
461
|
`EV_EXPAND_ALL`, `EV_COLLAPSE_ALL`, `EV_COPY_ALL`. Every kw carries only a
|
|
441
462
|
`path` string — never a DOM node or gobj.
|
|
463
|
+
- i18n keys added by the text view: `text view`, `tree view`,
|
|
464
|
+
`text truncated; collapse some branches`.
|
|
442
465
|
- Paths use the kernel delimiter (backtick) and index arrays numerically, so a
|
|
443
466
|
path emitted by the viewer round-trips through `kw_find_path` on the backend.
|
|
444
467
|
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -10416,6 +10416,39 @@ function format_epoch(value) {
|
|
|
10416
10416
|
if (isNaN(d.getTime())) return null;
|
|
10417
10417
|
return d.toLocaleString();
|
|
10418
10418
|
}
|
|
10419
|
+
/************************************************************
|
|
10420
|
+
* The text view's payload: the document as text, indented
|
|
10421
|
+
* four characters, cut at `max_chars`.
|
|
10422
|
+
*
|
|
10423
|
+
* Returns {text, capped}. `capped` is what the caller
|
|
10424
|
+
* announces under the dump — a cut that is not announced
|
|
10425
|
+
* reads as a document that ends there.
|
|
10426
|
+
************************************************************/
|
|
10427
|
+
function json_text_dump(root, max_chars) {
|
|
10428
|
+
let text;
|
|
10429
|
+
try {
|
|
10430
|
+
text = JSON.stringify(root, null, 4);
|
|
10431
|
+
} catch (e) {
|
|
10432
|
+
return {
|
|
10433
|
+
text: "",
|
|
10434
|
+
capped: false,
|
|
10435
|
+
error: String(e)
|
|
10436
|
+
};
|
|
10437
|
+
}
|
|
10438
|
+
if (text === void 0) return {
|
|
10439
|
+
text: "",
|
|
10440
|
+
capped: false,
|
|
10441
|
+
error: "not representable as JSON"
|
|
10442
|
+
};
|
|
10443
|
+
if (typeof max_chars === "number" && max_chars > 0 && text.length > max_chars) return {
|
|
10444
|
+
text: text.slice(0, max_chars),
|
|
10445
|
+
capped: true
|
|
10446
|
+
};
|
|
10447
|
+
return {
|
|
10448
|
+
text,
|
|
10449
|
+
capped: false
|
|
10450
|
+
};
|
|
10451
|
+
}
|
|
10419
10452
|
//#endregion
|
|
10420
10453
|
//#region src/c_yui_json.js
|
|
10421
10454
|
/***********************************************************************
|
|
@@ -10444,9 +10477,19 @@ function format_epoch(value) {
|
|
|
10444
10477
|
* Only expanded containers are materialised in the DOM, so the tree
|
|
10445
10478
|
* stays bounded no matter how large the source document is.
|
|
10446
10479
|
*
|
|
10480
|
+
* TWO VIEWS over the same working document, chosen by the `view_mode`
|
|
10481
|
+
* attr ("tree" | "text") and switched from the toolbar: the lazy tree
|
|
10482
|
+
* above, and the raw `JSON.stringify(…, 4)` dump of what is currently
|
|
10483
|
+
* loaded. The text view is what you reach for to read a document as
|
|
10484
|
+
* it is written, to select a slab of it, or to search it with the
|
|
10485
|
+
* browser's own Ctrl+F; it shows the `__collapsed__` sentinels
|
|
10486
|
+
* verbatim, because that is honestly what the client holds. The
|
|
10487
|
+
* tree-only controls (search, expand/collapse) hide with the tree.
|
|
10488
|
+
*
|
|
10447
10489
|
* DOM is self-describing (UPPER_SNAKE logical classes): JSON_VIEWER /
|
|
10448
|
-
* JSON_TOOLBAR / JSON_SEARCH /
|
|
10449
|
-
*
|
|
10490
|
+
* JSON_TOOLBAR / JSON_SEARCH / JSON_VIEW_MODE / JSON_TREE / JSON_TEXT /
|
|
10491
|
+
* JSON_TEXT_BODY / JSON_ROW / JSON_KEY / JSON_VALUE / JSON_SUMMARY /
|
|
10492
|
+
* JSON_COLLAPSED / JSON_TIME.
|
|
10450
10493
|
*
|
|
10451
10494
|
* Copyright (c) 2026, ArtGins.
|
|
10452
10495
|
* All Rights Reserved.
|
|
@@ -10456,6 +10499,7 @@ function format_epoch(value) {
|
|
|
10456
10499
|
***************************************************************/
|
|
10457
10500
|
var GCLASS_NAME$10 = "C_YUI_JSON";
|
|
10458
10501
|
var MAX_RENDER_ROWS = 5e3;
|
|
10502
|
+
var MAX_TEXT_CHARS = 2e6;
|
|
10459
10503
|
/***************************************************************
|
|
10460
10504
|
* Data
|
|
10461
10505
|
***************************************************************/
|
|
@@ -10463,6 +10507,7 @@ var attrs_table$10 = [
|
|
|
10463
10507
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "subscriber", 0, null, "Subscriber of output events"),
|
|
10464
10508
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "title", 0, "", "Optional header title (i18n key)"),
|
|
10465
10509
|
(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) or 'text' (raw JSON dump)"),
|
|
10466
10511
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$container", 0, null, "HTMLElement root, mounted by the parent"),
|
|
10467
10512
|
(0, _yuneta_gobj_js.SDATA_END)()
|
|
10468
10513
|
];
|
|
@@ -10473,7 +10518,13 @@ var PRIVATE_DATA$10 = {
|
|
|
10473
10518
|
errors: null,
|
|
10474
10519
|
search: "",
|
|
10475
10520
|
$tree: null,
|
|
10476
|
-
$
|
|
10521
|
+
$text: null,
|
|
10522
|
+
$text_body: null,
|
|
10523
|
+
$search: null,
|
|
10524
|
+
$search_ctl: null,
|
|
10525
|
+
$expand_btn: null,
|
|
10526
|
+
$collapse_btn: null,
|
|
10527
|
+
$mode_btn: null
|
|
10477
10528
|
};
|
|
10478
10529
|
var __gclass__$10 = null;
|
|
10479
10530
|
/******************************
|
|
@@ -10491,6 +10542,7 @@ function mt_create$10(gobj) {
|
|
|
10491
10542
|
let json_data = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "json_data");
|
|
10492
10543
|
if (json_data !== null && json_data !== void 0) priv.root = (0, _yuneta_gobj_js.json_deep_copy)(json_data);
|
|
10493
10544
|
build_ui$9(gobj);
|
|
10545
|
+
apply_view_mode(gobj);
|
|
10494
10546
|
let subscriber = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(gobj, "subscriber");
|
|
10495
10547
|
if (!subscriber) subscriber = (0, _yuneta_gobj_js.gobj_parent)(gobj);
|
|
10496
10548
|
(0, _yuneta_gobj_js.gobj_subscribe_event)(gobj, null, {}, subscriber);
|
|
@@ -10499,7 +10551,7 @@ function mt_create$10(gobj) {
|
|
|
10499
10551
|
* Framework Method: Start
|
|
10500
10552
|
***************************************************************/
|
|
10501
10553
|
function mt_start$10(gobj) {
|
|
10502
|
-
|
|
10554
|
+
render_view(gobj);
|
|
10503
10555
|
}
|
|
10504
10556
|
/***************************************************************
|
|
10505
10557
|
* Framework Method: Stop
|
|
@@ -10526,22 +10578,38 @@ function build_ui$9(gobj) {
|
|
|
10526
10578
|
class: "C_YUI_JSON JSON_VIEWER view-card",
|
|
10527
10579
|
style: "height:100%; display:flex; flex-direction:column;"
|
|
10528
10580
|
},
|
|
10529
|
-
[
|
|
10530
|
-
|
|
10531
|
-
|
|
10532
|
-
|
|
10533
|
-
|
|
10534
|
-
|
|
10535
|
-
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10581
|
+
[
|
|
10582
|
+
[
|
|
10583
|
+
"div",
|
|
10584
|
+
{ class: "JSON_TOOLBAR is-flex-grow-0" },
|
|
10585
|
+
[$toolbar]
|
|
10586
|
+
],
|
|
10587
|
+
[
|
|
10588
|
+
"div",
|
|
10589
|
+
{
|
|
10590
|
+
class: "JSON_TREE is-flex-grow-1",
|
|
10591
|
+
style: "flex:1 1 auto; min-height:0; overflow:auto;"
|
|
10592
|
+
},
|
|
10593
|
+
[]
|
|
10594
|
+
],
|
|
10595
|
+
[
|
|
10596
|
+
"div",
|
|
10597
|
+
{
|
|
10598
|
+
class: "JSON_TEXT is-flex-grow-1 is-hidden",
|
|
10599
|
+
style: "flex:1 1 auto; min-height:0; overflow:auto;"
|
|
10600
|
+
},
|
|
10601
|
+
[]
|
|
10602
|
+
]
|
|
10603
|
+
]
|
|
10541
10604
|
]);
|
|
10542
10605
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "$container", $container);
|
|
10543
10606
|
priv.$tree = $container.querySelector(".JSON_TREE");
|
|
10607
|
+
priv.$text = $container.querySelector(".JSON_TEXT");
|
|
10544
10608
|
priv.$search = $container.querySelector(".JSON_SEARCH");
|
|
10609
|
+
priv.$search_ctl = $container.querySelector(".JSON_SEARCH_CONTROL");
|
|
10610
|
+
priv.$expand_btn = $container.querySelector(".EV_EXPAND_ALL");
|
|
10611
|
+
priv.$collapse_btn = $container.querySelector(".EV_COLLAPSE_ALL");
|
|
10612
|
+
priv.$mode_btn = $container.querySelector(".JSON_VIEW_MODE");
|
|
10545
10613
|
(0, _yuneta_gobj_js.refresh_language)($container, i18next.t);
|
|
10546
10614
|
}
|
|
10547
10615
|
/************************************************************
|
|
@@ -10555,10 +10623,17 @@ function destroy_ui$5(gobj) {
|
|
|
10555
10623
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "$container", null);
|
|
10556
10624
|
}
|
|
10557
10625
|
priv.$tree = null;
|
|
10626
|
+
priv.$text = null;
|
|
10627
|
+
priv.$text_body = null;
|
|
10558
10628
|
priv.$search = null;
|
|
10629
|
+
priv.$search_ctl = null;
|
|
10630
|
+
priv.$expand_btn = null;
|
|
10631
|
+
priv.$collapse_btn = null;
|
|
10632
|
+
priv.$mode_btn = null;
|
|
10559
10633
|
}
|
|
10560
10634
|
/************************************************************
|
|
10561
|
-
* Toolbar: search +
|
|
10635
|
+
* Toolbar: search + tree/text switch + expand-all /
|
|
10636
|
+
* collapse-all / copy
|
|
10562
10637
|
************************************************************/
|
|
10563
10638
|
function make_toolbar$2(gobj) {
|
|
10564
10639
|
let title = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "title");
|
|
@@ -10587,7 +10662,7 @@ function make_toolbar$2(gobj) {
|
|
|
10587
10662
|
let $search_control = (0, _yuneta_gobj_js.createElement2)([
|
|
10588
10663
|
"div",
|
|
10589
10664
|
{
|
|
10590
|
-
class: "control has-icons-left",
|
|
10665
|
+
class: "control has-icons-left JSON_SEARCH_CONTROL",
|
|
10591
10666
|
style: "max-width:22em;"
|
|
10592
10667
|
},
|
|
10593
10668
|
[$search_input, [
|
|
@@ -10599,6 +10674,7 @@ function make_toolbar$2(gobj) {
|
|
|
10599
10674
|
attach_clear($search_control, $search_input);
|
|
10600
10675
|
left_items.push($search_control);
|
|
10601
10676
|
let right_items = [
|
|
10677
|
+
view_mode_button(gobj),
|
|
10602
10678
|
icon_button(gobj, "yi-chevron-right", "EV_EXPAND_ALL", "expand loaded"),
|
|
10603
10679
|
icon_button(gobj, "yi-chevron-right", "EV_COLLAPSE_ALL", "collapse all"),
|
|
10604
10680
|
icon_button(gobj, "yi-copy", "EV_COPY_ALL", "copy json")
|
|
@@ -10655,6 +10731,123 @@ function icon_button(gobj, icon, event_name, label_key) {
|
|
|
10655
10731
|
];
|
|
10656
10732
|
}
|
|
10657
10733
|
/************************************************************
|
|
10734
|
+
* The tree/text switch.
|
|
10735
|
+
*
|
|
10736
|
+
* It shows the view it takes you TO — the `code` glyph while the
|
|
10737
|
+
* tree is on screen, the `sitemap` glyph while the text is — and
|
|
10738
|
+
* sends EV_SET_VIEW_MODE with no mode, which the action reads as
|
|
10739
|
+
* "toggle". apply_view_mode() keeps the icon and its i18n keys in
|
|
10740
|
+
* step with the attr.
|
|
10741
|
+
************************************************************/
|
|
10742
|
+
function view_mode_button(gobj) {
|
|
10743
|
+
return [
|
|
10744
|
+
"button",
|
|
10745
|
+
{
|
|
10746
|
+
class: "button JSON_VIEW_MODE",
|
|
10747
|
+
style: "width:2.5em;",
|
|
10748
|
+
title: (0, i18next.t)("text view"),
|
|
10749
|
+
"data-i18n-title": "text view",
|
|
10750
|
+
"aria-label": (0, i18next.t)("text view"),
|
|
10751
|
+
"data-i18n-aria-label": "text view"
|
|
10752
|
+
},
|
|
10753
|
+
[[
|
|
10754
|
+
"span",
|
|
10755
|
+
{ class: "icon" },
|
|
10756
|
+
[["i", { class: "yi-code" }]]
|
|
10757
|
+
]],
|
|
10758
|
+
{ click: function(evt) {
|
|
10759
|
+
evt.stopPropagation();
|
|
10760
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SET_VIEW_MODE", {}, gobj);
|
|
10761
|
+
} }
|
|
10762
|
+
];
|
|
10763
|
+
}
|
|
10764
|
+
/************************************************************
|
|
10765
|
+
* The current view, normalised. Anything but "text" is the tree.
|
|
10766
|
+
************************************************************/
|
|
10767
|
+
function current_view_mode(gobj) {
|
|
10768
|
+
return (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "view_mode") === "text" ? "text" : "tree";
|
|
10769
|
+
}
|
|
10770
|
+
/************************************************************
|
|
10771
|
+
* Show the chrome of the current view and hide the other's.
|
|
10772
|
+
************************************************************/
|
|
10773
|
+
function apply_view_mode(gobj) {
|
|
10774
|
+
let priv = gobj.priv;
|
|
10775
|
+
let text_mode = current_view_mode(gobj) === "text";
|
|
10776
|
+
if (priv.$tree) priv.$tree.classList.toggle("is-hidden", text_mode);
|
|
10777
|
+
if (priv.$text) priv.$text.classList.toggle("is-hidden", !text_mode);
|
|
10778
|
+
[
|
|
10779
|
+
priv.$search_ctl,
|
|
10780
|
+
priv.$expand_btn,
|
|
10781
|
+
priv.$collapse_btn
|
|
10782
|
+
].forEach(function($el) {
|
|
10783
|
+
if ($el) $el.classList.toggle("is-hidden", text_mode);
|
|
10784
|
+
});
|
|
10785
|
+
if (priv.$mode_btn) {
|
|
10786
|
+
let icon = text_mode ? "yi-sitemap" : "yi-code";
|
|
10787
|
+
let key = text_mode ? "tree view" : "text view";
|
|
10788
|
+
let label = text_mode ? (0, i18next.t)("tree view") : (0, i18next.t)("text view");
|
|
10789
|
+
let $i = priv.$mode_btn.querySelector("i");
|
|
10790
|
+
if ($i) $i.className = icon;
|
|
10791
|
+
priv.$mode_btn.setAttribute("data-i18n-title", key);
|
|
10792
|
+
priv.$mode_btn.setAttribute("data-i18n-aria-label", key);
|
|
10793
|
+
priv.$mode_btn.setAttribute("title", label);
|
|
10794
|
+
priv.$mode_btn.setAttribute("aria-label", label);
|
|
10795
|
+
}
|
|
10796
|
+
}
|
|
10797
|
+
/************************************************************
|
|
10798
|
+
* Render whichever view is current.
|
|
10799
|
+
************************************************************/
|
|
10800
|
+
function render_view(gobj) {
|
|
10801
|
+
if (current_view_mode(gobj) === "text") render_text(gobj);
|
|
10802
|
+
else render_tree(gobj);
|
|
10803
|
+
}
|
|
10804
|
+
/************************************************************
|
|
10805
|
+
* Render the text view: the whole loaded document, verbatim.
|
|
10806
|
+
*
|
|
10807
|
+
* Unlike the tree, nothing here is lazy — what the client holds is
|
|
10808
|
+
* what it prints, `__collapsed__` sentinels included. Over
|
|
10809
|
+
* MAX_TEXT_CHARS the dump is cut and the cut is announced.
|
|
10810
|
+
************************************************************/
|
|
10811
|
+
function render_text(gobj) {
|
|
10812
|
+
let priv = gobj.priv;
|
|
10813
|
+
let $text = priv.$text;
|
|
10814
|
+
if (!$text) return;
|
|
10815
|
+
let scroll_top = $text.scrollTop;
|
|
10816
|
+
$text.textContent = "";
|
|
10817
|
+
priv.$text_body = null;
|
|
10818
|
+
if (priv.root === null || priv.root === void 0) {
|
|
10819
|
+
$text.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
10820
|
+
"div",
|
|
10821
|
+
{
|
|
10822
|
+
class: "JSON_EMPTY has-text-grey p-3",
|
|
10823
|
+
"data-i18n": "no data"
|
|
10824
|
+
},
|
|
10825
|
+
"no data"
|
|
10826
|
+
]));
|
|
10827
|
+
return;
|
|
10828
|
+
}
|
|
10829
|
+
let dump = json_text_dump(priv.root, MAX_TEXT_CHARS);
|
|
10830
|
+
if (dump.error) (0, _yuneta_gobj_js.log_error)(`${GCLASS_NAME$10}: cannot dump the document as text: ${dump.error}`);
|
|
10831
|
+
let $pre = (0, _yuneta_gobj_js.createElement2)([
|
|
10832
|
+
"pre",
|
|
10833
|
+
{ class: "JSON_TEXT_BODY" },
|
|
10834
|
+
[]
|
|
10835
|
+
]);
|
|
10836
|
+
$pre.textContent = dump.text;
|
|
10837
|
+
$text.appendChild($pre);
|
|
10838
|
+
priv.$text_body = $pre;
|
|
10839
|
+
if (dump.capped) $text.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
10840
|
+
"div",
|
|
10841
|
+
{
|
|
10842
|
+
class: "JSON_CAPPED has-text-warning p-2",
|
|
10843
|
+
"data-i18n": "text truncated; collapse some branches"
|
|
10844
|
+
},
|
|
10845
|
+
"text truncated; collapse some branches"
|
|
10846
|
+
]));
|
|
10847
|
+
(0, _yuneta_gobj_js.refresh_language)($text, i18next.t);
|
|
10848
|
+
$text.scrollTop = scroll_top;
|
|
10849
|
+
}
|
|
10850
|
+
/************************************************************
|
|
10658
10851
|
* Re-render the whole tree from priv.root + priv.expanded.
|
|
10659
10852
|
*
|
|
10660
10853
|
* Only expanded containers are walked, so the DOM size is
|
|
@@ -10985,7 +11178,7 @@ function ac_set_json(gobj, event, kw, src) {
|
|
|
10985
11178
|
priv.expanded.clear();
|
|
10986
11179
|
priv.pending.clear();
|
|
10987
11180
|
priv.errors.clear();
|
|
10988
|
-
|
|
11181
|
+
render_view(gobj);
|
|
10989
11182
|
return 0;
|
|
10990
11183
|
}
|
|
10991
11184
|
/************************************************************
|
|
@@ -11000,7 +11193,7 @@ function ac_subtree_loaded(gobj, event, kw, src) {
|
|
|
11000
11193
|
priv.pending.delete(path);
|
|
11001
11194
|
priv.errors.delete(path);
|
|
11002
11195
|
if (path) priv.expanded.add(path);
|
|
11003
|
-
|
|
11196
|
+
render_view(gobj);
|
|
11004
11197
|
return 0;
|
|
11005
11198
|
}
|
|
11006
11199
|
/************************************************************
|
|
@@ -11012,7 +11205,7 @@ function ac_subtree_error(gobj, event, kw, src) {
|
|
|
11012
11205
|
priv.pending.delete(path);
|
|
11013
11206
|
priv.errors.set(path, kw.error || "error");
|
|
11014
11207
|
(0, _yuneta_gobj_js.log_error)(`${GCLASS_NAME$10}: subtree load failed at '${path}': ${kw.error || ""}`);
|
|
11015
|
-
|
|
11208
|
+
render_view(gobj);
|
|
11016
11209
|
return 0;
|
|
11017
11210
|
}
|
|
11018
11211
|
/************************************************************
|
|
@@ -11023,7 +11216,7 @@ function ac_toggle_node(gobj, event, kw, src) {
|
|
|
11023
11216
|
let path = kw.path || "";
|
|
11024
11217
|
if (priv.expanded.has(path)) priv.expanded.delete(path);
|
|
11025
11218
|
else priv.expanded.add(path);
|
|
11026
|
-
|
|
11219
|
+
render_view(gobj);
|
|
11027
11220
|
return 0;
|
|
11028
11221
|
}
|
|
11029
11222
|
/************************************************************
|
|
@@ -11036,7 +11229,7 @@ function ac_expand_collapsed(gobj, event, kw, src) {
|
|
|
11036
11229
|
if (priv.pending.has(path)) return 0;
|
|
11037
11230
|
priv.pending.add(path);
|
|
11038
11231
|
priv.errors.delete(path);
|
|
11039
|
-
|
|
11232
|
+
render_view(gobj);
|
|
11040
11233
|
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_EXPAND_PATH", {
|
|
11041
11234
|
path,
|
|
11042
11235
|
size: kw.size
|
|
@@ -11049,7 +11242,7 @@ function ac_expand_collapsed(gobj, event, kw, src) {
|
|
|
11049
11242
|
function ac_search$1(gobj, event, kw, src) {
|
|
11050
11243
|
let priv = gobj.priv;
|
|
11051
11244
|
priv.search = (kw.text || "").trim().toLowerCase();
|
|
11052
|
-
|
|
11245
|
+
render_view(gobj);
|
|
11053
11246
|
return 0;
|
|
11054
11247
|
}
|
|
11055
11248
|
/************************************************************
|
|
@@ -11067,7 +11260,7 @@ function ac_expand_all$1(gobj, event, kw, src) {
|
|
|
11067
11260
|
paths.forEach(function(p) {
|
|
11068
11261
|
priv.expanded.add(p);
|
|
11069
11262
|
});
|
|
11070
|
-
|
|
11263
|
+
render_view(gobj);
|
|
11071
11264
|
return 0;
|
|
11072
11265
|
}
|
|
11073
11266
|
/************************************************************
|
|
@@ -11075,7 +11268,7 @@ function ac_expand_all$1(gobj, event, kw, src) {
|
|
|
11075
11268
|
************************************************************/
|
|
11076
11269
|
function ac_collapse_all$1(gobj, event, kw, src) {
|
|
11077
11270
|
gobj.priv.expanded.clear();
|
|
11078
|
-
|
|
11271
|
+
render_view(gobj);
|
|
11079
11272
|
return 0;
|
|
11080
11273
|
}
|
|
11081
11274
|
/************************************************************
|
|
@@ -11084,7 +11277,12 @@ function ac_collapse_all$1(gobj, event, kw, src) {
|
|
|
11084
11277
|
function ac_copy_all(gobj, event, kw, src) {
|
|
11085
11278
|
let priv = gobj.priv;
|
|
11086
11279
|
if (priv.root === null || priv.root === void 0) return 0;
|
|
11087
|
-
let
|
|
11280
|
+
let dump = json_text_dump(priv.root, 0);
|
|
11281
|
+
if (dump.error) {
|
|
11282
|
+
(0, _yuneta_gobj_js.log_error)(`${GCLASS_NAME$10}: cannot copy the document: ${dump.error}`);
|
|
11283
|
+
return -1;
|
|
11284
|
+
}
|
|
11285
|
+
let text = dump.text;
|
|
11088
11286
|
if (navigator.clipboard && navigator.clipboard.writeText) navigator.clipboard.writeText(text).catch(function(e) {
|
|
11089
11287
|
(0, _yuneta_gobj_js.log_error)(`${GCLASS_NAME$10}: clipboard write failed: ${e}`);
|
|
11090
11288
|
});
|
|
@@ -11092,6 +11290,23 @@ function ac_copy_all(gobj, event, kw, src) {
|
|
|
11092
11290
|
return 0;
|
|
11093
11291
|
}
|
|
11094
11292
|
/************************************************************
|
|
11293
|
+
* EV_SET_VIEW_MODE { mode } — "tree" | "text".
|
|
11294
|
+
*
|
|
11295
|
+
* With no mode it toggles, which is what the toolbar button sends.
|
|
11296
|
+
************************************************************/
|
|
11297
|
+
function ac_set_view_mode(gobj, event, kw, src) {
|
|
11298
|
+
let mode = kw.mode;
|
|
11299
|
+
if (mode === void 0 || mode === null || mode === "") mode = current_view_mode(gobj) === "text" ? "tree" : "text";
|
|
11300
|
+
else if (mode !== "tree" && mode !== "text") {
|
|
11301
|
+
(0, _yuneta_gobj_js.log_error)(`${GCLASS_NAME$10}: unknown view_mode '${mode}'`);
|
|
11302
|
+
return -1;
|
|
11303
|
+
}
|
|
11304
|
+
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "view_mode", mode);
|
|
11305
|
+
apply_view_mode(gobj);
|
|
11306
|
+
render_view(gobj);
|
|
11307
|
+
return 0;
|
|
11308
|
+
}
|
|
11309
|
+
/************************************************************
|
|
11095
11310
|
* EV_LANGUAGE_CHANGED — re-translate chrome + re-render
|
|
11096
11311
|
************************************************************/
|
|
11097
11312
|
function ac_language_changed$3(gobj, event, kw, src) {
|
|
@@ -11100,8 +11315,9 @@ function ac_language_changed$3(gobj, event, kw, src) {
|
|
|
11100
11315
|
if ($container) {
|
|
11101
11316
|
(0, _yuneta_gobj_js.refresh_language)($container, i18next.t);
|
|
11102
11317
|
if (priv.$search) priv.$search.setAttribute("placeholder", (0, i18next.t)("search"));
|
|
11318
|
+
apply_view_mode(gobj);
|
|
11103
11319
|
}
|
|
11104
|
-
|
|
11320
|
+
render_view(gobj);
|
|
11105
11321
|
return 0;
|
|
11106
11322
|
}
|
|
11107
11323
|
/************************************************************
|
|
@@ -11121,7 +11337,7 @@ function ac_hide$6(gobj, event, kw, src) {
|
|
|
11121
11337
|
* EV_REFRESH
|
|
11122
11338
|
************************************************************/
|
|
11123
11339
|
function ac_refresh$4(gobj, event, kw, src) {
|
|
11124
|
-
|
|
11340
|
+
render_view(gobj);
|
|
11125
11341
|
return 0;
|
|
11126
11342
|
}
|
|
11127
11343
|
/***************************
|
|
@@ -11147,6 +11363,11 @@ function create_gclass$10(gclass_name) {
|
|
|
11147
11363
|
ac_set_json,
|
|
11148
11364
|
"ST_READY"
|
|
11149
11365
|
],
|
|
11366
|
+
[
|
|
11367
|
+
"EV_SET_VIEW_MODE",
|
|
11368
|
+
ac_set_view_mode,
|
|
11369
|
+
null
|
|
11370
|
+
],
|
|
11150
11371
|
[
|
|
11151
11372
|
"EV_LANGUAGE_CHANGED",
|
|
11152
11373
|
ac_language_changed$3,
|
|
@@ -11213,6 +11434,11 @@ function create_gclass$10(gclass_name) {
|
|
|
11213
11434
|
ac_copy_all,
|
|
11214
11435
|
null
|
|
11215
11436
|
],
|
|
11437
|
+
[
|
|
11438
|
+
"EV_SET_VIEW_MODE",
|
|
11439
|
+
ac_set_view_mode,
|
|
11440
|
+
null
|
|
11441
|
+
],
|
|
11216
11442
|
[
|
|
11217
11443
|
"EV_LANGUAGE_CHANGED",
|
|
11218
11444
|
ac_language_changed$3,
|
|
@@ -11244,6 +11470,7 @@ function create_gclass$10(gclass_name) {
|
|
|
11244
11470
|
["EV_EXPAND_ALL", 0],
|
|
11245
11471
|
["EV_COLLAPSE_ALL", 0],
|
|
11246
11472
|
["EV_COPY_ALL", 0],
|
|
11473
|
+
["EV_SET_VIEW_MODE", 0],
|
|
11247
11474
|
["EV_LANGUAGE_CHANGED", 0],
|
|
11248
11475
|
["EV_REFRESH", 0],
|
|
11249
11476
|
["EV_SHOW", 0],
|