mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-21 03:03:15 +08:00
42457ef6f7696630ca19a61893473fa98a7a6b2c
1187
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
42457ef6f7 |
fix(latex): keep inline math that starts with a digit (#15588) (#15596)
Fixes #15588. ## Root cause `preprocessLatex` escapes any `$` that is followed by a digit, assuming it is a price: ```ts // Escape dollar signs that are likely currency indicators preprocessedContent = preprocessedContent.replace(/\$(?=\d)/g, '\\$'); ``` The step above it shields existing LaTeX from that escape — but only `$$…$$`, `\[…\]` and `\(…\)`. **Single-dollar inline math was never protected.** So for `$4\vee 6=12$`: 1. the protection pass does not match it, 2. the currency pass sees `$4` and rewrites it to `\$4`, 3. the expression never parses as math, and the closing `$` is left orphaned, which throws off the parse of everything after it. That last part is why a single such expression breaks the rest of the document, as the report describes. It also explains the reporter's `{ }` workaround: `${4}` is `$` followed by `{`, not a digit, so the escape never fires. ## The fix Protect single-dollar inline math too, using the usual rule for telling math from prices: - the opening `$` is not followed by whitespace, - the closing `$` is not preceded by whitespace, - the closing `$` is not followed by a digit. ```ts /(\$\$[\s\S]*?\$\$|\\\[[\s\S]*?\\\]|\\\(.*?\\\)|\$(?!\s)[^\n$]*?(?<!\s)\$(?!\d))/g ``` Currency is unaffected, which is the part worth checking: - `costs $5 and $10 today` — the only closing candidate is the `$` before `10`, and it is preceded by a space, so no match; both escape as before. - `$100$200` — the closing candidate is followed by `2`, so no match; both escape as before. - `it costs $5.00 total` — no closing `$` at all. `$$…$$` stays first in the alternation, so display math is still matched as display math. ## Verification New `blocksuite/affine/all/src/__tests__/adapters/latex-preprocessor.unit.spec.ts`, 11 cases: the digit-first expressions from the issue, the currency cases above, and guards for display math, a `$` followed by whitespace, `\(…\)` rewriting, and code spans. Reverting **only** the regex (keeping the export so the module still loads) fails exactly the four digit-first tests and leaves the other seven green: ``` × leaves binary operators untouched × leaves relation untouched × leaves single digit untouched × keeps every expression in a sentence mixing math and prose Tests 4 failed | 7 passed (11) ``` That the currency and existing-behaviour cases pass **without** the fix is the point — they are regression guards, not props for it. With the fix: ``` Test Files 14 passed (14) Tests 234 passed (234) ``` (the whole `blocksuite/affine/all` suite, which includes the 193 existing adapter tests). ## Notes - `preprocessLatex` is now exported so the delimiter rule can be tested directly. It was previously module-private with only the extension exported; `adapters/markdown/index.ts` already does `export * from './preprocessor.js'`, so nothing else changed. - I kept the change to the one regex and did not reformat the rest of the file — there is no Prettier config in the repo, and running Prettier with its defaults rewrites quotes and trailing commas across the whole file. - The lookbehind `(?<!\s)` is ES2018; the file already targets modern runtimes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved Markdown LaTeX preprocessing for inline expressions preceded by even-length backslash runs. - Continued to distinguish escaped dollar signs from valid math delimiters, while preserving currency values, display math, `\( \)` expressions, whitespace, mixed content, and code spans. - **Tests** - Added comprehensive coverage for inline and display math, delimiter escaping, currency values, whitespace, conversions, mixed content, digit-leading expressions, and code-span protection. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
82f8ada972 |
fix(latex): do not re-escape a dollar that is already escaped (#15602)
## Description Split out of #15596 on review feedback — this is an independent, pre-existing bug in the currency pass, so it does not belong in that PR. The currency pass escapes any `$` followed by a digit without looking at what precedes it: ```ts preprocessedContent = preprocessedContent.replace(/\$(?=\d)/g, '\\$'); ``` When the dollar is **already escaped**, that turns an odd backslash run even: ``` input: \$4 (an escaped dollar — the author wants a literal "$4") output: \\$4 (a literal backslash, then an unescaped `$`) ``` `MarkdownPreprocessorManager.process` runs this before `_markdownToAst`, so remark-math sees that bare `$` and can take it as an active delimiter — the opposite of what escaping it was for. ### The fix Escape only a dollar whose preceding backslash run is **even**, keeping the run itself: ```ts preprocessedContent = preprocessedContent.replace( /(?<!\\)((?:\\\\)*)\$(?=\d)/g, '$1\\$' ); ``` `(?<!\\)` anchors the run to its start and `((?:\\\\)*)` takes backslashes in pairs, so an odd run never matches. Behaviour that was already correct is untouched: | input | before | after | |---|---|---| | `costs $5 today` | `costs \$5 today` | unchanged | | `costs \\$4 today` (even run — literal `\` then a real `$`) | `costs \\\$4 today` | unchanged | | `costs \$4 today` (odd run — already escaped) | `costs \\$4 today` | **`costs \$4 today`** | ### Relationship to #15596 Both touch this file, so whichever lands second will need a trivial rebase: - Both add `export` to `preprocessLatex` (the same one-word change). - They edit **different** statements — #15596 changes the *protection* regex above, this one changes the *currency* regex below. - Test files are deliberately named differently (`latex-preprocessor.unit.spec.ts` there, `latex-currency-escape.unit.spec.ts` here) so they do not collide. Happy to fold them into one file once both are in, if you'd prefer that. I verified this bug is not introduced by #15596: `\$4` preprocesses to `\\$4` identically with and without that branch. ## Checklist - [ ] I have signed the [AFFiNE Contributor License Agreement](https://cla-assistant.io/toeverything/AFFiNE) — required before merge; the `license/cla` check must be green ([how it works](https://github.com/toeverything/AFFiNE/blob/canary/docs/BUILDING.md#sign-the-cla-first)) - [x] The PR targets the `canary` branch and its title follows [Conventional Commits](https://www.conventionalcommits.org/) - [x] Tests are added or updated where it makes sense - [x] `yarn lint` and `yarn typecheck` pass locally - [x] If the PR code includes AI-generated edits, I have carefully reviewed it to ensure that the scope of the PR is consistent with what is claimed in the title and description, and that there are no redundant or invalid implementations. - [x] I agree that maintainers may close the PR without discussion if they consider the code quality to be too low. ### Notes on the checklist - **CLA:** not signed yet — the repository owner is signing it; the `license/cla` check will go green once that happens. - **Tests:** 7 cases in `latex-currency-escape.unit.spec.ts`. Reverting only the regex fails exactly the three already-escaped cases and leaves the four guards (plain price, bare amount, two prices, even run) green — they are regression guards, not props. Full `blocksuite/affine/all` suite: 230 passing. - **Lint/format:** `oxlint --deny-warnings` and `oxfmt --check` are both clean on the two changed files. - **Typecheck:** clean for these files. For transparency, a full `yarn typecheck` on my machine also reports pre-existing `@prisma/client` errors under `packages/backend/server`; those come from my installing with `--mode=skip-build` (so `prisma generate` never ran) and are unrelated to this change. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved LaTeX handling for currency values by escaping dollar signs only when required. - Preserved already-escaped dollar signs and backslash sequences correctly. - **Tests** - Added coverage for plain currency amounts, already-escaped dollar signs, and even backslash runs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f26301a9fb |
fix(editor): improve code language search and prevent stale highlighting (#15593)
## Summary - Search language IDs, display labels, and aliases case-insensitively, preserving prefix matching and the existing result order. - Ignore pending grammar-load results when the selected language has changed, preventing highlighting from returning after switching to Plain Text. Related to #15492: display-label matching will also make “Plain Text” searchable by its full name, while the highlighting fix prevents pending language loads from restoring highlighting after switching to Plain Text. ## Validation Code-block E2E suite (7 passed), scoped TypeScript checks, lint, and formatting checks passed. Both focused regression tests fail on unmodified `canary` and pass with the fixes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Code block language search now matches display names, IDs, aliases, and labels without regard to letter case. - Search results prioritize matches at the beginning of language names and aliases over label-only matches. - **Bug Fixes** - Prevented outdated syntax highlighting from appearing after a code block language is changed or cleared while loading. - Prevented duplicate language-loading requests during concurrent highlighting updates. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com> Co-authored-by: DarkSky <darksky2048@gmail.com> |
||
|
|
19ed4226f0 |
fix(editor): add Plain Text option to language selector dropdown (#15492)
**Problem:** When a language was selected in a code block's language
dropdown, there was no way to reset it back to "Plain Text" (no syntax
highlighting). The dropdown only contained shiki languages, and the null
value representing Plain Text had no corresponding selectable option.
**Solution:** Added a "Plain Text" entry as the first item in the
language selector dropdown. This entry:
- Maps to language: null when selected
- Shows a checkmark when Plain Text is active
- Persists in localStorage alongside recently used languages
- Is searchable via aliases ("plain", "text", "none")
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added Plain Text as a selectable code block language.
* Plain Text is available in newly generated and previously saved
language lists.
* Code blocks correctly show Plain Text when no language is selected.
* Recognizes common names including “plain,” “text,” “plaintext,” “txt,”
and “none.”
* **Tests**
* Added coverage for switching between Rust and Plain Text.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
2af30773ae |
feat(ios): add stable Share Extension imports (#15547)
## Summary The changes below are prepared locally and have not been committed or pushed. - Save original URLs, user titles, selected text, images and PDFs through a versioned, file-backed Share Inbox. Stable document/attempt IDs, serialized imports and committed receipts make retries preserve user edits and recover native completion. - Keep rich previews transient. Share previews request transcript excerpts, clip optional display fields and bound response/image downloads. Saving does not wait for preview requests or persist provider metadata, transcript snapshots or dedicated preview blobs. - Restore the minimal App Group workspace-mode snapshot and `official`/`deferred` route. Official routes remain fixed for the pending share; deferred self-hosted previews use the selected server without a provider fallback. - Let bookmark and YouTube details read the current workspace's Link Preview API by URL. Full transcripts, chapters and timestamps load on expansion without document writes. Reuse editor styles and the existing portal for canvas details; isolate endpoint/base/transcript caches and keep transcript results out of persistent cache. ## Validation - Focused frontend suites: 128 tests passed; the 43 preview/details cases also passed after the final portal change. - `ShareInboxSafetyTests`: 57 tests passed on iOS 26.5 simulator. - `yarn typecheck` and full `yarn lint` passed. - iOS web bundle, Capacitor asset copy, and signed simulator App build with embedded ShareExtension passed. - Browser component checks: desktop, narrow viewport, light/dark themes, full transcript scrolling, canvas portal positioning and Escape dismissal. - Simulator Safari share: rich preview, cancellation, native-to-app handoff, workspace selection and successful save. The pending manifest contained original content and routing only, and was removed after import. Physical-device and network-capture matrices remain manual. The simulator YouTube iframe displayed player error 153; this is separate from the successful preview/import checks and video playback is not claimed as verified. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * iOS sharing now supports PDF files alongside images, with previews and attachment validation. * Share imports offer improved workspace selection, offline handling, retry recovery, and clearer error messages. * Link previews can display expandable metadata and transcript details for bookmarks and YouTube embeds. * Share inbox entries now identify unsupported versions and provide safer attachment resolution. * **Bug Fixes** * Improved cancellation, cleanup, and stale-request handling during sharing and importing. * Enhanced link-preview validation and protection against oversized or invalid responses. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <darksky2048@gmail.com> |
||
|
|
51fdf602ba |
feat(core): adapt new lifecycle (#15575)
fix #15574 #### PR Dependency Tree * **PR #15575** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * Added source-aware blob handling for current documents and page history. * Added document lifecycle support for trashing, restoring, and permanently deleting documents. * Copilot attachments now upload directly to session attachment endpoints. ## Bug Fixes * Document actions now complete before confirmations, notifications, and navigation proceed. * Improved cancellation, upload fallback, size-limit handling, and cloud synchronization reliability. * Invite-link expiration now remains reliable for long durations. * Improved synchronization for document permissions and reserved documents. ## Changes * Blob management now displays attachment icons instead of image previews. * Cloud synchronization now uses a unified batch protocol. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b5556f12d8 |
fix(editor): preserve expanded headings in readonly mode (#15549)
## Description Closes #13579. On readonly shared pages, selecting text under a heading persisted as collapsed caused reactive selection handling to restore the persisted collapsed value over the viewer-local expanded state. This closed the heading again and prevented selecting or copying its revealed content. This change: - separates persisted collapsed-state synchronization from selection cleanup; - makes the readonly-local collapsed state reactive for both BlockSuite effects and Lit rendering; - preserves selection and copying while a readonly heading is locally expanded; - still clears hidden text selection when the heading is collapsed again; - adds a Playwright regression covering collapse → readonly → expand → drag-select → copy → re-collapse. ## Checklist - [x] I have signed the [AFFiNE Contributor License Agreement](https://cla-assistant.io/toeverything/AFFiNE) — required before merge; the `license/cla` check must be green ([how it works](https://github.com/toeverything/AFFiNE/blob/canary/docs/BUILDING.md#sign-the-cla-first)) - [x] The PR targets the `canary` branch and its title follows [Conventional Commits](https://www.conventionalcommits.org/) - [x] Tests are added or updated where it makes sense - [x] `yarn lint` and `yarn typecheck` pass locally ## Testing - Focused Chromium regression: 1 passed - Adjacent readonly paragraph scenarios: 3 passed - Targeted `oxfmt --check`: passed - Targeted `oxlint --deny-warnings`: passed - `git diff --check`: passed `yarn typecheck` could not be confirmed in this checkout because required generated workspace declaration outputs are missing. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved collapsed heading behavior in read-only mode. * Preserved local heading expansion and text selection when copying content and collapsing the heading. * Ensured local expansion state resets correctly when switching out of and back into read-only mode. * **Tests** * Added coverage for read-only heading expansion, keyboard copying, clipboard access, mode switching, and text selection. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b4331cbe1e |
fix(editor): compare right child against the correct node in priority queue (#15568)
## Description `PriorityQueue.bubbleDown` compares `swap` against `null`, but `swap` is initialized to `-1` (`priority-queue.ts:19`), and the loop's own exit check uses `swap === -1` (`:43`). So `swap === null` is always false and `swap !== null` always true: the right child is only ever compared with the left child, never with the element being sunk. A node can sink below a child larger than itself, breaking the heap invariant. Randomized check on the current code: 394 of 20,000 random heaps dequeue out of order. Smallest reproducer is 7 elements — `[1, 2, 3, 7, 6, 5, 4]` dequeues as `[1, 2, 3, 5, 4, 6, 7]`. The queue backs `AStarRunner` (`a-star.ts:4`, its only consumer), which routes orthogonal connectors via `ConnectorPathGenerator.updatePath` — edgeless connector re-routing, mindmap rendering, and auto-complete. The A* heuristic is admissible, so a path is still produced; the effect is that nodes are expanded in the wrong order, so the shortest / fewest-bends guarantee is lost rather than the connector breaking. ### Why this needed a config change too The package's `vitest.config.ts` was dropped in the #10702 package reorg and never recreated at `blocksuite/affine/blocks/surface/`, so `vitest` collects none of its six test files: ``` $ yarn vitest run blocksuite/affine/blocks/surface/src/__tests__/priority-queue.unit.spec.ts No test files found, exiting with code 1 ``` They have not run since 2025-03-08, which is why this survived. Restoring the config re-enables all six files (40 tests, all passing) so the regression test added here actually guards the fix. Verified by reverting the one-line fix with the config in place: ``` FAIL should not sink a node past children that are all larger than it expected [1,2,3,5,4,6,7] to deeply equal [1,2,3,4,5,6,7] FAIL should dequeue in ascending order regardless of insertion order Tests 2 failed | 38 passed (40) ``` ## Checklist - [x] I have signed the [AFFiNE Contributor License Agreement](https://cla-assistant.io/toeverything/AFFiNE) — required before merge; the `license/cla` check must be green ([how it works](https://github.com/toeverything/AFFiNE/blob/canary/docs/BUILDING.md#sign-the-cla-first)) - [x] The PR targets the `canary` branch and its title follows [Conventional Commits](https://www.conventionalcommits.org/) - [x] Tests are added or updated where it makes sense - [x] `yarn lint` and `yarn typecheck` pass locally - [x] If the PR code includes AI-generated edits, I have carefully reviewed it to ensure that the scope of the PR is consistent with what is claimed in the title and description, and that there are no redundant or invalid implementations. - [x] I agree that maintainers may close the PR without discussion if they consider the code quality to be too low. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Corrected priority queue ordering behavior to ensure items are dequeued in ascending order across insertion sequences. - **Tests** - Added coverage for priority queue behavior when comparing nodes with two larger child values. - Added automated test configuration and coverage reporting for the surface components. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b6de0ad51b |
feat(ios): improve share preview (#15538)
#### PR Dependency Tree * **PR #15538** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added rich link previews to mobile and iOS sharing, including images, metadata, transcripts, and selected text. * Share imports can now create structured content blocks, embeds, bookmarks, and transcript callouts. * Added workspace-aware preview handling for cloud, self-hosted, and signed-out modes. * **Accessibility** * Improved collapse/expand controls with semantic buttons and ARIA relationships. * **Bug Fixes** * Enhanced URL and error sanitization in server logs. * Improved link-preview CORS support, validation, and request handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8e8a781ed1 |
feat(editor): improve html content color mapping (#15516)
fix #15514 #### PR Dependency Tree * **PR #15516** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved color handling when importing HTML content. * Added support for hex, RGB/RGBA, percentage, alpha, transparent, named, and HSL color values. * Correctly maps supported colors to the app’s color themes. * Prevents invalid, translucent, or unsuitable colors from being applied. * Preserves style values containing additional colons during import. * Improved imported text formatting for supported and unsupported colors. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
591f874dad |
fix(android): stabilize IME composition and deletion handling (#15370)
## Summary Fix Android editor IME corruption around composition, autocorrect replay, delete, Enter, and old WebView delete behavior. ## What changed - Add Android WebView InputConnection wrapper for editor IME handling. - Route Android delete events through BlockSuite editor input. - Guard against keyboard autocorrect/composition replay after delete or space. - Stabilize delete fallback on older Android/WebView versions. - Gate IME diagnostic logs behind debug builds. - Add Android IME fix notes and regression coverage. ## Validation - Manual Android testing passed. - `git diff --check upstream/canary...HEAD` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved Android text editing for Backspace, Delete, Enter, composing text, and keyboard events. * Prevented input methods from targeting the wrong editor area. * Improved caret-based text handling, focus synchronization, and composing-session cleanup. * **Platform Improvements** * Added a dedicated Android input bridge for smoother IME interactions and fallback keyboard behavior. * Improved editor actions, input recovery, and trusted-page validation for Android communication. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <darksky2048@gmail.com> |
||
|
|
8c9aad9a9b |
fix(editor): enable shift+wheel horizontal scroll on all platforms (#15494)
Fixes #10034 |
||
|
|
6375f5ab8c | chore: bump typescript 7 (#15465) | ||
|
|
0c7b20dc18 |
chore: migrate oxlint & oxfmt (#15464)
#### PR Dependency Tree * **PR #15464** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Replaced the project’s formatting and linting workflow with Oxfmt and Oxlint. * Added shared formatting and linting configuration, editor integration, and updated automated checks. * Updated generated files, scripts, and lint guidance to use the new tooling. * **Style** * Reformatted templates, source code, examples, and configuration files for consistent readability. * No user-facing functionality or rendering behavior changed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ee899a267b |
feat(server): improve context management (#15448)
#### PR Dependency Tree * **PR #15448** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added workspace artifact upload, browsing, removal, deduplication, and library ownership support. * Copilot now supports scoped document and artifact search, canvas reading, live editor context, and frontend tools. * Added scope and focus selectors with source-resolution receipts in chat. * Added embedding health, progress, synchronization, and retrieval capabilities. * Added BYOK policy visibility, provider restrictions, endpoint dialect selection, and validation. * Added delegated editor interactions and userdata document authorization. * **Bug Fixes** * Improved attachment handling, cancellation, access control, retrieval fallbacks, workspace synchronization, and configuration validation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6170a90785 |
feat(editor): add permanent global toggle for code block line numbers (#15381)
Add a persistent "Show line numbers in code blocks" setting to Editor Settings that controls line-number visibility across all code blocks. Individual blocks can still override the global default via the per-block More menu toggle. ## Changes - **schema.ts** - add `codeBlockLineNumbers: z.boolean().default(true)` to `AffineEditorSettingSchema` - **code-block.ts** - read `codeBlockLineNumbers` from `EditorSettingProvider` reactively via a stable `signal(true)` updated by `effect()` in `connectedCallback`; expose `showLineNumbers` getter as single source of truth used by both `renderBlock()` and the toolbar - **config.ts** - toolbar line-number toggle reads `blockComponent.showLineNumbers` (resolved state) instead of `model.props.lineNumber ?? true` - **general.tsx** - add `DefaultCodeBlockLineNumberSettings` Switch row in editor general settings - **en.json + i18n.gen.ts** - add i18n strings for the new setting - **line-numbers.spec.ts** - add 7 e2e tests covering default visibility, global toggle on/off, per-block override in both directions, multi-block, newly created blocks, and persistence across reload ## Behaviour | State | Result | |---|---| | Global ON (default), no per-block override | Line numbers shown | | Global OFF, no per-block override | Line numbers hidden | | Global OFF, per-block explicitly ON | Line numbers shown | | Global ON, per-block explicitly OFF | Line numbers hidden | | Mobile (feature flag) | Always hidden regardless of settings | ## Notes - Existing per-block toggle behaviour is fully preserved and unchanged - Default is `true` so no regression for existing users - The blocksuite-side reads `codeBlockLineNumbers` via a type cast (`as Record<string, unknown>`) because the key lives in the AFFiNE-level `EditorSettingSchema`, not in blocksuite's own `GeneralSettingSchema` - this is an intentional architectural boundary Closes #14965 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a global setting to show or hide line numbers in code blocks by default. * Added localized title and description text for the new setting. * Preserved per-code-block overrides through the block’s More menu. * **Bug Fixes** * Line-number visibility now stays consistent across existing and newly created code blocks, including after reloads. * **Tests** * Added end-to-end coverage for defaults, overrides, persistence, and multiple code blocks. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fb647b6003 |
chore: bump up js-yaml version to v5 [SECURITY] (#15385)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [js-yaml](https://redirect.github.com/nodeca/js-yaml) | [`^4.2.0` → `^5.0.0`](https://renovatebot.com/diffs/npm/js-yaml/4.3.0/5.2.2) |  |  | --- ### js-yaml: Exponential parsing time in flow collections leads to denial of service [GHSA-pm4m-ph32-ghv5](https://redirect.github.com/advisories/GHSA-pm4m-ph32-ghv5) <details> <summary>More information</summary> #### Details ##### Summary Parsing a small YAML document can take exponential time. An application that calls `load()` or `loadAll()` on untrusted input can be hung by a payload under 200 bytes. ##### Details When an entry in a flow sequence turns out to be a `key: value` pair, the parser rewinds and parses that entry a second time as the key. If the key is itself a nested flow sequence of the same shape, every level is parsed twice, so the total work is O(2^n) in the nesting depth. The default `maxDepth` of 100 does not help, because the time is already unmanageable at about 30 to 40 levels. Root cause, potentially the: `readFlowCollection` in [parser.ts](https://redirect.github.com/nodeca/js-yaml/blob/master/src/parser/parser.ts), the `restoreState` followed by a second `parseNode` further down. ##### PoC ```javascript const yaml = require('js-yaml') const n = 30 yaml.load('[ '.repeat(n) + '1' + ' ]: 0'.repeat(n)) ``` With default options: 22 levels takes about 1 second, 26 levels about 17 seconds, 30 levels over 2 minutes. The input stays under 200 bytes and grows linearly with `n`. ##### Impact Denial of service. A single small request can keep one CPU busy for minutes or longer and blocks the Node event loop, so one request can stall the whole process. No anchors, aliases, merges, tags, or non default options are required, and it reproduces on the default schema. #### Severity - CVSS Score: 7.5 / 10 (High) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H` #### References - [https://github.com/nodeca/js-yaml/security/advisories/GHSA-pm4m-ph32-ghv5](https://redirect.github.com/nodeca/js-yaml/security/advisories/GHSA-pm4m-ph32-ghv5) - [https://github.com/nodeca/js-yaml/commit/3e5240f9cbe645ce5afb58524954a13c8539c853](https://redirect.github.com/nodeca/js-yaml/commit/3e5240f9cbe645ce5afb58524954a13c8539c853) - [https://github.com/nodeca/js-yaml/releases/tag/5.2.2](https://redirect.github.com/nodeca/js-yaml/releases/tag/5.2.2) - [https://github.com/advisories/GHSA-pm4m-ph32-ghv5](https://redirect.github.com/advisories/GHSA-pm4m-ph32-ghv5) This data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-pm4m-ph32-ghv5) ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Release Notes <details> <summary>nodeca/js-yaml (js-yaml)</summary> ### [`v5.2.2`](https://redirect.github.com/nodeca/js-yaml/blob/HEAD/CHANGELOG.md#522---2026-07-24) [Compare Source](https://redirect.github.com/nodeca/js-yaml/compare/5.2.1...5.2.2) ##### Fixed - Quote flow scalars where a colon precedes a flow indicator, [#​773](https://redirect.github.com/nodeca/js-yaml/issues/773). ##### Security - Avoid exponential parsing time for nested flow sequence pairs. ### [`v5.2.1`](https://redirect.github.com/nodeca/js-yaml/blob/HEAD/CHANGELOG.md#521---2026-07-02) [Compare Source](https://redirect.github.com/nodeca/js-yaml/compare/5.2.0...5.2.1) ##### Fixed - Add `Map` support to !!omap (should work when `realMapTag` used) ##### Security - Remove quadratic complexity from !!omap `addItem`. Regression from v5 (usually not critical, because YAML11\_SCHEMA is not default anymore). ### [`v5.2.0`](https://redirect.github.com/nodeca/js-yaml/blob/HEAD/CHANGELOG.md#520---2026-06-26) [Compare Source](https://redirect.github.com/nodeca/js-yaml/compare/5.1.0...5.2.0) ##### Added - Added `maxTotalMergeKeys` (10000) loader option to limit the total number of keys processed by YAML merge (`<<`) across one `load()` / `loadAll()` call. - Added `maxAliases` (-1) loader option to limit the number of YAML aliases per document. ##### Removed - `maxMergeSeqLength` replaced with `maxTotalMergeKeys` for limiting YAML merge processing. ##### Fixed - Round-trip of integers with exponential form (>= `1e21`) ### [`v5.1.0`](https://redirect.github.com/nodeca/js-yaml/blob/HEAD/CHANGELOG.md#510---2026-06-23) [Compare Source](https://redirect.github.com/nodeca/js-yaml/compare/5.0.0...5.1.0) ##### Added - Collection tags can finalize an incrementally populated carrier into a different result value. ##### Changed - \[breaking] `quoteStyle` now selects the preferred quote style; use the restored `forceQuotes` option to force quoting non-key strings. ### [`v5.0.0`](https://redirect.github.com/nodeca/js-yaml/blob/HEAD/CHANGELOG.md#500---2026-06-20) [Compare Source](https://redirect.github.com/nodeca/js-yaml/compare/4.3.0...5.0.0) ##### Added - Added named exports for schemas, tags, parser events and AST utilities. - Reworked `JSON_SCHEMA` and `CORE_SCHEMA` with spec-compliant scalar resolution rules, and added `YAML11_SCHEMA`. - Added `realMapTag` for lossless mappings with non-string and complex keys. Object-based mappings now reject complex keys instead of stringifying them. - Added `dump()` `transform` option for changing the generated AST before rendering. - Added `dump()` options `seqInlineFirst`, `flowBracketPadding`, `flowSkipCommaSpace`, `flowSkipColonSpace`, `quoteFlowKeys`, `quoteStyle` and `tagBeforeAnchor`. - Added formal data layers (events and AST) for modular data pipelines. - Added low-level parser (to events), presenter and visitor APIs. - Added the [YAML Test Suite](https://redirect.github.com/yaml/yaml-test-suite) to the test set. ##### Changed - See the [migration guide](docs/migrate_v4_to_v5.md) for upgrade notes. - Rewritten in TypeScript and reorganized the public API around flat named exports. - Reduced the set of exported schemas: - YAML 1.2 schemas: `CORE_SCHEMA` (loader default), `JSON_SCHEMA`, `FAILSAFE_SCHEMA`. - `YAML11_SCHEMA`, a combination of all YAML 1.1 tags (YAML 1.1 does not specify a schema, only "types"). - `load`/`dump` default behaviour is now specified exactly via schemas: - `load` uses `CORE_SCHEMA`, without `!!merge` by default. - `dump` uses `YAML11_SCHEMA` + `CORE_SCHEMA` for the quoting check, to guarantee backward compatibility by default. - `!!set` is now loaded as a JavaScript `Set`. - Replaced the `Type` API with a tags API. Similar, but more precise and simpler. See examples for details. Tags can be defined via `defineScalarTag()`, `defineSequenceTag()` and `defineMappingTag()`, or as a spread + override of an existing tag. - Renamed `Schema.extend()` to `Schema.withTags()`. - Expanded YAML 1.2 conformance and improved handling of directives, document markers, block keys, multiline scalars, tag syntax and other things. - `load()` now throws on empty input instead of returning `undefined`. - Moved browser builds to the `js-yaml/browser` export. - Deprecated the `loadAll` signature with an iterator (still works, but is a candidate for removal). ##### Removed - Removed deprecated `safeLoad()`, `safeLoadAll()` and `safeDump()` exports. - Removed `DEFAULT_SCHEMA` and the nested `types` export. - Removed loader options `onWarning`, `legacy` and `listener`. - Removed dumper options `styles`, `replacer`, `noCompatMode`, `condenseFlow`, `quotingType` and `forceQuotes`. Renamed `noArrayIndent` to `seqNoIndent`. Formatting and representation are now configured through presenter options, schemas and tag definitions. See migration guide on how to replace. - Removed support for importing internal files from `lib/`. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4zLjIiLCJ1cGRhdGVkSW5WZXIiOiI0NC4zLjIiLCJ0YXJnZXRCcmFuY2giOiJjYW5hcnkiLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> |
||
|
|
b6fc0a2192 |
fix(mobile): mobile keyboard padding (#15365)
#### PR Dependency Tree * **PR #15365** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved mobile keyboard and toolbar layout handling when the keyboard overlays or resizes app content. - Prevented incorrect extra spacing when Android applies keyboard insets directly. - Updated toolbar sizing and visibility states for smoother transitions. - **Style** - Adjusted mobile bottom spacing to account for keyboard height, safe areas, and toolbar height. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e7ec8a1032 |
feat(editor): improve select perf (#15353)
maybe fix #12675 #### PR Dependency Tree * **PR #15353** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved block selection updates so selected states refresh reliably. - Corrected selected-block ordering and duplicate handling. - Improved toolbar positioning accuracy and reduced unnecessary layout recalculations. - Adjusted toolbar animation behavior for surface-based tools. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b05f165820 | fix(mobile): popover handle | ||
|
|
749f1c5f0b | fix(mobile): popover styles (#15351) | ||
|
|
49625298ee |
fix(editor): kanban data refresh (#15321)
fix #15281 #### PR Dependency Tree * **PR #15321** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved row handling during group and card updates to prevent rows from remaining locked. * Preserved manual card ordering when moving cards or updating group values. * Added coverage to verify row unlocking behavior during card moves. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4b37f9d42e |
feat(editor): improve obsidian import (#15304)
fix #15290 #### PR Dependency Tree * **PR #15304** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved Obsidian vault imports with more reliable attachment and embedded image matching. * Supports nested vault structures and configured attachment folders. * Preserves imported folder hierarchy and organizes imported content more accurately. * **Bug Fixes** * Fixed asset resolution for attachments with nested paths or duplicate filenames. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7318ef1ed4 |
fix(core): forward svg props to icon renderer (#15278)
## Problem Page reference icon is vertically misaligned because the `pageReferenceIcon` class is not applied. This is because `IconRenderer` does not forward SVG props to the underlying `AffineIconRenderer` component. ## Fix Main fix: - Forward SVG props in `getDocIconComponent`. - Add support for SVG props in `IconRenderer`. Side fixes: - Comment out color in `pageReferenceIcon` style so the icon inherits its parent color now that the class is actually applied - Remove hardcoded SVG margin used for vertical alignment. ## Before / After **Before** <img width="405" height="163" alt="before" src="https://github.com/user-attachments/assets/45c6f0c9-d2f8-4295-832a-03018cbe0bf1" /> **After** <img width="404" height="156" alt="after" src="https://github.com/user-attachments/assets/fa3f955a-b1fd-4bc1-b966-09b5b9d6a7e4" /> ## Related issues - Fixes #14978: Makes icon vertically aligned. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved icon rendering so additional display properties are correctly passed through to Affine icons. - Updated document icon components to support standard SVG properties, enabling more consistent customization. - Refined reference icon styling to allow color inheritance from surrounding UI context. - Removed unnecessary spacing beneath reference icons for cleaner alignment. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a868f54eeb |
fix(ios): stabilize keyboard toolbar, image picker, and scrolling (#15182)
## Summary - keep the editor active when iOS keyboard toolbar interactions move focus into range-sync excluded widgets - use the native iOS image picker/source sheet and sync native presentation with the app theme - pin `ListViewKit` to `1.1.6` so the iOS workspace resolves with Xcode 16.3 - restore vertical scrolling in the iOS `WKWebView` by removing the global `contentOffset` reset while preserving zoom prevention ## Test plan - [x] `yarn vitest --run --config \"vitest.config.ts\" --browser.enabled=false \"src/__tests__/inline/active.unit.spec.ts\"` - [x] `LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 xcodebuild -resolvePackageDependencies -workspace \"packages/frontend/apps/ios/App/App.xcworkspace\" -scheme \"App\"` - [x] `xcodebuild -workspace \"App.xcworkspace\" -scheme \"App\" -destination \"generic/platform=iOS Simulator\" build CODE_SIGNING_ALLOWED=NO ONLY_ACTIVE_ARCH=YES ARCHS=arm64` - [x] Xcode build validation for the updated PR branch |
||
|
|
9581432d21 |
feat(core): onenote importer (#15198)
#### PR Dependency Tree * **PR #15198** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added OneNote import support for `.one`, `.onetoc2`, and `.onepkg`, including OneNote-to-markdown content conversion. * OneNote now appears in the import flow with a dedicated label and format tooltip, and file pickers recognize the new OneNote type. * **Bug Fixes** * Import options that are desktop-only are now disabled when not running in the desktop app, with clear messaging. * Improved imported asset handling by converting non-image embedded assets into attachments for more consistent results. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8d72e4dc29 |
feat(core): import progress & perf (#15197)
#### PR Dependency Tree * **PR #15197** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a new import pipeline with “plan then commit” batch handling for Markdown, Notion HTML, Obsidian, and Bear backups. * Enabled native import sessions with progress, cancellation, and batch-by-batch committing (including assets, folders, icons, and tags). * Added web preflight limits for ZIP and multi-file imports. * **Bug Fixes** * Improved import error/warning reporting and continued processing when some items fail. * Strengthened snapshot-based file/directory picking to preserve paths. * **Chores** * Updated project packaging/configuration for the new import workflow. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
477015f064 |
feat(core): support Notion markdown zip imports (#14910)
## What changed - Markdown zip imports now resolve local `.md` links like `./test/2.md` into AFFiNE linked-page references when the target document exists in the same archive. - Added Notion Markdown `.zip` import support in the desktop import dialog, including nested zip traversal, Notion title extraction, hash-stripped folder names, attachments, and folder hierarchy integration. - Added i18n entries and adapter coverage for standard Markdown zip links and Notion Markdown zip imports. ## Why Markdown and Notion exports often contain links between notes using relative `.md` paths. Keeping those as plain URLs makes imported workspaces harder to navigate, so the importer now preassigns document ids and rewrites resolvable archive-local markdown links into linked pages. ## Notes The markdown zip folder hierarchy implementation now comes from latest `origin/canary`, so this PR only layers relative-link resolution and Notion Markdown zip support on top of that upstream behavior. ## Validation - `yarn vitest --run blocksuite/affine/all/src/__tests__/adapters/markdown.unit.spec.ts` - `yarn tsc -b blocksuite/affine/all/tsconfig.json --verbose` - `git diff --check` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for importing Notion Markdown exports in `.zip` format, including subpages, attachments, and nested folders. * Internal links inside imported Markdown now resolve correctly between pages, preserving link text when available. * The import dialog now includes a dedicated “Notion (Markdown, .zip)” option. * **Bug Fixes** * Improved filename handling so non-Latin characters in ZIP imports are preserved correctly. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com> Co-authored-by: DarkSky <darksky2048@gmail.com> |
||
|
|
11db127772 | chore: bump deps (#15151) | ||
|
|
154d9e975d | fix: deps & config (#15126) | ||
|
|
d500e472f0 | chore: bump deps (#15124) | ||
|
|
a77d89bb1a |
fix(editor): edgeless can't slider with finger (#15091)
fix bug edgeless can't slider with finger <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added mobile immersive edgeless mode with dynamic chrome auto-hide and tap-gesture controls. * Added a mobile zoom ruler UI for edgeless. * **Bug Fixes** * Improved iOS rendering/zoom by applying low-zoom survival behavior, gesture-aware refresh deferral, and effective-DPR canvas scaling. * Fixed iOS webview zoom/bounce and process-termination reload behavior. * Improved placeholder styling with theme-aware colors. * **Chores** * Updated local ignore rules and iOS app build/version configuration. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <darksky2048@gmail.com> |
||
|
|
ac3c93ccfa |
fix(editor): render strikethrough on links (#15109)
**Issue** Strikethrough on a link doesn't render. The toolbar button highlights but no line appears (#15106). **Solution** affine-link hardcoded text-decoration: none in the override it passes to affineTextStyles, which clobbered the decoration computed from strike/underline. Removing it fixes the render; plain links still show no underline because affineTextStyles returns none by default. **Result** Strikethrough and underline render on links again. Added an e2e test: a plain link stays undecorated, a struck link renders line-through, red before the fix and green after. fix #15106 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed link text-decoration styling to properly support strikethrough and other text formatting when applied to links. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6a2b73e76f |
feat(editor): improve database & table behavior (#15100)
fix #14982 fix #15028 fix #15099 #### PR Dependency Tree * **PR #15100** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Prevented Enter handling during IME composition to avoid unintended input. * Avoided overwriting external native selections when interacting with tables. * Improved validation of inline text selection ranges for more reliable behavior. * **Enhancements** * Scoped and refined text-selection styling and editability within tables and cells. * Added managed sorting for Kanban views to control card ordering. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
07a08e6d4d |
fix(editor): import & save logic (#15098)
fix #15080 fix #15085 fix #15031 fix #15094 #### PR Dependency Tree * **PR #15098** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved code-block paste behavior for plain-text insertion * Fixed block selection ordering to reflect document model * Made table cell formatting resilient to conversion errors * Ensured user feature list is consistently returned as an array * **Refactor** * Streamlined authentication session fetch and profile enrichment flow * **Tests** * Added tests for markdown blockquote list preservation * Added authentication session validation tests <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
aca47445aa |
feat(client): migration old package to rspack (#15068)
#### PR Dependency Tree * **PR #15068** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Upgraded Vitest across packages to 4.1.8 and bumped Tailwind PostCSS to 4.3.0 * CLI/tooling updated to support the media-capture-playground package and adjust build/dev server behavior * **Bug Fixes** * Improved workspace deletion reliability in the Electron app * **Refactor** * Simplified media capture playground build setup (build/config adjustments) * **Tests** * Made tests more robust by preserving/restoring environment state during runs <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
69c2f09eba |
fix(editor): keyboard shortcuts in table cells (#15067)
## Description Fixes keyboard shortcuts for text formatting (Ctrl+B, Ctrl+I, Ctrl+U, etc.) not working inside table cells. ## Changes - **Modified `table-cell.ts`**: Updated the `_handleKeyDown` method to only prevent default behavior for Tab key and allow other keyboard events to propagate, enabling text formatting shortcuts to work properly - **Created `table-keymap.ts`**: New module that registers the `textKeymap` for table blocks, ensuring text formatting shortcuts are available in table cells - **Updated `view.ts`**: Registered the `TableKeymapExtension` in the table view extension setup - **Cleaned up `format.ts`**: Removed unnecessary `TextSelection` check that was preventing shortcuts from working in table contexts ## Closes Closes #13916 #12127 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved Tab key handling within table cells for more consistent keyboard navigation. * Simplified read-only detection for keyboard shortcuts to avoid unexpected behavior. * **Refactor** * Reworked table keyboard mapping and registration to streamline shortcut handling and event flow. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
75f4c0eede |
feat(editor): add block button for hovering blocks (#14879)
This PR implements [feature request] #14845 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Add-block control that appears when hovering blocks in page mode to insert and auto-focus a new paragraph; control hides after insertion. * **Improvements** * Improved hover and interaction handling to avoid accidental triggers when interacting with the drag handle or add-block control. * Consistent sizing, positioning, and visibility behavior for the add-block control. * **Style** * Moved heading icon slightly for improved visual alignment. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com> |
||
|
|
2aa56cbccd | chore: bump toolchain & fix lint | ||
|
|
ef4939009f |
feat(editor): handle calendar view overflow in edgeless mode (#14992)
#### PR Dependency Tree * **PR #14992** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Calendar view now supports horizontal scrolling for better navigation. * **Bug Fixes** * Improved mouse wheel interaction handling to prevent unintended scrolling. * **Style** * Calendar layout is now more responsive and adapts better to different screen sizes. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14992?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0f5778ac89 |
feat(editor): calendar view for database block (#14984)
fix #13663 #### PR Dependency Tree * **PR #14984** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Calendar view for database blocks (month layout, entry cards, external-source support) * Workspace calendar integration and new slash-menu "Calendar View" * **Improvements** * Create/manage database rows from calendar UI; preserve durations when moving/resizing ranges * Drag-and-drop, drop-preview, and hit-testing support for calendar and docs * Redesigned in-menu View settings with multi-page navigation * Context-menu input autofocus toggle and conditional back-navigation * **Tests** * New unit and E2E suites covering calendar layout, interactions, sources, and slash-menu integration <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
542da0b347 |
feat(editor): improve latex editing support (#14924)
## Summary - support converting selected text into inline LaTeX equations - support turning text blocks into LaTeX equation blocks - add equation entries to editor toolbars while keeping inline equation with text formatting actions ## Tests - yarn tsc -b blocksuite/affine/inlines/latex/tsconfig.json blocksuite/affine/blocks/note/tsconfig.json blocksuite/affine/blocks/root/tsconfig.json blocksuite/affine/rich-text/tsconfig.json blocksuite/affine/widgets/keyboard-toolbar/tsconfig.json --pretty false - git diff --check origin/canary...HEAD <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Equation block support with conversion from existing blocks. * Inline LaTeX insertion added to the inline formatting toolbar. * Equation action added to the keyboard toolbar; Equation blocks searchable via math/equation/latex aliases. * **Improvements** * Inline LaTeX editor opens and syncs more reliably; selection/convert flow preserves distinct LaTeX values when converting in reverse order. * **Tests** * New e2e tests for inline LaTeX conversions and value preservation. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14924) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
659072183c | chore: bump deps | ||
|
|
76d57aa389 |
feat(editor): allow date picker to navigate back to year 1000 (#14942)
Fixes #14935 ## Summary The date picker had a hardcoded `_minYear = 1970` in [`date-picker.ts`](blocksuite/affine/components/src/date-picker/date-picker.ts), which prevented users from selecting dates earlier than 1970. This blocked legitimate use cases like historical and genealogical research (see the reporter's comment on #14935). ## Fix Lower the date picker's `_minYear` from `1970` to `1000`. The underlying storage is just a `zod.number()` (Unix timestamp in ms), which supports negative values, so no data-layer or backend changes are required — this is a UI-only constraint relaxation. ## Demo <img width="2044" height="1250" alt="image" src="https://github.com/user-attachments/assets/4b25b333-89c4-48e6-9f91-81781d680200" /> ## Test plan - [x] Insert a database in a doc → add a Date column - [x] Click a date cell → open the picker → click the year label → navigate back through decades - [x] Confirm the calendar reaches years well before 1970 (verified at May 1805) - [x] Confirm the calendar correctly renders weekdays for historical dates - [x] Confirm picking a modern date still works as before <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Date picker now allows selecting dates from year 1000 onward, expanding historical date coverage. * **Bug Fixes** * Navigation (month switches and keyboard arrows) now keeps the selection cursor within the allowed year range, preventing out-of-range jumps. [](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14942) <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
bcbde16c04 | feat(server): native safe fetch (#14931) | ||
|
|
ac37d07e74 |
feat(editor): add Bear backup import and markdown zip folder hierarchy (#14599)
## Summary
- Add Bear `.bear2bk` backup importer (TextBundle-based zip format)
- Enhance markdown zip import to preserve folder structure from zip
paths
- Add colored highlight (`<mark data-color="...">`) support to HTML
adapter
### Bear Import Details
Bear backups are zip archives of TextBundle directories. The importer:
- Parses Bear-specific markdown (highlights `==text==`, callouts `>
[!NOTE]`, inline tags `#tag`)
- Extracts creation/modification dates from `info.json` metadata
- Filters out trashed notes
- Converts Bear tags to AFFiNE tags (consolidated by root segment)
- Builds folder hierarchy from nested tag paths (e.g.,
`#work/projects/alpha`)
- Uses JSZip for lazy decompression to handle large backups without OOM
### Markdown Zip Folder Hierarchy
`importMarkdownZip` now returns `{ docIds, folderHierarchy }` instead of
just `docIds[]`, enabling the UI to recreate the zip's directory
structure as AFFiNE folders.
## Related Issues
- Implements the TextBundle-based import approach suggested in #14115 /
Discussion #14142
- Addresses folder structure preservation requested in #10003
- Partially addresses frontmatter metadata import from #11286
## Test Plan
- [ ] Import a Bear `.bear2bk` backup file via the import dialog
- [ ] Verify tags are created and assigned to documents
- [ ] Verify folder hierarchy matches Bear's nested tag structure
- [ ] Verify creation/modification dates are preserved
- [ ] Verify highlighted text and callouts render correctly
- [ ] Verify images and attachments are imported
- [ ] Import a markdown zip with nested folders, verify folder structure
is recreated
- [ ] Verify trashed Bear notes are excluded
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Bear (.bear2bk) backup import: bulk import notes, convert/dedupe tags,
create nested folders, and return imported doc IDs plus folder
hierarchy; UI import option and progress integrated.
* Markdown ZIP import now returns an optional folder hierarchy alongside
created doc IDs.
* **Bug Fixes / Improvements**
* Highlighting: mark elements validate color names, default safely, and
apply consistent background styling.
* **Chores**
* Added runtime dependency for ZIP handling.
* **Documentation**
* Added localization strings and i18n accessors for Bear import UI.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
|
||
|
|
440ff0c342 |
fix(editor): resolve UX inconsistencies in the AI chat interface (#14850)
# Closes #14189. Fixes the three UX issues reported in the original bug report, plus one small adjacent polish on the right-sidebar toggle that was requested during review. Each concern in the issue is addressed end-to-end, with the same treatment applied to both places the AI chat panel lives: the **sidebar chat panel** (right panel on a doc page) and the **standalone `/chat` page**. --- ## 1. `+` button → persistent multi-session tabs (issue point 1) **Before:** clicking `+` called `createFreshSession()` (standalone) or `newSession()` (sidebar), both of which tore down the current chat content and replaced it in place. There was no way to keep two chats open at once. **After:** a browser/IDE-style tab strip lives above the chat content. Each open session gets its own tab with a close `×`; the active tab is highlighted; `+` now adds a tab rather than replacing the chat. ### Details - New Lit component `ai-chat-tabs` ([packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-tabs.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-tabs.ts)). - Tab title is derived from `session.title` → first user message → `"New chat"`. - Horizontal scroll when tabs overflow, with a `wheel` handler that converts mouse wheel / trackpad vertical swipe into horizontal scroll (native horizontal trackpad swipes also work natively via `overflow-x: auto`). - Auto `scrollIntoView({ inline: 'nearest' })` on active tab change, so a newly created or newly selected tab slides into view instead of staying hidden behind the toolbar. - Close `×` removes the tab from the strip but leaves the session on the server (matches the existing **Chat history** dropdown semantics — the session is still reachable there). Closing the active tab switches to an adjacent one; closing the last tab starts a fresh session. - Persistence: open session IDs are saved per-workspace in `localStorage` under `ai-chat-open-tabs:{workspaceId}`. On mount, the React pages hydrate those IDs via `AIProvider.session.getSession` / `CopilotClient.getSession` — no new backend or schema work. - Wiring: identical effects on both variants ([chat.tsx (sidebar)](packages/frontend/core/src/desktop/pages/workspace/detail-page/tabs/chat.tsx) and [chat/index.tsx (standalone)](packages/frontend/core/src/desktop/pages/workspace/chat/index.tsx)) — hydrate → sync active session into tabs → persist. - The tab strip sits on the same row as the existing toolbar icons (pin / history / `+`), separated by `flex: 1` + `min-width: 0` so the tabs scroll cleanly up to the toolbar boundary. - The `ShadowlessElement` base class injects its static CSS globally, and the `:host` selector does not match in a React-rooted DOM — the component uses tag-selector CSS (`ai-chat-tabs { display: flex; … }`) instead. ## 2. Drag-and-drop attachments (issue point 2) **Before:** the chat input accepted no DnD. Attaching anything required the `+` → file-picker flow. **After:** the chat input accepts OS files via native HTML5 DnD and AFFiNE documents via the repo's existing pragmatic-drag-and-drop infrastructure. ### Details - Native handlers (`dragenter/over/leave/drop`) on [ai-chat-input.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/ai-chat-input.ts) accept OS files: images go into the image preview grid, other files become attachment chips, with the same 50 MB per-file cap as the `+` picker. - Internal AFFiNE document drags from the nav panel land as doc chips, handled via `dropTargetForElements` from `@atlaskit/pragmatic-drag-and-drop` (same library the rest of the app already uses for internal DnD). - A "Drop to attach" overlay appears during drag, reusing the existing focused-border token (`--affine-v2-layer-insideBorder-primaryBorder`) for visual consistency with the focused state. - The image/file routing logic that previously lived inline in `add-popover.ts` was factored into a shared helper [attachment-utils.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-chips/attachment-utils.ts) (`addFilesToChat`), so the `+` picker and the drop handler stay in lockstep. - Analytics: extended the `addEmbeddingDoc.control` union in [events.ts](packages/frontend/track/src/events.ts) with `'dragDrop'` so drag-originated attachments are distinguishable from button-initiated ones in telemetry. - `@atlaskit/pragmatic-drag-and-drop` is promoted from a transitive dependency (via `@affine/component`) to a direct dependency of `@affine/core` and `yarn.lock` is refreshed accordingly. ## 3. Chat-history tooltip + icon (issue point 3) **Before:** hovering the chat-history button showed a tooltip whose background did not invert for dark theme (`--affine-tooltip` is not theme-aware), and the icon was `ArrowDownSmallIcon` — a chevron that does not convey "history." **After:** the tooltip primitive itself is theme-aware (every tooltip in the app benefits, not just the chat one), and the icon is the semantically-clear `HistoryIcon`. ### Details - [tooltip.ts](blocksuite/affine/components/src/tooltip/tooltip.ts) now uses `var(--affine-v2-tooltips-background, var(--affine-tooltip))` and `var(--affine-v2-tooltips-foreground, var(--affine-white))`. The V2 tokens auto-invert with theme; the old vars remain as fallbacks so components that override via the existing `tooltipStyle` escape hatch continue to work. - Triangle arrow colors updated to use the same V2 token. - [ai-chat-toolbar.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-toolbar.ts): `ArrowDownSmallIcon` → `HistoryIcon`; added `data-testid="ai-panel-chat-history"` for future e2e coverage. ## 4. Right-sidebar toggle: tooltips + open-state icon *(adjacent polish)* Not part of the original issue, but surfaced while testing the tab strip — neither of the two right-sidebar toggle buttons had hover affordance, and both used the same icon regardless of the sidebar's state. - Added `tooltip="Open sidebar"` on the route-container button shown when the sidebar is hidden. - Added `tooltip="Close sidebar"` on the sidebar-header button shown when the sidebar is expanded. - The close button now renders a small inline `RightSidebarOpenIcon` variant: same outline as `RightSidebarIcon`, but with the right panel filled in the AFFiNE accent color to convey the open state. Icon shape change is self-contained — no new icon asset added to `@blocksuite/icons`. --- ## Commits - `2adc0c7` — fix(ai-chat): theme-aware tooltip + semantic chat-history icon *(2 files)* - `bf26974` — feat(ai-chat): drag-and-drop file and doc attachments in chat input *(7 files)* - `fca29c8` — feat(ai-chat): persistent multi-session tab strip *(8 files)* - `7d5dffe` — feat(workbench): tooltips and open-state icon for the right-sidebar toggle *(2 files)* Kept ordered smallest → largest blast radius so the history is easy to bisect. --- ## Test plan Verified locally against a fresh server stack (postgres / redis / mailpit via compose, migrations run) signed in as `dev@affine.pro`, in both `/chat` and the sidebar chat on a doc page, in light and dark themes: - [x] Tooltip: hover the chat-history icon in dark mode → tooltip is dark-on-light; toggle to light mode → tooltip is light-on-dark. Existing tooltips on other surfaces (slash menu, edgeless, linked-doc) still render correctly. - [x] Icon: chat-history button renders the history glyph (clock), not a chevron. - [x] Drag-and-drop (OS file): drop a PDF / PNG / TXT onto the input → overlay shows → chips/images appear; file > 50 MB → rejected silently (same as `+` picker). - [x] Drag-and-drop (internal doc): drag an AFFiNE doc from the nav panel → becomes a doc chip. - [x] Pin-picker, `+` picker, paste-image — all unchanged. - [x] Tab strip: first chat auto-becomes a tab on first message; `+` adds tab; click tab switches chat; `×` removes tab and switches to adjacent; close last tab → new fresh tab spawns. - [x] Reload browser → tab strip rehydrates from localStorage with the same sessions. - [x] Tab overflow: 12+ tabs → horizontal scroll via trackpad vertical swipe, trackpad horizontal swipe, and mouse wheel; active tab auto-scrolls into view on `+` click. - [x] Right-sidebar: hover both toggle buttons → tooltips appear; open the sidebar → close button shows the filled right-panel icon. - [x] `yarn lint:ox` and lint-staged both clean on every commit. Not verified locally (no local model key configured): the assistant actually streams a response. Drop/chip flow is independent of that path. ## Out of scope / follow-ups - No new unit or Playwright tests — the fixes are visually verifiable and reuse existing reducer / state paths. Happy to add tests if reviewers prefer. - `@affine/native` is not required for the web dev stack; I only built `@affine/server-native`. Irrelevant to the PR diff. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Multi-tab chat UI with a tabs component, open/close/switch actions, and per-workspace persistence/restoration. * Drag-and-drop attachments into chat input (files and docs). * **UI/UX** * Tooltip theming moved to v2 variables (includes arrow color). * Sidebar toggle/close buttons now show tooltips. * “Drop to attach” overlay and updated history icon. * **Behavior** * Unified attachment handling with 50MB validation and toast notices. * **Analytics** * Attachment events record drag-and-drop as a control method. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com> |
||
|
|
4e169ea5c7 |
fix(editor): cross browser test stability (#14897)
#### PR Dependency Tree * **PR #14897** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved reliability of shape and connector detection by forcing full DOM renders during waits. * Fixed race conditions in code-block theme loading and cleanup when components unmount. * Refined viewport element discovery to correctly handle rotated/canvas-layer elements and avoid stale DOM removal. * **Tests** * Increased polling timeouts and retries to reduce flakiness. * Disabled per-file parallelism and ensured test setup performs full cleanup before starting; extended test timeout. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9e412f58ec |
feat(editor): add collapse/expand functionality to code block component (#14884)
This PR fixes #14040 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Code blocks can be collapsed and expanded via a toolbar toggle (visible when the document is editable). * Collapsed code blocks show a limited preview (~8 lines) with a bottom fade overlay and reduced padding. * Toolbar button updates icon and tooltip to reflect collapsed/expanded state. * Collapse state is preserved on the block so its current collapsed/expanded setting is retained. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5d234ad6a8 |
fix(editor): single-letter tags in select/multi-select table cell (#14808)
### Summary of Changes Resolves #14715 and #14280. When a user types into a **Select/Multi-Select** table cell to create/choose a tag, that character is stashed on the cell container (setTagDraft) instead of going through valueSetFromString. Opening the tag picker reads it via consumeTagDraftFromTableCellHost. ### Verification - Added unit test to check that single-character input doesn't immediately call valueSetFromString. https://github.com/user-attachments/assets/432b2693-52f9-4ab4-a694-8440aea007a3 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Tag selection popups now initialize with draft text from keypresses in tag columns, improving user experience when editing tags. * **Tests** * Added comprehensive hotkey tests for single-select and multi-select tag column behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |