Hi Dave,
Please dig into *getLocalClipboard()* function in guacamole-common-js API,
once data is copied to *clipboardContent *it broadcast to *guacClipboard *i.e.
Guacamole menu.
*windows.clipboard* events only work in IE not in any other browsers.
In Google Chrome we can use paste event to get clipboard access.
document.addEventListener('copy', function (ev) {
> var selection = window.getSelection().toString();
> // Transform the selection in any way we want.
> // In this example we will escape HTML code.
>
> // Place the transformed text in the clipboard.
> ev.clipboardData.setData('text/plain', selection);
> //ev.clipboardData.setData('text/plain', 'some text here, ' + new
> Date);
> ev.preventDefault();
> alert('Text copied to system clipboard');
> });
> document.addEventListener('paste', function (e) {
> e.preventDefault();
> // IE
> if (window.clipboardData) {
> data = window.clipboardData.getData('Text');
> // Standard-compliant browsers
> } else {
> data = e.clipboardData.getData('text/plain');
> }
> var focused = document.activeElement;
> focused.value = data;
> });
I am not sure how to implement it in Chrome and Firefox but the following
code works in all the browsers without any API or extension. Please dig
into that.
var q = new function() {
function a(a, b) {
var c = q.parseClipData(b);
if (!(n.copyTextOnly && "text/plain" != c.type ||
q.processFileGroup(c)))
if (t.isEdge && "text/plain" != c.type) k.resetCSS(),
k.setValue(c.value), k.select(),
setTimeout(function() {
k.setValue("");
Q && Q.setValue("");
k.restoreCSS();
q.processImgCopy(c.value)
}, 555);
else {
a.clipboardData.setData(c.type, c.value);
if ("text/plain" != c.type) {
var d = hi5.browser.html2text(c.value);
d && a.clipboardData.setData("text/plain", d);
q.processImgCopy(c.value)
}
a.preventDefault()
}
}
function b() {
q && (q.copyContent &&
(q.copyToClipboard(q.copyContent.type, q.copyContent.value), q.copyContent
= null), q.waitingCopyContent = !1)
}
var d = 0;
this.hasCopyCmd = document.queryCommandSupported("copy");
this.hasPasteCmd =
document.queryCommandSupported("paste");
this.pasteEventFired = !1;
this.release = function() {
q.clipData = null
};
this.clipData = null;
this.paste = function(a, b) {
var c = new E,
d = 0,
f = null,
e = window.clipboardData || b.clipboardData,
g = window.clipboardData ? e.getData("Text") :
e.getData("text/plain"),
h = "",
k = "",
h = 0;
e.types && (k = e.getData("text/html"));
k && !g && (g = hi5.browser.html2text(k));
g && c.setData("text/plain", g);
if (n.pasteTextOnly) b.preventDefault(), a(c);
else {
var l = e.items;
if (l)
for (d = 0, h = l.length; d < h; d++) {
if ("image/png" ==
l[d].type) {
f = l[d].getAsFile();
break
}
} else if (e.files)
for (l = e.files, d = 0, h = l.length; d < h;
d++)
if (-1 != l[d].type.indexOf("image/png")) {
f = l[d];
break
}
if (f) d = new FileReader, b.preventDefault(),
d.onloadend = function(b) {
b.target.readyState == FileReader.DONE && (b =
hi5.Base64.enc(new Uint8Array(b.target.result)), c.setData("image/png", b),
a(c))
}, d.readAsArrayBuffer(f);
else if (g) {
if (e.types) {
f = e.types.indexOf ? -1 !=
e.types.indexOf("text/rtf") : e.types.contains("text/rtf");
if (h = e.getData("text/rtf")) 0 ==
h.charCodeAt(h.length -
1) && (h = h.substring(0, h.length - 1)),
c.setData("text/richtext", h);
k && (d = k.lastIndexOf("</html>"), d + 7 <
k.length && (k = k.substring(0, d + 7)), c.setData("text/html", k));
if (!hi5.browser.isEdge && (!f || h || k)) {
b.preventDefault();
a(c);
return
}
}
if ("TEXTAREA" == b.target.nodeName &&
document.queryCommandSupported("paste")) b.preventDefault(), c =
q.getClipContent(c), a(c);
else {
H && (H.disableTextInput = !0);
Q && (Q.disableTextInput = !0);
b.target.innerHTML = "";
var t = b.target.style.opacity;
b.target.style.opacity = 0;
setTimeout(function() {
var d =
b.target.innerHTML;
d && d != g && (c.setData("text/html",
"<body>" + d + "</body>"), H ? H.init() : b.target.innerHTML = "");
a(c);
b.target.style.opacity = t;
H && (H.disableTextInput = !1);
Q && (Q.disableTextInput = !1)
}, 300)
}
} else b.preventDefault(), a(c)
}
};
this.onCopy = function(c) {
if (c.target == k.element) {
M && X || cancelDefault(c);
if (!za) {
l(!0, 29);
var b = "copy" == c.type ? 67 : 88,
e = "copy" == c.type ? 46 : 45;
ca(!0, b, e);
ca(!1, b, e);
l(!1, 29)
}
if (Jb && (b = Date.now(), e = b - d, d = b, 500 < e))
return;
X && !qb && (gb = r.getClipData(c.type), a(c, gb),
q.clipData = null,
Y = !0, svGlobal.logger.info("clip synced: true"))
}
};
this.onPaste = function(a) {
if (a.target == k.element) {
Pa && Pa.cancelCtrlV();
if (!M || !X) return cancelDefault(a);
if (!g.alwaysPaste && Y) {
var c = !0;
g.onclipdata && (c = !g.onclipdata(q.clipData, !0));
c && setTimeout(Ra, 500);
svGlobal.logger.info("Ctrl+V only");
return cancelDefault(a)
}
Y = !0;
q.paste(Yb, a);
return !0
}
};
this.parseClipData = function(a) {
var c = a.indexOf(";"),
b = a.substring(0, c);
a = a.substring(c + 1);
return {
type: b,
value: a
}
};
this.getClipContent = function(a) {
if (!document.queryCommandSupported("paste")) return a;
var c = Ya(n.pasteTextOnly ? "textarea" : "div");
c.focus();
try {
if (document.queryCommandEnabled("paste") &&
document.execCommand("paste")) return a || (a = new E), n.pasteTextOnly ||
a.setData("text/html", "<body>" + c.innerHTML + "</body>"), -1 ==
a.types.indexOf("text/plain") && a.setData("text/plain", n.pasteTextOnly ?
c.value : c.innerText || c.innerHTML.replace(/<br>/gi,
"\n").replace(/ /gi, " ").replace(/&/gi, "&").replace(/"/gi,
'"').replace(/</gi, "<").replace(/>/gi, ">")), a
} finally {
g.focused = !0, c.parentNode.removeChild(c),
k && k.focus()
}
return a
};
this.accessClip = function(a) {
document.queryCommandSupported("paste") || a(null);
var c = Ya(n.pasteTextOnly ? "textarea" : "div");
c.focus();
c.addEventListener("paste", function(b) {
b.stopPropagation();
q.pasteEventFired = !0;
q.paste(function(b) {
g.focused = !0;
c.parentNode && c.parentNode.removeChild(c);
k && k.focus();
a(b)
}, b)
}, !1);
q.pasteEventFired = !1;
document.queryCommandEnabled("paste") &&
document.execCommand("paste") && q.pasteEventFired || setTimeout(function()
{
Y = !0;
q.pasteEventFired || a(null);
g.focused = !0;
c.parentNode && c.parentNode.removeChild(c);
k && k.focus()
}, 55)
};
this.getContent = function() {
var a = q.getClipContent();
k && k.element.removeEventListener("click", q.getContent,
!1);
return a && !a.equals(q.clipData) ? (q.clipData = a,
r.send("880text/plain,text/html\t0"), !0) : !1
};
this.startPasteCmd = function() {
k && document.queryCommandSupported("paste") &&
k.element.addEventListener("click", q.getContent)
};
this.waitingCopyContent = !1;
this.copyContent = null;
this.waitForCopyContent = function() {
q.waitingCopyContent = !0;
setTimeout(b,
700)
};
this.prePaste = function() {
Y || !document.queryCommandEnabled("paste") &&
!window.clipboardData || q.accessClip(function(a) {
if (a) {
var c = 0 === a.types.length ||
a.equals(q.clipData),
b = c ? "" : a.types.join(",");
c || (-1 != b.indexOf("text/html") && -1 ==
b.indexOf("text/richtext") && (b += ",text/richtext"), c = (c =
a.getData("text/plain")) ? c.hashCode() : 0, r.send("880" + b + "\t" + c),
q.clipData = a, Y = !0)
}
})
};
this.copyToClipboard = function(a, b) {
var c = "text/plain" == a ? "textarea" : "div",
d = Ya(c, !1),
f = !1,
e = 0 < b.indexOf("data-sv-img");
if ("div" ==
c)
if (d.innerHTML = b, d.focus(), e &&
document.body.createControlRange) {
var h = document.body.createControlRange();
h.add(d.childNodes[0]);
e = !1
} else t.selectEditable(d);
else d.value = b, d.focus(), d.select();
try {
f = h ? h.execCommand("Copy") :
document.execCommand("copy", !1, null)
} catch (y) {} finally {
g.focused = !0, d.parentNode.removeChild(d), k &&
k.focus()
}
Y = !0;
if (!f && g.beforeCopyDialog && g.beforeCopyDialog(b,
__svi18n.info.imgCopyDownload, a)) return !0;
c = e && q.processImgCopy(b);
f || c || g.showMessage({
title: __svi18n.info.userCopy,
msg: b,
timeout: 9999,
select: !0,
format: a
});
return f
};
this.processFileGroup = function(a) {
if ("application/x-filegroup" == a.type) {
a = a.value.split("\r\n");
var b = "",
c = 0;
a.forEach(function(a) {
a = a.split("\t");
1 < a.length && (b && (b += ","), b += a[0], c +=
parseInt(a[1], 10))
});
28 < b.length && (b = b.substring(0, 28) + "...");
b = b + "<br>Total: " + hi5.tool.bytesToSize(c) + "
Qty:" + a.length;
g.showMessage({
title: __svi18n.info.download,
msg: b,
timeout: 9E3,
cbYes: function() {
this.destroy();
I.download()
},
cbNo: function() {
this.destroy()
}
});
return !0
}
return !1
};
this.processImgCopy = function(a) {
return 0 < a.indexOf("data-sv-img") ? (g.showMessage({
title: __svi18n.info.imgCopyDownload,
msg: a,
timeout: 9999
}), !0) : !1
}
},
Please do let me know if it helps. For discussion or any queries please
let me know. I am also working it to work on all the browsers.
Regards,
Amarjeet Singh
On Sun, Sep 3, 2017 at 10:05 AM, davids4us <[email protected]> wrote:
> Hi,
>
> First of all, I want to say Guacamole is great and I appropriate the work
> and efforts you invest in it.
>
> I am implementing a Guacamole client using guacamole-common-js API, and I
> would like to add clipboard support. I understood from the official
> documentation that clipboard is currently supported only by the web
> application and not by the API.
>
> Can you please guide me how to implement it myself?
> If you can point me to some code that does it already it would be great.
>
> Thanks,
> Dave
>
>
>
>
> --
> Sent from: http://apache-guacamole-incubating-users.2363388.n4.nabble.com/
>