@yuneta/gobj-ui 7.26.30 → 7.26.32
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 +246 -72
- package/dist/gobj-ui.cjs.js +64 -20
- package/dist/gobj-ui.es.js +64 -20
- package/package.json +1 -1
- package/scripts/validate-locales.mjs +1755 -328
- package/src/c_g6_nodes_tree.js +6 -4
- package/src/c_yui_form.js +17 -4
- package/src/c_yui_treedb_graph.js +6 -3
- package/src/c_yui_treedb_topics.js +6 -3
- package/src/c_yui_window.js +32 -5
- package/src/i18n_key_functions.js +54 -31
- package/src/i18n_key_functions.test.js +461 -49
- package/src/window_layer.wiring.test.js +106 -0
- package/src/yui_table_select.js +20 -13
- package/src/yui_tabulator_i18n.js +10 -2
- package/src/yui_tabulator_i18n.test.js +80 -0
package/README.md
CHANGED
|
@@ -78,6 +78,15 @@ Published as `@yuneta/gobj-ui`. Built on top of [`@yuneta/gobj-js`](https://gith
|
|
|
78
78
|
> maximize/restore + close. The self-contained **"shade"** fallback (roll up to
|
|
79
79
|
> the title bar in place) and its `is-shaded` CSS are **removed**; an app that
|
|
80
80
|
> relied on shading needs to register a manager.
|
|
81
|
+
>
|
|
82
|
+
> **Where a window lives (7.26.31):** a `C_YUI_WINDOW` whose host names no
|
|
83
|
+
> `$parent` mounts in the **overlay layer of the shell** -- above the content,
|
|
84
|
+
> below the toolbar's dropdowns, the dialogs and the toasts -- and on
|
|
85
|
+
> `document.body` only when there is no shell. It used to be the body always,
|
|
86
|
+
> and since `.yui-shell` is `position: fixed` (a stacking context of its own)
|
|
87
|
+
> a window at z-index 11 covered the WHOLE shell, modal layer included: the
|
|
88
|
+
> confirmation of a window's own close opened under it, out of reach. A
|
|
89
|
+
> `$parent` the host names still wins.
|
|
81
90
|
|
|
82
91
|
## Two maintained lines
|
|
83
92
|
|
|
@@ -86,8 +95,8 @@ consumers. They are independent snapshots (no shared git ancestry):
|
|
|
86
95
|
|
|
87
96
|
| Line | Branch | Latest tag | Layout | Consumed by | How | Status |
|
|
88
97
|
|------|--------|------------|--------|-------------|-----|--------|
|
|
89
|
-
| **v2** | `main` | `7.26.x` | `src/` subdir | **gui_agent**, **gui_treedb**, **wattyzer**, the **yunovatios** GUIs | published npm `@yuneta/gobj-ui` (dist-tag `latest`) | active development |
|
|
90
|
-
| **v1** | `v1` | `1.0.4` | `src/` subdir | **
|
|
98
|
+
| **v2** | `main` | `7.26.x` | `src/` subdir | **gui_agent**, **gui_treedb**, **wattyzer**, the **yunovatios** GUIs, **estadodelaire** (since 2026-10-13) | published npm `@yuneta/gobj-ui` (dist-tag `latest`) | active development |
|
|
99
|
+
| **v1** | `v1` | `1.0.4` | `src/` subdir | **hidraulia** | published npm `@yuneta/gobj-ui@^1.0.4` (dist-tag `legacy`) | frozen, maintenance-only |
|
|
91
100
|
|
|
92
101
|
- **v2 / `main`** is the active development line: the declarative shell
|
|
93
102
|
(legacy-stack-free since `3.0.0`). It is embedded as a git submodule in
|
|
@@ -100,9 +109,10 @@ consumers. They are independent snapshots (no shared git ancestry):
|
|
|
100
109
|
(`npm run deploy-round` does the round). `test-app/` is the one exception:
|
|
101
110
|
it consumes the working tree (`file:..`), which is what it is for.
|
|
102
111
|
- **v1 / `v1`** is the frozen legacy-only stack (the declarative shell is not on
|
|
103
|
-
this line). It is **published to npm**;
|
|
104
|
-
`@yuneta/gobj-ui@^1.0.4` from the registry
|
|
105
|
-
|
|
112
|
+
this line). It is **published to npm**; hidraulia depends on
|
|
113
|
+
`@yuneta/gobj-ui@^1.0.4` from the registry (estadodelaire left it for v2 on
|
|
114
|
+
2026-10-13, and hidraulia is next). Land only maintenance fixes here, then
|
|
115
|
+
`npm publish` a new `1.x`.
|
|
106
116
|
|
|
107
117
|
All new feature work lands on `main`/v2.
|
|
108
118
|
|
|
@@ -3826,28 +3836,57 @@ text is a key, `"configuración"` included.
|
|
|
3826
3836
|
dependency of this package since `7.26.29`: an app need not declare it). A
|
|
3827
3837
|
LOCALE is not a source: it is parsed, and then imported, so its top-level code
|
|
3828
3838
|
runs -- the app's own code, but code. Comments are not code. A key is read
|
|
3829
|
-
where it is WRITTEN -- given to
|
|
3830
|
-
an object literal, by `setAttribute()`, or (since `7.26.29`) written
|
|
3831
|
-
member, `attrs.i18n = "save"`, `attrs["data-i18n-title"] = "save"` -- and
|
|
3832
|
-
FOLLOWED where the source writes it out
|
|
3839
|
+
where it is WRITTEN -- given to a translator, as an `i18n` or `data-i18n*`
|
|
3840
|
+
value of an object literal, by `setAttribute()`, or (since `7.26.29`) written
|
|
3841
|
+
as a member, `attrs.i18n = "save"`, `attrs["data-i18n-title"] = "save"` -- and
|
|
3842
|
+
FOLLOWED where the source writes it out.
|
|
3843
|
+
|
|
3844
|
+
A **translator** is one notion, the same everywhere the reader asks "is this a
|
|
3845
|
+
call of t()?" (since `7.26.32`; up to `7.26.31` it was a call NAMED `t` or
|
|
3846
|
+
`tr`): a name `t` or `tr` (whatever binds it), a member `.t` / `.tr`
|
|
3847
|
+
(`i18next.t`), i18next's `t` imported under any name (`import {t as tt} from
|
|
3848
|
+
"i18next"`), or an alias of one -- a const (`const translate = t`), a
|
|
3849
|
+
`.bind()` (`i18next.t.bind(i18next)`), a re-export of a module the reader
|
|
3850
|
+
reads --, called as `t(k)`, `t?.(k)`, `t.call(x, k)` or `t.apply(x, [k])`. An
|
|
3851
|
+
ARRAY given to it is i18next's list of fallback keys, and each one is a key:
|
|
3852
|
+
`t([specific, "generic"])` asks for "generic". The places, since `7.26.32`, also
|
|
3853
|
+
include `el.dataset.i18nTitle = k` (`dataset.i18nX` IS the attribute
|
|
3854
|
+
`data-i18n-x`), and an attribute or property NAMED by a const:
|
|
3855
|
+
`el.setAttribute(ATTR, k)`, `{[ATTR]: k}`, `x[ATTR] = k`, with `const ATTR =
|
|
3856
|
+
"data-i18n-title"`. What is followed:
|
|
3833
3857
|
|
|
3834
3858
|
- a string literal, a template with no `${}`, and every branch of `?:`, `||`
|
|
3835
3859
|
and `??` (the right one of `&&`), so
|
|
3836
3860
|
`"data-i18n": pending ? "loading" : "click to load"` asks for both, and
|
|
3837
3861
|
`comment || "print-tranger failed"` for its fallback;
|
|
3838
3862
|
- a `const`, to its value, in the scope that declares it (a parameter or a
|
|
3839
|
-
`let` of the same name hides it)
|
|
3863
|
+
`let` of the same name hides it), and what a destructuring reads from it
|
|
3864
|
+
(since `7.26.32`: `const {title = "untitled"} = LABELS`);
|
|
3865
|
+
- an IMPORT of a const or of a function, into the module it names, when the
|
|
3866
|
+
reader reads that module -- a file of the app, a module of this library;
|
|
3867
|
+
re-exports are followed (since `7.26.32`). A package (gobj-js, i18next) is
|
|
3868
|
+
not read, and neither is the export of a `let`;
|
|
3840
3869
|
- a property of a const object literal: `DEFAULT_LABEL.ok`, and for a
|
|
3841
|
-
computed one, `NOTES[verdict]`, every value the object holds;
|
|
3870
|
+
computed one, `NOTES[verdict]`, every value the object holds; also of a
|
|
3871
|
+
COPY of one (since `7.26.32`): `{...BASE, title: "t"}`,
|
|
3872
|
+
`Object.assign({}, BASE)`;
|
|
3842
3873
|
- the element of a const array literal that a `.map()`, `.forEach()`, ...
|
|
3843
3874
|
callback or a `for...of` walks, and what a destructuring reads from it
|
|
3844
3875
|
(`for(const {key} of ROWS)`);
|
|
3845
3876
|
- `String(x)`, and a template that is only `${x}`, as `x` (since `7.26.29`);
|
|
3846
|
-
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3877
|
+
- a parameter, however it is read (since `7.26.32`): `opts.title`,
|
|
3878
|
+
`opts?.title`, `arguments[1]`, `rest[0]` of a rest parameter, a destructuring
|
|
3879
|
+
in the parameter or in the body; and its default, `function f(msg =
|
|
3880
|
+
"fallback")`, besides the parameter (since `7.26.29`);
|
|
3881
|
+
- a call of a function whose every `return` is one of these (since
|
|
3882
|
+
`7.26.29`): of the same module, or (since `7.26.32`) imported from a module
|
|
3883
|
+
the reader reads, called by `.call()` / `.apply()` too. One that returns
|
|
3884
|
+
anything else -- a parameter, a variable, a concatenation -- is not
|
|
3885
|
+
followed. What a function returns is read ONCE, and a RECURSION is not
|
|
3886
|
+
followed: a call of a function that is being read is a value the reader
|
|
3887
|
+
cannot follow. Up to `7.26.31` a function was read again at every call of
|
|
3888
|
+
it, so a helper that calls itself in two branches (`label_of(n)` walking
|
|
3889
|
+
up a tree) took more than two minutes, and in three it never ended.
|
|
3851
3890
|
|
|
3852
3891
|
```js
|
|
3853
3892
|
const KEY = "save";
|
|
@@ -3864,12 +3903,12 @@ function pick(ok) {
|
|
|
3864
3903
|
t(pick(answer)); // asks for both
|
|
3865
3904
|
```
|
|
3866
3905
|
|
|
3867
|
-
What it cannot follow cannot be known: a `let`, a parameter
|
|
3868
|
-
call, a concatenation, data from a backend. A key
|
|
3869
|
-
PUBLISHED by its module (below), and the place it is
|
|
3870
|
-
`let` -- or a marked member or element of one -- is the
|
|
3871
|
-
followed" (below). A source file that cannot be parsed
|
|
3872
|
-
its keys would go unchecked.
|
|
3906
|
+
What it cannot follow cannot be known: a `let`, a parameter of an app's
|
|
3907
|
+
function, a call it does not read, a concatenation, data from a backend. A key
|
|
3908
|
+
that arrives that way is PUBLISHED by its module (below), and the place it is
|
|
3909
|
+
read is MARKED; a marked `let` -- or a marked member or element of one -- is the
|
|
3910
|
+
one exception to "not followed" (below). A source file that cannot be parsed
|
|
3911
|
+
fails the build, because its keys would go unchecked.
|
|
3873
3912
|
|
|
3874
3913
|
**A key handed to a FUNCTION is read where it is handed.**
|
|
3875
3914
|
`yui_shell_show_error(shell, "some records were gone before the delete")` asks
|
|
@@ -3891,10 +3930,16 @@ A position is an argument (`"1"`), a property of the object given there
|
|
|
3891
3930
|
(`"2.title"`, also through `Object.assign()` or a spread of a const object),
|
|
3892
3931
|
or a property of each object of an array (`"1.actions[].label"`). What is
|
|
3893
3932
|
given at those positions is read like any other key (literals, consts,
|
|
3894
|
-
branches): in the app's own code, on a call
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3933
|
+
branches): in the app's own code, on a call that reaches that function of
|
|
3934
|
+
gobj-ui (an app function of the same name is not mistaken for it), and in
|
|
3935
|
+
every module the app mounts, where an entry with `exported: false` is a
|
|
3936
|
+
helper of its own module. A call reaches it however it names it (since
|
|
3937
|
+
`7.26.32`; up to `7.26.31` only an import by its own name, or a namespace
|
|
3938
|
+
member): an import under any name, a re-export from a file of the app
|
|
3939
|
+
(`export {yui_shell_show_info as say} from "@yuneta/gobj-ui/src/shell_modals.js"`),
|
|
3940
|
+
a const alias (`const show = yui_shell_show_info`), a map in a const
|
|
3941
|
+
(`const API = {info: yui_shell_show_info}; API.info(...)`, imported too),
|
|
3942
|
+
`.call(x, ...)` and `.apply(x, [...])`. A position may also hold
|
|
3898
3943
|
DOM, which is no key (since `7.26.29`): an array (a `createElement2` spec), a
|
|
3899
3944
|
call of `createElement2()`, `createOneHtml()` or `html_markup()` imported
|
|
3900
3945
|
from gobj-js, of `text_node()` from gobj-ui, of `document.createElement()`
|
|
@@ -3915,12 +3960,14 @@ gclass name, which titles it).
|
|
|
3915
3960
|
(since `7.26.29`: up to `7.26.28` the table lacked 39 of them, and 6 entries
|
|
3916
3961
|
lacked positions, so a literal handed to one went unasked -- REV-CLOUD
|
|
3917
3962
|
V21.4.1). `src/i18n_key_functions.test.js` reads every module and finds each
|
|
3918
|
-
function that hands one of its PARAMETERS on to a place a key is read --
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3963
|
+
function that hands one of its PARAMETERS on to a place a key is read -- a
|
|
3964
|
+
translator (any of the forms above), an `i18n`, `code` or `data-i18n*` value
|
|
3965
|
+
(`el.dataset.i18nTitle` included), a key position of a function of the table
|
|
3966
|
+
-- the parameter itself or what is read from it: `opts.title`, `opts?.title`,
|
|
3967
|
+
a destructured `{label}` in the parameter or in the body, each `items[].name`,
|
|
3968
|
+
`arguments[1]`, `rest[0]`, a copy (`{...opts}`, `Object.assign({}, opts)`),
|
|
3969
|
+
directly or through a `let` it is given to. The search runs to a fixpoint: a
|
|
3970
|
+
function that hands its parameter to one it found is one too.
|
|
3924
3971
|
|
|
3925
3972
|
- A function called by NAME -- in its module, or exported -- must be in the
|
|
3926
3973
|
table with that position, or the test fails, naming the entry to add:
|
|
@@ -3937,7 +3984,47 @@ to one it found is one too.
|
|
|
3937
3984
|
writes `i18n: /* i18n: data */ title_key`: the window's title is a key its
|
|
3938
3985
|
host chose.
|
|
3939
3986
|
- What a gobj keeps in its `priv` is its own state, not what a caller hands:
|
|
3940
|
-
a path through the `priv` of a parameter is no position.
|
|
3987
|
+
a path through the `priv` of a parameter is no position. So is what is
|
|
3988
|
+
read from a parameter `gobj` (the convention of every gclass function):
|
|
3989
|
+
its attrs, `gobj_read_attr(gobj, "title")`, were set by whoever created it.
|
|
3990
|
+
- A parameter handed on through what NO position can name fails too (since
|
|
3991
|
+
`7.26.32`), unless it is marked where it is handed: a key transformed
|
|
3992
|
+
(`t(k.toLowerCase())`, `"prefix " + k`, a template with `${}`, a call of a
|
|
3993
|
+
helper that does not return it as it is), an iteration of
|
|
3994
|
+
`Object.entries(opts)`, a rest parameter walked (`rest.forEach(...)`),
|
|
3995
|
+
`arguments[i]` by a computed index, a part of a parameter that an array
|
|
3996
|
+
pattern destructures. Its callers' keys reach no reader, so either the key
|
|
3997
|
+
is handed on as it arrives -- and the function goes in the table -- or the
|
|
3998
|
+
hand-off is marked `/* i18n: data */` (or a list). The test names the
|
|
3999
|
+
function, the parameter and the line:
|
|
4000
|
+
|
|
4001
|
+
```js
|
|
4002
|
+
function caption(gobj, k) { return t(k.toLowerCase()); }
|
|
4003
|
+
```
|
|
4004
|
+
|
|
4005
|
+
```
|
|
4006
|
+
x.js:1 caption() hands its parameter [1] to a place a key is read through `k.toLowerCase()`,
|
|
4007
|
+
which no position can name: hand the key on as it arrives (the function then goes in
|
|
4008
|
+
the table), or mark it where it hands it
|
|
4009
|
+
```
|
|
4010
|
+
|
|
4011
|
+
It found four in the library itself: the column labels of a form's
|
|
4012
|
+
template in `build_html_form()` and `template2columns()`
|
|
4013
|
+
(`Object.entries(template)`: the host's schema, marked data), a label's key
|
|
4014
|
+
read back from its DOM (`name_form_control()` of `c_g6_nodes_tree.js`,
|
|
4015
|
+
marked data), and the message of `mark_field_validity()`, which mixes a key
|
|
4016
|
+
with the json field's own error (marked with its lists).
|
|
4017
|
+
- **The table is CORRECT, not only complete** (since `7.26.32`): the same
|
|
4018
|
+
search, started from NO table, must find every entry, at every position,
|
|
4019
|
+
with the same `exported`. An entry nothing forwards to -- a wrong position,
|
|
4020
|
+
a function that no longer hands it on -- fails, and so does an `exported`
|
|
4021
|
+
that disagrees with the module (it hides the calls of other modules). Up to
|
|
4022
|
+
`7.26.31` an extra entry passed every test. The check found two: an
|
|
4023
|
+
`exported: false` on a function its module exports (`create_floating_icon`),
|
|
4024
|
+
and `yui_selection_bar`'s `1.actions[].label`, true but invisible to the
|
|
4025
|
+
search, because the label travelled through a DOM property
|
|
4026
|
+
(`$b._yui_label`); the function now paints each label from the actions
|
|
4027
|
+
themselves, where the reader follows it.
|
|
3941
4028
|
|
|
3942
4029
|
Naming a function moves the marker to where the value ENTERS: its callers give
|
|
3943
4030
|
it a literal, a const, a position of their own, or a marker. The nav's items
|
|
@@ -3973,11 +4060,11 @@ that way. The same code with a `let` asks for neither.
|
|
|
3973
4060
|
export const MY_VIEW_I18N_KEYS = ['shape', 'radius', 'apply to'];
|
|
3974
4061
|
```
|
|
3975
4062
|
|
|
3976
|
-
The list is read as DATA, never run: `export const
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
4063
|
+
The list is read as DATA, never run: `export const`, or `const X = [...];
|
|
4064
|
+
export {X}` (or `export {x as X_I18N_KEYS}`), wrapped in `Object.freeze()` or
|
|
4065
|
+
not, each element a string literal, a template with no `${}`, or (since
|
|
4066
|
+
`7.26.29`) a SPREAD of another array of the same module read the same way -- a
|
|
4067
|
+
top-level `const`, which a list the module publishes is:
|
|
3981
4068
|
|
|
3982
4069
|
```js
|
|
3983
4070
|
const COMMON_KEYS = ['shape', 'radius'];
|
|
@@ -3989,16 +4076,31 @@ Anything named `*_I18N_KEYS` (the name in any letter case) that no consumer
|
|
|
3989
4076
|
can read **fails the build**, naming the file and the list, in the app's own
|
|
3990
4077
|
code too: an export that is not such an array (an element that is a variable,
|
|
3991
4078
|
a call, a template with `${}`, a spread of an import or of a `let`), a list
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
4079
|
+
declared with `let` or `var` (since `7.26.32`: it can be given other keys,
|
|
4080
|
+
which nobody reads), a list that is not exported, one declared inside a
|
|
4081
|
+
function or a block, one declared by destructuring (`export const
|
|
4082
|
+
{X_I18N_KEYS} = tables`), one exported under a name that does not end in
|
|
4083
|
+
`_I18N_KEYS`. Up to `7.26.27` the regex that read the lists dropped such a
|
|
4084
|
+
list in silence, and a key holding `]` dropped the whole array; up to
|
|
4085
|
+
`7.26.28` a spread of a const of the module was refused too.
|
|
4086
|
+
|
|
4087
|
+
**A published list is never MUTATED** (since `7.26.32`): it is read as it is
|
|
4088
|
+
WRITTEN, so a key it is given later is asked for by nobody. `X.push(k)`,
|
|
4089
|
+
`X.splice(i, 0, k)`, `X.unshift(k)`, `X.fill(k)`, `X[i] = k`, `X.length = n`,
|
|
4090
|
+
`Object.assign(X, ...)` and `delete X[i]` fail the build, in the module that
|
|
4091
|
+
publishes the list and in every module that imports it (under any name). Up
|
|
4092
|
+
to `7.26.31` an `export let` list was read and could be pushed into, and the
|
|
4093
|
+
pushed keys went unasked:
|
|
4094
|
+
|
|
4095
|
+
```js
|
|
4096
|
+
export let MY_VIEW_I18N_KEYS = ["shape"]; // fails: a published list is an export const
|
|
4097
|
+
MY_VIEW_I18N_KEYS.push("radius"); // fails: "radius" would be asked for by nobody
|
|
4098
|
+
```
|
|
3998
4099
|
|
|
3999
4100
|
**A MARKER says where the keys of a place come from.** It is a comment that
|
|
4000
|
-
stands right before the node it marks (only whitespace between
|
|
4001
|
-
a
|
|
4101
|
+
stands right before the node it marks (only whitespace between, and since
|
|
4102
|
+
`7.26.32` a parenthesis: `/* i18n: data */ (a || b)` marks `a || b`): an
|
|
4103
|
+
argument, a branch of one, a property value, or the whole call. Two kinds:
|
|
4002
4104
|
|
|
4003
4105
|
```js
|
|
4004
4106
|
yui_shell_show_error(shell, /* i18n: data */ comment || "print-tranger failed", {t: t});
|
|
@@ -4012,7 +4114,15 @@ confirm_then(gobj, /* i18n: C_YUI_FORM_I18N_KEYS */ kw.warning || "all changes w
|
|
|
4012
4114
|
above) are still read.
|
|
4013
4115
|
- `i18n: <NAME>_I18N_KEYS` (several by commas) -- the keys come from those
|
|
4014
4116
|
published lists. The keys of the marked expression that the reader CAN
|
|
4015
|
-
follow must be in them: a marker is a claim, and it is checked.
|
|
4117
|
+
follow must be in them: a marker is a claim, and it is checked. A key BUILT
|
|
4118
|
+
at run time is published that way and marked with its list -- gui_agent's
|
|
4119
|
+
monitor names a control's label `monitor ${control}`, and publishes the six
|
|
4120
|
+
keys that template builds in `C_AGENT_MONITOR_I18N_KEYS`. A template with
|
|
4121
|
+
`${}` under a list marker must have the SHAPE of some key of the lists
|
|
4122
|
+
(since `7.26.32`): `monitor ${control}` is checked against `^monitor .*$`,
|
|
4123
|
+
so a marker naming the wrong list fails. Every key of a published list is
|
|
4124
|
+
asked for, so a control whose key the list lacks is the one thing no check
|
|
4125
|
+
sees: the list sits next to the template, and a comment says so.
|
|
4016
4126
|
|
|
4017
4127
|
**A `data` marker is a claim too** (since `7.26.29`). On what the reader
|
|
4018
4128
|
follows to keys and nothing else -- a literal, a template with no `${}`, a
|
|
@@ -4033,6 +4143,31 @@ yui_shell_show_info(shell, /* i18n: data */ pick());
|
|
|
4033
4143
|
`/* i18n: data */ comment || "print-tranger failed"` stays legal: `comment` is
|
|
4034
4144
|
data, and the fallback is read anyway.
|
|
4035
4145
|
|
|
4146
|
+
Since `7.26.32` the claim is checked further:
|
|
4147
|
+
|
|
4148
|
+
- the call may be of a function IMPORTED from a module the reader reads (a
|
|
4149
|
+
file of the app, a module of the library), and the const may be imported:
|
|
4150
|
+
both are followed into their module, so `/* i18n: data */ pick()` fails
|
|
4151
|
+
there too;
|
|
4152
|
+
- a data marker on a call whose returns MIX keys with data fails: the reader
|
|
4153
|
+
does not read such a call (it reads a call only when it knows every
|
|
4154
|
+
return), so the marker would hide the key. Split the branches, so the key is
|
|
4155
|
+
handed where it is read and only the data is marked:
|
|
4156
|
+
|
|
4157
|
+
```js
|
|
4158
|
+
function label(kw) { return kw.ok? "accepted" : kw.comment; }
|
|
4159
|
+
yui_shell_show_info(shell, /* i18n: data */ label(kw)); // fails
|
|
4160
|
+
yui_shell_show_info(shell, /* i18n: data */ kw.comment || "accepted"); // the same, split
|
|
4161
|
+
```
|
|
4162
|
+
|
|
4163
|
+
The library had it twice: `refusal_text()` of the treedb views returned the
|
|
4164
|
+
backend's words or "print-tranger failed". It returns the words only now,
|
|
4165
|
+
and the call writes the fallback. Under a LIST marker such a call is
|
|
4166
|
+
checked, not refused: its keys are asked for and must be in the lists;
|
|
4167
|
+
- a data marker on an ARRAY OF STRING LITERALS fails: it is no DOM (a
|
|
4168
|
+
`createElement2` spec carries its attrs, an object, in its second slot), so
|
|
4169
|
+
the strings would be hidden.
|
|
4170
|
+
|
|
4036
4171
|
**A marked `let` (or `var`) is held to its marker.** A marker that names a list
|
|
4037
4172
|
used to let a `let` pass unread, whatever it held: a new literal branch on it
|
|
4038
4173
|
was neither asked for nor checked (REV-CLOUD V20). Now, when what a marker
|
|
@@ -4093,10 +4228,19 @@ would not carry what is pushed into it to the reader.
|
|
|
4093
4228
|
|
|
4094
4229
|
`validate-locales` checks every marker in what it scans, in an app's code too:
|
|
4095
4230
|
a comment that starts with `i18n:` and is no marker, a marker that stands
|
|
4096
|
-
before no place a key is read (a key position,
|
|
4231
|
+
before no place a key is read (a key position, a translator, an `i18n` or
|
|
4097
4232
|
`data-i18n*` value), a marker that names a list no module the app mounts
|
|
4098
|
-
publishes, a marked key that is not in the lists it names, a marked
|
|
4099
|
-
|
|
4233
|
+
publishes, a marked key that is not in the lists it names, a marked template
|
|
4234
|
+
with no key of its shape in them, a marked variable that only ever holds
|
|
4235
|
+
literals -- each one fails, with the file and the line. A marker that stands
|
|
4236
|
+
before no place says what it stands before, and why that is none (since
|
|
4237
|
+
`7.26.32`; it used to say only *"stands before no place a key is read"*):
|
|
4238
|
+
|
|
4239
|
+
```
|
|
4240
|
+
main.js:8: the i18n marker stands before `1;`, the value a variable is DECLARED with: mark it
|
|
4241
|
+
where the variable is handed to a place a key is read. A marker marks the value it stands
|
|
4242
|
+
right before, where a key is read: ...
|
|
4243
|
+
```
|
|
4100
4244
|
|
|
4101
4245
|
**The rule is per CALL, in the library and in the app.**
|
|
4102
4246
|
`src/i18n_key_functions.test.js` reads every module of the library with the
|
|
@@ -4123,7 +4267,11 @@ src/main.js:12: yui_shell_confirm_yesno() [2.title] is given opts, which the rea
|
|
|
4123
4267
|
|
|
4124
4268
|
A TRANSLATED text handed to a key position fails even when it is marked: the
|
|
4125
4269
|
function translates it again and marks it `data-i18n` with the translation,
|
|
4126
|
-
so it never changes language. Hand it the key
|
|
4270
|
+
so it never changes language. Hand it the key. A translated text is the value
|
|
4271
|
+
of any TRANSLATOR (since `7.26.32`; up to `7.26.31` only a call named `t`, so
|
|
4272
|
+
`tr("save")`, an alias of t, `t?.()` or `t.call()` passed marked -- and an
|
|
4273
|
+
unmarked `tr()` failed with *"cannot follow"*, whose advice was the marker that
|
|
4274
|
+
then let it pass):
|
|
4127
4275
|
|
|
4128
4276
|
```js
|
|
4129
4277
|
yui_install_ask_once(shell, {t: t, message: t("install this app")}); // fails
|
|
@@ -4133,7 +4281,7 @@ yui_install_ask_once(shell, {t: t, message: "install this app"}); // the ke
|
|
|
4133
4281
|
```
|
|
4134
4282
|
src/c_app.js:734 (call at line 732): yui_install_ask_once() [1.message] is given t("install this app"):
|
|
4135
4283
|
a TRANSLATED text where a KEY goes (translated again and marked data-i18n with the translation,
|
|
4136
|
-
it never changes language): hand
|
|
4284
|
+
it never changes language, and no marker excuses it): hand the key, not t(key)
|
|
4137
4285
|
```
|
|
4138
4286
|
|
|
4139
4287
|
In an app, what a wrapper of its own hands on is marked where it hands it:
|
|
@@ -4154,10 +4302,11 @@ module. The same test fails when a marker is not one
|
|
|
4154
4302
|
or stands nowhere; when a marker names a list that is not published by its
|
|
4155
4303
|
module or by one it imports (a consumer would not read it); when a marked key
|
|
4156
4304
|
the reader can follow is not in the list; when a marked variable only ever
|
|
4157
|
-
holds literals; when a list is not readable, holds a key that is
|
|
4158
|
-
lower-case ASCII, holds one twice, or holds one written nowhere else in
|
|
4159
|
-
module (stale); when an entry of the table names a function its module
|
|
4160
|
-
not declare.
|
|
4305
|
+
holds literals; when a list is not readable, is mutated, holds a key that is
|
|
4306
|
+
not lower-case ASCII, holds one twice, or holds one written nowhere else in
|
|
4307
|
+
its module (stale); when an entry of the table names a function its module
|
|
4308
|
+
does not declare, or (since `7.26.32`) a position the search for forwarders
|
|
4309
|
+
does not find.
|
|
4161
4310
|
|
|
4162
4311
|
**Every key of every list is PINNED**: dropping it from its list fails a test,
|
|
4163
4312
|
or loses nothing. For each key, one of these holds, or the test fails with
|
|
@@ -4201,19 +4350,41 @@ the node graph's key-taking helpers from its syntax tree, and
|
|
|
4201
4350
|
`yui_dev_controls.test.js` builds the Developer window and compares every key
|
|
4202
4351
|
it asks for or carries with the list.
|
|
4203
4352
|
|
|
4204
|
-
**What
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
`
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4353
|
+
**What stays INVISIBLE** -- read by no check, failing nothing; found only by
|
|
4354
|
+
reading the page in another language:
|
|
4355
|
+
|
|
4356
|
+
- a key handed to a translator, an `i18n` or a `data-i18n*` value by an
|
|
4357
|
+
UNMARKED `let`, a call the reader does not follow (a recursion, one whose
|
|
4358
|
+
returns mix keys and data, a function of a package) or a computed string:
|
|
4359
|
+
a translator is not a key function, and only the positions of
|
|
4360
|
+
`I18N_KEY_FUNCTIONS` are held to the per-call rule -- in the library and in
|
|
4361
|
+
an app alike. (A PARAMETER is not, in the library: the forwarder test puts
|
|
4362
|
+
its function in the table, or demands a marker, also when no position can
|
|
4363
|
+
name it.);
|
|
4364
|
+
- a translator the reader does not know as one: a name other than `t` / `tr`
|
|
4365
|
+
that no const or import makes an alias of -- a parameter `translate`, a
|
|
4366
|
+
`let` alias, `opts.translate(k)`, `i18next.getFixedT()`;
|
|
4367
|
+
- a key function reached through a parameter (`apply(fn)` calling
|
|
4368
|
+
`fn(shell, "k")`), a `let` given more than one function, a map in a `let`,
|
|
4369
|
+
a computed member (`API[name](...)`), or `.apply()` of an array the source
|
|
4370
|
+
does not write out;
|
|
4371
|
+
- a `data-i18n*` attribute written through an alias of `dataset`
|
|
4372
|
+
(`const ds = el.dataset; ds.i18nTitle = k`), by `Object.assign()` into it,
|
|
4373
|
+
or named by a `let`;
|
|
4374
|
+
- what is written INTO a `const` table after its declaration
|
|
4375
|
+
(`TABLE.k = "k"`): the reader follows a const to its value, and only a
|
|
4376
|
+
marked `let` is followed into what is written into it (a published list
|
|
4377
|
+
that is written into fails: above);
|
|
4378
|
+
- what a module of a package exports (gobj-js, i18next), and an exported
|
|
4379
|
+
`let`;
|
|
4380
|
+
- in the library's forwarder search, a key stored in a heap object or a DOM
|
|
4381
|
+
node and read back somewhere else (`$b._yui_label` was one), and what a
|
|
4382
|
+
caller puts in a gobj's attrs (a window's `title` given at `gobj_create()`);
|
|
4383
|
+
- in an app, a key its callers hand a wrapper of its own reaches the locales
|
|
4384
|
+
only through a list the module publishes: the wrapper's hand-off must be
|
|
4385
|
+
marked (the rule per call), and nothing ties its callers' literals to the
|
|
4386
|
+
list -- nor a key built at run time (a template) to the list its marker
|
|
4387
|
+
names, beyond the shape of the template.
|
|
4217
4388
|
|
|
4218
4389
|
**What fails the build, besides a key no locale defines:**
|
|
4219
4390
|
|
|
@@ -4224,9 +4395,12 @@ callers' literals to the list.
|
|
|
4224
4395
|
- a locale that looks like one and exports no `{<code>}` with a
|
|
4225
4396
|
`translation` dict;
|
|
4226
4397
|
- a source file that cannot be parsed;
|
|
4227
|
-
- a published list no consumer can read (above)
|
|
4228
|
-
|
|
4229
|
-
|
|
4398
|
+
- a published list no consumer can read (above), declared with `let` or
|
|
4399
|
+
`var`, or mutated;
|
|
4400
|
+
- a marker that is wrong (above): a `data` marker on what the reader follows
|
|
4401
|
+
to keys, or on what would hide a key (a call mixing keys and data, an array
|
|
4402
|
+
of string literals), a list marker on a template whose shape no key of the
|
|
4403
|
+
list has;
|
|
4230
4404
|
- a key position of a key function, in the app's own code, given what the
|
|
4231
4405
|
reader cannot follow and unmarked, or given a translated text (the rule per
|
|
4232
4406
|
call, above).
|