@yuneta/gobj-ui 7.23.157 → 7.23.159

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.
@@ -80,7 +80,7 @@ import {
80
80
  } from "@yuneta/gobj-js";
81
81
 
82
82
 
83
- import {attach_clear} from "./yui_inputs.js";
83
+ import {attach_clear, refresh_clear} from "./yui_inputs.js";
84
84
  import {register_c_g6_nodes_tree} from "./c_g6_nodes_tree.js";
85
85
  import {yui_toolbar, yui_toolbar_icon, YUI_TOOLBAR_ICON_SIZE} from "./yui_toolbar.js";
86
86
  import {
@@ -982,11 +982,13 @@ function make_toolbar(gobj)
982
982
  * Right: find a node.
983
983
  *
984
984
  * A graph of a few hundred records has no other way in: the only way
985
- * to locate one was to read every card. The box highlights every
986
- * match with the same amber the topic focus uses and centres the
987
- * viewport on them, and it SAYS how many it found — a graph that did
988
- * not move looks the same whether nothing matched or the match was
989
- * already on screen.
985
+ * to locate one was to read every card. The box lights every match
986
+ * ON SCREEN with the same amber the topic focus uses and changes
987
+ * nothing else (no unfold, no layout, no camera); Enter centres the
988
+ * next lit card, Shift+Enter the previous. It SAYS how many it found,
989
+ * and how many more are folded away or in hidden topics — a graph
990
+ * with no amber looks the same whether nothing matched or the matches
991
+ * are not on screen.
990
992
  */
991
993
  /* Materialised, not a spec: attach_clear() hangs the NORM clear (✕)
992
994
  * on a real element. Clearing dispatches a synthetic `input`, which
@@ -1000,8 +1002,12 @@ function make_toolbar(gobj)
1000
1002
  * cannot reach it: it needs its own key. */
1001
1003
  placeholder: t('search'),
1002
1004
  'data-i18n-placeholder': 'search',
1003
- 'aria-label': t('search'),
1004
- 'data-i18n-aria-label': 'search'
1005
+ /* The title is where Enter is told: nothing else on the
1006
+ * box says it can step through the matches. */
1007
+ title: t('find on screen'),
1008
+ 'data-i18n-title': 'find on screen',
1009
+ 'aria-label': t('find on screen'),
1010
+ 'data-i18n-aria-label': 'find on screen'
1005
1011
  }, [], {
1006
1012
  /* Rate-limited, not delayed for effect: a match repaints the
1007
1013
  * cards it lands on, and on a large treedb the first letter
@@ -1018,6 +1024,24 @@ function make_toolbar(gobj)
1018
1024
  priv.find_timer = null;
1019
1025
  gobj_send_event(gobj, "EV_FIND_NODES", {text: text}, gobj);
1020
1026
  }, 250);
1027
+ },
1028
+ /* Enter steps through the lit cards. A term still waiting
1029
+ * on the rate limit is sent first, or Enter would step
1030
+ * through the matches of the term before it. */
1031
+ keydown: (evt) => {
1032
+ if(evt.key !== 'Enter' || evt.isComposing) {
1033
+ return;
1034
+ }
1035
+ evt.preventDefault();
1036
+ evt.stopPropagation();
1037
+ if(priv.find_timer) {
1038
+ clearTimeout(priv.find_timer);
1039
+ priv.find_timer = null;
1040
+ gobj_send_event(
1041
+ gobj, "EV_FIND_NODES", {text: evt.target.value.trim()}, gobj
1042
+ );
1043
+ }
1044
+ gobj_send_event(gobj, "EV_FIND_NEXT", {back: evt.shiftKey}, gobj);
1021
1045
  }
1022
1046
  }]);
1023
1047
 
@@ -3188,6 +3212,23 @@ function ac_find_nodes(gobj, event, kw, src)
3188
3212
  return 0;
3189
3213
  }
3190
3214
 
3215
+ /************************************************************
3216
+ * Enter in the find box: forward the step down to the graph child.
3217
+ ************************************************************/
3218
+ function ac_find_next(gobj, event, kw, src)
3219
+ {
3220
+ let priv = gobj.priv;
3221
+ if(priv.gobj_nodes_tree) {
3222
+ gobj_send_event(
3223
+ priv.gobj_nodes_tree,
3224
+ "EV_FIND_NEXT",
3225
+ {back: !!(kw && kw.back)},
3226
+ gobj
3227
+ );
3228
+ }
3229
+ return 0;
3230
+ }
3231
+
3191
3232
  /************************************************************
3192
3233
  * One press of the fold stepper (EV_EXPAND_LEVEL /
3193
3234
  * EV_COLLAPSE_LEVEL): the level moves by one, is SAVED (the
@@ -3307,17 +3348,47 @@ function refresh_find_result(gobj)
3307
3348
  }
3308
3349
 
3309
3350
  let text = t("matches", {count: (kw && kw.matches) || 0});
3310
- /* Matches in HIDDEN topics, counted apart: "0" alone reads as
3311
- * "does not exist" when it means "is hidden". */
3351
+ /* Where Enter stands among the lit cards: "3/12 matches". */
3352
+ let current = (kw && kw.current) || 0;
3353
+ if(current > 0) {
3354
+ text = `${current}/${text}`;
3355
+ }
3356
+ /* Matches NOT lit, counted apart: "0" alone reads as "does not
3357
+ * exist" when it means "is folded away" or "is hidden". */
3358
+ let extra = [];
3359
+ let folded = (kw && kw.folded_matches) || 0;
3360
+ if(folded > 0) {
3361
+ extra.push(`+${folded} ${t("not shown")}`);
3362
+ }
3312
3363
  let hidden = (kw && kw.hidden_matches) || 0;
3313
3364
  if(hidden > 0) {
3314
- text += ` (+${hidden} ${t("hidden topics")})`;
3365
+ extra.push(`+${hidden} ${t("hidden topics")}`);
3366
+ }
3367
+ if(extra.length) {
3368
+ text += ` (${extra.join(", ")})`;
3315
3369
  }
3316
3370
  $count.textContent = text;
3317
3371
  $result.classList.remove("is-hidden");
3318
3372
  return 0;
3319
3373
  }
3320
3374
 
3375
+ function clear_find_box(gobj)
3376
+ {
3377
+ let priv = gobj.priv;
3378
+ if(priv.find_timer) {
3379
+ clearTimeout(priv.find_timer);
3380
+ priv.find_timer = null;
3381
+ }
3382
+ let $container = gobj_read_attr(gobj, "$container");
3383
+ let $input = $container? $container.querySelector(".GRAPH_FIND_INPUT") : null;
3384
+ if($input) {
3385
+ $input.value = "";
3386
+ refresh_clear($input);
3387
+ }
3388
+ priv._find_result = null;
3389
+ refresh_find_result(gobj);
3390
+ }
3391
+
3321
3392
  function ac_set_focus_topic(gobj, event, kw, src)
3322
3393
  {
3323
3394
  let priv = gobj.priv;
@@ -3334,6 +3405,13 @@ function ac_set_focus_topic(gobj, event, kw, src)
3334
3405
  }
3335
3406
  }
3336
3407
 
3408
+ /* A topic focus takes the highlight from the find (the engine
3409
+ * drops its term), so the box must not go on showing a term
3410
+ * nothing is lit for. */
3411
+ if(priv.focus_topic) {
3412
+ clear_find_box(gobj);
3413
+ }
3414
+
3337
3415
  if(priv.gobj_nodes_tree) {
3338
3416
  gobj_send_event(
3339
3417
  priv.gobj_nodes_tree,
@@ -3435,6 +3513,7 @@ function create_gclass(gclass_name)
3435
3513
  ["EV_SET_OPERATION_MODE", ac_set_operation_mode, null],
3436
3514
  ["EV_SET_FOCUS_TOPIC", ac_set_focus_topic, null],
3437
3515
  ["EV_FIND_NODES", ac_find_nodes, null],
3516
+ ["EV_FIND_NEXT", ac_find_next, null],
3438
3517
  ["EV_EXPAND_LEVEL", ac_fold_level_step, null],
3439
3518
  ["EV_COLLAPSE_LEVEL", ac_fold_level_step, null],
3440
3519
  ["EV_SET_NODE_MODE", ac_set_node_mode, null],
@@ -3482,6 +3561,7 @@ function create_gclass(gclass_name)
3482
3561
  ["EV_SET_OPERATION_MODE", 0],
3483
3562
  ["EV_SET_FOCUS_TOPIC", 0],
3484
3563
  ["EV_FIND_NODES", 0],
3564
+ ["EV_FIND_NEXT", 0],
3485
3565
  ["EV_EXPAND_LEVEL", 0],
3486
3566
  ["EV_COLLAPSE_LEVEL", 0],
3487
3567
  ["EV_SET_NODE_MODE", 0],
@@ -141,3 +141,70 @@
141
141
  font-style: italic;
142
142
  opacity: 0.6;
143
143
  }
144
+
145
+ /*
146
+ * A file cell that names an asset is a LINK: the click opens it
147
+ * (EV_SHOW_CELL_FILE). Same shape as the JSON cell beside it.
148
+ */
149
+ .FILE_CELL_LINK {
150
+ white-space: nowrap;
151
+ }
152
+ .FILE_CELL_LINK .FILE_CELL_ICON {
153
+ margin-right: 0.25rem;
154
+ vertical-align: middle;
155
+ }
156
+ .FILE_CELL_LINK .FILE_CELL_ID {
157
+ text-decoration: underline;
158
+ vertical-align: middle;
159
+ }
160
+ .FILE_CELL_LINK .FILE_CELL_MORE {
161
+ margin-left: 0.35rem;
162
+ font-family: inherit;
163
+ opacity: 0.7;
164
+ vertical-align: middle;
165
+ }
166
+
167
+ /*
168
+ * The file popup: one item per asset the cell names, each the thing
169
+ * itself and a caption (what it is, and a way to open it full size).
170
+ */
171
+ .TREEDB_CELL_FILE {
172
+ display: flex;
173
+ flex-direction: column;
174
+ gap: 1rem;
175
+ padding: 0.75rem;
176
+ height: 100%;
177
+ overflow: auto;
178
+ }
179
+ .TREEDB_CELL_FILE .CELL_FILE_ITEM {
180
+ display: flex;
181
+ flex-direction: column;
182
+ align-items: center;
183
+ gap: 0.35rem;
184
+ min-width: 0;
185
+ }
186
+ .TREEDB_CELL_FILE img.CELL_FILE_MEDIA,
187
+ .TREEDB_CELL_FILE video.CELL_FILE_MEDIA {
188
+ display: block;
189
+ max-width: 100%;
190
+ max-height: 70vh;
191
+ object-fit: contain;
192
+ }
193
+ .TREEDB_CELL_FILE audio.CELL_FILE_MEDIA {
194
+ width: 100%;
195
+ }
196
+ .TREEDB_CELL_FILE iframe.CELL_FILE_MEDIA {
197
+ min-height: 60vh;
198
+ }
199
+ .TREEDB_CELL_FILE .CELL_FILE_CAPTION {
200
+ display: flex;
201
+ flex-wrap: wrap;
202
+ justify-content: center;
203
+ gap: 0.75rem;
204
+ font-size: 0.8rem;
205
+ opacity: 0.85;
206
+ }
207
+ .TREEDB_CELL_FILE .CELL_FILE_ID {
208
+ font-family: monospace;
209
+ overflow-wrap: anywhere;
210
+ }