Skip to content
This repository has been archived by the owner on Feb 6, 2023. It is now read-only.

Commit

Permalink
Adding 'preserveSelectionOnBlur' prop (#2128)
Browse files Browse the repository at this point in the history
Summary:
**Summary**

This adds a `preserveSelectionOnBlur` prop as per #2123

**Test Plan**

Tests were added for the two possible scenarios. I'm not sure how much to mock in this test because it is just testing a specific branch of code, so I've faked certain details like the rangeCount.

What do you think mrkev claudiopro ?
Pull Request resolved: #2128

Reviewed By: claudiopro

Differential Revision: D16270879

Pulled By: mrkev

fbshipit-source-id: 304af92c1211b8ff95741bff434b4fe3c4b6dd7d
  • Loading branch information
Matthew Holloway authored and facebook-github-bot committed Jul 16, 2019
1 parent 4064cae commit db792ef
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/component/base/DraftEditorProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ export type DraftEditorProps = {
// is used for both rendering and paste processing.
blockRenderMap: DraftBlockRenderMap,

// When the Editor loses focus (blurs) text selections are cleared
// by default to mimic <textarea> behaviour, however in some situations
// users may wish to preserve native behaviour.
preserveSelectionOnBlur?: boolean,

// Overrides for cut, copy & paste, which can be used to implement custom
// behavior like entity cut/copy/paste (see PR #1784)."
onPaste?: (DraftEditor, SyntheticClipboardEvent<>) => void,
Expand Down
104 changes: 104 additions & 0 deletions src/component/handlers/edit/__tests__/editOnBlur-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+draft_js
* @format
*/

'use strict';

jest.disableAutomock();

const ContentBlock = require('ContentBlock');
const ContentState = require('ContentState');
const EditorState = require('EditorState');

const onBlur = require('editOnBlur');

const getEditorState = (text: string = 'Arsenal') => {
return EditorState.createWithContent(
ContentState.createFromBlockArray([
new ContentBlock({
key: 'a',
text,
}),
]),
);
};

const getBlurEvent = data => ({
data,
});

function withGlobalGetSelectionAs(getSelectionValue = {}, callback) {
const oldGetSelection = global.getSelection;
try {
global.getSelection = () => {
return getSelectionValue;
};
callback();
} finally {
global.getSelection = oldGetSelection;
}
}

test('editor removes selection on blur (default behaviour)', () => {
const anchorNodeText = 'react draftjs';
const anchorNode = document.createTextNode(anchorNodeText);
const globalSelection = {
anchorNode,
focusNode: anchorNode,
removeAllRanges: jest.fn(),
rangeCount: 1,
};

const editorNode = document.createElement('div');
editorNode.appendChild(anchorNode);

withGlobalGetSelectionAs(globalSelection, () => {
const editorState = getEditorState(anchorNodeText);
const editor = {
_latestEditorState: editorState,
props: {
preserveSelectionOnBlur: false,
},
editor: editorNode,
};

onBlur(editor, getBlurEvent());

expect(globalSelection.removeAllRanges).toHaveBeenCalledTimes(1);
});
});

test('editor preserves selection on blur', () => {
const anchorNodeText = 'react draftjs';
const anchorNode = document.createTextNode(anchorNodeText);
const globalSelection = {
anchorNode,
focusNode: anchorNode,
removeAllRanges: jest.fn(),
rangeCount: 1,
};

const editorNode = document.createElement('div');
editorNode.appendChild(anchorNode);

withGlobalGetSelectionAs(globalSelection, () => {
const editorState = getEditorState(anchorNodeText);
const editor = {
_latestEditorState: editorState,
props: {
preserveSelectionOnBlur: true,
},
editor: editorNode,
};

onBlur(editor, getBlurEvent());

expect(globalSelection.removeAllRanges).toHaveBeenCalledTimes(0);
});
});
7 changes: 6 additions & 1 deletion src/component/handlers/edit/editOnBlur.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ function editOnBlur(editor: DraftEditor, e: SyntheticEvent<>): void {
// We therefore force the issue to be certain, checking whether the active
// element is `body` to force it when blurring occurs within the window (as
// opposed to clicking to another tab or window).
if (getActiveElement() === document.body) {
// However if users wish to override this behaviour they can provide
// a prop preserveSelectionOnBlur of `true`.
if (
!editor.props.preserveSelectionOnBlur &&
getActiveElement() === document.body
) {
const selection = global.getSelection();
const editorNode = editor.editor;
if (
Expand Down

0 comments on commit db792ef

Please sign in to comment.