|
1 | | -import {EditorSelection, Extension, Facet, combineConfig, Prec, EditorState} from "@codemirror/state" |
| 1 | +import {EditorSelection, SelectionRange, Extension, Facet, combineConfig, Prec, EditorState} from "@codemirror/state" |
2 | 2 | import {ViewUpdate, nativeSelectionHidden} from "./extension" |
3 | 3 | import {EditorView} from "./editorview" |
4 | | -import {layer, RectangleMarker} from "./layer" |
| 4 | +import {layer, RectangleMarker, getBase} from "./layer" |
| 5 | +import browser from "./browser" |
5 | 6 |
|
6 | 7 | type SelectionConfig = { |
7 | 8 | /// The length of a full cursor blink cycle, in milliseconds. |
@@ -93,11 +94,27 @@ function setBlinkRate(state: EditorState, dom: HTMLElement) { |
93 | 94 | dom.style.animationDuration = state.facet(selectionConfig).cursorBlinkRate + "ms" |
94 | 95 | } |
95 | 96 |
|
| 97 | +const enum Handle { Size = 8, Half = Size >> 1 } |
| 98 | + |
| 99 | +function iosSelectionHandles(view: EditorView, range: SelectionRange) { |
| 100 | + let handles: RectangleMarker[] = [], base = getBase(view) |
| 101 | + let start = view.coordsAtPos(range.from, 1) |
| 102 | + if (start) handles.push(new RectangleMarker("cm-selectionHandle", start.left - base.left - Handle.Half, |
| 103 | + start.top - base.top - Handle.Size, Handle.Size, Handle.Size)) |
| 104 | + let end = view.coordsAtPos(range.to, -1) |
| 105 | + if (end) handles.push(new RectangleMarker("cm-selectionHandle", end.left - base.left - Handle.Half, |
| 106 | + end.bottom - base.top, Handle.Size, Handle.Size)) |
| 107 | + return handles |
| 108 | +} |
| 109 | + |
96 | 110 | const selectionLayer = layer({ |
97 | 111 | above: false, |
98 | 112 | markers(view) { |
99 | | - return view.state.selection.ranges.map(r => r.empty ? [] : RectangleMarker.forRange(view, "cm-selectionBackground", r)) |
| 113 | + let {selection} = view.state |
| 114 | + let markers = selection.ranges.map(r => r.empty ? [] : RectangleMarker.forRange(view, "cm-selectionBackground", r)) |
100 | 115 | .reduce((a, b) => a.concat(b)) |
| 116 | + if (browser.ios && !selection.main.empty) markers = markers.concat(iosSelectionHandles(view, selection.main)) |
| 117 | + return markers |
101 | 118 | }, |
102 | 119 | update(update, dom) { |
103 | 120 | return update.docChanged || update.selectionSet || update.viewportChanged || configChanged(update) |
|
0 commit comments