# RichTextEditor Changelog

## Version 2.0.0.7

### Improved — Yjs textSync caret preservation
The `textSync: true` Yjs binding now saves and restores the local caret as a
character-offset into the body before / after a remote update is applied,
instead of letting the cursor unconditionally snap to position 0. The caret
still jumps when the remote edit lands at or before the local cursor (HTML
character offsets don't track rendered offsets exactly), but for the common
case of two users typing in different parts of the document the local caret
now stays put.

The proper per-node binding (one `Y.Text` per block element with shared `Y.Map`
keyed by stable IDs) is still planned for a future release; this is a quality-
of-life improvement to the existing whole-HTML-string MVP.

## Version 2.0.0.6

### Added — Dictation plugin
New `plugins/dictation.js`. Speech-to-text via the Web Speech API with a toolbar microphone button. Opt-in via `config.dictationEnabled = true`. JS API: `editor.dictation.start() / stop() / toggle() / isListening() / isSupported()`. Live interim transcripts render under the cursor. Chrome / Edge / Safari / Opera supported; Firefox detects as unsupported and hides the button.

### Added — Mobile toolbar stylesheet
New `rte_mobile.css`. Add class `rte-mobile` to any editor container to reshape the toolbar for phones: horizontally-scrolling strip, 44×44 tap targets, sticky header, bottom-sheet dropdowns / dialogs / review drawer. Scoped behind `@media (max-width: 768px), (pointer: coarse)` so desktop layouts stay unchanged.

### Improved — Paste from Word list conversion
Rewrote `_ConvertWordLists` to correctly detect ordered vs unordered, handle nested levels (via `mso-list: l{N} level{M}`), and strip actual bullet glyphs (`·`, `•`, `◦`, `§`, `—`) instead of the previously ineffective character class. Numeric / alphabetic / Roman markers are now preserved as `<ol>` with proper nesting.

## Version 2.0.0.5

### Added — Revision history: named versions + diff API
`editor.revisionHistory` gets three new methods closing the gap against CKEditor's premium named-versions feature:
- `promptAndSnapshot(defaultLabel?)` — pops a native prompt for a version name, then takes the snapshot. Returns the entry or `null` if cancelled.
- `rename(id, label)` — rename an existing snapshot; flips its `isNamed` flag to `true`.
- `listNamed()` — return only named snapshots (handy for a "milestones only" filter).
- `diff(idA, idB)` — return `{ oldEntry, newEntry, oldText, newText, lines[] }` so callers can build a side-by-side diff UI on top of the plugin's data.

Each entry now carries an `isNamed` boolean. Snapshots with an `auto: true` metadata flag always stay unnamed. Existing entries that were saved before this release are treated as unnamed.

## Version 2.0.0.5

### Added — DOCX export client helper
- New `editor.aiToolkit.exportDocx({ url?, fileName?, title?, html?, onError? })` builds a POST to the server DOCX endpoint (default `/richtextbox/export/docx`) and triggers a browser download via Blob + anchor. Falls back to `navigator.msSaveOrOpenBlob` on legacy IE/Edge.
- Pairs with the new `DocxExporter` server in RichTextBox.AspNetCore 1.0.0-preview.11.

### Added — Yjs text sync preview (opt-in concurrent typing)
- `editor.collab.attach({ doc, provider, textSync: true })` binds the editor's full HTML to a shared `Y.Text` on the given Y.Doc. CRDT merges concurrent inserts/deletes at character level; two users typing at the same time both see each other's edits survive.
- Tradeoffs in this preview: remote updates re-set the body (caret snaps to start), HTML character offsets don't align with rendered caret offsets. Per-node binding is on the roadmap.
- New config keys: `collabTextSync` (bool, default false) and `collabTextName` (string, default `richtextbox.body`).

## Version 2.0.0.4

### Added — Streaming AI client helper
- New `editor.aiToolkit.streamRequest({ url, body, onDelta, onResponse, onDone, onError })`
  consumes Server-Sent Events from a streaming AI endpoint (like the new
  `MapRichTextBoxAiStream()` endpoint in RichTextBox.AspNetCore 1.0.0-preview.10).
  Returns `{ promise, abort() }`. Browsers without `fetch`/`ReadableStream`
  fall back to a non-streaming XHR against the same endpoint with `/stream`
  stripped — same callback shape either way.
- Works against any SSE source that follows `data:` / `event: response` /
  `event: done` framing; not tied to RichTextBox.

## Version 2.0.0.3

### New plugins — Collaboration & Review
- **Slash commands** (`plugins/slashcommand.js`): type `/` at the start of a line (or after whitespace) to open an inline command picker with 15 built-in blocks / inserts (H1-H3, lists, quote, code block, divider, table, image, link, emoji, template, today's date). Every `aiToolkitActions` entry is auto-imported into the same menu. Public API: `editor.slashCommands.register/remove/list/open/close`. Demo: `Demo/slashcommand.html` + `.aspx`.
- **@mentions** (`plugins/mentionplugin.js`): trigger-character framework for `@`, `#`, `[[wiki]]`, etc. Async source with debounce + "Searching…" loading state, atomic non-editable pills that backspace removes as a single unit, per-trigger `renderItem`/`renderInsert`/`insertClass` hooks. Demo: `Demo/mentionplugin.html` + `.aspx`.
- **Tracked Changes** (`plugins/trackedchanges.js`): Word-style human suggesting mode. Intercepts `beforeinput` and wraps insertions in underlined spans + deletions in strikethrough spans (without removing them) in the current user's color. Sequential deletes merge into one span; backspacing inside your own just-typed insert shrinks it. Per-author accept / reject. Requires `config.currentUser`. Demo: `Demo/trackedchanges.html` + `.aspx`.
- **Comments** (`plugins/comments.js`): threaded sidebar comments anchored to selection ranges. Composer + reply + resolve + delete. Clicking any highlighted span focuses its thread. Demo: `Demo/comments.html` + `.aspx`.
- **Revision History** (`plugins/revisionhistory.js`): snapshot browser with sandboxed preview iframe and an LCS-based line diff tab. Toolbar button + `Ctrl+Shift+H` shortcut. Manual snapshots or opt-in `revisionHistoryAutoSnapshotMs` debounced auto-snapshots. localStorage persistence; optional `revisionHistoryUrl` server POST. Demo: `Demo/revisionhistory.html` + `.aspx`.
- **Yjs Collaboration** (`plugins/yjscollab.js`): presence (remote cursors + name badges) + shared review ledger sync via a `Y.Map`. Peer-dependency pattern (Yjs + provider are the customer's choice). Concurrent text editing is not in v1 — the plugin scope is "review together" not "type together". Demo: `Demo/yjscollab.html` + `.aspx`.

### Shared Review Ledger (additive in `aitoolkit.js`)
- New `editor.reviewLedger` API: `add`, `update`, `remove`, `get`, `list`, `refreshPanel`. Used by Tracked Changes, Comments, and the AI drawer. Backward compatible: existing AI suggestions default to `{ id: "ai", name: "AI", color: "#8b5cf6" }` author.
- Extended `serializeSuggestion` / `normalizeLedgerEntry` / `normalizePersistedSuggestion` with `changeType`, `author`, `replies[]`, `text`, `blockPath` fields so non-AI entries round-trip through localStorage + the optional `aiToolkitSuggestionLedgerUrl` endpoint.
- `renderReviewPanel` filters out non-AI (`changeType !== "ai-preview"`) entries so the AI drawer keeps its existing shape; Tracked Changes + Comments ship their own UIs.

### Fixes
- **Ask AI dialog Translate action did nothing.** The action definition's `target: "dialog"` was inherited by `buildLegacyOperation` at runtime, producing an `open-dialog` op (dialog is already open) instead of a real translated-text op. `defaultResolveAction`'s translate branch now filters out the `"dialog"` target and falls through to `selection-preview` / `document`.
- **AI Chat panel too small.** `rte-ai-chat-panel` width bumped `340px → 420px`, shell `min-height` `460/520 → 560/660`, feed row `minmax(0, 1fr) → minmax(180px, 1fr)`.
- **AI menu icons rendering at native (giant) size in static Zip demos.** `PublishTool/autogen_template/page.html` now links `richtexteditor/plugins/aitoolkit.css` so every generated demo HTML has the icon-sizing rules. All 35 existing demos in `Zips/` patched in place.
- **Double-folder extraction from customer zips.** `PublishTool.AddFolderToZip` no longer prefixes entries with the zip's base name — Windows Explorer "Extract All" now yields one folder level instead of `<foo>/<foo>/…`. All existing zips in `Zips/` rewrapped.

### Docs / examples
- Removed `<script src="/richtexteditor/rte-config.js"></script>` from customer-facing code examples across 40 demos + `Docs/ai-toolkit.aspx`. Kept runtime `<script>` loads on marketing sites (`demo.master`, `default.aspx`) where rte-config.js still ships as a separate file.
- Rewrote stale `rte-config.js` prose mentions in quick-start, install_div, install_textarea, ai-toolkit, configuration, and compare pages to "editable `RTE_DefaultConfig` block at the top of `rte.js`".

### Packaging
- `plugins/-combine-plugins.bat` glob-includes new plugins automatically; bundle regenerated on each build.
- `plugins/all_plugins.js` refreshed (post-session, single-layer zips).

## Version 2.0.0.2

### AI Toolkit Polish
- Tightened the Ask AI dialog: shorter labels ("Action", "Scope", "Run"), simplified copy, reduced vertical height by ~100px through denser padding and smaller corner radii.
- Simplified the apply-row button labels: "Apply", "Replace selection", "Preview inline", "Insert below", "Replace document", "Reject" (previously the longer "Accept into/below/document" variants).
- Added a `reason` rationale to every built-in demo resolver mode (proofread, rewrite, shorten, expand, summarize, translate, justify) so the "Why this suggestion" panel always populates.
- Improved `buildDemoResult` for `proofread` so it now fixes punctuation spacing, collapses stray periods, and capitalizes the first letter. `rewrite` drops the "Here is a clearer rewrite:" preface and strips more filler phrases (`just`, `in order to`, `due to the fact that`) in addition to `very` and `really`.
- Chat panel: shorter subtitle, compact scope pill ("Selection" / "Document"), meta separator changed from `-` to `·`, "Apply plan" → "Apply" in message actions.
- Review panel: shorter subtitle and empty-state copy; smaller card radii; hover states added to control/action buttons.
- Unified the primary blue gradient between dialog / chat send / review primary buttons for visual consistency.

### Icon and Plugin Loading
- Replaced the Insert Code icon SVG with a clearer stroke-based `</>` glyph (using `currentColor` so it picks up toolbar theming).
- Added default `svgCode_insertcode` and `svgCode_aiassist` fallbacks in `rte-config.js` so those toolbar icons render correctly even when `insertcode.js` / `aitoolkit.js` aren't bundled (previously they fell back to the bookmark-shaped `svgCode_default`).
- Rebuilt `plugins/all_plugins.js` to include `aitoolkit.js` so demos using the consolidated bundle (e.g. `MinDemo.aspx`) get the AI toolkit automatically.
- Fixed a BOM-mid-file issue introduced when concatenating plugins: `-combine-plugins.bat` now uses a PowerShell block that strips any UTF-8 BOM from each source and writes a clean no-BOM UTF-8 bundle. Source plugin files (`html2pdf.js`, `imageeditor.js`, `insertcode.js`, `insertemoji.js`) were also stripped of their leading BOMs.
- Added `plugins/aitoolkit.css` to `Demo/MinDemo.aspx` so the AI button and panels are styled correctly in the minimum demo.
- Removed a stray `console.log` from the `exec_command_insertcode` handler.

### Manual Test Page
- Extended `_tests/ai-manual-test.html` to load `insertcode.js`, `insertemoji.js`, `insertgallery.js`, `inserttemplate.js`, `imageeditor.js`, and `html2pdf.js` so every default-toolbar command has its handler in the manual test environment.

## Version 2.0.0.1

### Toolbar and Icon Updates
- Added the RichTextBox-style bottom toolbar row to the built-in `full` toolbar.
- Added pure JavaScript toolbar buttons for `Insert Merge Field`, `Insert Footnote`, `Insert Table of Contents`, `Insert Page Break`, and `Revision History`.
- Restored the original RichTextEditor `ForeColor` and `BackColor` toolbar icons after testing the RichTextBox icon set.
- Added the original RichTextBox-style paragraph operation icons to the last toolbar row.

### Dialog Improvements
- Reworked `Insert Comment` to use the RichTextBox plugin-style behavior in the JavaScript editor.
- `Insert Comment` now shows the selected-text preview, uses the smaller `Add Comment` dialog flow, highlights selections with a yellow comment mark, and inserts a compact comment marker when there is no selection.
- Updated the JavaScript editor `Insert Image`, `Image Gallery`, `Insert Template`, and document-related dialogs to use the cleaner RichTextBox dialog styling.
- Removed the `Camera` option from the `Insert Image` command menu.

### JavaScript-Only Features
- Added a built-in pure JavaScript `Insert Comment` command path.
- Added a built-in pure JavaScript `Insert Page Break` command path.
- Added pure JavaScript implementations for `Insert Merge Field`, `Insert Footnote`, `Insert Table of Contents`, and `Revision History`.
- Kept unsupported server-side-only commands out of the live toolbar and demo workflow.

### Demo and UX Cleanup
- Increased the width of the `Demo/Default.aspx` experience by widening the shared shell layout.
- Cleaned up the JavaScript demo page so the main toolbar only shows real JavaScript features.
- Removed preview-only/server-side icon sections that did not have a real JavaScript implementation.
- Added cache-busting updates to the demo asset URLs while iterating on toolbar and dialog behavior.
- Hid the paragraph floating toolbar by default in the JavaScript demo configuration.

### Visual Matching
- Applied the RichTextBox color picker styling to the JavaScript editor color picker UI.
- Applied RichTextBox floating toolbar styling to the JavaScript editor.
- Updated the dialog button and toolbar icon set so RichTextEditor and RichTextBox feel more consistent while preserving the preferred legacy color buttons.

## Version 2.0

### Scrollbar Fix
- **Vertical scrollbar not appearing**: Fixed iframe height not being recalculated when content is loaded via `setHTMLCode` or on initial editor load, causing the scrollbar to never appear even when content exceeds the editor height.
- **Flex overflow fix**: Added `min-height:0` to the `rte-content` container to prevent the flex layout from growing instead of scrolling.
- **Plus button scroll**: Fixed "add paragraph" button not updating iframe height, so the editor now scrolls to the new paragraph correctly.

### Bug Fixes (from bug list)
1. **Upper-roman list display**: Fixed typo in roman numeral list preview (`rte-config.js`) - duplicate characters in value III.
2. **Enter key scrollbar**: Rewrote `__AdjustScrollTop_ForInsertPoint` with zero-rect fallback and `scrollIntoViewIfNeeded` so the cursor stays visible when pressing Enter at the bottom of the editor.
3. **Search & Replace crash**: Rewrote `replaceAll` to search from document start and added loop guard to prevent infinite loop when replacing text.
4. **Underline CSS**: Added `text-decoration` normalization in `__GetHTMLCode` so underline styling is preserved correctly in output HTML.
5. **Insert row sizing**: Table row insert now copies styles (height, cell widths) from the reference row. Fixed insert-below index calculation.
6. **getSelectedHTML API**: Added `editor.getSelectedHTML()` method to retrieve the currently selected HTML content.
7. **Textarea paste line breaks**: Plain text paste now converts `\n` to `<br>` instead of collapsing all lines into one.
8. **Image upload in table cell**: Inserting an image inside a table cell no longer creates a root-level paragraph outside the table.
9. **File upload type filter**: Changed file input `accept` attribute from `image/*` to explicit extensions (`.jpg,.jpeg,.png,.gif,.bmp,.webp,.svg`) for better compatibility.
10. **List toggle with anchors**: Fixed numbered/bullet list toggle when selection contains anchor (`<a>`) elements - consecutive inline siblings are now grouped into a single `<li>` instead of being split incorrectly.
11. **HTML comments in code view**: Code/source view now preserves HTML comments (`<!-- -->`) instead of dropping them.
12. **onChange for spaces**: Changed change detection from stripping all whitespace to normalizing whitespace, so adding/removing a single space is now detected as a content change.
13. **Excel paste colors**: Fixed `<body>` content extraction bug (`indexOf` offset calculation) and fixed CSS style parsing to split on first colon only, preserving values that contain colons (e.g., URLs).
14. **Word paste as list**: Added `_ConvertWordLists` to convert Word's `MsoListParagraph` elements to proper `<ul>/<ol>` lists. Added XML namespace and conditional comment cleanup.
15. **Firefox Ctrl+B/I/U**: Added explicit keyboard handlers for bold, italic, and underline with `metaKey` support for macOS.
16. **Image drag disappears**: Fixed image drag-and-drop within the editor - the browser's native drag is now preserved instead of being intercepted and discarded.

### SVG Icon Fixes (`rte-config.js`)
- **svgCode_justifyright**: Removed invalid `//` before closing `/>` tag - icon was not rendering.
- **svgCode_fullscreenexit**: Added missing `</svg>` closing tag.
- **svgCode_imagescale**: Removed extra `<` before `</svg>` closing tag.
- **svgCode_imagestyle**: Fixed double-quote `""` on path `d` attribute causing malformed markup.
- **svgCode_controleditlink**: Removed stray `</g>` closing tag with no matching opening `<g>`.
- **svgCode_inlinestyle**: Removed duplicate `</svg></svg>` closing tags.
- **svgCode_floatleft**: Fixed missing `>` on `</path` closing tag.
- **svgCode_link**: Changed viewBox from `0 0 20 20` to `0 0 24 24` - path coordinates extended beyond the old viewBox causing the icon to be clipped.
- **svgCode_insertlink / svgCode_unlink**: Removed unnecessary invisible `<path d="M0 0h24v24H0V0z" fill="none"/>` elements.
- Fixed double semicolons on `controlsize25` and `tablecellmerge` declarations.

### Documentation Rewrite (55 files)
- Rewrote all 55 ASPX documentation pages with clean formatting.
- Replaced pre-tokenized Prism.js HTML spans with plain code blocks for easier maintenance.
- Fixed 16+ content bugs: Chinese-only page rewritten in English, copy-paste errors, wrong descriptions, mislabeled parameters, naming inconsistencies, missing closing braces in CSS examples, typos.
- Added new `getSelectedHTML()` method documentation page.
- Updated navigation.xml: added Skin page, FAQ, All Events, and getSelectedHTML entries.
- Expanded skin configuration page with all available values and examples.

### Cleanup
- Removed debug `console.trace` call from `___Adjust_After_Content_Changed`.

---

## Version 1.015
- (No changelog recorded)

## Version 1.013
- Better selection, better bookmark

## Version 1.012
- Better drag and drop, new bookmark logic

## Version 1.011
- Better bookmark

## Version 1.010
- Fix more selection bugs

## Version 1.009
- Implement formatblock, improve LI, selection
