@yuneta/gobj-ui 7.23.38 → 7.23.40

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.
@@ -10916,10 +10916,6 @@ function make_toolbar$5(gobj) {
10916
10916
  "span",
10917
10917
  { class: "JSON_GRAPH_FIND_COUNT" },
10918
10918
  ""
10919
- ], [
10920
- "span",
10921
- { i18n: "matches" },
10922
- "matches"
10923
10919
  ]]
10924
10920
  ]]);
10925
10921
  let center_items = [];
@@ -11437,7 +11433,7 @@ function collect_foldable_paths(value, path, out, is_root) {
11437
11433
  * move looks the same whether nothing matched or the match
11438
11434
  * was already on screen.
11439
11435
  ************************************************************/
11440
- function update_find_result(gobj) {
11436
+ function update_find_result$1(gobj) {
11441
11437
  let priv = gobj.priv;
11442
11438
  if (!priv.$find_result || !priv.$find_count) return;
11443
11439
  if (empty_string(priv.search)) {
@@ -11445,7 +11441,7 @@ function update_find_result(gobj) {
11445
11441
  priv.$find_count.textContent = "";
11446
11442
  return;
11447
11443
  }
11448
- priv.$find_count.textContent = String(priv.match_count);
11444
+ priv.$find_count.textContent = t("matches", { count: priv.match_count });
11449
11445
  priv.$find_result.classList.remove("is-hidden");
11450
11446
  }
11451
11447
  /************************************************************
@@ -11702,7 +11698,7 @@ function ac_change_layout$2(gobj, event, kw, src) {
11702
11698
  edge: { type: cfg.edge_type }
11703
11699
  });
11704
11700
  refresh_json(gobj);
11705
- update_find_result(gobj);
11701
+ update_find_result$1(gobj);
11706
11702
  return 0;
11707
11703
  }
11708
11704
  /************************************************************
@@ -11731,7 +11727,7 @@ function ac_toggle_fold(gobj, event, kw, src) {
11731
11727
  }
11732
11728
  priv.pending_keep = keep_of(gobj, kw && kw.keep || path);
11733
11729
  refresh_json(gobj, { preserve_view: true });
11734
- update_find_result(gobj);
11730
+ update_find_result$1(gobj);
11735
11731
  return 0;
11736
11732
  }
11737
11733
  /************************************************************
@@ -11742,11 +11738,11 @@ function ac_toggle_fold(gobj, event, kw, src) {
11742
11738
  * keystroke is unusable. The count says whether there is
11743
11739
  * anything to look for elsewhere.
11744
11740
  ************************************************************/
11745
- function ac_find_nodes$2(gobj, event, kw, src) {
11741
+ function ac_find_nodes$3(gobj, event, kw, src) {
11746
11742
  let priv = gobj.priv;
11747
11743
  priv.search = (kw && kw.text || "").trim().toLowerCase();
11748
11744
  refresh_json(gobj, { preserve_view: true });
11749
- update_find_result(gobj);
11745
+ update_find_result$1(gobj);
11750
11746
  return 0;
11751
11747
  }
11752
11748
  /************************************************************
@@ -11758,7 +11754,7 @@ function ac_expand_all$2(gobj, event, kw, src) {
11758
11754
  priv.collapsed.clear();
11759
11755
  priv.reserved.clear();
11760
11756
  refresh_json(gobj);
11761
- update_find_result(gobj);
11757
+ update_find_result$1(gobj);
11762
11758
  return 0;
11763
11759
  }
11764
11760
  /************************************************************
@@ -11775,7 +11771,7 @@ function ac_collapse_all$2(gobj, event, kw, src) {
11775
11771
  priv.collapsed = new Set(paths);
11776
11772
  priv.reserved.clear();
11777
11773
  refresh_json(gobj);
11778
- update_find_result(gobj);
11774
+ update_find_result$1(gobj);
11779
11775
  return 0;
11780
11776
  }
11781
11777
  /************************************************************
@@ -12049,7 +12045,7 @@ function create_gclass$13(gclass_name) {
12049
12045
  ],
12050
12046
  [
12051
12047
  "EV_FIND_NODES",
12052
- ac_find_nodes$2,
12048
+ ac_find_nodes$3,
12053
12049
  null
12054
12050
  ],
12055
12051
  [
@@ -16127,6 +16123,21 @@ function node_status(d) {
16127
16123
  if (!d || !d.running) return "stopped";
16128
16124
  return d.playing ? "playing" : "running";
16129
16125
  }
16126
+ var STATUS_SYMBOLS = {
16127
+ "playing": "▶︎",
16128
+ "running": "‖",
16129
+ "stopped": "■︎"
16130
+ };
16131
+ var DISABLED_SYMBOL = "⊘";
16132
+ /************************************************************
16133
+ * The symbol of a node's status, which is what the reader
16134
+ * actually sees first. `disabled` overrides the rest: a
16135
+ * disabled gobj is not going to run whatever it is doing now.
16136
+ ************************************************************/
16137
+ function node_status_symbol(d) {
16138
+ if (d && d.disabled) return DISABLED_SYMBOL;
16139
+ return STATUS_SYMBOLS[node_status(d)] || STATUS_SYMBOLS.stopped;
16140
+ }
16130
16141
  /************************************************************
16131
16142
  * The i18n key of the status, which is NOT the status itself:
16132
16143
  * a gobj that runs and does not play is PAUSED to the reader,
@@ -16255,7 +16266,7 @@ function node_labels(t) {
16255
16266
  full_name: t("full name"),
16256
16267
  role: t("role"),
16257
16268
  status: t("status"),
16258
- state: t("state"),
16269
+ fsm_state: t("fsm state"),
16259
16270
  disabled: t("disabled"),
16260
16271
  parent: t("parent"),
16261
16272
  bottom_gobj: t("bottom gobj"),
@@ -16284,8 +16295,8 @@ function node_info_rows(d, t) {
16284
16295
  rows.push([f.name, d.name || "—"]);
16285
16296
  if (d.fullname && d.fullname !== d.shortname) rows.push([f.full_name, d.fullname]);
16286
16297
  rows.push([f.role, L.role[role_i18n_key(node_role(d))]]);
16287
- rows.push([f.status, L.status[node_status_key(d)]]);
16288
- rows.push([f.state, d.state || "—"]);
16298
+ rows.push([f.status, node_status_symbol(d) + " " + L.status[node_status_key(d)]]);
16299
+ rows.push([f.fsm_state, d.state || "—"]);
16289
16300
  if (d.disabled) rows.push([f.disabled, f.yes]);
16290
16301
  if (d.parent) rows.push([f.parent, d.parent]);
16291
16302
  if (d.bottom_gobj) rows.push([f.bottom_gobj, d.bottom_gobj]);
@@ -16767,6 +16778,12 @@ var PRIVATE_DATA$9 = {
16767
16778
  theme: null,
16768
16779
  theme_observer: null,
16769
16780
  $layout_select: null,
16781
+ search: "",
16782
+ match_count: 0,
16783
+ find_timer: null,
16784
+ $find_input: null,
16785
+ $find_result: null,
16786
+ $find_count: null,
16770
16787
  $popover: null,
16771
16788
  $popover_title: null,
16772
16789
  $popover_body: null,
@@ -16912,6 +16929,7 @@ var NODE_SIZES = {
16912
16929
  /***************************************************************
16913
16930
  * Shared card typography.
16914
16931
  ***************************************************************/
16932
+ var FIND_MATCH_COLOR = "#D9A23F";
16915
16933
  var GT_FONT = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
16916
16934
  /***************************************************************
16917
16935
  * Theme-aware card palette derived from the role colour.
@@ -17284,11 +17302,103 @@ function destroy_ui$4(gobj) {
17284
17302
  /************************************************************
17285
17303
  * Toolbar
17286
17304
  ************************************************************/
17305
+ /************************************************************
17306
+ * The find box and its count.
17307
+ *
17308
+ * A tree of a real yuno is a hundred cards, and the only way
17309
+ * to locate one was to read them all. The COUNT is what makes
17310
+ * it honest: a graph that did not move looks the same whether
17311
+ * nothing matched or the match was already on screen -- the
17312
+ * same reason the JSON graph carries one, and the same
17313
+ * drawing, because the two sit in the same console.
17314
+ ************************************************************/
17315
+ function make_find_items(gobj) {
17316
+ let priv = gobj.priv;
17317
+ let $find_input = createElement2([
17318
+ "input",
17319
+ {
17320
+ class: "GOBJ_TREE_FIND_INPUT input",
17321
+ type: "text",
17322
+ placeholder: t("search"),
17323
+ "data-i18n-placeholder": "search",
17324
+ "aria-label": t("search"),
17325
+ "data-i18n-aria-label": "search"
17326
+ },
17327
+ [],
17328
+ { input: (evt) => {
17329
+ evt.stopPropagation();
17330
+ let text = evt.target.value.trim();
17331
+ if (priv.find_timer) clearTimeout(priv.find_timer);
17332
+ priv.find_timer = setTimeout(function() {
17333
+ priv.find_timer = null;
17334
+ gobj_send_event(gobj, "EV_FIND_NODES", { text }, gobj);
17335
+ }, 250);
17336
+ } }
17337
+ ]);
17338
+ let $find_control = createElement2([
17339
+ "div",
17340
+ {
17341
+ class: "GOBJ_TREE_FIND control has-icons-left",
17342
+ style: "margin-left:.5rem; margin-right:.5rem; max-width:12rem; min-width:7rem;"
17343
+ },
17344
+ [$find_input, [
17345
+ "span",
17346
+ { class: "icon is-left" },
17347
+ [["i", { class: "yi-magnifying-glass" }]]
17348
+ ]]
17349
+ ]);
17350
+ attach_clear($find_control, $find_input);
17351
+ priv.$find_input = $find_input;
17352
+ return [$find_control, [
17353
+ "div",
17354
+ {
17355
+ class: "GOBJ_TREE_FIND_RESULT is-hidden",
17356
+ style: "display:flex; align-items:center; gap:.3rem; margin-right:.5rem; font-size:.85rem;"
17357
+ },
17358
+ [[
17359
+ "span",
17360
+ { class: "GOBJ_TREE_FIND_COUNT" },
17361
+ ""
17362
+ ]]
17363
+ ]];
17364
+ }
17365
+ /************************************************************
17366
+ * Does this node answer the current find term?
17367
+ *
17368
+ * What a reader types is a gclass, a name or a state -- the
17369
+ * three things a card shows. The full name is searched too,
17370
+ * because it is what the popover shows and what a log line
17371
+ * carries.
17372
+ ************************************************************/
17373
+ function node_matches(d, term) {
17374
+ if (!term) return false;
17375
+ return [
17376
+ d.gclass,
17377
+ d.name,
17378
+ d.fullname,
17379
+ d.state
17380
+ ].filter((x) => typeof x === "string").join(" ").toLowerCase().indexOf(term) >= 0;
17381
+ }
17382
+ /************************************************************
17383
+ * Repaint the count chip. Hidden while nothing is typed:
17384
+ * "0 matches" beside an empty box says nothing.
17385
+ ************************************************************/
17386
+ function update_find_result(gobj) {
17387
+ let priv = gobj.priv;
17388
+ if (!priv.$find_result || !priv.$find_count) return;
17389
+ if (!priv.search) {
17390
+ priv.$find_result.classList.add("is-hidden");
17391
+ priv.$find_count.textContent = "";
17392
+ return;
17393
+ }
17394
+ priv.$find_count.textContent = t("matches", { count: priv.match_count });
17395
+ priv.$find_result.classList.remove("is-hidden");
17396
+ }
17287
17397
  function make_toolbar$1(gobj) {
17288
17398
  let priv = gobj.priv;
17289
17399
  let toolbar_wide = gobj_read_attr(gobj, "wide");
17290
17400
  let current_layout = gobj_read_str_attr(gobj, "layout");
17291
- let left_items = yui_graph_fold_items(gobj, toolbar_wide);
17401
+ let left_items = yui_graph_fold_items(gobj, toolbar_wide).concat(make_find_items(gobj));
17292
17402
  let center_items = [];
17293
17403
  let right_items = [];
17294
17404
  center_items = yui_graph_camera_items(gobj, priv.graph, toolbar_wide);
@@ -17339,6 +17449,8 @@ function make_toolbar$1(gobj) {
17339
17449
  right_items
17340
17450
  ]
17341
17451
  ]);
17452
+ priv.$find_result = $toolbar.querySelector(".GOBJ_TREE_FIND_RESULT");
17453
+ priv.$find_count = $toolbar.querySelector(".GOBJ_TREE_FIND_COUNT");
17342
17454
  refresh_language($toolbar, t);
17343
17455
  return $toolbar;
17344
17456
  }
@@ -17514,26 +17626,32 @@ function render_toggle_html(node_id, collapsed, num_children, cs) {
17514
17626
  /************************************************************
17515
17627
  * HTML for the status pill: what the gobj is DOING.
17516
17628
  *
17517
- * A dot plus a word, and the word is dropped in the compact
17518
- * card where there is no room for it -- the colour still
17519
- * carries it, and the `title` says it in full either way.
17629
+ * A SYMBOL plus a word, and the word is dropped in the
17630
+ * compact card where there is no room for it.
17631
+ *
17632
+ * The symbol carries the state on its own, which a dot never
17633
+ * did: a dot has one shape, so telling running from stopped
17634
+ * meant telling green from red at 10 pixels -- and stopped is
17635
+ * the one that has to be seen. Play, pause and stop are also
17636
+ * the framework's own three verbs, not a borrowed metaphor.
17520
17637
  ************************************************************/
17521
17638
  function render_status_html(d, ss, labels, with_label) {
17522
17639
  let full = d.disabled ? labels.field.disabled : labels.status[node_status_key(d)] || node_status_key(d);
17523
17640
  let label = d.disabled ? labels.field.disabled : labels.status_short[node_status(d)] || node_status(d);
17641
+ let symbol = node_status_symbol(d);
17524
17642
  if (!with_label) return `<span title="${escapeHtml(full)}" style="
17525
17643
  flex: 0 0 auto;
17526
- width: 10px; height: 10px; border-radius: 50%;
17527
- background: ${ss.dot};
17528
- box-shadow: 0 0 0 2px ${ss.bg};
17529
17644
  margin-left: 6px;
17530
- "></span>`;
17645
+ color: ${ss.dot};
17646
+ font-size: 11px;
17647
+ line-height: 1;
17648
+ ">${escapeHtml(symbol)}</span>`;
17531
17649
  return `<span title="${escapeHtml(full)}" style="
17532
17650
  flex: 0 0 auto;
17533
17651
  display: inline-flex;
17534
17652
  align-items: center;
17535
17653
  gap: 4px;
17536
- padding: 1px 7px 1px 5px;
17654
+ padding: 1px 7px 1px 6px;
17537
17655
  background: ${ss.bg};
17538
17656
  color: ${ss.fg};
17539
17657
  border-radius: 9px;
@@ -17541,7 +17659,8 @@ function render_status_html(d, ss, labels, with_label) {
17541
17659
  font-weight: 700;
17542
17660
  line-height: 1.45;
17543
17661
  white-space: nowrap;
17544
- "><span style="width:7px; height:7px; border-radius:50%; background:${ss.dot};"></span>${escapeHtml(label)}</span>`;
17662
+ "><span style="color:${ss.dot}; font-size:11px; line-height:1;"
17663
+ >${escapeHtml(symbol)}</span>${escapeHtml(label)}</span>`;
17545
17664
  }
17546
17665
  /************************************************************
17547
17666
  * HTML for the badges: what the gobj IS, besides its colour.
@@ -17588,6 +17707,12 @@ function build_gobj_nodes(gobj, d, nodes, edges, parent_id, compact, labels) {
17588
17707
  let height = size.h;
17589
17708
  let border_width = category === "yuno" || category === "service" ? 2 : 1;
17590
17709
  let border_style = d.disabled ? "dashed" : "solid";
17710
+ if (node_matches(d, priv.search)) {
17711
+ priv.match_count++;
17712
+ border_width = 3;
17713
+ border_style = "solid";
17714
+ cs = Object.assign({}, cs, { border: FIND_MATCH_COLOR });
17715
+ }
17591
17716
  let children = d.children || [];
17592
17717
  let num_children = children.length;
17593
17718
  let has_children = num_children > 0;
@@ -17712,6 +17837,7 @@ function load_tree(gobj) {
17712
17837
  }
17713
17838
  let layout_cfg = get_layout_cfg(gobj_read_str_attr(gobj, "layout"));
17714
17839
  let labels = node_labels(t);
17840
+ priv.match_count = 0;
17715
17841
  let anchor = priv.pending_anchor || null;
17716
17842
  let preserve_view = !!priv.pending_preserve_view;
17717
17843
  priv.pending_anchor = null;
@@ -18141,6 +18267,23 @@ var GobjLanesHLayout = class extends BaseLayout {
18141
18267
  /************************************************************
18142
18268
  *
18143
18269
  ************************************************************/
18270
+ /************************************************************
18271
+ * EV_FIND_NODES {text}
18272
+ *
18273
+ * The cards carry the highlight in their own markup (an html
18274
+ * node paints no G6 state), so finding is a REBUILD -- which
18275
+ * is also why the box is rate-limited. The view is preserved:
18276
+ * a reader who typed a letter did not ask to be moved.
18277
+ ************************************************************/
18278
+ function ac_find_nodes$2(gobj, event, kw, src) {
18279
+ let priv = gobj.priv;
18280
+ let text = String(kw && kw.text || "").trim().toLowerCase();
18281
+ if (text === priv.search) return 0;
18282
+ priv.search = text;
18283
+ refresh_tree(gobj, { preserve_view: true });
18284
+ update_find_result(gobj);
18285
+ return 0;
18286
+ }
18144
18287
  function ac_refresh$3(gobj, event, kw, src) {
18145
18288
  save_view_state(gobj);
18146
18289
  refresh_tree(gobj);
@@ -18494,6 +18637,7 @@ function ac_language_changed$3(gobj, event, kw, src) {
18494
18637
  if ($container) refresh_language($container, t);
18495
18638
  hide_popover(gobj);
18496
18639
  refresh_tree(gobj);
18640
+ update_find_result(gobj);
18497
18641
  return 0;
18498
18642
  }
18499
18643
  /***************************
@@ -18514,6 +18658,7 @@ function create_gclass$9(gclass_name) {
18514
18658
  return -1;
18515
18659
  }
18516
18660
  __gclass__$9 = gclass_create(gclass_name, [
18661
+ ["EV_FIND_NODES", 0],
18517
18662
  ["EV_REFRESH", 0],
18518
18663
  ["EV_THEME", 0],
18519
18664
  ["EV_CHANGE_LAYOUT", 0],
@@ -18534,6 +18679,11 @@ function create_gclass$9(gclass_name) {
18534
18679
  ["EV_GCLASS_CLOSED", 0],
18535
18680
  ["EV_LANGUAGE_CHANGED", 0]
18536
18681
  ], [["ST_IDLE", [
18682
+ [
18683
+ "EV_FIND_NODES",
18684
+ ac_find_nodes$2,
18685
+ null
18686
+ ],
18537
18687
  [
18538
18688
  "EV_REFRESH",
18539
18689
  ac_refresh$3,
@@ -20002,11 +20152,7 @@ function build_body(shell, t) {
20002
20152
  let $count = createElement2([
20003
20153
  "span",
20004
20154
  { class: "ROUTEMAP_COUNT is-size-7 has-text-grey is-hidden" },
20005
- [$count_n, [
20006
- "span",
20007
- { i18n: "matches" },
20008
- "matches"
20009
- ]]
20155
+ [$count_n]
20010
20156
  ]);
20011
20157
  let $refs_input = createElement2(["input", {
20012
20158
  class: "ROUTEMAP_REFS_INPUT",
@@ -20044,7 +20190,7 @@ function build_body(shell, t) {
20044
20190
  if ($root_li) filter_li($root_li, q, false, __show_refs__);
20045
20191
  if (q === "") $count.classList.add("is-hidden");
20046
20192
  else {
20047
- $count_n.textContent = $tree.querySelectorAll(".ROUTEMAP_MATCH").length;
20193
+ $count_n.textContent = t("matches", { count: $tree.querySelectorAll(".ROUTEMAP_MATCH").length });
20048
20194
  $count.classList.remove("is-hidden");
20049
20195
  }
20050
20196
  };
@@ -57978,10 +58124,6 @@ function make_toolbar(gobj) {
57978
58124
  "span",
57979
58125
  { class: "GRAPH_FIND_COUNT" },
57980
58126
  ""
57981
- ], [
57982
- "span",
57983
- { i18n: "matches" },
57984
- "matches"
57985
58127
  ]]
57986
58128
  ]]
57987
58129
  ],
@@ -59037,7 +59179,7 @@ function ac_find_result(gobj, event, kw, src) {
59037
59179
  $count.textContent = "";
59038
59180
  return 0;
59039
59181
  }
59040
- $count.textContent = String(kw && kw.matches || 0);
59182
+ $count.textContent = t("matches", { count: kw && kw.matches || 0 });
59041
59183
  $result.classList.remove("is-hidden");
59042
59184
  return 0;
59043
59185
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.38",
3
+ "version": "7.23.40",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",