You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/soma/components/words
dev 12a7e5cfd3
fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers
5 months ago
..
components fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago
engine fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago
test fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago
README.md fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago
exports.ts fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago
index.ts Build TextArea component + fix locale propagation bug across soma providers 5 months ago
types.ts fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago
words-content.svelte.test.ts fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago
words-provider.svelte.test.ts fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago
words-provider.svelte.ts fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers 5 months ago

README.md

Words Soma

Soma sera el propietario del motor headless de Words.

Este directorio esta creado como staging documental. La implementacion no debe empezar hasta cerrar contrato Morfo y alcance V1.

Estado

2026-05-24:

  • Alcance V1 firmado.
  • Slice 4 de motor puro implementado en engine/.
  • Slice 5 implementa el primer Provider Soma real y el puente contenteditable.
  • Slice 6 cierra wrapper Eidos, receta visual, pack Sema y demo UIX de 6 tabs.
  • Tests focalizados en engine/engine.test.ts, words-provider.svelte.test.ts y words-content.svelte.test.ts.

Responsabilidad

  • Documento canonico JSON.
  • Estado editable/readonly/disabled/focused/empty/invalid.
  • Seleccion DOM <-> seleccion de documento.
  • Pipeline de input: beforeinput, input, composition/IME, paste, drop.
  • Comandos.
  • History.
  • Normalizacion de documento.
  • Plugins internos.
  • Serializacion JSON/HTML/Markdown.
  • Integracion con logger, clipboard, format y events de ActiveUIX.

Submodulos propuestos

words/
  README.md
  types.ts
  index.ts
  exports.ts
  words-provider.svelte.ts
  words-provider.svelte.test.ts
  engine/
    document.ts
    dom.ts
    dom-selection.ts
    selection.ts
    commands.ts
    history.ts
    input.ts
    normalize.ts
    operations.ts
    render.ts
    clipboard.ts
    serialize-json.ts
    serialize-html.ts
    serialize-markdown.ts
    logger.ts
  plugins/
    basic.ts
    marks.ts
    blocks.ts
    lists.ts
    links.ts
    history.ts
    markdown.ts
  components/
    words.svelte
    words-content.svelte
    words-placeholder.svelte
    words-toolbar.svelte
    words-toolbar-group.svelte
    words-command-button.svelte
    words-bubble-menu.svelte
    words-link-editor.svelte
    words-bubble-menu.svelte
    words-link-popover.svelte
    words-hidden-input.svelte
    words-status.svelte

Modelo minimo V1

type WordsDocument = {
	version: 1;
	children: WordsBlock[];
};

type WordsBlock =
	| { type: 'paragraph'; children: WordsInline[] }
	| { type: 'heading'; level: 1 | 2 | 3; children: WordsInline[] }
	| { type: 'quote'; children: WordsInline[] }
	| { type: 'list'; kind: 'ordered' | 'unordered' | 'check'; children: WordsListItem[] };

type WordsInline =
	| { type: 'text'; text: string; marks?: WordsMark[] }
	| { type: 'link'; href: string; title?: string; children: WordsInline[] };

type WordsMark = 'bold' | 'italic' | 'underline' | 'strike' | 'code';

Comandos V1

  • focus
  • blur
  • undo
  • redo
  • toggleMark
  • setBlock
  • toggleList
  • insertText
  • insertLineBreak
  • insertLink
  • unlink
  • clearFormatting
  • replaceDocument
  • importContent
  • exportContent

Slice implementado

Archivo Estado
engine/document.ts Modelo JSON V1, factories y helpers de marcas/texto.
engine/dom.ts Contrato data-words-*, path encode/decode y selection targets.
engine/dom-selection.ts Adaptador Selection API para leer/restaurar seleccion real del DOM.
engine/normalize.ts Normaliza documentos, bloques, inline nodes, marks y links inseguros.
engine/selection.ts Modelo de seleccion path + offset, rangos y text leaves.
engine/path.ts Navegacion de arbol, paths profundos, replace/set helpers.
engine/operations.ts Rangos, insert, marks, blocks, listas, links, Enter, Backspace.
engine/commands.ts Dispatcher tipado de comandos V1 parciales.
engine/history.ts Undo/redo por snapshots con batching y limite de stack.
engine/input.ts Traduccion de beforeinput a comandos o accion de history.
engine/render.ts Descriptor de render headless con tags y attrs para contenteditable.
engine/serialize-json.ts Parse normalizado y serialize sin mutacion implicita.
engine/serialize-html.ts Export HTML limpio sin data-words-* ni zero-width placeholders.
engine/serialize-text.ts Import seguro de texto plano a parrafos canonicos.
engine/engine.test.ts Cobertura de normalizacion, listas, rangos, links, history y teclado.

Correcciones cerradas en slice 5

  • src/uix/morfo/components/words.ts declara contrato V1: Provider, Content, Placeholder, Toolbar, ToolbarGroup, CommandButton, LinkEditor, HiddenInput y Status.
  • Morfo incluye data-focused, data-empty, data-dirty, data-disabled, data-readonly, data-required, data-invalid, data-composing, data-selection, data-block, data-command, data-state y data-status.
  • Eventos declarados con familias Sema validas: contact-focus, commit-content, commit-format, commit-link, commit-unlink, commit-history, commit-clear y signal-invalid-input.
  • Provider Soma mantiene documento, seleccion, history, active marks, focused, dirty, disabled, readonly, required, invalid e integracion con FieldProvider.
  • Content renderiza HTML seguro desde descriptores propios del motor, escucha beforeinput, paste, shortcuts de teclado y composition events.
  • HiddenInput serializa JSON canonico para formularios.
  • CommandButton ejecuta comandos de formato, listas, bloques, undo, redo, clear y commit; expone estado activo/deshabilitado por Morfo.
  • LinkEditor aplica insertLink y unlink sobre la seleccion estable del documento, expone selectedLink, canUnlink, captureSelection y feedback de URL invalida.
  • Paste HTML sin texto plano se rechaza y se reporta por el logger UIX como soma.words.
  • IME/composition queda conectado al Provider: compositionend aplica el comando final.
  • deleteWord* y deleteLine* tienen comandos propios; los beforeinput no soportados no se cancelan cuando el motor no los posee.
  • Las listas tienen salida por Enter en item vacio y Backspace al inicio del primer item; setBlock sobre listas produce un bloque por item.
  • Los botones de lista se activan por listKind, no por cualquier bloque list.
  • Los links anidados se aplanan en normalizacion y insertLink no anida dentro de un link existente.
  • exportContent expone JSON, texto plano y HTML limpio; importContent acepta JSON, texto plano y HTML seguro conservador.
  • exportContent tambien expone Markdown V1 sin dependencia externa; importContent acepta Markdown conservador para headings, quote, listas, links y marcas inline basicas.
  • Words.Content renderiza el HTML seguro del motor como contenido inicial de Svelte y usa un efecto posterior solo para restaurar la seleccion cuando el editor mantenia foco interno. La rama gestionada no monta snippets internos, de modo que wrappers Eidos/demos no apagan accidentalmente el render del documento. Tiene cobertura montando el componente Svelte real.
  • WordsProvider sincroniza cambios externos de value y selection sin remount, normaliza el documento entrante y no emite callbacks de edicion de usuario para cambios controlados desde fuera.
  • El Provider usa batch: 'typing' de beforeinput para agrupar escritura, borrado e IME contiguos en una sola entrada de undo; seleccion externa, blur, commit, undo/redo o comandos de formato cierran el batch.
  • La seleccion de rango se sincroniza desde selectionchange, teclado, puntero y select; CommandButton preserva la seleccion del editor antes de aplicar comandos de toolbar sobre el rango seleccionado.
  • Ctrl+A usa selectAll() dentro del Provider para seleccionar todo el documento en el modelo Soma y restaurar la Selection API con data-selection="range".
  • BubbleMenu calcula su posicion desde el rectangulo de Selection API, expone data-open, data-positioned, data-side y data-selection, y evita que el pointerdown del toolbar contextual colapse la seleccion antes de ejecutar comandos.

Correcciones cerradas en slice 2

  • Paths de profundidad variable para parrafos, listas y texto dentro de links.
  • getNodeAtPath, resolveTextAtPath, replaceInlineAtPath y helpers de hijos inline.
  • Operaciones de rango multi-inline y multi-bloque para reemplazo de texto.
  • Edicion real dentro de list items.
  • insertParagraph, insertLineBreak, deleteBackward, deleteForward y deleteRange.
  • unlink desde el texto interior de un link.
  • Links relativos internos (/ruta, ?query, #anchor) permitidos.
  • History con batchHistoryCommands y limite por defecto de 200 snapshots.
  • serializeWordsJson ya no normaliza ni muta silenciosamente.

Correcciones cerradas en slice 3

  • Contrato DOM estable basado en data-words-node y data-words-path.
  • Encode/decode de paths para no depender de indices inventados por el DOM.
  • Mapping WordsSelection <-> targets DOM serializables y clampados.
  • Render headless de bloques, listas, items, links y text leaves.
  • Texto vacio renderizable mediante placeholder zero-width y data-words-empty-text.
  • Traduccion de beforeinput para texto, Enter, line break, delete, formato, history undo/redo y composition guard.

Correcciones cerradas en slice 4

  • Lectura de Selection API desde DOM real mediante data-words-path.
  • Soporte de rangos que cruzan texto normal y texto dentro de link.
  • Restauracion de Selection API desde targets DOM codificados.
  • Clamp de offsets DOM contra texto renderizado y placeholders vacios.
  • Primitivas de paste seguro: texto plano con normalizacion de saltos de linea, HTML ignorado hasta tener importador seguro.
  • Primitivas IME/composition: begin, update y commit final como comando explicito.

Pendiente despues de Provider

  • Importador HTML avanzado con tablas, imagenes y HTML arbitrario completo.
  • Drop/clipboard avanzado a traves de servicios ActiveUIX.
  • Popover flotante de links anclado directamente al rango seleccionado. V1 usa LinkEditor dentro de toolbar/bubble menu con el popover reutilizable de Eidos.
  • Cobertura de componentes Svelte renderizados para el resto de partes compuestas.
  • Eidos recipe y demo bajo web/routes/uix/components/words ya existen; queda auditoria visual iterativa conforme crezcan BubbleMenu/import/export.

Reglas de seguridad

  • HTML importado debe validarse y normalizarse antes de entrar al documento.
  • Links solo con protocolos permitidos.
  • javascript:, data: y protocolos desconocidos deben rechazarse o convertirse en error logueado.
  • No aceptar nodos desconocidos silenciosamente.
  • Paste desde HTML debe tener fallback a texto plano si la importacion falla.

Eventos

Soma dispara runtime.trigger(...) solo para eventos declarados en Morfo. Cambios internos frecuentes deben agruparse y convertirse en commit-content cuando proceda.

Powered by TurnKey Linux.