Just when you think something’s gonna be easy...
Attempting to download a bunch of old email assets before purging them, I noticed “Edit Code » Download HTML” wasn’t serving up a file.

Checking the F12 Console revealed a fatal JS error:

Turns out whoever wrote the downloadHTML
function at Marketo made the mistake of thinking the browser-standard btoa
method works on any text. Nope!

See, btoa
— despite being mistakenly used, in countless broken scenarios, as if it’s an all-purpose Base64 encoder — only works on Latin-1 input. That is, the 128 ASCII characters plus the first non-ASCII block of 128 symbols & characters, nothing more.
btoa
throws a fatal error on characters outside of this range. And many of the client’s emails use everyday characters that happen to be outside of Latin-1, like the single curly quote/apostrophe ’
and curly double quotes “”
and em dashes —
. (All of which I recommend highly and use on this very blog.)


Obviously, the problem would be exponentially worse in a non-Latin language where every character except certain punctuation is outside the range.
What the code should do (I’ll open a Support Case) is just leave the HTML unencoded:
this.encode = function(data){
return "data:text/html," + encodeURIComponent(data);
}
Meantime, the workaround is just Select All → Copy → Paste from the Edit Code window, more annoying but it does work.