u2ui 1.5.3 → 1.5.7

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.
Files changed (146) hide show
  1. package/el/ico/ico.js +5 -5
  2. package/el/rte/README.md +53 -13
  3. package/el/rte/manifest.json +19 -4
  4. package/el/rte/rte.css +31 -6
  5. package/el/rte/rte.js +174 -44
  6. package/el/rte0/README.md +37 -0
  7. package/el/rte0/manifest.json +33 -0
  8. package/el/rte0/rte0.css +9 -0
  9. package/el/rte0/rte0.js +56 -0
  10. package/el/system/styler.js +2 -0
  11. package/el/tooltip/tooltip.css +2 -2
  12. package/js/Placer/Placer.js +2 -1
  13. package/js/rte/AGENTS.md +142 -0
  14. package/js/rte/PLAN.md +487 -0
  15. package/js/rte/README.md +319 -25
  16. package/js/rte/blocks.js +7 -0
  17. package/js/rte/breaks.js +6 -0
  18. package/js/rte/classes.js +7 -0
  19. package/js/rte/docs/usage.md +845 -0
  20. package/js/rte/images.js +7 -0
  21. package/js/rte/link.js +8 -0
  22. package/js/rte/playground/README.md +95 -0
  23. package/js/rte/playground/hosts.html +553 -0
  24. package/js/rte/playground/index.html +835 -0
  25. package/js/rte/rte.js +56 -5
  26. package/js/rte/run.out +17 -0
  27. package/js/rte/source.js +12 -0
  28. package/js/rte/src/browser/README.md +40 -0
  29. package/js/rte/src/browser/interactive.js +17 -0
  30. package/js/rte/src/browser/range-rect.js +82 -0
  31. package/js/rte/src/client/README.md +385 -0
  32. package/js/rte/src/client/blocks.js +38 -0
  33. package/js/rte/src/client/breaks.js +212 -0
  34. package/js/rte/src/client/classes.js +48 -0
  35. package/js/rte/src/client/editor.js +472 -0
  36. package/js/rte/src/client/external-input.js +47 -0
  37. package/js/rte/src/client/history.js +13 -0
  38. package/js/rte/src/client/images.js +285 -0
  39. package/js/rte/src/client/link.js +567 -0
  40. package/js/rte/src/client/marks.js +25 -0
  41. package/js/rte/src/client/source.js +182 -0
  42. package/js/rte/src/client/structure.js +27 -0
  43. package/js/rte/src/client/tables.js +165 -0
  44. package/js/rte/src/client/unstyle.js +32 -0
  45. package/js/rte/src/command/README.md +520 -0
  46. package/js/rte/src/command/block-boundary.js +43 -0
  47. package/js/rte/src/command/block-style.js +120 -0
  48. package/js/rte/src/command/commands.js +159 -0
  49. package/js/rte/src/command/delete.js +119 -0
  50. package/js/rte/src/command/edit.js +78 -0
  51. package/js/rte/src/command/element.js +45 -0
  52. package/js/rte/src/command/enter.js +175 -0
  53. package/js/rte/src/command/fragment.js +76 -0
  54. package/js/rte/src/command/insert.js +52 -0
  55. package/js/rte/src/command/list.js +284 -0
  56. package/js/rte/src/command/mark.js +583 -0
  57. package/js/rte/src/command/pending-marks.js +216 -0
  58. package/js/rte/src/command/table.js +207 -0
  59. package/js/rte/src/command/unstyle.js +248 -0
  60. package/js/rte/src/config/README.md +96 -0
  61. package/js/rte/src/config/config.js +134 -0
  62. package/js/rte/src/core/README.md +63 -0
  63. package/js/rte/src/core/core.js +247 -0
  64. package/js/rte/src/history/README.md +83 -0
  65. package/js/rte/src/history/history.js +283 -0
  66. package/js/rte/src/input/README.md +173 -0
  67. package/js/rte/src/input/external-input.js +130 -0
  68. package/js/rte/src/input/input-pipeline.js +459 -0
  69. package/js/rte/src/mark/README.md +219 -0
  70. package/js/rte/src/mark/dom-adapter.js +100 -0
  71. package/js/rte/src/mark/mark.js +133 -0
  72. package/js/rte/src/mark/standard.js +76 -0
  73. package/js/rte/src/model/README.md +71 -0
  74. package/js/rte/src/model/content-model.js +213 -0
  75. package/js/rte/src/model/html/README.md +51 -0
  76. package/js/rte/src/model/html/html-model.js +90 -0
  77. package/js/rte/src/normalize/execute/README.md +33 -0
  78. package/js/rte/src/normalize/execute/repair-executor.js +129 -0
  79. package/js/rte/src/normalize/normalizer/README.md +48 -0
  80. package/js/rte/src/normalize/normalizer/normalizer.js +141 -0
  81. package/js/rte/src/normalize/repair/README.md +70 -0
  82. package/js/rte/src/normalize/repair/repair-planner.js +208 -0
  83. package/js/rte/src/sanitize/README.md +108 -0
  84. package/js/rte/src/sanitize/native.js +43 -0
  85. package/js/rte/src/sanitize/policy.js +206 -0
  86. package/js/rte/src/selection/README.md +39 -0
  87. package/js/rte/src/selection/map/README.md +53 -0
  88. package/js/rte/src/selection/map/point-map.js +307 -0
  89. package/js/rte/src/selection/ownership/README.md +32 -0
  90. package/js/rte/src/selection/ownership/ownership.js +42 -0
  91. package/js/rte/src/selection/point/README.md +34 -0
  92. package/js/rte/src/selection/point/point.js +83 -0
  93. package/js/rte/src/selection/range/README.md +38 -0
  94. package/js/rte/src/selection/range/edit-range.js +223 -0
  95. package/js/rte/src/selection/snapshot.js +64 -0
  96. package/js/rte/src/source/README.md +64 -0
  97. package/js/rte/src/source/source.js +193 -0
  98. package/js/rte/src/surface/README.md +36 -0
  99. package/js/rte/src/surface/content.js +16 -0
  100. package/js/rte/src/surface/surface.js +87 -0
  101. package/js/rte/src/transaction/README.md +35 -0
  102. package/js/rte/src/transaction/transaction.js +56 -0
  103. package/js/rte/src/ui/README.md +271 -0
  104. package/js/rte/src/ui/caret.js +17 -0
  105. package/js/rte/src/ui/chrome.js +214 -0
  106. package/js/rte/src/ui/handles.js +179 -0
  107. package/js/rte/src/ui/highlight.js +86 -0
  108. package/js/rte/src/ui/place.js +25 -0
  109. package/js/rte/src/ui/toolbar.js +258 -0
  110. package/js/rte/src/unstyle/README.md +103 -0
  111. package/js/rte/src/unstyle/unstyle.js +140 -0
  112. package/js/rte/tables.js +7 -0
  113. package/js/rte/unstyle.js +8 -0
  114. package/js/rte0/README.md +37 -0
  115. package/js/rte0/rte.js +7 -0
  116. package/js/{rte → rte0}/src/behavior.js +0 -1
  117. package/js/{rte → rte0}/src/events.js +0 -1
  118. package/js/{rte → rte0}/src/range.js +0 -2
  119. package/js/{rte → rte0}/src/ui.items.js +0 -2
  120. package/js/{rte → rte0}/src/ui.js +0 -1
  121. package/package.json +1 -1
  122. package/u2/Element.js +2 -2
  123. package/u2/plan-scoped-refactoring.md +133 -303
  124. package/u2/projects.json +18 -2
  125. package/u2/tools/update.repos.json.js +1 -1
  126. package/el/qrcode/package.json +0 -22
  127. /package/js/{rte → rte0}/old/NodeCleaner.js +0 -0
  128. /package/js/{rte → rte0}/old/Rte/Rte.mjs +0 -0
  129. /package/js/{rte → rte0}/old/Rte/Rte.ui.items.mjs +0 -0
  130. /package/js/{rte → rte0}/old/Rte/Rte.ui.mjs +0 -0
  131. /package/js/{rte → rte0}/old/Rte/crossbrowser.mjs +0 -0
  132. /package/js/{rte → rte0}/old/Rte/font/tinymce.svg +0 -0
  133. /package/js/{rte → rte0}/old/Rte/font/tinymce.woff +0 -0
  134. /package/js/{rte → rte0}/old/Rte/helpers.mjs +0 -0
  135. /package/js/{rte → rte0}/old/Rte/htmlparser.mjs +0 -0
  136. /package/js/{rte → rte0}/old/Rte/index.mjs +0 -0
  137. /package/js/{rte → rte0}/old/Rte/main.css +0 -0
  138. /package/js/{rte → rte0}/old/old.rte.js +0 -0
  139. /package/js/{rte → rte0}/old/range-selection.old.js +0 -0
  140. /package/js/{rte → rte0}/src/fixes.js +0 -0
  141. /package/js/{rte → rte0}/src/rte.js +0 -0
  142. /package/js/{rte → rte0}/src/ui/items/ai.js +0 -0
  143. /package/js/{rte → rte0}/src/ui/items/code.js +0 -0
  144. /package/js/{rte → rte0}/src/ui/items/undo.js +0 -0
  145. /package/js/{rte → rte0}/src/util/htmlparser.js +0 -0
  146. /package/js/{rte → rte0}/src/util/indentHtml.js +0 -0
package/js/rte/README.md CHANGED
@@ -1,19 +1,9 @@
1
- # SelectorObserver.js
2
- Easily Make Elements Editable with Intuitive Controls
1
+ # RTE
2
+ A modular rich-text editing engine for current browsers
3
3
 
4
- ## Usage
5
-
6
- ```html
7
- <div contenteditable style="--u2-rte:true" id="myEditor">
8
- Start <strong>typing</strong> here...
9
- </div>
10
- ```
11
-
12
- ```css
13
- #myEditor {
14
- --u2-rte-toolbar:Bold Italic Code;
15
- }
16
- ```
4
+ RTE is a modern, modular rich-text editing engine for current browsers. Its
5
+ small core owns editor state, transactions, selections, and ranges; everything
6
+ else plugs in as an independent module. A UI is only one possible consumer.
17
7
 
18
8
  ## Install
19
9
 
@@ -23,18 +13,322 @@ import * as module from "https://cdn.jsdelivr.net/gh/u2ui/u2@main/js/rte/rte.js"
23
13
 
24
14
  ## Demos
25
15
 
26
- [behavior.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/behavior.html)
27
- [test.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/test.html)
28
- [selection-explorer.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/selection-explorer.html)
29
- [events.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/events.html)
30
- [minimal.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/minimal.html)
31
- [fixes.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/fixes.html)
32
- [range.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/range.html)
33
- [ai.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/ai.html)
16
+ [index.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/index.html)
17
+
18
+ ## Start here
19
+
20
+ Read this file for the design, then [`PLAN.md`](./PLAN.md) for implementation
21
+ status and the README beside the responsibility being changed for its exact
22
+ contract and TODOs. The current production path includes the representation of
23
+ text formatting after the command layer: registered commands replace prevented
24
+ native input, starting with Enter, while marks describe formatting such as bold,
25
+ links, and colors, how those values coexist, and how HTML represents them.
26
+ Generic commands now apply and remove one configured mark over a selected
27
+ range, derive active/mixed state, toggle it, and set an exact canonical mark set
28
+ within a caller-supplied adapter universe. Pending caret marks carry an explicit
29
+ override through the next ordinary text input or native IME composition.
30
+ Ready-made HTML adapters for bold, italic, underline, strike, code, and links
31
+ compose the same generic path.
32
+
33
+ Run the dependency-free browser suite at `/u2/js/rte/tests/` and inspect
34
+ normalization interactively at `/u2/js/rte/playground/`. The runner displays
35
+ its own test count and result. A result is cross-browser evidence only after
36
+ that exact revision has run in current Chromium, Firefox, and WebKit.
37
+
38
+ `../rte0` is a read-only behavioral reference. Reuse proven behavior and CSS
39
+ configuration ideas, but do not copy its architecture or modify its files.
40
+
41
+ ## Intended features
42
+
43
+ - Native `contenteditable`, `Selection`, `Range`, `beforeinput`, and Input
44
+ Events instead of a parallel document model.
45
+ - Stable selection snapshots that survive focus changes and controlled DOM
46
+ mutations, including backward selections, multiple roots, Shadow DOM, and
47
+ atomic elements.
48
+ - Transaction-based editing with predictable hooks before and after mutations,
49
+ selection restoration, normalization, history, and change reporting.
50
+ - Composable modules for commands, keyboard behavior, paste/drop handling,
51
+ normalization, schema rules, browser fixes, history, collaboration, and UI.
52
+ - Explicit browser policies: quirks stay isolated, feature-detected, tested,
53
+ replaceable, and never leak into the generic editing core.
54
+ - Context-aware commands that expose availability, active state, and execution
55
+ without depending on a toolbar.
56
+ - CSS-driven behavior and presentation through custom properties, selectors,
57
+ states, and modern standards such as nesting and anchor positioning where
58
+ useful.
59
+ - Semantic defaults derived from the editing host: lists create list items,
60
+ inline-only hosts stay inline, and generic block hosts create paragraphs.
61
+ - One shared core per selection context coordinates any number of editable
62
+ surfaces without duplicating document-level listeners or state machinery.
63
+ - Pluggable HTML policy aligned with the native HTML Sanitizer API. The native
64
+ adapter is implemented for applications that explicitly parse HTML strings.
65
+ Ordinary paste/drop remains browser-native and needs no fallback parser.
66
+ Applications may narrow elements and attributes without coupling security
67
+ sanitizing to structural editor normalization.
68
+ - Deterministic tests for browser input, selection direction, range boundaries,
69
+ DOM mutations, undo/redo, clipboard data, focus changes, and known engine
70
+ differences.
71
+
72
+ ## Module contract
73
+
74
+ A module declares only the capabilities it contributes and receives an editor
75
+ context during setup. It may register commands, event handlers, transforms,
76
+ normalizers, state derivations, or browser policies. Resources are returned as
77
+ objects with one idempotent `dispose()` method.
78
+ Module order and conflicts are explicit; no module reaches into another
79
+ module's private state.
80
+
81
+ Public behavior is event- and transaction-oriented. DOM mutations happen
82
+ through the editor transaction boundary so ranges can be preserved and every
83
+ consumer observes one coherent change.
84
+
85
+ ## Structure
86
+
87
+ Production responsibilities live under `src/`. Each one keeps its implementation,
88
+ tests, and README together so its local contract remains visible beside the
89
+ code. The root contains only the public entry point and project-wide clients,
90
+ tests, and documentation.
91
+
92
+ ```text
93
+ rte/
94
+ ├── blocks.js Optional block-style module and public entry
95
+ ├── classes.js Optional content-class control module and entry
96
+ ├── breaks.js Optional visible-line-break extension and entry
97
+ ├── images.js Optional image frame and sizing module and entry
98
+ ├── link.js Optional contextual link editor module and entry
99
+ ├── rte.js Stable public API, default core, and convention client
100
+ ├── source.js Optional HTML source view module and entry
101
+ ├── tables.js Optional table structure module and entry
102
+ ├── unstyle.js Optional staged remove-format module and entry
103
+ ├── src/ Production responsibilities
104
+ │ ├── browser/ Isolated native browser policies and fallbacks
105
+ │ ├── client/ Lazy batteries-included editor wiring and defaults
106
+ │ ├── command/ Registry, Enter/delete, structure, and range marks
107
+ │ ├── config/ CSS configuration and semantic host defaults
108
+ │ ├── core/ Shared root lifecycle and surface registry
109
+ │ ├── history/ Snapshot undo and redo for one surface
110
+ │ ├── input/ beforeinput, paste, drop, and composition
111
+ │ ├── mark/ Formatting values and HTML adapters
112
+ │ ├── model/ Replaceable HTML content rules and categories
113
+ │ ├── normalize/ Repair planning, execution, and normalization
114
+ │ ├── sanitize/ External HTML, attribute, and URL security policy
115
+ │ ├── source/ Surface content as readable and writable HTML text
116
+ │ ├── selection/ Selection, range, ownership, and point mapping
117
+ │ ├── surface/ State of one editable host
118
+ │ ├── transaction/ Atomic editing changes and dirty scopes
119
+ │ ├── unstyle/ Shared selection and external presentation policy
120
+ │ └── ui/ Editor chrome: toolbar, handles, placement, caret
121
+ ├── docs/ Project-wide guides
122
+ ├── playground/ Visual normalization, input, and mark inspection
123
+ └── tests/ Shared harness and cross-module browser cases
124
+ ```
125
+
126
+ Later layers depend on these public contracts, never on private
127
+ implementation.
128
+
129
+ ## Runtime and UI
130
+
131
+ The normal setup has one core for a `Document` and registers multiple
132
+ `contenteditable` surfaces with it. A surface owns its configuration, schema,
133
+ history, and current editor state; the core owns shared event routing and the
134
+ active selection context. Additional cores remain possible for separate
135
+ documents, isolated tests, or deliberately independent environments, but are
136
+ not the default architecture.
137
+
138
+ UI modules consume core and surface state without becoming part of either. A
139
+ `Toolbar` now binds application-owned command controls to the active surface,
140
+ keeps its saved selection across UI focus, and leaves markup, styling, icons,
141
+ and placement replaceable. A future static UI binds to one surface. Several
142
+ roaming and static UIs may coexist and expose different subsets of the same
143
+ commands.
144
+
145
+ `rte.js` is also the convenience layer: importing it once and opting hosts in
146
+ with `--u2-rte` lazily adds the standard Enter/input path, Bold, and one shared
147
+ default toolbar. Optional extensions can add and remove commands, controls, and
148
+ owned resources across current and future surfaces through the client without
149
+ changing the engine. The provisional decisions stay in `src/client/`; explicit
150
+ consumers import only the modules they need and never touch `editor`.
151
+
152
+ The convention client's own defaults arrive as three ordinary modules using
153
+ that same contract: `history` for undo and redo, `marks` for the ready inline
154
+ marks, and `structure` for lists, their nesting levels, and a separator. They
155
+ hold no privileged position and can be removed like any other module; every
156
+ control they contribute is gated by `--u2-rte-toolbar`.
157
+
158
+ The first substantial optional command module is `blocks.js`. It contributes a
159
+ command-valued Block style select for Paragraph, H1, H2, and H3. Applications
160
+ can replace its closed style group with their own selectors, target tags, and
161
+ attribute writers without allowing the command to reinterpret arbitrary layout
162
+ blocks.
163
+
164
+ The first lifecycle extension is `breaks.js`. It provides a CSS-defaulted,
165
+ optional toolbar toggle for presentation-only line-break marks. Its one
166
+ top-layer overlay never enters editable HTML and exercises editor-wide setup,
167
+ per-surface attachment, ShadowRoot style ownership, view-only commands, and
168
+ complete disposal.
169
+
170
+ The optional `unstyle.js` module adds a selection-only, staged remove-format
171
+ action. Its immutable policy is not tied to UI: the same ordered levels can
172
+ remove presentation cumulatively from a safely parsed paste/drop fragment.
173
+
174
+ External HTML processing has three distinct stages:
175
+
176
+ 1. Security sanitizing accepts external HTML through safe, context-aware sinks.
177
+ The implemented native adapter uses `Element.setHTML()` and fails explicitly
178
+ when that safe sink is absent. This stage is needed only when RTE explicitly
179
+ parses an HTML string rather than leaving insertion to the browser.
180
+ 2. Optional Unstyle cleanup removes configured classes, styles, presentation
181
+ attributes, and formatting wrappers without making security decisions.
182
+ 3. Structural normalization enforces the application's editable HTML model,
183
+ such as allowed blocks, nesting, attributes, and canonical markup.
184
+
185
+ The normal input path leaves paste/drop insertion native, records only elements
186
+ added during that input, removes their configured presentation, and then
187
+ normalizes their structure. `ExternalInput` optionally composes all three stages
188
+ before insertion and passes the browser's target range to `insertFragment`.
189
+
190
+ ## Configuration and defaults
191
+
192
+ Most serializable behavior is configured through inheritable CSS custom
193
+ properties. This lets a stylesheet configure an editor family while each
194
+ `contenteditable` may override only what differs. `auto` selects the semantic
195
+ default for the host element. JavaScript configuration is reserved for values
196
+ that CSS cannot express, such as functions and policy modules.
197
+
198
+ Current controls cover UI mode and toolbar items, allowed elements, block and
199
+ Enter behavior, cleanup level and timing, optional visible line breaks, and an
200
+ optional external-import Unstyle level. Future modules will add contextual
201
+ plain-text import, selection presentation, and browser-policy overrides. Defaults must
202
+ make an unconfigured editor useful and produce structurally valid HTML:
203
+
204
+ - `ul` and `ol` hosts create and retain `li` children;
205
+ - paragraph-like and other inline-only hosts never gain block children;
206
+ - generic block containers use paragraphs as their default text blocks;
207
+ - table-related hosts follow their native HTML content model;
208
+ - nested editable hosts form explicit boundaries and are never normalized by
209
+ their parent editor.
210
+
211
+ ## Commands and range formatting
212
+
213
+ RTE does not use `document.execCommand()`. Commands are explicit algorithms
214
+ executed inside transactions. They inspect the current selection, split only
215
+ the necessary boundaries, transform the covered content, restore selection,
216
+ and normalize the affected scope.
217
+
218
+ A mark operation applies or removes a semantic element, class, attribute, style
219
+ declaration, or custom representation over a range. The algebra gives every
220
+ mark a policy type, serializable value, deterministic order, and directional
221
+ exclusions. The implemented generic range commands split selected boundaries,
222
+ reuse suitable inline elements when the adapter allows it, preserve selection
223
+ direction, and treat configured atomic elements and nested editors as
224
+ boundaries. They derive selection and structural caret state and toggle a mark
225
+ without `execCommand()`. Pending marks replace the next ordinary text input.
226
+ During IME composition they leave every native mutation untouched, track its
227
+ live start, and apply the override only after `compositionend`. Selection
228
+ movement still needs no additional listener. Exact mark-set commands resolve
229
+ exclusions, remove configured values absent from their target, and apply the
230
+ canonical result in one mapped operation. Canonical wrappers are ordered by the
231
+ same stable mark rank; redundant nesting and newly exposed equivalent siblings
232
+ are merged to a fixed point without crossing meaningful or atomic boundaries.
233
+ The shipped standard policies recognize semantic aliases, emit one canonical
234
+ tag, and remove their representation without dropping unrelated attributes.
235
+
236
+ Commands are registered per surface, expose execution and availability
237
+ independently of any UI, and declare which native `inputType` they replace. The
238
+ input pipeline prevents exactly those native behaviors and runs the command
239
+ inside one transaction. Active and mixed mark state use the same command
240
+ contract. Undo and redo operate on complete editor transactions rather than
241
+ individual incidental DOM mutations.
242
+
243
+ ## Normalization
244
+
245
+ Normalization is driven by the host's HTML content model and replaceable editor
246
+ policy, not by a list of isolated browser fixes. Rules describe permitted
247
+ children, default blocks, equivalent elements, transparent wrappers, atomic
248
+ content, splitting, lifting, unwrapping, merging, and conversion. Attributes,
249
+ classes, and styles contribute semantic weight, so a meaningful wrapper is not
250
+ discarded merely because its tag is otherwise redundant.
251
+
252
+ Cleanup has three levels:
253
+
254
+ - `minimal` repairs only invalid structures and caret-critical browser debris;
255
+ - `structural` is the default and additionally canonicalizes the affected
256
+ blocks, removes redundant wrappers, and merges equivalent neighbors;
257
+ - `canonical` recursively produces deterministic markup for an explicitly
258
+ requested subtree or the whole editor.
259
+
260
+ Work is limited through dirty scopes:
261
+
262
+ - typing normalizes the smallest affected inline or block neighborhood after
263
+ the input transaction;
264
+ - native paste/drop unstyles only observed added roots, then normalizes the
265
+ insertion neighborhood; explicitly parsed rich input sanitizes first;
266
+ - commands normalize their touched nodes and necessary ancestors;
267
+ - external DOM mutations queue only their affected subtrees;
268
+ - blur, serialization, or an explicit cleanup command may request canonical
269
+ normalization of the complete editor.
270
+
271
+ A scope expands only when a repair crosses its boundary. Normalization must be
272
+ idempotent, preserve meaningful content and selection, and never cross another
273
+ editable host.
274
+
275
+ ## Input pipeline
276
+
277
+ `InputPipeline` is installed per surface and treats native editing as a DOM
278
+ mutation followed by explicit postcondition checks. It captures live
279
+ `beforeinput` target ranges, classifies paste and drop separately, defers work
280
+ during IME composition, normalizes the smallest useful block scope, and maps
281
+ the current selection through every repair. CSS controls which of `input`,
282
+ `paste`, `drop`, and `command` trigger cleanup. Nested editors remain isolated,
283
+ and disconnecting a surface tears down its listeners. Prevented native input
284
+ passes its `inputType`, text data, and target range unchanged to the replacing
285
+ command.
286
+
287
+ The pipeline deliberately does not read or trust clipboard and drag payloads.
288
+ For native paste/drop it observes newly added element roots, maps presentation
289
+ cleanup through the current selection, and then performs normal structural
290
+ cleanup. Classes and inline styles are removed by default; existing destination
291
+ content is untouched.
292
+ The optional `ExternalInput` boundary owns rich HTML first, uses a selected
293
+ sanitizer and optional Unstyle policy, then invokes the mapped
294
+ `insertFragment` command. Sanitizer failures keep native insertion prevented
295
+ and are reported as input-phase errors. Contextual plain-text/quotation import
296
+ remains open.
297
+
298
+ ## Documentation and tests
299
+
300
+ Every production source currently has:
301
+
302
+ - its own focused documentation describing purpose, public contract,
303
+ invariants, browser considerations, examples, and concrete TODOs;
304
+ - a dedicated, comprehensive test file covering its public behavior, boundary
305
+ cases, cleanup, and relevant browser differences.
306
+
307
+ Cross-browser integration scenarios complement those per-file tests. Tests run
308
+ against real browser editing behavior; DOM emulation alone is not considered
309
+ sufficient for selection and input semantics.
310
+
311
+ The dependency-free visual playground at `playground/` runs the same planner,
312
+ normalizer, point mapping, range, input, and mark-command code as production. It
313
+ can inspect invalid DOM structures and visualize class and bold mark behavior,
314
+ pending caret input, and the roaming toolbar on a live selection.
315
+
316
+ The current suite combines fixture tests, direct event integration tests,
317
+ seeded generated cases, and browser-regression cases. Later command, clipboard/drop, generated DOM/range,
318
+ and history phases add trusted interactions and their exact invariants. Across
319
+ all phases, core invariants include valid host structure, idempotent
320
+ normalization, stable canonical output, equivalent results for forward and
321
+ backward selections, preserved selection intent, complete cleanup, and exact
322
+ transactional undo/redo.
34
323
 
35
- ## Files
324
+ ## TODO
36
325
 
37
- - /src/fixes.js: Tries to fix as many wrong browser behaviors as possible for a seamless experience.
326
+ - Add contextual plain-text/quotation import.
327
+ - Define a link-control module only after its URL-entry and validation contract.
328
+ - Exercise the new synchronous extension lifecycle with another contextual UI
329
+ before adding dependency, ordering, or asynchronous setup concepts.
330
+ - Build the browser test matrix for current Chromium, Firefox, and WebKit.
331
+ - Port only the proven ideas from `../rte0`; keep its implementation untouched.
38
332
 
39
333
  ## About
40
334
 
@@ -0,0 +1,7 @@
1
+ import {editor} from './rte.js';
2
+ import {blocks} from './src/client/blocks.js';
3
+
4
+ export {blocks, blockStyles, defaultBlockStyles} from './src/client/blocks.js';
5
+ export {BlockStyles} from './src/command/block-style.js';
6
+
7
+ editor.add(blocks);
@@ -0,0 +1,6 @@
1
+ import {editor} from './rte.js';
2
+ import {breaks} from './src/client/breaks.js';
3
+
4
+ export {breakMarks, breaks} from './src/client/breaks.js';
5
+
6
+ editor.add(breaks);
@@ -0,0 +1,7 @@
1
+ import {classes} from './src/client/classes.js';
2
+ import {editor} from './rte.js';
3
+
4
+ export {classes, classStyles} from './src/client/classes.js';
5
+ export {classMark} from './src/mark/standard.js';
6
+
7
+ editor.add(classes);