@yuneta/gobj-ui 7.23.114 → 7.23.116
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/dist/gobj-ui.cjs.js +60 -8
- package/dist/gobj-ui.es.js +60 -8
- package/package.json +1 -1
- package/src/c_yui_form.js +33 -0
- package/src/c_yui_schema_editor.js +47 -8
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -7219,6 +7219,30 @@ function destroy_ui$10(gobj) {
|
|
|
7219
7219
|
/******************************************************************
|
|
7220
7220
|
* Build form with bulma and createElement2
|
|
7221
7221
|
******************************************************************/
|
|
7222
|
+
/************************************************************
|
|
7223
|
+
* Put the field's NAME on its control.
|
|
7224
|
+
*
|
|
7225
|
+
* The label of a field is written `<label for={name}>` -- and
|
|
7226
|
+
* `for` matches an **id**, which no control here sets: they
|
|
7227
|
+
* carry `name`. So the association reads right in the source
|
|
7228
|
+
* and does not exist in the document, and every field of every
|
|
7229
|
+
* form of this library was unlabelled for anything that is not
|
|
7230
|
+
* an eye.
|
|
7231
|
+
*
|
|
7232
|
+
* `aria-label` and not an `id`: two forms can be open at once
|
|
7233
|
+
* (a record in a window and another in a modal), and duplicate
|
|
7234
|
+
* ids would break the association for both. The key is the
|
|
7235
|
+
* label's own, so a language change reaches it.
|
|
7236
|
+
************************************************************/
|
|
7237
|
+
function name_form_control($field, conf) {
|
|
7238
|
+
if (!$field || typeof $field.querySelector !== "function" || !conf) return;
|
|
7239
|
+
let key = conf.label_i18n || conf.label || "";
|
|
7240
|
+
if (!key) return;
|
|
7241
|
+
let $control = $field.querySelector("input, select, textarea");
|
|
7242
|
+
if (!$control || $control.getAttribute("aria-label")) return;
|
|
7243
|
+
$control.setAttribute("aria-label", (0, i18next.t)(key));
|
|
7244
|
+
$control.setAttribute("data-i18n-aria-label", key);
|
|
7245
|
+
}
|
|
7222
7246
|
function build_form(gobj) {
|
|
7223
7247
|
let form_id = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "form_id");
|
|
7224
7248
|
let $form = (0, _yuneta_gobj_js.createElement2)(["form", {
|
|
@@ -7255,6 +7279,7 @@ function build_html_form(gobj, $form, prefix, template) {
|
|
|
7255
7279
|
if (placeholders[key]) html_field_conf.placeholder = placeholders[key];
|
|
7256
7280
|
if (html_field_conf.tag) {
|
|
7257
7281
|
let $field = create_form_field(gobj, $form, prefix, field_desc, html_field_conf);
|
|
7282
|
+
name_form_control($field, html_field_conf);
|
|
7258
7283
|
$form.appendChild($field);
|
|
7259
7284
|
}
|
|
7260
7285
|
});
|
|
@@ -34979,7 +35004,7 @@ var reRgbaInteger = new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`);
|
|
|
34979
35004
|
var reRgbaPercent = new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`);
|
|
34980
35005
|
var reHslPercent = new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`);
|
|
34981
35006
|
var reHslaPercent = new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`);
|
|
34982
|
-
var named = {
|
|
35007
|
+
var named$1 = {
|
|
34983
35008
|
aliceblue: 15792383,
|
|
34984
35009
|
antiquewhite: 16444375,
|
|
34985
35010
|
aqua: 65535,
|
|
@@ -35158,7 +35183,7 @@ function color_formatRgb() {
|
|
|
35158
35183
|
function color(format) {
|
|
35159
35184
|
var m, l;
|
|
35160
35185
|
format = (format + "").trim().toLowerCase();
|
|
35161
|
-
return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) : l === 3 ? new Rgb(m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, (m & 15) << 4 | m & 15, 1) : l === 8 ? rgba(m >> 24 & 255, m >> 16 & 255, m >> 8 & 255, (m & 255) / 255) : l === 4 ? rgba(m >> 12 & 15 | m >> 8 & 240, m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, ((m & 15) << 4 | m & 15) / 255) : null) : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) : named.hasOwnProperty(format) ? rgbn(named[format]) : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
|
|
35186
|
+
return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) : l === 3 ? new Rgb(m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, (m & 15) << 4 | m & 15, 1) : l === 8 ? rgba(m >> 24 & 255, m >> 16 & 255, m >> 8 & 255, (m & 255) / 255) : l === 4 ? rgba(m >> 12 & 15 | m >> 8 & 240, m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, ((m & 15) << 4 | m & 15) / 255) : null) : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) : named$1.hasOwnProperty(format) ? rgbn(named$1[format]) : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
|
|
35162
35187
|
}
|
|
35163
35188
|
function rgbn(n) {
|
|
35164
35189
|
return new Rgb(n >> 16 & 255, n >> 8 & 255, n & 255, 1);
|
|
@@ -68242,15 +68267,42 @@ function open_dialog(gobj, $content, title, logical, title_prefix) {
|
|
|
68242
68267
|
* carries its name, so reading the form back is one query and
|
|
68243
68268
|
* a language change does not have to know the form exists.
|
|
68244
68269
|
***************************************************************/
|
|
68245
|
-
|
|
68246
|
-
|
|
68270
|
+
/***************************************************************
|
|
68271
|
+
* Put a NAME on the control of a field, from the label's key.
|
|
68272
|
+
*
|
|
68273
|
+
* It DESCENDS: `select_input()` hands back Bulma's wrapper
|
|
68274
|
+
* (`<div class="select"><select>`), so a check on the outer tag
|
|
68275
|
+
* named the div -- which names nothing -- and every select of
|
|
68276
|
+
* the two forms stayed anonymous while the inputs beside them
|
|
68277
|
+
* were fixed. Measured on a deployed schema: `SELECT[type]` with
|
|
68278
|
+
* no `aria-label` while `INPUT[header]` had one.
|
|
68279
|
+
*
|
|
68280
|
+
* The first control found is the one named: a field has one, and
|
|
68281
|
+
* where it has two (the hook's topic and column) they are named
|
|
68282
|
+
* where they are built, because "hook" would not tell them apart.
|
|
68283
|
+
***************************************************************/
|
|
68284
|
+
function named($spec, label) {
|
|
68285
|
+
name_control($spec, label);
|
|
68286
|
+
return $spec;
|
|
68287
|
+
}
|
|
68288
|
+
function name_control($spec, label) {
|
|
68289
|
+
if (!(0, _yuneta_gobj_js.is_array)($spec) || !(0, _yuneta_gobj_js.is_object)($spec[1])) return false;
|
|
68290
|
+
if ([
|
|
68247
68291
|
"input",
|
|
68248
68292
|
"select",
|
|
68249
68293
|
"textarea"
|
|
68250
|
-
].includes($
|
|
68251
|
-
|
|
68252
|
-
|
|
68294
|
+
].includes($spec[0])) {
|
|
68295
|
+
if (!$spec[1]["aria-label"]) {
|
|
68296
|
+
$spec[1]["aria-label"] = (0, i18next.t)(label);
|
|
68297
|
+
$spec[1]["data-i18n-aria-label"] = label;
|
|
68298
|
+
}
|
|
68299
|
+
return true;
|
|
68253
68300
|
}
|
|
68301
|
+
for (let child of $spec[2] || []) if (name_control(child, label)) return true;
|
|
68302
|
+
return false;
|
|
68303
|
+
}
|
|
68304
|
+
function field(logical, name, label, $control, help) {
|
|
68305
|
+
name_control($control, label);
|
|
68254
68306
|
return [
|
|
68255
68307
|
"div",
|
|
68256
68308
|
{ class: `${logical} field mb-3` },
|
|
@@ -68473,7 +68525,7 @@ function open_column_form(gobj, topic, col, prefill) {
|
|
|
68473
68525
|
class: "is-flex",
|
|
68474
68526
|
style: "gap:.4rem;"
|
|
68475
68527
|
},
|
|
68476
|
-
[select_input("hook_topic", hook_topic, [""].concat(sibling_topics)), text_input("hook_col", hook_col, (0, i18next.t)("the fkey column of the child"))]
|
|
68528
|
+
[named(select_input("hook_topic", hook_topic, [""].concat(sibling_topics)), "hook topic"), named(text_input("hook_col", hook_col, (0, i18next.t)("the fkey column of the child")), "hook column")]
|
|
68477
68529
|
],
|
|
68478
68530
|
[
|
|
68479
68531
|
"p",
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -7214,6 +7214,30 @@ function destroy_ui$10(gobj) {
|
|
|
7214
7214
|
/******************************************************************
|
|
7215
7215
|
* Build form with bulma and createElement2
|
|
7216
7216
|
******************************************************************/
|
|
7217
|
+
/************************************************************
|
|
7218
|
+
* Put the field's NAME on its control.
|
|
7219
|
+
*
|
|
7220
|
+
* The label of a field is written `<label for={name}>` -- and
|
|
7221
|
+
* `for` matches an **id**, which no control here sets: they
|
|
7222
|
+
* carry `name`. So the association reads right in the source
|
|
7223
|
+
* and does not exist in the document, and every field of every
|
|
7224
|
+
* form of this library was unlabelled for anything that is not
|
|
7225
|
+
* an eye.
|
|
7226
|
+
*
|
|
7227
|
+
* `aria-label` and not an `id`: two forms can be open at once
|
|
7228
|
+
* (a record in a window and another in a modal), and duplicate
|
|
7229
|
+
* ids would break the association for both. The key is the
|
|
7230
|
+
* label's own, so a language change reaches it.
|
|
7231
|
+
************************************************************/
|
|
7232
|
+
function name_form_control($field, conf) {
|
|
7233
|
+
if (!$field || typeof $field.querySelector !== "function" || !conf) return;
|
|
7234
|
+
let key = conf.label_i18n || conf.label || "";
|
|
7235
|
+
if (!key) return;
|
|
7236
|
+
let $control = $field.querySelector("input, select, textarea");
|
|
7237
|
+
if (!$control || $control.getAttribute("aria-label")) return;
|
|
7238
|
+
$control.setAttribute("aria-label", t(key));
|
|
7239
|
+
$control.setAttribute("data-i18n-aria-label", key);
|
|
7240
|
+
}
|
|
7217
7241
|
function build_form(gobj) {
|
|
7218
7242
|
let form_id = gobj_read_str_attr(gobj, "form_id");
|
|
7219
7243
|
let $form = createElement2(["form", {
|
|
@@ -7250,6 +7274,7 @@ function build_html_form(gobj, $form, prefix, template) {
|
|
|
7250
7274
|
if (placeholders[key]) html_field_conf.placeholder = placeholders[key];
|
|
7251
7275
|
if (html_field_conf.tag) {
|
|
7252
7276
|
let $field = create_form_field(gobj, $form, prefix, field_desc, html_field_conf);
|
|
7277
|
+
name_form_control($field, html_field_conf);
|
|
7253
7278
|
$form.appendChild($field);
|
|
7254
7279
|
}
|
|
7255
7280
|
});
|
|
@@ -34974,7 +34999,7 @@ var reRgbaInteger = new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`);
|
|
|
34974
34999
|
var reRgbaPercent = new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`);
|
|
34975
35000
|
var reHslPercent = new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`);
|
|
34976
35001
|
var reHslaPercent = new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`);
|
|
34977
|
-
var named = {
|
|
35002
|
+
var named$1 = {
|
|
34978
35003
|
aliceblue: 15792383,
|
|
34979
35004
|
antiquewhite: 16444375,
|
|
34980
35005
|
aqua: 65535,
|
|
@@ -35153,7 +35178,7 @@ function color_formatRgb() {
|
|
|
35153
35178
|
function color(format) {
|
|
35154
35179
|
var m, l;
|
|
35155
35180
|
format = (format + "").trim().toLowerCase();
|
|
35156
|
-
return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) : l === 3 ? new Rgb(m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, (m & 15) << 4 | m & 15, 1) : l === 8 ? rgba(m >> 24 & 255, m >> 16 & 255, m >> 8 & 255, (m & 255) / 255) : l === 4 ? rgba(m >> 12 & 15 | m >> 8 & 240, m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, ((m & 15) << 4 | m & 15) / 255) : null) : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) : named.hasOwnProperty(format) ? rgbn(named[format]) : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
|
|
35181
|
+
return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) : l === 3 ? new Rgb(m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, (m & 15) << 4 | m & 15, 1) : l === 8 ? rgba(m >> 24 & 255, m >> 16 & 255, m >> 8 & 255, (m & 255) / 255) : l === 4 ? rgba(m >> 12 & 15 | m >> 8 & 240, m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, ((m & 15) << 4 | m & 15) / 255) : null) : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) : named$1.hasOwnProperty(format) ? rgbn(named$1[format]) : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
|
|
35157
35182
|
}
|
|
35158
35183
|
function rgbn(n) {
|
|
35159
35184
|
return new Rgb(n >> 16 & 255, n >> 8 & 255, n & 255, 1);
|
|
@@ -68237,15 +68262,42 @@ function open_dialog(gobj, $content, title, logical, title_prefix) {
|
|
|
68237
68262
|
* carries its name, so reading the form back is one query and
|
|
68238
68263
|
* a language change does not have to know the form exists.
|
|
68239
68264
|
***************************************************************/
|
|
68240
|
-
|
|
68241
|
-
|
|
68265
|
+
/***************************************************************
|
|
68266
|
+
* Put a NAME on the control of a field, from the label's key.
|
|
68267
|
+
*
|
|
68268
|
+
* It DESCENDS: `select_input()` hands back Bulma's wrapper
|
|
68269
|
+
* (`<div class="select"><select>`), so a check on the outer tag
|
|
68270
|
+
* named the div -- which names nothing -- and every select of
|
|
68271
|
+
* the two forms stayed anonymous while the inputs beside them
|
|
68272
|
+
* were fixed. Measured on a deployed schema: `SELECT[type]` with
|
|
68273
|
+
* no `aria-label` while `INPUT[header]` had one.
|
|
68274
|
+
*
|
|
68275
|
+
* The first control found is the one named: a field has one, and
|
|
68276
|
+
* where it has two (the hook's topic and column) they are named
|
|
68277
|
+
* where they are built, because "hook" would not tell them apart.
|
|
68278
|
+
***************************************************************/
|
|
68279
|
+
function named($spec, label) {
|
|
68280
|
+
name_control($spec, label);
|
|
68281
|
+
return $spec;
|
|
68282
|
+
}
|
|
68283
|
+
function name_control($spec, label) {
|
|
68284
|
+
if (!is_array($spec) || !is_object($spec[1])) return false;
|
|
68285
|
+
if ([
|
|
68242
68286
|
"input",
|
|
68243
68287
|
"select",
|
|
68244
68288
|
"textarea"
|
|
68245
|
-
].includes($
|
|
68246
|
-
|
|
68247
|
-
|
|
68289
|
+
].includes($spec[0])) {
|
|
68290
|
+
if (!$spec[1]["aria-label"]) {
|
|
68291
|
+
$spec[1]["aria-label"] = t(label);
|
|
68292
|
+
$spec[1]["data-i18n-aria-label"] = label;
|
|
68293
|
+
}
|
|
68294
|
+
return true;
|
|
68248
68295
|
}
|
|
68296
|
+
for (let child of $spec[2] || []) if (name_control(child, label)) return true;
|
|
68297
|
+
return false;
|
|
68298
|
+
}
|
|
68299
|
+
function field(logical, name, label, $control, help) {
|
|
68300
|
+
name_control($control, label);
|
|
68249
68301
|
return [
|
|
68250
68302
|
"div",
|
|
68251
68303
|
{ class: `${logical} field mb-3` },
|
|
@@ -68468,7 +68520,7 @@ function open_column_form(gobj, topic, col, prefill) {
|
|
|
68468
68520
|
class: "is-flex",
|
|
68469
68521
|
style: "gap:.4rem;"
|
|
68470
68522
|
},
|
|
68471
|
-
[select_input("hook_topic", hook_topic, [""].concat(sibling_topics)), text_input("hook_col", hook_col, t("the fkey column of the child"))]
|
|
68523
|
+
[named(select_input("hook_topic", hook_topic, [""].concat(sibling_topics)), "hook topic"), named(text_input("hook_col", hook_col, t("the fkey column of the child")), "hook column")]
|
|
68472
68524
|
],
|
|
68473
68525
|
[
|
|
68474
68526
|
"p",
|
package/package.json
CHANGED
package/src/c_yui_form.js
CHANGED
|
@@ -490,6 +490,38 @@ function destroy_ui(gobj)
|
|
|
490
490
|
/******************************************************************
|
|
491
491
|
* Build form with bulma and createElement2
|
|
492
492
|
******************************************************************/
|
|
493
|
+
/************************************************************
|
|
494
|
+
* Put the field's NAME on its control.
|
|
495
|
+
*
|
|
496
|
+
* The label of a field is written `<label for={name}>` -- and
|
|
497
|
+
* `for` matches an **id**, which no control here sets: they
|
|
498
|
+
* carry `name`. So the association reads right in the source
|
|
499
|
+
* and does not exist in the document, and every field of every
|
|
500
|
+
* form of this library was unlabelled for anything that is not
|
|
501
|
+
* an eye.
|
|
502
|
+
*
|
|
503
|
+
* `aria-label` and not an `id`: two forms can be open at once
|
|
504
|
+
* (a record in a window and another in a modal), and duplicate
|
|
505
|
+
* ids would break the association for both. The key is the
|
|
506
|
+
* label's own, so a language change reaches it.
|
|
507
|
+
************************************************************/
|
|
508
|
+
function name_form_control($field, conf)
|
|
509
|
+
{
|
|
510
|
+
if(!$field || typeof $field.querySelector !== "function" || !conf) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
let key = conf.label_i18n || conf.label || "";
|
|
514
|
+
if(!key) {
|
|
515
|
+
return; /* a field with no label names nothing */
|
|
516
|
+
}
|
|
517
|
+
let $control = $field.querySelector("input, select, textarea");
|
|
518
|
+
if(!$control || $control.getAttribute("aria-label")) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
$control.setAttribute("aria-label", t(key));
|
|
522
|
+
$control.setAttribute("data-i18n-aria-label", key);
|
|
523
|
+
}
|
|
524
|
+
|
|
493
525
|
function build_form(gobj)
|
|
494
526
|
{
|
|
495
527
|
let form_id = gobj_read_str_attr(gobj, "form_id");
|
|
@@ -566,6 +598,7 @@ function build_html_form(gobj, $form, prefix, template)
|
|
|
566
598
|
*/
|
|
567
599
|
if(html_field_conf.tag) {
|
|
568
600
|
let $field = create_form_field(gobj, $form, prefix, field_desc, html_field_conf);
|
|
601
|
+
name_form_control($field, html_field_conf);
|
|
569
602
|
$form.appendChild($field);
|
|
570
603
|
}
|
|
571
604
|
});
|
|
@@ -1556,6 +1556,46 @@ function open_dialog(gobj, $content, title, logical, title_prefix)
|
|
|
1556
1556
|
* carries its name, so reading the form back is one query and
|
|
1557
1557
|
* a language change does not have to know the form exists.
|
|
1558
1558
|
***************************************************************/
|
|
1559
|
+
/***************************************************************
|
|
1560
|
+
* Put a NAME on the control of a field, from the label's key.
|
|
1561
|
+
*
|
|
1562
|
+
* It DESCENDS: `select_input()` hands back Bulma's wrapper
|
|
1563
|
+
* (`<div class="select"><select>`), so a check on the outer tag
|
|
1564
|
+
* named the div -- which names nothing -- and every select of
|
|
1565
|
+
* the two forms stayed anonymous while the inputs beside them
|
|
1566
|
+
* were fixed. Measured on a deployed schema: `SELECT[type]` with
|
|
1567
|
+
* no `aria-label` while `INPUT[header]` had one.
|
|
1568
|
+
*
|
|
1569
|
+
* The first control found is the one named: a field has one, and
|
|
1570
|
+
* where it has two (the hook's topic and column) they are named
|
|
1571
|
+
* where they are built, because "hook" would not tell them apart.
|
|
1572
|
+
***************************************************************/
|
|
1573
|
+
function named($spec, label)
|
|
1574
|
+
{
|
|
1575
|
+
name_control($spec, label);
|
|
1576
|
+
return $spec;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
function name_control($spec, label)
|
|
1580
|
+
{
|
|
1581
|
+
if(!is_array($spec) || !is_object($spec[1])) {
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
if(["input", "select", "textarea"].includes($spec[0])) {
|
|
1585
|
+
if(!$spec[1]["aria-label"]) {
|
|
1586
|
+
$spec[1]["aria-label"] = t(label);
|
|
1587
|
+
$spec[1]["data-i18n-aria-label"] = label;
|
|
1588
|
+
}
|
|
1589
|
+
return true;
|
|
1590
|
+
}
|
|
1591
|
+
for(let child of ($spec[2] || [])) {
|
|
1592
|
+
if(name_control(child, label)) {
|
|
1593
|
+
return true;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
return false;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1559
1599
|
function field(logical, name, label, $control, help)
|
|
1560
1600
|
{
|
|
1561
1601
|
/* The label is a SIBLING of the control -- Bulma's `field` shape --
|
|
@@ -1563,12 +1603,7 @@ function field(logical, name, label, $control, help)
|
|
|
1563
1603
|
* wrapping, and a reader announces the box as unlabelled. The name
|
|
1564
1604
|
* is put on the control itself, from the label's own key, so the
|
|
1565
1605
|
* two cannot drift and a language change reaches both. */
|
|
1566
|
-
|
|
1567
|
-
["input", "select", "textarea"].includes($control[0]) &&
|
|
1568
|
-
!$control[1]["aria-label"]) {
|
|
1569
|
-
$control[1]["aria-label"] = t(label);
|
|
1570
|
-
$control[1]["data-i18n-aria-label"] = label;
|
|
1571
|
-
}
|
|
1606
|
+
name_control($control, label);
|
|
1572
1607
|
return ["div", {class: `${logical} field mb-3`}, [
|
|
1573
1608
|
["label", {class: "label", i18n: label}, t(label)],
|
|
1574
1609
|
["div", {class: "control"}, [$control]],
|
|
@@ -1733,9 +1768,13 @@ function open_column_form(gobj, topic, col, prefill)
|
|
|
1733
1768
|
]],
|
|
1734
1769
|
["div", {class: "SCHEMA_COL_FORM_HOOK field mb-3"}, [
|
|
1735
1770
|
["label", {class: "label", i18n: "hook"}, t("hook")],
|
|
1771
|
+
/* TWO controls in one field, so each says which half it
|
|
1772
|
+
* is: `hook` alone would name them both the same. */
|
|
1736
1773
|
["div", {class: "is-flex", style: "gap:.4rem;"}, [
|
|
1737
|
-
select_input("hook_topic", hook_topic,
|
|
1738
|
-
|
|
1774
|
+
named(select_input("hook_topic", hook_topic,
|
|
1775
|
+
[""].concat(sibling_topics)), "hook topic"),
|
|
1776
|
+
named(text_input("hook_col", hook_col,
|
|
1777
|
+
t("the fkey column of the child")), "hook column")
|
|
1739
1778
|
]],
|
|
1740
1779
|
["p", {class: "help", i18n: "a hook names the child topic and the column of the child that points back"},
|
|
1741
1780
|
t("a hook names the child topic and the column of the child that points back")]
|