0

I have an (ASP.Net) application that has the following client-side Javascript, to facilitate copying to clipboard:

var ua = window.navigator.userAgent;
var is_ie = /MSIE|Trident/.test(ua);

if (is_ie) {
    var input = document.getElementById("inputcopy"); // select it

    input.value = text;
    input.select();
    document.execCommand("copy");
    this.focus();
}
else {     
    navigator.clipboard.writeText(text).then(() => {
        writeLog('Copy successful');
        if (showalert == true) alert('Copied to clipboard');
    }).catch(() => {
        writeLog('Copy failed');
        if (showalert == true) alert('Copy to clipboard failed');
    });           
}   

We need to be compatible with all "modern" browsers - Chrome, Firefox and, don't shoot the messenger, IE11. The first two are fine, but the latter ...

As IE doesn't support the navigator.clipboard I've got the if (is_ie) in there, which works fine. However, IE doesn't know about the Promise in the non-IE section, and complains horribly about "Invalid Syntax" at

navigator.clipboard.writeText(text).then(() => {

even though it'll never actually run it.

How can I tell IE to ignore that bit of code, or work around this issue? I've looked at conditionally loading a separate JS file based on browser, but that doesn't look like much fun. Is there a better option?

KenD
  • 5,280
  • 7
  • 48
  • 85
  • 1
    You can try `eval()` to get around this issue. Or if possible, just use a promise polyfill. – Abana Clara Apr 12 '19 at 08:22
  • @AbanaClara — A promise polyfill won't add support for arrow functions. – Quentin Apr 12 '19 at 08:25
  • @Quentin just convert it to normal functions. It's not like the entire block is 100 lines long – Abana Clara Apr 12 '19 at 08:29
  • 1
    @AbanaClara: I'm sure it's not anyone's preferred solution, but `eval()` works beautifully! If you want to add that as an answer I'll mark that as the answer. – KenD Apr 12 '19 at 08:31
  • `eval` does **not** work beautifully, it is slow, it is really hard to debug when things go wrong, and it can do confusing things with scope. – Quentin Apr 12 '19 at 08:32
  • @Quentin: OK agreed - I did say it's not going to be anyone's preferred way of doing things - but this is for 5 lines for code. I certainly don't hope there will be any other IE-only requirements! – KenD Apr 12 '19 at 08:36
  • @KenD — Or you could just not use an arrow function in the first place (it isn't like you are even making use of `this` inside it). – Quentin Apr 12 '19 at 08:36
  • 1
    @Quentin it is just a handful lines of code that doesn't look to be doing some risky stuff. OP isn't going to revolve around `eval()` like it was in the dark ages – Abana Clara Apr 12 '19 at 08:40
  • @AbanaClara — I didn't mention "risky stuff" at all. `eval` is slow, hard to debug, and *much more complicated* than *just using a function expression*. – Quentin Apr 12 '19 at 08:47
  • 1
    @Quentin and I'm not disagreeing with you. But this is just a negligible amount of code. This scenario is a perfectly acceptable compromise, if the polyfill and function expression isn't an option.. – Abana Clara Apr 12 '19 at 08:51
  • @AbanaClara — There is no need for a polyfill. Just the function expression. And there is no reason for a function expression to not be an option. – Quentin Apr 12 '19 at 08:52
  • @Quentin ooh I get it. Since the code won't ever be executed anyway, the polyfill doesn't matter. Didn't think of that. – Abana Clara Apr 12 '19 at 08:54

2 Answers2

1

You can't make a JavaScript parser skip over syntax in parts of a program it isn't going to run (to oversimplify the situation horribly: It still needs to parse that bit of the program to find the } that ends the else block.

Either write your JS to use syntax that is supported by IE (i.e. use a function expression instead of an arrow function) or transpile your JS to a version that IE will support (with a tool like Babel).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

Adding my comment as an answer by OP's suggestion.

You can try eval() to get around this issue. What eval() does is parse a string into an executable code. This will literally make IE ignore this code since it's not gonna execute anyway.

Yes, we don't typically use eval(), but rare scenarios like this are perfect reasons to use it.

Here's some resource about eval: Why is using the JavaScript eval function a bad idea?

Or if possible, just use a promise polyfill.


As @Quentin explained, merely using the function expression should easily fix this without using eval().

Abana Clara
  • 4,602
  • 3
  • 18
  • 31
  • "Or if possible, just use a promise polyfill." — The problem is the arrow function, not the promise. Heck, the promise isn't even being explicitly created by the OP's code (it is created by the `writeText` method, so a Promise polyfill won't do anything at all). – Quentin Apr 12 '19 at 08:52
  • @Quentin Yes, I was doubtful that a promise polyfill is gonna work. But in case you're wrong, what if the `writeText()` method is actually still implicitly creating a promise internally via `new Promise()`? Perhaps – Abana Clara Apr 12 '19 at 08:53
  • I'm not wrong. `writeText` **is** creating a promise internally, but `writeText` doesn't exist in IE, so it isn't trying to create one internally there. – Quentin Apr 12 '19 at 08:54