From d92351e67a0f5dda4e43f35c654220cca6b59de8 Mon Sep 17 00:00:00 2001 From: Aaryan Pashine Date: Fri, 21 Feb 2025 00:17:07 -0500 Subject: [PATCH 1/4] support css scaling --- src/block-cursor.ts | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/block-cursor.ts b/src/block-cursor.ts index e686d63..3c773ca 100644 --- a/src/block-cursor.ts +++ b/src/block-cursor.ts @@ -60,6 +60,8 @@ export class BlockCursorPlugin { measureReq: {read: () => Measure, write: (value: Measure) => void} cursorLayer: HTMLElement cm: CodeMirror + scaleX = 1 + scaleY = 1 constructor(readonly view: EditorView, cm: CodeMirror) { this.cm = cm; @@ -67,8 +69,10 @@ export class BlockCursorPlugin { this.cursorLayer = view.scrollDOM.appendChild(document.createElement("div")) this.cursorLayer.className = "cm-cursorLayer cm-vimCursorLayer" this.cursorLayer.setAttribute("aria-hidden", "true") + this.cursorLayer.style.position = "absolute" + this.scale() view.requestMeasure(this.measureReq) - this.setBlinkRate() + this.setBlinkRate() } setBlinkRate() { @@ -78,11 +82,20 @@ export class BlockCursorPlugin { } update(update: ViewUpdate) { - if (update.selectionSet || update.geometryChanged || update.viewportChanged) { + if (update.selectionSet || update.geometryChanged || update.viewportChanged) { + this.scale() this.view.requestMeasure(this.measureReq) this.cursorLayer.style.animationName = this.cursorLayer.style.animationName == "cm-blink" ? "cm-blink2" : "cm-blink" - } - if (configChanged(update)) this.setBlinkRate(); + } + if (configChanged(update)) this.setBlinkRate(); + } + + scale() { + let { scaleX, scaleY } = this.view + if (scaleX != this.scaleX || scaleY != this.scaleY) { + this.scaleX = scaleX; this.scaleY = scaleY + this.cursorLayer.style.transform = `scale(${1 / scaleX}, ${1 / scaleY})` + } } scheduleRedraw() { @@ -146,7 +159,7 @@ export const hideNativeSelection = Prec.highest(EditorView.theme(themeSpec)) function getBase(view: EditorView) { let rect = view.scrollDOM.getBoundingClientRect() let left = view.textDirection == Direction.LTR ? rect.left : rect.right - view.scrollDOM.clientWidth - return {left: left - view.scrollDOM.scrollLeft, top: rect.top - view.scrollDOM.scrollTop} + return {left: left - view.scrollDOM.scrollLeft * view.scaleX, top: rect.top - view.scrollDOM.scrollTop * view.scaleY} } function measureCursor(cm: CodeMirror, view: EditorView, cursor: SelectionRange, primary: boolean): Piece | null { @@ -207,10 +220,7 @@ function measureCursor(cm: CodeMirror, view: EditorView, cursor: SelectionRange, letter += view.state.sliceDoc(head + 1, head + 2); } let h = (pos.bottom - pos.top); - return new Piece(left - base.left, pos.top - base.top + h * (1 - hCoeff), h * hCoeff, - style.fontFamily, style.fontSize, style.fontWeight, style.color, - primary ? "cm-fat-cursor cm-cursor-primary" : "cm-fat-cursor cm-cursor-secondary", - letter, hCoeff != 1) + return new Piece(left - base.left, pos.top - base.top + h * (1 - hCoeff), h * hCoeff, style.fontFamily, parseFloat(style.fontSize) * view.scaleX + "px", style.fontWeight, style.color, primary ? "cm-fat-cursor cm-cursor-primary" : "cm-fat-cursor cm-cursor-secondary", letter, hCoeff != 1) } else { return null; } From 6cf80d67c5752498c4e415d29e3e8b688f12c232 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 26 Mar 2025 17:21:37 +0400 Subject: [PATCH 2/4] simplify scale support --- src/block-cursor.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/block-cursor.ts b/src/block-cursor.ts index 3c773ca..0346d14 100644 --- a/src/block-cursor.ts +++ b/src/block-cursor.ts @@ -60,8 +60,6 @@ export class BlockCursorPlugin { measureReq: {read: () => Measure, write: (value: Measure) => void} cursorLayer: HTMLElement cm: CodeMirror - scaleX = 1 - scaleY = 1 constructor(readonly view: EditorView, cm: CodeMirror) { this.cm = cm; @@ -69,8 +67,6 @@ export class BlockCursorPlugin { this.cursorLayer = view.scrollDOM.appendChild(document.createElement("div")) this.cursorLayer.className = "cm-cursorLayer cm-vimCursorLayer" this.cursorLayer.setAttribute("aria-hidden", "true") - this.cursorLayer.style.position = "absolute" - this.scale() view.requestMeasure(this.measureReq) this.setBlinkRate() } @@ -83,19 +79,10 @@ export class BlockCursorPlugin { update(update: ViewUpdate) { if (update.selectionSet || update.geometryChanged || update.viewportChanged) { - this.scale() this.view.requestMeasure(this.measureReq) this.cursorLayer.style.animationName = this.cursorLayer.style.animationName == "cm-blink" ? "cm-blink2" : "cm-blink" - } - if (configChanged(update)) this.setBlinkRate(); - } - - scale() { - let { scaleX, scaleY } = this.view - if (scaleX != this.scaleX || scaleY != this.scaleY) { - this.scaleX = scaleX; this.scaleY = scaleY - this.cursorLayer.style.transform = `scale(${1 / scaleX}, ${1 / scaleY})` } + if (configChanged(update)) this.setBlinkRate(); } scheduleRedraw() { @@ -220,7 +207,10 @@ function measureCursor(cm: CodeMirror, view: EditorView, cursor: SelectionRange, letter += view.state.sliceDoc(head + 1, head + 2); } let h = (pos.bottom - pos.top); - return new Piece(left - base.left, pos.top - base.top + h * (1 - hCoeff), h * hCoeff, style.fontFamily, parseFloat(style.fontSize) * view.scaleX + "px", style.fontWeight, style.color, primary ? "cm-fat-cursor cm-cursor-primary" : "cm-fat-cursor cm-cursor-secondary", letter, hCoeff != 1) + return new Piece((left - base.left)/view.scaleX, (pos.top - base.top + h * (1 - hCoeff))/view.scaleY, h * hCoeff/view.scaleY, + style.fontFamily, parseFloat(style.fontSize) + "px", style.fontWeight, style.color, + primary ? "cm-fat-cursor cm-cursor-primary" : "cm-fat-cursor cm-cursor-secondary", + letter, hCoeff != 1) } else { return null; } From 4b9e1a020003e8778c594c115ed3ce85b70c94ca Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 26 Mar 2025 17:48:20 +0400 Subject: [PATCH 3/4] fix cursor taking color of previous character --- src/block-cursor.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/block-cursor.ts b/src/block-cursor.ts index 0346d14..1f43b4b 100644 --- a/src/block-cursor.ts +++ b/src/block-cursor.ts @@ -179,6 +179,12 @@ function measureCursor(cm: CodeMirror, view: EditorView, cursor: SelectionRange, let base = getBase(view); let domAtPos = view.domAtPos(head); let node = domAtPos ? domAtPos.node : view.contentDOM; + if (node instanceof Text && domAtPos.offset >= node.data.length) { + if (node.parentElement?.nextSibling) { + node = node.parentElement?.nextSibling; + domAtPos = {node: node, offset: 0}; + }; + } while (domAtPos && domAtPos.node instanceof HTMLElement) { node = domAtPos.node; domAtPos = {node: domAtPos.node.childNodes[domAtPos.offset], offset: 0}; From d8e13282b2022638f0e8540044a388f11269abbc Mon Sep 17 00:00:00 2001 From: Harutyun Amirjanyan Date: Wed, 26 Mar 2025 18:03:31 +0400 Subject: [PATCH 4/4] Update src/block-cursor.ts --- src/block-cursor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block-cursor.ts b/src/block-cursor.ts index 1f43b4b..65166b1 100644 --- a/src/block-cursor.ts +++ b/src/block-cursor.ts @@ -214,7 +214,7 @@ function measureCursor(cm: CodeMirror, view: EditorView, cursor: SelectionRange, } let h = (pos.bottom - pos.top); return new Piece((left - base.left)/view.scaleX, (pos.top - base.top + h * (1 - hCoeff))/view.scaleY, h * hCoeff/view.scaleY, - style.fontFamily, parseFloat(style.fontSize) + "px", style.fontWeight, style.color, + style.fontFamily, style.fontSize, style.fontWeight, style.color, primary ? "cm-fat-cursor cm-cursor-primary" : "cm-fat-cursor cm-cursor-secondary", letter, hCoeff != 1) } else {