]> git.proxmox.com Git - mirror_xterm.js.git/blame - src/handlers/Clipboard.js
Merge pull request #380 from Tyriar/378_handle_keypress_scroll
[mirror_xterm.js.git] / src / handlers / Clipboard.js
CommitLineData
42a1e4ef
PK
1/**
2 * xterm.js: xterm, in the browser
3 * Copyright (c) 2016, SourceLair Private Company <www.sourcelair.com> (MIT License)
4 */
5
a224acb5
PK
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
42a1e4ef
PK
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}
42a1e4ef
PK
18 */
19function 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.
a224acb5 36 * @param {ClipboardEvent} ev The original copy event to be handled
42a1e4ef 37 */
5808de64 38function copyHandler(ev, term) {
42a1e4ef
PK
39 var copiedText = window.getSelection().toString(),
40 text = prepareTextForClipboard(copiedText);
41
5808de64 42 if (term.browser.isMSIE) {
43 window.clipboardData.setData('Text', text);
44 } else {
45 ev.clipboardData.setData('text/plain', text);
46 }
47
42a1e4ef
PK
48 ev.preventDefault(); // Prevent or the original text will be copied.
49}
50
51/**
a224acb5
PK
52 * Redirect the clipboard's data to the terminal's input handler.
53 * @param {ClipboardEvent} ev The original paste event to be handled
54 * @param {Terminal} term The terminal on which to apply the handled paste event
42a1e4ef
PK
55 */
56function pasteHandler(ev, term) {
57 ev.stopPropagation();
77ca1549 58
59 var dispatchPaste = function(text) {
42a1e4ef
PK
60 term.handler(text);
61 term.textarea.value = '';
62 return term.cancel(ev);
77ca1549 63 };
64
5808de64 65 if (term.browser.isMSIE) {
77ca1549 66 if (window.clipboardData) {
67 var text = window.clipboardData.getData('Text');
68 dispatchPaste(text);
69 }
70 } else {
71 if (ev.clipboardData) {
72 var text = ev.clipboardData.getData('text/plain');
73 dispatchPaste(text);
74 }
42a1e4ef
PK
75 }
76}
77
a224acb5
PK
78/**
79 * Bind to right-click event and allow right-click copy and paste.
80 *
81 * **Logic**
82 * If text is selected and right-click happens on selected text, then
83 * do nothing to allow seamless copying.
84 * If no text is selected or right-click is outside of the selection
85 * area, then bring the terminal's input below the cursor, in order to
86 * trigger the event on the textarea and allow-right click paste, without
87 * caring about disappearing selection.
88 * @param {ClipboardEvent} ev The original paste event to be handled
89 * @param {Terminal} term The terminal on which to apply the handled paste event
90 */
91function rightClickHandler(ev, term) {
42a1e4ef 92 var s = document.getSelection(),
35637797 93 selectedText = prepareTextForClipboard(s.toString()),
00dcb4f6 94 clickIsOnSelection = false;
42a1e4ef 95
00dcb4f6
PK
96 if (s.rangeCount) {
97 var r = s.getRangeAt(0),
98 cr = r.getClientRects(),
99 x = ev.clientX,
100 y = ev.clientY,
101 i, rect;
42a1e4ef 102
00dcb4f6
PK
103 for (i=0; i<cr.length; i++) {
104 rect = cr[i];
105 clickIsOnSelection = (
106 (x > rect.left) && (x < rect.right) &&
107 (y > rect.top) && (y < rect.bottom)
108 );
35637797
PK
109
110 if (clickIsOnSelection) {
00dcb4f6
PK
111 break;
112 }
42a1e4ef 113 }
35637797
PK
114 // If we clicked on selection and selection is not a single space,
115 // then mark the right click as copy-only. We check for the single
116 // space selection, as this can happen when clicking on an &nbsp;
117 // and there is not much pointing in copying a single space.
118 if (selectedText.match(/^\s$/) || !selectedText.length) {
119 clickIsOnSelection = false;
120 }
42a1e4ef
PK
121 }
122
123 // Bring textarea at the cursor position
124 if (!clickIsOnSelection) {
125 term.textarea.style.position = 'fixed';
35637797
PK
126 term.textarea.style.width = '20px';
127 term.textarea.style.height = '20px';
128 term.textarea.style.left = (x - 10) + 'px';
129 term.textarea.style.top = (y - 10) + 'px';
42a1e4ef
PK
130 term.textarea.style.zIndex = 1000;
131 term.textarea.focus();
132
133 // Reset the terminal textarea's styling
134 setTimeout(function () {
135 term.textarea.style.position = null;
136 term.textarea.style.width = null;
137 term.textarea.style.height = null;
138 term.textarea.style.left = null;
139 term.textarea.style.top = null;
140 term.textarea.style.zIndex = null;
35637797 141 }, 4);
42a1e4ef
PK
142 }
143}
144
145export {
146 prepareTextForClipboard, copyHandler, pasteHandler, rightClickHandler
147};