Ok, there are a few moving parts to this. Keeping it as short as possible, this is the new Clipboard API:
Support is extremely limited at the moment, but for now I'd be happy to get something working in Chrome:
Here's Google's live sample page:
For obvious reasons, there's a lot of paranoid security around JavaScript access to the clipboard. This is the specific detail I'm running into:
These APIs throw a security exception if document.hasFocus() is false. And I'm not seeing any way to honour that rule in a GWT app. In my production app, and in a tiny standalone GWT app I just generated for testing purposes, document.hasFocus() is always false ($doc.hasFocus() is true).
For testing purposes, I generated the GWT StockWatcher demo app:
Then I added some UI hooks for clipboard testing elements in StockWatcher.html:
<h1>Web Application Starter Project</h1>
<table align="center">
<tr>
<td colspan="2" style="font-weight:bold;">Please enter your name:</td>
</tr>
<tr>
<td id="nameFieldContainer"></td>
<td id="sendButtonContainer"></td>
</tr>
<tr>
<td colspan="2" style="color:red;" id="errorLabelContainer"></td>
</tr>
<tr>
<td id="readTextField"></td>
<td id="readTextButton"></td>
</tr>
<tr>
<td id="writeTextField"></td>
<td id="writeTextButton"></td>
</tr>
</table>
And minimal testing UI in StockWatcher.java onModuleLoad:
TextBox readText = new TextBox();
readText.setText("readText");
Button readTextButton = new Button("readText");
TextBox writeText = new TextBox();
writeText.setText("writeText");
Button writeTextButton = new Button("writeText");
RootPanel.get("readTextField").add(readText);
RootPanel.get("readTextButton").add(readTextButton);
RootPanel.get("writeTextField").add(writeText);
RootPanel.get("writeTextButton").add(writeTextButton);
readTextButton.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
readText();
}
});
writeTextButton.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
writeText(writeText.getText());
}
});
And corresponding JSNI functions to attempt to invoke the Clipboard API:
public native void readText()
/*-{
try
{
if (navigator.clipboard)
{
console.log('navigator.clipboard.readText()');
console.log('document.hasFocus()='+document.hasFocus());
console.log('$doc.hasFocus()='+$doc.hasFocus());
var promise = navigator.clipboard.readText();
var resolve = function(text) {
console.log(text);
};
var reject = function(reason) {
console.log('navigator.clipboard.readText failed: '+reason);
};
promise["catch"](reject);
promise.then(resolve,reject)["catch"](reject);
}
else
{
console.log('This browser does not support navigator.clipboard.');
}
}
catch (e)
{
console.error(e,e.stack);
}
}-*/;
public native void writeText(String p_text)
/*-{
try
{
var _this = this;
if (navigator.clipboard)
{
console.log('navigator.clipboard.writeText()');
console.log('document.hasFocus()='+document.hasFocus());
console.log('$doc.hasFocus()='+$doc.hasFocus());
var promise = navigator.clipboard.writeText(p_text);
var resolve = function(text) {
console.log('navigator.clipboard.writeText '+text);
};
var reject = function(reason) {
console.log('navigator.clipboard.writeText failed: '+reason);
};
promise["catch"](reject);
promise.then(resolve,reject)["catch"](reject);
}
else
{
console.log('This browser does not support navigator.clipboard.');
}
}
catch (e)
{
console.error(e,e.stack);
}
}-*/;
And I'm stuck on the same security error noted in that StackOverflow question, but with no obvious way to satisfy that requirement:
navigator.clipboard.readText()
document.hasFocus()=false
$doc.hasFocus()=true
navigator.clipboard.readText failed: NotAllowedError: Document is not focused.
navigator.clipboard.writeText()
document.hasFocus()=false
$doc.hasFocus()=true
navigator.clipboard.writeText failed: NotAllowedError: Document is not focused.
Is there any way to make this work in GWT?