diff --git a/packages/diffs/src/editor/css.ts b/packages/diffs/src/editor/css.ts index e6d9b4bba..f12cf2ef0 100644 --- a/packages/diffs/src/editor/css.ts +++ b/packages/diffs/src/editor/css.ts @@ -1,8 +1,6 @@ -const DEBUG_SELECTION = false; - export const editorCSS: string = /* CSS */ ` ::selection { - background-color: ${DEBUG_SELECTION ? 'rgba(255, 0, 0, 0.1)' : 'transparent'}; + background-color: transparent; } @keyframes blinking { 0% { opacity: 1; } @@ -22,7 +20,7 @@ export const editorCSS: string = /* CSS */ ` } @media (min-width: 480px) { [data-content] { - caret-color: ${DEBUG_SELECTION ? 'red' : 'transparent'}; + caret-color: transparent; } [data-quick-edit] { caret-color: currentColor; @@ -66,7 +64,12 @@ export const editorCSS: string = /* CSS */ ` [data-caret] { width: 2px; height: 1lh; - background-color: ${DEBUG_SELECTION ? 'transparent' : 'var(--diffs-bg-caret)'}; + background-color: var(--diffs-bg-caret-override, var(--diffs-editor-cursor-fg, + light-dark( + color-mix(in lab, var(--diffs-fg) 50%, var(--diffs-bg)), + color-mix(in lab, var(--diffs-fg) 75%, var(--diffs-bg)) + )) + ); animation: blinking 1.2s infinite; animation-delay: 0.8s; visibility: hidden; @@ -76,6 +79,23 @@ export const editorCSS: string = /* CSS */ ` z-index: -10; background-color: var(--diffs-editor-selection-bg); } + [data-selection-corner] { + width: 100%; + height: 100%; + background-color: var(--diffs-bg); + } + [data-rtl] { + border-top-left-radius: 3px; + } + [data-rtr] { + border-top-right-radius: 3px; + } + [data-rbl] { + border-bottom-left-radius: 3px; + } + [data-rbr] { + border-bottom-right-radius: 3px; + } [data-editor-overlay] { display: contents; } diff --git a/packages/diffs/src/editor/editor.ts b/packages/diffs/src/editor/editor.ts index 589b7ea30..4ed93814b 100644 --- a/packages/diffs/src/editor/editor.ts +++ b/packages/diffs/src/editor/editor.ts @@ -76,8 +76,13 @@ function clampDomOffset(node: Node, offset: number): number { } export interface EditorOptions { + /** Render rounded corners for selection ranges, default is true. */ + roundedSelection?: boolean; + /** Show the clickable quick edit icon, default is disabled. */ enabledQuickEdit?: boolean; + /** Render the quick edit widget element. */ renderQuickEdit?: (context: QuickEditContext) => HTMLElement; + /** Callback when the editor document changes. */ onChange?: ( file: FileContents, lineAnnotations?: DiffLineAnnotation[] @@ -342,9 +347,12 @@ export class Editor implements DiffsEditor { const line = el.dataset.line; const lineType = el.dataset.lineType; if (line !== undefined) { - const lineIndex = Number(line) - 1; - startingLine ??= lineIndex; - endLine = lineIndex; + const lineNumber = parseInt(line, 10); + if (!Number.isNaN(lineNumber)) { + const lineIndex = lineNumber - 1; + startingLine ??= lineIndex; + endLine = lineIndex; + } } if (lineType === undefined || !isLineEditable(lineType)) { el.contentEditable = 'false'; @@ -368,9 +376,11 @@ export class Editor implements DiffsEditor { // inject editor css to the file container if (this.#componentContainer !== fileContainer) { this.#componentContainer = fileContainer; - this.#codePaddingTop = Number( - getComputedStyle(codeElement).paddingTop.slice(0, -2) + const codePaddingTop = parseInt( + getComputedStyle(codeElement).paddingTop.slice(0, -2), + 10 ); + this.#codePaddingTop = Number.isNaN(codePaddingTop) ? 0 : codePaddingTop; if (this.#globalStyleElement !== undefined) { fileContainer.appendChild(this.#globalStyleElement); } @@ -639,21 +649,25 @@ export class Editor implements DiffsEditor { if (target === undefined || textDocument === undefined) { return; } - const lineNumber = target.dataset.columnNumber; + const columnNumber = target.dataset.columnNumber; const lineType = target.dataset.lineType; if ( - lineNumber === undefined || + columnNumber === undefined || lineType === undefined || !isLineEditable(lineType) ) { return; } - const lineIndex = Number(lineNumber) - 1; + const lineNumber = parseInt(columnNumber, 10); + if (Number.isNaN(lineNumber)) { + return; + } + const line = lineNumber - 1; const selection: EditorSelection = { - start: { line: lineIndex, character: 0 }, + start: { line, character: 0 }, end: { - line: lineIndex, - character: textDocument.getLineText(lineIndex).length, + line, + character: textDocument.getLineText(line).length, }, direction: DirectionForward, }; @@ -677,17 +691,22 @@ export class Editor implements DiffsEditor { if (target === undefined) { return; } - const lineNumber = + + const line = target.dataset.columnNumber ?? target.dataset.line; const lineType = target.dataset.lineType; if ( this.#isGutterMouseDown && this.#textDocument !== undefined && - lineNumber !== undefined && + line !== undefined && lineType !== undefined && isLineEditable(lineType) ) { - const lineIndex = Number(lineNumber) - 1; + const lineNumber = parseInt(line, 10); + if (Number.isNaN(lineNumber)) { + return; + } + const lineIndex = lineNumber - 1; let selection: EditorSelection = { start: { line: lineIndex, character: 0 }, end: { @@ -1118,15 +1137,18 @@ export class Editor implements DiffsEditor { const el = child as HTMLElement; const line = el.dataset.line; if (line !== undefined) { - const lineIndex = Number(el.dataset.line) - 1; - const tokens = dirtyLines.get(lineIndex); - if (tokens !== undefined) { - el.replaceChildren( - ...renderLineTokens(tokens, tokenizer.themeType) - ); - dirtyLineIndexes.delete(lineIndex); - if (dirtyLineIndexes.size === 0) { - break; + const lineNumber = parseInt(line, 10); + if (!Number.isNaN(lineNumber)) { + const lineIndex = lineNumber - 1; + const tokens = dirtyLines.get(lineIndex); + if (tokens !== undefined) { + el.replaceChildren( + ...renderLineTokens(tokens, tokenizer.themeType) + ); + dirtyLineIndexes.delete(lineIndex); + if (dirtyLineIndexes.size === 0) { + break; + } } } } @@ -1139,16 +1161,19 @@ export class Editor implements DiffsEditor { i++ ) { const child = children[i] as HTMLElement | undefined; - if (child?.dataset.line !== undefined) { - const lineIndex = Number(child.dataset.line) - 1; - if (dirtyLines.has(lineIndex)) { - const tokens = dirtyLines.get(lineIndex)!; - child.replaceChildren( - ...renderLineTokens(tokens, tokenizer.themeType) - ); - dirtyLineIndexes.delete(lineIndex); - if (dirtyLineIndexes.size === 0) { - break; + if (child !== undefined && child.dataset.line !== undefined) { + const lineNumber = parseInt(child.dataset.line, 10); + if (!Number.isNaN(lineNumber)) { + const lineIndex = lineNumber - 1; + if (dirtyLines.has(lineIndex)) { + const tokens = dirtyLines.get(lineIndex)!; + child.replaceChildren( + ...renderLineTokens(tokens, tokenizer.themeType) + ); + dirtyLineIndexes.delete(lineIndex); + if (dirtyLineIndexes.size === 0) { + break; + } } } } @@ -1203,18 +1228,25 @@ export class Editor implements DiffsEditor { const children = parent.children; for (let i = children.length - 1; i >= 0; i--) { const child = children[i] as HTMLElement; - const { lineIndex, lineAnnotation } = child.dataset; - if (lineIndex !== undefined || lineAnnotation !== undefined) { - const lineIndexNum = Number( - lineAnnotation !== undefined - ? lineAnnotation.split(',')[1] - : lineIndex - ); - if (lineIndexNum < change.lineCount) { - break; - } - child.remove(); + const { line, columnNumber, lineAnnotation } = child.dataset; + if ( + line === undefined && + columnNumber === undefined && + lineAnnotation === undefined + ) { + continue; + } + const lineIndex = + lineAnnotation !== undefined + ? parseInt(lineAnnotation.split(',')[1], 10) + : parseInt(line ?? columnNumber!, 10) - 1; + if (Number.isNaN(lineIndex)) { + continue; + } + if (lineIndex < change.lineCount) { + break; } + child.remove(); } } } @@ -1468,29 +1500,28 @@ export class Editor implements DiffsEditor { } const { start, end } = selection; - for (let ln = start.line; ln <= end.line; ln++) { - if (!this.#isLineVisible(ln)) { + for (let line = start.line; line <= end.line; line++) { + if (!this.#isLineVisible(line)) { continue; } - const lineText = this.#textDocument.getLineText(ln); - const startChar = ln === start.line ? start.character : 0; - const endChar = ln === end.line ? end.character : lineText.length; + const isLastLine = line === end.line; + const lineText = this.#textDocument.getLineText(line); + const startChar = line === start.line ? start.character : 0; + const endChar = isLastLine ? end.character : lineText.length; if (this.#wrap) { - const paddingInline = this.#metrics.ch; // 1ch, align to diff css: padding-inline: 1ch const contentWidth = this.#getContentWidth(); const textWidth = - 2 * paddingInline + this.#metrics.measureTextWidth(lineText); + 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText); if (textWidth > contentWidth) { this.#renderWrappedSelection( renderCtx, - selection, - ln, + line, lineText, startChar, endChar, - paddingInline + isLastLine ); continue; } @@ -1498,24 +1529,20 @@ export class Editor implements DiffsEditor { let left = 0; let width = 0; - if (startChar === endChar && startChar === 0) { + if (startChar === 0) { left = this.#getGutterWidth() + this.#metrics.ch; // gutter width + inline padding (1ch) - width = ln === end.line ? 0 : this.#metrics.ch; } else { - left = this.#getCharX(ln, startChar)[0]; + left = this.#getCharX(line, startChar)[0]; + } + if (startChar === endChar) { + width = isLastLine ? 0 : this.#metrics.ch; + } else { width = - endChar === startChar ? 0 : this.#getCharX(ln, endChar)[0] - left; + this.#getCharX(line, endChar)[0] - + left + + (isLastLine ? 0 : this.#metrics.ch); } - this.#renderSelectionRange( - renderCtx, - selection, - ln, - 0, - startChar, - endChar, - width, - left - ); + this.#renderSelectionLine(renderCtx, line, 0, left, width); } } @@ -1530,21 +1557,19 @@ export class Editor implements DiffsEditor { fragment: DocumentFragment; elements: Map; }, - selection: EditorSelection, line: number, lineText: string, startChar: number, endChar: number, - paddingInline: number + isLastLine: boolean ) { const wrapOffsets = this.#wrapLineText(line); const segmentCount = wrapOffsets.length - 1; - const lastSegmentIndex = segmentCount - 1; - const offsetLeft = this.#getGutterWidth() + paddingInline; + const offsetLeft = this.#getGutterWidth() + this.#metrics.ch; - for (let w = 0; w < segmentCount; w++) { - const segmentStart = wrapOffsets[w]; - const segmentEnd = wrapOffsets[w + 1]; + for (let wrapLine = 0; wrapLine < segmentCount; wrapLine++) { + const segmentStart = wrapOffsets[wrapLine]; + const segmentEnd = wrapOffsets[wrapLine + 1]; const wrapStartChar = Math.max(startChar, segmentStart); const wrapEndChar = Math.min(endChar, segmentEnd); @@ -1553,26 +1578,10 @@ export class Editor implements DiffsEditor { continue; } - // Zero-width slices on segment boundaries can appear on two consecutive - // segments (end of one, start of the next). Only render at the natural - // anchor positions: the very beginning of the first visual line, or the - // very end of the last visual line. - if (wrapStartChar === wrapEndChar) { - const isAtLineStart = wrapStartChar === 0 && w === 0; - const isAtLineEnd = - wrapEndChar === lineText.length && w === lastSegmentIndex; - if (!isAtLineStart && !isAtLineEnd) { - continue; - } - } - let segmentLeft: number; let segmentWidth: number; - if (wrapStartChar === 0 && wrapEndChar === 0) { - // Empty range pinned to line start (e.g. multi-line selection ending - // with end.character === 0). Mirrors the non-wrap path. + if (wrapStartChar === 0) { segmentLeft = offsetLeft; - segmentWidth = line === selection.end.line ? 0 : paddingInline; } else { const prefixInSegment = lineText.slice(segmentStart, wrapStartChar); const prefixAsciiColumns = getExpandedAsciiTextColumns( @@ -1584,70 +1593,172 @@ export class Editor implements DiffsEditor { (prefixAsciiColumns !== -1 ? prefixAsciiColumns * this.#metrics.ch : this.#metrics.measureTextWidth(prefixInSegment)); - - if (wrapStartChar === wrapEndChar) { - segmentWidth = 0; - } else { - const selectionInSegment = lineText.slice(wrapStartChar, wrapEndChar); - const selectionAsciiWidth = getExpandedAsciiTextColumns( - selectionInSegment, - this.#metrics.tabSize - ); - segmentWidth = - selectionAsciiWidth !== -1 - ? selectionAsciiWidth * this.#metrics.ch - : this.#metrics.measureTextWidth(selectionInSegment); + } + if (wrapStartChar === wrapEndChar) { + segmentWidth = wrapLine === segmentCount - 1 ? 0 : this.#metrics.ch; + } else { + const selectionInSegment = lineText.slice(wrapStartChar, wrapEndChar); + const selectionAsciiWidth = getExpandedAsciiTextColumns( + selectionInSegment, + this.#metrics.tabSize + ); + segmentWidth = + selectionAsciiWidth !== -1 + ? selectionAsciiWidth * this.#metrics.ch + : this.#metrics.measureTextWidth(selectionInSegment); + if (!isLastLine && wrapLine === segmentCount - 1) { + segmentWidth += this.#metrics.ch; } } - this.#renderSelectionRange( + this.#renderSelectionLine( renderCtx, - selection, line, - w, - wrapStartChar, - wrapEndChar, - segmentWidth, + wrapLine, segmentLeft, - w === lastSegmentIndex + segmentWidth ); } } - // Render one selection range div for a single visual line. `applyEolSpacing` - // controls whether the trailing one-character "line continuation" marker is - // appended at the end. For wrapped logical lines this must be false on every - // visual segment except the last one, since an intra-line wrap is not a real - // newline and shouldn't visually extend past the wrapped content. - #renderSelectionRange( + #renderSelectionLine( renderCtx: { fragment: DocumentFragment; elements: Map; + previousSelectionRange?: { + element: HTMLElement; + line: number; + wrapLine: number; + left: number; + width: number; + }; }, - selection: EditorSelection, - ln: number, + line: number, wrapLine: number, - startChar: number, - endChar: number, - width: number, left: number, - applyEolSpacing = true + width: number ) { - const spacing = - !applyEolSpacing || - selection.end.line === ln || - (startChar === endChar && ln !== selection.start.line) - ? 0 - : this.#metrics.ch; - const css = `width:${width + spacing}px;transform:translateY(${this.#getLineY(ln) + wrapLine * this.#metrics.lineHeight}px) translateX(${left}px);`; - const cacheKey = 'selection-range-' + css; + if (width === 0) { + return; + } + + const { ch, lineHeight } = this.#metrics; + const y = this.#getLineY(line) + wrapLine * lineHeight; + const css = `width:${width}px;transform:translateX(${left}px) translateY(${y}px);`; + const cacheKey = `selection-line-${left}-${y}-${width}`; const selectionEls = this.#selectionElements; - if (renderCtx.elements.has(cacheKey)) { + const rounded = this.#options.roundedSelection ?? true; + const addRoundedCorner = ( + line: number, + wrapLine: number, + left: number, + radius: 'rtl' | 'rbl' | 'rbr' + ) => { + const top = this.#getLineY(line) + wrapLine * lineHeight; + const css = `width:${ch}px;transform:translateX(${left}px) translateY(${top}px);`; + const dataset = { + selectionCorner: '', + [radius]: '', + }; + const cacheKeyPrefix = `selection-line-${left}-${top}-1ch`; + let cacheKey = cacheKeyPrefix + '-' + radius; + if (radius === 'rbl') { + const prevCornerKey = cacheKeyPrefix + '-rtl'; + const prevCorner = renderCtx.elements.get(prevCornerKey); + if (prevCorner !== undefined) { + prevCorner.remove(); + renderCtx.elements.delete(prevCornerKey); + cacheKey += '-rtl'; + dataset.rtl = ''; + } + } + let cornerEl = renderCtx.elements.get(cacheKey); + if (cornerEl !== undefined) { + return; + } + if (selectionEls?.has(cacheKey) === true) { + cornerEl = selectionEls.get(cacheKey)!; + selectionEls.delete(cacheKey); + } else { + cornerEl = h( + 'div', + { + dataset: 'selectionRange', + style: { cssText: css }, + children: [ + h('div', { + dataset: dataset, + }), + ], + }, + renderCtx.fragment + ); + } + renderCtx.elements.set(cacheKey, cornerEl); + }; + const addRadiusStyle = (element: HTMLElement) => { + const end = left + width; + const dataset = element.dataset; + const previousSelectionRange = renderCtx.previousSelectionRange; + if ( + previousSelectionRange === undefined || + previousSelectionRange.line !== line || + previousSelectionRange.wrapLine !== wrapLine + ) { + renderCtx.previousSelectionRange = { + element, + line, + wrapLine, + left, + width, + }; + } + if ( + previousSelectionRange === undefined || + end <= previousSelectionRange.left + ) { + ['rtl', 'rtr', 'rbl', 'rbr'].forEach((key) => { + dataset[key] = ''; + }); + } else { + const prevLine = previousSelectionRange.line; + const prevWrapLine = previousSelectionRange.wrapLine; + const prevLeft = previousSelectionRange.left; + const prevDataset = previousSelectionRange.element.dataset; + const prevEnd = prevLeft + previousSelectionRange.width; + if (prevLeft > left) { + addRoundedCorner(prevLine, prevWrapLine, prevLeft - ch, 'rbr'); + } + delete prevDataset.rbl; + delete dataset.rtl; + delete dataset.rtr; + if (end >= prevEnd) { + delete prevDataset.rbr; + } + if (end > prevEnd) { + addRoundedCorner(prevLine, prevWrapLine, prevEnd, 'rbl'); + dataset.rtr = ''; + } + if (end < prevEnd) { + addRoundedCorner(line, wrapLine, end, 'rtl'); + } + if (left < prevLeft) { + dataset.rtl = ''; + } + dataset.rbl = ''; + dataset.rbr = ''; + } + }; + + let rangeEl = renderCtx.elements.get(cacheKey); + if (rangeEl !== undefined) { + if (rounded) { + addRadiusStyle(rangeEl); + } return; } - let rangeEl: HTMLElement | undefined; if (selectionEls?.has(cacheKey) === true) { rangeEl = selectionEls.get(cacheKey)!; selectionEls.delete(cacheKey); @@ -1662,6 +1773,9 @@ export class Editor implements DiffsEditor { ); } + if (rounded) { + addRadiusStyle(rangeEl); + } renderCtx.elements.set(cacheKey, rangeEl); } @@ -1678,16 +1792,18 @@ export class Editor implements DiffsEditor { return; } const [left, wrapLine] = this.#getCharX(line, character); - const cacheKey = 'caret-' + line + '(' + wrapLine + ')-' + character; + const cacheKey = 'caret-' + line + '/' + wrapLine + ':' + character; if (renderCtx.elements.has(cacheKey)) { return; } + const x = left - 1; + const y = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight; const caretEl = h( 'div', { dataset: 'caret', style: { - transform: `translateY(${this.#getLineY(line) + wrapLine * this.#metrics.lineHeight}px) translateX(${left - 1}px)`, + transform: `translateX(${x}px) translateY(${y}px)`, }, }, renderCtx.fragment @@ -2145,7 +2261,7 @@ export class Editor implements DiffsEditor { lineNumber !== undefined && lineType !== undefined && isLineEditable(lineType) && - Number(lineNumber) === line + 1 + parseInt(lineNumber, 10) === line + 1 ) { return child; } @@ -2185,7 +2301,10 @@ export class Editor implements DiffsEditor { diffsColumnNumberWidth.length > 2 && diffsColumnNumberWidth.endsWith('px') ) { - this.#gutterWidthCache = Number(diffsColumnNumberWidth.slice(0, -2)); + this.#gutterWidthCache = parseInt( + diffsColumnNumberWidth.slice(0, -2), + 10 + ); } else { this.#gutterWidthCache = gutterElement.offsetWidth; } @@ -2209,7 +2328,9 @@ export class Editor implements DiffsEditor { diffsColumnContentWidth.length > 2 && diffsColumnContentWidth.endsWith('px') ) { - this.#contentWidthCache = Number(diffsColumnContentWidth.slice(0, -2)); + this.#contentWidthCache = parseFloat( + diffsColumnContentWidth.slice(0, -2) + ); } else { this.#contentWidthCache = this.#contentElement.offsetWidth; } diff --git a/packages/diffs/src/editor/selection.ts b/packages/diffs/src/editor/selection.ts index 31c4e9248..1db533fc7 100644 --- a/packages/diffs/src/editor/selection.ts +++ b/packages/diffs/src/editor/selection.ts @@ -1460,14 +1460,23 @@ function getLineChildEnd( function getLineIndex(el: HTMLElement): number | undefined { const { line } = el.dataset; if (line !== undefined) { - return parseInt(line) - 1; + const lineNumber = parseInt(line, 10); + if (!Number.isNaN(lineNumber)) { + return lineNumber - 1; + } } return undefined; } function getCharacterIndex(el: HTMLElement): number | undefined { const { char } = el.dataset; - return char !== undefined ? parseInt(char) : undefined; + if (char !== undefined) { + const charIndex = parseInt(char, 10); + if (!Number.isNaN(charIndex)) { + return charIndex; + } + } + return undefined; } function getTextOffset( diff --git a/packages/diffs/src/editor/textMeasure.ts b/packages/diffs/src/editor/textMeasure.ts index 24c270017..3839a08be 100644 --- a/packages/diffs/src/editor/textMeasure.ts +++ b/packages/diffs/src/editor/textMeasure.ts @@ -33,10 +33,10 @@ export class Metrics { const { fontSize, fontFamily, tabSize, lineHeight } = getComputedStyle(root); if (lineHeight.endsWith('px')) { - this.lineHeight = Number(lineHeight.slice(0, -2)); + this.lineHeight = parseFloat(lineHeight.slice(0, -2)); } else if (fontSize.endsWith('px')) { this.lineHeight = round( - Number(fontSize.slice(0, -2)) * Number(lineHeight) + parseFloat(fontSize.slice(0, -2)) * parseFloat(lineHeight) ); } const font = fontSize + ' ' + fontFamily; @@ -45,7 +45,7 @@ export class Metrics { this.#canvasCtx.font = font; this.ch = this.canvasMeasureTextWidth('0'); } - this.tabSize = Number(tabSize); + this.tabSize = parseInt(tabSize, 10); } /** measure the width of the text */ diff --git a/packages/diffs/src/editor/tokenzier.ts b/packages/diffs/src/editor/tokenzier.ts index 9e2d5f69b..57875c591 100644 --- a/packages/diffs/src/editor/tokenzier.ts +++ b/packages/diffs/src/editor/tokenzier.ts @@ -92,12 +92,14 @@ export class EditorTokenizer { const lineHighlightBackground = colors['editor.lineHighlightBackground']; const gutterForeground = colors['editorLineNumber.foreground']; const gutterActiveForeground = colors['editorLineNumber.activeForeground']; + const cursorForeground = colors['editorCursor.foreground']; this.#setStyle(`:host { --diffs-editor-selection-bg: ${selectionBackground ?? 'var(--diffs-line-bg)'}; --diffs-editor-line-highlight-bg: ${lineHighlightBackground ?? 'var(--diffs-line-bg)'}; --diffs-editor-line-number-fg: ${gutterForeground ?? 'var(--diffs-fg-number)'}; --diffs-editor-line-number-active-bg: ${lineHighlightBackground ?? 'var(--diffs-line-bg, var(--diffs-bg))'}; --diffs-editor-line-number-active-fg: ${gutterActiveForeground ?? 'var(--diffs-selection-number-fg)'}; + ${cursorForeground !== undefined ? '--diffs-editor-cursor-fg: ' + cursorForeground : ''}; }`); }; diff --git a/packages/diffs/src/style.css b/packages/diffs/src/style.css index 44cccdf0b..981c90a3a 100644 --- a/packages/diffs/src/style.css +++ b/packages/diffs/src/style.css @@ -132,14 +132,6 @@ var(--diffs-fg-number) ); - --diffs-bg-caret: var( - --diffs-bg-caret-override, - light-dark( - color-mix(in lab, var(--diffs-fg) 50%, var(--diffs-bg)), - color-mix(in lab, var(--diffs-fg) 75%, var(--diffs-bg)) - ) - ); - --diffs-deletion-base: var( --diffs-deletion-color-override, light-dark( diff --git a/packages/diffs/src/types.ts b/packages/diffs/src/types.ts index c72327250..3199a4980 100644 --- a/packages/diffs/src/types.ts +++ b/packages/diffs/src/types.ts @@ -888,19 +888,7 @@ export interface StickySpecs { height: number; } -export interface DiffsEditor { - syncWithRender( - highlighter: DiffsHighlighter, - fileContainer: HTMLElement, - fileContents: FileContents, - lineAnnotations: LineAnnotation[] | undefined, - renderRange: RenderRange | undefined, - editMode?: 'simple' | 'advanced' - ): void; - cleanUp(): void; -} - -export interface DiffsEditorOptions extends BaseCodeOptions { +export interface DiffsComponentOptions extends BaseCodeOptions { enableGutterUtility?: boolean; enableLineSelection?: boolean; expandUnchanged?: boolean; @@ -909,8 +897,8 @@ export interface DiffsEditorOptions extends BaseCodeOptions { export interface DiffsBaseComponent { readonly top?: number; - readonly options: DiffsEditorOptions; - setOptions: (options: Partial) => void; + readonly options: DiffsComponentOptions; + setOptions: (options: Partial) => void; setSelectedLines: (range: { start: number; end: number } | null) => void; rerender(): void; cleanUp(): void; @@ -931,10 +919,16 @@ export interface DiffsEditableComponent< ) => void; } -export interface DiffsTextDocument { - lineCount: number; - getLineText: (lineNumber: number) => string; - getText: () => string; +export interface DiffsEditor { + syncWithRender( + highlighter: DiffsHighlighter, + fileContainer: HTMLElement, + fileContents: FileContents, + lineAnnotations: LineAnnotation[] | undefined, + renderRange: RenderRange | undefined, + editMode?: 'simple' | 'advanced' + ): void; + cleanUp(): void; } export interface DiffsEditorSelection { @@ -948,3 +942,9 @@ export interface DiffsEditorSelection { }; direction: 'none' | 'backward' | 'forward'; } + +export interface DiffsTextDocument { + readonly lineCount: number; + getLineText: (lineNumber: number) => string; + getText: () => string; +}