CI / Build & Quality Checks (push) Successful in 1m52s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 10s
CI / Trigger Desktop Build (push) Successful in 4s
CI / Playwright smoke (e2e) (push) Successful in 10m45s
When a multi-line paste looks like code, a chip above the composer asks "That looks like code. Format it as a code block (js)?" with Format as code / No thanks. It never converts on its own; typing, No, or 8 s dismiss it, and Settings → Editor → "Offer to Format Pasted Code" turns it off. - utils/looksLikeCode.ts (pure, tested): ≥ 3 lines and ≥ 2 of indentation with depth changes, statement terminators, operators + brackets, keywords, monospace/<pre> clipboard HTML, or SQL clause lines. Prose guards: quoted replies, URL lists, long sentence-punctuated lines, plain-word lines, markdown lists. Language guess only when fairly sure (js/ts/python/sql/ rust/c/php). - Accept rebuilds the pasted paragraphs as one code block from their plain text (code lines hold text only) and leaves the caret after it. - Code blocks carry an optional lang → <code class="language-js"> (whitelisted identifier only). Verified in Chromium: pasting a JS function shows the chip; Format as code → sent formatted_body is <pre><code class="language-js"> with indentation intact; a three-line prose paste shows no chip; typing after a paste dismisses it. Unit tests: 14 detector fixtures + 2 output tests; chromium e2e 19 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
114 lines
2.4 KiB
TypeScript
114 lines
2.4 KiB
TypeScript
import { BaseEditor } from 'slate';
|
|
import { ReactEditor } from 'slate-react';
|
|
import { HistoryEditor } from 'slate-history';
|
|
import { BlockType } from './types';
|
|
|
|
export type HeadingLevel = 1 | 2 | 3;
|
|
|
|
export type Editor = BaseEditor & HistoryEditor & ReactEditor;
|
|
|
|
export type Text = {
|
|
text: string;
|
|
};
|
|
|
|
export type FormattedText = Text & {
|
|
bold?: boolean;
|
|
italic?: boolean;
|
|
underline?: boolean;
|
|
strikeThrough?: boolean;
|
|
code?: boolean;
|
|
spoiler?: boolean;
|
|
};
|
|
|
|
export type LinkElement = {
|
|
type: BlockType.Link;
|
|
href: string;
|
|
children: Text[];
|
|
};
|
|
|
|
export type MentionElement = {
|
|
type: BlockType.Mention;
|
|
id: string;
|
|
eventId?: string;
|
|
viaServers?: string[];
|
|
highlight: boolean;
|
|
name: string;
|
|
children: Text[];
|
|
};
|
|
export type EmoticonElement = {
|
|
type: BlockType.Emoticon;
|
|
key: string;
|
|
shortcode: string;
|
|
children: Text[];
|
|
};
|
|
export type CommandElement = {
|
|
type: BlockType.Command;
|
|
command: string;
|
|
children: Text[];
|
|
};
|
|
|
|
export type InlineElement = Text | LinkElement | MentionElement | EmoticonElement | CommandElement;
|
|
|
|
export type ParagraphElement = {
|
|
type: BlockType.Paragraph;
|
|
children: InlineElement[];
|
|
};
|
|
export type HeadingElement = {
|
|
type: BlockType.Heading;
|
|
level: HeadingLevel;
|
|
children: InlineElement[];
|
|
};
|
|
export type CodeLineElement = {
|
|
type: BlockType.CodeLine;
|
|
children: Text[];
|
|
};
|
|
export type CodeBlockElement = {
|
|
type: BlockType.CodeBlock;
|
|
/** [Gitea #107] Optional language → `<code class="language-…">`. */
|
|
lang?: string;
|
|
children: CodeLineElement[];
|
|
};
|
|
export type QuoteLineElement = {
|
|
type: BlockType.QuoteLine;
|
|
children: InlineElement[];
|
|
};
|
|
export type BlockQuoteElement = {
|
|
type: BlockType.BlockQuote;
|
|
children: QuoteLineElement[];
|
|
};
|
|
export type ListItemElement = {
|
|
type: BlockType.ListItem;
|
|
children: InlineElement[];
|
|
};
|
|
export type OrderedListElement = {
|
|
type: BlockType.OrderedList;
|
|
children: ListItemElement[];
|
|
};
|
|
export type UnorderedListElement = {
|
|
type: BlockType.UnorderedList;
|
|
children: ListItemElement[];
|
|
};
|
|
|
|
export type CustomElement =
|
|
| LinkElement
|
|
| MentionElement
|
|
| EmoticonElement
|
|
| CommandElement
|
|
| ParagraphElement
|
|
| HeadingElement
|
|
| CodeLineElement
|
|
| CodeBlockElement
|
|
| QuoteLineElement
|
|
| BlockQuoteElement
|
|
| ListItemElement
|
|
| OrderedListElement
|
|
| UnorderedListElement;
|
|
|
|
declare module 'slate' {
|
|
interface CustomTypes {
|
|
Editor: Editor;
|
|
Element: CustomElement;
|
|
Text: FormattedText & Text;
|
|
}
|
|
}
|