]> git.proxmox.com Git - mirror_xterm.js.git/blob - src/handlers/Clipboard.js
Document new Clipboard module
[mirror_xterm.js.git] / src / handlers / Clipboard.js
1 /**
2 * xterm.js: xterm, in the browser
3 * Copyright (c) 2016, SourceLair Private Company <www.sourcelair.com> (MIT License)
4 */
5
6 /**
7 * Clipboard handler module. This module contains methods for handling all
8 * clipboard-related events appropriately in the terminal.
9 * @module xterm/handlers/Clipboard
10 */
11
12 /**
13 * Prepares text copied from terminal selection, to be saved in the clipboard by:
14 * 1. stripping all trailing white spaces
15 * 2. converting all non-breaking spaces to regular spaces
16 * @param {string} text The copied text that needs processing for storing in clipboard
17 * @returns {string}
18 */
19 function prepareTextForClipboard(text) {
20 var space = String.fromCharCode(32),
21 nonBreakingSpace = String.fromCharCode(160),
22 allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),
23 processedText = text.split('\n').map(function (line) {
24 // Strip all trailing white spaces and convert all non-breaking spaces
25 // to regular spaces.
26 var processedLine = line.replace(/\s+$/g, '').replace(allNonBreakingSpaces, space);
27
28 return processedLine;
29 }).join('\n');
30
31 return processedText;
32 }
33
34 /**
35 * Binds copy functionality to the given terminal.
36 * @param {ClipboardEvent} ev The original copy event to be handled
37 */
38 function copyHandler (ev) {
39 var copiedText = window.getSelection().toString(),
40 text = prepareTextForClipboard(copiedText);
41
42 ev.preventDefault(); // Prevent or the original text will be copied.
43 }
44
45 /**
46 * Redirect the clipboard's data to the terminal's input handler.
47 * @param {ClipboardEvent} ev The original paste event to be handled
48 * @param {Terminal} term The terminal on which to apply the handled paste event
49 */
50 function pasteHandler(ev, term) {
51 ev.stopPropagation();
52 if (ev.clipboardData) {
53 var text = ev.clipboardData.getData('text/plain');
54 term.handler(text);
55 term.textarea.value = '';
56 return term.cancel(ev);
57 }
58 }
59
60 /**
61 * Bind to right-click event and allow right-click copy and paste.
62 *
63 * **Logic**
64 * If text is selected and right-click happens on selected text, then
65 * do nothing to allow seamless copying.
66 * If no text is selected or right-click is outside of the selection
67 * area, then bring the terminal's input below the cursor, in order to
68 * trigger the event on the textarea and allow-right click paste, without
69 * caring about disappearing selection.
70 * @param {ClipboardEvent} ev The original paste event to be handled
71 * @param {Terminal} term The terminal on which to apply the handled paste event
72 */
73 function rightClickHandler(ev, term) {
74 var s = document.getSelection(),
75 sText = prepareTextForClipboard(s.toString()),
76 r = s.getRangeAt(0);
77
78 var x = ev.clientX,
79 y = ev.clientY;
80
81 var cr = r.getClientRects(),
82 clickIsOnSelection = false,
83 i, rect;
84
85 for (i=0; i<cr.length; i++) {
86 rect = cr[i];
87 clickIsOnSelection = (
88 (x > rect.left) && (x < rect.right) &&
89 (y > rect.top) && (y < rect.bottom)
90 );
91 // If we clicked on selection and selection is not a single space,
92 // then mark the right click as copy-only. We check for the single
93 // space selection, as this can happen when clicking on an &nbsp;
94 // and there is not much pointing in copying a single space.
95 // Single space is char
96 if (clickIsOnSelection && (sText !== ' ')) {
97 break;
98 }
99 }
100
101 // Bring textarea at the cursor position
102 if (!clickIsOnSelection) {
103 term.textarea.style.position = 'fixed';
104 term.textarea.style.width = '10px';
105 term.textarea.style.height = '10px';
106 term.textarea.style.left = x + 'px';
107 term.textarea.style.top = y + 'px';
108 term.textarea.style.zIndex = 1000;
109 term.textarea.focus();
110
111 // Reset the terminal textarea's styling
112 setTimeout(function () {
113 term.textarea.style.position = null;
114 term.textarea.style.width = null;
115 term.textarea.style.height = null;
116 term.textarea.style.left = null;
117 term.textarea.style.top = null;
118 term.textarea.style.zIndex = null;
119 }, 1);
120 }
121 }
122
123 export {
124 prepareTextForClipboard, copyHandler, pasteHandler, rightClickHandler
125 };