Skip to content

Instantly share code, notes, and snippets.

@karudo
Created May 15, 2020 17:41
Show Gist options
  • Save karudo/af9cdafcb0890076d804965e11a64a36 to your computer and use it in GitHub Desktop.
Save karudo/af9cdafcb0890076d804965e11a64a36 to your computer and use it in GitHub Desktop.
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;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment