CL-WHO is always starting with a single quote - javascript

My issue is that CL-WHO begins each expression with a single quotation market when it turns the Lisp S-expressions into html output. This is okay most of the time, but it is an issue since I am linking my file to an external javascript file. I am trying to make this project simple, and since none of the javascript developers on my team know Common Lisp, using parenscript is likely out of the equation. Here is an example of my issue and one of the errors in my program:
:onclick "alertUser('id')"
When a particular element is pressed within the html document, this should trigger a JavaScript function called alertUser, and the id of the tag should be passed to the JavaScript function as an argument. But no matter what I do, CL-WHO will convert that string into single quotation marks, so I end up with an invalid expression. Here is what that code converts to:
onclick='alertUser('id')'>
Everything is a single quotation so 'alertUser(' is passed as the first string which is obviously invalid and I receive a syntax area in my developer tools. I thought that I could solve this problem by using the format function with escape characters. This would equate to:
CL-USER> (format t "\"alertUser('id')\"")
"alertUser('id')"
NIL
CL-USER>
But when I try that with CL-WHO:
:onclick (format nil "\"alertUser('id')\"")
That translates to:
onclick='"alertUser('locos-tacos-order')"'>
Which is also invalid html. As you can see, CL-WHO will start with a single quote no matter what. Next I tried the CL-WHO fmt function:
:onclick (fmt "\"alertUser('locos-tacos-order')\"")
When I use the fmt function it gets rid of my :onclick expression entirely when it is converted to html!:
id='id'"alertUser('id')">
Lastly I tried the str function, and got similarly invalid output to my original attempt:
onclick='"alertUser('id')"'
Obviously if I code this in pure html it will look like:
onclick="alertUser('id')">
Which is valid.
My question is simply how do I enable CL-WHO to use double quotation marks in these situations instead of single quotation marks?

#jkiiski was has the correct answer in the comments underneath my question, but I wanted to post the answer so that anyone with a similar issue in the future can resolve the problem. As #jkiiski said, there is a variable called ATTRIBUTE-QUOTE-CHAR in the cl-who package that defaults to #\'. You can simply set that variable to #\" instead in order for the default quotations used to be double quotation marks:
(setf *attribute-quote-char* #\")
After adding that line of code near the top of the file my html defaults to:
onclick="alertUser('id')"
and now the javascript can execute properly. Credit to #jkiiski for a correct answer.

Related

Convert JavaScript string to JavaScript literal

In Chrome, when you right-click a string on the console, you'll see "copy string as javascript literal" option. This is what I want to have now, in JavaScript.
For example, let's say I have the following text content:
console.log('hoge');
My question is, how can I get something below from the above?
"console.log('hoge');"
I want to do this because, I have a mega bytes of webpack-generated long JavaScript content, and for a reason I need to eval() the script on an other environment, so I want to copy-and-paste the JavaScript literal text to inside the "eval()". (you may suggest exchanging the data not with the literal but with json (json.stringify/parse), I know, but I just prefer the literal way for now)
So is it possible? Thanks.
After noting the advice regarding the security weakness inherent in using eval (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)
You can achieve what you want by enclosing the entire literal code inside back-ticks and using the resulting string as the eval argument. back tick quotted strings can include line breaks so you should be able to pass your entire code block inside a single set.
Working snippet.
console.log('hoge');
console.log('another hoge');
eval(`console.log('hoge');
console.log('another hoge')`);
You can easily enclose Javascript in backticks to get a template literal:
eval(`console.log('hoge')`)
But you should also escape backticks inside the Javascript code to handle situations like this:
eval(`console.log(`hoge`)`) // SyntaxError
As a solution, you can use this bash one-liner:
sed 's/`/\\`/g' | xargs -0 printf 'eval(`%s`)'
Invoke the command by pressing Enter.
Paste in the Javascript you want to escape and press Enter again.
Press Ctrl+D to finish input.
You will get valid eval() function call with escaped template literal on the output.
You can assign this one-liner command to an alias for easy use:
alias js_eval_literal="sed '"'s/`/\\`/g'"' | xargs -0 printf '"'eval(`%s`)'"'"

Regular Expression in java to get parameters from javascript methods

Long story short, i would like to get the parameters list from JavaScript methods in Java. It works well if i got any parameters, but if the parameter list is empty it's just not working.
For example
function() { return fn.num(tra.getMaster_id(fg)+1)
My regular expression is:
(?<=\({1}).*?(?=\){1})
The result i get:
tra.getMaster_id(fg
The result i want is the empty space between the ().
If i test it with Here everything is fine, but in java it didn't working yet :(
I would appreciate any ideas!
First of all, you don't need {1} repetition quantifiers, everything is repeated just once by default. Secondly, since regexes in java are just strings that get interpreted, you have to escape escaping slashes (\):
(?<=\\().*?(?=\\))
Thirdly, you are getting the match that you want, it is just that there are more than one matches in this case. You are currently fetching the last one and not the first one.

g:message with arguments inside Javascript / jQuery not working as expected

I had an issue where String arguments were being truncated to the first character in our g:message tags (longs/integers seemed to be fine).
Ultimately, I figured out we were not calling g:message syntactically correct from within Javascript so some minor tweaks fixed the issue. Problem is - I don't understand why the former doesn't work.
Can anyone describe what was happening here?
jQuery("#myId").html("<g:message code='domain.message.path' args="${command?.foo?.name}"/>"); //incorrect, only displays first character of message
jQuery("#myId").html("${g.message(code: 'domain.message.path', args: [command?.foo?.name])}"); //correct, displays full string
I assume you're rendering this as part of a .gsp page? Here's the thing. In the first one, you're nesting quotes, essentially leaving the ${} section out of the string. Even Stackoverflow can tell; note how that part is a different color:
jQuery("#myId").html("<g:message code='domain.message.path' args="${command?.foo?.name}"/>");
See how the quote at the end of html( is ended by the quote before ${, leaving the ${command?.foo?.name} block outside the string? If command.foo.name was the string "bob", then when this rendered, you'd get:
jQuery("#myId").html("<g:message code='domain.message.path' args="bob"/>");
You might think this looks right, but javascript will handle this poorly.
If you used single quotes for the internal string, like you do with 'domain.message.path', it should work fine:
jQuery("#myId").html("<g:message code='domain.message.path' args='${command?.foo?.name}'/>");

Is AngularJS parsing the value incorrectly?

I have an extremely simple example here: http://jsfiddle.net/daylight/hqHSr/
To try it, just go to the fiddle and click the [Add Item] button to add some rows.
Next, click the check box next to any item and you'll see something similar to the following:
Problem: Only Displays Numeric Part
The problem is that the value should display the entire string shown in the row. In the example that means it should display: 86884-LLMUL.
Notice that it only displays the numeric part of the value.
If you look at the control you'll see that I'm using an input of type="text".
Also, if you look at the model (simpleItem) object you'll see that the one property it has is a string.
The JavaScript for the model class looks like:
function simpleItem(id) {
this.id = id;
}
My Attempt To Force to String Type
When I generate each of the simpleItems I even go so far as to set them to a character when I call the constructor (just to force the id to be set to a string type).
Here's the code that initializes each of the simpleItem ids:
currentItem.id = getRandom(100000).toString() + "-" + getRandomLetters(5).toUpperCase();
You can see the rest of the code in the fiddle, but the thing is I generate a random value and concatenate the value together with a hyphen and 5 letters. It's just a silly little piece of code for this sample.
But now, here is the part where it gets really odd.
If I simply change the hyphen - to another character like an uppercase X I get an error each time I click on the checkbox.
Here's the changed code and the new output, which you can see at the revised fiddle: fiddle version 2
currentItem.id = getRandom(100000).toString() + "X" + getRandomLetters(5).toUpperCase();
Also, now if you open Dev Tools in your browser you'll see in the console that Angular is now reporting an error each time you click the [Add Item] button. It looks like:
Adding Single-quotes ?Fixes? It
If you go up to the HTML and alter the following line from this:
ng-init="itemId ={{l.id.toString()}}"
to this
ng-init="itemId ='{{l.id.toString()}}'"
Now when you run it, the error will go away and it will work as you can see at the updated fiddle here: fiddle Version 3
Angular : Converts Hyphen to Minus Sign?
You see, Angular seems to be converting it to a numeric, attempting to do math on it (parsing the hyphen as a minus sign) and then truncating the string portion. That all seems to work when I use a hyphen, but when I use a X then Angular chokes.
Here's what it looks like when you add the single-quotes - of course the angular errors in Dev Tools console go away too.
Angular Forces to Numeric Type?
Why would this occur in Angular? It's as if it is attempting to force my string value to a numeric even though the INPUT element is type text and the JavaScript var is type string.
Anyone have ideas about this?
What About the Asterisk (multiplication symbol)?
Right as I was completing this I wondered what would happen if I changed the - to a * and ran it again. This time I saw the error below, which is indicative that something is attempting to convert to numeric.
This is the expected behavior. Angular is merely interpolating the text you have in your scope into the ng-init expression using scope.$eval and then executing that expression. This has very little to do with what is the type of the input box of the rest of the surrounding context.
It is definitely not desirable that Angular should wrap any interpolation it does in quotes, it'll break its use in all other places such as class="my-class {{dynamic-class}}".
Replace your ng-init with
ng-init="itemId =l.id.toString()"
In following with the docs, you should only use init in special circumstances anyway, you should rely on your controller for this. http://docs.angularjs.org/api/ng.directive:ngInit
I think we're just getting confused with Angular's weirdness. Basically, you're giving angular a string which it's turning into a javascript expression because it's in a {{}}. It's already, explicitly, a string (between the double-quotes):
ng-init="itemId ={{l.id.toString()}}"
It's apparently ignoring the fact that you're saying "hey, no really, this is a real string" with your l.id.toString(). It doesn't care. It's already a string and is going to evaluate it.
Just use the single quotes?
If you ng-init itemId={{undefined===undefined}}, what would you expect to happen? (it prints "true" in the alert).
Same with this: (undefined === undefined is in quotes) ng-init itemId={{'undefined===undefined'}}; prints true in the alert.
ng-init expects an angular expression. You don't have to use curly brackets there. You can simply write it like this:
ng-init="itemId=l.id" ng-click="checkBoxClicked(itemId)"

javascript syntax for passing variables to function

I have a JavaScript hyperlink that is not passing variable to function, undoubtedly due to syntax. Can someone please spot error.
jsfiddle: http://jsfiddle.net/kSVVX/
js
function follow(id){
alert(id);
}
html
<a href='javascript:void(0);' onclick= 'follow('1');'><img src='images/test.gif' border=0 alt='follow'></a>
Note: The reason that I am using all apostrophes is that this link is actually getting echoed from php where a long string is enclosed in quote marks (as certain things in the string must be in apostrophes.) I have a feeling this is source of problem, but have not succeeded in solving it by changing punctuation around.
Thanks for any suggestions.
You are using ' characters to delimit your JavaScript string and the HTML attribute value it is embedded in.
This results in:
onclick= 'follow('
Either:
Avoid intrinsic event attributes (which you should be doing anyway, unobtrusive JavaScript is recommended).
Use different characters to delimit the attribute value (onclick="follow('1');") or string (onclick= 'follow("1");')
Use HTML entities to include the quote mark you are using in the data for the attribute value (onclick= 'follow('1');')

Categories

Resources