u2ui 1.5.3 → 1.5.4
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.
- package/el/ico/ico.js +5 -5
- package/el/rte/README.md +53 -13
- package/el/rte/manifest.json +19 -4
- package/el/rte/rte.css +31 -6
- package/el/rte/rte.js +174 -44
- package/el/rte0/README.md +37 -0
- package/el/rte0/manifest.json +33 -0
- package/el/rte0/rte0.css +9 -0
- package/el/rte0/rte0.js +56 -0
- package/el/system/styler.js +2 -0
- package/el/tooltip/tooltip.css +2 -2
- package/js/Placer/Placer.js +2 -1
- package/js/rte/AGENTS.md +142 -0
- package/js/rte/PLAN.md +488 -0
- package/js/rte/README.md +319 -25
- package/js/rte/blocks.js +7 -0
- package/js/rte/breaks.js +6 -0
- package/js/rte/classes.js +7 -0
- package/js/rte/docs/usage.md +845 -0
- package/js/rte/images.js +7 -0
- package/js/rte/link.js +8 -0
- package/js/rte/playground/README.md +95 -0
- package/js/rte/playground/hosts.html +518 -0
- package/js/rte/playground/index.html +824 -0
- package/js/rte/rte.js +56 -5
- package/js/rte/source.js +12 -0
- package/js/rte/src/browser/README.md +40 -0
- package/js/rte/src/browser/range-rect.js +82 -0
- package/js/rte/src/client/README.md +378 -0
- package/js/rte/src/client/blocks.js +38 -0
- package/js/rte/src/client/breaks.js +212 -0
- package/js/rte/src/client/classes.js +48 -0
- package/js/rte/src/client/editor.js +461 -0
- package/js/rte/src/client/external-input.js +47 -0
- package/js/rte/src/client/history.js +13 -0
- package/js/rte/src/client/images.js +275 -0
- package/js/rte/src/client/link.js +572 -0
- package/js/rte/src/client/marks.js +25 -0
- package/js/rte/src/client/source.js +182 -0
- package/js/rte/src/client/structure.js +27 -0
- package/js/rte/src/client/tables.js +162 -0
- package/js/rte/src/client/unstyle.js +32 -0
- package/js/rte/src/command/README.md +517 -0
- package/js/rte/src/command/block-boundary.js +43 -0
- package/js/rte/src/command/block-style.js +120 -0
- package/js/rte/src/command/commands.js +158 -0
- package/js/rte/src/command/delete.js +112 -0
- package/js/rte/src/command/edit.js +72 -0
- package/js/rte/src/command/element.js +45 -0
- package/js/rte/src/command/enter.js +175 -0
- package/js/rte/src/command/fragment.js +76 -0
- package/js/rte/src/command/insert.js +52 -0
- package/js/rte/src/command/list.js +284 -0
- package/js/rte/src/command/mark.js +583 -0
- package/js/rte/src/command/pending-marks.js +216 -0
- package/js/rte/src/command/table.js +207 -0
- package/js/rte/src/command/unstyle.js +248 -0
- package/js/rte/src/config/README.md +96 -0
- package/js/rte/src/config/config.js +127 -0
- package/js/rte/src/core/README.md +41 -0
- package/js/rte/src/core/core.js +156 -0
- package/js/rte/src/history/README.md +83 -0
- package/js/rte/src/history/history.js +283 -0
- package/js/rte/src/input/README.md +155 -0
- package/js/rte/src/input/external-input.js +130 -0
- package/js/rte/src/input/input-pipeline.js +414 -0
- package/js/rte/src/mark/README.md +219 -0
- package/js/rte/src/mark/dom-adapter.js +100 -0
- package/js/rte/src/mark/mark.js +133 -0
- package/js/rte/src/mark/standard.js +76 -0
- package/js/rte/src/model/README.md +71 -0
- package/js/rte/src/model/content-model.js +213 -0
- package/js/rte/src/model/html/README.md +51 -0
- package/js/rte/src/model/html/html-model.js +90 -0
- package/js/rte/src/normalize/execute/README.md +33 -0
- package/js/rte/src/normalize/execute/repair-executor.js +129 -0
- package/js/rte/src/normalize/normalizer/README.md +48 -0
- package/js/rte/src/normalize/normalizer/normalizer.js +141 -0
- package/js/rte/src/normalize/repair/README.md +70 -0
- package/js/rte/src/normalize/repair/repair-planner.js +208 -0
- package/js/rte/src/sanitize/README.md +105 -0
- package/js/rte/src/sanitize/native.js +43 -0
- package/js/rte/src/sanitize/policy.js +202 -0
- package/js/rte/src/selection/README.md +39 -0
- package/js/rte/src/selection/map/README.md +53 -0
- package/js/rte/src/selection/map/point-map.js +307 -0
- package/js/rte/src/selection/ownership/README.md +32 -0
- package/js/rte/src/selection/ownership/ownership.js +42 -0
- package/js/rte/src/selection/point/README.md +34 -0
- package/js/rte/src/selection/point/point.js +83 -0
- package/js/rte/src/selection/range/README.md +38 -0
- package/js/rte/src/selection/range/edit-range.js +223 -0
- package/js/rte/src/selection/snapshot.js +64 -0
- package/js/rte/src/source/README.md +64 -0
- package/js/rte/src/source/source.js +193 -0
- package/js/rte/src/surface/README.md +36 -0
- package/js/rte/src/surface/content.js +16 -0
- package/js/rte/src/surface/surface.js +87 -0
- package/js/rte/src/transaction/README.md +35 -0
- package/js/rte/src/transaction/transaction.js +56 -0
- package/js/rte/src/ui/README.md +255 -0
- package/js/rte/src/ui/chrome.js +214 -0
- package/js/rte/src/ui/handles.js +179 -0
- package/js/rte/src/ui/place.js +25 -0
- package/js/rte/src/ui/toolbar.js +283 -0
- package/js/rte/src/unstyle/README.md +103 -0
- package/js/rte/src/unstyle/unstyle.js +140 -0
- package/js/rte/tables.js +7 -0
- package/js/rte/unstyle.js +8 -0
- package/js/rte0/README.md +37 -0
- package/js/rte0/rte.js +7 -0
- package/js/{rte → rte0}/src/behavior.js +0 -1
- package/js/{rte → rte0}/src/events.js +0 -1
- package/js/{rte → rte0}/src/range.js +0 -2
- package/js/{rte → rte0}/src/ui.items.js +0 -2
- package/js/{rte → rte0}/src/ui.js +0 -1
- package/package.json +1 -1
- package/u2/Element.js +2 -2
- package/u2/plan-scoped-refactoring.md +133 -303
- package/u2/projects.json +18 -2
- package/u2/tools/update.repos.json.js +1 -1
- package/el/qrcode/package.json +0 -22
- /package/js/{rte → rte0}/old/NodeCleaner.js +0 -0
- /package/js/{rte → rte0}/old/Rte/Rte.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/Rte.ui.items.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/Rte.ui.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/crossbrowser.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/font/tinymce.svg +0 -0
- /package/js/{rte → rte0}/old/Rte/font/tinymce.woff +0 -0
- /package/js/{rte → rte0}/old/Rte/helpers.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/htmlparser.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/index.mjs +0 -0
- /package/js/{rte → rte0}/old/Rte/main.css +0 -0
- /package/js/{rte → rte0}/old/old.rte.js +0 -0
- /package/js/{rte → rte0}/old/range-selection.old.js +0 -0
- /package/js/{rte → rte0}/src/fixes.js +0 -0
- /package/js/{rte → rte0}/src/rte.js +0 -0
- /package/js/{rte → rte0}/src/ui/items/ai.js +0 -0
- /package/js/{rte → rte0}/src/ui/items/code.js +0 -0
- /package/js/{rte → rte0}/src/ui/items/undo.js +0 -0
- /package/js/{rte → rte0}/src/util/htmlparser.js +0 -0
- /package/js/{rte → rte0}/src/util/indentHtml.js +0 -0
package/js/rte/README.md
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# RTE
|
|
2
|
+
A modular rich-text editing engine for current browsers
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
[
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
[
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
|
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
|
-
##
|
|
324
|
+
## TODO
|
|
36
325
|
|
|
37
|
-
-
|
|
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
|
|
package/js/rte/blocks.js
ADDED
package/js/rte/breaks.js
ADDED