import { EditorState, ContentBlock, genKey } from 'draft-js'; import { List, Map } from 'immutable'; export const getSelectionRange = () => { const selection = window.getSelection(); if (selection.rangeCount === 0) return null; return selection.getRangeAt(0); }; export const getSelectionCoords = (selectionRange) => { const editorBounds = document.getElementById('editor-container').getBoundingClientRect(); const rangeBounds = selectionRange.getBoundingClientRect(); const rangeWidth = rangeBounds.right - rangeBounds.left; const offsetLeft = (rangeBounds.left - editorBounds.left) + (rangeWidth / 2) /* 107px is width of inline toolbar */ - (142 / 2); // 42px is height of inline toolbar (35px) + 5px center triangle and 2px for spacing const offsetTop = rangeBounds.top - editorBounds.top - 42; return { offsetLeft, offsetTop }; }; export const getCurrentBlock = (editorState) => { const selectionState = editorState.getSelection(); const contentState = editorState.getCurrentContent(); return contentState.getBlockForKey(selectionState.getStartKey()); }; /* Used from [react-rte](https://github.com/sstur/react-rte/blob/master/src/lib/insertBlockAfter.js) by [sstur](https://github.com/sstur) */ export const addNewBlockAt = ( editorState, pivotBlockKey, newBlockType = 'unstyled', initialData = new Map({}) ) => { const content = editorState.getCurrentContent(); const blockMap = content.getBlockMap(); const block = blockMap.get(pivotBlockKey); if (!block) { throw new Error(`The pivot key - ${ pivotBlockKey } is not present in blockMap.`); } const blocksBefore = blockMap.toSeq().takeUntil((v) => (v === block)); const blocksAfter = blockMap.toSeq().skipUntil((v) => (v === block)).rest(); const newBlockKey = genKey(); const newBlock = new ContentBlock({ key: newBlockKey, type: newBlockType, text: '', characterList: new List(), depth: 0, data: initialData, }); const newBlockMap = blocksBefore.concat( [[pivotBlockKey, block], [newBlockKey, newBlock]], blocksAfter ).toOrderedMap(); const selection = editorState.getSelection(); const newContent = content.merge({ blockMap: newBlockMap, selectionBefore: selection, selectionAfter: selection.merge({ anchorKey: newBlockKey, anchorOffset: 0, focusKey: newBlockKey, focusOffset: 0, isBackward: false, }), }); return EditorState.push(editorState, newContent, 'split-block'); }; export const closest = (element, matchFunction) => { let currentElement = element; while (currentElement) { if (matchFunction(currentElement)) return currentElement; currentElement = currentElement.parentNode; } }; export const hasClass = (element, className) => { let isHasClass = false; if (element.classList) { isHasClass = element.classList.contains(className); } else { isHasClass = new RegExp(`(^| )${ className }( |$)`, 'gi').test(element.className); } return isHasClass; };