sillsdev / sillsdev/TheCombine
Evaluate KeymanWeb integration for data-entry fields (ref: Bloom POC)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 22
- Forks
- 10
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 9
Description
Summary
Evaluation of whether Bloom's KeymanWeb integration can be reused to add
Keyman keyboard support to The Combine's data-entry fields.
Source reference: src/BloomBrowserUI/bookEdit/js/keymanWebIntegration.ts on the
Keyman branch of BloomDesktop
(an explicitly-labeled proof-of-concept).
Verdict
- As a drop-in module: not usable. It's a POC — hard-coded to one Thai keyboard,
any-typed throughout, CDN-coupled, and wired to Bloom'scontenteditableDOM model. - As a reference implementation: valuable. The engine-loading and race-condition
logic transfers directly, and The Combine already has the attach points it needs.
What the Bloom file does
Lazy-loads the KeymanWeb engine once from s.keyman.com, registers the thai_kedmanee
keyboard, waits for the keyboard code (not just its stub) to finish downloading, then on
each focus attaches the engine to the focused element, activates Thai, and shows the
on-screen keyboard (OSK). It is driven by a global focusin handler over Bloom's
bloom-editable divs.
What ports well to The Combine
- Attach points already exist. KeymanWeb's
attachToControlworks on
<input>/<textarea>, andVernWithSuggestionsalready exposes both avernInputref
and anonFocuscallback. Bloom's globalfocusinbecomes a clean per-field
onFocus={() => attachKeymanWebIfNeeded(vernInput.current)}. - The non-trivial engine logic is the real payload: single-instance load promise;
the "keyboard stub registered ≠ keyboard code loaded" poll; attach-once-via-WeakSet/
activate-on-every-focus split; and theroot/resources/fontspathing fix. lang-based dispatch fits our model. We key everything on BCP47 tags, so the POC's
isThai(lang)gate generalizes to "does this writing system have a configured keyboard."
Blockers specific to The Combine
- Controlled-input conflict (biggest risk). Our fields are MUI
Autocomplete+
controlledTextFieldthat normalize viaonInputChange/onChange. KeymanWeb writes
directly into the DOM input and dispatches events; whether React's controlled state, the
Autocomplete suggestion list, and NFC normalization stay in sync with Keyman's insertions
must be verified empirically. Bloom edits uncontrolledcontenteditable, so it never
hit this. - CDN dependency vs. offline deployment. We ship as a self-hostable stack (Docker/helm/
ansible) for low-connectivity field sites. A hards.keyman.comdependency undercuts
that; the engine + keyboards would need to be bundled/served locally. (Keyman is on npm,
which would also remove the pathing hacks and theanytyping.) - Hard-coded single language. We are multilingual by project. The
WritingSystemmodel
hasbcp47/name/font/rtlbut no keyboard field, and Keyman keyboard IDs are not
1:1 with BCP47. Real use requires a data-model addition plus a per-writing-system keyboard
picker. - Repo style.
window as any/keyman: anyconflict with our strict-TS / no-any
conventions; needs a typed wrapper. - OSK ↔ Autocomplete focus. Clicking the floating on-screen keyboard can blur the input,
firingonBlurand closing the suggestion dropdown. Needs testing; the OSK may be more
friction than value versus relying on OS/browser IMEs.
Recommendation / next steps
Treat the Bloom file as a cookbook, not a component:
- Lift the load-once promise, keyboard-loaded poll, and pathing fix into a typed
keymanIntegration.ts(bundle Keyman from npm rather than CDN injection). - Drive it from field
onFocusinVernWithSuggestions(and laterGlossWithSuggestions). - Go/no-go gate: prove out one real writing system end-to-end and confirm the
controlled-input sync (blocker #1) before generalizing. - If pursued, design the
WritingSystemkeyboard field + per-writing-system keyboard
picker (blocker #3).
Findings generated during a code evaluation; details and file/line references available on request.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read src/BloomBrowserUI/bookEdit/js/keymanWebIntegration.ts on the BloomDesktop Keyman branch, then inspect VernWithSuggestions and its vernInput ref and onFocus callback. Run an end-to-end experiment with one writing system to verify controlled-input synchronization, Autocomplete focus behavior, and offline loading. The evaluation is done when there is a documented go/no-go decision and the remaining data-model and keyboard-picker requirements are clear.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend, internationalization
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100