Rendering engine confused by certain pass-through inputs

Topics: User Forum
Jan 1, 2010 at 11:11 PM

I inserted this bit of code (tracking code from Google to supply analytics data) in the <FooterText> element of my .shfbproj file.
For the purposes of this issue, I have duplicated the line of code, swapping single quotes for double quotes.

&lt;script type='text/javascript'&gt;
document.write(unescape('%3Cscript src="' + gaJsHost + 'google-analytics.com/ga.js" type="text/javascript"%3E%3C/script%3E'));
&lt;/script&gt;
&lt;script type='text/javascript'&gt;
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
&lt;/script&gt;


It seems to be passed along correctly to the intermediate PresentationStyleBuilderContent.xml file,
where the URL encodings have been converted to literals:

<script type='text/javascript'>
document.write(unescape('<script src="' + gaJsHost + 'google-analytics.com/ga.js" type="text/javascript"></script>'));
</script>
<script type='text/javascript'>
document.write(unescape("<script src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'></script>"));
</script>




But when it gets to the final HTML file, the doubly-nested quotation marks have caused some errors.
The engine has apparently lost track of the nested quote marks, yielding invalid javascript code:

<script type="text/javascript">
document.write(unescape('<script src="' + gaJsHost + 'google-analytics.com/ga.js" type="text/javascript"></script>'));
</script>
<script type="text/javascript">
document.write(unescape("<script src="&quot; + gaJsHost + &quot;google-analytics.com/ga.js" type="text/javascript"></script>"));
</script>


The problem further manifests when one views the HTML file in a browser--the very end of the web page visbily shows a line
containing this:
')); "));

 

http://shfb.codeplex.com/Thread/List.aspx
Coordinator
Jan 2, 2010 at 10:13 PM

The HeaderText and FooterText properties support HTML tags so enter it without encoding the script angle brackets just as you would for any normal chunk of XML.  You'll also need to encode the '%' characters as '%25' so that the XML parser doesn't convert the encoded characters to normal characters:

<script type='text/javascript'>
document.write(unescape('%253Cscript src="' + gaJsHost + 'google-analytics.com/ga.js" type="text/javascript"%253E%253C/script%253E'));
</script>
<script type='text/javascript'>
document.write(unescape("%253Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%253E%253C/script%253E"));
</script>

Eric

 

Jan 3, 2010 at 2:51 AM
Edited Jan 3, 2010 at 2:57 AM

Hi, Eric:

(1) I tried both changes you suggested but there was no difference in my final output.

(2) I also tried putting the document.write statement in an XML CDATA section ( i.e. <script><![CDATA[ document.write... ]]></script> ) which did get rid of the &quot; in the final output source, but on screen it made it worse, now showing ')); ]]> ")); ]]>.

(3) Of the two document.write lines I originally reported, I can see from the quote mixup in the second one why the final 4 characters rendered as normal text, but I do not see why the first one shows the same problem--it appears syntactically correct to me...

Coordinator
Jan 3, 2010 at 9:17 PM

I tried it in a test project literally as posted in my reply and it seemed to work okay.  The only error I got was that gaJsHost wasn't defined which was expected.  After removing that reference, the pages rendered without error in the browser.

Eric

 

Jan 4, 2010 at 10:56 PM
Edited Jan 4, 2010 at 10:58 PM

So I wonder what is different between our two environments...? Let me walk you through some steps for comparison. In my test project

(containing virtually nothing) I include your six lines of text and I get this in my output HTML files:

<script type="text/javascript" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
document.write(unescape('<script src="' + gaJsHost + 'google-analytics.com/ga.js" type="text/javascript"></script>'));
</script

<script type="text/javascript" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
document.write(unescape("<script src="&quot; + gaJsHost + &quot;google-analytics.com/ga.js" type="text/javascript"></script>"));
</script>

Q1: Is your output the same?

Independently I created a simple, standalone HTML file using a similar JavaScript invocation. Here is the entire file:
<html>
  <head>
    <script type="text/javascript" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      document.write(unescape('<script>' + 'confirm("hello world")' + '</script>'));
    </script>
  </head>
</html>


In both IE8 and Firefox 3.5, this renders incorrectly: the JavaScript does not execute and on screen I see four characters that should not be visible: '));

Q2: Do you see the same in IE8 and/or Firefox?


This simple code example may be corrected by simply adding a backslash before the forward slash within the document.write.
Once patched you should see a simple pop-up when the page is reloaded and no extraneous characters. (See Dynamically Loading External JavaScript Files for supporting evidence.)
Here is the modified code:
<html>
<head>
<script type="text/javascript" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
document.write(unescape('<script>' + 'confirm("hello world")' + '<\/script>'));
</script>
</head>
</html>


Q3: Do you get the JavaScript pop-up with this change?

So, from my points detailed here, it follows that your original six lines of code are not generating HTML that works in Firefox or IE8.

I thought a workaround would be as simple as adding the backslash into the <FooterText> element in the SHFB project file, but when I attempt to build,
SHFB balks at the presence of the backslash. I have tried URL-encoding it with %5C and even %255C but neither makes a difference--same complaint.



Coordinator
Jan 5, 2010 at 3:07 AM

I think I see the problem.  There's an MSBuild namespace on the script tag in your latest example.  Did you cut and paste your code directly into the SHFB project file bypassing the GUI?  If so, that is causing the problem because it isn't getting encoded correctly for storage in the project file.  Take my example from my first reply, join it all onto one single line (it won't past the line feeds in the GUI), paste that single line into the FooterText property in the GUI, and build it.  I think you'll find that it works.  I tried your examples above and as long as I entered the angle brackets in the unescape() calls as '%253C' and '%253E' in the property text, I got the expected results.  Just so you know, I'm using Window 7 64-bit and IE8.  I'm also using the just released 1.8.0.3 release of SHFB but that shouldn't affect anything.

Eric

 

Jan 5, 2010 at 4:43 AM
Edited Jan 5, 2010 at 6:15 PM

Good eye, Eric! I did paste directly into the project file--I did not consider the GUI encoding text into it.

With the angle brackets encoded (and therefore effectively invisible), that also explains why the extra backslash that I showed above is not needed.

Thanks for your useful feedback!

So for other readers who might be interested, here are the "Lessons Learned" for <FooterText> and <HeaderText>:
(1) If you need curly braces double them, i.e. {{ for { and }} for }.
(2) If you need a percent character URL-encode it, i.e. %25 for %.
(3) Enter your text through the GUI rather than editing the project file (*.shfbproj) itself--that allows SHFB to properly encode it to survive the trip to the web page.

~~Michael