<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Everything old is new again &#187; JavaScript</title>
	<atom:link href="http://www.svendtofte.com/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.svendtofte.com</link>
	<description>rantings &#38; scraps on code and web development</description>
	<lastBuildDate>Thu, 27 Aug 2009 22:38:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Javascript ghost debugging</title>
		<link>http://www.svendtofte.com/javascript/javascript-ghost-debugging/</link>
		<comments>http://www.svendtofte.com/javascript/javascript-ghost-debugging/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 00:46:35 +0000</pubDate>
		<dc:creator>Svend</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[debugger]]></category>

		<guid isPermaLink="false">http://www.svendtofte.com/?p=262</guid>
		<description><![CDATA[
Recently, I tried to use jQuery, as a way of dynamically loading all the scripts that a certain page requires. Instead of utilizing script tags in the header section, using a simple $.getScript("script.js"); loads the same code, what&#8217;s more, this code is loaded asynchronously, which helps improve loading performance. The only problem is that loading [...]]]></description>
			<content:encoded><![CDATA[<div style="float:right;"><img src="/wp-content/uploads/2009/07/mario-boo.jpg" alt="Boo"></div>
<p>Recently, I tried to use jQuery, as a way of dynamically loading all the scripts that a certain page requires. Instead of utilizing script tags in the header section, using a simple <code>$.getScript("script.js");</code> loads the same code, what&#8217;s more, this code is loaded asynchronously, which helps <a href="http://www.stevesouders.com/blog/2008/12/27/coupling-async-scripts /">improve loading performance</a>. The only problem is that loading scripts this way, makes them <em>unavailable for debugging</em>.</p>
<p>Debugging dynamically included script files presents some special challenges on it&#8217;s own. The primary being that that the web is basicly not a structured enviroment, like a folder on disk, and references to files and/or code is can be very intermittent.</p>
<p><span id="more-262"></span></p>
<h3>Some methods for loading remote code</h3>
<p>Here&#8217;s just some of the many ways that code may be included dynamically in a page (these are just rough outlines, buyer beware.) Be especially wary that this code is specifically for loading scripts, if you want to load JSON, you&#8217;ll need a different approach, just spilling your guts in the global scope is quite messy.</p>
<ol>
<li>
<p>Using XMLHttpRequest to load the script, and then insert via DOM methods into the page itself.</p>
<pre>
var req = new XMLHttpRequest();
req.open('GET', 'delayed.js', true)
req.onreadystatechange = function(e) {
    var head= document.getElementsByTagName('body')[0];
    var delayed = document.createElement('script');
    var txt = document.createTextNode(req.responseText);
    delayed.appendChild(txt);
    head.appendChild(delayed);
}
req.send();
</pre>
</li>
<li>
<p>Using XMLHttpRequest to load the script, and then use <code>eval</code> to execute the code in the global scope.</p>
<pre>
var req = new XMLHttpRequest();
req.open('GET', 'delayed.js', true)
req.onreadystatechange = function(e) {
    eval(req.responseText);
}
req.send();
</pre>
</li>
<li>
<p>Dynamically create a script tag with DOM methods, and then point it&#8217;s <code>src</code> attribute to the script you wish download.</p>
<pre>
var head= document.getElementsByTagName('head')[0];
var delayed = document.createElement('script');
delayed.onreadystatechange = function() {
    if (delayed.readyState == "loaded" ||
        delayed.readyState == "complete") delay();
}
delayed.src = "delayed.js";
head.appendChild(delayed);
</pre>
<p>This code also details how you can get a callback for when the actual script has loaded, so you&#8217;re not &#8220;missing&#8221; out on the callback functionality of XMLHttpRequest.</p>
</li>
</ol>
<p>jQuery basicly executes the first approach. The little twist is that just after the script has been added to the browser, it removes the tag again, so it&#8217;s not &#8220;littering&#8221; the document DOM with these script tags the author himself didn&#8217;t insert. This can be seen in the jQuery script at around line 646, where you find the <code>globalEval</code> function (assuming the development version, not the minified versions.)</p>
<h3>The problem with anonymous code</h3>
<p>This is all dandy, the problem simply is that no debuggers expose the anonymous code which enters the global scope in this fashion.</p>
<p class="imgWithCaption"><img src="http://www.svendtofte.com/wp-content/uploads/2009/07/firebug-html-view.gif" alt="Firebug showing a webpage with a static and dynamic node of Javascript" /><br /> Firebug showing a webpage with both a static and a dynamically loaded script (the script was loaded with jQuery, but with a modified jQuery so that it leaves the node in the DOM). Everything looks fine.</p>
<p class="imgWithCaption"><img src="http://www.svendtofte.com/wp-content/uploads/2009/07/firebug-js-view.gif" alt="Firebug's Javascript tab with only the static node available for debugging." /><br /> Firebug&#8217;s script tab shows a different view, namely the one where the dynamically loaded script block is gone, and thus not available for debugging.  </p>
<p>If you try to load the following script, with this piece of jQuery, <code>$.getScript("delay.js", function() { delay(); });</code>, will lead the debugger to exclaim that the method name is &#8220;anonymous&#8221;!</p>
<pre>
function delay() {
    alert("hello from delayed.js");
    console.trace();
}
</pre>
<h3>Loading code for proper debugging</h3>
<p>As you can see, the way that jQuery (and many other libs) chooses to load their scripts is a rather high-tech one, and the solution is as simple as not using XMLHttpRequest. By utilizing the third method of remotely loading scripts, allows you to morely accurately debug the scripts.</p>
<p>Take the following page and two script files for instance:</p>
<pre>
&lt;html&gt;
&lt;head&gt;
&lt;script type="text/javascript"&gt;
function load(scriptSrc, callback) {
    var head= document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.onreadystatechange = function() {
        if (script.readyState == "loaded" ||
            script.readyState == "complete") callback();
    }
    script.src = scriptSrc;
    head.appendChild(script);
}
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;&lt;a href="javascript:load('load1.js',function() { load1(); });"&gt;load 1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="javascript:load('load2.js',function() { load2(); });"&gt;load 1&lt;/a&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<pre>
function load1() {
    alert("hello from load1");
}
</pre>
<pre>
function load2() {
    alert("hello from load2");
}
</pre>
<p>If we look at IE8&#8217;s Developer Tools JS debugger, you&#8217;ll notice that on page load, the scripts drop-down does not contain neither load1.js or load2.js.</p>
<p class="imgWithCaption"><img src="/wp-content/uploads/2009/07/ie-dev-tools-initial.gif" width="535" height="198" alt="IE8 Developer Tools on initial page load" /><br /> IE8&#8217;s Developer Tools on initial loading of a simple HTML page.</p>
<p>If we try to click the links however, the scripts we load will appear in the  dropdown, and allow easy debugging.</p>
<p class="imgWithCaption"><img src="/wp-content/uploads/2009/07/ie-dev-tools-loaded.gif" alt="IE8 Developer tools showing script available for debugging." width="535" height="198" /><br />IE8&#8217;s Developer Tools after having clicked the load link, the loaded script is now available for easy debugging (this works just as well in Firebug btw.)</p>
<h3>Debuggers</h3>
<p>Debuggers are still lacking behind in this area, compared to debuggers operating in more stable enviroments. There&#8217;s no denying that the web presents unique challenges, but the fact remains that the code is available for execution, but is not exposed for debugging. So while JS debuggers has moved forward since the days of <a href="/code/learning_venkman">Venkman</a>, I think there&#8217;s still ways to improve (and this need will become more pronounced as the dynamic nature of the web increases with time).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.svendtofte.com/javascript/javascript-ghost-debugging/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JavaScript date string formatting</title>
		<link>http://www.svendtofte.com/javascript/javascript-date-string-formatting/</link>
		<comments>http://www.svendtofte.com/javascript/javascript-date-string-formatting/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 21:23:20 +0000</pubDate>
		<dc:creator>Svend</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[formatting]]></category>

		<guid isPermaLink="false">http://www.svendtofte.com/?p=18</guid>
		<description><![CDATA[Date string formatting is very brutal in JavaScript, which probably has the worst built in library in relation to the distribution this language sees. So a long time ago I whipped up a script file, for doing just this. I always though PHP&#8217;s date function looked very nice, so I decided to model my function [...]]]></description>
			<content:encoded><![CDATA[<p>Date string formatting is very brutal in JavaScript, which probably has the worst built in library in relation to the distribution this language sees. So a long time ago I whipped up a script file, for doing just this. I always though <a href="http://php.net/date">PHP&#8217;s date function</a> looked very nice, so I decided to model my function upon that. </p>
<p><span id="more-18"></span></p>
<p>Download: <a href="http://www.svendtofte.com/wp-content/uploads/2008/07/formatdate.js">formatDate.js</a> (13kB)</p>
<h3>Supported switches and test</h3>
<p>I&#8217;m not going to duplicate <a href="http://php.net/date">PHP&#8217;s documentation</a>. But I will list briefly the supported switches. Basicly, switches should return the same as in PHP, if they don&#8217;t, it&#8217;s most likely in error, so let me know at <script>myEmail();</script>. </p>
<table class="tufteDesign">
<tr>
<td>Supported switches</td>
<td>Unsupported switches</td>
<td>Currently unsupported, but might be included in the future</td>
</tr>
<tr>
<td>a, A, B, c, d, D, F, g, G, h, H, i, I (uppercase i), j, l (lowecase L),  L, m, M, n, N, O, P, r, s, S, t, U, w, W, y, Y, z, Z</td>
<td>T, e, o</td>
<td></td>
</tr>
</table>
<p>Here&#8217;s some examples.</p>
<p><script src="http://www.svendtofte.com/wp-content/uploads/2008/07/formatdate.js"></script><script>
var currDate = new Date();
</script></p>
<table class="tufteDesign">
<tr>
<td>Example</td>
<td>Output</td>
</tr>
<tr>
<td><code>F j, Y, g:i a</code></td>
<td><script>document.write(currDate.formatDate("F j, Y, g:i a"));</script></td>
</tr>
<tr>
<td><code>m.d.y</code></td>
<td><script>document.write(currDate.formatDate("m.d.y"));</script></td>
</tr>
<tr>
<td><code>j, n, Y</code></td>
<td><script>document.write(currDate.formatDate("j, n, Y"));</script></td>
</tr>
<tr>
<td><code>Ymd</code></td>
<td><script>document.write(currDate.formatDate("Ymd"));</script></td>
</tr>
<tr>
<td><code>h-i-s, j-m-y, it is w Day z</code></td>
<td><script>document.write(currDate.formatDate("h-i-s, j-m-y, it is w Day z"));</script></td>
</tr>
<tr>
<td><code>%i%t %i%s %t%h%e jS %d%a%y.</code></td>
<td><script>document.write(currDate.formatDate("%i%t %i%s %t%h%e jS %d%a%y."));</script></td>
</tr>
<tr>
<td><code>D M j G:i:s T Y</code></td>
<td><script>document.write(currDate.formatDate("D M j G:i:s T Y"));</script></td>
</tr>
<tr>
<td><code>H:m:s %m %i%s% %m%o%n%t%h</code></td>
<td><script>document.write(currDate.formatDate("H:m:s %m %i%s% %m%o%n%t%h"));</script></td>
</tr>
<tr>
<td><code>H:i:s</code></td>
<td><script>document.write(currDate.formatDate("H:i:s"));</script></td>
</tr>
</table>
<p>And here you can test your own flags if you should wish.<br />
<script>
function testDateFormat() {
  var inFormat = document.getElementById("dateFormatIn").value;
  var output = document.getElementById("dateFormatOut");
  var d = new Date();
  output.innerHTML = d.formatDate(inFormat);
}
</script></p>
<form onsubmit="return false;">
<p><input type="text" width="20" id="dateFormatIn" value="c"/>
<input type="button" value="hit it!" onclick="testDateFormat();return false;" /> output: <code><span id="dateFormatOut"></span></code></p>
</form>
<h3>Differences and gotchas</h3>
<p>You should note quite quickly that you use <code>%</code> to escape, not backslash (<code>\</code>). PHP gets to treat strings a bit different, and frankly, <code>\\d\\u\\m\\b</code> looks stupid (not to mention the quadruple escape, <code>\\\\</code>, if you want a <em>single</em> backslash in your output).</p>
<p>Another thing to note is that this code operates either directly on a Date object (which always have a time set), or a passed in value, which it interprets as a date. <em>The script doesn&#8217;t help you in any way in setting a time.</em> As a developer, you need to be careful when juggling dates on the client side, and also if you create any dates, don&#8217;t make assumptions regarding what timezone the runtime thinks it is.</p>
<p>I&#8217;ve obsoleted my old page, though <a href="/code/date_format/_index.php">it&#8217;s still on the site under a different name</a>. It had some more rigerous testing (it&#8217;s using the old version of the script so take care), and also some stuff about localization which I don&#8217;t really think is that interesting anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.svendtofte.com/javascript/javascript-date-string-formatting/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
