Encoding problems converting string to blob for teams-js' clipboard api

21 views Asked by At

I am currently developing an app for Microsoft Teams using the Teams-Toolkit and @microsoft/teams-js. Because teams apps are embeded as an <iframe> inside teams, I am unable to use the browser's native clipboard API (navigator.clipboard) and I have to use Microsoft's own clipboard API from the teams-js SDK. However this API is rather limited, as it has only one function to write data to the clipboard, which only accepts a blob and supports a limited amount of types.

Therefore I wrote the following code to copy a string to the clipboard:

    await clipboard.write(
        new Blob([title], {type: "text/plain"})
    );

The problem with this approach is that the copied text is wrongly encoded. Copying "Änderungen für die Öffentlichkeit" results in "Ãnderungen für die Ãffentlichkeit".

I tried the following things to fix this issue, none of them worked:

Encoding the text with the TextEncoder:

const data = new TextEncoder().encode(title);
const blob = new Blob([data], {
                  type: "text/plain",
             });
await clipboard.write(blob);

This didn't work.


Specifying the encoding in the blob's type:

const data = new TextEncoder().encode(title);
const blob = new Blob([data], {
                  type: "text/plain;encoding=UTF-8",
             });
await clipboard.write(blob);

Here clipboard.write(...) throws an excepting because the type is not supported.


Today, as a last resort, I tried investigating the results of the text-encoder. For this I used coderstool's unicode-to-text-converter.

What I noticed is that when I log the encoded data from the TextEncoder() as decimal numbers:

const data = new TextEncoder().encode(title);
console.log(data.join(" "));

Example from above in decimal: 195 132 110 100 101 114 117 110 103 101 110 32 102 195 188 114 32 100 105 101 32 195 150 102 102 101 110 116 108 105 99 104 107 101 105 116.

And copied that into the unicode decoder the formatting was wrong, suggesting that the TextEncoder() encoded the string wrong or (more likely) I am misinterpreting the results.

However, when logging the result from the TextEncoder() as hexadecimal (which should still log every byte exactly as if I was logging it as decimal):

const data = new TextEncoder().encode(title);
console.log(Array.from(data).map((b) => `\\x${b.toString(16)}`).join(""));

Example from above in hex: \xc3\x84\x6e\x64\x65\x72\x75\x6e\x67\x65\x6e\x20\x66\xc3\xbc\x72\x20\x64\x69\x65\x20\xc3\x96\x66\x66\x65\x6e\x74\x6c\x69\x63\x68\x6b\x65\x69\x74.

The unicode decoder decoded it correctly.

What am I doing wrong here or what's the problem with my approach?

0

There are 0 answers