Skip to content

Commit 6d67e6b

Browse files
committed
fix: clipboard edit menu>paste not working in tauri
1 parent f859c25 commit 6d67e6b

File tree

3 files changed

+95
-24
lines changed

3 files changed

+95
-24
lines changed

src/editor/EditorCommandHandlers.js

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
*
2020
*/
2121

22+
/*global Phoenix*/
23+
2224
/**
2325
* Text-editing commands that apply to whichever Editor is currently focused
2426
*/
@@ -1185,24 +1187,34 @@ define(function (require, exports, module) {
11851187
function _execCommandCopy() {
11861188
_execCommand("copy");
11871189
}
1190+
1191+
function _applyPaste(text) {
1192+
var editor = EditorManager.getFocusedEditor();
1193+
if(editor){
1194+
var doc = editor._codeMirror.getDoc();
1195+
var selection = doc.getSelection();
1196+
var cursor = doc.getCursor();
1197+
if(selection){
1198+
doc.replaceSelection(text);
1199+
} else {
1200+
doc.replaceRange(text, cursor);
1201+
}
1202+
}
1203+
}
1204+
11881205
function _execCommandPaste() {
1189-
if(window.navigator && window.navigator.clipboard){
1190-
window.navigator.clipboard.readText().then(function (text) {
1191-
var editor = EditorManager.getFocusedEditor();
1192-
if(editor){
1193-
var doc = editor._codeMirror.getDoc();
1194-
var selection = doc.getSelection();
1195-
var cursor = doc.getCursor();
1196-
if(selection){
1197-
doc.replaceSelection(text);
1198-
} else {
1199-
doc.replaceRange(text, cursor);
1200-
}
1201-
}
1206+
const result = new $.Deferred();
1207+
Phoenix.app.clipboardReadText()
1208+
.then(_applyPaste)
1209+
.catch(err =>{
1210+
console.error(err);
1211+
_execCommand("paste");
1212+
})
1213+
.finally(()=>{
1214+
// always resolve as we don't know if the _execCommand("paste") did its work or not.
1215+
result.resolve();
12021216
});
1203-
} else {
1204-
_execCommand("paste");
1205-
}
1217+
return result.promise();
12061218
}
12071219

12081220
// Register commands

src/phoenix/shell.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,26 @@ Phoenix.app = {
6363
}
6464
window.__TAURI__.window.appWindow.close();
6565
},
66+
clipboardReadText: function () {
67+
if(Phoenix.browser.isTauri){
68+
return window.__TAURI__.clipboard.readText();
69+
} else if(window.navigator && window.navigator.clipboard){
70+
return window.navigator.clipboard.readText();
71+
}
72+
return Promise.reject(new Error("clipboardReadText: Unable to access clipboard text."));
73+
},
74+
copyToClipboard: function (textToCopy) {
75+
if(Phoenix.browser.isTauri){
76+
return window.__TAURI__.clipboard.writeText(textToCopy);
77+
}
78+
const textArea = document.createElement("textarea");
79+
textArea.value = textToCopy;
80+
document.body.appendChild(textArea);
81+
textArea.select();
82+
document.execCommand("copy");
83+
document.body.removeChild(textArea);
84+
return Promise.resolve();
85+
},
6686
isFullscreen: function () {
6787
if(!Phoenix.browser.isTauri) {
6888
// use browser full screen api in browsers.
@@ -175,14 +195,6 @@ Phoenix.app = {
175195
nativeWindow.isTauriWindow = false;
176196
return nativeWindow;
177197
},
178-
copyToClipboard: function (textToCopy) {
179-
const textArea = document.createElement("textarea");
180-
textArea.value = textToCopy;
181-
document.body.appendChild(textArea);
182-
textArea.select();
183-
document.execCommand("copy");
184-
document.body.removeChild(textArea);
185-
},
186198
getApplicationSupportDirectory: Phoenix.VFS.getAppSupportDir,
187199
getExtensionsDirectory: Phoenix.VFS.getExtensionDir,
188200
getUserDocumentsDirectory: Phoenix.VFS.getUserDocumentsDirectory,

test/spec/EditorCommandHandlers-integ-test.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,53 @@ define(function (require, exports, module) {
210210
});
211211
});
212212

213+
if(window.Phoenix.browser.isTauri) {
214+
// unfortunately, browsers don't allow unattended clip board access as its a secure context. Clipboard API
215+
// will usually popup a clipboard access popup which the user have to click agree manually. So
216+
// we do this test only in tauri.
217+
describe("Editor copy paste Commands Test", function () {
218+
let savedClipboardText = '';
219+
beforeAll(async function () {
220+
try{
221+
// we don't want to nuke the users clipboard text just for running the test runner.
222+
// So save and restore clipboard.
223+
savedClipboardText = await testWindow.Phoenix.app.clipboardReadText();
224+
} catch (e) {
225+
//ignore this error.
226+
console.error("Could not read clipboard text", e);
227+
}
228+
});
229+
230+
afterAll(async function () {
231+
try{
232+
// we don't want to nuke the users clipboard text just for running the test runner.
233+
// So save and restore clipboard.
234+
await testWindow.Phoenix.app.copyToClipboard(savedClipboardText || '');
235+
} catch (e) {
236+
//ignore this error.
237+
console.error("Could not read clipboard text", e);
238+
}
239+
});
240+
241+
it("should copy and paste without selection", async function () {
242+
let promise;
243+
promise = CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: testPath + "/test.js"});
244+
await awaitsForDone(promise, "Open into working set");
245+
246+
myEditor = EditorManager.getCurrentFullEditor();
247+
myEditor.setSelection({line: 5, ch: 8}, {line: 5, ch: 10});
248+
249+
const textToCopy = "#Phcode_Copy_test";
250+
await testWindow.Phoenix.app.copyToClipboard(textToCopy);
251+
252+
promise = CommandManager.execute(Commands.EDIT_PASTE);
253+
await awaitsForDone(promise, "pasted");
254+
255+
myEditor.setSelection({line: 5, ch: 8}, {line: 5, ch: 8 + textToCopy.length});
256+
expect(myEditor.getSelectedText()).toEql(textToCopy);
257+
});
258+
});
259+
}
213260

214261
describe("Open Line Above and Below - inline editor", function () {
215262

0 commit comments

Comments
 (0)