Escaping and UnEscaping Strings?

The following command returns the raw source of an email, as a string:

	set myselection to selection
	source of item 1 of myselection as string
end tell

In the result box, that string is properly escaped. Quotes have \ before them, it looks ready to be used.

HOWEVER when I try to use that string in safari to submit it into a form field (specifically a textarea), the escaping disappears and I get javascript errors.

tell application "Safari"
	set JSCommand to "document.getElementsByName('spam')[0].value = '" & MailSource & "';"
		do JavaScript JSCommand in document 1
end tell

What gets sent to Safari is no longer escaped, and I end up getting javascript errors because the first apostrophe prematurely ends the string and the rest of the string immediately throws an error, as you would expect.

WHO exactly is un-escaping the string? How can I prevent that?

From another post, about a different person have a different problem, but relevant here:

“If a text object contains a \ then the script editor will add a leading backslash when it displays the result, but that doesn’t mean it’s there - it’s only added for display purposes.”

Suggesting that my string isn’t REALLY escaped, it just looks it in the Script Editor result box. So then the question now goes back to the simple question of, how do you quote a string in applescript to be used as a string in javascript via do javascript ?

Dunno whether there is a single, foolproof solution.

So here are two approaches that depend upon the source of the text.

If you get the text externally, eg read it in or get the clipboard, then double quotes require single escaping. Ignore any single quotes.

eg \"white knight\"

If you set it within the script itself, then double quotes require triple escaping:

eg \\\"black knight\\\"

when set within script

use scripting additions

set kr to "king's \\\"knight\\\"" -- source string requiring triple escaping
log "kr: " & kr
set qkr to quote & kr & quote -- source inside double quotes
log "qkr: " & qkr

tell application "Safari"
	set JSCommand to "document.getElementsByTagName('textarea')[0].value = " & qkr & " ;"
	log JSCommand
	do JavaScript JSCommand in document 1
	JSCommand
end tell

when set outside of script

contents of dexpose file; quotes are single escaped

queen’s \"knight\"
use scripting additions

set fid to ((path to desktop as text) & "dexpose") -- path to source file; quotes are single escaped, eg \"word\"
set redd to read file fid as «class utf8» -- 
log redd
set mys to quote & redd & quote -- source inside double quotes
log mys

tell application "Safari"
	set JSCommand to "document.getElementsByTagName('textarea')[0].value = " & mys & " ;"
	do JavaScript JSCommand in document 1
end tell

You can also use the clipboard like so:
Copy this to the clipboard: queen's \"knight\"

use scripting additions

set redd to the clipboard as «class utf8»
log redd
set mys to quote & redd & quote -- source inside double quotes
log mys

tell application "Safari"
	set JSCommand to "document.getElementsByTagName('textarea')[0].value = " & mys & " ;"
	do JavaScript JSCommand in document 1
end tell
1 Like

The problem is, this is going into javascript code, so I do need to escape all single and double quotes. Not just at the start and end of the string. The whooooooole thing. I’m not sure if there are other characters that need to be escaped too.
Also the strings are coming from email source. So in theory someone could email anything to me and i need to be able to get the text and send it into javascript in safari. Unless i’m misreading, your code is just wrapping the string in another set of quotes?

So this is kinda weird. I was poking around more and I didn’t realize, but quoted form of does escape quotes in the string. So I thought that was my solution after all. But it turns out it escapes quotes, but then puts the escape mark in its own single quotes? I don’t understand why it does this, and it of course breaks javascript when I try to use it in a do javascript command.

Original text as seen in the subject of an email:

You did it! You’ve earned a FREE Medium 2-Topping Pizza! :raised_hands: :pizza:

What quoted form of that text returns:

‘You did it! You’\'‘ve earned a FREE Medium 2-Topping Pizza! :raised_hands: :pizza:’

It puts the escape mark itself in single quotes too. Which of course, ends the string and the escape mark just becomes a symbol in the code wherever I try to use this string as an in-code string.

Note that I had to double the escape slash to get it to show up in this forum post but just to clarify, this is what is in the quoted string:


“You” singlequote backslash singlequote singlequote “ve”


I’m not really sure what you mean. The examples I provided have single and double quotes within their text. Those quotes are handled properly when using the do javascript command to insert the text into an html textarea. Did you even try the script?

Every code environment — eg applescript, javascript, shell, unix commands — has special characters. When you start layering these environments, these special characters need to be escaped as they go through the layers. Each layer has its own treatment. So in one form or another all of it is just wrapping a string in another set of quotes. If you look at the log history, you can see how the quoting evolves.

An example of this issue is how I needed two separate forms depending upon how the source text was fed in. That’s because applescript handles some stuff internally and other stuff not at all.

Your scripts are using already escaped symbols. I’m trying to ADD escaping to strings. For example if you wrap the ‘knight’ in single quotes like that, all your script is doing is adding escaped quotes to each end:

set kr to "king's 'knight'" -- source string requiring triple escaping
log "kr: " & kr
set qkr to quote & kr & quote -- source inside double quotes
log "qkr: " & qkr

tell application "Safari"
	set JSCommand to "document.getElementsByTagName('textarea')[0].value = " & qkr & " ;"
	log JSCommand
	do JavaScript JSCommand in document 1
	JSCommand
end tell

"document.getElementsByTagName(‘textarea’)[0].value = \“king’s 'knight'" ;”

I’m trying to ADD escaping

Try concatenation by encapsulating the string using

quote & [your Java commands] & quote

Could you use JSON.parse()

Well this is in native applescript, not jxa. If I’m using jxa, theres all sorts of fairly easy ways I can do it, including just simple string replace calls.

Edit: Wait, how would json.parse() help me with this?

I just tried the pizza string with one of the scripts and it worked fine. The emojis have issues but that is unrelated. However, if you have an email string that contains double quotes, we can test with that.

Please note that the ‘knight’ strings I provided were these below. The first case is for when you provide the string within the script (eg set var to “a”), the second when it’s brought in from outside the script, for example with the read command or using the clipboard. The second one is probably best suited for your case, so you need to insert a backslash before each double quote.

king's \\\"knight\\\"

and

king's \"knight\"

It was not this:

king's 'knight'

You are correct about what ‘quoted form of’ does to single quotes, which is why this doesn’t provide a general solution. @jambomac has the right idea, which is to use the quote constant, which is what I’ve done although I only apply this to the string as the javascript command on its own is fine.

So, the issue at this point, is how to add a backslash before the double quotes within your text. You should be able to do a simple search and replace using delimiters.

Testing

I created an html page with the source code below. It has a ‘textarea’ in it. You can save this as an html file and open it in safari as a test page.

Here is an example script. Create a text file on the desktop containing the string queen's "knight" with the name ‘raw’. The script will place a single backslash before each of the two double quotes and then replace whatever is in the web page’s textarea with the original text. If it works, put your own string in the text file and try again.

This way, you can see exactly what the script does with a generic textarea.

Script

-- contents of example text file
--> queen’s "knight"

-- read text file
set fid to ((path to desktop as text) & "raw")
set redd to read file fid as «class utf8»

-- split text on "
set text item delimiters to quote
set tim to text items of redd

-- rejoin text around \"
set text item delimiters to "\\\""
set mys to tim as text
-- queen’s "knight" becomes "queen’s \"knight\""

-- wrap entire string in quotes
set mys to quote & mys & quote

-- set value of textarea
tell application "Safari"
	activate
	set JSCommand to "document.getElementsByTagName('textarea')[0].value = " & mys & " ;"
	log JSCommand
	do JavaScript JSCommand in document 1
end tell

HTML

<!DOCTYPE html>
<head>
<title>Test for 'textarea'</title>
    <meta charset="utf-8">
	<style>
	h2 {font-size:1.8em; text-align:center; color:#249eb1;}
	h2 {max-width:20em;line-height:1.3em; padding-left:6px;}
	p {max-width:30em; font-size:1.2em; line-height:1.4em;} 
	</style>
</head>
<body>
<h2>Leave a comment:</h2>

<p>textarea below 👇</p>
<textarea rows="8" cols="60" placeholder="Write your comment here
"></textarea>

</body>
</html>