gitoriaLog in with ident

components

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commit4b4dabe54b4dabe5State of 2026-09-27, before the move to gitoriamre4b4dabe5/STATUS.md

20.0 KB

  1. # STATUS
  2. ## 2026-09-26 — ticket #4: file upload, one file (pure Hybriel, rebuilt on hybriel#94)
  3. `components/file-upload/file-upload.hl` (ONE file, own `Style`, no `.js`) + `demo.hl` (`/file-upload`) + README; home entry and routes added. Choose or drop: name, size, progress (`on client uploadProgress`), then "Uploaded" and a list. The file goes through `emit server saveFile(file)`; the demo stores it in storage/uploads (random name, 24 h). One file at a time. The earlier parked build was not reused. Gate: 154 checks (drop 3 MB: progress to 100%, bytes stored; choose via input; no console errors). Not deployed; not tested: Firefox, a very large file.
  4. ## 2026-09-26 — ticket #12 (2nd fix: choose button, caret lost)
  5. The first fix missed the File button and a lost caret (the point sat at the surface end, not in the item). Now the block is put after the list as elements whenever the point is in a list or at the surface end after a list. Gate checks drop / paste / choose × caret in item / no caret: 147 passed, 0 failed. Not deployed.
  6. ## 2026-09-26 — ticket #12 (1st): a file added in a list item
  7. A file/image dropped, pasted or chosen with the caret inside a list item now lands as its own block after the list (before: glued to the item text, `- second![x.png](…)`). Gate: 142 passed, 0 failed. Not deployed.
  8. ## 2026-09-26 — ticket #9: files and images in the Markdown editor
  9. Drop / paste / "File" button (several files): `emit server mdUpload(files)` (hybriel#94, files over HTTP with progress), a progress row per
  10. file under the toolbar (`on client uploadProgress`), then `![name](url)` (images, drawn in the editor; only http(s) and `/path` src) or
  11. `[name](url)` at the drop point / caret. The app stores: demo.hl answers the face (storage/md-files, random name, known extensions only,
  12. 24 h, 5 MiB `uploadMax`) and project.hl serves `/md-editor/files/*` (nosniff + sandbox). No XHR/fetch in the component. Gate: 141 passed, 0 failed
  13. (3 dropped files → 2 images + link, progress to 100%, images load, pasted image, javascript:/data: image refused). Not deployed; on the live
  14. site storage/ persists (bind mount). Not tested: Firefox, touch, a real 1 GiB file.
  15. ## 2026-09-26 — mission 037: re-vendored Hybriel master e6720b1f
  16. `bin/hybriel` + `plugins/` from hybriel master e6720b1f (includes #103/#104, #105 f15a2f7f, #106, #94 c12065d8; old copy in
  17. `.scratch/pre-037/`). No local patch. Gate `node tests/browser.mjs`: 132 passed, 0 failed. Dev server (`~/scratch-037/hashcheck.sh
  18. components.hybriel.worldapi.org COMPONENTS /`, port 8720): `/__hl/hl-runtime.js?v=…`, `/__hl/web/client.js?v=…`, `/__hl/app.css?v=…`
  19. (immutable), bare `/__hl/app.css` → no-cache, 0 unhashed refs. Not deployed.
  20. ## 2026-09-26 — ticket #11: month view marks the visitor's today
  21. The browser's today (and language) was only read when a pointer/finger/key first reached the month view, so until then the server's UTC date was marked. Now the month view reads it at load (mount hook: 100 ms CSS animation, as in md-editor); touch/hover stay as a fallback. Gate now runs the browser in Pacific/Kiritimati (UTC+14, a day ahead of the server) and waits for today without any pointer. Gate: 132 passed, 0 failed. Not deployed.
  22. ## 2026-09-25 — ticket #10 (2nd fix): closers, and code is only text
  23. Typing a closer on the empty indented line between an auto-inserted pair (`if (x) {` Enter `}`) now closes it (`if (x) {\n}`), no doubled `}`. The code was already only ever text (surface built with `textContent`/text nodes, never as markup); new gate checks type `if (x) {` unclosed, `</div><b>x` and `<img src=x onerror=window.__pwned=1>`: page structure unchanged, text literal, `window.__pwned` undefined. Gate: 131 passed, 1 failed (`today is marked` — date check of the date picker, not this ticket). Not deployed.
  24. ## 2026-09-25 — ticket #10: code editor (pure Hybriel)
  25. `components/code-editor/code-editor.hl` (ONE file, own `Style`, no `.js`) + `demo.hl` (`/code-editor`: a Hybriel and a JS editor, the second with `spaces = 2`) + README; home entry and routes added.
  26. Port of custom-ide's CodeJar editor (renderer/vendor/codejar.js): one `contenteditable="plaintext-only"` surface, highlighted tokens as `<span class="tok-…">` (hybriel / js / plain: comments, strings, numbers, keywords, function names, Capitalised names), caret kept as text offsets across the repaint, line-number gutter, Tab / Shift+Tab (also on several selected lines), Enter keeps the indent (+ one level after `( [ {`, closer moves down), autoclose of brackets/quotes (with wrap and step-over), own undo/redo history (Ctrl+Z, Ctrl+Shift+Z / Ctrl+Y), paste as plain text. Value in a hidden `<input name>` + bubbling `input` event; mount hook = the 100 ms CSS animation of md-editor.
  27. Hybriel facts learned: `let h = root.list` COPIES a list held on a DOM element — mutate `root.list` in place; `from` is reserved (also as a parameter); Chrome shows a last empty line only when one more line feed follows, so the surface always carries one extra trailing `\n` that is stripped when read; `execCommand('insertText')` / CDP `Input.insertText` split lines into `<div>`s in plaintext-only, so paste is handled by the component.
  28. Not ported: search, minimap, breadcrumbs, change bars, read-only, drop handling (native), scrolling the caret into view after Enter at the bottom of a tall editor. Gate: 119 passed, 0 failed (real keys: highlight, numbers, Tab/Shift+Tab, Enter indent, autoclose, undo/redo, paste, form post, 390 px). Not deployed; not tested: Firefox, Safari, touch, IME.
  29. ## 2026-09-25 — ticket #8: Markdown WYSIWYG editor (pure Hybriel)
  30. `components/md-editor/md-editor.hl` (ONE file, own `Style`, no `.js`) + `demo.hl` (`/md-editor`, two editors) + README; home entry and routes added.
  31. Port of worldapi-components/md-editor.js: headings 1-6, paragraphs, lists, fenced code, `code`, links, *em*, **strong**; toolbar (B I <> Link H lists Block undo redo);
  32. typing rules (`# `, `- `, `1. `, closed `**x**` `*x*` `_x_` `` `x` ``, ``` + Enter); Ctrl+B/I/E/K, Ctrl+Alt+0-3/C, Ctrl+Shift+7/8, Ctrl+Enter, Backspace at block start;
  33. paste/drop read as Markdown (HTML pasted stays text); "Markdown source" switch; value in a hidden `<input name>` + bubbling `input` event; an untouched value is returned byte for byte.
  34. How: contenteditable surface built in handlers (createElement only), never re-rendered by the framework; mount hook = a 100 ms CSS animation whose `animationiteration` fires after hydration.
  35. Hybriel facts learned: plain lists are COPIED when passed to a function (a function must return its list); `parent` `set` `on` are reserved words; a `<form>` inside a form breaks hydration (`claim: no element for …`), so the link form is a plain element.
  36. Not ported: textarea "enhance" mode, disabled/readonly/toolbar="none", the `[text](url)` typing rule, per-block byte-for-byte spelling, MdEditor.markdown API; files/images = ticket #9. The form post turns LF into CRLF (HTML rule).
  37. Gate: 88 passed, 0 failed (real keys and clicks: typing rules, toolbar, undo, link form, javascript: refused, paste, source switch, form post, 390 px). Not deployed; not tested: Firefox, Safari, touch.
  38. ## 2026-09-25 — ticket #7 (2nd try): a copied component is styled without tokens
  39. Every colour in the four components' `Style` is now `var(--color-x, <palette value>)`: the palette value is the fallback, so a component
  40. copied into an app with no tokens still gets its colours; an app that imports `shared/tokens.hl` (and sets its accent) overrides them.
  41. Checked in a bare app (month-view.hl + clock.hl, empty styles file, no tokens): served css carries the component rules and the month view
  42. looks the same as on the site (screenshots compared by eye; page background/heading are the app's own). Gate: 57 passed, 0 failed. Not deployed.
  43. ## 2026-09-25 — ticket #7: every component carries its own Style
  44. month-view, date-picker, range-picker and pagination each have a `Style { }` in their file (scoped by the component's tag, colours as
  45. `var(--color-…)` semantic tokens, buttons styled inside the component). `styles.hl` keeps only the page layout (header, main, home list,
  46. global button). A component cannot import `shared/tokens.hl` (its `hl:web/css` import fails in a browser module), so tokens are
  47. written as css variables; the app's styles.hl must import the tokens. Gate: 57 passed, 0 failed. Not deployed.
  48. ## 2026-09-25 — mission 035: re-vendored Hybriel master 13ef4f9b
  49. `bin/hybriel` + `plugins/` from hybriel master 13ef4f9b (old copy in `.scratch/pre-035/`). No local patch existed or was needed.
  50. Gate `node tests/browser.mjs` (run with `COMPONENTS_GATE_PORT=8720 COMPONENTS_GATE_CHROME=8721-8729`): 72 passed, 0 failed
  51. before and after (also on 9d608332). Dev server: page links `/__hl/app.css?v=<hash>` (Cache-Control immutable); bare `/__hl/app.css` → no-cache.
  52. Not deployed (architect).
  53. **File uploads taken OFF the site** (creator: "the file upload still bypasses the framework using XMLHttpRequest"), until
  54. hybriel#94 (files through emit): routes `/file-upload`, `/file-upload/receive|received|README.md`, `/files-upload[/README.md]`,
  55. the two home entries, their styles and gate sections removed; `components/file-upload` + `components/files-upload` moved (not
  56. deleted) to `.scratch/pre-035/upload-parked/` (with the removed styles `styles-upload.hl.txt`, gate section
  57. `gate-upload-section.mjs.txt` and the pre-change sources in `src/`). New gate checks: home lists no upload, the four URLs 404,
  58. `grep -rE "XMLHttpRequest|fetch\(" components/` finds nothing. Gate: **57 passed, 0 failed**. Byrodin: deploy.sh has no
  59. --delete, so the old folders stay there unused (no route imports them).
  60. ## 2026-09-25 — ticket #2: a clicked day now lands in the field (live it stayed empty)
  61. Live, with a real mouse click, the day set the field's `value` attribute but the field showed nothing (the input's `value` property
  62. stayed empty); locally the same click worked, so the gate missed it. Cause: the fields were rows bound to `values`/`invalids`, and every
  63. pick re-assigned `rows`, which re-renders the inputs. Fix: `rows` is never re-assigned; a pick / typed text is written to the input
  64. element itself (`value`, `aria-invalid`) from the handler. The gate now moves the pointer first, holds the button 100 ms, and checks the
  65. input element is the same one after a pick. Gate: 72 passed, 0 failed. NOT reproducible locally (also not with 80 ms lag), so the live
  66. fix is unproven until deployed. Not tested: Firefox, Safari, touch.
  67. ## 2026-09-25 — ticket #2 reworked: date picker in pure Hybriel
  68. The creator's reason for "total fail" was hand-written .js. `date-picker.js` and its route are deleted; the date picker is ONE
  69. file, `components/date-picker/date-picker.hl`, built like the range picker (own month grid, focus-within popup, `Date`/`Intl` read
  70. in a View handler when a field gets focus). `DatePicker { names = "arrival,departure" }` makes one field per name, each posts by its
  71. name; the month arrows, typing, an impossible date (`aria-invalid`), Escape, and the form post are all covered. It no longer needs
  72. the month view component. Gate: 71 passed, 0 failed. No `.js` of this project's own is left in `components/`.
  73. Hybriel limits met: a View attribute cannot be a list literal or expression (so `names` is a string, row `hint` a field);
  74. a host cannot read the child's values (hybriel#87). Not tested: Firefox, Safari, touch.
  75. ## 2026-09-25 — ticket #1 reworked again: month view without any .js
  76. The real reason for "total fail" (creator, via the architect): the components were hand-written .js files. `month-view.js` is deleted
  77. (file, route, script tags). The browser's today and language now come from Hybriel handlers in `month-view.hl` (`Date`/`Intl` are browser
  78. globals of View handlers) — read once when the pointer, a finger or the keyboard first reaches the month view, or on the first click of
  79. ‹ ›; until then the server's UTC date and English names show (Hybriel has no mount event). The month view is on the home page and has
  80. its demo page. Gate: 69 passed, 0 failed. STILL hand-written .js: `components/date-picker/date-picker.js` (ticket #2, not this one).
  81. ## 2026-09-25 — ticket #4 reworked: file upload in pure Hybriel
  82. Rejected because the components "write fucking javascript files". `file-upload.js` and `demo.js` are deleted; the component is ONE
  83. `file-upload.hl` (drop, choose, XHR with real progress, list of uploaded files via optional `listUrl`). The `Uploaded` list moved
  84. into the component (a host cannot hear a child's emit, hybriel#87). Finding: writes made in an async callback (XHR progress/onload)
  85. are never painted — only a DOM event's handler repaints; workaround: the callback dispatches standard DOM events (`progress`, `load`)
  86. at elements whose handlers write the state. Gate: upload checks pass (drop, chosen file, list, no .js served, no console errors).
  87. ## 2026-09-25 — ticket #3 reworked: date range picker in pure Hybriel
  88. Rejected because the components "write fucking javascript files". The range picker is now ONE file, `components/range-picker/range-picker.hl`
  89. (month grid, state, clicks, typing, Escape — all Hybriel; `Date`/`Intl` are browser globals of the View handlers); `range-picker.js` is deleted,
  90. and it no longer needs the month view. The field has a `name` and posts in a form. The demo lost the start/end outputs (a host cannot read a
  91. child member, hybriel#87). Gate: 56 passed (real clicks, swap, 9 days between, typed range, invalid range, form post, no .js file).
  92. Learned: `aria-invalid = x` is parsed as a subtraction — write `'aria-invalid' = x`; an element's attributes and `on` handlers must sit
  93. on ONE line (a newline before `on` is a parse error).
  94. STILL hand-written `.js` (not part of this ticket): month-view.js, date-picker.js, file-upload — the same rework applies.
  95. ## 2026-09-25 — ticket #1 rework (rejected: "total fail")
  96. The ticket's test is "open the site: the month view is there" — it was only behind a click. The month view now sits at the top of the
  97. home page (`components/index.hl`), the component list below; the demo page `/month-view` stays. Gate: 49 passed, 0 failed.
  98. The creator gave no reason beyond "total fail", so this is my reading; the rest is unchanged.
  99. ## 2026-09-25 — ticket #2 reworked: date picker for input fields
  100. The first build was one hard-wired field (fixed id, no name, one per page) and was rejected ("total fail", no reason given).
  101. Now `DatePicker { }` is placed once and EVERY `input.date-field` opens the month under itself (placed under the focused
  102. field), so several fields work on one page and post by their own `name`. The demo has two fields in a GET form.
  103. Gate: 55 passed, 0 failed (real mouse clicks; second field; typed month; impossible date; Escape; form posts both).
  104. The month view's next-month check is timing-flaky (English name before the browser's language arrives); passes on rerun.
  105. Not deployed; not tested: Firefox/Safari, touch. The range picker is unchanged (own field, not together with this one).
  106. ## 2026-09-25 — ticket #5 reworked: multiple file upload in pure Hybriel
  107. Rejected because the components "write fucking javascript files". `components/files-upload/files-upload.hl` is now the whole component
  108. (`files-upload.js` and its route are gone): drag/drop/change handlers, `fetch` (awaited inside the handler) per file, one row each, count line.
  109. Gate (tests/browser.mjs, multi section): 3 dropped = 3 rows, all Uploaded, "3 uploaded", 2 chosen add 2, no script served, no overflow at 390 px.
  110. GAPS: (1) real progress percent is impossible: an `XMLHttpRequest` `onprogress`/`onload` callback (or an `emit` from it) runs but the
  111. page does not take the state it writes (only handler code that finished normally renders), and `new Promise` inside a handler breaks it;
  112. so the bar is 0 → 100. (2) the `uploaded` / `uploadsdone` events for the Markdown editor are gone (hybriel#87).
  113. Note: another worker is reworking file-upload (ticket #4) in the same folder; its gate section may fail until it is done.
  114. ## 2026-09-25 — ticket #4: file upload (one file)
  115. Built `components/file-upload/` (component, script, demo + demo list script, README): drop zone + "Choose a file"; the file is
  116. POSTed (XHR, for real progress) to the component's `data-url` as `?name=<file name>` with the bytes as body; shows name, size,
  117. progress bar, "Uploaded"/"Failed (…)"; fires `uploaded` / `uploadfailed`. The app decides where it is stored: the demo's receiver
  118. (`/file-upload/receive`, project.hl) keeps only name and size (last 20, in memory) because hl:fs cannot write raw bytes yet.
  119. Gate: 40 passed, 0 failed (drop with name/size/100%, demo list, chosen file, no console errors, no overflow at 390 px).
  120. Not deployed; not tested: Firefox, big files, an app that really stores bytes. One per page; one file at a time.
  121. ## 2026-09-25 — ticket #3: date range picker
  122. Built `components/range-picker/` (component, demo, bridge script, README) on the month view, like the date picker: one field
  123. "YYYY-MM-DD – YYYY-MM-DD"; first click = start, second = end (earlier second click swaps), start/end marked, days between
  124. highlighted. Gate: 32 passed, 0 failed (incl. swap, between = 9 days, typed range, impossible range invalid, no console errors).
  125. Not deployed; not tested: Firefox, a real form post. One per page, not together with the date picker (shared month view state).
  126. ## 2026-09-25 — ticket #2: date picker
  127. Built `components/date-picker/` (component, demo, bridge script, README) on the month view; the month view got a hidden
  128. `#month-view-goto` input (jump to a "YYYY-MM-DD" month). Gate: 21 passed, 0 failed (closed at first, click opens, picked
  129. day = YYYY-MM-DD in the field and the month closes, typed 2028-02-29 opens February and marks it, impossible date marks
  130. the field invalid, no console errors, no overflow at 390 px). Not deployed; not tested: Firefox, a real form post.
  131. - The popup opens with CSS `:focus-within` (no class/`if`: hl:web re-renders reset them). A `<label>` around the picker
  132. refocuses the field on every click in the month — do not wrap it.
  133. - Data out still goes through the script (the month view's `emit` does not reach the host, hybriel#87). One per page.
  134. ## 2026-09-25 — ticket #1: month view
  135. Built: the app (Hybriel/hl:web, Docker, deploy.sh, gate) and the month view component (`components/month-view/`).
  136. - Verified: `node tests/browser.mjs` → 12 passed, 0 failed (server render of 42 days; today marked by the browser's date;
  137. next/prev; February 2028 has 29 days and starts on a Tuesday; December 2027 starts on a Wednesday; no console
  138. errors; no overflow at 390 px). `./deploy.sh --dry-run --target <local dir>` passes the gate.
  139. - Not deployed (architect). Not tested: a real Byrodin container, Firefox.
  140. - The first render is the server's UTC date and English names; the browser then sets its own today and language
  141. (`month-view.js` → hidden input). Between the two a moment of English names is possible.
  142. ## Hybriel findings (reported)
  143. - A nested `for` (rows → days) is not re-rendered when the outer list is reassigned: only the title changed; a flat
  144. list of 42 days works. So the component uses a flat list.
  145. - `emit` from a composed component's handler did not reach a handler of the same name in the host page; a host cannot read
  146. a composed member without redeclaring it (which overrides the child's value). So the month view has no data out yet.
  147. ## 2026-09-25 — ticket #6: pagination
  148. Built `components/pagination/` (component, demo, README): `Previous 1 … 44 45 46 … 89 Next`, no script, `Pagination { pages = 89 }`.
  149. Home entry, `/pagination` demo and README route, styles added. Gate extended (page 1, 4, middle, last, Previous, a click on … does nothing).
  150. No data out yet (hybriel#87). Not tested: Firefox. Hyphenated attributes (`aria-*`, `data-*`) do not compile / render literally in hl:web, so
  151. no ARIA attributes on the buttons.
  152. ## 2026-09-26 — ticket #8 fix: typed Markdown shortcuts are consumed
  153. `# `, `- `, `1. ` typed at the start of a paragraph, an (emptied) heading or a list item now drop the marker (no more `# # Heading`,
  154. `- - two`); a marker of the other list kind switches the list. Emptied surface gets a plain `<p>` (no nested paragraphs).
  155. Gate: 8 new checks typing character by character with real keys (126 passed; the one failure, "today is marked", is a
  156. local-vs-UTC date mismatch around midnight, not the editor). Not deployed.

Branches

Latest commits

  • 4b4dabe5State of 2026-09-27, before the move to gitoriamre