@@ -2,6 +2,7 @@ import {EditorSelection, Extension, Facet, combineConfig, Prec, EditorState} fro
22import { ViewUpdate , nativeSelectionHidden } from "./extension"
33import { EditorView } from "./editorview"
44import { layer , RectangleMarker } from "./layer"
5+ import browser from "./browser"
56
67type SelectionConfig = {
78 /// The length of a full cursor blink cycle, in milliseconds.
@@ -10,13 +11,18 @@ type SelectionConfig = {
1011 /// Whether to show a cursor for non-empty ranges. Defaults to
1112 /// true.
1213 drawRangeCursor ?: boolean
14+ /// Because hiding the cursor also hides the selection handles in
15+ /// the iOS browser, when this is enabled (the default), the
16+ /// extension draws handles on the side of the selection in iOS.
17+ iosSelectionHandles ?: boolean
1318}
1419
1520const selectionConfig = Facet . define < SelectionConfig , Required < SelectionConfig > > ( {
1621 combine ( configs ) {
1722 return combineConfig ( configs , {
1823 cursorBlinkRate : 1200 ,
19- drawRangeCursor : true
24+ drawRangeCursor : true ,
25+ iosSelectionHandles : true
2026 } , {
2127 cursorBlinkRate : ( a , b ) => Math . min ( a , b ) ,
2228 drawRangeCursor : ( a , b ) => a || b
@@ -68,7 +74,7 @@ const cursorLayer = layer({
6874 let cursors = [ ]
6975 for ( let r of state . selection . ranges ) {
7076 let prim = r == state . selection . main
71- if ( r . empty || conf . drawRangeCursor ) {
77+ if ( r . empty || conf . drawRangeCursor && ! ( prim && browser . ios && conf . iosSelectionHandles ) ) {
7278 let className = prim ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary"
7379 let cursor = r . empty ? r : EditorSelection . cursor ( r . head , r . head > r . anchor ? - 1 : 1 )
7480 for ( let piece of RectangleMarker . forRange ( view , className , cursor ) ) cursors . push ( piece )
@@ -96,8 +102,19 @@ function setBlinkRate(state: EditorState, dom: HTMLElement) {
96102const selectionLayer = layer ( {
97103 above : false ,
98104 markers ( view ) {
99- return view . state . selection . ranges . map ( r => r . empty ? [ ] : RectangleMarker . forRange ( view , "cm-selectionBackground" , r ) )
100- . reduce ( ( a , b ) => a . concat ( b ) )
105+ let markers = [ ] , { main, ranges} = view . state . selection
106+ for ( let r of ranges ) if ( ! r . empty ) {
107+ for ( let marker of RectangleMarker . forRange ( view , "cm-selectionBackground" , r ) ) markers . push ( marker )
108+ }
109+ if ( browser . ios && ! main . empty && view . state . facet ( selectionConfig ) . iosSelectionHandles ) {
110+ for ( let piece of RectangleMarker . forRange ( view , "cm-selectionHandle cm-selectionHandle-start" ,
111+ EditorSelection . cursor ( main . from , 1 ) ) )
112+ markers . push ( piece )
113+ for ( let piece of RectangleMarker . forRange ( view , "cm-selectionHandle cm-selectionHandle-end" ,
114+ EditorSelection . cursor ( main . to , 1 ) ) )
115+ markers . push ( piece )
116+ }
117+ return markers
101118 } ,
102119 update ( update , dom ) {
103120 return update . docChanged || update . selectionSet || update . viewportChanged || configChanged ( update )
0 commit comments