From 2012c8c91d17b1b2cf162ddd74f03021af99424f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 7 Jun 2017 13:42:08 -0700 Subject: [PATCH] Move prepareTextForClipboard logic into SelectionManager --- src/SelectionManager.ts | 11 ++++++++++- src/handlers/Clipboard.test.ts | 9 --------- src/handlers/Clipboard.ts | 31 +++++-------------------------- src/xterm.js | 5 ++--- 4 files changed, 17 insertions(+), 39 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 02eebb1d8..22eac8a45 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -42,6 +42,9 @@ const CLEAR_MOUSE_DISTANCE = 10; const LINE_DATA_CHAR_INDEX = 1; const LINE_DATA_WIDTH_INDEX = 2; +const NON_BREAKING_SPACE_CHAR = String.fromCharCode(160); +const ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g'); + export class SelectionManager extends EventEmitter { protected _model: SelectionModel; @@ -177,7 +180,13 @@ export class SelectionManager extends EventEmitter { result.push(this._translateBufferLineToString(this._buffer.get(end[1]), true, 0, end[0])); } - return result.join('\n'); + // Format string by replacing non-breaking space chars with regular spaces + // and joining the array into a multi-line string. + const formattedResult = result.map(line => { + return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' '); + }).join('\n'); + + return formattedResult; } /** diff --git a/src/handlers/Clipboard.test.ts b/src/handlers/Clipboard.test.ts index 59ac76179..187d3a891 100644 --- a/src/handlers/Clipboard.test.ts +++ b/src/handlers/Clipboard.test.ts @@ -2,15 +2,6 @@ import { assert } from 'chai'; import * as Terminal from '../xterm'; import * as Clipboard from './Clipboard'; - -describe('evaluateCopiedTextProcessing', function () { - it('should replace non-breaking spaces with regular spaces', () => { - const nbsp = String.fromCharCode(160); - const result = Clipboard.prepareTextForClipboard(`foo${nbsp}bar\ntest${nbsp}${nbsp}`); - assert.equal(result, 'foo bar\ntest '); - }); -}); - describe('evaluatePastedTextProcessing', function () { it('should replace carriage return + line feed with line feed on windows', function () { const pastedText = 'foo\r\nbar\r\n', diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index 120d6275d..493f11cdf 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -16,24 +16,6 @@ interface IWindow extends Window { declare var window: IWindow; -const SPACE_CHAR = String.fromCharCode(32); -const NON_BREAKING_SPACE_CHAR = String.fromCharCode(160); -const ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g'); - -/** - * Prepares text copied from terminal selection, to be saved in the clipboard by: - * 1. stripping all trailing white spaces - * 2. converting all non-breaking spaces to regular spaces - * @param {string} text The copied text that needs processing for storing in clipboard - * @returns {string} - */ -export function prepareTextForClipboard(text: string): string { - // TODO: Pass an unjoined string array into this function so not splitting is needed - return text.split('\n').map(line => { - return line.replace(ALL_NON_BREAKING_SPACE_REGEX, SPACE_CHAR); - }).join('\n'); -} - /** * Prepares text to be pasted into the terminal by normalizing the line endings * @param text The pasted text that needs processing before inserting into the terminal @@ -50,17 +32,14 @@ export function prepareTextForTerminal(text: string, isMSWindows: boolean): stri * @param {ClipboardEvent} ev The original copy event to be handled */ export function copyHandler(ev: ClipboardEvent, term: ITerminal, selectionManager: ISelectionManager) { - // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData` - // property that we use below for Internet Explorer. - let text = prepareTextForClipboard(selectionManager.selectionText); - if (term.browser.isMSIE) { - window.clipboardData.setData('Text', text); + window.clipboardData.setData('Text', selectionManager.selectionText); } else { - ev.clipboardData.setData('text/plain', text); + ev.clipboardData.setData('text/plain', selectionManager.selectionText); } - ev.preventDefault(); // Prevent or the original text will be copied. + // Prevent or the original text will be copied. + ev.preventDefault(); } /** @@ -111,7 +90,7 @@ export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, textarea.style.zIndex = '1000'; // Get textarea ready to copy from the context menu - textarea.value = prepareTextForClipboard(selectionManager.selectionText); + textarea.value = selectionManager.selectionText; textarea.focus(); textarea.select(); diff --git a/src/xterm.js b/src/xterm.js index eb44d3bf0..a476fd7eb 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -13,7 +13,7 @@ import { CompositionHelper } from './CompositionHelper'; import { EventEmitter } from './EventEmitter'; import { Viewport } from './Viewport'; -import { rightClickHandler, pasteHandler, copyHandler, prepareTextForClipboard } from './handlers/Clipboard'; +import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard'; import { CircularList } from './utils/CircularList'; import { C0 } from './EscapeSequences'; import { InputHandler } from './InputHandler'; @@ -1385,8 +1385,7 @@ Terminal.prototype.hasSelection = function() { * behavior outside of xterm.js. */ Terminal.prototype.getSelection = function() { - // TODO: Should prepareTextForClipboard logic be moved to SelectionManager? - return prepareTextForClipboard(this.selectionManager.selectionText); + return this.selectionManager.selectionText; } /**