mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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
This commit is contained in:
parent
a147aedb10
commit
d6fb48c0ff
@ -1,6 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
|
|
||||||
import { QueryField } from './QueryField';
|
import { QueryField } from './QueryField';
|
||||||
|
|
||||||
describe('<QueryField />', () => {
|
describe('<QueryField />', () => {
|
||||||
@ -28,4 +27,35 @@ describe('<QueryField />', () => {
|
|||||||
expect(handleEnterAndTabKeySpy).toBeCalled();
|
expect(handleEnterAndTabKeySpy).toBeCalled();
|
||||||
expect(instance.executeOnChangeAndRunQueries).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');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -620,15 +620,30 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleCopy = (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();
|
event.preventDefault();
|
||||||
const selectedBlocks = change.value.document.getBlocksAtRange(change.value.selection);
|
|
||||||
event.clipboardData.setData('Text', selectedBlocks.map((block: Block) => block.text).join('\n'));
|
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;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
handlePaste = (event: ClipboardEvent, change: Editor) => {
|
handlePaste = (event: ClipboardEvent, change: Change) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const pastedValue = event.clipboardData.getData('Text');
|
const pastedValue = event.clipboardData.getData('Text');
|
||||||
const lines = pastedValue.split('\n');
|
const lines = pastedValue.split('\n');
|
||||||
@ -643,7 +658,7 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
handleCut = (event: ClipboardEvent, change: Editor) => {
|
handleCut = (event: ClipboardEvent, change: Change) => {
|
||||||
this.handleCopy(event, change);
|
this.handleCopy(event, change);
|
||||||
change.deleteAtRange(change.value.selection);
|
change.deleteAtRange(change.value.selection);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user