xonecode 0.28.0 → 0.31.0
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/agent/dispositivos/recargaEnAparato.js +46 -5
- package/dist/agent/dispositivos/recargaEnAparato.js.map +1 -1
- package/dist/agent/grafo/validarFicheroXone.js +114 -0
- package/dist/agent/grafo/validarFicheroXone.js.map +1 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js +49 -8
- package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
- package/dist/agent/turno/resumenDeTool.js +2 -0
- package/dist/agent/turno/resumenDeTool.js.map +1 -1
- package/dist/core/contextos.js +20 -0
- package/dist/core/contextos.js.map +1 -1
- package/dist/core/cssBienFormado.js +97 -0
- package/dist/core/cssBienFormado.js.map +1 -0
- package/dist/core/jsParaRhino.js +93 -0
- package/dist/core/jsParaRhino.js.map +1 -0
- package/dist/core/notify.js +2 -0
- package/dist/core/notify.js.map +1 -1
- package/dist/core/recargaEnCaliente.js +16 -8
- package/dist/core/recargaEnCaliente.js.map +1 -1
- package/dist/core/xmlBienFormado.js +206 -0
- package/dist/core/xmlBienFormado.js.map +1 -0
- package/package.json +2 -1
- package/skills/xone-hotswap/SKILL.md +3 -2
- package/skills/xone-hotswap/references/comandos.md +17 -1
- package/skills/xone-hotswap/scripts/xone-recargar-android +36 -3
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
* en memoria, y por eso se sube también a disco — sin eso,
|
|
10
10
|
* relanzar la app la devuelve a la versión anterior.
|
|
11
11
|
* JavaScript (`.js`) → `uploadFile` + `loadIncludeFile` con `compile: true`.
|
|
12
|
-
* CSS
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* CSS (`.css`) → `uploadFile` + `runScript` con `appData.unloadCssFile` y
|
|
13
|
+
* `appData.loadCssFile` + `refresh` (idea suya, medido: el
|
|
14
|
+
* color cambia sin relanzar). Si el script falla, se relanza.
|
|
15
|
+
* `.ini`, `app.xml`, un `.xne` sin colección (mappings)
|
|
16
|
+
* → `uploadFile` y se RELANZA la app, que es lo único que los
|
|
17
|
+
* relee.
|
|
16
18
|
* todo lo demás (iconos, `bd/`, `files/`) → no se recarga: lo lleva el despliegue entero.
|
|
17
19
|
*
|
|
18
|
-
* **Relanzar
|
|
19
|
-
*
|
|
20
|
+
* **Relanzar SÍ se hace solo** (lo pidió así: lo guardado tiene que verse): el precio, que la app
|
|
21
|
+
* vuelve a su pantalla de inicio, lo dice la frase.
|
|
20
22
|
*/
|
|
21
23
|
import { decodificarComoTexto, esUtf8Valido, tablaDeLosBytes } from "./codificacion.js";
|
|
22
24
|
/** Las extensiones que el aparato sabe tomar sueltas. Las mismas del script. */
|
|
@@ -43,6 +45,8 @@ export function claseDeRecarga(ruta, bytes) {
|
|
|
43
45
|
return "no-aplica";
|
|
44
46
|
if (ext === ".js")
|
|
45
47
|
return "js";
|
|
48
|
+
if (ext === ".css")
|
|
49
|
+
return "css";
|
|
46
50
|
if (ext === ".xne") {
|
|
47
51
|
let cabeza = "";
|
|
48
52
|
for (const b of bytes)
|
|
@@ -88,11 +92,15 @@ export function textoDeRecarga(r) {
|
|
|
88
92
|
case "aplicada":
|
|
89
93
|
return r.clase === "js"
|
|
90
94
|
? "Aparato: JavaScript recargado; la app sigue viva"
|
|
91
|
-
:
|
|
95
|
+
: r.clase === "css"
|
|
96
|
+
? "Aparato: estilos recargados en caliente; la app sigue viva"
|
|
97
|
+
: "Aparato: pantalla recargada en caliente; la app sigue viva";
|
|
92
98
|
case "relanzar":
|
|
93
99
|
return "Aparato: subido; para verlo hay que relanzar la app";
|
|
94
100
|
case "relanzada":
|
|
95
|
-
return "
|
|
101
|
+
return r.clase === "relanzar" || r.clase === "css"
|
|
102
|
+
? "Aparato: cambios aplicados relanzando la app (vuelve a su pantalla de inicio)"
|
|
103
|
+
: "Aparato: app relanzada y viva";
|
|
96
104
|
case "sin-app":
|
|
97
105
|
// El motivo, si se sabe: «no hay aparato elegido» y «no está en la medida» no se arreglan
|
|
98
106
|
// en el mismo sitio que «la app no corre».
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recargaEnCaliente.js","sourceRoot":"","sources":["../../src/core/recargaEnCaliente.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"recargaEnCaliente.js","sourceRoot":"","sources":["../../src/core/recargaEnCaliente.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ¿Está bien formado este XML? Puro, sin librerías y sin llamar a nadie.
|
|
3
|
+
*
|
|
4
|
+
* Existe por un turno real (soporte de APPSalud): la persona pegó el error del parser de Studio
|
|
5
|
+
* («'name' is an unexpected token. The expected token is '='. Line 381, position 4») y el agente,
|
|
6
|
+
* sin forma de comprobarlo, revisó el fichero a ojo durante minutos — tenía razón a los dos
|
|
7
|
+
* minutos («está bien formado») y no se lo creyó. Esto contesta la pregunta con un sí o con la
|
|
8
|
+
* línea y la columna, como un parser.
|
|
9
|
+
*
|
|
10
|
+
* Solo la FORMA del XML: etiquetas que abren y cierran en orden, atributos con su `=` y su valor
|
|
11
|
+
* entre comillas, sin repetir, separados por blancos; comentarios (sin `--` dentro), CDATA,
|
|
12
|
+
* instrucciones `<?…?>`, entidades, una sola raíz. **No** sabe nada de XOne: un atributo que XOne
|
|
13
|
+
* no conoce está bien formado (para eso, `xone_atributos`).
|
|
14
|
+
*/
|
|
15
|
+
const ENTIDADES = new Set(["amp", "lt", "gt", "quot", "apos"]);
|
|
16
|
+
/** Primer carácter de un nombre XML (aproximado a lo que usa un proyecto XOne, con Unicode). */
|
|
17
|
+
const INICIO_DE_NOMBRE = /[A-Za-z_:À-]/;
|
|
18
|
+
const RESTO_DE_NOMBRE = /[A-Za-z0-9_:.\-·À-]/;
|
|
19
|
+
export function comprobarXml(entrada) {
|
|
20
|
+
const texto = entrada.startsWith("") ? entrada.slice(1) : entrada;
|
|
21
|
+
let i = 0;
|
|
22
|
+
/** Línea y columna (desde 1) de una posición. */
|
|
23
|
+
const donde = (pos) => {
|
|
24
|
+
let linea = 1;
|
|
25
|
+
let inicio = 0;
|
|
26
|
+
for (let k = 0; k < pos && k < texto.length; k++) {
|
|
27
|
+
if (texto[k] === "\n") {
|
|
28
|
+
linea += 1;
|
|
29
|
+
inicio = k + 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { linea, columna: pos - inicio + 1 };
|
|
33
|
+
};
|
|
34
|
+
const fallo = (pos, motivo) => ({ ok: false, ...donde(pos), motivo });
|
|
35
|
+
const blanco = (c) => c === " " || c === "\t" || c === "\n" || c === "\r";
|
|
36
|
+
const saltarBlancos = () => {
|
|
37
|
+
while (blanco(texto[i]))
|
|
38
|
+
i++;
|
|
39
|
+
};
|
|
40
|
+
const leerNombre = () => {
|
|
41
|
+
const desde = i;
|
|
42
|
+
if (i < texto.length && INICIO_DE_NOMBRE.test(texto[i])) {
|
|
43
|
+
i++;
|
|
44
|
+
while (i < texto.length && RESTO_DE_NOMBRE.test(texto[i]))
|
|
45
|
+
i++;
|
|
46
|
+
}
|
|
47
|
+
return texto.slice(desde, i);
|
|
48
|
+
};
|
|
49
|
+
/** Una entidad que empieza en `pos` (un `&`). Devuelve el motivo si no vale. */
|
|
50
|
+
const entidadMala = (pos) => {
|
|
51
|
+
const fin = texto.indexOf(";", pos);
|
|
52
|
+
const cuerpo = fin < 0 ? "" : texto.slice(pos + 1, fin);
|
|
53
|
+
if (fin < 0 || fin - pos > 12 || !/^#?[A-Za-z0-9]+$/.test(cuerpo))
|
|
54
|
+
return "un «&» suelto: escríbelo «&»";
|
|
55
|
+
if (/^#[0-9]+$/.test(cuerpo) || /^#x[0-9A-Fa-f]+$/.test(cuerpo) || ENTIDADES.has(cuerpo))
|
|
56
|
+
return undefined;
|
|
57
|
+
return `entidad desconocida «&${cuerpo};»: en XML solo valen & < > " ' y las numéricas`;
|
|
58
|
+
};
|
|
59
|
+
const abiertas = [];
|
|
60
|
+
let raices = 0;
|
|
61
|
+
while (i < texto.length) {
|
|
62
|
+
const c = texto[i];
|
|
63
|
+
if (c !== "<") {
|
|
64
|
+
if (c === "&") {
|
|
65
|
+
const mala = entidadMala(i);
|
|
66
|
+
if (mala !== undefined)
|
|
67
|
+
return fallo(i, mala);
|
|
68
|
+
}
|
|
69
|
+
else if (abiertas.length === 0 && !blanco(c)) {
|
|
70
|
+
return fallo(i, raices === 0 ? "hay texto antes del elemento raíz" : "hay texto después de cerrar el elemento raíz");
|
|
71
|
+
}
|
|
72
|
+
i++;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
// Comentario.
|
|
76
|
+
if (texto.startsWith("<!--", i)) {
|
|
77
|
+
const fin = texto.indexOf("-->", i + 4);
|
|
78
|
+
if (fin < 0)
|
|
79
|
+
return fallo(i, "un comentario «<!--» que no se cierra con «-->»");
|
|
80
|
+
const dobleGuion = texto.indexOf("--", i + 4);
|
|
81
|
+
if (dobleGuion >= 0 && dobleGuion < fin)
|
|
82
|
+
return fallo(dobleGuion, "«--» dentro de un comentario: XML no lo admite");
|
|
83
|
+
i = fin + 3;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
// CDATA.
|
|
87
|
+
if (texto.startsWith("<![CDATA[", i)) {
|
|
88
|
+
if (abiertas.length === 0)
|
|
89
|
+
return fallo(i, "un bloque CDATA fuera del elemento raíz");
|
|
90
|
+
const fin = texto.indexOf("]]>", i + 9);
|
|
91
|
+
if (fin < 0)
|
|
92
|
+
return fallo(i, "un «<![CDATA[» que no se cierra con «]]>»");
|
|
93
|
+
i = fin + 3;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
// DOCTYPE: se salta entero, hasta su «>».
|
|
97
|
+
if (texto.startsWith("<!DOCTYPE", i)) {
|
|
98
|
+
const fin = texto.indexOf(">", i);
|
|
99
|
+
if (fin < 0)
|
|
100
|
+
return fallo(i, "un «<!DOCTYPE» sin cerrar");
|
|
101
|
+
i = fin + 1;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Instrucción de proceso (el prólogo `<?xml …?>`).
|
|
105
|
+
if (texto.startsWith("<?", i)) {
|
|
106
|
+
const fin = texto.indexOf("?>", i + 2);
|
|
107
|
+
if (fin < 0)
|
|
108
|
+
return fallo(i, "un «<?» que no se cierra con «?>»");
|
|
109
|
+
i = fin + 2;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
// Cierre.
|
|
113
|
+
if (texto.startsWith("</", i)) {
|
|
114
|
+
const pos = i;
|
|
115
|
+
i += 2;
|
|
116
|
+
const nombre = leerNombre();
|
|
117
|
+
if (nombre === "")
|
|
118
|
+
return fallo(i, "falta el nombre de la etiqueta tras «</»");
|
|
119
|
+
saltarBlancos();
|
|
120
|
+
if (texto[i] !== ">")
|
|
121
|
+
return fallo(i, `se esperaba «>» para cerrar «</${nombre}»`);
|
|
122
|
+
const abierta = abiertas.pop();
|
|
123
|
+
if (abierta === undefined)
|
|
124
|
+
return fallo(pos, `«</${nombre}>» cierra algo que no está abierto`);
|
|
125
|
+
if (abierta.nombre !== nombre) {
|
|
126
|
+
const { linea } = donde(abierta.pos);
|
|
127
|
+
return fallo(pos, `«</${nombre}>» no cierra la etiqueta abierta, que es «<${abierta.nombre}>» (línea ${linea})`);
|
|
128
|
+
}
|
|
129
|
+
i++;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
// Apertura.
|
|
133
|
+
const pos = i;
|
|
134
|
+
i++;
|
|
135
|
+
const nombre = leerNombre();
|
|
136
|
+
if (nombre === "")
|
|
137
|
+
return fallo(i, "un «<» que no empieza ninguna etiqueta: si es texto, escríbelo «<»");
|
|
138
|
+
if (abiertas.length === 0) {
|
|
139
|
+
raices += 1;
|
|
140
|
+
if (raices > 1)
|
|
141
|
+
return fallo(pos, `un segundo elemento raíz «<${nombre}>»: un XML solo tiene una raíz`);
|
|
142
|
+
}
|
|
143
|
+
const vistos = new Set();
|
|
144
|
+
for (;;) {
|
|
145
|
+
const antes = i;
|
|
146
|
+
saltarBlancos();
|
|
147
|
+
const c2 = texto[i];
|
|
148
|
+
if (c2 === undefined)
|
|
149
|
+
return fallo(pos, `la etiqueta «<${nombre}» no se cierra`);
|
|
150
|
+
if (c2 === ">") {
|
|
151
|
+
abiertas.push({ nombre, pos });
|
|
152
|
+
i++;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
if (c2 === "/") {
|
|
156
|
+
if (texto[i + 1] !== ">")
|
|
157
|
+
return fallo(i, "se esperaba «/>»");
|
|
158
|
+
i += 2;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
if (i === antes)
|
|
162
|
+
return fallo(i, `falta un espacio antes del atributo, en «<${nombre}»`);
|
|
163
|
+
const posAtributo = i;
|
|
164
|
+
const atributo = leerNombre();
|
|
165
|
+
if (atributo === "")
|
|
166
|
+
return fallo(i, `carácter inesperado «${c2}» dentro de «<${nombre}»`);
|
|
167
|
+
saltarBlancos();
|
|
168
|
+
if (texto[i] !== "=") {
|
|
169
|
+
// El caso del soporte: un atributo sin su `=` (el .NET de Studio lo dice al revés: el
|
|
170
|
+
// token que encuentra donde esperaba el `=`).
|
|
171
|
+
return fallo(i, `al atributo «${atributo}» le falta el «=» y su valor`);
|
|
172
|
+
}
|
|
173
|
+
i++;
|
|
174
|
+
saltarBlancos();
|
|
175
|
+
const comilla = texto[i];
|
|
176
|
+
if (comilla !== '"' && comilla !== "'")
|
|
177
|
+
return fallo(i, `el valor del atributo «${atributo}» tiene que ir entre comillas`);
|
|
178
|
+
const fin = texto.indexOf(comilla, i + 1);
|
|
179
|
+
if (fin < 0)
|
|
180
|
+
return fallo(i, `el valor del atributo «${atributo}» no cierra su comilla`);
|
|
181
|
+
for (let k = i + 1; k < fin; k++) {
|
|
182
|
+
if (texto[k] === "<")
|
|
183
|
+
return fallo(k, `un «<» dentro del valor de «${atributo}»: escríbelo «<»`);
|
|
184
|
+
if (texto[k] === "&") {
|
|
185
|
+
const mala = entidadMala(k);
|
|
186
|
+
if (mala !== undefined)
|
|
187
|
+
return fallo(k, mala);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (vistos.has(atributo))
|
|
191
|
+
return fallo(posAtributo, `el atributo «${atributo}» está repetido en «<${nombre}»`);
|
|
192
|
+
vistos.add(atributo);
|
|
193
|
+
i = fin + 1;
|
|
194
|
+
if (!blanco(texto[i]) && texto[i] !== ">" && texto[i] !== "/" && texto[i] !== undefined) {
|
|
195
|
+
return fallo(i, `falta un espacio entre el atributo «${atributo}» y lo que sigue`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const abierta = abiertas.pop();
|
|
200
|
+
if (abierta !== undefined)
|
|
201
|
+
return fallo(abierta.pos, `«<${abierta.nombre}>» se abre y no se cierra antes de que acabe el fichero`);
|
|
202
|
+
if (raices === 0)
|
|
203
|
+
return fallo(texto.length, "no hay ningún elemento raíz");
|
|
204
|
+
return { ok: true };
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=xmlBienFormado.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xmlBienFormado.js","sourceRoot":"","sources":["../../src/core/xmlBienFormado.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xonecode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "Consola CLI y harness de agente para desarrollar aplicaciones XOne",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"@langchain/openai": "1.5.5",
|
|
47
47
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
48
48
|
"@truefoundry/trueforge-core": "0.2.1",
|
|
49
|
+
"acorn": "^8.19.0",
|
|
49
50
|
"better-sqlite3": "13.0.3",
|
|
50
51
|
"deepagents": "^1.14.0",
|
|
51
52
|
"fflate": "^0.8.3",
|
|
@@ -107,7 +107,8 @@ xone-desplegar-android --app MiApp --serie emulator-5554
|
|
|
107
107
|
# «cambié un botón / una función / un color»: NO despliegues entero. Compara el proyecto con el
|
|
108
108
|
# aparato, sube SOLO lo que difiere y lo aplica por la vía más barata (1-2 s si es una colección):
|
|
109
109
|
# colección (.xne) → recarga en caliente JavaScript (.js) → recarga del include
|
|
110
|
-
# CSS
|
|
110
|
+
# CSS (.css) → recarga en caliente (loadCssFile; en frameworks viejos, por runScript)
|
|
111
|
+
# app.xml, app.ini, mappings → relanza la app (unos 6 s)
|
|
111
112
|
# Necesita la app YA desplegada. Lo que no sabe aplicar (iconos, bd) lo dice y manda a desplegar.
|
|
112
113
|
xone-recargar-android
|
|
113
114
|
xone-recargar-android MenuPrincipal.xne functions.js # solo esos, sin comparar
|
|
@@ -246,7 +247,7 @@ Detalle de despliegue, relanzado y endpoints de fichero: [conexión y despliegue
|
|
|
246
247
|
| Tocar (`click`, `tap`, `doubleTap`, `longPress`, `openSelector`, `fill`, `clear`, `scroll`, `pressKey`) | sí | **sí**, con desviaciones (abajo) |
|
|
247
248
|
| Ciclo de app (`launchApplication`, `exitApplication`, `directdownload`) | sí | `launchApplication` y `directdownload` sí; `exitApplication` no |
|
|
248
249
|
| Atributos y colecciones (`setAttribute`, `deleteAttribute`, `loadCollection`) | sí | sí |
|
|
249
|
-
| CSS, `replaceProperty`, `refresh`, `relayout`, `loadIncludeFile` | sí | **no** |
|
|
250
|
+
| CSS (`setCssAttribute`, `loadCssFile`/`unloadCssFile`), `replaceProperty`, `refresh`, `relayout`, `loadIncludeFile` | sí | **no** |
|
|
250
251
|
| Ficheros (`/file_upload`, `/file_download`, `uploadFile`, `getFileChecksum`) | sí | **no** (`listappfiles` sí) |
|
|
251
252
|
| Scripts y SQL (`runScript`, `runSql`, `getDatabaseTableNames`, `queryDatabaseTable`) | sí | **no** |
|
|
252
253
|
| Logs (`getLog`, `*DeviceLogging`, `setLog*`) | sí | **no** |
|
|
@@ -81,6 +81,7 @@ por los dos canales.
|
|
|
81
81
|
| `deleteAttribute` | sí | sí | **solo WS** |
|
|
82
82
|
| `replaceProperty` | sí | — | — |
|
|
83
83
|
| `setCssAttribute` / `deleteCssAttribute` | sí | — | — |
|
|
84
|
+
| `loadCssFile` / `unloadCssFile` (desde 5.0.5.7dev) | sí | — | — |
|
|
84
85
|
| `refresh` / `relayout` | sí | — | — |
|
|
85
86
|
| `status` / `state` | sí | sí | **solo WS** |
|
|
86
87
|
| `uploadFile` | sí | — | — |
|
|
@@ -542,7 +543,8 @@ Carga o recarga una colección XML en caliente. **Entrada:** `xmlNode` (XML en *
|
|
|
542
543
|
|---|---|---|
|
|
543
544
|
| Colección `.xne` | `loadCollection` con el fichero entero en Base64 y `encoding=UTF-8` | Se repinta en ~2 s, **solo en memoria**: al relanzar la app vuelve la versión de disco. Para que persista, subir también el fichero con `uploadFile`. |
|
|
544
545
|
| JavaScript | `uploadFile` y luego `loadIncludeFile` con `compile=true` | Se aplica al instante. Solo subirlo, o `loadCollection`, **no** lo recarga. |
|
|
545
|
-
| CSS | `uploadFile` y luego `
|
|
546
|
+
| CSS (5.0.5.7dev en adelante) | `uploadFile` y luego `loadCssFile` con `fileName` | Se aplica al instante (medido: ~50 ms), **sin relanzar ni `refresh`**: sustituye la hoja en su sitio de la cascada y relayouta. |
|
|
547
|
+
| CSS (antes de 5.0.5.7dev, donde `loadCssFile` es `Unknown command`) | `uploadFile`, `runScript` con `appData.unloadCssFile(n); appData.loadCssFile(n, enc); return "ok";` y luego `refresh` | Se aplica sin relanzar. **Sin el `refresh` no se ve**: el cambio entra en el siguiente pintado. `setCssAttribute`, `relayout`, `refresh` y `loadCollection` solos contestan `result:true` y el color **no cambia**; `loadIncludeFile` no admite css (`Unknown script language css`). |
|
|
546
548
|
|
|
547
549
|
`uploadFile`: `destinationPath` cuelga del directorio de datos del framework, no del de la app.
|
|
548
550
|
La app vive en `app_<nombre en minúsculas>/`, así que hay que dar `app_holamundo/functions.js`; con
|
|
@@ -567,6 +569,20 @@ relayout o refresh según el atributo. **(iOS)** también es legado: solo WebSoc
|
|
|
567
569
|
### `setCssAttribute` / `deleteCssAttribute` — solo Android
|
|
568
570
|
`fileName`, `className`, `attributeName` (+ `attributeValue` en el set).
|
|
569
571
|
|
|
572
|
+
### `loadCssFile` / `unloadCssFile` — solo Android, desde 5.0.5.7dev
|
|
573
|
+
`loadCssFile`: `fileName` (sí), `encoding` (no, `UTF-8`), `conditions` (no, vacío = siempre),
|
|
574
|
+
`strictMode` (no, `false`). Carga una hoja que **ya está en el dispositivo** (súbela antes con
|
|
575
|
+
`uploadFile`), como un `<style>` del `<app>`, y relayouta las ventanas visibles. Si ya estaba cargada
|
|
576
|
+
con las mismas `conditions`, la **sustituye** en su sitio: así se aplica una hoja recién subida, sin
|
|
577
|
+
`unloadCssFile` antes. `unloadCssFile`: `fileName` (sí); quita la hoja y relayouta; una que no está
|
|
578
|
+
cargada responde éxito.
|
|
579
|
+
|
|
580
|
+
**Medido (5.0.5.7dev, emulador):** `uploadFile` + `loadCssFile fileName=default-colors.css` cambia el
|
|
581
|
+
color de un botón en ~50 ms, sin relanzar. Un nombre que no existe: `result:false` con
|
|
582
|
+
`FileNotFoundException`. Sin app cargada contestan `App is not running` en `status`. En 5.0.5.5dev el
|
|
583
|
+
comando no existe (`Unknown command: loadCssFile`): ahí, las funciones de XOne por `runScript` + `refresh`
|
|
584
|
+
(tabla de arriba).
|
|
585
|
+
|
|
570
586
|
### `refresh` / `relayout` — solo Android
|
|
571
587
|
En iOS las ramas existen en el dispatcher pero están **vacías**: no hacen nada.
|
|
572
588
|
|
|
@@ -13,9 +13,13 @@
|
|
|
13
13
|
* devuelve a la versión anterior.
|
|
14
14
|
* JavaScript (.js) → `loadIncludeFile` con compile=true. Subir el fichero NO basta,
|
|
15
15
|
* y `loadCollection` tampoco lo recarga.
|
|
16
|
-
* CSS
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* CSS (.css) → el comando `loadCssFile` (framework 5.0.5.7dev en adelante): la
|
|
17
|
+
* sustituye y relayouta solo. En uno anterior, que contesta
|
|
18
|
+
* `Unknown command`, `runScript` con `appData.unloadCssFile` +
|
|
19
|
+
* `appData.loadCssFile` y un `refresh`. Medidos los dos: el color
|
|
20
|
+
* cambia SIN relanzar. Lo que no sirve, también medido:
|
|
21
|
+
* `setCssAttribute`, `relayout`, `refresh` o `loadCollection` solos.
|
|
22
|
+
* .ini, app.xml, mappings → relanzar la app (`launchApplication`): solo se leen al cargarla.
|
|
19
23
|
*
|
|
20
24
|
* **`result:true` es «aceptado», no «aplicado».** Lo que dice si funcionó es el árbol de
|
|
21
25
|
* controles, y por eso el script lo pide al acabar. Un atributo que XOne no conoce tampoco da
|
|
@@ -202,6 +206,7 @@ if (cambiados.length === 0) {
|
|
|
202
206
|
function clase(rel) {
|
|
203
207
|
const ext = extname(rel).toLowerCase();
|
|
204
208
|
if (ext === ".js") return "js";
|
|
209
|
+
if (ext === ".css") return "css";
|
|
205
210
|
if (ext === ".xne") return /<coll[\s>]/.test(readFileSync(rel, "latin1")) ? "coleccion" : "relanzar";
|
|
206
211
|
return "relanzar";
|
|
207
212
|
}
|
|
@@ -248,6 +253,7 @@ for (const rel of cambiados) {
|
|
|
248
253
|
const clases = new Map(subidos.map((f) => [f, clase(f)]));
|
|
249
254
|
const hayQueRelanzar = [...clases.values()].includes("relanzar");
|
|
250
255
|
const fallos = [];
|
|
256
|
+
let necesitaRefresh = false;
|
|
251
257
|
|
|
252
258
|
if (hayQueRelanzar) {
|
|
253
259
|
const r = mandar("launchApplication", { appName: app });
|
|
@@ -263,12 +269,39 @@ if (hayQueRelanzar) {
|
|
|
263
269
|
const r = mandar("loadCollection", { xmlNode: xmlEnUtf8(readFileSync(f)).toString("base64"), encoding: "UTF-8" });
|
|
264
270
|
if (r.result !== true) fallos.push(`${f}: loadCollection ${r.exceptionMessage ?? r.status ?? "sin motivo"}`);
|
|
265
271
|
else console.log(` ${f} → colección recargada en caliente`);
|
|
272
|
+
} else if (c === "css") {
|
|
273
|
+
// La codificación de SUS bytes: `loadCssFile` asume UTF-8 si no se le dice.
|
|
274
|
+
let tabla = "UTF-8";
|
|
275
|
+
try {
|
|
276
|
+
new TextDecoder("utf-8", { fatal: true }).decode(readFileSync(f));
|
|
277
|
+
} catch {
|
|
278
|
+
tabla = "windows-1252";
|
|
279
|
+
}
|
|
280
|
+
const nativo = mandar("loadCssFile", { fileName: f, encoding: tabla });
|
|
281
|
+
if (nativo.result === true) {
|
|
282
|
+
console.log(` ${f} → estilos recargados en caliente`);
|
|
283
|
+
} else if (/Unknown command/i.test(String(nativo.exceptionMessage ?? nativo.status ?? ""))) {
|
|
284
|
+
// Framework anterior a 5.0.5.7dev: las mismas funciones de XOne, por `runScript`, y un
|
|
285
|
+
// `refresh` (abajo) para que se pinte.
|
|
286
|
+
const script = `appData.unloadCssFile(${JSON.stringify(f)}); appData.loadCssFile(${JSON.stringify(f)}, ${JSON.stringify(tabla)}); return "ok";`;
|
|
287
|
+
const r = mandar("runScript", { scriptLanguage: "javascript", scriptText: Buffer.from(script, "utf8").toString("base64") });
|
|
288
|
+
if (r.result !== true) fallos.push(`${f}: loadCssFile ${r.exceptionMessage ?? r.status ?? "sin motivo"}`);
|
|
289
|
+
else {
|
|
290
|
+
necesitaRefresh = true;
|
|
291
|
+
console.log(` ${f} → estilos recargados en caliente (por runScript)`);
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
fallos.push(`${f}: loadCssFile ${nativo.exceptionMessage ?? nativo.status ?? "sin motivo"}`);
|
|
295
|
+
}
|
|
266
296
|
} else {
|
|
267
297
|
const r = mandar("loadIncludeFile", { file: f, language: "javascript", encoding: "UTF-8", compile: true });
|
|
268
298
|
if (r.result !== true) fallos.push(`${f}: loadIncludeFile ${r.exceptionMessage ?? r.status ?? "sin motivo"}`);
|
|
269
299
|
else console.log(` ${f} → JavaScript recargado`);
|
|
270
300
|
}
|
|
271
301
|
}
|
|
302
|
+
// Por `runScript` los estilos se ven en el SIGUIENTE pintado: sin este `refresh`, no cambia nada
|
|
303
|
+
// (medido). El comando `loadCssFile` relayouta él solo.
|
|
304
|
+
if (necesitaRefresh) mandar("refresh");
|
|
272
305
|
dormir(1);
|
|
273
306
|
}
|
|
274
307
|
|