Editor: Fixes issue where only entire lines were being copied (#18806)
* Editor: Fixes issue where only entire lines were being copied
Closes #18768
* Simplifies onCopy handler and factors out logic for easier testing
Also adds tests to verify behaviour
(cherry picked from commit d6fb48c0ff)
This commit is contained in:
committed by
Torkel Ödegaard
parent
8c168a6b83
commit
b2d86c76c6
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { QueryField } from './QueryField';
|
||||
|
||||
describe('<QueryField />', () => {
|
||||
@@ -28,4 +27,35 @@ describe('<QueryField />', () => {
|
||||
expect(handleEnterAndTabKeySpy).toBeCalled();
|
||||
expect(instance.executeOnChangeAndRunQueries).toBeCalled();
|
||||
});
|
||||
|
||||
it('should copy selected text', () => {
|
||||
const wrapper = shallow(<QueryField initialQuery="" />);
|
||||
const instance = wrapper.instance() as QueryField;
|
||||
const textBlocks = ['ignore this text. copy this text'];
|
||||
const copiedText = instance.getCopiedText(textBlocks, 18, 32);
|
||||
|
||||
expect(copiedText).toBe('copy this text');
|
||||
});
|
||||
|
||||
it('should copy selected text across 2 lines', () => {
|
||||
const wrapper = shallow(<QueryField initialQuery="" />);
|
||||
const instance = wrapper.instance() as QueryField;
|
||||
const textBlocks = ['ignore this text. start copying here', 'lorem ipsum. stop copying here. lorem ipsum'];
|
||||
const copiedText = instance.getCopiedText(textBlocks, 18, 30);
|
||||
|
||||
expect(copiedText).toBe('start copying here\nlorem ipsum. stop copying here');
|
||||
});
|
||||
|
||||
it('should copy selected text across > 2 lines', () => {
|
||||
const wrapper = shallow(<QueryField initialQuery="" />);
|
||||
const instance = wrapper.instance() as QueryField;
|
||||
const textBlocks = [
|
||||
'ignore this text. start copying here',
|
||||
'lorem ipsum doler sit amet',
|
||||
'lorem ipsum. stop copying here. lorem ipsum',
|
||||
];
|
||||
const copiedText = instance.getCopiedText(textBlocks, 18, 30);
|
||||
|
||||
expect(copiedText).toBe('start copying here\nlorem ipsum doler sit amet\nlorem ipsum. stop copying here');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import _ from 'lodash';
|
||||
import React, { Context } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
// @ts-ignore
|
||||
import { Change, Value } from 'slate';
|
||||
import { Change, Value, Block } from 'slate';
|
||||
// @ts-ignore
|
||||
import { Editor } from 'slate-react';
|
||||
// @ts-ignore
|
||||
@@ -476,10 +476,47 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
|
||||
);
|
||||
};
|
||||
|
||||
handlePaste = (event: ClipboardEvent, change: Editor) => {
|
||||
getCopiedText(textBlocks: string[], startOffset: number, endOffset: number) {
|
||||
if (!textBlocks.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const excludingLastLineLength = textBlocks.slice(0, -1).join('').length + textBlocks.length - 1;
|
||||
return textBlocks.join('\n').slice(startOffset, excludingLastLineLength + endOffset);
|
||||
}
|
||||
|
||||
handleCopy = (event: ClipboardEvent, change: Change) => {
|
||||
event.preventDefault();
|
||||
|
||||
const { document, selection, startOffset, endOffset } = change.value;
|
||||
const selectedBlocks = document.getBlocksAtRangeAsArray(selection).map((block: Block) => block.text);
|
||||
|
||||
const copiedText = this.getCopiedText(selectedBlocks, startOffset, endOffset);
|
||||
if (copiedText) {
|
||||
event.clipboardData.setData('Text', copiedText);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
handlePaste = (event: ClipboardEvent, change: Change) => {
|
||||
event.preventDefault();
|
||||
const pastedValue = event.clipboardData.getData('Text');
|
||||
const newValue = change.value.change().insertText(pastedValue);
|
||||
this.onChange(newValue);
|
||||
const lines = pastedValue.split('\n');
|
||||
|
||||
if (lines.length) {
|
||||
change.insertText(lines[0]);
|
||||
for (const line of lines.slice(1)) {
|
||||
change.splitBlock().insertText(line);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
handleCut = (event: ClipboardEvent, change: Change) => {
|
||||
this.handleCopy(event, change);
|
||||
change.deleteAtRange(change.value.selection);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user