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

<channel>
	<title>Less Talk, More Do &#187; JavaScript</title>
	<atom:link href="http://www.chrisfinke.com/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.chrisfinke.com</link>
	<description>Christopher Finke is a software engineer. He is available for birthday parties and bar mitzvahs.</description>
	<lastBuildDate>Sun, 28 Feb 2010 00:09:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Uploading form data and files with JavaScript (Mozilla)</title>
		<link>http://www.chrisfinke.com/2010/01/30/uploading-form-data-and-files-with-javascript-mozilla/</link>
		<comments>http://www.chrisfinke.com/2010/01/30/uploading-form-data-and-files-with-javascript-mozilla/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 21:23:34 +0000</pubDate>
		<dc:creator>Christopher Finke</dc:creator>
				<category><![CDATA[Browser Add-ons]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.chrisfinke.com/?p=1573</guid>
		<description><![CDATA[One problem I stumble across occasionally in writing Firefox extensions is properly uploading form data that includes a file - that is, assembling the POST request in JavaScript while still maintaining the sanctity of any file or string data.  You can't just do this:

var request = "--boundary\r\n some text\r\n--boundary" + fileBytes + "\r\n--boundary--";

I had [...]]]></description>
			<content:encoded><![CDATA[<p>One problem I stumble across occasionally in writing Firefox extensions is properly uploading form data that includes a file - that is, assembling the POST request in JavaScript while still maintaining the sanctity of any file or string data.  You can't just do this:</p>
<pre>
var request = "--boundary\r\n some text\r\n--boundary" + fileBytes + "\r\n--boundary--";
</pre>
<p>I had to spend a bit of time getting this just right in order to allow <a href="http://www.scribefire.com/">ScribeFire</a> to upload media to <a href="http://posterous.com/">Posterous</a>, so I'm posting below the final solution at which I arrived; it was cobbled together from a dozen different examples I found around the Web (none of them solving the full problem), then lovingly massaged into the elegant function you see before you.  With this function, you can pass in an array of fields and files, and the request will be crafted and returned to you, ready for upload.</p>
<p>Instructions for use are in the comment block at the top of the function.</p>
<pre>
function createPostRequest(args) {
  /**
   * Generates a POST request body for uploading.
   *
   * args is an associative array of the form fields.
   *
   * Example:
   * var args = { "field1": "abc", "field2" : "def", "fileField" :
   *              { "file": theFile, "headers" : [ "X-Fake-Header: foo" ] } };
   *
   * theFile is an nsILocalFile; the headers param for the file field is optional.
   *
   * This function returns an array like this:
   * { "requestBody" : uploadStream, "boundary" : BOUNDARY }
   *
   * To upload:
   *
   * var postRequest = createPostRequest(args);
   * var req = new XMLHttpRequest();
   * req.open("POST", ...);
   * req.setRequestHeader("Content-Type","multipart/form-data; boundary="+postRequest.boundary);
   * req.setRequestHeader("Content-Length", (postRequest.requestBody.available()));
   * req.send(postRequest.requestBody);
   */

  function stringToStream(str) {
    function encodeToUtf8(oStr) {
      var utfStr = oStr;
      var uConv = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
                    .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
      uConv.charset = "UTF-8";
      utfStr = uConv.ConvertFromUnicode(oStr);

      return utfStr;
    }

    str = encodeToUtf8(str);

    var stream = Components.classes["@mozilla.org/io/string-input-stream;1"]
                   .createInstance(Components.interfaces.nsIStringInputStream);
    stream.setData(str, str.length);

    return stream;
  }

  function fileToStream(file) {
    var fpLocal  = Components.classes['@mozilla.org/file/local;1']
                     .createInstance(Components.interfaces.nsILocalFile);
    fpLocal.initWithFile(file);

    var finStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                      .createInstance(Components.interfaces.nsIFileInputStream);
    finStream.init(fpLocal, 1, 0, false);

    var bufStream = Components.classes["@mozilla.org/network/buffered-input-stream;1"]
                      .createInstance(Components.interfaces.nsIBufferedInputStream);
    bufStream.init(finStream, 9000000);

    return bufStream;
  }

  var mimeSvc = Components.classes["@mozilla.org/mime;1"]
                  .getService(Components.interfaces.nsIMIMEService);
  const BOUNDARY = "---------------------------32191240128944"; 

  var streams = [];

  for (var i in args) {
    var buffer = "--" + BOUNDARY + "\r\n";
    buffer += "Content-Disposition: form-data; name=\"" + i + "\"";
    streams.push(stringToStream(buffer));

    if (typeof args[i] == "object") {
      buffer = "; filename=\"" + args[i].file.leafName + "\"";

      if ("headers" in args[i]) {
        if (args[i].headers.length > 0) {
          for (var q = 0; q < args[i].headers.length; q++){
            buffer += "\r\n" + args[i].headers[q];
          }
        }
      }

      var theMimeType = mimeSvc.getTypeFromFile(args[i].file);

      buffer += "\r\nContent-Type: " + theMimeType;
      buffer += "\r\n\r\n";

      streams.push(stringToStream(buffer));

      streams.push(fileToStream(args[i].file));
    }
    else {
      buffer = "\r\n\r\n";
      buffer += args[i];
      buffer += "\r\n";
      streams.push(stringToStream(buffer));
    }
  }

  var buffer = "--" + BOUNDARY + "--\r\n";
  streams.push(stringToStream(buffer));

  var uploadStream = Components.classes["@mozilla.org/io/multiplex-input-stream;1"]
                       .createInstance(Components.interfaces.nsIMultiplexInputStream);

  for (var i = 0; i < streams.length; i++) {
    uploadStream.appendStream(streams[i]);
  }

  return { "requestBody" : uploadStream, "boundary": BOUNDARY };
}
</pre>
 <img src="http://www.chrisfinke.com/wp-content/plugins/feed-statistics.php?view=1&post_id=1573" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.chrisfinke.com/2010/01/30/uploading-form-data-and-files-with-javascript-mozilla/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Image-to-Email: Broken Again</title>
		<link>http://www.chrisfinke.com/2007/11/16/facebook-image-to-email-broken-again/</link>
		<comments>http://www.chrisfinke.com/2007/11/16/facebook-image-to-email-broken-again/#comments</comments>
		<pubDate>Fri, 16 Nov 2007 22:17:32 +0000</pubDate>
		<dc:creator>Christopher Finke</dc:creator>
				<category><![CDATA[Browser Add-ons]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Facebook Image-to-Email]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla Firefox]]></category>

		<guid isPermaLink="false">http://www.chrisfinke.com/2007/11/16/facebook-image-to-email-broken-again/</guid>
		<description><![CDATA[I am aware that the Facebook Image-to-Email Firefox extension is (once again) broken, and given that version 1.1 installed on Firefox 2.0.0.8 was working, and now version 1.1 installed on Firefox 2.0.0.8 is not working, it has to be due to a change that Facebook made.  The problem is that I can't discern any [...]]]></description>
			<content:encoded><![CDATA[<p>I am aware that the <a href="http://www.chrisfinke.com/addons/facebook-image-to-email/">Facebook Image-to-Email</a> Firefox extension is (once again) broken, and given that version 1.1 installed on Firefox 2.0.0.8 <em>was</em> working, and now version 1.1 installed on Firefox 2.0.0.8 is not working, it has to be due to a change that Facebook made.  The problem is that I can't discern any relevant changes in Facebook's profile pages that would cause a problem.</p>
<p>The crux is this: I'm getting an NS_ERROR_DOM_SECURITY_ERR error when trying to run context.getImageData().  From what I've read, this implies that the JavaScript is not in the same domain as the image that was fed into the canvas and/or does not have permission to know the image's contents, but as far as I can tell, Facebook didn't change where the e-mail images are coming from, so that would seem to be a strange problem to have.</p>
<p>Any insight into this is appreciated.</p>
 <img src="http://www.chrisfinke.com/wp-content/plugins/feed-statistics.php?view=1&post_id=520" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.chrisfinke.com/2007/11/16/facebook-image-to-email-broken-again/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Convert Facebook e-mail images to actual e-mail links</title>
		<link>http://www.chrisfinke.com/2007/09/11/convert-facebook-e-mail-images-to-actual-e-mail-links/</link>
		<comments>http://www.chrisfinke.com/2007/09/11/convert-facebook-e-mail-images-to-actual-e-mail-links/#comments</comments>
		<pubDate>Tue, 11 Sep 2007 16:04:10 +0000</pubDate>
		<dc:creator>Christopher Finke</dc:creator>
				<category><![CDATA[Browser Add-ons]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Facebook Image-to-Email]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla Firefox]]></category>

		<guid isPermaLink="false">http://www.chrisfinke.com/2007/09/11/convert-facebook-e-mail-images-to-actual-e-mail-links/</guid>
		<description><![CDATA[The massively popular social network Facebook uses images to display the e-mail addresses of your friends, making it impossible to copy the e-mail address or click on it to send e-mails to your friends, thus making Facebook's own proprietary in-site messaging system more attractive to its users.  Yesterday, Gervase Markham posited that it should [...]]]></description>
			<content:encoded><![CDATA[<p>The massively popular social network Facebook uses images to display the e-mail addresses of your friends, making it impossible to copy the e-mail address or click on it to send e-mails to your friends, thus making Facebook's own proprietary in-site messaging system more attractive to its users.  Yesterday, <a href="http://weblogs.mozillazine.org/gerv/archives/2007/09/facebook_imagetoemail.html">Gervase Markham posited</a> that it should be possible to determine the text displayed in the image programmatically by way of the canvas tag and some JavaScript.  I'm writing this to confirm that it is indeed possible and <a href="http://www.chrisfinke.com/addons/facebook-image-to-email/">has been achieved</a>.</p>
<p>The extension I've written to do this is called <a href="http://www.chrisfinke.com/addons/facebook-image-to-email/">Facebook Image-to-Email</a>.  On any Facebook page containing an e-mail address image, the extension converts the image to text using the following workflow:</p>
<ol>
<li>Copy the image to a canvas using drawImage()</li>
<li>Scans through the canvas to find matches for a pre-determined set of character sprites using getImageData</li>
<li>Replaces the image with a clickable text e-mail address</li>
</ol>
<p>Here's an example of a "before" view:</p>
<p style="text-align: center;"><img src='http://www.chrisfinke.com/files/2007/09/facebook-before.png' alt='facebook-before.png' /></p>
<p>And "after":</p>
<p style="text-align: center;"><img src='http://www.chrisfinke.com/files/2007/09/facebook-after.png' alt='facebook-after.png' /></p>
<p>Of course, this appears to be pretty simple. Ironically, the hardest part of solving this problem was the only part that Gervase remarked would be trivial: matching the image against a set of known character patterns.  Since the font is not monospaced, and certain letters bleed into each other when adjacent (such as "89" and "ef"), it wasn't possible to just store the pixel values for each full letter.  What I ended up doing was only matching against only the center of the letters (which are never affected by adjacent letters) and just ignoring character edges. </p>
<p>One other detail as to the implementation: there appears to be some sort of security restriction in Firefox on reading data from images that are not in the same domain as the script reading them.  For example, trying to call getImageData() from the chrome on a canvas that contained an image loaded from facebook.com returned null every time; the same happened if the script was running locally but loading a remote image.  For this reason, the actual scripting that converts the image to text has to be injected into each page that requires it so that it appears to be running in the same domain as the image.</p>
<p>I'm not claiming that this is the most efficient implementation, but it is definitely complete.   In my testing so far, it has correctly identified 100% of the e-mail addresses displayed in the images.</p>
 <img src="http://www.chrisfinke.com/wp-content/plugins/feed-statistics.php?view=1&post_id=469" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.chrisfinke.com/2007/09/11/convert-facebook-e-mail-images-to-actual-e-mail-links/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Pownce has a big security problem</title>
		<link>http://www.chrisfinke.com/2007/07/08/pownce-has-a-big-security-problem/</link>
		<comments>http://www.chrisfinke.com/2007/07/08/pownce-has-a-big-security-problem/#comments</comments>
		<pubDate>Sun, 08 Jul 2007 06:29:42 +0000</pubDate>
		<dc:creator>Christopher Finke</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Kevin Rose]]></category>
		<category><![CDATA[Leah Culver]]></category>
		<category><![CDATA[Mozilla Firefox]]></category>
		<category><![CDATA[Netscape Navigator]]></category>
		<category><![CDATA[Pownce]]></category>
		<category><![CDATA[Safari]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Applications]]></category>

		<guid isPermaLink="false">http://www.chrisfinke.com/2007/07/08/pownce-has-a-big-security-problem/</guid>
		<description><![CDATA[Kevin Rose's latest project, Pownce, has a glaring security problem on its front page.  The JavaScript that Pownce uses in its login form can reveal your password in plain text on the screen.  Here are the steps to reproduce the problem in Firefox:


Login to Pownce via http://www.pownce.com/.  Allow Firefox to save your [...]]]></description>
			<content:encoded><![CDATA[<p>Kevin Rose's latest project, <a href="http://www.pownce.com/">Pownce</a>, has a glaring security problem on its front page.  The JavaScript that Pownce uses in its login form can reveal your password in plain text on the screen.  Here are the steps to reproduce the problem in Firefox:</p>
<ol>
<li>
<p>Login to Pownce via <a href="http://www.pownce.com/">http://www.pownce.com/</a>.  Allow Firefox to save your login information for next time, and then log out.</p>
<p><img src='http://www.chrisfinke.com/files/2007/07/pownce-pass-1.png' alt='Pownce's login form' /></p>
</li>
<li>
<p>Navigate to <a href="http://www.pownce.com/">http://www.pownce.com/</a> and type the first part of your username in the "Enter username..." box. Firefox will supply all of the matching usernames it remembers for this site. (So far, so good.)</p>
<p><img src='http://www.chrisfinke.com/files/2007/07/pownce-pass-2.png' alt='Using Firefox's remembering skills' />
</li>
<li>
<p>Select your username and press return to have the browser autofill the rest of your information.  Oh look, there's your Pownce password in plain view!  I hope no one in the room was watching you login...</p>
<p><img src='http://www.chrisfinke.com/files/2007/07/pownce-pass-3.png' alt='Hey look, it's my password in plain text!' />
</li>
</ol>
<p>The method that Pownce is using to show the "Enter password..." prompt in the password field is the reason for this malfunction; browsers force all text in password fields to be hidden with asterisks, so if you want to show normal text in a password field like Pownce has chosen to, you have to do so in a non-standard way.</p>
<p>This bug affects Firefox and Netscape users who have JavaScript enabled, but it doesn't affect Safari users.</p>
 <img src="http://www.chrisfinke.com/wp-content/plugins/feed-statistics.php?view=1&post_id=384" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.chrisfinke.com/2007/07/08/pownce-has-a-big-security-problem/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Extending JavaScript</title>
		<link>http://www.chrisfinke.com/2007/05/05/extending-javascript/</link>
		<comments>http://www.chrisfinke.com/2007/05/05/extending-javascript/#comments</comments>
		<pubDate>Sat, 05 May 2007 21:49:06 +0000</pubDate>
		<dc:creator>Christopher Finke</dc:creator>
				<category><![CDATA[Browser Add-ons]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Netscape Navigator]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.chrisfinke.com/2007/05/05/extending-javascript/</guid>
		<description><![CDATA[There are a lot of common programming algorithms that are built into various languages as functions: checking if an array contains a certain item, trimming a string, mapping a function to an array, etc.  JavaScript doesn't have a lot of these built-ins, but with prototypical inheritance, it's easy enough to add them.
I'm thinking it [...]]]></description>
			<content:encoded><![CDATA[<p>There are a lot of common programming algorithms that are built into various languages as functions: checking if an array contains a certain item, trimming a string, mapping a function to an array, etc.  JavaScript doesn't have a lot of these built-ins, but with <a href="http://javascript.crockford.com/prototypal.html">prototypical inheritance</a>, it's easy enough to add them.</p>
<p>I'm thinking it might be beneficial to include with the browser a "JavaScript extension" file - that is, one JS file packaged with the browser that contains function definitions for these common tasks.  It wouldn't necessarily be visible to scripts in webpages (and it would probably be a bad idea to do so, as it might break current scripts), but it could be utilized by extension developers if they choose to do so, just by adding this to their main XUL overlay file:</p>
<p><code>&lt;script type="application/x-javascript" src="chrome://browser/content/extend.js">&lt;/script></code></p>
<p>I know that I've had to write an Array.contains function for just about every extension I've written, so I know this kind of library would come in handy.  These are the functions that got me thinking about this:</p>
<p>String.reverse<br />
String.trim (and maybe ltrim and rtrim, but these tend to be used less)<br />
String.md5<br />
String.stripTags (not as keen on this one)<br />
Array.contains<br />
Array.map<br />
Array.random<br />
Array.shuffle<br />
Date.format (a pseudo-port of <a href="http://us2.php.net/manual/en/function.date.php">PHP's date() function</a>)</p>
<p>Any recommendations for other functions that might as well be standard?</p>
<p><i>Note: As this is being posted on my personal site, this is no guarantee or indication that Netscape Navigator 9 will be supplying this kind of library.  If the feedback is positive though, I would definitely bring it up for consideration.</i></p>
 <img src="http://www.chrisfinke.com/wp-content/plugins/feed-statistics.php?view=1&post_id=273" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.chrisfinke.com/2007/05/05/extending-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Video Tutorial: The JavaScript Programming Language</title>
		<link>http://www.chrisfinke.com/2007/05/04/video-tutorial-the-javascript-programming-language/</link>
		<comments>http://www.chrisfinke.com/2007/05/04/video-tutorial-the-javascript-programming-language/#comments</comments>
		<pubDate>Fri, 04 May 2007 21:04:55 +0000</pubDate>
		<dc:creator>Christopher Finke</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Recommendations]]></category>
		<category><![CDATA[Yahoo!]]></category>

		<guid isPermaLink="false">http://www.chrisfinke.com/2007/05/04/video-tutorial-the-javascript-programming-language/</guid>
		<description><![CDATA[Yahoo!'s video of Douglas Crockford's The JavaScript Programming Language lecture is definitely the best overview of JavaScript that I've ever seen.  (The first part is embedded below, and the remaining 3 parts are linked after that.)  I saw it a while back, but it's been getting a fair amount of press in the [...]]]></description>
			<content:encoded><![CDATA[<p>Yahoo!'s video of Douglas Crockford's <em>The JavaScript Programming Language</em> lecture is definitely the best overview of JavaScript that I've ever seen.  (The first part is embedded below, and the remaining 3 parts are linked after that.)  I saw it a while back, but it's been getting a fair amount of press in the social media space this week.</p>
<p><embed src='http://us.i1.yimg.com/cosmos.bcst.yahoo.com/player/media/swf/FLVVideoSolo.swf' flashvars='id=1710507&#038;emailUrl=http%3A%2F%2Fvideo.yahoo.com%2Futil%2Fmail%3Fei%3DUTF-8%26vid%3D111593&#038;imUrl=http%253A%252F%252Fvideo.yahoo.com%252Fvideo%252Fplay%253Fei%253DUTF-8%2526vid%253D111593&#038;imTitle=Douglas%2BCrockford%253A%2B%2526quot%253BThe%2BJavaScript%2BProgramming%2BLanguage%2526quot%253B%252F1%2Bof%2B4&#038;searchUrl=http://video.yahoo.com/video/search?p=&#038;profileUrl=http://video.yahoo.com/video/profile?yid=&#038;creatorValue=ZXJpY21pcmFnbGlh&#038;vid=111593' type='application/x-shockwave-flash' width='425' height='350'></embed></p>
<p><a href="http://video.yahoo.com/video/play?ei=UTF-8&#038;b=24&#038;vid=111594&#038;gid=133414">Part 2</a> <a href="http://video.yahoo.com/video/play?ei=UTF-8&#038;b=25&#038;vid=111595&#038;gid=133414">Part 3</a> <a href="http://video.yahoo.com/video/play?ei=UTF-8&#038;b=7&#038;vid=111596&#038;gid=133414">Part 4</a></p>
<p>I'm self-taught when it comes to JavaScript, as I've never taken a formal class that dealt with it, and it was refreshing to find that I've managed to pick up most of the good habits that Crockford recommends while avoiding most of the bad habits he cautions against.  I must have made good choices as to which sites' and browser extensions' source code I studied.</p>
<p>I think next I'll get started on watching their <a href="http://video.yahoo.com/video/play?ei=UTF-8&#038;b=15&#038;vid=111585&#038;gid=133414">"Advanced JavaScript" series</a>.</p>
 <img src="http://www.chrisfinke.com/wp-content/plugins/feed-statistics.php?view=1&post_id=272" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.chrisfinke.com/2007/05/04/video-tutorial-the-javascript-programming-language/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
