a tool for shared writing and social publishing
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

handle backwards selection

+44 -8
+4
components/Blocks.tsx
··· 30 30 interface ReplayedKeyboardEvent extends KeyboardEvent { 31 31 replayed: boolean; 32 32 } 33 + let skip = false; 33 34 export function Blocks(props: { entityID: string }) { 34 35 let rep = useReplicache(); 35 36 let ref = useRef<HTMLDivElement | null>(null); ··· 38 39 useEffect(() => { 39 40 if (!isMobile) return; 40 41 let selectionChangeHandler = () => { 42 + if (skip == true) return; 41 43 let selection = window.getSelection(); 42 44 let ranges; 43 45 if (previous.current !== selection?.type) { ··· 65 67 previous.current = selection?.type || "None"; 66 68 }; 67 69 let keyDownHandler = (e: KeyboardEvent) => { 70 + skip = true; 68 71 let selection = window.getSelection(); 69 72 if (selection?.type !== "Range") return; 70 73 if ((e as ReplayedKeyboardEvent).replayed) { 74 + skip = false; 71 75 return; 72 76 } 73 77 e.stopPropagation();
+40 -8
components/SelectionManager.tsx
··· 28 28 }, [moreThanOneSelected, rep]); 29 29 let dragStart = useSelectingMouse((s) => s.start); 30 30 let initialContentEditableParent = useRef<null | Node>(null); 31 - let savedSelection = useRef<Range[] | null>(); 31 + let savedSelection = useRef<SavedRange[] | null>(); 32 32 useEffect(() => { 33 33 let mouseDownListener = (e: MouseEvent) => { 34 34 initialContentEditableParent.current = getContentEditableParent( ··· 47 47 ) { 48 48 setTimeout(() => { 49 49 window.getSelection()?.removeAllRanges(); 50 - }, 10); 50 + }, 5); 51 51 } 52 52 savedSelection.current = null; 53 53 useSelectingMouse.setState({ start: null }); ··· 86 86 return null; 87 87 } 88 88 89 + type SavedRange = { 90 + startContainer: Node; 91 + startOffset: number; 92 + endContainer: Node; 93 + endOffset: number; 94 + direction: "forward" | "backward"; 95 + }; 89 96 export function saveSelection() { 90 97 let selection = window.getSelection(); 91 98 if (selection && selection.rangeCount > 0) { 92 - let ranges: Range[] = []; 99 + let ranges: SavedRange[] = []; 93 100 for (let i = 0; i < selection.rangeCount; i++) { 94 - ranges.push(selection.getRangeAt(i)); 101 + let range = selection.getRangeAt(i); 102 + ranges.push({ 103 + startContainer: range.startContainer, 104 + startOffset: range.startOffset, 105 + endContainer: range.endContainer, 106 + endOffset: range.endOffset, 107 + direction: 108 + selection.anchorNode === range.startContainer && 109 + selection.anchorOffset === range.startOffset 110 + ? "forward" 111 + : "backward", 112 + }); 95 113 } 96 114 return ranges; 97 115 } 98 116 return []; 99 117 } 100 118 101 - export function restoreSelection(savedRanges: Range[]) { 102 - if (savedRanges) { 103 - let selection = window.getSelection() || new Selection(); 119 + export function restoreSelection(savedRanges: SavedRange[]) { 120 + if (savedRanges && savedRanges.length > 0) { 121 + let selection = window.getSelection(); 122 + if (!selection) return; 104 123 selection.removeAllRanges(); 105 124 for (let i = 0; i < savedRanges.length; i++) { 106 - selection.addRange(savedRanges[i]); 125 + let range = document.createRange(); 126 + range.setStart(savedRanges[i].startContainer, savedRanges[i].startOffset); 127 + range.setEnd(savedRanges[i].endContainer, savedRanges[i].endOffset); 128 + 129 + selection.addRange(range); 130 + 131 + // If the direction is backward, collapse the selection to the end and then extend it backward 132 + if (savedRanges[i].direction === "backward") { 133 + selection.collapseToEnd(); 134 + selection.extend( 135 + savedRanges[i].startContainer, 136 + savedRanges[i].startOffset, 137 + ); 138 + } 107 139 } 108 140 } 109 141 }