Oh wow, I completely missed that. Of course *navigator* is really *window.navigator*. JavaScript sample code almost always references *navigator*, not *window.navigator*, and I rarely think of that detail. Even after staring at that code for hours looking for something I might have missed, that never occurred to me. Thanks, Thomas; that's exactly what I was missing. With that simple change, this now works.
On Wednesday, October 16, 2019 at 5:44:05 AM UTC-7, Thomas Broyer wrote: > > Have you tried with $wnd.navigator.clipboard? > > On Tuesday, October 15, 2019 at 10:40:04 PM UTC+2, Jim Douglas wrote: >> >> Ok, there are a few moving parts to this. Keeping it as short as >> possible, this is the new Clipboard API: >> >> https://developer.mozilla.org/en-US/docs/Web/API/Clipboard >> >> Support is extremely limited at the moment, but for now I'd be happy to >> get something working in Chrome: >> >> https://caniuse.com/#feat=mdn-api_clipboard >> >> Here's Google's live sample page: >> >> https://googlechrome.github.io/samples/async-clipboard/index.html >> >> 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: >> >> >> https://stackoverflow.com/questions/56306153/domexception-on-calling-navigator-clipboard-readtext >> >> 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: >> >> http://www.gwtproject.org/doc/latest/tutorial/create.html >> >> 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? >> > -- You received this message because you are subscribed to the Google Groups "GWT Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/17cfe4e3-6add-4396-a7e1-78f7c2b86b0e%40googlegroups.com.
