function editOnSelect(editor: DraftEditor): void { if (editor._blockSelectEvents || editor._latestEditorState !== editor.props.editorState) { return; } var editorState = editor.props.editorState; var documentSelection = getDraftEditorSelection( editorState, ReactDOM.findDOMNode(editor.refs.editorContainer).firstChild, ); var updatedSelectionState = documentSelection.selectionState; if (updatedSelectionState !== editorState.getSelection()) { if (documentSelection.needsRecovery) { editorState = EditorState.forceSelection( editorState, updatedSelectionState, ); } else { editorState = EditorState.acceptSelection( editorState, updatedSelectionState, ); } editor.update(editorState); } }
it('is entirely selected', function() { var block = blocks[0]; var decorators = block.childNodes; var leafs = decorators[0].childNodes; window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: block, anchorOffset: 0, focusNode: block, focusOffset: decorators.length, }); var textLength = 0; for (var ii = 0; ii < leafs.length; ii++) { textLength += leafs[ii].textContent.length; } var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 0, focusKey: 'a', focusOffset: textLength, isBackward: false, }), needsRecovery: true, }); });
const assertGetDraftEditorSelection = getSelectionReturnValue => { document.selection = null; window.getSelection = jest.fn(); window.getSelection.mockReturnValueOnce(getSelectionReturnValue); const selection = getDraftEditorSelection(editorState, root); expect({ ...selection, selectionState: selection.selectionState.toJS(), }).toMatchSnapshot(); };
function editOnSelect(editor: DraftEditor): void { if ( editor._blockSelectEvents || editor._latestEditorState !== editor.props.editorState ) { if (editor._blockSelectEvents) { const editorState = editor.props.editorState; const selectionState = editorState.getSelection(); DraftJsDebugLogging.logBlockedSelectionEvent({ // For now I don't think we need any other info anonymizedDom: 'N/A', extraParams: JSON.stringify({stacktrace: new Error().stack}), selectionState: JSON.stringify(selectionState.toJS()), }); } return; } let editorState = editor.props.editorState; const editorNode = ReactDOM.findDOMNode(editor.editorContainer); invariant(editorNode, 'Missing editorNode'); invariant( editorNode.firstChild instanceof HTMLElement, 'editorNode.firstChild is not an HTMLElement', ); const documentSelection = getDraftEditorSelection( editorState, editorNode.firstChild, ); const updatedSelectionState = documentSelection.selectionState; if (updatedSelectionState !== editorState.getSelection()) { if (documentSelection.needsRecovery) { editorState = EditorState.forceSelection( editorState, updatedSelectionState, ); } else { editorState = EditorState.acceptSelection( editorState, updatedSelectionState, ); } editor.update(editorState); } }
it('starts at head of text node, ends at head of leaf span', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: textNodes[0], anchorOffset: 0, focusNode: leafs[4], focusOffset: 0, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 0, focusKey: 'c', focusOffset: 0, isBackward: false, }), needsRecovery: true, }); });
it('is collapsed at start', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: root, anchorOffset: 0, focusNode: root, focusOffset: 0, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 0, focusKey: 'a', focusOffset: 0, isBackward: false, }), needsRecovery: true, }); });
it('goes from end of one to end of other', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: blocks[0], anchorOffset: blocks[0].childNodes.length, focusNode: blocks[2], focusOffset: blocks[2].childNodes.length, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: blocks[0].textContent.length, focusKey: 'c', focusOffset: blocks[2].textContent.length, isBackward: false, }), needsRecovery: true, }); });
it('reversed leaf to leaf', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: leafs[4], anchorOffset: leafs[4].childNodes.length, focusNode: leafs[0], focusOffset: 0, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'c', anchorOffset: leafs[4].textContent.length, focusKey: 'a', focusOffset: 0, isBackward: true, }), needsRecovery: true, }); });
it('is the same as above but reversed', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: blocks[2].firstChild, anchorOffset: 1, focusNode: blocks[0], focusOffset: 1, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'c', anchorOffset: textNodes[4].textContent.length, focusKey: 'a', focusOffset: blocks[0].textContent.length, isBackward: true, }), needsRecovery: true, }); });
it('is contains multiple children', () => { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: contents, anchorOffset: 0, focusNode: contents, focusOffset: 3, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 0, focusKey: 'c', focusOffset: blocks[2].textContent.length, isBackward: false, }), needsRecovery: true, }); });
it('from start of one to start of another', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: leafs[0], anchorOffset: 0, focusNode: leafs[4], focusOffset: 0, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 0, focusKey: 'c', focusOffset: 0, isBackward: false, }), needsRecovery: true, }); });
it('does the crazy stuff described above', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: textNodes[0], anchorOffset: 0, focusNode: root, focusOffset: root.childNodes.length, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 0, focusKey: 'c', focusOffset: blocks[2].textContent.length, isBackward: false, }), needsRecovery: true, }); });
it('is a reversed selection across multiple text nodes', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: textNodes[4], anchorOffset: 4, focusNode: textNodes[0], focusOffset: 6, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'c', anchorOffset: 4, focusKey: 'a', focusOffset: 6, isBackward: true, }), needsRecovery: false, }); });
it('starts within one text node and ends within another', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: textNodes[0], anchorOffset: 4, focusNode: textNodes[4], focusOffset: 6, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 4, focusKey: 'c', focusOffset: 6, isBackward: false, }), needsRecovery: false, }); });
it('extends from head of one node to end of another', function() { window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: textNodes[0], anchorOffset: 0, focusNode: textNodes[2], focusOffset: textNodes[2].textContent.length, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 0, focusKey: 'b', focusOffset: textNodes[2].textContent.length, isBackward: false, }), needsRecovery: false, }); });
it('is a reversed text-to-leaf selection', function() { var leaf = leafs[4]; window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: leaf, anchorOffset: 0, focusNode: textNodes[0], focusOffset: 4, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'c', anchorOffset: 0, focusKey: 'a', focusOffset: 4, isBackward: true, }), needsRecovery: true, }); });
it('contains an entire leaf', function() { var leaf = leafs[4]; window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: leaf, anchorOffset: 0, focusNode: leaf, focusOffset: leaf.childNodes.length, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'c', anchorOffset: 0, focusKey: 'c', focusOffset: leaf.textContent.length, isBackward: false, }), needsRecovery: true, }); });
it('starts within text node, ends at end of leaf span', function() { var leaf = leafs[4]; window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: textNodes[0], anchorOffset: 4, focusNode: leaf, focusOffset: leaf.childNodes.length, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 4, focusKey: 'c', focusOffset: leaf.textContent.length, isBackward: false, }), needsRecovery: true, }); });
it('must find offsets for selection on entire text node', function() { var textNode = textNodes[0]; window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: textNode, anchorOffset: 0, focusNode: textNode, focusOffset: textNode.length, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 0, focusKey: 'a', focusOffset: textNode.length, isBackward: false, }), needsRecovery: false, }); });
it('is reversed from the first case', function() { var textNode = textNodes[0]; var block = blocks[0]; window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: block, anchorOffset: block.childNodes.length, focusNode: textNode, focusOffset: 0, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: block.textContent.length, focusKey: 'a', focusOffset: 0, isBackward: true, }), needsRecovery: true, }); });
it('begins within text node, ends at end of block', function() { var textNode = textNodes[0]; var block = blocks[0]; window.getSelection.mockReturnValueOnce({ rangeCount: 1, anchorNode: textNode, anchorOffset: 5, focusNode: block, focusOffset: block.childNodes.length, }); var selection = getDraftEditorSelection(editorState, root); assertEquals(selection, { selectionState: new SelectionState({ anchorKey: 'a', anchorOffset: 5, focusKey: 'a', focusOffset: block.textContent.length, isBackward: false, }), needsRecovery: true, }); });