11# Java Notebook
22
3- Notebook de Java 100% client-side que corre en el navegador. Java 17 completo corre en WebAssembly via CheerpJ + JShell — sin servidor, sin backend, sin instalacion.
3+ Notebook de Java 100% client-side que corre en el navegador. Java 17 completo corre en WebAssembly via CheerpJ + JShell. Sin servidor, sin backend, sin instalacion.
44
55## Arquitectura
66
77```
88index.html → Punto de entrada (Vite entry point)
99css/notebook.css → Estilos responsive mobile-first con dark mode
1010js/
11- app.js → Bootstrap, navbar, settings, shortcuts modal, read mode, autosave, ejemplos
11+ app.js → Bootstrap, navbar, settings, shortcuts modal, read mode, autosave, ejemplos, import por URL
1212 tab-manager.js → Multiples notebooks en pestanas, barra de tabs + menu de acciones
1313 cell-manager.js → Ciclo de vida de celdas, seleccion, ejecucion, mutaciones DOM targeted
1414 cell-renderer.js → Creacion del DOM para celdas code/markdown (Bootstrap cards)
@@ -34,33 +34,33 @@ start.bat → Script de inicio para Windows
3434
3535## Stack tecnico
3636
37- - ** Vite** — build tool + dev server, resuelve dependencias desde node_modules/
38- - ** Bootstrap 5** via npm — framework CSS + componentes JS (navbar, nav-tabs, cards, modals, dropdowns)
39- - ** Bootstrap Icons** via npm — iconos consistentes en toda la UI
40- - ** CodeMirror 6** via npm — editor, syntax highlighting Java + Markdown, search
41- - ** marked.js** via npm — renderizado de markdown
42- - ** CheerpJ** — JVM completa en WebAssembly, cargada desde CDN
43- - ** JShell** — REPL de Java 17 para evaluacion interactiva de codigo
44- - ** @codemirror/theme-one-dark ** — tema oscuro, togglable desde settings (Auto/Claro/Oscuro)
45- - ** @codemirror/lang-markdown ** — syntax highlighting para editor de celdas markdown
37+ - ** Vite** : build tool + dev server, resuelve dependencias desde node_modules/
38+ - ** Bootstrap 5** via npm: framework CSS + componentes JS (navbar, nav-tabs, cards, modals, dropdowns)
39+ - ** Bootstrap Icons** via npm: iconos consistentes en toda la UI
40+ - ** CodeMirror 6** via npm: editor, syntax highlighting Java + Markdown, search
41+ - ** marked.js** via npm: renderizado de markdown
42+ - ** CheerpJ** : JVM completa en WebAssembly, cargada desde CDN
43+ - ** JShell** : REPL de Java 17 para evaluacion interactiva de codigo
44+ - ** @codemirror/theme-one-dark ** : tema oscuro, togglable desde settings (Auto/Claro/Oscuro)
45+ - ** @codemirror/lang-markdown ** : syntax highlighting para editor de celdas markdown
4646
4747## Como funciona la ejecucion
4848
49491 . CheerpJ se inicializa una vez al cargar la pagina (carga JVM WASM desde CDN)
50502 . JShellBridge se carga via ` cheerpjRunLibrary() ` en library mode
51513 . Cada tab crea una sesion JShell independiente via ` JShellBridge.init(sessionId) `
52524 . Al ejecutar una celda, ` jshell-proxy.js ` llama a ` JShellBridge.eval(sessionId, code) `
53- 5 . JShell compila y ejecuta el snippet — variables , clases y metodos persisten en la sesion
53+ 5 . JShell compila y ejecuta el snippet. Variables , clases y metodos persisten en la sesion
54546 . La salida se captura de dos fuentes: Java ` SwitchOutputStream ` buffer + CheerpJ ` #console ` DOM
55557 . "Reiniciar y ejecutar todo" hace reset de la sesion y ejecuta todas las celdas en orden
5656
5757## Sesiones JShell por tab
5858
5959- Cada tab tiene su propia sesion JShell (Map<String, SessionState> en Java)
60- - Las sesiones son independientes — variables de un tab no afectan a otro
60+ - Las sesiones son independientes. Variables de un tab no afectan a otro
6161- "Reiniciar sesion" destruye y recrea la sesion JShell del tab activo
6262- Al cerrar un tab se destruye su sesion (` JShellBridge.close(sessionId) ` )
63- - Las evaluaciones se serializan via promise chain — solo una eval a la vez (output capture compartido)
63+ - Las evaluaciones se serializan via promise chain, solo una eval a la vez (output capture compartido)
6464
6565## JShellBridge (src/JShellBridge.java)
6666
@@ -71,42 +71,79 @@ Bridge multi-sesion entre JavaScript y JShell en CheerpJ. Estrategia de evaluaci
71713 . Declaraciones/statements → eval normal con display de valores post-iteracion
7272
7373Workarounds para CheerpJ:
74- - ` SnippetEvent.value() ` siempre retorna null — no usable
75- - ` shell.varValue() ` retorna defaults (0, null, false) — no usable
74+ - ` SnippetEvent.value() ` siempre retorna null, no usable
75+ - ` shell.varValue() ` retorna defaults (0, null, false), no usable
7676- Se usa ` shell.eval("println(varName)") ` para leer valores reales
77- - Excepciones del LocalExecutionControl se tragan silenciosamente — wrap en try/catch
77+ - Excepciones del LocalExecutionControl se tragan silenciosamente, wrap en try/catch
7878
7979## Limitaciones de CheerpJ
8080
81- - ` Scanner ` / ` System.in ` — NO hay stdin en browser
82- - ` java.io.File ` — NO hay filesystem
81+ - ` Scanner ` / ` System.in ` : NO hay stdin en browser
82+ - ` java.io.File ` : NO hay filesystem
8383- Algunas excepciones no se lanzan (ej: ` 1/0 ` retorna 0 en vez de ArithmeticException)
8484- Primera ejecucion lenta (~ 5-10s) mientras CheerpJ inicializa la JVM
85- - CheerpJ se carga desde CDN — requiere conexion a internet
85+ - CheerpJ se carga desde CDN, requiere conexion a internet
86+
87+ ## UI: menus y controles
88+
89+ ** Menu Archivo** (navbar dropdown):
90+ - Importar: abre un .ipynb desde disco (tambien drag-drop)
91+ - Exportar: descarga el notebook actual
92+ - Ejemplos: notebooks de ejemplo cargados desde ` public/examples/index.json `
93+
94+ ** Configuracion** (engranaje en navbar):
95+ - Tema: Auto, Claro, Oscuro
96+ - Identacion: 2 o 4 espacios
97+ - Modo: Edicion o Lectura (alterna controles de edicion)
98+ - Atajos generales: On u Off
99+
100+ ** Menu del notebook** (icono ⋮ a la derecha de la barra de tabs):
101+ - Reiniciar y ejecutar todo
102+ - Reiniciar sesion
103+ - Agregar celda: Codigo, Texto
104+ - Celda seleccionada: Subir, Bajar, Cortar, Copiar, Pegar, Eliminar, Deshacer eliminar
105+
106+ ** Pestanas** :
107+ - Boton + para nuevo notebook
108+ - Doble clic en pestana para renombrar (long-press en mobile)
109+ - Boton X para cerrar
110+
111+ ** Celdas de codigo** : boton Ejecutar, botones Subir/Bajar/Eliminar, botones Copiar/Limpiar resultado
112+ ** Celdas de markdown** : doble clic para editar, botones Editar/Listo, Subir/Bajar/Eliminar
113+
114+ ## Import por URL
115+
116+ Se puede abrir un notebook desde una URL con el query parameter ` ?url= ` :
117+ ```
118+ https://sitio.com/?url=https://ejemplo.com/notebook.ipynb
119+ ```
120+ - Hace fetch del .ipynb, lo parsea y abre como tab nuevo
121+ - Muestra "Notebook importado: nombre" en el loading overlay
122+ - Si ya hay otra pestana del navegador abierta, delega via BroadcastChannel y muestra "Notebook enviado a la pestana abierta"
86123
87124## Settings
88125
89126Se guardan en localStorage key ` java-notebook-settings ` :
90127- ` theme ` : system, light o dark (default system)
91128- ` indentSize ` : 2 o 4 espacios (default 4)
92- - ` readMode ` : true/false (default false) — modo lectura oculta controles de edicion
93- - ` shortcuts ` : true/false (default false) — habilita atajos idle (cut/copy/paste/delete/undo celda)
129+ - ` readMode ` : true/false (default false). Modo lectura oculta controles de edicion
130+ - ` shortcuts ` : true/false (default false). Habilita atajos idle (cut/copy/paste/delete/undo celda)
94131
95132Los tabs/notebooks se guardan en localStorage key ` java-notebook-autosave ` (formato multi-tab).
96133
97134## Atajos de teclado
98135
99136Hay dos categorias de atajos globales (Ctrl+key):
100137
101- ** Always-on** — funcionan siempre, incluso dentro del editor (bloqueados solo por modals/dropdowns):
138+ ** Always-on** , funcionan siempre, incluso dentro del editor (bloqueados solo por modals/dropdowns):
102139
103140| Atajo | Accion |
104141| ---| ---|
105142| Ctrl+S | Exportar notebook |
106143| Ctrl+E | Alternar modo lectura/edicion |
107144| Ctrl+Up/Down | Navegar entre celdas |
108145
109- ** Idle-only** — requieren foco fuera del editor + setting "Atajos generales" habilitado:
146+ ** Idle-only** , requieren foco fuera del editor + setting "Atajos generales" habilitado:
110147
111148| Atajo | Accion |
112149| ---| ---|
@@ -122,7 +159,7 @@ Hay dos categorias de atajos globales (Ctrl+key):
122159| ---| ---|
123160| Shift+Enter | Ejecutar y quedarse (code) / Salir edicion (markdown) |
124161| Ctrl+Enter | Ejecutar y avanzar (code) / Salir y avanzar (markdown) |
125- | Ctrl+Shift+F | Formatear codigo |
162+ | Ctrl+Shift+F | Corregir indentacion |
126163| Escape | Salir de edicion markdown |
127164| ? | Mostrar/ocultar modal de atajos (fuera de editor) |
128165
0 commit comments