http://qs321.pair.com?node_id=218598

perlcgi has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
First of all if you hate JavaScript, read no further dear Monk. Please don't downvote me, as I think this is an interesting chicken and egg problem that may interest many Monks, who some some day may encounter the same situation.
I am working with a HTML templating system, that is essentially, a black box. I cannot configure/hack it in any way. But I need to munge the expanded template codes for presentation, so I'm guessing the only tool I can use is JavaScript. (PerlScript here is not an option) For example the template code $123 might expand into "Hello World". Normally something like this works fine:
<script> var field = '$123'; document.write ('field'); </script>
But if the template code expands into "Hello Fred's World" then you'll get a syntax error as the apostrophe in Fred's is interpreted as the end of the string.
Is there a way to escape apostrophes and inverted comma characters before their assignment in JavaScript? Or is there some JavaScript trick to accommodate this situation?
I'd be obliged for any help Monk, and am thankful for your patience in allowing yourself to be exposed to this question.
perlcgi

Replies are listed 'Best First'.
Re: Template-output quoting (Warning: Contains JavaScript)
by dingus (Friar) on Dec 09, 2002 at 18:06 UTC
    document.write('"hello Fred\'s world"');
    works fine as does the excessively complex '"hello \"Fred\'s world\" "'

    This means that you can safely do a s(["'])/\$1/g server side thingy and all is OK. You can also do most perl regexen in javascript. However there is a bug in IE that means that string.split(/(?:a|b)/) causes the JS engine to stop - although string.split(/(a|b)/) does work ok. On the other hand in Mozilla string.split(/(a|b)/) crashes the browser - this is a known bug and may be fixed in 1.2 - which makes cross-browser support somewhat problematical! However the example below works fine

    ss = ", (?:\S+\. )*"; sre = (document.all)?/, (\S+\. )*/:new RegExp(", (?:\\S+\\. )*"); // later on a = data.split(sre );
    update The mozilla bug is 163323

    Dingus


    Enter any 47-digit prime number to continue.
Re: Template-output quoting (Warning: Contains JavaScript)
by tachyon (Chancellor) on Dec 10, 2002 at 14:50 UTC

    But if the template code expands into "Hello Fred's World" then you'll get a syntax error as the apostrophe in Fred's is interpreted as the end of the string.

    Ah, uhm, I don't think so. 'field' is a string literal not an interpolated variable.....Anyway here is some code that proves the point and shows you how to do s/this/that/g in javascript

    <script> var problem = "O'dear"; document.write( 'problem' + "<br>\n" ); problem = problem.replace( /'/g, "\\'" ); document.write( 'still' + ' no ' + problem ); </script> __DATA__ problem<BR> still no O\'dear

    Now I just have to log off, log on as my alter ego and downvote myself for contaminating the hallowed ground of PM.....It was only 4 lines. Hopefully the gods will be kind.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Dear dingus and tachyon, (and anyone else whose listening),
      Thanks for taking the trouble to respond and for pointing out how the regex expertise we lean form perl can easily be taken to JavaScript. ( I guess the same is true now for Java and C#).
      Anyways, my problem remains, perhaps because I have not explained the problem properly - the template codes can expand to any arbitrary string - so for example the template could expand to a string like:
      Larry said "Let there be light"; Bill swallowed hard.
      This gives a runtime error on my IE5.5 with JS debugging turned on. e.g.
      var problem = "Larry said "Let there be light"; Bill swallowed hard";
      Do you get my problem? Maybe it's impossible without opening the black-box.
      Thanks again for any suggestions, guys.
      perlcgi

        From what you are saying the way that the templating system is working is to arbirarily insert vars into the HTML as a pre-process. As such it can arbitrarily break your javascript before it can run. In this case by far the easiest solution, in fact probably the only solution will be to attack the source and send correctly escaped strings s/([^\w])/\\$1/g;

        The only other possible solution that occurs to me is trick the javascript thusly (pseudo code)

        <script> /* <VAR1> $var1 </VAR1> <VAR2> $var2 </VAR2> */ // now provided $var1 and $var2 did not contain the */ sequence // we should have all their values in pseudo XML within our // script. so now all we need to do is read the comment // somehow (don't know how but document.me.content.value or some // such probably holds the entire HTML text) and then use some regex // magic to extract the values we want // begin magic... </script>

        We trick the javacript to thinking that

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print