<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkQNQH4ycSp7ImA9WxFaFEQ.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669</id><updated>2010-07-19T03:13:11.099+03:00</updated><title>i'm under construction</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.igstan.ro/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.igstan.ro/" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/igstan" /><feedburner:info uri="igstan" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A0MHQH47fip7ImA9WxBUF0U.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-6312107429269964086</id><published>2010-03-05T13:33:00.003+02:00</published><updated>2010-03-05T13:43:51.006+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-05T13:43:51.006+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Git" /><category scheme="http://www.blogger.com/atom/ns#" term="Good To Know" /><title>Git's environment filter</title><content type="html">This is a thing I keep on forgetting although I've done it several times. So, I'm writing a blog post hoping it will help me memorize this.&lt;br /&gt;&lt;br /&gt;So... how do you rewrite Git's history, specifically the environment variables? With &lt;code&gt;git filter-branch&lt;/code&gt; of course. I frequently need it in order to change the author and committer email addresses (either from personal to work or the other way around).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL="email@address.com"' HEAD&lt;br /&gt;git filter-branch --env-filter 'export GIT_COMMITTER_EMAIL="email@address.com"' HEAD&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Don't forget that there are two email addresses, OK? The author's and committer's one. Oh, and no spaces around the equal sign.&lt;br /&gt;&lt;br /&gt;For a more complicated situation see &lt;a href="http://serverfault.com/questions/12373/how-do-i-edit-gits-history-to-correct-an-incorrect-email-address-name"&gt;this answer on serverfault.com&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-6312107429269964086?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/DaK44Pcv1wU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/6312107429269964086/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2010/03/gits-environment-filter.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/6312107429269964086?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/6312107429269964086?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/DaK44Pcv1wU/gits-environment-filter.html" title="Git's environment filter" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.igstan.ro/2010/03/gits-environment-filter.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4CRH8yfCp7ImA9WxNTEEU.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-8864091694343575452</id><published>2009-06-05T01:54:00.016+03:00</published><updated>2009-08-12T16:16:05.194+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-12T16:16:05.194+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tricks" /><category scheme="http://www.blogger.com/atom/ns#" term="Mozilla" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><category scheme="http://www.blogger.com/atom/ns#" term="CSS" /><category scheme="http://www.blogger.com/atom/ns#" term="Firefox" /><title>CSS for Firefox only</title><content type="html">&lt;strong&gt;So, how do you write &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt; code that will be understood only by Firefox?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Same &lt;a href="http://stackoverflow.com/questions/952861/targeting-only-firefox-with-css"&gt;question&lt;/a&gt; was asked by someone on &lt;a href="http://stackoverflow.com/"&gt;stackoverflow.com&lt;/a&gt;. My first attempt was to use &lt;a href="https://developer.mozilla.org/en/XBL/XBL%5F1.0%5FReference"&gt;XBL&lt;/a&gt; and Mozilla's proprietary -moz-binding CSS extension in order to run some JavaScript that will eventually load the intended CSS rules. This solution was inspired by &lt;a href="http://dean.edwards.name/moz-behaviors/"&gt;Dean Edwards' moz-behaviors library&lt;/a&gt; and it looks like this:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;index.html&lt;/h4&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;!DOCTYPE&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;html&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;html&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;head&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker9"&gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="css1-reservedword"&gt;body &lt;/span&gt;&lt;span class="css1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="css1-space"&gt; &lt;/span&gt;&lt;span class="css1-undefinedproperty"&gt;-moz-binding&lt;/span&gt;&lt;span class="css1-symbol"&gt;:&lt;/span&gt;&lt;span class="css1-space"&gt; &lt;/span&gt;&lt;span class="css1-value"&gt;url(ff.xml#load-mozilla-css)&lt;/span&gt;&lt;span class="css1-symbol"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker9"&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/head&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;body&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;h1&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;This should be red in FF&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/h1&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/body&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/html&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;ff.xml&lt;/h4&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="xml1-processinginstruction"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;lt;bindings&lt;/span&gt;&lt;span class="xml1-whitespace"&gt; &lt;/span&gt;&lt;span class="xml1-namespaceattributename"&gt;xmlns&lt;/span&gt;&lt;span class="xml1-symbol"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="xml1-namespaceattributevalue"&gt;http://www.mozilla.org/xbl&lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="xml1-text"&gt;    &lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;lt;binding&lt;/span&gt;&lt;span class="xml1-whitespace"&gt; &lt;/span&gt;&lt;span class="xml1-attributename"&gt;id&lt;/span&gt;&lt;span class="xml1-symbol"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="xml1-attributevalue"&gt;load-mozilla-css&lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="xml1-text"&gt;        &lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;lt;implementation&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="xml1-text"&gt;            &lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;lt;constructor&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="xml1-text"&gt;            &lt;/span&gt;&lt;span class="xml1-cdatasection"&gt;&amp;lt;![CDATA[&lt;br /&gt;                var link = document.createElement(&amp;quot;link&amp;quot;);&lt;br /&gt;                    link.setAttribute(&amp;quot;rel&amp;quot;, &amp;quot;stylesheet&amp;quot;);&lt;br /&gt;                    link.setAttribute(&amp;quot;type&amp;quot;, &amp;quot;text/css&amp;quot;);&lt;br /&gt;                    link.setAttribute(&amp;quot;href&amp;quot;, &amp;quot;ff.css&amp;quot;);&lt;br /&gt;&lt;br /&gt;                document.getElementsByTagName(&amp;quot;head&amp;quot;)[0]&lt;br /&gt;                        .appendChild(link);&lt;br /&gt;            ]]&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="xml1-text"&gt;            &lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;lt;/constructor&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="xml1-text"&gt;        &lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;lt;/implementation&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="xml1-text"&gt;    &lt;/span&gt;&lt;span class="xml1-symbol"&gt;&amp;lt;/binding&amp;gt;&lt;br /&gt;&amp;lt;/bindings&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;ff.css&lt;/h4&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="css1-reservedword"&gt;h1 &lt;/span&gt;&lt;span class="css1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="css1-space"&gt; &lt;/span&gt;&lt;span class="css1-property"&gt;color&lt;/span&gt;&lt;span class="css1-symbol"&gt;:&lt;/span&gt;&lt;span class="css1-space"&gt; &lt;/span&gt;&lt;span class="css1-value"&gt;red&lt;/span&gt;&lt;span class="css1-symbol"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But I felt that there should be a better solution. So I kept digging on &lt;a href="https://developer.mozilla.org/En"&gt;&lt;acronym title="Mozilla Developer Center"&gt;MDC&lt;/acronym&gt;&lt;/a&gt;. After a couple of clicks I discovered the easiest solution out there for targeting just the Firefox browser in our CSS. It uses a Mozilla specific at-rule, called &lt;a href="https://developer.mozilla.org/en/CSS/@-moz-document"&gt;@-moz-document&lt;/a&gt;, and it's actually intended for user styling.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Here's the final solution&lt;/h4&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;!DOCTYPE&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;html&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;html&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;head&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker9"&gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="css1-reservedword"&gt;@-moz-document url-prefix() &lt;/span&gt;&lt;span class="css1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="css1-space"&gt;    &lt;/span&gt;&lt;span class="css1-undefinedproperty"&gt;h1&lt;/span&gt;&lt;span class="css1-space"&gt; &lt;/span&gt;&lt;span class="css1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="css1-space"&gt;        &lt;/span&gt;&lt;span class="css1-property"&gt;color&lt;/span&gt;&lt;span class="css1-symbol"&gt;:&lt;/span&gt;&lt;span class="css1-space"&gt; &lt;/span&gt;&lt;span class="css1-value"&gt;red&lt;/span&gt;&lt;span class="css1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="css1-space"&gt;    &lt;/span&gt;&lt;span class="css1-symbol"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span class="css1-reservedword"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker9"&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/head&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;body&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;h1&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;This should be red in FF&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/h1&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/body&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/html&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;A word of caution&lt;/h4&gt;We all know how many hours Internet Explorer conditional comments have saved us, but I believe Firefox is a much, much better browser, so please think twice before using the above trick. I'm pretty sure there must be some other way. We don't want to maintain three different stylesheets, for &lt;acronym title="Internet Explorer"&gt;IE&lt;/acronym&gt;, &lt;acronym title="Firefox"&gt;FF&lt;/acronym&gt; and the rest of the browsers out there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-8864091694343575452?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/ne9oiEzULsY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/8864091694343575452/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/06/css-for-firefox-only.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/8864091694343575452?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/8864091694343575452?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/ne9oiEzULsY/css-for-firefox-only.html" title="CSS for Firefox only" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/06/css-for-firefox-only.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IGRXYzfyp7ImA9WxJTGU8.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-7287038469945447761</id><published>2009-04-28T15:13:00.004+03:00</published><updated>2009-04-28T15:25:24.887+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-28T15:25:24.887+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="ECMAScript" /><category scheme="http://www.blogger.com/atom/ns#" term="JScript" /><category scheme="http://www.blogger.com/atom/ns#" term="ECMAScript 3" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>JScript deviations from ECMAScript 3</title><content type="html">Just found a great resource of "things" that are specific to JScript and are not conforming to the ECMAScript 3 standard. Found it on a &lt;a href="http://blogs.msdn.com/jscript/archive/2007/10/29/ecmascript-3-and-beyond.aspx"&gt;MSDN blog post from 2007&lt;/a&gt;. Enjoy, 87 pages of standards deviations (aka bugs)! &lt;a href="http://wiki.ecmascript.org/lib/exe/fetch.php?id=resources%3Aresources&amp;amp;cache=cache&amp;amp;media=resources:jscriptdeviationsfromes3.pdf"&gt;Here's the PDF&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-7287038469945447761?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/eNVEUL4HAHA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/7287038469945447761/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/04/jscript-deviations-from-ecmascript-3.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/7287038469945447761?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/7287038469945447761?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/eNVEUL4HAHA/jscript-deviations-from-ecmascript-3.html" title="JScript deviations from ECMAScript 3" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/04/jscript-deviations-from-ecmascript-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUANSHc8fyp7ImA9WxVaEko.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-1359713913194971780</id><published>2009-04-03T02:16:00.012+03:00</published><updated>2009-04-09T13:43:19.977+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-09T13:43:19.977+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="anonymous functions" /><category scheme="http://www.blogger.com/atom/ns#" term="lambda" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="closures" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP 5.3" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>Lambdas and closures in PHP 5.3</title><content type="html">&lt;a href="http://igstan.blogspot.com/2009/04/whats-new-in-php-53.html"&gt;Beginning with PHP 5.3&lt;/a&gt; we'll be able to write anonymous functions and build closures around them - almost the same way we do it in JavaScript. I'd like to introduce these to those of you unaware of these new possibilities in this little blog post.&lt;br /&gt;&lt;h4&gt;Defining a lambda&lt;/h4&gt;&lt;br /&gt;The most simple way to define a lambda can be find below. It's exactly the same way JavaScript handles it. One has to assing a function to a variable.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$lambda&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;function&lt;/span&gt;&lt;span class="php1-symbol"&gt;()&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;return&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'Hello World'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;};&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-comment"&gt;// &amp;lt;- this semicolon is mandatory, unlike JavaScript&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$lambda&lt;/span&gt;&lt;span class="php1-symbol"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;Creating closures&lt;/h4&gt;&lt;br /&gt;However, if we want closures, we have to do something more and this because the way scope is designed in PHP where functions don't get easy access to variables declared outside them. If we want that with a normal (old style) function, we need to import them using the &lt;code&gt;global&lt;/code&gt; keyword. Following the same idea, in order to capture a variable into a closure we need to &lt;code&gt;use&lt;/code&gt; it:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$word&lt;/span&gt;&lt;span class="php1-space"&gt;   &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;' World'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$lambda&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;function&lt;/span&gt;&lt;span class="php1-symbol"&gt;()&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;use&lt;/span&gt;&lt;span class="php1-symbol"&gt;(&lt;/span&gt;&lt;span class="php1-variable"&gt;$word&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;return&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'Hello'&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;.&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$word&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$lambda&lt;/span&gt;&lt;span class="php1-symbol"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;Mutable closures&lt;/h4&gt;&lt;br /&gt;Now, our anonymous functions has access to &lt;code&gt;$word&lt;/code&gt;. But &lt;strong&gt;there's a gotcha&lt;/strong&gt; right here. It has read only access to &lt;code&gt;$word&lt;/code&gt;. We may try to modify &lt;code&gt;$word&lt;/code&gt; inside our function, but those changes won't be visible outside it. So, here we are, introducing the third thing we need to know about lambdas and closures in PHP. In order to be able to modify a closed variable, we need to import it using the reference operator:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$word&lt;/span&gt;&lt;span class="php1-space"&gt;   &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;' World'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$lambda&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;function&lt;/span&gt;&lt;span class="php1-symbol"&gt;()&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;use&lt;/span&gt;&lt;span class="php1-symbol"&gt;(&amp;amp;&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$word&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-variable"&gt;$result&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'Hello'&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;.&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$word&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-variable"&gt;$word&lt;/span&gt;&lt;span class="php1-space"&gt;   &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'Bye World'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;return&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$result&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$lambda&lt;/span&gt;&lt;span class="php1-symbol"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$word&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This time, &lt;code&gt;$word&lt;/code&gt; can and will be modified. The variable inside the closure is mutable.&lt;br /&gt;&lt;h4&gt;Some history about the future&lt;/h4&gt;&lt;br /&gt;Although, as of yet, a stable version of PHP 5.3 is not yet out, I should mention that in the process of bringing lambdas and closures to the language there was a particular property of these in that they were able to automagically import the $this pointer if the function was defined inside a class. Not long after, some people thought about writing PHP in the prototypal style of JavaScript, thus there were some discussion that lead the PHP internals to temporarily remove the magic import feature. The main reason was that they had to push the final version out sooner and any new feature would have meant delays. Nevertheless, this feature has been postponed for PHP 6 in which we may get some niceties that should allow us to more easily write code in a monkey patching/prototypal style.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-1359713913194971780?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/c6C4uagVmGg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/1359713913194971780/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/04/lambdas-and-closures-in-php-53.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/1359713913194971780?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/1359713913194971780?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/c6C4uagVmGg/lambdas-and-closures-in-php-53.html" title="Lambdas and closures in PHP 5.3" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/04/lambdas-and-closures-in-php-53.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EMR3c5cSp7ImA9WxVaEEg.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-4239315621780051470</id><published>2009-04-01T14:26:00.021+03:00</published><updated>2009-04-07T02:14:46.929+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-07T02:14:46.929+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP 5.3" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>What's new in PHP 5.3</title><content type="html">A few weeks ago, &lt;a href="http://www.php.net/archive/2009.php#id2009-03-24-1"&gt;PHP 5.3 RC1 has been released&lt;/a&gt; and I expect the final version to be out in no more than a month. I'm watching its development since the beginning of 2008 and am really eager to see it in production. The reason for this impatience is that it brings really cool features to the language and I'd like to enumerate some of them in order of my preferences. Initially I also wanted to briefly describe them, but apparently there was to much to talk about in just one post, therefore each feature in the list below will, eventually, point to a more detailed post about the respective feature. So here's what I like best:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://igstan.blogspot.com/2009/04/lambdas-and-closures-in-php-53.html"&gt;Lambdas and closures&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Callable classes&lt;/li&gt;&lt;li&gt;Namespaces&lt;/li&gt;&lt;li&gt;The Phar extension&lt;/li&gt;&lt;li&gt;Late static binding&lt;/li&gt;&lt;/ol&gt;There are some other features beside the above mentioned, but these are easier to present so I'll shortly describe them here:&lt;h4&gt;1. __callStatic&lt;/h4&gt;This is just like the __call we all know except it is designed to work when calling methods in a static context:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size-adjust: none; font-stretch: normal;font-family:Courier New;font-size:10;"  &gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;class&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;Test&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;public&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;static&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;function&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;__callStatic(&lt;/span&gt;&lt;span class="php1-variable"&gt;$method&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$args&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;        &lt;/span&gt;&lt;span class="php1-reservedword"&gt;return&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;array&lt;/span&gt;&lt;span class="php1-symbol"&gt;(&lt;/span&gt;&lt;span class="php1-variable"&gt;$method&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$args&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-symbol"&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var_dump(Test::dummyMethod(&lt;/span&gt;&lt;span class="php1-string"&gt;'with dummy argument'&lt;/span&gt;&lt;span class="php1-symbol"&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;2. NOWDOC strings&lt;/h4&gt;We all know &lt;a href="http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc"&gt;HEREDOC&lt;/a&gt; strings and the fact they are parsed by the PHP engine for variable interpolation. They're also good when we have large strings with both single and double quotes, because it saves us from escaping them. Some PHP internals thought though, that the overhead produced for variable interpolation is to big, so they came up with &lt;a href="http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.nowdoc"&gt;NOWDOC strings&lt;/a&gt;. This is just like HEREDOC save for the variable interpolation. Here's an example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size-adjust: none; font-stretch: normal;font-family:Courier New;font-size:10;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$here_doc&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;&amp;lt;&amp;lt;&amp;lt;STR&lt;br /&gt;Some&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;random&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;string&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;with&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$variable&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;interpolation...&lt;br /&gt;STR;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$now_doc&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="php1-string"&gt;'STR'&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-identifier"&gt;Some&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;random&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;string&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;without&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;$variable&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;interpolation...&lt;br /&gt;STR;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;3. Ternary shortcut (?:)&lt;/h4&gt;This is just like the old ternary operator except that we can leave out the middle statement. &lt;a href="http://php.net/ternary#language.operators.comparison.ternary"&gt;The rule is&lt;/a&gt; that, if the left-hand side expression evaluates to true, its result is returned, otherwise it will return the result of the result of right-hand side expression:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size-adjust: none; font-stretch: normal;font-family:Courier New;font-size:10;"  &gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;var_dump(&lt;/span&gt;&lt;span class="php1-string"&gt;''&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;?:&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'there was an empty string'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;var_dump(&lt;/span&gt;&lt;span class="php1-string"&gt;'I am not empty'&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;?:&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'there was an empty string'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;4. Limited goto&lt;/h4&gt;Honestly, I don't yet understand why this construct is limited because I have never worked with gotos. All I know is that we cannot use goto statements inside loops, this will cause a fatal error to be thrown. Anyway, here's a &lt;a href="http://www.php.net/manual/en/control-structures.goto.php"&gt;basic example taken straight from the manual&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size-adjust: none; font-stretch: normal;font-family:Courier New;font-size:10;"  &gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;&lt;span class="php1-reservedword"&gt;goto&lt;/span&gt;&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;a;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'Foo'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;a:&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'Bar'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-4239315621780051470?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/OH9RMeYXw88" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/4239315621780051470/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/04/whats-new-in-php-53.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/4239315621780051470?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/4239315621780051470?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/OH9RMeYXw88/whats-new-in-php-53.html" title="What's new in PHP 5.3" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>4</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/04/whats-new-in-php-53.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8GSH0yeSp7ImA9WxVbFUU.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-707071365465380392</id><published>2009-04-01T12:46:00.004+03:00</published><updated>2009-04-01T14:20:29.391+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-01T14:20:29.391+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="easter eggs" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="April Fools" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP 5.3" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>PHP 5.3 April Fools Easter Egg</title><content type="html">Apparently, PHP 5.3 RC1 changes the PHP logo generated by php_logo_guid() or phpinfo() on April 1st. There's an &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=elephpant&amp;amp;btnG=Google+Search&amp;amp;aq=1&amp;amp;oq="&gt;elephpant&lt;/a&gt; right there :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_3mx3vaA_Qok/SdM6VlcLwMI/AAAAAAAAACM/f906_MWwml8/s1600-h/php-april-fools-easter-egg.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 139px; height: 87px;" src="http://3.bp.blogspot.com/_3mx3vaA_Qok/SdM6VlcLwMI/AAAAAAAAACM/f906_MWwml8/s400/php-april-fools-easter-egg.png" alt="" id="BLOGGER_PHOTO_ID_5319659727356674242" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-707071365465380392?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/e_HxdgVkWSQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/707071365465380392/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/04/php-53-april-fools-easter-egg.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/707071365465380392?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/707071365465380392?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/e_HxdgVkWSQ/php-53-april-fools-easter-egg.html" title="PHP 5.3 April Fools Easter Egg" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_3mx3vaA_Qok/SdM6VlcLwMI/AAAAAAAAACM/f906_MWwml8/s72-c/php-april-fools-easter-egg.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/04/php-53-april-fools-easter-egg.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8BQn0zcSp7ImA9WxVbF0k.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-7689674618882066136</id><published>2009-03-28T23:55:00.009+02:00</published><updated>2009-04-03T11:54:13.389+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-03T11:54:13.389+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Komodo Edit" /><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="editors" /><category scheme="http://www.blogger.com/atom/ns#" term="themes" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>Komodo Edit dark theme</title><content type="html">For some time now, I developed some computer related eye fatigue, which kinda sucks and I believe this is related (in part) with the white background of my text editor(s). That's why I decided to try a dark theme in Komodo Edit. The one shipped with the editor is a bit ugly, I wanted something more like &lt;a href="http://jyte.com/cl/twilight-is-the-best-textmate-theme"&gt;Twilight for Textmate&lt;/a&gt; and any Google search for Komodo themes returned pretty much nothing. So, here's my creation, &lt;span style="font-style: italic;"&gt;inspired&lt;/span&gt; by all those dark themes out there, especially Twilight.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_3mx3vaA_Qok/Sc6e5BF_biI/AAAAAAAAABs/Ii0cs2BpMpI/s1600-h/twilight-php-syntax.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 299px;" src="http://4.bp.blogspot.com/_3mx3vaA_Qok/Sc6e5BF_biI/AAAAAAAAABs/Ii0cs2BpMpI/s400/twilight-php-syntax.png" alt="" id="BLOGGER_PHOTO_ID_5318362912354430498" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;If you like it, you can &lt;a href="http://github.com/igstan/komodo-themes/tree/master"&gt;grab the theme file from github&lt;/a&gt;. You don't need to know/use &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt;, there's a download button somewhere on that page.&lt;br /&gt;&lt;br /&gt;It only supports PHP and JavaScript syntax for the moment. More to come when I'll have some time. &lt;span style="font-weight: bold;"&gt;Update&lt;/span&gt;: There's Python and XML support right now.&lt;br /&gt;&lt;br /&gt;After you download it, put the .ksf file in your Komodo Edit application data folder, more precisely the &lt;span style="font-style: italic;"&gt;schemes&lt;/span&gt; directory. On my Windows machine this is: &lt;span style="font-style: italic;"&gt;C:\Documents and Settings\{user}\Application Data\ActiveState\KomodoEdit\4.3\schemes&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-7689674618882066136?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/a-0ZuoXVLKg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/7689674618882066136/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/03/komodo-edit-theme.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/7689674618882066136?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/7689674618882066136?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/a-0ZuoXVLKg/komodo-edit-theme.html" title="Komodo Edit dark theme" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_3mx3vaA_Qok/Sc6e5BF_biI/AAAAAAAAABs/Ii0cs2BpMpI/s72-c/twilight-php-syntax.png" height="72" width="72" /><thr:total>8</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/03/komodo-edit-theme.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04MRn05fCp7ImA9WxVbF0o.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-8907756923846555665</id><published>2009-03-20T16:55:00.016+02:00</published><updated>2009-04-03T18:19:47.324+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-03T18:19:47.324+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XHTML" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><category scheme="http://www.blogger.com/atom/ns#" term="Weird Stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="HTML" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>XHTML no matter what!</title><content type="html">&lt;p&gt;&lt;a href="http://metropotam.ro/"&gt;metropotam.ro&lt;/a&gt; changed their layout. Here's what XHTML obsession means (look after IE conditional comments):&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;base&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;href=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;http://metropotam.ro/&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="html1-comment"&gt;&amp;lt;!--[if IE]&amp;gt;&amp;lt;/base&amp;gt;&amp;lt;![endif]--&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;I simply cannot see the reason for such a useless hack. Too bad they forgot to do the same thing for &lt;code&gt;script&lt;/code&gt; tags. But I see the reason for the one below (again, look after IE conditional comments):&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;li&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;class=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;selected&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-comment"&gt;&amp;lt;!--[if lte IE 6]&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;![endif]--&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt; &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;ul&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;  ...&lt;br /&gt; &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/ul&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-comment"&gt;&amp;lt;!--[if lte IE 6]&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;![endif]--&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/li&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;But then again. What's this? (look after IE conditional comments):&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;li&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;a&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;href=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;http://metropotam.ro/Unde-iesim-index/&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;strong&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;Unde iesim&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/strong&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-comment"&gt;&amp;lt;!--[if gte IE 7]&amp;gt;&amp;lt;!--&amp;gt;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/a&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-comment"&gt;&amp;lt;!--&amp;lt;![endif]--&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Regardless of the above nitpicking though, I like the new layout.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-8907756923846555665?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/XNPtTv8q0G4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/8907756923846555665/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/03/xhtml-no-matter-what.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/8907756923846555665?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/8907756923846555665?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/XNPtTv8q0G4/xhtml-no-matter-what.html" title="XHTML no matter what!" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/03/xhtml-no-matter-what.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4BR3oyeSp7ImA9WxVUFUs.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-5326242720505432761</id><published>2009-03-18T11:40:00.006+02:00</published><updated>2009-03-20T17:29:16.491+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-20T17:29:16.491+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Exceptions" /><category scheme="http://www.blogger.com/atom/ns#" term="Good To Know" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>PHP's ErrorException class</title><content type="html">Did you know &lt;acronym title="PHP HyperText Preprocessor"&gt;PHP&lt;/acronym&gt; has an &lt;a href="http://www.php.net/manual/en/class.errorexception.php"&gt;&lt;code&gt;ErrorException&lt;/code&gt; class&lt;/a&gt; that solves the problem of throwing exceptions from an &lt;a href="http://www.php.net/manual/en/function.set-error-handler.php"&gt;error handler function&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;What problem?&lt;br /&gt;&lt;br /&gt;Well, if you throw a normal &lt;code&gt;Exception&lt;/code&gt; from such a handler, the file name and line number of the &lt;code&gt;Exception&lt;/code&gt; will be set to match the file and line where the &lt;code&gt;Exception&lt;/code&gt; was actually thrown and not the place where the error happened. There was no way to extend an Exception class and provide the correct information as &lt;code&gt;Exception&lt;/code&gt;'s &lt;code&gt;$file&lt;/code&gt; and &lt;code&gt;$line&lt;/code&gt; properties are private and there are no setter for them, only getters.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;ErrorException&lt;/code&gt; solves this problem by overriding the &lt;code&gt;Exception&lt;/code&gt; constructor, allowing us to pass up to five arguments. From these five arguments, four have the same meaning as the four arguments passed to the error handler function: &lt;code&gt;$errno&lt;/code&gt;, &lt;code&gt;$errstr&lt;/code&gt;, &lt;code&gt;$errfile&lt;/code&gt;, &lt;code&gt;$errline&lt;/code&gt;. By passing along these arguments to the &lt;code&gt;ErrorException&lt;/code&gt; constructor we get a more meaningful exception from our error handler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-5326242720505432761?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/l66EqHYKge0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/5326242720505432761/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/03/errorexception.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/5326242720505432761?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/5326242720505432761?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/l66EqHYKge0/errorexception.html" title="PHP's ErrorException class" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/03/errorexception.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4MRH88eSp7ImA9WxVUFUs.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-1608580044441681858</id><published>2009-02-16T23:37:00.008+02:00</published><updated>2009-03-20T17:29:45.171+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-20T17:29:45.171+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mozilla" /><category scheme="http://www.blogger.com/atom/ns#" term="Thunderbird" /><category scheme="http://www.blogger.com/atom/ns#" term="Good To Know" /><category scheme="http://www.blogger.com/atom/ns#" term="How to" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>Change default sort order in Mozilla Thunderbird</title><content type="html">I like email and feed messages ordered by date ascending in my Thunderbird, but its default settings are date descending. So I changed it like this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Go to: Tools -&gt; Options&lt;/li&gt;&lt;li&gt;Click "Config Editor..." button&lt;/li&gt;&lt;li&gt;Search for "sort"&lt;/li&gt;&lt;li&gt;Change value of &lt;span style="font-weight: bold;"&gt;mailnews.default_sort_order&lt;/span&gt; from 1 to &lt;span style="font-weight: bold;"&gt;2&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;In case you had no idea whether Thunderbird has an &lt;span style="font-weight: bold;"&gt;about:config&lt;/span&gt; capability like Firefox, now you know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-1608580044441681858?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/AIDtn3XmBEY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/1608580044441681858/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/02/how-to-change-sort-order-in-mozilla.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/1608580044441681858?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/1608580044441681858?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/AIDtn3XmBEY/how-to-change-sort-order-in-mozilla.html" title="Change default sort order in Mozilla Thunderbird" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/02/how-to-change-sort-order-in-mozilla.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMMRHo7eSp7ImA9WxVbGUo.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-30493451711038504</id><published>2009-02-13T10:37:00.013+02:00</published><updated>2009-04-06T01:28:05.401+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-06T01:28:05.401+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MySQL" /><category scheme="http://www.blogger.com/atom/ns#" term="Good To Know" /><category scheme="http://www.blogger.com/atom/ns#" term="transliteration" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>MySQL transliteration function</title><content type="html">In my latest project at work I had to obtain, by means of an &lt;abbr title="Structured Query Language"&gt;SQL&lt;/abbr&gt; query, &lt;a href="http://en.wikipedia.org/wiki/Transliteration"&gt;transliterated&lt;/a&gt; values of certain data fields in our database. And when I say transliteration I don't mean to transform characters from all over the world into latin characters. What I wanted was to strip &lt;a href="http://en.wikipedia.org/wiki/Diacritic"&gt;diacritics&lt;/a&gt; out of latin based characters, like: ş, ţ, ă, î or â.&lt;br /&gt;&lt;br /&gt;Initially I thought this should be an easy job as database, table and column charset values were all set to utf8_general_ci and I knew &lt;a href="http://www.mysql.com/"&gt;MySQL&lt;/a&gt; does well at comparing basic latin characters against derived ones. Well, it wasn't. Although the following query returns true (or 1), there's no way of querying MySQL for a transliterated value, i.e. from the right hand side string to obtain the left hand side string.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT 'staia' = 'şţăîâ';&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So what I did was to define a function in which to take advantage of the comparison feature in order to obtain &lt;a href="http://en.wikipedia.org/wiki/Transliteration"&gt;transliteration&lt;/a&gt;. What I came up with might end up on &lt;a href="http://thedailywtf.com/"&gt;thedailywtf.com&lt;/a&gt; but despite its apparent stupidity it does its job very well. So here's the function (or as a &lt;a href="http://gist.github.com/62005"&gt;gist on github&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="sql1-identifier"&gt;DELIMITER&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;$$&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DROP&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;FUNCTION&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;IF&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;EXISTS&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;`transliterate`&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;$$&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-reservedword"&gt;CREATE&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;FUNCTION&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;`transliterate`&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;(original&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;VARCHAR&lt;/span&gt;&lt;span class="sql1-symbol"&gt;(&lt;/span&gt;&lt;span class="sql1-number"&gt;128&lt;/span&gt;&lt;span class="sql1-symbol"&gt;))&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;RETURNS&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;VARCHAR&lt;/span&gt;&lt;span class="sql1-symbol"&gt;(&lt;/span&gt;&lt;span class="sql1-number"&gt;128&lt;/span&gt;&lt;span class="sql1-symbol"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-reservedword"&gt;BEGIN&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;  &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DECLARE&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;translit&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;VARCHAR&lt;/span&gt;&lt;span class="sql1-symbol"&gt;(&lt;/span&gt;&lt;span class="sql1-number"&gt;128&lt;/span&gt;&lt;span class="sql1-symbol"&gt;)&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DEFAULT&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;''&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;  &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DECLARE&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;len&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-identifier"&gt;INT(&lt;/span&gt;&lt;span class="sql1-number"&gt;3&lt;/span&gt;&lt;span class="sql1-symbol"&gt;)&lt;/span&gt;&lt;span class="sql1-space"&gt;       &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DEFAULT&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-number"&gt;0&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;  &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DECLARE&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;pos&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-identifier"&gt;INT(&lt;/span&gt;&lt;span class="sql1-number"&gt;3&lt;/span&gt;&lt;span class="sql1-symbol"&gt;)&lt;/span&gt;&lt;span class="sql1-space"&gt;       &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DEFAULT&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-number"&gt;1&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;  &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DECLARE&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt;   &lt;/span&gt;&lt;span class="sql1-identifier"&gt;CHAR(&lt;/span&gt;&lt;span class="sql1-number"&gt;1&lt;/span&gt;&lt;span class="sql1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;  &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;len&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;CHAR_LENGTH&lt;/span&gt;&lt;span class="sql1-symbol"&gt;(original);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;  &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHILE&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;(pos&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;len)&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;DO&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;    &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SUBSTRING&lt;/span&gt;&lt;span class="sql1-symbol"&gt;(original,&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;pos,&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-number"&gt;1&lt;/span&gt;&lt;span class="sql1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;    &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;CASE&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;TRUE&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'a'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'a'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'b'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'b'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'c'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'c'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'d'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'d'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'e'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'e'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'f'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'f'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'g'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'g'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'h'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'h'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'i'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'i'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'j'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'j'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'k'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'k'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'l'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'l'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'m'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'m'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'n'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'n'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'o'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'o'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'p'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'p'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'q'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'q'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'r'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'w'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'s'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'s'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'t'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'t'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'u'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'u'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'v'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'v'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'w'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'w'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'x'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'x'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'y'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'y'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;      &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'z'&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;THEN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-string"&gt;'z'&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;    &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;END&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;CASE&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;    &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;translit&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;CONCAT(translit,&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;letter);&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;    &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;SET&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;pos&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;=&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;pos&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;+&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-number"&gt;1&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;  &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;END&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;WHILE&lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-space"&gt;  &lt;/span&gt;&lt;span class="sql1-reservedword"&gt;RETURN&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;translit;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="sql1-reservedword"&gt;END&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-identifier"&gt;$$&lt;br /&gt;&lt;br /&gt;DELIMITER&lt;/span&gt;&lt;span class="sql1-space"&gt; &lt;/span&gt;&lt;span class="sql1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-30493451711038504?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/S4eQBBy3R0w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/30493451711038504/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/02/mysql-transliteration-function.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/30493451711038504?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/30493451711038504?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/S4eQBBy3R0w/mysql-transliteration-function.html" title="MySQL transliteration function" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/02/mysql-transliteration-function.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAARH45eCp7ImA9WxVaEEg.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-3828306042744919003</id><published>2009-01-11T01:05:00.019+02:00</published><updated>2009-04-07T00:35:45.020+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-07T00:35:45.020+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Ajax file upload" /><category scheme="http://www.blogger.com/atom/ns#" term="Ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><category scheme="http://www.blogger.com/atom/ns#" term="Articles" /><title>Ajax file upload with pure JavaScript</title><content type="html">I don't know about you, but there's one little thing I've always hated about Ajax. The impossibility of file uploading. I still remember the ugly day when I discovered the terrible truth. There was no chance on earth you could send a file using an XML HTTP request, thus workarounds appeared. Google made use of a hidden iframe to imitate such an asynchronous call for their Gmail service, and later on, Flash based uploaders appeared. Things are though going forward.&lt;br /&gt;Firefox 3 introduced a new API, that few people know about, which allows JavaScript to read local files selected by an user from a form file-upload dialog. A copy of Firefox 3 with default settings offers full access to this new programming interface. So we'll embrace the challenge and write a little JavaScript uploader on top of this new API.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://amenthes.110mb.com/code-samples.zip"&gt;You may download the final script right now&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Goal&lt;/h4&gt;In this tutorial we'll write a little application that is able to read and upload local files to a remote web server using an asynchronous HTTP request. The whole application consists of three parts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;     the client side comprised of JavaScript, HTML and a little CSS&lt;/li&gt;&lt;li&gt;     the server side script, written in PHP&lt;/li&gt;&lt;li&gt;     the communication channel in between them, old good HTTP&lt;/li&gt;&lt;/ul&gt;We'll start with the JavaScript side, as I'm sure you're eager to find about the new file access API, then we'll review the XMLHttpRequest object as available in Firefox version 3 (it got enhanced with a new method). After the client-side part follows explanations for the server-side script, written in PHP, continued with a little summary over the HTTP protocol concerning data transmission and HTML forms. Finally, we'll put all these together to build a powerful asynchronous file uploader.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;The Firefox file upload API&lt;/h4&gt;When Firefox 3 has been launched in June this year, we heard a lot about the improvements it brought to the web development field by further implementing existing standards and technologies like HTML, CSS and JavaScript. One thing I have never seen mentioned was the interface for reading local files, provided the file is chosen by the user through an HTML file input element. For example, a simple Google search for getAsBinary, one of the new methods in the API, will give you few results, even when counting the false positives (such a false positive is related to ColdFusion which has a similar method name, and results comprising information about it are preponderant). That surprises me a lot as, in my opinion, it is a huge step forward in building more powerful web applications. Actually, there is &lt;a href="http://soakedandsoaped.com/articles/read/firefox-3-native-ajax-file-upload"&gt;someone&lt;/a&gt; that wrote about it in May 2008. Alas the news hasn't spread.&lt;br /&gt;With this new API, each input element (not only file input elements), is given a property called files. This property is our gateway to reading local files. When the type attribute of the input element isn't file, the value of the files property is null. On the other hand, for input elements whose type attribute is file, the files property is of type FileList and resembles a NodeList object returned by, let's say, document.getElementsByTagName(). You may access it as if it were an Array and has the following properties and methods:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;  length&lt;/li&gt;&lt;li&gt;  item(index)&lt;/li&gt;&lt;/ul&gt;Each element in the files property is a File element that exposes the following properties and methods:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;  fileName&lt;/li&gt;&lt;li&gt;  fileSize&lt;/li&gt;&lt;li&gt;  getAsBinary()&lt;/li&gt;&lt;li&gt;  getAsText(encoding)&lt;/li&gt;&lt;li&gt;  getAsDataURL()&lt;/li&gt;&lt;/ul&gt;Those two lists above are all there is to know about the API for reading local files. There is nothing more about it. No security restrictions, no special configurations.&lt;br /&gt;As I'm sure the files property itself poses no problem in understanding its interface let's review the contained file objects with a little script. You may want to download https://addons.mozilla.org/en-US/firefox/addon/1843 Firebug in order to get a through understanding of the following exploration. Here's the code that we'll use:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;!DOCTYPE&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;HTML&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;PUBLIC&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;&amp;quot;-//W3C//DTD&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;HTML&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;4.01//EN&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-space"&gt;     &lt;/span&gt;&lt;span class="html1-identifier"&gt;&amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;html&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;head&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;title&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;JavaScript file upload&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/title&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;meta&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;http-equiv&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;content-type&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;content&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;text/html; charset=UTF-8&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;upload&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;return&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;false&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/head&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;body&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;form&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;action&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;method&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;onsubmit&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;return upload();&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;fieldset&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;legend&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;Upload photo&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/legend&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;input&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;type&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;file&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;name&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;id&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;input&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;type&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;value&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;Upload&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/fieldset&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/form&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/body&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/html&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The fileName property gives us the name of the picked up file, but not the absolute path on the filesystem, just the basename. Modify the above source code above so that the JavaScript part now becomes:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;upload&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// the file is the first element in the files property&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-space"&gt;  &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;files&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;];&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;File name: &amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fileName&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;return&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;false&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The fileSize property returns, as you may have guessed, the size of the file in bytes:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;upload&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// the file is the first element in the files property&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-space"&gt;  &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;files&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;];&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;File name: &amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fileName&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;File name: &amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fileSize&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;return&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;false&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The getAsBinary() method will read the contents of the file and return them in binary representation. If you select a binary file, an image for example, you should see some weird characters, question marks or even rectangles in the alert, this is how Firefox represents the bytes contained in the file. For a text file it will simply output its text.&lt;br /&gt;&lt;br /&gt;The getAsText(encoding) method will return the contents as a string of bytes encoded depending on the encoding parameter. This is by default UTF-8, but the encoding parameter it's not really optional. You still have to pass some value. An empty string will do it just fine:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;upload&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// the file is the first element in the files property&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-space"&gt;  &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;files&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;];&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;File name: &amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fileName&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;File size: &amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fileSize&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;Binary content: &amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getAsBinary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;());&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;Text content: &amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getAsText&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;));&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// or&lt;br /&gt;// alert(&amp;quot;Text content: &amp;quot; + file.getAsText(&amp;quot;utf8&amp;quot;));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;return&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;false&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Finally, the getAsDataURL() method, a very interesting and very useful one, will return the file contents in a format ideally suited for, let's say, the src attribute of an IMG tag. Of course, this will work as we're in Firefox right now, so let's add a IMG tag to the HTML source and the appropriate JavaScript code to make this work:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;!DOCTYPE&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;HTML&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;PUBLIC&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;&amp;quot;-//W3C//DTD&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;HTML&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;4.01//EN&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-space"&gt;     &lt;/span&gt;&lt;span class="html1-identifier"&gt;&amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;html&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;head&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;title&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;JavaScript file upload&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/title&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;meta&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;http-equiv&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;content-type&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;content&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;text/html; charset=UTF-8&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;upload&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// the file is the first element in the files property&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-space"&gt;  &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;files&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;];&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// alert(&amp;quot;File name: &amp;quot; + file.fileName);&lt;br /&gt;// alert(&amp;quot;File size: &amp;quot; + file.fileSize);&lt;br /&gt;// alert(&amp;quot;Binary content: &amp;quot; + file.getAsBinary());&lt;br /&gt;// alert(&amp;quot;Text content: &amp;quot; + file.getAsText(&amp;quot;&amp;quot;));&lt;br /&gt;// or&lt;br /&gt;// alert(&amp;quot;Text content: &amp;quot; + file.getAsText(&amp;quot;utf8&amp;quot;));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;preview&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;preview&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;preview&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;src&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getAsDataURL&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;();&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;return&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;false&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class="multi1-marker3"&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/head&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;body&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;form&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;action&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;method&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;onsubmit&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;return upload();&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;fieldset&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;legend&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;Upload photo&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/legend&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;input&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;type&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;file&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;name&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;id&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;input&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;type&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;value&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;Upload&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;hr&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;img&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;src&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;alt&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;Image preview&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;id&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;preview&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/fieldset&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/form&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/body&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/html&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;More information about the new API can be found on their dedicated pages on Mozilla Developer Center:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;  &lt;a href="https://developer.mozilla.org/en/nsIDOMFileList"&gt;https://developer.mozilla.org/en/nsIDOMFileList&lt;/a&gt;&lt;/li&gt;&lt;li&gt;  &lt;a href="https://developer.mozilla.org/en/nsIDOMFile"&gt;https://developer.mozilla.org/en/nsIDOMFile&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Some extra information&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You may wonder why an array of files for just one input element. It turns out that &lt;a href="http://www.faqs.org/rfcs/rfc1867.html"&gt;RFC 1867&lt;/a&gt;, concerning form-based file uploads, specifies that a file input element allows its size attribute to receive a complex value:&lt;br /&gt;&lt;blockquote&gt;The SIZE attribute might be specified using SIZE=width,height,&lt;br /&gt;where width is some default for file name width, while height is&lt;br /&gt;the expected size showing the list of selected files.  For example,&lt;br /&gt;this would be useful for forms designers who expect to get several&lt;br /&gt;files and who would like to show a multiline file input field in&lt;br /&gt;the browser (with a "browse" button beside it, hopefully).  It&lt;br /&gt;would be useful to show a one line text field when no height is&lt;br /&gt;specified (when the forms designer expects one file, only) and to&lt;br /&gt;show a multiline text area with scrollbars when the height is&lt;br /&gt;greater than 1 (when the forms designer expects multiple files).&lt;br /&gt;&lt;/blockquote&gt;None of the browsers I tested this in seems to obey the RFC, nevertheless this should be the reason for which the files property is an array-like object.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;The XMLHttpRequest object&lt;/h4&gt;Now that we're able to read local files, we need a way to get this data, over the network, to the server. As we're aiming for an asynchronous data transmission, an XMLHttpRequest object should do the job just fine. Unfortunately, its send() method isn't that reliable in sending binary data. For this reason, along with the local file access interface, Firefox 3 brought a new method to the XMLHttpRequest object: sendAsBinary(data). Just as the send() method, the new one takes a single argument, a string, which is converted to a string of single-byte characters by truncation (removing the high-order byte of each character), according to the &lt;a href="https://developer.mozilla.org/en/XMLHttpRequest#sendAsBinary%28%29"&gt;documentation&lt;/a&gt;. The difference, a very important one, is that, as long as send() knows how to process an URL query string, sendAsBinary() expects a totally different format in order to be useful for the server-side end of the application, but we'll talk about this a little bit later. Let's just write a little JavaScript skeleton, that we'll use when assembling together all the pieces of the application:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;new&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;onreadystatechange&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;if&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;readyState&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;===&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-number"&gt;4&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;responseText&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;sendAsBinary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As you see, there's an undefined variable in the above snippet, data, which remains to be defined after we review the mechanism behind files upload over HTTP. For the moment though, I want to talk about the server-side part, as it will guide us in choosing the appropriate strategy for sending binary information.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;The server-side script&lt;/h4&gt;PHP, as well as several web frameworks made on top of other languages, offers different access points for reading POST data containing uploaded files and POST data containing just simple values. In PHP there are two predefined arrays giving you access to simple POST data, the $_POST array, and another one for accessing files sent to the server, the $_FILES array. It is thus wise to build a client-side script able to send information that PHP would read as from a classical request issued with an HTML form: our uploaded files would appear as elements inside the $_FILES array and additional values as elements inside the $_POST array. Under these circumstances we can write the PHP script to test that our JavaScript client is performing well:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;print_r(&lt;/span&gt;&lt;span class="php1-variable"&gt;$_FILES&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;print_r(&lt;/span&gt;&lt;span class="php1-variable"&gt;$_POST&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That's all we need on the server. Although simple this we'll give us valuable feedback about the sent data. The PHP script should list our uploaded files inside the $_FILES array and any additional form data (like text INPUT or SELECT element) inside the $_POST array.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Form data over HTTP theory&lt;/h4&gt;As we saw, PHP treats POST-ed files differently than ordinary form field values, so it's only natural to ask ourselves what's the "clue" that helps PHP tell apart one from the other.&lt;br /&gt;First of all, every HTML form element out there has an optional attribute called enctype, with a default value of application/x-www-form-urlencoded. This is actually a MIME type value specifying the encoding to be used by the web browser when sending form data. It also guides the web server script in decoding that data as the encoding is sent by the browser to the server in the form of an HTTP header, called Content-Type.&lt;br /&gt;For a default enctype value, form data is sent as ASCII characters, URL encoded when necessary. On the other hand, when uploading files, we need to change the enconding to multipart/form-data. Cloning this basic form functionality inside our JavaScript client is what we should do. Let's modify the earlier script so that it sends such a multipart/form-data header:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;new&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;onreadystatechange&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;if&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;readyState&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;===&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-number"&gt;4&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;responseText&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;setRequestHeader&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;multipart/form-data&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;sendAsBinary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;RFC 1867, regarding form-based file uploads, dictates that an extra parameter is required for the Content-Type header when its value is multipart/form-data. It is called boundary and its presence it's very logical. The multipart word inside the header means the sent request is formed of multiple parts (obviously), so there must be something to separate those parts. This thing is the boundary parameter which value must be a string of characters that shouldn't be found inside any of the form values we send, otherwise the request will get garbled. Once again, let's modify the script to reflect this requirement.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;new&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;onreadystatechange&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;if&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;readyState&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;===&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-number"&gt;4&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;responseText&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;/*&lt;br /&gt;* The value of the boundary doesn't matter as long as no other&lt;br /&gt;* structure in the request contains such a sequence of characters.&lt;br /&gt;* We chose, nevertheless, a pseudo-random value based on the current&lt;br /&gt;* timestamp of the browser.&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;AJAX--------------&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;new&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;Date&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;).&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getTime&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;contentType&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;multipart/form-data; boundary=&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;setRequestHeader&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;contentType&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;sendAsBinary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Next, let's talk about the structure of the parts comprised in the request. Each of these is like a little request on its own. Each has its own headers structure and body.&lt;br /&gt;The mandatory header, every part must have, is called Content-Disposition and its value should be form-data followed by an additional parameter called name, which represents the name of the form input that holds the data. In case of parts holding uploaded files, a second parameter must also be present, called filename. This is the name of the file as it was on the user's computer. Not the absolute path, just the basename (for example, monkey.png). Parameter values are enclosed inside double quotes. A little example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-identifier"&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Disposition&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;filename&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;monkey.png&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In the case of files, a second header must is also needed. It is called Content-Type and specifies the MIME type of the file. This may be deduced by reading the file extension or the source of the file. Anyway, a general value of application/octet-stream is perfectly acceptable:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-identifier"&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Disposition&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;filename&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;monkey.png&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;image&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;png&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As per the &lt;a href="http://www.faqs.org/rfcs/rfc822.html"&gt;standards&lt;/a&gt;, every such header should end with two characters, a carriage return and a new line: CR and LF. The last header doubles this sequence (i.e. it ends with CRLFCRLF).&lt;br /&gt;Following the headers is the body which consists of the form field value. I'll illustrate with a simple text file upload, although it could be any type of file. The text inside the file is "my random notes about web programming":&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-identifier"&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Disposition&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;notes&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;filename&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;my_notes.txt&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;text&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;plain&lt;br /&gt;&lt;br /&gt;my&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;random&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;notes&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;about&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;web&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;programming&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Finally I'll give you a final example with both the HTML markup of the form as well as a fictional request from that form:&lt;br /&gt;&lt;br /&gt;The form:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;form&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;action&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;upload.php&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;method&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;enctype&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;multipart/form-data&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;fieldset&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;legend&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;Upload photo&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/legend&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;label&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;for&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;image_name&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;Image name:&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/label&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;input&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;type&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;name&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;image_name&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;id&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;image_name&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;select&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;name&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;image_type&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;       &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;option&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;Family&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/option&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;       &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;option&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;Work&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/option&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;       &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;option&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="html1-text"&gt;Vacation&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/option&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/select&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;input&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;type&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;file&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;name&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;id&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="html1-text"&gt;   &lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;input&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;type&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class="html1-space"&gt; &lt;/span&gt;&lt;span class="html1-identifier"&gt;value&lt;/span&gt;&lt;span class="html1-symbol"&gt;=&lt;/span&gt;&lt;span class="html1-value"&gt;&amp;quot;Upload&amp;quot;&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/div&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html1-reservedword"&gt;/form&lt;/span&gt;&lt;span class="html1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The issued request could be:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-identifier"&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;multipart&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;/&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;RANDOM_STRING_BOUNDARY&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;--&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;RANDOM_STRING_BOUNDARY&lt;br /&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Disposition&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image_name&amp;quot;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Monkey&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;--&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;RANDOM_STRING_BOUNDARY&lt;br /&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Disposition&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image_type&amp;quot;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Vacation&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;--&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;RANDOM_STRING_BOUNDARY&lt;br /&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Disposition&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;filename&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;monkey.png&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;image&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;png&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;here&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;would&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;be&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;the&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;png&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;file&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;in&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;binary&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;]&lt;br /&gt;--&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;RANDOM_STRING_BOUNDARY&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;--&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In case you didn't noticed, the boundary, when used in between the parts is prepended with two hyphens and the last one appended with also two hyphens. Don't forget about this, it's an ugly source of bugs.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Encapsulating the JavaScript logic&lt;/h4&gt;At this point we know all the parts to successfully build a pure JavaScript file uploader, which we're going to implement as an object. Here's the basic structure of the constructor and its prototype:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt;* @param DOMNode form&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Uploader&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;this&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Uploader&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;prototype&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt;* @param Object HTTP headers to send to the server, the key is the&lt;br /&gt;* header name, the value is the header value&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;headers&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{},&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt;* @return Array of DOMNode elements&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;get&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;elements&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{},&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt;* @return String A random string&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;generateBoundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{},&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt;* Constructs the message as discussed in the section about form&lt;br /&gt;* data transmission over HTTP.&lt;br /&gt;*&lt;br /&gt;* @param  Array  elements&lt;br /&gt;* @param  String boundary&lt;br /&gt;* @return String&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;buildMessage&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;elements&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{},&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt;* @return null&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;send&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{}&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In case you didn't understand the elements() construct, this is called a getter and is supported by the latest versions of Firefox, Opera, Safari and Chrome. A setter form is also provided. You can find more about these on &lt;a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters"&gt;Mozilla Developer Center&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;We should fill the above methods, so let's start with the send() method because we already wrote much of it in a previous sections of the tutorial:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt;* @return null&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;send&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;this&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;generateBoundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;new&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;open&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;this&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;action&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;true&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;onreadystatechange&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;if&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;readyState&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;===&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-number"&gt;4&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;alert&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;responseText&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;contentType&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;multipart/form-data; boundary=&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;setRequestHeader&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;contentType&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;for&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;header&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;in&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;this&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;headers&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;setRequestHeader&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;header&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;headers&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;header&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// here's our data variable that we talked about earlier&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;this&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;buildMessage&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;this&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;elements&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// finally send the request as binary data&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;xhr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;sendAsBinary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;data&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In addition to what we had earlier we have now introduced an iteration that allows us to send additional headers without modifying the prototype itself. We have also defined the variable we talked about earlier, data, which holds the source of the HTTP request. It holds the value returned by a call to a method whose only purpose is to build an HTTP compliant request for file uploads. Here's its source:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt;* @param Array elements&lt;br /&gt;* @param String boundary&lt;br /&gt;* @return String&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;buildMessage&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;elements&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-space"&gt;  &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;parts&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[];&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;elements&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;forEach&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;index&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;all&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;TEXT&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;if&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;nodeName&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;toUpperCase&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;===&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;INPUT&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getAttribute&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;).&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;toUpperCase&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;if&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;===&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;FILE&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;files&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;length&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fieldName&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fileName&lt;/span&gt;&lt;span class="jscript1-space"&gt;  &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;files&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;].&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fileName&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-comment"&gt;/*&lt;br /&gt;            * Content-Disposition header contains name of the field&lt;br /&gt;            * used to upload the file and also the name of the file as&lt;br /&gt;            * it was on the user's computer.&lt;br /&gt;            */&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;'Content-Disposition: form-data; '&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;'name=&amp;quot;'&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fieldName&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;'&amp;quot;; '&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;'filename=&amp;quot;'&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fileName&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;'&amp;quot;'&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-comment"&gt;/*&lt;br /&gt;            * Content-Type header contains the mime-type of the file&lt;br /&gt;            * to send. Although we could build a map of mime-types&lt;br /&gt;            * that match certain file extensions, we'll take the easy&lt;br /&gt;            * approach and send a general binary header:&lt;br /&gt;            *      application/octet-stream&lt;br /&gt;            */&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;Content-Type: application/octet-stream&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-comment"&gt;// marks end of the headers part&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-comment"&gt;/*&lt;br /&gt;            * File contents read as binary data, obviously&lt;br /&gt;            */&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;files&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;].&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getAsBinary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;}&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;else&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-comment"&gt;/*&lt;br /&gt;            * In case of non-files fields, Content-Disposition&lt;br /&gt;            * contains only the name of the field holding the data.&lt;br /&gt;            */&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;'Content-Disposition: form-data; '&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;'name=&amp;quot;'&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;'&amp;quot;'&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-comment"&gt;/*&lt;br /&gt;            * Field value&lt;br /&gt;            */&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;           &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;element&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;value&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;parts&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;push&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;part&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;});&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;request&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;--&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;        &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;request&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;parts&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;join&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;--&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;        &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;request&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;--&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;boundary&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;--&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;CRLF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;return&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;request&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Although it looks complex, it has a fair amount of comments so that you won't have hard times understanding what it does. It simply iterates over an array of HTML elements and for each such an element constructs a different message depending whether the element is a file upload input or not. It pushes this message into an internal array, which is finally joined using the boundary sent as an argument inside the send() method.&lt;br /&gt;&lt;br /&gt;Here follows the source of the elements() getter, used in send():&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt; * @return Array&lt;br /&gt; */&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;get&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;elements&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fields&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[];&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// gather INPUT elements&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;inputs&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;this&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;INPUT&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;for&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;l&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;inputs&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;length&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;i&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;i&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fields&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;push&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;inputs&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;i&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-comment"&gt;// gather SELECT elements&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;selects&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;this&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;SELECT&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;for&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;l&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;selects&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;length&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;i&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;i&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fields&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;push&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;selects&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;i&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;return&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fields&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The snippet above grabs all the INPUT and SELECT elements inside the FORM element associated with the Uploader object. These elements are eventually returned into a unified array. There are, however no checks on these elements, like filtering disabled controls. Furthermore, the RFC specifies that a client should send form data in the same order it was rendered in the user agent. For keeping the examples as short as I could, the method above doesn't take care of that, but the code inside the accompanying archive does.&lt;br /&gt;&lt;br /&gt;The final piece of code left for presentation is the generateBoundary() method which must return a string unique in the body of our request. For our simple example though, the method below should be just fine:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-comment"&gt;/**&lt;br /&gt; * @return String&lt;br /&gt; */&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;generateBoundary&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;return&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;AJAX-----------------------&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;+&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;new&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;Date&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;).&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getTime&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The code inside is building a string based on the current timestamp to which some other characters are prepended. I'm using the uppercased word AJAX and some dashes, but this prefix isn't mandatory, the only condition that must be met is that the result of generateBoudary() should not appear anywhere else in out request except for the boundary placeholders.&lt;br /&gt;&lt;br /&gt;Finally, the headers property of our object remains like it was in the skeleton. It is there so that you can append additional headers to the request, for example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;upl&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;new&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Uploader&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;upl&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;headers&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;X-Requested-With&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;]&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;XMLHttpRequest&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Save the source of the Uploader object in a file called uploader.js, we'll use it in a few moments.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Putting it all together&lt;/h4&gt;Let's now write the final HTML source and save it inside a file called index.html. Aside the markup, the code below introduces some event listeners for the Upload and Preview button:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;DOCTYPE&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;HTML&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;PUBLIC&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;     &lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;html&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;head&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;title&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;title&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;meta&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;http&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;equiv&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;content-type&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;text/html; charset=UTF-8&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;meta&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;http&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;equiv&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;imagetoolbar&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;meta&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;http&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;-&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;equiv&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;imagetoolbar&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;content&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;no&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;link&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;rel&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;href&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;css/default.css&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;script&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;src&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;uploader.js&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;script&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;script&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;window&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;addEventListener&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;load&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-comment"&gt;// handle image preview&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;input&lt;/span&gt;&lt;span class="jscript1-space"&gt;      &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;img&lt;/span&gt;&lt;span class="jscript1-space"&gt;        &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;img&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;previewBtn&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;preview&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;previewBtn&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;addEventListener&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;img&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;src&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;input&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;files&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;[&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;].&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getAsDataURL&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;},&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;false&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-comment"&gt;// handle file upload&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-space"&gt;      &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;form&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;)[&lt;/span&gt;&lt;span class="jscript1-number"&gt;0&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;uploader&lt;/span&gt;&lt;span class="jscript1-space"&gt;  &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;new&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Uploader&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;var&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;uploadBtn&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;document&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;getElementById&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;upload&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;uploadBtn&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;addEventListener&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;(&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;,&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;function&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;()&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;uploader&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;.&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;send&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;    &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;},&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;false&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;},&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;false&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;script&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;head&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;body&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;action&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;upload.php&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;method&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;post&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;enctype&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;multipart/form-data&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;onsubmit&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;return false;&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fieldset&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;legend&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;Upload&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;photo&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;legend&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;label&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;for&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image_name&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;Image&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;label&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;input&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image_name&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;id&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image_name&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;|&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;label&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-reservedword"&gt;for&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image_type&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;Image&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;:&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;label&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;select&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image_type&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;id&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image_type&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;option&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;JPEG&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;option&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;option&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;PNG&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;option&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;       &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;option&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;GIF&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;option&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;select&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;|&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;input&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;file&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;name&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;id&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;input&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;value&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;Upload&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;id&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;upload&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;input&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;type&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;value&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;Preview&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;id&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;preview&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;hr&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="jscript1-space"&gt;   &lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;lt;&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;img&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;src&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;alt&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;image preview&amp;quot;&lt;/span&gt;&lt;span class="jscript1-space"&gt; &lt;/span&gt;&lt;span class="jscript1-identifier"&gt;id&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;=&lt;/span&gt;&lt;span class="jscript1-string"&gt;&amp;quot;img&amp;quot;&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;fieldset&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;form&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-non-reservedkeyword"&gt;body&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span class="jscript1-identifier"&gt;html&lt;/span&gt;&lt;span class="jscript1-symbol"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now create another file, save it as upload.php, and write inside it the code we presented in the server-side section of the tutorial:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;print_r(&lt;/span&gt;&lt;span class="php1-variable"&gt;$_FILES&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;print_r(&lt;/span&gt;&lt;span class="php1-variable"&gt;$_POST&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That's all. You may now test the application, which will hopefully work from the first run. Don't forget to install Firebug to inspect what's happening behind the scenes.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;There's probably a lot to be discussed around this new feature Mozilla introduced along with Firefox 3. Some may wonder if it is worth using it. Well, as ever, it depends on what you want to accomplish. You may employ fall back techniques (like the iframe workaround) in order to have support for other browsers, if that is your concern. If you want a fancy UI though, a Flash based uploader may be better. But don't forget, the new API is not all about uploading. You may now read local files and process them right there in the browser. You may resize images, parse XML or do whatever your imagination limits are. In my opinion this is a huge step forward for web development and I'd really like other browser vendors to implement this API as http://www.w3.org/TR/file-upload/ the standards seem to be abandoned. Rich Internet applications would be far more powerful and their responsiveness further increased.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-3828306042744919003?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/pIdY3Yj5I9Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/3828306042744919003/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html#comment-form" title="22 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/3828306042744919003?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/3828306042744919003?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/pIdY3Yj5I9Q/pure-javascript-file-upload.html" title="Ajax file upload with pure JavaScript" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>22</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcHR3c4eCp7ImA9WxVUFUs.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-2268926105600682238</id><published>2009-01-05T23:10:00.009+02:00</published><updated>2009-03-20T17:30:36.930+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-20T17:30:36.930+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Open Source" /><category scheme="http://www.blogger.com/atom/ns#" term="PHPUnit" /><category scheme="http://www.blogger.com/atom/ns#" term="Contributions" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>My first contribution to an open source project</title><content type="html">Two weeks ago, while writing some unit tests for one of my projects I wanted to use an &lt;a href="http://www.phpunit.de/manual/current/en/appendixes.configuration.html#appendixes.configuration.phpunit"&gt;XML configuration file&lt;/a&gt; in order to bootstrap the &lt;a href="http://www.phpunit.de/"&gt;PHPUnit testing framework.&lt;/a&gt; As you may know, in PHPUnit you may organize your unit tests in test suites, and also give them names. So, for better organizing my tests, I wanted five directories holding five different test suites which I thought could be easily configured inside the phpunit.xml file. Well, apparently there was support for only one test suite and a &lt;a href="http://www.phpunit.de/ticket/623"&gt;ticket opened&lt;/a&gt; for such an addition to the framework. As a result I hacked a little bit the source code and came up with a &lt;a href="http://www.phpunit.de/ticket/623#comment:2"&gt;simple patch&lt;/a&gt; (really, there is nothing fancy about it) so that now the config file accepts multiple test suites.&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://sebastian-bergmann.de/"&gt;Sebastian Bergmann&lt;/a&gt; the &lt;a href="http://www.phpunit.de/changeset/4423"&gt;patch got accepted&lt;/a&gt; and it will be available with PHPUnit 3.4&lt;br /&gt;&lt;br /&gt;For many (web) developers out there this might be something really, really trivial and they're right, but this is my first contribution to an open source project and I'm happy about it. Some time ago, reading a &lt;a href="http://artfulco.de/post/45-planuri-de-viitor"&gt;blog post of Andrei Maxim&lt;/a&gt; (a fellow web developer and citizen) I got inspired and said to myself that I should too contribute some code to an open source project (he wanted a commit though, not a patch). Well, this was my first step. More to come... I hope.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-2268926105600682238?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/aBMnxc2yztk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/2268926105600682238/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2009/01/my-first-contribution-to-open-source.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/2268926105600682238?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/2268926105600682238?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/aBMnxc2yztk/my-first-contribution-to-open-source.html" title="My first contribution to an open source project" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.igstan.ro/2009/01/my-first-contribution-to-open-source.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUESXk4eyp7ImA9WxVbGEo.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-9065132051946239117</id><published>2008-12-20T14:35:00.033+02:00</published><updated>2009-04-04T23:50:08.733+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-04T23:50:08.733+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Good To Know" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>How not to use dates in PHP</title><content type="html">How many times did you find yourself using basic arithmetic operations to make a range of UNIX timestamps, given that you know the ends of the interval? I'm talking about something like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;date_default_timezone_set(&lt;/span&gt;&lt;span class="php1-string"&gt;'Europe/Bucharest'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$start&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;strtotime(&lt;/span&gt;&lt;span class="php1-string"&gt;'01 October 2008'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$end&lt;/span&gt;&lt;span class="php1-space"&gt;   &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;strtotime(&lt;/span&gt;&lt;span class="php1-string"&gt;'01 November 2008'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$start&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;while&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;(&lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$end&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;date(&lt;/span&gt;&lt;span class="php1-string"&gt;'Y M d'&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-string"&gt;'&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;+=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-number"&gt;60&lt;/span&gt;&lt;span class="php1-symbol"&gt;*&lt;/span&gt;&lt;span class="php1-number"&gt;60&lt;/span&gt;&lt;span class="php1-symbol"&gt;*&lt;/span&gt;&lt;span class="php1-number"&gt;24&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you run the above little script you might be surprised to see that October 26th appears twice, one after the other.&lt;br /&gt;&lt;br /&gt;If you're not aware of &lt;span style="font-weight: bold;"&gt;Daylight Saving Time&lt;/span&gt; you may have hard times understanding what's happening behind the scenes and solving the problem. In the above snippet I started the script by specifying that &lt;acronym title="PHP Hypertext Preprocessor"&gt;PHP&lt;/acronym&gt;'s all date/time functions should use Bucharest's timezone. That means that my &lt;a href="http://www.php.net/manual/en/function.date.php"&gt;date()&lt;/a&gt; call in the for loop would know that October 26th, 2008 is officially marked as the end of Daylight Saving Time for Bucharest (as well as whole Europe). In that day 04:00 &lt;acronym title="Ante Meridiem"&gt;AM&lt;/acronym&gt; became 03:00 &lt;acronym title="Ante Meridiem"&gt;AM&lt;/acronym&gt;, "rewinding" time one hour and passing from &lt;acronym title="Eastern European Summer Time"&gt;EEST&lt;/acronym&gt; to &lt;acronym title="Eastern European Time"&gt;EET&lt;/acronym&gt;.&lt;br /&gt;&lt;br /&gt;So how can only one hour duplicate a day? Well, by observing &lt;acronym title="Daylight Saving Time"&gt;DST&lt;/acronym&gt;, one day in year gets one hour longer, while another day gets one hour shorter. October 26th, 2008 is the day that got one hour longer, counting a total of 25 hours, while our script is adding 24 hours for each iteration. That's why, when the counter is supposed to return a UNIX timestamp for October 27th, 2008 it actually returns the timestamp for October 26, 2008 &lt;span style="font-weight: bold;"&gt;23:00:00&lt;/span&gt;, because now it's one hour behind &lt;acronym title="Daylight Saving Time"&gt;DST&lt;/acronym&gt;. Here's a modified script to show exactly this transition:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;date_default_timezone_set(&lt;/span&gt;&lt;span class="php1-string"&gt;'Europe/Bucharest'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$start&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;strtotime(&lt;/span&gt;&lt;span class="php1-string"&gt;'01 October 2008'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$end&lt;/span&gt;&lt;span class="php1-space"&gt;   &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;strtotime(&lt;/span&gt;&lt;span class="php1-string"&gt;'01 November 2008'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$start&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;while&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;(&lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$end&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-string"&gt;' '&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;date(&lt;/span&gt;&lt;span class="php1-string"&gt;'Y M d H:i:s'&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-string"&gt;'&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;+=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-number"&gt;60&lt;/span&gt;&lt;span class="php1-symbol"&gt;*&lt;/span&gt;&lt;span class="php1-number"&gt;60&lt;/span&gt;&lt;span class="php1-symbol"&gt;*&lt;/span&gt;&lt;span class="php1-number"&gt;24&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;'&amp;lt;hr&amp;gt;'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$hours_in_26&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;(strtotime(&lt;/span&gt;&lt;span class="php1-string"&gt;'27 October 2008'&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;-&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;strtotime(&lt;/span&gt;&lt;span class="php1-string"&gt;'26 October 2008'&lt;/span&gt;&lt;span class="php1-symbol"&gt;));&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$hours_in_26&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$hours_in_26&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;/&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-number"&gt;60&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;/&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-number"&gt;60&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-string"&gt;&amp;quot;October 26th, has &lt;/span&gt;&lt;span class="php1-variable"&gt;$hours_in_26&lt;/span&gt;&lt;span class="php1-string"&gt; hours when observing DST.&amp;quot;&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I've also made a little diagram to highlight the problem. On the left hand side is the way &lt;a href="http://www.php.net/manual/en/function.date.php"&gt;date()&lt;/a&gt; function works when we've set a timezone value. On the right hand side is the way our script works, by treating all days as having only 24 hours. The green rectangle is that one hour difference between our script and &lt;a href="http://www.php.net/manual/en/function.date.php"&gt;date()&lt;/a&gt;. The red hours is when &lt;acronym title="Daylight Saving Time"&gt;DST&lt;/acronym&gt; ends.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3mx3vaA_Qok/SU0GJM2p69I/AAAAAAAAAAU/1mTzD86N12M/s1600-h/dst.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 190px; height: 400px;" src="http://1.bp.blogspot.com/_3mx3vaA_Qok/SU0GJM2p69I/AAAAAAAAAAU/1mTzD86N12M/s400/dst.png" alt="" id="BLOGGER_PHOTO_ID_5281884693114514386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Now that we know the problem we should fix it and the most simple solution is to change the timezone. Instead of Europe/Bucharest I could have been used &lt;acronym title="Greenwich Mean Time"&gt;GMT&lt;/acronym&gt; and the above script had been worked well:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;date_default_timezone_set(&lt;/span&gt;&lt;span class="php1-string"&gt;'GMT'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Unfortunately, using &lt;acronym title="Greenwich Mean Time"&gt;GMT&lt;/acronym&gt; is not always an option, as you want to display users valid dates  for their territories, that is, you want localization or &lt;abbr title="localization"&gt;l10n&lt;/abbr&gt;. The other solution, which is better, is to not rely on arithmetic for such calculations. You're better off using &lt;a href="http://www.php.net/manual/en/function.mktime.php"&gt;mktime()&lt;/a&gt; which, as any other date/time function, is &lt;acronym title="Daylight Saving Time"&gt;DST&lt;/acronym&gt; aware.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;date_default_timezone_set(&lt;/span&gt;&lt;span class="php1-string"&gt;'Europe/Bucharest'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$start&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;strtotime(&lt;/span&gt;&lt;span class="php1-string"&gt;'01 October 2008'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$end&lt;/span&gt;&lt;span class="php1-space"&gt;   &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;strtotime(&lt;/span&gt;&lt;span class="php1-string"&gt;'01 November 2008'&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$start&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-reservedword"&gt;while&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;(&lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$end&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;echo&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;date(&lt;/span&gt;&lt;span class="php1-string"&gt;'Y M d H:i:s'&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-string"&gt;'&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-reservedword"&gt;list&lt;/span&gt;&lt;span class="php1-symbol"&gt;(&lt;/span&gt;&lt;span class="php1-variable"&gt;$month&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$day&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$year&lt;/span&gt;&lt;span class="php1-symbol"&gt;)&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;explode(&lt;/span&gt;&lt;span class="php1-string"&gt;'-'&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;date(&lt;/span&gt;&lt;span class="php1-string"&gt;'n-j-Y'&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-symbol"&gt;));&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-space"&gt;    &lt;/span&gt;&lt;span class="php1-variable"&gt;$next&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-identifier"&gt;mktime(&lt;/span&gt;&lt;span class="php1-number"&gt;0&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-number"&gt;0&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-number"&gt;0&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$month&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$day&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;+&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-number"&gt;1&lt;/span&gt;&lt;span class="php1-symbol"&gt;,&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-variable"&gt;$year&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;By the way, changing timezone identifier to 'Asia/Jerusalem' would double October 5th, 2008 in the first version of the script. You may find more about these on &lt;a href="http://www.timeanddate.com/"&gt;timeanddate.com&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-9065132051946239117?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/xm6jgPa43cc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/9065132051946239117/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2008/12/how-not-to-make-dates-in-php.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/9065132051946239117?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/9065132051946239117?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/xm6jgPa43cc/how-not-to-make-dates-in-php.html" title="How not to use dates in PHP" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_3mx3vaA_Qok/SU0GJM2p69I/AAAAAAAAAAU/1mTzD86N12M/s72-c/dst.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.igstan.ro/2008/12/how-not-to-make-dates-in-php.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcAR3Y9eCp7ImA9WxVUFUs.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-7994388288824640862</id><published>2008-12-16T12:15:00.012+02:00</published><updated>2009-03-20T17:30:46.860+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-20T17:30:46.860+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ajax file upload" /><category scheme="http://www.blogger.com/atom/ns#" term="Tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><category scheme="http://www.blogger.com/atom/ns#" term="Articles" /><title>Article submission to sitepoint.com</title><content type="html">Two days ago I finished what could be my first article for &lt;a href="http://www.sitepoint.com/"&gt;sitepoint.com&lt;/a&gt;. I've emailed them the article (actually a tutorial) yesterday in the morning and now I'm wainting for their response. If there's no response it means I failed. Hopefully it won't be so.&lt;br /&gt;&lt;br /&gt;I wrote about a pure JavaScript solution for &lt;acronym title="Asynchronous JavaScript And XML"&gt;AJAX&lt;/acronym&gt; file uploads. My solution doesn't make use of the iframe workaround or any Flash helper, it's really pure JavaScript. Unfortunately it requires Firefox 3 in order to work. Also, no special configurations on the browser, it should work with default factory settings.&lt;br /&gt;&lt;br /&gt;In case sitepoint.com rejects my tutorial I'll post it here, on my blog. The reason is that, in case of acceptance, they require full 90 days exclusivity over the article. You may found more on &lt;a href="http://www.sitepoint.com/about/writeforus"&gt;their dedicated page&lt;/a&gt;. I hope though, it will get accepted.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; The article got rejected but I have published the article on my blog: &lt;a href="http://igstan.blogspot.com/2009/01/pure-javascript-file-upload.html"&gt;Pure JavaScript file upload&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-7994388288824640862?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/GkXEdTLcD_8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/7994388288824640862/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2008/12/article-submission-to-sitepointcom.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/7994388288824640862?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/7994388288824640862?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/GkXEdTLcD_8/article-submission-to-sitepointcom.html" title="Article submission to sitepoint.com" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.igstan.ro/2008/12/article-submission-to-sitepointcom.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYCQXwycCp7ImA9WxRaEUs.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-7419246283967530632</id><published>2008-12-09T21:50:00.002+02:00</published><updated>2008-12-13T13:02:40.298+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-13T13:02:40.298+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="RoR" /><category scheme="http://www.blogger.com/atom/ns#" term="easter eggs" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby on Rails" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="funny" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>PHP Easter eggs</title><content type="html">Here's something I've just found about while Googling a little bit. Some &lt;acronym title="PHP Hypertext Preprocessor"&gt;PHP&lt;/acronym&gt; &lt;a href="http://en.wikipedia.org/wiki/Easter_egg_%28media%29"&gt;Easter eggs&lt;/a&gt;. The funny thing is that you can use this Easter eggs to discover whether a particular website is &lt;acronym title="PHP Hypertext Preprocessor"&gt;PHP&lt;/acronym&gt; powered. Like 37signals.com the creators of Ruby on Rails and... at some moment even rubyonrails.org :)&lt;br /&gt;Anyway, it appears the latter have now switched to &lt;acronym title="Ruby on Rails"&gt;RoR&lt;/acronym&gt; or turned off &lt;code&gt;expose_php&lt;/code&gt; in php.ini, as this would hide the Easter egg away from curious people.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://shiflett.org/blog/2006/feb/php-easter-eggs"&gt;PHP Easter eggs&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-7419246283967530632?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/9PuIo72k8Ms" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/7419246283967530632/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2008/12/php-easter-eggs.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/7419246283967530632?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/7419246283967530632?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/9PuIo72k8Ms/php-easter-eggs.html" title="PHP Easter eggs" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.igstan.ro/2008/12/php-easter-eggs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcCR3g5fip7ImA9WxRbGU4.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-3444509465571363641</id><published>2008-10-20T21:42:00.001+03:00</published><updated>2008-12-10T21:41:06.626+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-10T21:41:06.626+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="hype" /><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="design patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="nerd" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>MVC example from real, biological life</title><content type="html">Lately I've been thinking a lot about &lt;a href="http://en.wikipedia.org/wiki/Design_pattern"&gt;software design patterns&lt;/a&gt; and software architecture in an attempt of being a better software developer (or just being one). Anyway, to much talk, I want to get to the subject because I think it's very nice.&lt;br /&gt;&lt;br /&gt;You've probably heard of the &lt;a href="http://en.wikipedia.org/wiki/Model_view_controller"&gt;Model-View-Controller pattern&lt;/a&gt; which is a big hype nowadays thanks to Ruby on Rails web framework. It's all about separating data access (Model) from data presentation (View) and that's all. You may wonder where's the third part, the Controller. It's in between gluing the two parts together. The controller, while an important aspect of the &lt;acronym title="Model View Controller"&gt;MVC&lt;/acronym&gt; paradigm, is not as important as the idea of separation data and presentation.&lt;br /&gt;&lt;br /&gt;You've also probably read a lot of examples about &lt;acronym title="Model View Controller"&gt;MVC&lt;/acronym&gt;, involving web application that suddenly have to switch from a certain database vendor to another or output data in multiple formats, like &lt;acronym title="Hyper Text Markup Language"&gt;HTML&lt;/acronym&gt;, &lt;acronym title="JavaScript Object Notation"&gt;JSON&lt;/acronym&gt;, &lt;acronym title="Portable Document Format"&gt;PDF&lt;/acronym&gt;, &lt;abbr title="et cetera"&gt;etc.&lt;/abbr&gt; Well, here's a little &lt;acronym title="Model View Controller"&gt;MVC&lt;/acronym&gt; example that actually lies within your own body.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;It's the very human act of expressing ideas, either written or spoken.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When someone is expressing her ideas in speech she uses an &lt;acronym title="Model View Controller"&gt;MVC&lt;/acronym&gt; system where data is the idea itself (what she thinks) that sits in the Model (our conscience and perception of the surrounding world), the View is the language in which the ideas are presented and the Controller is the sum of biological and associated neuronic structures that let us map these ideas to comprehensible and logical sounds (in a normal human being).&lt;br /&gt;&lt;br /&gt;It's true that I exaggerated a little about the limits between the parts of this system and that these are very blurry line that separate them... nevertheless is the idea that matters. If it weren't for this &lt;acronym title="Model View Controller"&gt;MVC&lt;/acronym&gt; system inside us, speaking foreign languages would be impossible.&lt;br /&gt;&lt;br /&gt;P.S. Who?! Me? A nerd?!&lt;br /&gt;P.S.S. I'm not implying that my English view is perfect&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-3444509465571363641?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/gJDhCDCsrLo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/3444509465571363641/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2008/10/mvc-example-from-real-biological-life.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/3444509465571363641?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/3444509465571363641?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/gJDhCDCsrLo/mvc-example-from-real-biological-life.html" title="MVC example from real, biological life" /><author><name>Ionut G. Stan</name><uri>http://www.blogger.com/profile/10325171641002588574</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15948822882588615836" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.igstan.ro/2008/10/mvc-example-from-real-biological-life.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QFSH46eip7ImA9WxRXFEU.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-1148376030952994197</id><published>2008-09-04T13:41:00.000+03:00</published><updated>2008-10-20T10:55:19.012+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-20T10:55:19.012+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="install" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>Installing Python libraries on Windows</title><content type="html">Whenever you have to install another Python library on a Windows OS is good to do it like this from command line:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;cd path/to/library/dir&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;python setup.py bdist --format=wininst&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will pack all the source into an installer that can be found under:&lt;br /&gt;&lt;br /&gt;path/to/library/dir/&lt;span style="font-weight: bold;"&gt;dist&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Using this method you will later be able to go to Control Panel/Add or Remove Programs and uninstall such a library from there.&lt;br /&gt;&lt;br /&gt;For other platforms and options see  &lt;a href="http://docs.python.org/dist/built-dist.html"&gt;Python documentation on creating built distributions&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-1148376030952994197?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/aGCL9Z_1-hg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/1148376030952994197/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2008/09/installing-python-libraries-on-windows.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/1148376030952994197?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/1148376030952994197?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/aGCL9Z_1-hg/installing-python-libraries-on-windows.html" title="Installing Python libraries on Windows" /><author><name>I. G. Stan</name><email>noreply@blogger.com</email></author><thr:total>0</thr:total><feedburner:origLink>http://blog.igstan.ro/2008/09/installing-python-libraries-on-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIGQX07fSp7ImA9WxRaF0Q.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-3299959601380726859</id><published>2008-09-02T22:42:00.001+03:00</published><updated>2008-12-20T18:28:40.305+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-20T18:28:40.305+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><category scheme="http://www.blogger.com/atom/ns#" term="English" /><category scheme="http://www.blogger.com/atom/ns#" term="browser" /><title>Assessing Google Chrome</title><content type="html">&lt;div&gt;I have already discovered some bugs and managed to crash two tabs in under 3 minutes when I interrupted for writing this post. There are also some features I miss from Firefox. Details...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Bugs:&lt;/span&gt;&lt;div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;It erroneously fills some form fields from a forum I often visit overriding the input's value attribute (at least that's what I was able to see with the built in, à la firebug, inspector, which is good news by the way.)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The whole browser freezed when opening a link from the above mentioned forum that pointed to my weblog home page. I succeded to take back control when killing one process from the Windows task manager, which aparently made two tabs, not one (I killed one process, not tow), to show the sad face of failure.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Opening a 155 page PDF document made iresponsive the whole browser, not just the respective tab as said in the comic book and reduced 4 tab-processes to only one process in the Windows task manager which took the whole browser down when killing it.&lt;/li&gt;&lt;li&gt;After reboot the PDF page still isn't rendered as it should and any interaction with it slows down (to freezing) the whole browser. (At least this blog entry was preserved in the textarea).&lt;/li&gt;&lt;li&gt;There appear to be some bugs with the character encoding support. In Romanian we have special characters like şăîţâ that aren't rendered as they should nor when the enconding is ISO-8859-2 (which I know should be OK for Romanian), nor when I change it to UTF-8. Anyways, the website isn't sending a charset in the HTTP headers (according to LiveHTTPHeaders), on other web sites it is OK.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Missing features:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Middle-click scrolls page :(  That's awful for me, a reason not to use a browser.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Iframes used for rich text editing don't have spell checking, whereas textarea elements do.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I can't turn off spell checking on textarea elements.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Maybe not a missing features but I couldn't find it. Where can I choose another engine from my opensearch engines that were imported from Firefox after the installation? (later on) it may be redundant as all the opensearch providers are available for querying inside the address bar.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I'd really like to disable the close buttons on every opened tab.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When opening many tabs (&gt; 20) there's no way to know what site is in which tab, except for the favicon (if there is one) that is being displayed. That is because a tab's width is in inverse ratio with the number of tabs. I tend to like more the scrolling feature of Firefox in such a case (but maybe I'm just spoiled by Firefox). Anyway, they load fine dispite the large number.&lt;/li&gt;&lt;li&gt;It comes with built-in support for Adobe Flash and Adobe PDF but not Quick Time.&lt;/li&gt;&lt;li&gt;At this moment I have 7 folders of bookmarks imported from Firefox. When clicking one, there's a submenu that popups and the bookmars contained can be seen, well, now I expect that hovering another folder will open it automatically without click on it again but it doesn't happen like this, you have to click it again. I think on a Windows OS this is common practice for user interface (not to be forced to click again).&lt;/li&gt;&lt;li&gt;I don't have a history list by the back/forward buttons.&lt;/li&gt;&lt;li&gt;An RSS/Atom reader like in Firefox.&lt;/li&gt;&lt;li&gt;No "Zoom page" tool, only zoom text with CTRL++, CTRL+- and CTRL+0 just like in Firefox.&lt;/li&gt;&lt;li&gt;I can't middle click the back/forward button to open a previous page in new tab.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Good things/features:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;The HTML inspector (mentioned above) and JS debugger and console.&lt;/li&gt;&lt;li&gt;Searching through the installation files I discovered some js scripts that deal with the local data store and seemed to be integrated with the Inspector but I couldn't lauch it from the browser.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The source turn links into real links so that I can quickly go to the CSS and JS files of a website.&lt;/li&gt;&lt;li&gt;Mozilla Prism's idea of web pages that could be saved as desktop apps is now to be found in Google Chrome. You can save a shortcut to Gmail, for example, on the desktop, quick launch bar and start menu. &lt;a href="http://www.google.com/support/chrome/bin/answer.py?answer=95710&amp;amp;hl=en"&gt;Details&lt;/a&gt;&lt;/li&gt;&lt;li&gt;It has "View Frame Source" when right clicking on an iframe element.&lt;/li&gt;&lt;li&gt;I like the search capabilities in the address bar (I always wished it in Firefox).&lt;/li&gt;&lt;li&gt;The "bookmark this page" from the address bar is like Firefox's, except it misses tagging.&lt;/li&gt;&lt;li&gt;Incognito mode.&lt;/li&gt;&lt;li&gt;Speed of loading for some of the pages I visited.&lt;/li&gt;&lt;li&gt;Incremental search + it shows how many results it has found until that point + highlighting of matching keywords + F3 does work to jump to next result + ... the place of the search box :).&lt;/li&gt;&lt;li&gt;CTRL+J opens downloads tab.&lt;/li&gt;&lt;li&gt;Detaching tabs in standalone windows.&lt;/li&gt;&lt;li&gt;X/Y resizable textarea element, but the resizer image has a non-transparent upper-left corner.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;WTFs:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;The installation place. On my system (Windows XP Professional 32bit) it was in: "C:\Documents and Settings\username\Local Settings\Application Data\Google\Chrome\Application\chrome.exe", along with Gears and... GoogleUpdate.&lt;/user-name&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-3299959601380726859?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/OtJpz0DNOeQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/3299959601380726859/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2008/09/assessing-google-chrome.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/3299959601380726859?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/3299959601380726859?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/OtJpz0DNOeQ/assessing-google-chrome.html" title="Assessing Google Chrome" /><author><name>I. G. Stan</name><email>noreply@blogger.com</email></author><thr:total>0</thr:total><feedburner:origLink>http://blog.igstan.ro/2008/09/assessing-google-chrome.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQFRXw-cCp7ImA9WxVbGEo.&quot;"><id>tag:blogger.com,1999:blog-7374711781626641669.post-518782520701104938</id><published>2008-09-02T16:01:00.002+03:00</published><updated>2009-04-04T23:51:54.258+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-04T23:51:54.258+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="logică" /><category scheme="http://www.blogger.com/atom/ns#" term="română" /><category scheme="http://www.blogger.com/atom/ns#" term="de reţinut" /><title>XOR în PHP</title><content type="html">De reţinut:&lt;br /&gt;&lt;br /&gt;În PHP, operatorul logic XOR are precendenţă mai mică decât operaţia de asignare (=). Asta înseamnă că trebuiesc folosite paranteze şi pentru o singură operaţie logică XOR:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font: 10pt Courier New;"&gt;&lt;span class="php1-symbol"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$a&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt;  &lt;/span&gt;&lt;span class="php1-reservedword"&gt;true&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;xor&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;true&lt;/span&gt;&lt;span class="php1-symbol"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-variable"&gt;$b&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;=&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-symbol"&gt;(&lt;/span&gt;&lt;span class="php1-reservedword"&gt;true&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;xor&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;true&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;var_dump(&lt;/span&gt;&lt;span class="php1-variable"&gt;$a&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;var_dump(&lt;/span&gt;&lt;span class="php1-variable"&gt;$b&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;var_dump(&lt;/span&gt;&lt;span class="php1-reservedword"&gt;true&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;xor&lt;/span&gt;&lt;span class="php1-space"&gt; &lt;/span&gt;&lt;span class="php1-reservedword"&gt;true&lt;/span&gt;&lt;span class="php1-symbol"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="php1-comment"&gt;/* va afişa&lt;br /&gt;&lt;br /&gt;bool(true);&lt;br /&gt;bool(false);&lt;br /&gt;bool(false);&lt;br /&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.php.net/manual/en/language.operators.php#language.operators.precedence"&gt;PHP: precedenţă operatori&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7374711781626641669-518782520701104938?l=blog.igstan.ro' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/igstan/~4/YlyX-iEnyCo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.igstan.ro/feeds/518782520701104938/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.igstan.ro/2008/09/xor-n-php.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/518782520701104938?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7374711781626641669/posts/default/518782520701104938?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/igstan/~3/YlyX-iEnyCo/xor-n-php.html" title="XOR în PHP" /><author><name>I. G. Stan</name><email>noreply@blogger.com</email></author><thr:total>2</thr:total><feedburner:origLink>http://blog.igstan.ro/2008/09/xor-n-php.html</feedburner:origLink></entry></feed>
