Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Function to get information around cursor
/* @flow */
/* this code heavily borrows from */
export type CursorContext = {
textNode: Node;
textNodeParent: Node;
textNodeContent: string;
textBeforeCursor: string;
textAfterCursor: string;
cursorCharacterPosition: number;
export default function getCursorContext(): ?CursorContext {
let cursorTextNodeAndParent = getTextNodeAndParent();
if(!cursorTextNodeAndParent) return null;
// we now normalize the textNodeParent to make sure there's only one text node
// makes subsequent code a lot simpler
cursorTextNodeAndParent = getTextNodeAndParent();
if(!cursorTextNodeAndParent) return null;
const {textNode, textNodeParent, selection} = cursorTextNodeAndParent;
const range = selection.getRangeAt(0);
const textNodeContent = textNode.textContent;
const cursorCharacterPosition = range.startOffset;
if(!(cursorCharacterPosition >= 0)) return null;
return {
textNode, textNodeParent, textNodeContent, cursorCharacterPosition,
textBeforeCursor: textNodeContent.substring(0, cursorCharacterPosition),
textAfterCursor: textNodeContent.substr(cursorCharacterPosition)
function getTextNodeAndParent(): ?{textNode: Node; textNodeParent: Node; selection: Selection;} {
const selection = document.getSelection();
if(!selection) return null;
const textNode = selection.anchorNode;
if(!textNode || textNode.nodeType !== Node.TEXT_NODE) return null;
const textNodeParent = textNode.parentNode;
if(!textNodeParent) return null;
return {textNode, textNodeParent, selection};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment