@@ -2,6 +2,7 @@ import { SelectionRange } from "@codemirror/state";
22import { Direction , EditorView , LayerConfig , LayerMarker , MeasureRequest , PluginInstance , ViewUpdate } from "@codemirror/view" ;
33import { debounce } from "obsidian" ;
44import { CursorLayerView , CursorPluginInstance } from "./typing" ;
5+ import { AnimatedCursorSettings } from "main" ;
56
67/** Ensure that it is a layer config. */
78function _isLayerConfig ( object : object ) : object is LayerConfig {
@@ -80,16 +81,18 @@ const _blinkDebouncer = debounce((layerEl: HTMLElement) => {
8081 */
8182class _CursorMarker implements LayerMarker {
8283 private className : string ;
84+ private useTransform : boolean ;
8385
8486 readonly left : number ;
8587 readonly top : number ;
8688 readonly height : number ;
8789
88- constructor ( className : string , left : number , top : number , height : number ) {
90+ constructor ( className : string , left : number , top : number , height : number , useTransform : boolean ) {
8991 this . className = className ;
90- this . left = left ;
91- this . top = top ;
92- this . height = height ;
92+ this . left = Math . round ( left ) ;
93+ this . top = Math . round ( top ) ;
94+ this . height = Math . round ( height ) ;
95+ this . useTransform = useTransform ;
9396 }
9497
9598 draw ( ) : HTMLElement {
@@ -100,8 +103,10 @@ class _CursorMarker implements LayerMarker {
100103 }
101104
102105 update ( cursorEl : HTMLElement , prev : _CursorMarker ) : boolean {
103- if ( prev . className != this . className )
104- return false ;
106+ if (
107+ prev . className != this . className ||
108+ prev . useTransform != this . useTransform
109+ ) return false ;
105110
106111 // Reuse previous debouncer.
107112 this . requestAdjust = prev . requestAdjust ?? this . requestAdjust ;
@@ -115,7 +120,8 @@ class _CursorMarker implements LayerMarker {
115120 this . left == other . left &&
116121 this . top == other . top &&
117122 this . height == other . height &&
118- this . className == other . className
123+ this . className == other . className &&
124+ this . useTransform == other . useTransform
119125 ) ;
120126 }
121127
@@ -124,22 +130,30 @@ class _CursorMarker implements LayerMarker {
124130 * range, the function will use its head position as the marker
125131 * position.
126132 */
127- static forRange ( view : EditorView , className : string , range : SelectionRange ) : _CursorMarker | null {
133+ static forRange ( view : EditorView , className : string , range : SelectionRange , useTransform : boolean ) : _CursorMarker | null {
128134 let cursorPos = view . coordsAtPos ( range . head , range . assoc || 1 ) ;
129135 if ( ! cursorPos ) return null ;
130136 let baseCoords = _getBaseCoords ( view ) ;
131137 return new _CursorMarker (
132138 className ,
133139 cursorPos . left - baseCoords . left ,
134140 cursorPos . top - baseCoords . top ,
135- cursorPos . bottom - cursorPos . top
141+ cursorPos . bottom - cursorPos . top ,
142+ useTransform
136143 ) ;
137144 }
138145
139- /** Adjust the marker position. Should not be run in updating process. */
146+ /**
147+ * Adjust the marker position. Should not be run immediately in `update`
148+ * call, use `requestAdjust` instead.
149+ */
140150 private adjust = ( cursorEl : HTMLElement ) : void => {
141- cursorEl . style . left = this . left + "px" ;
142- cursorEl . style . top = this . top + "px" ;
151+ if ( this . useTransform ) {
152+ cursorEl . style . transform = `translateX(${ this . left } px) translateY(${ this . top } px)` ;
153+ } else {
154+ cursorEl . style . left = this . left + "px" ;
155+ cursorEl . style . top = this . top + "px" ;
156+ }
143157 cursorEl . style . height = this . height + "px" ;
144158 }
145159
@@ -168,9 +182,9 @@ export function hookCursorPlugin(view: EditorView): CursorLayerView | null | und
168182 * Patch the cursor plugin and return the original config that can be
169183 * restored again.
170184 *
171- * **Should only be excuted once after successful hook attemp.**
185+ * **Should not be executed again after successful hook attemp.**
172186 */
173- export function patchCursorPlugin ( cursorPlugin : CursorLayerView ) : LayerConfig {
187+ export function patchCursorPlugin ( cursorPlugin : CursorLayerView , settings : AnimatedCursorSettings ) : LayerConfig {
174188 // Store the original config.
175189 let originalConfig = Object . assign ( { } , cursorPlugin . layer ) ;
176190
@@ -199,7 +213,7 @@ export function patchCursorPlugin(cursorPlugin: CursorLayerView): LayerConfig {
199213 // implemented, so the primary is able to be animated.
200214 let isPrimary = range == state . selection . main ,
201215 className = "cm-cursor " + ( isPrimary ? "cm-cursor-primary" : "cm-cursor-secondary" ) ,
202- cursorMarker = _CursorMarker . forRange ( view , className , range ) ;
216+ cursorMarker = _CursorMarker . forRange ( view , className , range , settings . useTransform ) ;
203217
204218 if ( cursorMarker )
205219 cursors . push ( cursorMarker ) ;
0 commit comments