@yuneta/gobj-ui 7.26.27 → 7.26.29
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 +590 -25
- package/dist/gobj-ui.cjs.js +1080 -229
- package/dist/gobj-ui.es.js +1081 -230
- package/package.json +4 -2
- package/scripts/validate-locales.mjs +2656 -315
- package/src/c_g6_nodes_tree.js +1086 -253
- package/src/c_yui_form.js +16 -4
- package/src/c_yui_fsm_graph.js +5 -0
- package/src/c_yui_gclass.js +11 -0
- package/src/c_yui_gobj_tree_js.js +18 -1
- package/src/c_yui_json_graph.js +5 -0
- package/src/c_yui_nav.js +21 -16
- package/src/c_yui_pager.js +1 -1
- package/src/c_yui_period.js +10 -3
- package/src/c_yui_schema_editor.js +34 -18
- package/src/c_yui_shell.js +11 -10
- package/src/c_yui_treedb_graph.js +17 -9
- package/src/c_yui_treedb_schema.js +5 -0
- package/src/c_yui_treedb_topic_with_form.js +9 -9
- package/src/c_yui_treedb_topics.js +13 -13
- package/src/c_yui_window.js +2 -2
- package/src/c_yui_window_manager.js +5 -2
- package/src/c_yui_wizard.js +8 -1
- package/src/form_json_field.js +7 -0
- package/src/g6_canvas_tab_order.js +84 -0
- package/src/g6_canvas_tab_order.wiring.test.js +232 -0
- package/src/g6_nodes_tree_controls.test.js +547 -0
- package/src/g6_nodes_tree_focus.wiring.test.js +1360 -0
- package/src/g6_nodes_tree_i18n_keys.test.js +241 -5
- package/src/i18n_key_functions.js +235 -0
- package/src/i18n_key_functions.test.js +1525 -0
- package/src/lib_graph.js +38 -1
- package/src/nav_backbar_name.wiring.test.js +82 -0
- package/src/schema_flags.js +47 -0
- package/src/schema_import.js +7 -0
- package/src/shell_modals.js +20 -16
- package/src/shell_route_map.js +13 -3
- package/src/wizard_helpers.js +8 -0
- package/src/yui_dev.js +16 -3
- package/src/yui_dev_controls.test.js +174 -0
- package/src/yui_gclass_view.js +1 -1
- package/src/yui_graph_camera.js +1 -1
- package/src/yui_install.js +10 -8
- package/src/yui_table_select.js +2 -2
- package/src/yui_time.js +17 -2
package/src/c_yui_form.js
CHANGED
|
@@ -805,11 +805,13 @@ function build_html_form(gobj, $form, prefix, template)
|
|
|
805
805
|
}
|
|
806
806
|
|
|
807
807
|
/*
|
|
808
|
-
* Build the html field and add to form, if <tag> is not-null
|
|
808
|
+
* Build the html field and add to form, if <tag> is not-null.
|
|
809
|
+
* Its label and options are the schema's: column names and
|
|
810
|
+
* headers, data.
|
|
809
811
|
*/
|
|
810
812
|
if(html_field_conf.tag) {
|
|
811
|
-
let $field = create_form_field(gobj, $form, prefix, field_desc, html_field_conf);
|
|
812
|
-
name_form_control($field, html_field_conf);
|
|
813
|
+
let $field = create_form_field(gobj, $form, prefix, field_desc, /* i18n: data */ html_field_conf);
|
|
814
|
+
name_form_control($field, /* i18n: data */ html_field_conf);
|
|
813
815
|
$form.appendChild($field);
|
|
814
816
|
}
|
|
815
817
|
});
|
|
@@ -2547,11 +2549,21 @@ function field_validation_message($input)
|
|
|
2547
2549
|
{
|
|
2548
2550
|
let key = field_validation_key($input);
|
|
2549
2551
|
if(key) {
|
|
2550
|
-
return t(key);
|
|
2552
|
+
return t(/* i18n: C_YUI_FORM_I18N_KEYS, FORM_JSON_FIELD_I18N_KEYS */ key);
|
|
2551
2553
|
}
|
|
2552
2554
|
return $input.validationMessage;
|
|
2553
2555
|
}
|
|
2554
2556
|
|
|
2557
|
+
/* The keys this form hands on as data: the one field_validation_key()
|
|
2558
|
+
* returns, which reaches t() by a variable, and the warning of a close
|
|
2559
|
+
* it vetoes (`kw.warning`), which its HOST shows. Published for a
|
|
2560
|
+
* consumer's validate-locales, which asks the app's locales for every
|
|
2561
|
+
* key of an exported `*_I18N_KEYS` array; i18n_key_functions.test.js
|
|
2562
|
+
* holds it to what field_validation_key() returns and to every
|
|
2563
|
+
* `.warning =` of this module. (The json editor's own key is published
|
|
2564
|
+
* by form_json_field.js.) */
|
|
2565
|
+
export const C_YUI_FORM_I18N_KEYS = ["this field is required", "all changes will be lost"];
|
|
2566
|
+
|
|
2555
2567
|
/************************************************************
|
|
2556
2568
|
* The i18n key of the message, when the message is ours ("" when
|
|
2557
2569
|
* it is the browser's): written as the help line's data-i18n, so
|
package/src/c_yui_fsm_graph.js
CHANGED
|
@@ -71,6 +71,7 @@ import {
|
|
|
71
71
|
import {yui_is_dark, yui_theme_now, yui_watch_theme} from "./yui_theme.js";
|
|
72
72
|
import {ensure_drag_canvas_patch} from "./g6_drag_canvas_touch.js";
|
|
73
73
|
import {ensure_pinch_zoom_patch} from "./g6_touch_gestures.js";
|
|
74
|
+
import {keep_canvas_tab_order} from "./g6_canvas_tab_order.js";
|
|
74
75
|
|
|
75
76
|
import {t} from "i18next";
|
|
76
77
|
|
|
@@ -428,6 +429,10 @@ function build_graph(gobj)
|
|
|
428
429
|
}
|
|
429
430
|
}
|
|
430
431
|
|
|
432
|
+
/* Tab goes from the graph to its own buttons: the main canvas in
|
|
433
|
+
* the Tab order, the other layers out (g6_canvas_tab_order.js). */
|
|
434
|
+
keep_canvas_tab_order(gobj, priv.graph);
|
|
435
|
+
|
|
431
436
|
priv.graph.on('aftertransform', () => {
|
|
432
437
|
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
433
438
|
});
|
package/src/c_yui_gclass.js
CHANGED
|
@@ -136,6 +136,17 @@ const ZONES = [
|
|
|
136
136
|
{id: "machine", key: "machine", col: "right"},
|
|
137
137
|
];
|
|
138
138
|
|
|
139
|
+
/* The keys of VIEWS, MACHINE_VIEWS and ZONES: they reach t() as data
|
|
140
|
+
* (`v.key`, `zone.key`), where no scan of the source reads them, so
|
|
141
|
+
* they are published here for a consumer's validate-locales, which asks
|
|
142
|
+
* the app's locales for every key of an exported `*_I18N_KEYS` array. A
|
|
143
|
+
* view or a zone added to those tables adds its key here. */
|
|
144
|
+
export const C_YUI_GCLASS_I18N_KEYS = [
|
|
145
|
+
"zones view", "raw view",
|
|
146
|
+
"matrix view", "graph view",
|
|
147
|
+
"attributes", "commands", "methods", "trace levels", "machine"
|
|
148
|
+
];
|
|
149
|
+
|
|
139
150
|
/***************************************************************
|
|
140
151
|
* Data
|
|
141
152
|
***************************************************************/
|
|
@@ -82,6 +82,7 @@ import { ensure_drag_canvas_patch } from "./g6_drag_canvas_touch.js";
|
|
|
82
82
|
import { ensure_pinch_zoom_patch } from "./g6_touch_gestures.js";
|
|
83
83
|
import { yui_is_dark, yui_theme_now, yui_watch_theme } from "./yui_theme.js";
|
|
84
84
|
import {g6_event_kw} from "./g6_event_kw.js";
|
|
85
|
+
import {keep_canvas_tab_order} from "./g6_canvas_tab_order.js";
|
|
85
86
|
|
|
86
87
|
/***************************************************************
|
|
87
88
|
* Constants
|
|
@@ -523,6 +524,18 @@ const LAYOUTS = {
|
|
|
523
524
|
},
|
|
524
525
|
};
|
|
525
526
|
|
|
527
|
+
/* The `key` of every layout: the picker hands it to t() as data
|
|
528
|
+
* (`LAYOUTS[key].key`), where no scan of the source reads it, so it is
|
|
529
|
+
* published here for a consumer's validate-locales, which asks the
|
|
530
|
+
* app's locales for every key of an exported `*_I18N_KEYS` array. A
|
|
531
|
+
* layout added to LAYOUTS adds its key here. */
|
|
532
|
+
export const C_YUI_GOBJ_TREE_JS_I18N_KEYS = [
|
|
533
|
+
"vertical tree", "vertical tree compact",
|
|
534
|
+
"horizontal tree", "horizontal tree compact",
|
|
535
|
+
"lanes vertical", "lanes horizontal",
|
|
536
|
+
"dagre top-down", "dagre left-right"
|
|
537
|
+
];
|
|
538
|
+
|
|
526
539
|
function get_layout_cfg(layout_key)
|
|
527
540
|
{
|
|
528
541
|
return LAYOUTS[layout_key] || LAYOUTS["vertical-compact"];
|
|
@@ -1150,6 +1163,10 @@ function build_graph(gobj)
|
|
|
1150
1163
|
graph.setTheme(priv.theme);
|
|
1151
1164
|
}
|
|
1152
1165
|
|
|
1166
|
+
/* Tab goes from the graph to its own buttons: the main canvas in
|
|
1167
|
+
* the Tab order, the other layers out (g6_canvas_tab_order.js). */
|
|
1168
|
+
keep_canvas_tab_order(gobj, graph);
|
|
1169
|
+
|
|
1153
1170
|
/* The readout follows ANY camera change, the wheel included — a
|
|
1154
1171
|
* wheel notch passes through no action of ours. */
|
|
1155
1172
|
graph.on('aftertransform', () => {
|
|
@@ -2845,7 +2862,7 @@ function ac_open_gclass(gobj, event, kw, src)
|
|
|
2845
2862
|
close_gclass_view(priv.gclass_view);
|
|
2846
2863
|
priv.gclass_view = null;
|
|
2847
2864
|
|
|
2848
|
-
priv.gclass_view = open_gclass_view(gobj, node_data.gclass, {
|
|
2865
|
+
priv.gclass_view = open_gclass_view(gobj, /* i18n: data */ node_data.gclass, {
|
|
2849
2866
|
title_prefix: gobj_yuno_name() || "",
|
|
2850
2867
|
/* Which state THIS gobj is in. The description describes the
|
|
2851
2868
|
* CLASS and cannot carry it, and the tree is the only party
|
package/src/c_yui_json_graph.js
CHANGED
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
count_branches,
|
|
84
84
|
} from "./json_view_helpers.js";
|
|
85
85
|
import {g6_event_kw} from "./g6_event_kw.js";
|
|
86
|
+
import {keep_canvas_tab_order} from "./g6_canvas_tab_order.js";
|
|
86
87
|
|
|
87
88
|
/***************************************************************
|
|
88
89
|
* Constants
|
|
@@ -754,6 +755,10 @@ function build_graph(gobj)
|
|
|
754
755
|
graph.setTheme(priv.theme);
|
|
755
756
|
}
|
|
756
757
|
|
|
758
|
+
/* Tab goes from the graph to its own buttons: the main canvas in
|
|
759
|
+
* the Tab order, the other layers out (g6_canvas_tab_order.js). */
|
|
760
|
+
keep_canvas_tab_order(gobj, graph);
|
|
761
|
+
|
|
757
762
|
graph.on(NodeEvent.CLICK, (evt) => {
|
|
758
763
|
/* An identity, never the G6 event: a kw is plain json, and the
|
|
759
764
|
* event is circular -- the machine trace dumps the kw. */
|
package/src/c_yui_nav.js
CHANGED
|
@@ -230,17 +230,19 @@ function build_ui(gobj)
|
|
|
230
230
|
let menu_id = gobj_read_attr(gobj, "menu_id") || "nav";
|
|
231
231
|
let $container;
|
|
232
232
|
|
|
233
|
+
/* The items are the app's nav declaration: the keys of their names
|
|
234
|
+
* are read there (app_config.json), not here. */
|
|
233
235
|
switch(layout) {
|
|
234
|
-
case "vertical": $container = render_vertical(gobj, items); break;
|
|
235
|
-
case "icon-bar": $container = render_icon_bar(gobj, items); break;
|
|
236
|
-
case "tabs": $container = render_tabs(gobj, items); break;
|
|
237
|
-
case "drawer": $container = render_drawer(gobj, items); break;
|
|
238
|
-
case "submenu": $container = render_submenu(gobj, items); break;
|
|
239
|
-
case "accordion": $container = render_accordion(gobj, items); break;
|
|
240
|
-
case "cards": $container = render_cards(gobj, items); break;
|
|
241
|
-
case "backbar": $container = render_backbar(gobj);
|
|
242
|
-
case "breadcrumb": $container = render_breadcrumb(gobj, items); break;
|
|
243
|
-
default: $container = render_vertical(gobj, items);
|
|
236
|
+
case "vertical": $container = render_vertical(gobj, /* i18n: data */ items); break;
|
|
237
|
+
case "icon-bar": $container = render_icon_bar(gobj, /* i18n: data */ items); break;
|
|
238
|
+
case "tabs": $container = render_tabs(gobj, /* i18n: data */ items); break;
|
|
239
|
+
case "drawer": $container = render_drawer(gobj, /* i18n: data */ items); break;
|
|
240
|
+
case "submenu": $container = render_submenu(gobj, /* i18n: data */ items); break;
|
|
241
|
+
case "accordion": $container = render_accordion(gobj, /* i18n: data */ items); break;
|
|
242
|
+
case "cards": $container = render_cards(gobj, /* i18n: data */ items); break;
|
|
243
|
+
case "backbar": $container = render_backbar(gobj); break;
|
|
244
|
+
case "breadcrumb": $container = render_breadcrumb(gobj, /* i18n: data */ items); break;
|
|
245
|
+
default: $container = render_vertical(gobj, /* i18n: data */ items);
|
|
244
246
|
}
|
|
245
247
|
$container.setAttribute("data-nav-zone", zone);
|
|
246
248
|
$container.setAttribute("data-nav-layout", layout);
|
|
@@ -268,7 +270,7 @@ function build_ui(gobj)
|
|
|
268
270
|
if(!$container.hasAttribute("aria-label")) {
|
|
269
271
|
/* A key, translated by the shell's translator: the bare
|
|
270
272
|
* menu_id read out "secondary.main.system". */
|
|
271
|
-
|
|
273
|
+
const label = gobj_read_attr(gobj, "nav_label") || "navigation";
|
|
272
274
|
$container.setAttribute("aria-label", t(label));
|
|
273
275
|
$container.setAttribute("data-i18n-aria-label", label);
|
|
274
276
|
}
|
|
@@ -527,16 +529,19 @@ function render_backbar(gobj)
|
|
|
527
529
|
if(label) {
|
|
528
530
|
label_attrs.i18n = label;
|
|
529
531
|
}
|
|
532
|
+
/* Named by the label when the nav has one, else by "back" -- through
|
|
533
|
+
* t() and with its key, or it reads the raw key in every language. */
|
|
534
|
+
const name_key = label || "back";
|
|
530
535
|
let a_attrs = {
|
|
531
536
|
class: "yui-nav-item yui-nav-back",
|
|
532
537
|
href: back_route ? "#" + back_route : "#",
|
|
533
538
|
"data-item-id": "__index__",
|
|
534
539
|
"data-route": back_route,
|
|
535
|
-
|
|
540
|
+
title: t(name_key),
|
|
541
|
+
"data-i18n-title": name_key,
|
|
542
|
+
"aria-label": t(name_key),
|
|
543
|
+
"data-i18n-aria-label": name_key
|
|
536
544
|
};
|
|
537
|
-
if(label) {
|
|
538
|
-
a_attrs["data-i18n-aria-label"] = label;
|
|
539
|
-
}
|
|
540
545
|
return createElement2(
|
|
541
546
|
["div", {},
|
|
542
547
|
["a", a_attrs, [
|
|
@@ -558,7 +563,7 @@ function render_drawer(gobj, items)
|
|
|
558
563
|
wrap.className = "yui-drawer";
|
|
559
564
|
wrap.setAttribute("role", "dialog");
|
|
560
565
|
wrap.setAttribute("aria-modal", "true");
|
|
561
|
-
|
|
566
|
+
const nav_label = gobj_read_attr(gobj, "nav_label") || "navigation";
|
|
562
567
|
wrap.setAttribute("aria-label", t(nav_label));
|
|
563
568
|
wrap.setAttribute("data-i18n-aria-label", nav_label);
|
|
564
569
|
|
package/src/c_yui_pager.js
CHANGED
|
@@ -237,7 +237,7 @@ function render_header(gobj)
|
|
|
237
237
|
* deeper pages show a back arrow.
|
|
238
238
|
*/
|
|
239
239
|
let $back_icon = $back.querySelector('i');
|
|
240
|
-
|
|
240
|
+
const back_key = (model.back_kind === "close") ? 'close' : 'back';
|
|
241
241
|
$back_icon.className = (back_key === 'close') ? 'yi-xmark' : 'yi-arrow-left';
|
|
242
242
|
/* The key moves with the glyph: a key left on "back" made the ✕ of
|
|
243
243
|
* the root page announce itself as Back after a language switch. */
|
package/src/c_yui_period.js
CHANGED
|
@@ -112,6 +112,13 @@ const GCLASS_NAME = "C_YUI_PERIOD";
|
|
|
112
112
|
const MODE_SPAN = "span";
|
|
113
113
|
const MODE_CUSTOM = "custom";
|
|
114
114
|
|
|
115
|
+
/* Their names: a mode is named by its id through a variable
|
|
116
|
+
* (`t(mode.id)`), where no scan of the source reads it, so they are
|
|
117
|
+
* published for a consumer's validate-locales, which asks the app's
|
|
118
|
+
* locales for every key of an exported `*_I18N_KEYS` array. The names
|
|
119
|
+
* of the granularities and of the rolling windows are yui_time.js's. */
|
|
120
|
+
export const C_YUI_PERIOD_I18N_KEYS = ["span", "custom"];
|
|
121
|
+
|
|
115
122
|
/***************************************************************
|
|
116
123
|
* Data
|
|
117
124
|
***************************************************************/
|
|
@@ -475,7 +482,7 @@ function build_ui(gobj)
|
|
|
475
482
|
if(mode.overflow || mode.hidden) {
|
|
476
483
|
continue;
|
|
477
484
|
}
|
|
478
|
-
priv.$modes.appendChild(build_mode_button(gobj, mode));
|
|
485
|
+
priv.$modes.appendChild(build_mode_button(gobj, /* i18n: C_YUI_PERIOD_I18N_KEYS, YUI_TIME_I18N_KEYS */ mode));
|
|
479
486
|
}
|
|
480
487
|
|
|
481
488
|
/* Scroll plumbing, not an action: it changes nothing outside the strip.
|
|
@@ -591,7 +598,7 @@ function build_more_menu(gobj)
|
|
|
591
598
|
if(!mode.overflow) {
|
|
592
599
|
continue;
|
|
593
600
|
}
|
|
594
|
-
let name = mode_name(mode);
|
|
601
|
+
let name = mode_name(/* i18n: C_YUI_PERIOD_I18N_KEYS, YUI_TIME_I18N_KEYS */ mode);
|
|
595
602
|
let $item = createElement2(
|
|
596
603
|
["a", {class: `dropdown-item YUI_PERIOD_MODE ` +
|
|
597
604
|
`YUI_PERIOD_MODE_${mode.id.toUpperCase()}`, href: "#",
|
|
@@ -1364,7 +1371,7 @@ function ac_language_changed(gobj, event, kw, src)
|
|
|
1364
1371
|
if(!mode.$btn) {
|
|
1365
1372
|
continue;
|
|
1366
1373
|
}
|
|
1367
|
-
let name = mode_name(mode);
|
|
1374
|
+
let name = mode_name(/* i18n: C_YUI_PERIOD_I18N_KEYS, YUI_TIME_I18N_KEYS */ mode);
|
|
1368
1375
|
let $text = mode.$btn.querySelector(".YUI_PERIOD_MODE_TEXT");
|
|
1369
1376
|
if($text) {
|
|
1370
1377
|
$text.textContent = name;
|
|
@@ -168,6 +168,16 @@ import {text_node} from "./yui_text.js";
|
|
|
168
168
|
***************************************************************/
|
|
169
169
|
const GCLASS_NAME = "C_YUI_SCHEMA_EDITOR";
|
|
170
170
|
|
|
171
|
+
/* The keys this editor hands to t() as DATA, where no scan of the
|
|
172
|
+
* source reads them: the severity of a finding, which the checks of
|
|
173
|
+
* schema_validate.js write (`add("error", ...)`) and the report
|
|
174
|
+
* translates. Published for a consumer's validate-locales, which asks
|
|
175
|
+
* the app's locales for every key of an exported `*_I18N_KEYS` array;
|
|
176
|
+
* i18n_key_functions.test.js holds it to the severities those checks
|
|
177
|
+
* write. The flags' words are schema_flags.js's, the plan's ops
|
|
178
|
+
* schema_import.js's. */
|
|
179
|
+
export const C_YUI_SCHEMA_EDITOR_I18N_KEYS = ["error", "warning"];
|
|
180
|
+
|
|
171
181
|
/* The three topics a schema is stored in. Named once: everything
|
|
172
182
|
* below addresses them by these constants and nothing composes the
|
|
173
183
|
* strings again. */
|
|
@@ -1248,7 +1258,7 @@ function render(gobj)
|
|
|
1248
1258
|
}
|
|
1249
1259
|
if(state === "ST_IDLE") {
|
|
1250
1260
|
show_notice(gobj, priv.load_error ? "cannot load the schemas" : "not connected",
|
|
1251
|
-
priv.load_error, true);
|
|
1261
|
+
/* i18n: data */ priv.load_error, true);
|
|
1252
1262
|
destroy_diagram(gobj);
|
|
1253
1263
|
clear($body);
|
|
1254
1264
|
return;
|
|
@@ -1352,16 +1362,16 @@ function render_treedbs(gobj, $body)
|
|
|
1352
1362
|
let $cards = [];
|
|
1353
1363
|
|
|
1354
1364
|
for(let treedb of priv.model.treedbs) {
|
|
1355
|
-
|
|
1365
|
+
const from_c = treedb.c_schema_version !== undefined &&
|
|
1366
|
+
String(treedb.c_schema_version) !== String(treedb.schema_version);
|
|
1367
|
+
const tags = [
|
|
1356
1368
|
{i18n: "topics", text: treedb.topics.length},
|
|
1357
1369
|
{i18n: "version", text: treedb.schema_version === undefined
|
|
1358
|
-
? "?" : treedb.schema_version}
|
|
1370
|
+
? "?" : treedb.schema_version},
|
|
1371
|
+
...(from_c
|
|
1372
|
+
? [{i18n: "from c", text: treedb.c_schema_version, style: "is-warning is-light"}]
|
|
1373
|
+
: [])
|
|
1359
1374
|
];
|
|
1360
|
-
if(treedb.c_schema_version !== undefined &&
|
|
1361
|
-
String(treedb.c_schema_version) !== String(treedb.schema_version)
|
|
1362
|
-
) {
|
|
1363
|
-
tags.push({i18n: "from c", text: treedb.c_schema_version, style: "is-warning is-light"});
|
|
1364
|
-
}
|
|
1365
1375
|
$cards.push(open_card(gobj, "SCHEMA_TREEDB_CARD", treedb.id, "yi-database",
|
|
1366
1376
|
tags, "EV_SELECT_TREEDB", {treedb: treedb.id}));
|
|
1367
1377
|
}
|
|
@@ -1396,7 +1406,7 @@ function render_topics(gobj, $body)
|
|
|
1396
1406
|
let treedb = current_treedb(gobj);
|
|
1397
1407
|
|
|
1398
1408
|
if(!treedb) {
|
|
1399
|
-
show_notice(gobj, "that treedb is not here any more", priv.treedb_id);
|
|
1409
|
+
show_notice(gobj, "that treedb is not here any more", /* i18n: data */ priv.treedb_id);
|
|
1400
1410
|
return;
|
|
1401
1411
|
}
|
|
1402
1412
|
|
|
@@ -1544,7 +1554,7 @@ function render_columns(gobj, $body)
|
|
|
1544
1554
|
let topic = current_topic(gobj);
|
|
1545
1555
|
|
|
1546
1556
|
if(!topic) {
|
|
1547
|
-
show_notice(gobj, "that topic is not here any more", priv.topic_name);
|
|
1557
|
+
show_notice(gobj, "that topic is not here any more", /* i18n: data */ priv.topic_name);
|
|
1548
1558
|
return;
|
|
1549
1559
|
}
|
|
1550
1560
|
|
|
@@ -1805,7 +1815,7 @@ function render_diagram(gobj)
|
|
|
1805
1815
|
if(!treedb) {
|
|
1806
1816
|
destroy_diagram(gobj);
|
|
1807
1817
|
clear($body);
|
|
1808
|
-
show_notice(gobj, "that treedb is not here any more", priv.treedb_id);
|
|
1818
|
+
show_notice(gobj, "that treedb is not here any more", /* i18n: data */ priv.treedb_id);
|
|
1809
1819
|
return;
|
|
1810
1820
|
}
|
|
1811
1821
|
if(!gclass_find_by_name("C_YUI_TREEDB_SCHEMA")) {
|
|
@@ -2425,7 +2435,8 @@ function open_report(gobj, findings, treedb_id)
|
|
|
2425
2435
|
return ["tr", {class: `SCHEMA_REPORT_ROW SCHEMA_REPORT_${finding.severity.toUpperCase()}`}, [
|
|
2426
2436
|
["td", {class: "SCHEMA_REPORT_SEVERITY"}, [
|
|
2427
2437
|
["span", {class: `tag ${finding.severity === "error" ? "is-danger" : "is-warning"}` +
|
|
2428
|
-
" is-light", i18n: finding.severity},
|
|
2438
|
+
" is-light", i18n: finding.severity},
|
|
2439
|
+
t(finding.severity)]
|
|
2429
2440
|
]],
|
|
2430
2441
|
["td", {class: "SCHEMA_REPORT_WHAT", i18n: finding.code}, t(finding.code)],
|
|
2431
2442
|
["td", {class: "SCHEMA_REPORT_TOPIC"}, text_node(finding.topic || "")],
|
|
@@ -3527,7 +3538,7 @@ function ac_mt_command_answer(gobj, event, kw, src)
|
|
|
3527
3538
|
return late_write_done(gobj, command, topic_name, data);
|
|
3528
3539
|
}
|
|
3529
3540
|
if(result < 0) {
|
|
3530
|
-
return end_writes(gobj, comment ||
|
|
3541
|
+
return end_writes(gobj, /* i18n: data */ comment || "the treedb refused the write");
|
|
3531
3542
|
}
|
|
3532
3543
|
priv.save_wrote = true;
|
|
3533
3544
|
let record = null;
|
|
@@ -4229,7 +4240,8 @@ function confirm_column_delete(gobj, verdict)
|
|
|
4229
4240
|
capped: "the records read hold no value in this column, but not all were read: the rest may hold values that no reader will show any more",
|
|
4230
4241
|
unknown: "the records of this topic could not be read: if they hold values in this column, they keep them, but no reader shows them any more"
|
|
4231
4242
|
};
|
|
4232
|
-
|
|
4243
|
+
const message = "delete this column?";
|
|
4244
|
+
let $warning = null;
|
|
4233
4245
|
if(NOTES[verdict]) {
|
|
4234
4246
|
let children = [
|
|
4235
4247
|
["p", {class: "CONFIRM_MSG yui-confirm-msg", i18n: message}, t(message)],
|
|
@@ -4242,9 +4254,9 @@ function confirm_column_delete(gobj, verdict)
|
|
|
4242
4254
|
["span", {class: "ml-1"}, String(c.scanned)]
|
|
4243
4255
|
]]);
|
|
4244
4256
|
}
|
|
4245
|
-
|
|
4257
|
+
$warning = createElement2(["div", {class: "SCHEMA_COLUMN_DATA_WARNING"}, children]);
|
|
4246
4258
|
}
|
|
4247
|
-
confirm_then(gobj, message, `${c.topic}.${c.col}`,
|
|
4259
|
+
confirm_then(gobj, $warning? $warning : message, `${c.topic}.${c.col}`,
|
|
4248
4260
|
{what: "column", topic: c.topic, col: c.col});
|
|
4249
4261
|
return 0;
|
|
4250
4262
|
}
|
|
@@ -4482,7 +4494,9 @@ function ac_validate(gobj, event, kw, src)
|
|
|
4482
4494
|
written_topics: Object.keys(priv.written),
|
|
4483
4495
|
baseline: priv.baseline
|
|
4484
4496
|
});
|
|
4485
|
-
|
|
4497
|
+
/* The severities are C_YUI_SCHEMA_EDITOR_I18N_KEYS; the codes are the
|
|
4498
|
+
* checks' own keys, read where schema_validate.js writes them. */
|
|
4499
|
+
open_report(gobj, /* i18n: C_YUI_SCHEMA_EDITOR_I18N_KEYS */ findings, treedb.id);
|
|
4486
4500
|
if(has_errors(findings)) {
|
|
4487
4501
|
log_warning(`${gobj_short_name(gobj)}: ${treedb.id} would be refused as it is`);
|
|
4488
4502
|
}
|
|
@@ -4566,7 +4580,9 @@ function ac_preview_import(gobj, event, kw, src)
|
|
|
4566
4580
|
|
|
4567
4581
|
let plan = plan_import(treedb, incoming, {prune: !!kw.prune});
|
|
4568
4582
|
priv.import_plan = plan;
|
|
4569
|
-
|
|
4583
|
+
/* Its writes are SCHEMA_IMPORT_I18N_KEYS; its conflicts are keys of
|
|
4584
|
+
* their own, read where schema_import.js writes them. */
|
|
4585
|
+
render_import_plan(gobj, /* i18n: SCHEMA_IMPORT_I18N_KEYS */ plan);
|
|
4570
4586
|
return 0;
|
|
4571
4587
|
}
|
|
4572
4588
|
|
package/src/c_yui_shell.js
CHANGED
|
@@ -281,7 +281,8 @@ function mt_start(gobj)
|
|
|
281
281
|
|
|
282
282
|
build_item_index(gobj, config);
|
|
283
283
|
instantiate_menus(gobj, config);
|
|
284
|
-
|
|
284
|
+
/* The app's shell declaration: its toolbar's keys are read there */
|
|
285
|
+
build_toolbar(gobj, /* i18n: data */ config);
|
|
285
286
|
|
|
286
287
|
/* lifecycle: "eager" — preinstantiate views that must exist from boot. */
|
|
287
288
|
preinstantiate_eager_views(gobj);
|
|
@@ -1781,7 +1782,7 @@ function safe_id(s)
|
|
|
1781
1782
|
************************************************************/
|
|
1782
1783
|
function build_toolbar(gobj, config)
|
|
1783
1784
|
{
|
|
1784
|
-
|
|
1785
|
+
const tb = config && config.toolbar;
|
|
1785
1786
|
if(!tb || !is_array(tb.items)) {
|
|
1786
1787
|
return;
|
|
1787
1788
|
}
|
|
@@ -1807,7 +1808,7 @@ function build_toolbar(gobj, config)
|
|
|
1807
1808
|
* which createElement2 maps to `data-i18n` on the rendered
|
|
1808
1809
|
* element. Apps swap languages by calling
|
|
1809
1810
|
* refresh_language(shell.$container, t) — no DOM rebuild here. */
|
|
1810
|
-
|
|
1811
|
+
const toolbar_aria = tb.aria_label || "toolbar";
|
|
1811
1812
|
let $bar = createElement2(
|
|
1812
1813
|
["nav", {class: "yui-toolbar navbar",
|
|
1813
1814
|
role: "navigation",
|
|
@@ -2060,8 +2061,8 @@ function build_toolbar_brand_item(gobj, it)
|
|
|
2060
2061
|
function build_toolbar_avatar_item(gobj, it)
|
|
2061
2062
|
{
|
|
2062
2063
|
let priv = gobj.priv;
|
|
2063
|
-
|
|
2064
|
-
|
|
2064
|
+
const aria_key = it.aria_label || it.name || it.id || "user menu";
|
|
2065
|
+
const i18n_aria = it.aria_label || it.name || "user menu";
|
|
2065
2066
|
let action_type = (it.action && it.action.type) || "";
|
|
2066
2067
|
let attrs = {
|
|
2067
2068
|
class: "navbar-item yui-toolbar-item yui-toolbar-avatar is-unselectable",
|
|
@@ -2151,8 +2152,8 @@ function attach_context_action(gobj, $item, it)
|
|
|
2151
2152
|
function build_toolbar_connection_item(gobj, it)
|
|
2152
2153
|
{
|
|
2153
2154
|
let priv = gobj.priv;
|
|
2154
|
-
|
|
2155
|
-
|
|
2155
|
+
const aria_key = it.aria_label || it.name || it.id || "backend connection";
|
|
2156
|
+
const i18n_aria = it.aria_label || it.name || "backend connection";
|
|
2156
2157
|
let attrs = {
|
|
2157
2158
|
class: "navbar-item yui-toolbar-item yui-toolbar-conn " +
|
|
2158
2159
|
"is-unselectable is-disconnected",
|
|
@@ -2328,8 +2329,8 @@ function open_toolbar_dropdown(gobj, item, action, $trigger)
|
|
|
2328
2329
|
* (yui_shell_set_translator), re-apply it to the freshly built
|
|
2329
2330
|
* $panel. Rebuilt per open ⇒ a later language switch is picked
|
|
2330
2331
|
* up the next time the dropdown opens. */
|
|
2331
|
-
|
|
2332
|
-
|
|
2332
|
+
const aria_key = item && (item.aria_label || item.name || item.id) || "menu";
|
|
2333
|
+
const i18n_aria = (item && (item.aria_label || item.name)) || "menu";
|
|
2333
2334
|
let $panel = createElement2(["div", {
|
|
2334
2335
|
class: "yui-toolbar-dropdown-panel",
|
|
2335
2336
|
role: "menu",
|
|
@@ -2341,7 +2342,7 @@ function open_toolbar_dropdown(gobj, item, action, $trigger)
|
|
|
2341
2342
|
let raw_items = is_array(action.items) ? action.items : [];
|
|
2342
2343
|
for(let i = 0; i < raw_items.length; i++) {
|
|
2343
2344
|
let sub = raw_items[i];
|
|
2344
|
-
let $row = build_dropdown_row(gobj, sub, i);
|
|
2345
|
+
let $row = build_dropdown_row(gobj, /* i18n: data */ sub, i); // the app's shell declaration
|
|
2345
2346
|
if(!$row) {
|
|
2346
2347
|
continue;
|
|
2347
2348
|
}
|
|
@@ -513,7 +513,7 @@ function show_load_error(gobj, message)
|
|
|
513
513
|
$container.insertBefore($err, $container.firstChild);
|
|
514
514
|
}
|
|
515
515
|
let treedb = gobj_read_attr(gobj, "treedb_name") || "";
|
|
516
|
-
$err.textContent = (treedb ? `${treedb}: ` : "") + (message || "cannot load treedb");
|
|
516
|
+
$err.textContent = (treedb ? `${treedb}: ` : "") + (message || t("cannot load treedb"));
|
|
517
517
|
}
|
|
518
518
|
|
|
519
519
|
/************************************************************
|
|
@@ -671,6 +671,15 @@ const NODE_MODE_ICONS = {
|
|
|
671
671
|
shape: 'yi-hexagon-nodes',
|
|
672
672
|
};
|
|
673
673
|
|
|
674
|
+
/* The keys that reach t() as data: the labels of NODE_MODE_LABELS.
|
|
675
|
+
* Published for a consumer's validate-locales, which asks the app's
|
|
676
|
+
* locales for every key of an exported `*_I18N_KEYS` array. A view
|
|
677
|
+
* added to NODE_MODE_LABELS adds its label here
|
|
678
|
+
* (i18n_key_functions.test.js checks it). */
|
|
679
|
+
export const C_YUI_TREEDB_GRAPH_I18N_KEYS = [
|
|
680
|
+
'full', 'compact', 'shape'
|
|
681
|
+
];
|
|
682
|
+
|
|
674
683
|
/* The pressed view and the labels toggle, from the attrs. The
|
|
675
684
|
* toggle only means something on figures, so it is disabled
|
|
676
685
|
* elsewhere.
|
|
@@ -1219,7 +1228,7 @@ function open_json_viewer(gobj)
|
|
|
1219
1228
|
close_json_viewer(gobj);
|
|
1220
1229
|
return;
|
|
1221
1230
|
}
|
|
1222
|
-
priv.json_modal = yui_shell_show_modal(shell, $box, {
|
|
1231
|
+
priv.json_modal = yui_shell_show_modal(shell, /* i18n: data */ $box, {
|
|
1223
1232
|
dialog: true,
|
|
1224
1233
|
logical_class: "TREEDB_JSON_SHEET",
|
|
1225
1234
|
title_prefix: priv.treedb_name,
|
|
@@ -1352,8 +1361,7 @@ function answer_print_tranger_refused(gobj, path, answer)
|
|
|
1352
1361
|
gobj_send_event(jv, "EV_SUBTREE_ERROR",
|
|
1353
1362
|
Object.assign({path: path}, answer), gobj);
|
|
1354
1363
|
} else {
|
|
1355
|
-
yui_shell_show_error(yui_shell_of(gobj),
|
|
1356
|
-
answer.i18n || answer.error, {t: t});
|
|
1364
|
+
yui_shell_show_error(yui_shell_of(gobj), answer.i18n || answer.error, {t: t});
|
|
1357
1365
|
}
|
|
1358
1366
|
}
|
|
1359
1367
|
|
|
@@ -1404,7 +1412,7 @@ function request_print_tranger(gobj, path)
|
|
|
1404
1412
|
}, gobj);
|
|
1405
1413
|
if(ret) {
|
|
1406
1414
|
log_error(ret);
|
|
1407
|
-
answer_print_tranger_refused(gobj, path, {error: refusal_text(ret)});
|
|
1415
|
+
answer_print_tranger_refused(gobj, path, {error: /* i18n: data */ refusal_text(ret)});
|
|
1408
1416
|
return;
|
|
1409
1417
|
}
|
|
1410
1418
|
if(path) {
|
|
@@ -2167,7 +2175,7 @@ function ac_mt_command_answer(gobj, event, kw, src)
|
|
|
2167
2175
|
{path: path, error: comment || "print-tranger failed"}, gobj);
|
|
2168
2176
|
} else {
|
|
2169
2177
|
yui_shell_show_error(yui_shell_of(gobj),
|
|
2170
|
-
comment || "print-tranger failed", {t: t});
|
|
2178
|
+
/* i18n: data */ comment || "print-tranger failed", {t: t});
|
|
2171
2179
|
}
|
|
2172
2180
|
return 0;
|
|
2173
2181
|
}
|
|
@@ -2184,9 +2192,9 @@ function ac_mt_command_answer(gobj, event, kw, src)
|
|
|
2184
2192
|
/* The schema couldn't load (not a treedb, no authz for it, backend
|
|
2185
2193
|
* down…). Show an inline banner in the view rather than a blocking
|
|
2186
2194
|
* app-modal that wedges the whole SPA behind an empty tab. */
|
|
2187
|
-
show_load_error(gobj, t(comment));
|
|
2195
|
+
show_load_error(gobj, t(/* i18n: data */ comment));
|
|
2188
2196
|
} else {
|
|
2189
|
-
yui_shell_show_error(yui_shell_of(gobj), comment, {t: t});
|
|
2197
|
+
yui_shell_show_error(yui_shell_of(gobj), /* i18n: data */ comment, {t: t});
|
|
2190
2198
|
}
|
|
2191
2199
|
// HACK don't return for non-descs, pass errors when need it.
|
|
2192
2200
|
}
|
|
@@ -3099,7 +3107,7 @@ function refresh_legend(gobj)
|
|
|
3099
3107
|
hidden? `${entry.total}` : `${entry.visible}/${entry.total}`]
|
|
3100
3108
|
);
|
|
3101
3109
|
|
|
3102
|
-
|
|
3110
|
+
const body_key = is_main? 'main topic' : (hidden? 'show topic' : 'hide topic');
|
|
3103
3111
|
|
|
3104
3112
|
/* Built as an object first: an attribute that is `undefined`
|
|
3105
3113
|
* is still SET by createElement2 (to the string "undefined"),
|
|
@@ -68,6 +68,7 @@ import {
|
|
|
68
68
|
yui_graph_update_zoom,
|
|
69
69
|
} from "./yui_graph_camera.js";
|
|
70
70
|
import {ensure_pinch_zoom_patch} from "./g6_touch_gestures.js";
|
|
71
|
+
import {keep_canvas_tab_order} from "./g6_canvas_tab_order.js";
|
|
71
72
|
import {col_key_roles} from "./treedb_topic_keys.js";
|
|
72
73
|
|
|
73
74
|
import {getStrokeColor} from "./lib_graph.js";
|
|
@@ -659,6 +660,10 @@ function build_graph(gobj)
|
|
|
659
660
|
|
|
660
661
|
graph.setTheme(dark ? "dark" : "light");
|
|
661
662
|
|
|
663
|
+
/* Tab goes from the graph to its own buttons: the main canvas in
|
|
664
|
+
* the Tab order, the other layers out (g6_canvas_tab_order.js). */
|
|
665
|
+
keep_canvas_tab_order(gobj, graph);
|
|
666
|
+
|
|
662
667
|
/* The readout follows ANY camera change, the wheel included -- a
|
|
663
668
|
* wheel notch passes through no action of ours. */
|
|
664
669
|
graph.on('aftertransform', () => {
|
|
@@ -1512,7 +1512,7 @@ function create_tabulator(gobj)
|
|
|
1512
1512
|
|
|
1513
1513
|
let colDef = {
|
|
1514
1514
|
title: col_label(col, gobj_read_str_attr(gobj, "topic_name")),
|
|
1515
|
-
titleFormatter: col_title_formatter(gobj, col),
|
|
1515
|
+
titleFormatter: col_title_formatter(gobj, /* i18n: data */ col), // a column of the schema
|
|
1516
1516
|
field: col.id,
|
|
1517
1517
|
sorter: sorter,
|
|
1518
1518
|
hozAlign: hozAlign,
|
|
@@ -2428,7 +2428,7 @@ function open_form_dialog(gobj, mode, record)
|
|
|
2428
2428
|
* while "new"/"edit"/"view" is what only this header can tell you.
|
|
2429
2429
|
* All three are keys this library already uses. */
|
|
2430
2430
|
let pkey = desc.pkey || "id";
|
|
2431
|
-
|
|
2431
|
+
const title = (mode === "create")? "new" : ((mode === "view")? "view" : "edit");
|
|
2432
2432
|
let title_prefix = "";
|
|
2433
2433
|
if(mode !== "create") {
|
|
2434
2434
|
let rid = record ? String(record[pkey] ?? "") : "";
|
|
@@ -2548,7 +2548,7 @@ function form_may_close(gobj)
|
|
|
2548
2548
|
* a second key to define — and the one that was here had never
|
|
2549
2549
|
* been defined in any locale, which renders as the English
|
|
2550
2550
|
* sentence itself, in every language, for ever. */
|
|
2551
|
-
confirm_then(gobj, kw.warning || "all changes will be lost",
|
|
2551
|
+
confirm_then(gobj, /* i18n: C_YUI_FORM_I18N_KEYS */ kw.warning || "all changes will be lost",
|
|
2552
2552
|
{what: "close_form"});
|
|
2553
2553
|
return false;
|
|
2554
2554
|
}
|
|
@@ -2676,7 +2676,7 @@ function open_schema_dialog(gobj)
|
|
|
2676
2676
|
/* Title split in two halves: the topic name is DATA (never
|
|
2677
2677
|
* translated) and "schema" is the kind (carries its i18n key), so
|
|
2678
2678
|
* the header re-translates on a language switch. */
|
|
2679
|
-
let presented = present_json_popup(gobj, $box, {
|
|
2679
|
+
let presented = present_json_popup(gobj, /* i18n: data */ $box, { // the viewer's own DOM
|
|
2680
2680
|
name: "schemawin_" + clean_name(gobj_name(gobj)),
|
|
2681
2681
|
logical_class: "TREEDB_SCHEMA",
|
|
2682
2682
|
title_prefix: gobj_read_str_attr(gobj, "topic_name"),
|
|
@@ -2803,7 +2803,7 @@ function open_cell_json_dialog(gobj, row_id, col_id)
|
|
|
2803
2803
|
* i18n key — the shared `col.id` one, so the header re-translates on a
|
|
2804
2804
|
* language switch and reads as the raw id where the app defines no key
|
|
2805
2805
|
* (exactly what an untranslated column header already shows). */
|
|
2806
|
-
let presented = present_json_popup(gobj, $box, {
|
|
2806
|
+
let presented = present_json_popup(gobj, /* i18n: data */ $box, { // the viewer's own DOM
|
|
2807
2807
|
name: "cellwin_" + clean_name(gobj_name(gobj)),
|
|
2808
2808
|
logical_class: "TREEDB_CELL_JSON",
|
|
2809
2809
|
title_prefix: String(row_id),
|
|
@@ -4599,7 +4599,7 @@ function ac_show_hook_data(gobj, event, kw, src)
|
|
|
4599
4599
|
String(kw.row_id), kw.col_id);
|
|
4600
4600
|
return 0;
|
|
4601
4601
|
}
|
|
4602
|
-
open_hook_choice_dialog(gobj, targets, String(kw.row_id), kw.col_id);
|
|
4602
|
+
open_hook_choice_dialog(gobj, /* i18n: data */ targets, String(kw.row_id), kw.col_id); // the schema's topics
|
|
4603
4603
|
return 0;
|
|
4604
4604
|
}
|
|
4605
4605
|
|
|
@@ -4681,7 +4681,7 @@ function ac_refresh(gobj, event, kw, src)
|
|
|
4681
4681
|
************************************************************/
|
|
4682
4682
|
function ac_show_cell_json(gobj, event, kw, src)
|
|
4683
4683
|
{
|
|
4684
|
-
open_cell_json_dialog(gobj, kw.row_id, kw.col_id);
|
|
4684
|
+
open_cell_json_dialog(gobj, kw.row_id, /* i18n: data */ kw.col_id);
|
|
4685
4685
|
|
|
4686
4686
|
return 0;
|
|
4687
4687
|
}
|
|
@@ -4695,7 +4695,7 @@ function ac_show_cell_json(gobj, event, kw, src)
|
|
|
4695
4695
|
************************************************************/
|
|
4696
4696
|
function ac_show_cell_file(gobj, event, kw, src)
|
|
4697
4697
|
{
|
|
4698
|
-
open_cell_file_dialog(gobj, kw.row_id, kw.col_id);
|
|
4698
|
+
open_cell_file_dialog(gobj, kw.row_id, /* i18n: data */ kw.col_id);
|
|
4699
4699
|
|
|
4700
4700
|
return 0;
|
|
4701
4701
|
}
|
|
@@ -5291,7 +5291,7 @@ function open_table_json_dialog(gobj, records)
|
|
|
5291
5291
|
}
|
|
5292
5292
|
|
|
5293
5293
|
/* The topic is DATA (the prefix), the title carries its key. */
|
|
5294
|
-
let presented = present_json_popup(gobj, $box, {
|
|
5294
|
+
let presented = present_json_popup(gobj, /* i18n: data */ $box, { // the viewer's own DOM
|
|
5295
5295
|
name: "tablejsonwin_" + clean_name(gobj_name(gobj)),
|
|
5296
5296
|
logical_class: "TREEDB_TABLE_JSON",
|
|
5297
5297
|
title_prefix: gobj_read_str_attr(gobj, "topic_name"),
|