xonecode 0.1.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/README.md +167 -0
- package/dist/agent/authEnDisco.js +56 -0
- package/dist/agent/authEnDisco.js.map +1 -0
- package/dist/agent/configEnDisco.js +109 -0
- package/dist/agent/configEnDisco.js.map +1 -0
- package/dist/agent/crearProyecto.js +34 -0
- package/dist/agent/crearProyecto.js.map +1 -0
- package/dist/agent/entorno.js +124 -0
- package/dist/agent/entorno.js.map +1 -0
- package/dist/agent/guionizado.js +53 -0
- package/dist/agent/guionizado.js.map +1 -0
- package/dist/agent/instantanea.js +129 -0
- package/dist/agent/instantanea.js.map +1 -0
- package/dist/agent/interrupts.js +83 -0
- package/dist/agent/interrupts.js.map +1 -0
- package/dist/agent/mensajes.js +24 -0
- package/dist/agent/mensajes.js.map +1 -0
- package/dist/agent/modelos.js +42 -0
- package/dist/agent/modelos.js.map +1 -0
- package/dist/agent/normalizar.js +20 -0
- package/dist/agent/normalizar.js.map +1 -0
- package/dist/agent/perfiles.js +103 -0
- package/dist/agent/perfiles.js.map +1 -0
- package/dist/agent/proyecto.js +107 -0
- package/dist/agent/proyecto.js.map +1 -0
- package/dist/agent/puente.js +142 -0
- package/dist/agent/puente.js.map +1 -0
- package/dist/agent/resumenDeTool.js +48 -0
- package/dist/agent/resumenDeTool.js.map +1 -0
- package/dist/agent/skills.js +65 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/textoDeTool.js +113 -0
- package/dist/agent/textoDeTool.js.map +1 -0
- package/dist/agent/turnoReal.js +173 -0
- package/dist/agent/turnoReal.js.map +1 -0
- package/dist/agent/verificador.js +65 -0
- package/dist/agent/verificador.js.map +1 -0
- package/dist/agent/xoneAgent.js +106 -0
- package/dist/agent/xoneAgent.js.map +1 -0
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/aprobar.js +82 -0
- package/dist/cli/aprobar.js.map +1 -0
- package/dist/cli/config.js +133 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/consola.js +346 -0
- package/dist/cli/consola.js.map +1 -0
- package/dist/cli/describe.js +53 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/doctor.js +45 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/main.js +520 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/markdown.js +90 -0
- package/dist/cli/markdown.js.map +1 -0
- package/dist/cli/run.js +164 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/spinner.js +89 -0
- package/dist/cli/spinner.js.map +1 -0
- package/dist/cli/stdio.js +193 -0
- package/dist/cli/stdio.js.map +1 -0
- package/dist/cli/tema.js +40 -0
- package/dist/cli/tema.js.map +1 -0
- package/dist/cli/verify.js +62 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/core/bitacora.js +30 -0
- package/dist/core/bitacora.js.map +1 -0
- package/dist/core/config.js +236 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contextos.js +56 -0
- package/dist/core/contextos.js.map +1 -0
- package/dist/core/deps.js +51 -0
- package/dist/core/deps.js.map +1 -0
- package/dist/core/diff.js +79 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/esqueleto.js +366 -0
- package/dist/core/esqueleto.js.map +1 -0
- package/dist/core/events.js +2 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/modelos.js +85 -0
- package/dist/core/modelos.js.map +1 -0
- package/dist/core/notify.js +106 -0
- package/dist/core/notify.js.map +1 -0
- package/dist/core/ports.js +114 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/turno.js +127 -0
- package/dist/core/turno.js.map +1 -0
- package/dist/vendor/hitl.js +103 -0
- package/dist/vendor/hitl.js.map +1 -0
- package/dist/vendor/skillLoaders/catalog.js +74 -0
- package/dist/vendor/skillLoaders/catalog.js.map +1 -0
- package/dist/vendor/tokenTracking.js +58 -0
- package/dist/vendor/tokenTracking.js.map +1 -0
- package/package.json +41 -0
- package/skills/xone-debugging/SKILL.md +52 -0
- package/skills/xone-debugging/references/faq.md +561 -0
- package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
- package/skills/xone-development/SKILL.md +105 -0
- package/skills/xone-development/references/anti-patrones.md +94 -0
- package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
- package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
- package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
- package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
- package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
- package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
- package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
- package/skills/xone-development/references/datos/appdata.md +611 -0
- package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
- package/skills/xone-development/references/datos/http.md +366 -0
- package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
- package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
- package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
- package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
- package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
- package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
- package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
- package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
- package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
- package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
- package/skills/xone-development/references/indice-completo.md +77 -0
- package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
- package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
- package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
- package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
- package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
- package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
- package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
- package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
- package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
- package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
- package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
- package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
- package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
- package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
- package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
- package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
- package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
- package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
- package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
- package/skills/xone-development/references/tipos-de-prop.md +28 -0
- package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
- package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
- package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
- package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
- package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
- package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
- package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
- package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
- package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
- package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
- package/skills/xone-development/references/xml-ui/mapas.md +685 -0
- package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
- package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
- package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
- package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
- package/skills/xone-plan-builder/SKILL.md +183 -0
- package/skills/xone-plan-builder/agents/openai.yaml +5 -0
- package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
- package/skills/xone-project-generator/SKILL.md +111 -0
- package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
- package/skills/xone-project-generator/references/colecciones-base.md +16 -0
- package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
- package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
- package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
- package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
- package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
- package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
- package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
- package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
- package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
- package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
- package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
- package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
- package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
- package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
- package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
- package/skills/xone-review/SKILL.md +189 -0
- package/skills/xone-spec-builder/SKILL.md +235 -0
- package/skills/xone-spec-builder/agents/openai.yaml +5 -0
- package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
- package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
- package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
# XOne — appData: colecciones, sesión, macros y SQL
|
|
2
|
+
|
|
3
|
+
> Fuente: `xone/v2/xone-help-docs/topics/03c-js-appdata-http.md` §4. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
|
|
4
|
+
|
|
5
|
+
Contenido: §4 appData completo: getCollection y operaciones, login/logout, paso de datos entre pantallas, macros globales, SQL directo, detección de dispositivo, loadIncludeFile y loadCssFile
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 4. Objeto Global `appData` - Aplicación
|
|
10
|
+
|
|
11
|
+
El objeto global `appData` gestiona datos, configuración, sesión y estado de la aplicación.
|
|
12
|
+
|
|
13
|
+
### 4.1 Colecciones
|
|
14
|
+
|
|
15
|
+
#### Crear objetos: patrón preferido (constructor `new`)
|
|
16
|
+
|
|
17
|
+
Toda colección de la aplicación está disponible como constructor global. `new NombreColeccion()` crea un objeto nuevo de esa colección y acepta un parámetro opcional con los valores iniciales (cada propiedad se asigna igual que `obj.PROP = valor`, disparando sus `onchange`):
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
// Crear un objeto nuevo con valores iniciales
|
|
21
|
+
let obj = new Clientes({ NOMBRE: "ACME", ACTIVO: 1 });
|
|
22
|
+
|
|
23
|
+
// El parámetro es opcional
|
|
24
|
+
let obj2 = new Clientes();
|
|
25
|
+
|
|
26
|
+
// Crear, añadir a la colección y guardar
|
|
27
|
+
let coll = appData.getCollection("Clientes");
|
|
28
|
+
let obj3 = new Clientes({ NOMBRE: "Nuevo registro" });
|
|
29
|
+
coll.addItem(obj3);
|
|
30
|
+
obj3.save();
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Cuándo NO aplica el constructor:
|
|
34
|
+
|
|
35
|
+
- **Contents anidados**: para crear líneas de un content usa `self.Contents("Lineas").createObject()` — crear desde el content establece el vínculo con el objeto padre; el constructor crea sobre la colección global y no vincula.
|
|
36
|
+
- **Nombre de colección dinámico**: si el nombre llega en una variable, usa el patrón legacy `appData.getCollection(nombre).createObject()`.
|
|
37
|
+
|
|
38
|
+
El constructor solo crea objetos. No existen métodos estáticos tipo ORM (`Usuarios.find(...)`, `Usuarios.create(...)`, `Usuarios.findById(...)`); las consultas se hacen con `appData.getCollection("Usuarios").findObject(...)` y demás métodos de la colección.
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
// (legacy) Patrón antiguo de creación — sigue funcionando, pero el preferido es el constructor
|
|
42
|
+
let coll = appData.getCollection("Clientes");
|
|
43
|
+
let obj = coll.createObject();
|
|
44
|
+
obj.NOMBRE = "ACME";
|
|
45
|
+
obj.ACTIVO = 1;
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### API de colecciones
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
// === Obtener una coleccion por nombre ===
|
|
52
|
+
let coll = appData.getCollection("NombreColeccion");
|
|
53
|
+
|
|
54
|
+
// === Crear nuevo objeto y agregarlo ===
|
|
55
|
+
let obj = new NombreColeccion({ MAP_NOMBRE: "Nuevo registro" });
|
|
56
|
+
coll.addItem(obj);
|
|
57
|
+
obj.save();
|
|
58
|
+
|
|
59
|
+
// === Cargar todos los registros ===
|
|
60
|
+
coll.loadAll();
|
|
61
|
+
let nCount = coll.getCount(); // Número de registros cargados
|
|
62
|
+
|
|
63
|
+
// === Iterar registros ===
|
|
64
|
+
for (let i = 0; i < coll.getCount(); i++) {
|
|
65
|
+
let obj = coll.get(i);
|
|
66
|
+
console.log(obj.MAP_NOMBRE);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// === Navegacion con browse ===
|
|
70
|
+
coll.startBrowse();
|
|
71
|
+
let item = coll.getCurrentItem();
|
|
72
|
+
coll.moveFirst();
|
|
73
|
+
while (coll.getCurrentItem() != null) {
|
|
74
|
+
// Procesar item
|
|
75
|
+
coll.moveNext();
|
|
76
|
+
}
|
|
77
|
+
coll.endBrowse();
|
|
78
|
+
|
|
79
|
+
// === Buscar objetos ===
|
|
80
|
+
let obj = coll.findObject("LOGIN = 'admin'");
|
|
81
|
+
let obj2 = coll.findObject("ID = 5 AND ACTIVO = 1");
|
|
82
|
+
let obj3 = coll.getItem("MAP_CAMPO", valor);
|
|
83
|
+
let todos = coll.findAllObjects("TIPO = 'A'");
|
|
84
|
+
|
|
85
|
+
// === Filtrar y ordenar ===
|
|
86
|
+
coll.setFilter("ACTIVO = 1 AND TIPO = 'A'");
|
|
87
|
+
coll.clear();
|
|
88
|
+
coll.loadAll();
|
|
89
|
+
coll.doSort("NOMBRE ASC");
|
|
90
|
+
|
|
91
|
+
// === Eliminar registros ===
|
|
92
|
+
coll.deleteItem(indice); // Eliminar por indice
|
|
93
|
+
coll.browseDeleteAll(); // Eliminar todos de la BD
|
|
94
|
+
coll.clear(); // Limpiar solo memoria
|
|
95
|
+
|
|
96
|
+
// === Guardar todos los registros modificados ===
|
|
97
|
+
coll.saveAll();
|
|
98
|
+
|
|
99
|
+
// === Bloquear/desbloquear para modificaciones ===
|
|
100
|
+
coll.lock();
|
|
101
|
+
coll.unlock();
|
|
102
|
+
|
|
103
|
+
// === Clonar coleccion ===
|
|
104
|
+
let collClone = coll.createClone();
|
|
105
|
+
|
|
106
|
+
// === Cargar desde JSON ===
|
|
107
|
+
coll.loadFromJson("[{'ID': 1, 'NOMBRE': 'Item1'}, {'ID': 2, 'NOMBRE': 'Item2'}]");
|
|
108
|
+
|
|
109
|
+
// === Variables y macros de coleccion ===
|
|
110
|
+
coll.setVariable("totalProcesados", 0);
|
|
111
|
+
let total = coll.getVariable("totalProcesados");
|
|
112
|
+
coll.setMacro("##FILTRO##", "activo=1");
|
|
113
|
+
let filtro = coll.getMacro("##FILTRO##");
|
|
114
|
+
|
|
115
|
+
// === Busqueda en memoria ===
|
|
116
|
+
coll.createSearchIndex(["NOMBRE", "DESCRIPCION"]);
|
|
117
|
+
coll.doSearch("texto a buscar");
|
|
118
|
+
|
|
119
|
+
// === Información de la coleccion ===
|
|
120
|
+
let nombre = coll.getName();
|
|
121
|
+
let propCount = coll.getPropertyCount();
|
|
122
|
+
let propName = coll.propertyName(0);
|
|
123
|
+
let propType = coll.getPropType("MAP_CAMPO");
|
|
124
|
+
|
|
125
|
+
// === Generar ROWID ===
|
|
126
|
+
let rowid = coll.generateRowId();
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 4.2 Autenticación
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
// === Login ===
|
|
133
|
+
appData.login({
|
|
134
|
+
userName : self.MAP_USER,
|
|
135
|
+
password : self.MAP_PASSWORD,
|
|
136
|
+
entryPoint : "MenuPrincipal",
|
|
137
|
+
onLoginSuccessful : function() {
|
|
138
|
+
ui.showToast("Login OK!");
|
|
139
|
+
},
|
|
140
|
+
onLoginFailed : function() {
|
|
141
|
+
ui.showToast("Login failed!");
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// === Logout ===
|
|
146
|
+
appData.logout();
|
|
147
|
+
|
|
148
|
+
// === Salir de la app ===
|
|
149
|
+
appData.exit();
|
|
150
|
+
|
|
151
|
+
// === Reiniciar la app ===
|
|
152
|
+
appData.restart();
|
|
153
|
+
|
|
154
|
+
// === Obtener empresa y usuario actual ===
|
|
155
|
+
let empresa = appData.getCurrentEnterprise();
|
|
156
|
+
let empresas = appData.getAllowedEnterprises();
|
|
157
|
+
let usuarios = appData.getAllowedUsers();
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 4.3 Navegación entre Pantallas con Datos
|
|
161
|
+
|
|
162
|
+
Para abrir una pantalla pasándole datos, se usa el patrón **dataObject + `ui.openEditView()`**:
|
|
163
|
+
|
|
164
|
+
1. Obtener (o crear) un **dataObject** de la colección destino.
|
|
165
|
+
2. Asignar los valores deseados a sus propiedades (`obj.MAP_X = valor`).
|
|
166
|
+
3. Llamar a `ui.openEditView(dataObject)` — XOne abre la vista de edición de ese objeto.
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
// === Pasar un objeto NUEVO a la pantalla destino ===
|
|
170
|
+
let coll = appData.getCollection("DetalleCliente");
|
|
171
|
+
let obj = new DetalleCliente({ MAP_CLIENTE_ID: clienteId, MAP_MODO: "consulta" });
|
|
172
|
+
coll.addItem(obj);
|
|
173
|
+
ui.openEditView(obj);
|
|
174
|
+
|
|
175
|
+
// === Abrir un objeto EXISTENTE recuperado de la BD ===
|
|
176
|
+
let coll = appData.getCollection("Clientes");
|
|
177
|
+
let cliente = coll.findObject("ID = " + clienteId);
|
|
178
|
+
if (cliente) {
|
|
179
|
+
ui.openEditView(cliente);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Forma corta — crear + abrir en una sola llamada:**
|
|
184
|
+
|
|
185
|
+
Si solo necesitas abrir un objeto nuevo sin preparar nada de antemano, basta con pasar el nombre de la colección. XOne hace internamente `createObject()` + `addItem()`:
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
ui.openEditView("DetalleCliente");
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Cerrar la vista actual al abrir la nueva:**
|
|
192
|
+
|
|
193
|
+
`openEditView` admite un segundo argumento booleano para terminar la vista origen tras abrir la siguiente (flujos lineales sin botón atrás):
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
ui.openEditView(obj, true); // cierra la vista origen al abrir la nueva
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 4.4 Macros Globales
|
|
200
|
+
|
|
201
|
+
Las macros globales son pares clave-valor accesibles desde toda la aplicación. Son la alternativa de XOne a `localStorage`:
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
// === Establecer y leer macros personalizadas ===
|
|
205
|
+
appData.setGlobalMacro("##MI_TOKEN##", "abc123");
|
|
206
|
+
let token = appData.getGlobalMacro("##MI_TOKEN##");
|
|
207
|
+
|
|
208
|
+
// === Macros del sistema ===
|
|
209
|
+
let deviceOs = appData.getGlobalMacro("##DEVICE_OS##"); // "android" o "ios"
|
|
210
|
+
let version = appData.getGlobalMacro("##VERSION##");
|
|
211
|
+
let frameVersion = appData.getGlobalMacro("##FRAME_VERSION##");
|
|
212
|
+
|
|
213
|
+
// === Obtener todas las macros ===
|
|
214
|
+
let todasMacros = appData.getAllGlobalMacros();
|
|
215
|
+
|
|
216
|
+
// === Patron comun: almacenar datos de sesion ===
|
|
217
|
+
function guardarSesion(usuario) {
|
|
218
|
+
appData.setGlobalMacro("##USERID##", usuario.ID);
|
|
219
|
+
appData.setGlobalMacro("##USERNAME##", usuario.NOMBRE);
|
|
220
|
+
appData.setGlobalMacro("##USERROLE##", usuario.ROL);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function limpiarSesion() {
|
|
224
|
+
appData.setGlobalMacro("##USERID##", "");
|
|
225
|
+
appData.setGlobalMacro("##USERNAME##", "");
|
|
226
|
+
appData.setGlobalMacro("##USERROLE##", "");
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### 4.5 SQL Directo
|
|
231
|
+
|
|
232
|
+
**Firma:** `appData.executeSql(sql)`
|
|
233
|
+
|
|
234
|
+
- Acepta **exactamente 1 parámetro** (string SQL); no admite placeholders `?` ni varargs.
|
|
235
|
+
- **Sustituye automáticamente** las macros del framework (`##USERID##`, `##NOW##`, etc.) en el SQL antes de ejecutar.
|
|
236
|
+
- **No usar para leer escalares**: para `SELECT` no devuelve el valor, devuelve un cursor inutilizable desde JS. Para leer datos usar `SqlManager.doRawQuery()` + cursor.
|
|
237
|
+
- Casos de uso: sentencias de modificación masiva, sobre todo cuando hay cursores abiertos sobre la misma tabla y `CurrentItem` no puede modificarse desde la coll.
|
|
238
|
+
|
|
239
|
+
```javascript
|
|
240
|
+
// === Ejecutar SQL directo (UPDATE/INSERT/DELETE) ===
|
|
241
|
+
appData.executeSql("UPDATE gen_productos SET ACTIVO=0 WHERE STOCK=0");
|
|
242
|
+
|
|
243
|
+
// NO usar executeSql para leer escalares: no devuelve el COUNT, devuelve un ResultSet
|
|
244
|
+
// var n = appData.executeSql("SELECT COUNT(*) FROM gen_clientes"); // MAL
|
|
245
|
+
|
|
246
|
+
// === SqlManager para consultas avanzadas ===
|
|
247
|
+
let sqlManager = new SqlManager();
|
|
248
|
+
try {
|
|
249
|
+
sqlManager.openDatabase({
|
|
250
|
+
databasePath : "gestion.db",
|
|
251
|
+
useWal : true,
|
|
252
|
+
readOnly : false,
|
|
253
|
+
useExistingConnection: true,
|
|
254
|
+
onDatabaseCorrupted : function() {
|
|
255
|
+
ui.showToast("Base de datos corrupta");
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Consulta con parametros (SEGURO contra SQL injection)
|
|
260
|
+
let cursor = sqlManager.doRawQuery(
|
|
261
|
+
"SELECT * FROM gen_usuarios WHERE LOGIN=? AND ACTIVO=?",
|
|
262
|
+
"admin", 1
|
|
263
|
+
);
|
|
264
|
+
try {
|
|
265
|
+
if (cursor.getCount() > 0) {
|
|
266
|
+
cursor.moveToFirst();
|
|
267
|
+
let nombre = cursor.getString("NOMBRE");
|
|
268
|
+
let id = cursor.getInteger("ID");
|
|
269
|
+
}
|
|
270
|
+
} finally {
|
|
271
|
+
cursor.close(); // SIEMPRE cerrar el cursor
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Insertar con parametros seguros
|
|
275
|
+
sqlManager.insert({
|
|
276
|
+
tableName: "gen_productos",
|
|
277
|
+
fields: {
|
|
278
|
+
CODIGO: "PROD001",
|
|
279
|
+
NOMBRE: "Producto nuevo",
|
|
280
|
+
PRECIO: 29.99,
|
|
281
|
+
ACTIVO: 1
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// Batch de SQLs
|
|
286
|
+
let sqls = [];
|
|
287
|
+
sqls.push("UPDATE gen_productos SET PROCESADO=1 WHERE FECHA < '2024-01-01'");
|
|
288
|
+
sqls.push("DELETE FROM gen_log WHERE FECHA < '2023-01-01'");
|
|
289
|
+
sqlManager.doBatchParseSqls(sqls);
|
|
290
|
+
|
|
291
|
+
// Mantenimiento
|
|
292
|
+
sqlManager.doWalCheckpoint();
|
|
293
|
+
sqlManager.doVacuum();
|
|
294
|
+
|
|
295
|
+
} finally {
|
|
296
|
+
sqlManager.close(); // SIEMPRE cerrar la conexión
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 4.6 Encriptación (Básica)
|
|
301
|
+
|
|
302
|
+
```javascript
|
|
303
|
+
// Encriptar string (encriptacion simple del framework)
|
|
304
|
+
let encrypted = appData.encryptString("texto secreto");
|
|
305
|
+
|
|
306
|
+
// Desencriptar string
|
|
307
|
+
let decrypted = appData.decryptString(encrypted);
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Para encriptación avanzada (AES, RSA, firma digital), usar el objeto `crypto` documentado más adelante en la sección de Seguridad.
|
|
311
|
+
|
|
312
|
+
### 4.7 Deteccion de Dispositivo
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
// Tipo de dispositivo
|
|
316
|
+
if (appData.isPhone()) { /* Teléfono */ }
|
|
317
|
+
if (appData.isTablet()) { /* Tablet */ }
|
|
318
|
+
if (appData.isWatch()) { /* Smartwatch */ }
|
|
319
|
+
if (appData.isWatchRound()) { /* Reloj redondo */ }
|
|
320
|
+
if (appData.isWatchSquare()) { /* Reloj cuadrado */ }
|
|
321
|
+
|
|
322
|
+
// Subtipos de teléfono
|
|
323
|
+
appData.isMiniPhone(); // Teléfono pequeño
|
|
324
|
+
appData.isMidPhone(); // Teléfono mediano
|
|
325
|
+
appData.isHiPhone(); // Teléfono grande
|
|
326
|
+
|
|
327
|
+
// Orientacion
|
|
328
|
+
if (appData.isVertical()) { /* Modo vertical (portrait) */ }
|
|
329
|
+
if (appData.isHorizontal()) { /* Modo horizontal (landscape) */ }
|
|
330
|
+
|
|
331
|
+
// Sistema operativo
|
|
332
|
+
let so = appData.getGlobalMacro("##DEVICE_OS##"); // "android" o "ios"
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### 4.8 Push Notifications
|
|
336
|
+
|
|
337
|
+
`appData.registerPush(...)` admite tres firmas:
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
// Forma 1: objeto con callbacks (los nombres correctos son onSuccess/onFailure/onPushReceived,
|
|
341
|
+
// NO "onRegistered"; el motor lee exactamente esos tres)
|
|
342
|
+
appData.registerPush({
|
|
343
|
+
onSuccess: function(event) {
|
|
344
|
+
let pushToken = event.pushToken; // EventOnPushRegistered.pushToken
|
|
345
|
+
console.log("Push token: " + pushToken);
|
|
346
|
+
// Enviar token al servidor
|
|
347
|
+
},
|
|
348
|
+
onFailure: function(ex) {
|
|
349
|
+
console.error("Push registration failed:", ex);
|
|
350
|
+
},
|
|
351
|
+
onPushReceived: function(message) {
|
|
352
|
+
// Manejar la notificación recibida
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// Forma 2: una función (callback de éxito)
|
|
357
|
+
appData.registerPush(function(event) { /* event.pushToken */ });
|
|
358
|
+
|
|
359
|
+
// Forma 3: dos funciones posicionales (éxito, fallo)
|
|
360
|
+
appData.registerPush(function(event) { /* OK */ },
|
|
361
|
+
function(ex) { /* error */ });
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
> Las notificaciones entrantes también se manejan con el nodo `<onpushreceived>` declarado en la `<coll Empresas>`.
|
|
365
|
+
|
|
366
|
+
### 4.9 Otros Métodos Importantes
|
|
367
|
+
|
|
368
|
+
```javascript
|
|
369
|
+
// === Cerrar la app ===
|
|
370
|
+
appData.exit();
|
|
371
|
+
|
|
372
|
+
// === Cerrar la ventana actual ===
|
|
373
|
+
ui.getView(self).exit();
|
|
374
|
+
|
|
375
|
+
// === Escribir en consola de debug ===
|
|
376
|
+
appData.writeConsoleString("Debug: valor = " + valor);
|
|
377
|
+
|
|
378
|
+
// === Cargar archivos include (solo para casos dinámicos — preferir <include>/<script> en <app>; ver 4.11) ===
|
|
379
|
+
appData.loadIncludeFile("scripts/miModulo.js", "javascript", "UTF-8");
|
|
380
|
+
|
|
381
|
+
// === Cargar/descargar archivos CSS en runtime (solo para casos dinámicos — preferir <style> en <app>; ver 4.12) ===
|
|
382
|
+
appData.loadCssFile("temas/oscuro.css");
|
|
383
|
+
appData.unloadCssFile("temas/oscuro.css");
|
|
384
|
+
|
|
385
|
+
// === Rutas del sistema ===
|
|
386
|
+
let appPath = appData.getAppPath(); // Ruta base de la aplicación
|
|
387
|
+
let filesPath = appData.getFilesPath(); // Ruta de carpeta files/
|
|
388
|
+
|
|
389
|
+
// === Manejo de errores ===
|
|
390
|
+
let error = appData.error();
|
|
391
|
+
if (error.getNumber() != 0) {
|
|
392
|
+
console.log("Error: " + error.getDescription());
|
|
393
|
+
console.log("SQL fallido: " + error.getFailedSql());
|
|
394
|
+
error.clear();
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// === Limpiar caches ===
|
|
398
|
+
appData.clearCaches();
|
|
399
|
+
|
|
400
|
+
// === Crear objetos especiales ===
|
|
401
|
+
let pdf = new XOnePDF();
|
|
402
|
+
let ocr = new XOneOCR();
|
|
403
|
+
let nfc = new XOneNFC();
|
|
404
|
+
let printer = new XOnePrinter();
|
|
405
|
+
let wifiMgr = new WifiManager();
|
|
406
|
+
|
|
407
|
+
// === Redondeo seguro ===
|
|
408
|
+
let resultado = appData.safeRound(3.14159, 2); // 3.14
|
|
409
|
+
|
|
410
|
+
// === Replicacion ===
|
|
411
|
+
let isReplicating = appData.isReplicating();
|
|
412
|
+
let replicationId = appData.getReplicationId();
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### 4.10 Métodos Adicionales de appData
|
|
416
|
+
|
|
417
|
+
#### getCurrentEnterprise() - Empresa Actual
|
|
418
|
+
|
|
419
|
+
```javascript
|
|
420
|
+
var empresa = appData.getCurrentEnterprise();
|
|
421
|
+
|
|
422
|
+
// Almacenar variables de sesion en la empresa
|
|
423
|
+
empresa.setVariable("GPSTime", new Date().toString());
|
|
424
|
+
empresa.setVariable("LATITUD", latitud);
|
|
425
|
+
empresa.setVariable("MIUBICACION", 0);
|
|
426
|
+
|
|
427
|
+
// Recuperar variables de la empresa
|
|
428
|
+
var valor = empresa.getVariable("GPSTime");
|
|
429
|
+
var lat = empresa.getVariable("LATITUD");
|
|
430
|
+
var debug = empresa.getVariable("Debug");
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
#### safeRound(value, decimals) - Redondeo Seguro
|
|
434
|
+
|
|
435
|
+
```javascript
|
|
436
|
+
var precio = appData.safeRound(vPendiente, 2);
|
|
437
|
+
var total = appData.safeRound(cantidad * precioUnitario, 2);
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
#### encryptString(text) / decryptString(text) - Cifrado/Descifrado
|
|
441
|
+
|
|
442
|
+
```javascript
|
|
443
|
+
var cifrado = appData.encryptString("texto sensible");
|
|
444
|
+
var descifrado = appData.decryptString(cifrado);
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
#### error() - Objeto de Error del Framework
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
var error = appData.error();
|
|
451
|
+
if (error.getNumber() != 0) {
|
|
452
|
+
console.log("Código: " + error.getNumber());
|
|
453
|
+
console.log("Descripción: " + error.getDescription());
|
|
454
|
+
console.log("SQL fallido: " + error.getFailedSql());
|
|
455
|
+
error.clear();
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
#### writeConsoleString(message) - Consola de Depuracion
|
|
460
|
+
|
|
461
|
+
```javascript
|
|
462
|
+
appData.writeConsoleString("App_log_xone->Mensaje de depuracion");
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
#### setIsReplicating(boolean) - Control de Replicación
|
|
466
|
+
|
|
467
|
+
```javascript
|
|
468
|
+
appData.setIsReplicating(false);
|
|
469
|
+
// ... operaciones de mantenimiento local
|
|
470
|
+
appData.setIsReplicating(true);
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
#### Conexiones
|
|
474
|
+
|
|
475
|
+
```javascript
|
|
476
|
+
// Conexión por nombre (útil cuando la app declara varias conexiones)
|
|
477
|
+
var conn = appData.getConnection("REMOTA");
|
|
478
|
+
|
|
479
|
+
// String de la conexión PRINCIPAL (la por defecto)
|
|
480
|
+
var s = appData.getConnString();
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
#### getCollectionCount() / getVisualConditions()
|
|
484
|
+
|
|
485
|
+
```javascript
|
|
486
|
+
var nColls = appData.getCollectionCount(); // total de colecciones registradas
|
|
487
|
+
var conds = appData.getVisualConditions(); // string con las condiciones visuales activas
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### 4.11 Carga dinámica de scripts (`loadIncludeFile`) y declaración preferida
|
|
491
|
+
|
|
492
|
+
> **Regla general:** declara los scripts en el nodo `<app>` siempre que puedas. Reserva `loadIncludeFile()` para casos especiales que **realmente** necesiten cargar el fichero en runtime (carga condicional según usuario/empresa, scripts descargados dinámicamente, parches en caliente, etc.).
|
|
493
|
+
|
|
494
|
+
#### Forma preferida: declarar en el nodo `<app>` (estática)
|
|
495
|
+
|
|
496
|
+
```xml
|
|
497
|
+
<app default-language="javascript" ...>
|
|
498
|
+
<!-- functions.js se carga automáticamente, no hace falta declararlo -->
|
|
499
|
+
|
|
500
|
+
<!-- Forma <include>: encoding por defecto ISO-8859-1 -->
|
|
501
|
+
<include file="scripts/utils.js" />
|
|
502
|
+
<include url="scripts/api.js" encoding="UTF-8" />
|
|
503
|
+
|
|
504
|
+
<!-- Forma <script> (alias estilo HTML): encoding por defecto UTF-8 -->
|
|
505
|
+
<script src="scripts/auth.js" />
|
|
506
|
+
</app>
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
**Atributos comunes a `<include>` y `<script>`:**
|
|
510
|
+
|
|
511
|
+
| Atributo | Alias | Obligatorio | Default | Descripción |
|
|
512
|
+
|---|---|---|---|---|
|
|
513
|
+
| `file` | `url`, `src` | sí | — | Ruta del fichero |
|
|
514
|
+
| `language` | — | no | `default-language` del `<app>` | `"javascript"` o `"vbscript"` |
|
|
515
|
+
| `encoding` | `charset` | no | `ISO-8859-1` en `<include>` · `UTF-8` en `<script>` | Codificación del fichero |
|
|
516
|
+
| `delay-compilation` | — | no | `false` | Difiere la compilación hasta el primer uso |
|
|
517
|
+
| `compile` | — | no | `true` | Si `false`, registra el fichero pero no lo compila |
|
|
518
|
+
|
|
519
|
+
#### Forma dinámica: `appData.loadIncludeFile()` (solo casos especiales)
|
|
520
|
+
|
|
521
|
+
```javascript
|
|
522
|
+
appData.loadIncludeFile(fileName [, scriptLanguage] [, encoding] [, delayCompilation] [, compile]);
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
| # | Nombre | Obligatorio | Valor por defecto | Descripción |
|
|
526
|
+
|---|---|---|---|---|
|
|
527
|
+
| 1 | `fileName` | sí | — | Ruta del fichero igual que en el nodo XML `<include>` |
|
|
528
|
+
| 2 | `scriptLanguage` | no | `default-language` del nodo `<app>` | `"javascript"` o `"vbscript"` |
|
|
529
|
+
| 3 | `encoding` | no | `"ISO-8859-1"` | Codificación del fichero. **Atención: el default NO es UTF-8** |
|
|
530
|
+
| 4 | `delayCompilation` | no | `false` | Si `true`, difiere la compilación hasta el primer uso |
|
|
531
|
+
| 5 | `compile` | no | `true` | Si `false`, registra el fichero pero no lo compila |
|
|
532
|
+
|
|
533
|
+
```javascript
|
|
534
|
+
// Carga simple (asume default-language=javascript y encoding ISO-8859-1)
|
|
535
|
+
appData.loadIncludeFile("scripts/miModulo.js");
|
|
536
|
+
|
|
537
|
+
// Recomendado si el script tiene tildes/ñ guardadas como UTF-8
|
|
538
|
+
appData.loadIncludeFile("scripts/miModulo.js", "javascript", "UTF-8");
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
**Advertencia sobre el encoding:** el valor por defecto es `ISO-8859-1`, no UTF-8. Si tu script contiene caracteres no-ASCII (tildes, ñ, símbolos) y está guardado como UTF-8, **se romperán** salvo que pases `"UTF-8"` explícitamente como tercer parámetro.
|
|
542
|
+
|
|
543
|
+
Llamadas posteriores al mismo fichero **no recompilan**: el motor reutiliza el bytecode ya cargado.
|
|
544
|
+
|
|
545
|
+
### 4.12 Carga dinámica de CSS (`loadCssFile` / `unloadCssFile`) y declaración preferida
|
|
546
|
+
|
|
547
|
+
> **Regla general:** declara las hojas de estilo en el nodo `<app>` siempre que puedas. Reserva `loadCssFile()` / `unloadCssFile()` para casos especiales (cambio de tema por usuario, modo oscuro/claro en runtime, A/B testing visual, etc.).
|
|
548
|
+
|
|
549
|
+
#### Forma preferida: declarar en el nodo `<app>` (estática)
|
|
550
|
+
|
|
551
|
+
```xml
|
|
552
|
+
<app ...>
|
|
553
|
+
<style url="estilos.css" />
|
|
554
|
+
<style url="temas/oscuro.css" encoding="UTF-8" conditions="##DEVICE_OS##='android'" strict-mode="true" />
|
|
555
|
+
</app>
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
**Atributos del nodo `<style>`:**
|
|
559
|
+
|
|
560
|
+
| Atributo | Obligatorio | Default | Descripción |
|
|
561
|
+
|---|---|---|---|
|
|
562
|
+
| `url` | sí | — | Ruta del fichero CSS |
|
|
563
|
+
| `encoding` | no | (depende del fichero) | Codificación del fichero |
|
|
564
|
+
| `conditions` | no | (sin condición) | Condición de carga evaluada al iniciar (p. ej. macros globales) |
|
|
565
|
+
| `strict-mode` | no | `false` | Si `true`, exige CSS bien formado (avisa de errores como falta de `;`). En modo estricto hay que escapar `:` en valores: `title:Hola\:Mundo;` |
|
|
566
|
+
|
|
567
|
+
#### Forma dinámica: `appData.loadCssFile()` / `appData.unloadCssFile()` (solo casos especiales)
|
|
568
|
+
|
|
569
|
+
**Firmas:**
|
|
570
|
+
|
|
571
|
+
```javascript
|
|
572
|
+
// Forma 1: argumentos posicionales
|
|
573
|
+
appData.loadCssFile(name [, encoding] [, conditions] [, strictMode]);
|
|
574
|
+
|
|
575
|
+
// Forma 2: objeto literal
|
|
576
|
+
appData.loadCssFile({ name: "...", encoding: "...", conditions: "...", strictMode: false });
|
|
577
|
+
|
|
578
|
+
// Descarga (un único argumento)
|
|
579
|
+
appData.unloadCssFile(name);
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
**Parámetros de `loadCssFile`:**
|
|
583
|
+
|
|
584
|
+
| # / clave | Obligatorio | Valor por defecto | Descripción |
|
|
585
|
+
|---|---|---|---|
|
|
586
|
+
| `name` | sí | — | Ruta del fichero CSS |
|
|
587
|
+
| `encoding` | no | `"UTF-8"` | Codificación del fichero (¡distinto de `loadIncludeFile`!) |
|
|
588
|
+
| `conditions` | no | (sin condición) | Condición de carga |
|
|
589
|
+
| `strictMode` | no | `false` | Modo estricto de parseo |
|
|
590
|
+
|
|
591
|
+
**Ejemplo (cambio de tema en runtime):**
|
|
592
|
+
|
|
593
|
+
```javascript
|
|
594
|
+
function aplicarTemaOscuro() {
|
|
595
|
+
appData.unloadCssFile("temas/claro.css");
|
|
596
|
+
appData.loadCssFile("temas/oscuro.css", "UTF-8");
|
|
597
|
+
// El framework limpia caches de propiedades y refresca la cascada
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
`loadCssFile()` y `unloadCssFile()` invalidan automáticamente los caches internos de propiedades visuales (`ClearCollPropValueCaches()`), por lo que los cambios se reflejan en los siguientes renders sin reiniciar la app.
|
|
602
|
+
|
|
603
|
+
**Diferencia de encoding por defecto:**
|
|
604
|
+
|
|
605
|
+
| Método | Default encoding |
|
|
606
|
+
|---|---|
|
|
607
|
+
| `appData.loadCssFile()` | `"UTF-8"` |
|
|
608
|
+
| `appData.loadIncludeFile()` | `"ISO-8859-1"` |
|
|
609
|
+
| `<style>` en `<app>` | depende del fichero |
|
|
610
|
+
| `<include>` en `<app>` | `"ISO-8859-1"` |
|
|
611
|
+
| `<script>` en `<app>` | `"UTF-8"` |
|