Thursday, December 29, 2022

Re: Is it possible to use the new Clipboard API in a GWT app? It depends on document.hasFocus being true.

As it's doing it asynchronously, you'll need to add a callback to return the string.

Something like this:

---

package mypackage;

public interface Loaded<T> {
    public void data(T data);
}

---

public static native String readText(Loaded<String> clipboardText) /*-{
    try {
        var promise = $wnd.navigator.clipboard.readText();
        var resolve = function(text) {
        console.log(text);// I can print text here but not able to return it as String
        clipboardText.@mypackage.Loaded::data(*)(text);
    }
    catch (e){
      //futher code goes here
    }
}-*/;

---

Note:  I'm just copying your JavaScript, it doesn't look correct to me, I think you also need:

promise.then(resolve);

or something like that.

On Friday, 30 December 2022 at 2:30:14 pm UTC+11 patil.p...@gmail.com wrote:
Yes, it's working but not working with GWT, I think the async function and await keyword is not supported with GWT, was getting a compiler error, I tried below code which worked, but not able to return as String, can print the copied text with console.log(text). As of now I didn't get any solution, I tried to search on the internet but had no luck.

is there any library or anything to be included/imported to get async/await support with GWT?
public static native String readText()/*-{     try       {        var promise = $wnd.navigator.clipboard.readText();        var resolve = function(text){        console.log(text);// I can print text here but not able to return it as String        }        catch (e){        //futher code goes here        }       }-*/;

On Fri, Dec 30, 2022 at 8:04 AM Craig Mitchell <ma...@craig-mitchell.com> wrote:
Apologies.  That stackoverflow example gets blocked due to cross origin.

Just ran a simple test:

<html>
<script>
async function readClipboard () {
  if (!navigator.clipboard) {
    // Clipboard API not available
    return
  }
  try {
    const text = await navigator.clipboard.readText();
    document.querySelector('.clipboard-content').innerText = text;
  } catch (err) {
    console.error('Failed to copy!', err)
  }
}

function updateClipboard() {
  // Here You Can Debug without DomException
  debugger
  const clipboard = document.querySelector('.clipboard-content').innerText;
  document.querySelector('.clipboard-content').innerText = 'Updated => ' + clipboard;
}
</script>

<body>
<button onclick="readClipboard()">Paste</button>
<p class="clipboard-content"></p>
<button onclick="updateClipboard()">Edit</button>
</body>
</html>

and it worked fine (browser popped up a message asking for permission).

On Thursday, 29 December 2022 at 5:02:34 pm UTC+11 Craig Mitchell wrote:
Browsers now need you to get your users to grant permissions in their browsers for this to work.  See "Permissions API" here: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText#security 

An example:  https://stackoverflow.com/a/59954231/418057  When I run the code snippet, and press "paste", it give "NotAllowedError".

On Monday, 26 December 2022 at 5:02:32 pm UTC+11 patil.p...@gmail.com wrote:
Hi Experts,
I am newbie with javascript and GWT, I want my function to return clipboard data,for further use in application upon click of(tool button).
Is there any way to get the text read from clipboard, I am looking something similar @Jim Douglas mentioned, with $wnd.navigator.clipboard.readText() is working but I need the "pasted" text to be returned to my native method call 

public static native String readText(){
try{
   if($wnd.navigator.clipboard){
      var promise= $wnd.navigator.clipboard.readText();
      var resolve =function(text){
      console.log(text);   // i want this text which i can see on console(string)  to be returned , Is it possible and how to achieve it any hack to ge
    }
  }
}
}

Please help, as i got stuck at this point for a while. Thanks.
On Wednesday, 16 October 2019 at 19:53:27 UTC+5:30 Jim Douglas wrote:
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:


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?

--
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 google-web-tool...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/9856ced4-a191-499c-9118-edc72ef6831fn%40googlegroups.com.


--
Thanks and regards,
 Pramod Patil
 Contact +91-8975432800

--
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 google-web-toolkit+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/d0792d02-8185-464b-aa53-89179c2845a7n%40googlegroups.com.

Re: Is it possible to use the new Clipboard API in a GWT app? It depends on document.hasFocus being true.

Yes, it's working but not working with GWT, I think the async function and await keyword is not supported with GWT, was getting a compiler error, I tried below code which worked, but not able to return as String, can print the copied text with console.log(text). As of now I didn't get any solution, I tried to search on the internet but had no luck.

is there any library or anything to be included/imported to get async/await support with GWT?
public static native String readText()/*-{     try       {        var promise = $wnd.navigator.clipboard.readText();        var resolve = function(text){        console.log(text);// I can print text here but not able to return it as String        }        catch (e){        //futher code goes here        }       }-*/;

On Fri, Dec 30, 2022 at 8:04 AM Craig Mitchell <mail@craig-mitchell.com> wrote:
Apologies.  That stackoverflow example gets blocked due to cross origin.

Just ran a simple test:

<html>
<script>
async function readClipboard () {
  if (!navigator.clipboard) {
    // Clipboard API not available
    return
  }
  try {
    const text = await navigator.clipboard.readText();
    document.querySelector('.clipboard-content').innerText = text;
  } catch (err) {
    console.error('Failed to copy!', err)
  }
}

function updateClipboard() {
  // Here You Can Debug without DomException
  debugger
  const clipboard = document.querySelector('.clipboard-content').innerText;
  document.querySelector('.clipboard-content').innerText = 'Updated => ' + clipboard;
}
</script>

<body>
<button onclick="readClipboard()">Paste</button>
<p class="clipboard-content"></p>
<button onclick="updateClipboard()">Edit</button>
</body>
</html>

and it worked fine (browser popped up a message asking for permission).

On Thursday, 29 December 2022 at 5:02:34 pm UTC+11 Craig Mitchell wrote:
Browsers now need you to get your users to grant permissions in their browsers for this to work.  See "Permissions API" here: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText#security 

An example:  https://stackoverflow.com/a/59954231/418057  When I run the code snippet, and press "paste", it give "NotAllowedError".

On Monday, 26 December 2022 at 5:02:32 pm UTC+11 patil.p...@gmail.com wrote:
Hi Experts,
I am newbie with javascript and GWT, I want my function to return clipboard data,for further use in application upon click of(tool button).
Is there any way to get the text read from clipboard, I am looking something similar @Jim Douglas mentioned, with $wnd.navigator.clipboard.readText() is working but I need the "pasted" text to be returned to my native method call 

public static native String readText(){
try{
   if($wnd.navigator.clipboard){
      var promise= $wnd.navigator.clipboard.readText();
      var resolve =function(text){
      console.log(text);   // i want this text which i can see on console(string)  to be returned , Is it possible and how to achieve it any hack to ge
    }
  }
}
}

Please help, as i got stuck at this point for a while. Thanks.
On Wednesday, 16 October 2019 at 19:53:27 UTC+5:30 Jim Douglas wrote:
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:


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?

--
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 google-web-toolkit+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/9856ced4-a191-499c-9118-edc72ef6831fn%40googlegroups.com.


--
Thanks and regards,
 Pramod Patil
 Contact +91-8975432800

--
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 google-web-toolkit+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/CAAXS9-XTSvOEknv1FSNETBmywQuSKdoP8uTQuzR0RA3YG8xzDA%40mail.gmail.com.

Re: Is it possible to use the new Clipboard API in a GWT app? It depends on document.hasFocus being true.

Apologies.  That stackoverflow example gets blocked due to cross origin.

Just ran a simple test:

<html>
<script>
async function readClipboard () {
  if (!navigator.clipboard) {
    // Clipboard API not available
    return
  }
  try {
    const text = await navigator.clipboard.readText();
    document.querySelector('.clipboard-content').innerText = text;
  } catch (err) {
    console.error('Failed to copy!', err)
  }
}

function updateClipboard() {
  // Here You Can Debug without DomException
  debugger
  const clipboard = document.querySelector('.clipboard-content').innerText;
  document.querySelector('.clipboard-content').innerText = 'Updated => ' + clipboard;
}
</script>

<body>
<button onclick="readClipboard()">Paste</button>
<p class="clipboard-content"></p>
<button onclick="updateClipboard()">Edit</button>
</body>
</html>

and it worked fine (browser popped up a message asking for permission).

On Thursday, 29 December 2022 at 5:02:34 pm UTC+11 Craig Mitchell wrote:
Browsers now need you to get your users to grant permissions in their browsers for this to work.  See "Permissions API" here: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText#security 

An example:  https://stackoverflow.com/a/59954231/418057  When I run the code snippet, and press "paste", it give "NotAllowedError".

On Monday, 26 December 2022 at 5:02:32 pm UTC+11 patil.p...@gmail.com wrote:
Hi Experts,
I am newbie with javascript and GWT, I want my function to return clipboard data,for further use in application upon click of(tool button).
Is there any way to get the text read from clipboard, I am looking something similar @Jim Douglas mentioned, with $wnd.navigator.clipboard.readText() is working but I need the "pasted" text to be returned to my native method call 

public static native String readText(){
try{
   if($wnd.navigator.clipboard){
      var promise= $wnd.navigator.clipboard.readText();
      var resolve =function(text){
      console.log(text);   // i want this text which i can see on console(string)  to be returned , Is it possible and how to achieve it any hack to ge
    }
  }
}
}

Please help, as i got stuck at this point for a while. Thanks.
On Wednesday, 16 October 2019 at 19:53:27 UTC+5:30 Jim Douglas wrote:
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:


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?

--
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 google-web-toolkit+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/9856ced4-a191-499c-9118-edc72ef6831fn%40googlegroups.com.